From b90375565296d0e524ee959f3336321e1413cf78 Mon Sep 17 00:00:00 2001 From: sters Date: Wed, 17 Sep 2025 12:01:22 +0900 Subject: [PATCH] add is_hidden support for information_schema_source --- v2/Makefile | 2 +- v2/loader/information_schema_source.go | 6 +- v2/test/testdata/schema.sql | 6 + .../default/composite_primary_key.yo.go | 2 +- .../custom_composite_primary_key.yo.go | 2 +- .../testmodels/default/full_text_search.yo.go | 176 ++++++++++++++++++ .../dump_types/full_text_search.txt | 12 ++ .../composite_primary_key.yo.go | 16 +- .../custom_composite_primary_key.yo.go | 16 +- .../legacy_default/full_text_search.yo.go | 176 ++++++++++++++++++ 10 files changed, 394 insertions(+), 20 deletions(-) create mode 100644 v2/test/testmodels/default/full_text_search.yo.go create mode 100644 v2/test/testmodels/dump_types/full_text_search.txt create mode 100644 v2/test/testmodels/legacy_default/full_text_search.yo.go diff --git a/v2/Makefile b/v2/Makefile index 0511e7d4..30082c4b 100644 --- a/v2/Makefile +++ b/v2/Makefile @@ -73,4 +73,4 @@ check-diff: echo "--- Actual Files ---" ; \ echo "$$ACTUAL_FILES" ; \ exit 1 ; \ - fi \ No newline at end of file + fi diff --git a/v2/loader/information_schema_source.go b/v2/loader/information_schema_source.go index e2058aa1..aa179f50 100644 --- a/v2/loader/information_schema_source.go +++ b/v2/loader/information_schema_source.go @@ -90,7 +90,8 @@ func (s *informationSchemaSource) ColumnList(table string) ([]*SpannerColumn, er ` AND ic.COLUMN_NAME = c.COLUMN_NAME` + ` AND ic.INDEX_NAME = "PRIMARY_KEY" ` + `) IS_PRIMARY_KEY, ` + - `IS_GENERATED = "ALWAYS" AS IS_GENERATED ` + + `IS_GENERATED = "ALWAYS" AS IS_GENERATED, ` + + `c.IS_HIDDEN ` + `FROM INFORMATION_SCHEMA.COLUMNS c ` + `WHERE c.TABLE_SCHEMA = "" AND c.TABLE_NAME = @table ` + `ORDER BY c.ORDINAL_POSITION` @@ -136,6 +137,9 @@ func (s *informationSchemaSource) ColumnList(table string) ([]*SpannerColumn, er if err := row.ColumnByName("IS_GENERATED", &c.IsGenerated); err != nil { return nil, err } + if err := row.ColumnByName("IS_HIDDEN", &c.IsHidden); err != nil { + return nil, err + } res = append(res, &c) } diff --git a/v2/test/testdata/schema.sql b/v2/test/testdata/schema.sql index 3bf13d93..f3e84d3e 100644 --- a/v2/test/testdata/schema.sql +++ b/v2/test/testdata/schema.sql @@ -171,3 +171,9 @@ CREATE TABLE Inflectionzz ( X STRING(32) NOT NULL, Y STRING(32) NOT NULL, ) PRIMARY KEY(X); + +CREATE TABLE FullTextSearch ( + ID INT64 NOT NULL, + Content STRING(2048) NOT NULL, + Content_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(Content)) HIDDEN, +) PRIMARY KEY(ID); diff --git a/v2/test/testmodels/default/composite_primary_key.yo.go b/v2/test/testmodels/default/composite_primary_key.yo.go index c245e1a2..3a551ffa 100644 --- a/v2/test/testmodels/default/composite_primary_key.yo.go +++ b/v2/test/testmodels/default/composite_primary_key.yo.go @@ -417,8 +417,8 @@ func ReadCompositePrimaryKeysByCompositePrimaryKeysByError3(ctx context.Context, "PKey1", "PKey2", "Error", - "Z", "Y", + "Z", } decoder := newCompositePrimaryKey_Decoder(columns) diff --git a/v2/test/testmodels/default/custom_composite_primary_key.yo.go b/v2/test/testmodels/default/custom_composite_primary_key.yo.go index 35fc0fba..049d6d1f 100644 --- a/v2/test/testmodels/default/custom_composite_primary_key.yo.go +++ b/v2/test/testmodels/default/custom_composite_primary_key.yo.go @@ -417,8 +417,8 @@ func ReadCustomCompositePrimaryKeysByCustomCompositePrimaryKeysByError3(ctx cont "PKey1", "PKey2", "Error", - "Z", "Y", + "Z", } decoder := newCustomCompositePrimaryKey_Decoder(columns) diff --git a/v2/test/testmodels/default/full_text_search.yo.go b/v2/test/testmodels/default/full_text_search.yo.go new file mode 100644 index 00000000..2455bbc1 --- /dev/null +++ b/v2/test/testmodels/default/full_text_search.yo.go @@ -0,0 +1,176 @@ +// Code generated by yo. DO NOT EDIT. + +// Package models contains the types. +package models + +import ( + "context" + "fmt" + + "cloud.google.com/go/spanner" + "google.golang.org/grpc/codes" +) + +// FullTextSearch represents a row from 'FullTextSearch'. +type FullTextSearch struct { + ID int64 `spanner:"ID" json:"ID"` // ID + Content string `spanner:"Content" json:"Content"` // Content +} + +func FullTextSearchPrimaryKeys() []string { + return []string{ + "ID", + } +} + +func FullTextSearchColumns() []string { + return []string{ + "ID", + "Content", + } +} + +func FullTextSearchWritableColumns() []string { + return []string{ + "ID", + "Content", + } +} + +func (fts *FullTextSearch) columnsToPtrs(cols []string) ([]interface{}, error) { + ret := make([]interface{}, 0, len(cols)) + for _, col := range cols { + switch col { + case "ID": + ret = append(ret, yoDecode(&fts.ID)) + case "Content": + ret = append(ret, yoDecode(&fts.Content)) + default: + return nil, fmt.Errorf("unknown column: %s", col) + } + } + return ret, nil +} + +func (fts *FullTextSearch) columnsToValues(cols []string) ([]interface{}, error) { + ret := make([]interface{}, 0, len(cols)) + for _, col := range cols { + switch col { + case "ID": + ret = append(ret, yoEncode(fts.ID)) + case "Content": + ret = append(ret, yoEncode(fts.Content)) + default: + return nil, fmt.Errorf("unknown column: %s", col) + } + } + + return ret, nil +} + +// newFullTextSearch_Decoder returns a decoder which reads a row from *spanner.Row +// into FullTextSearch. The decoder is not goroutine-safe. Don't use it concurrently. +func newFullTextSearch_Decoder(cols []string) func(*spanner.Row) (*FullTextSearch, error) { + return func(row *spanner.Row) (*FullTextSearch, error) { + var fts FullTextSearch + ptrs, err := fts.columnsToPtrs(cols) + if err != nil { + return nil, err + } + + if err := row.Columns(ptrs...); err != nil { + return nil, err + } + + return &fts, nil + } +} + +// Insert returns a Mutation to insert a row into a table. If the row already +// exists, the write or transaction fails. +func (fts *FullTextSearch) Insert(ctx context.Context) *spanner.Mutation { + values, _ := fts.columnsToValues(FullTextSearchWritableColumns()) + return spanner.Insert("FullTextSearch", FullTextSearchWritableColumns(), values) +} + +// Update returns a Mutation to update a row in a table. If the row does not +// already exist, the write or transaction fails. +func (fts *FullTextSearch) Update(ctx context.Context) *spanner.Mutation { + values, _ := fts.columnsToValues(FullTextSearchWritableColumns()) + return spanner.Update("FullTextSearch", FullTextSearchWritableColumns(), values) +} + +// InsertOrUpdate returns a Mutation to insert a row into a table. If the row +// already exists, it updates it instead. Any column values not explicitly +// written are preserved. +func (fts *FullTextSearch) InsertOrUpdate(ctx context.Context) *spanner.Mutation { + values, _ := fts.columnsToValues(FullTextSearchWritableColumns()) + return spanner.InsertOrUpdate("FullTextSearch", FullTextSearchWritableColumns(), values) +} + +// Replace returns a Mutation to insert a row into a table, deleting any +// existing row. Unlike InsertOrUpdate, this means any values not explicitly +// written become NULL. +func (fts *FullTextSearch) Replace(ctx context.Context) *spanner.Mutation { + values, _ := fts.columnsToValues(FullTextSearchWritableColumns()) + return spanner.Replace("FullTextSearch", FullTextSearchWritableColumns(), values) +} + +// UpdateColumns returns a Mutation to update specified columns of a row in a table. +func (fts *FullTextSearch) UpdateColumns(ctx context.Context, cols ...string) (*spanner.Mutation, error) { + // add primary keys to columns to update by primary keys + colsWithPKeys := append(cols, FullTextSearchPrimaryKeys()...) + + values, err := fts.columnsToValues(colsWithPKeys) + if err != nil { + return nil, newErrorWithCode(codes.InvalidArgument, "FullTextSearch.UpdateColumns", "FullTextSearch", err) + } + + return spanner.Update("FullTextSearch", colsWithPKeys, values), nil +} + +// FindFullTextSearch gets a FullTextSearch by primary key +func FindFullTextSearch(ctx context.Context, db YODB, id int64) (*FullTextSearch, error) { + _key := spanner.Key{yoEncode(id)} + row, err := db.ReadRow(ctx, "FullTextSearch", _key, FullTextSearchColumns()) + if err != nil { + return nil, newError("FindFullTextSearch", "FullTextSearch", err) + } + + decoder := newFullTextSearch_Decoder(FullTextSearchColumns()) + fts, err := decoder(row) + if err != nil { + return nil, newErrorWithCode(codes.Internal, "FindFullTextSearch", "FullTextSearch", err) + } + + return fts, nil +} + +// ReadFullTextSearch retrieves multiples rows from FullTextSearch by KeySet as a slice. +func ReadFullTextSearch(ctx context.Context, db YODB, keys spanner.KeySet) ([]*FullTextSearch, error) { + var res []*FullTextSearch + + decoder := newFullTextSearch_Decoder(FullTextSearchColumns()) + + rows := db.Read(ctx, "FullTextSearch", keys, FullTextSearchColumns()) + err := rows.Do(func(row *spanner.Row) error { + fts, err := decoder(row) + if err != nil { + return err + } + res = append(res, fts) + + return nil + }) + if err != nil { + return nil, newErrorWithCode(codes.Internal, "ReadFullTextSearch", "FullTextSearch", err) + } + + return res, nil +} + +// Delete deletes the FullTextSearch from the database. +func (fts *FullTextSearch) Delete(ctx context.Context) *spanner.Mutation { + values, _ := fts.columnsToValues(FullTextSearchPrimaryKeys()) + return spanner.Delete("FullTextSearch", spanner.Key(values)) +} diff --git a/v2/test/testmodels/dump_types/full_text_search.txt b/v2/test/testmodels/dump_types/full_text_search.txt new file mode 100644 index 00000000..4febfb71 --- /dev/null +++ b/v2/test/testmodels/dump_types/full_text_search.txt @@ -0,0 +1,12 @@ +# Field list of FullTextSearch + +* ID INT64 int64 +* Content STRING(2048) string +* ContentTokens TOKENLIST TOKENLIST + +# Primary Key + +* ID INT64 int64 + +# Index list of FullTextSearch + diff --git a/v2/test/testmodels/legacy_default/composite_primary_key.yo.go b/v2/test/testmodels/legacy_default/composite_primary_key.yo.go index 6db3b726..c19c0df8 100644 --- a/v2/test/testmodels/legacy_default/composite_primary_key.yo.go +++ b/v2/test/testmodels/legacy_default/composite_primary_key.yo.go @@ -363,10 +363,10 @@ func ReadCompositePrimaryKeysByZError(ctx context.Context, db YODB, keys spanner return res, nil } -// FindCompositePrimaryKeysByZYError retrieves multiple rows from 'CompositePrimaryKeys' as a slice of CompositePrimaryKey. +// FindCompositePrimaryKeysByYZError retrieves multiple rows from 'CompositePrimaryKeys' as a slice of CompositePrimaryKey. // // Generated from index 'CompositePrimaryKeysByError3'. -func FindCompositePrimaryKeysByZYError(ctx context.Context, db YODB, e int64) ([]*CompositePrimaryKey, error) { +func FindCompositePrimaryKeysByYZError(ctx context.Context, db YODB, e int64) ([]*CompositePrimaryKey, error) { const sqlstr = "SELECT " + "Id, PKey1, PKey2, Error, X, Y, Z " + "FROM CompositePrimaryKeys@{FORCE_INDEX=CompositePrimaryKeysByError3} " + @@ -390,12 +390,12 @@ func FindCompositePrimaryKeysByZYError(ctx context.Context, db YODB, e int64) ([ if err == iterator.Done { break } - return nil, newError("FindCompositePrimaryKeysByZYError", "CompositePrimaryKeys", err) + return nil, newError("FindCompositePrimaryKeysByYZError", "CompositePrimaryKeys", err) } cpk, err := decoder(row) if err != nil { - return nil, newErrorWithCode(codes.Internal, "FindCompositePrimaryKeysByZYError", "CompositePrimaryKeys", err) + return nil, newErrorWithCode(codes.Internal, "FindCompositePrimaryKeysByYZError", "CompositePrimaryKeys", err) } res = append(res, cpk) @@ -404,21 +404,21 @@ func FindCompositePrimaryKeysByZYError(ctx context.Context, db YODB, e int64) ([ return res, nil } -// ReadCompositePrimaryKeysByZYError retrieves multiples rows from 'CompositePrimaryKeys' by KeySet as a slice. +// ReadCompositePrimaryKeysByYZError retrieves multiples rows from 'CompositePrimaryKeys' by KeySet as a slice. // // This does not retrieve all columns of 'CompositePrimaryKeys' because an index has only columns // used for primary key, index key and storing columns. If you need more columns, add storing // columns or Read by primary key or Query with join. // // Generated from unique index 'CompositePrimaryKeysByError3'. -func ReadCompositePrimaryKeysByZYError(ctx context.Context, db YODB, keys spanner.KeySet) ([]*CompositePrimaryKey, error) { +func ReadCompositePrimaryKeysByYZError(ctx context.Context, db YODB, keys spanner.KeySet) ([]*CompositePrimaryKey, error) { var res []*CompositePrimaryKey columns := []string{ "PKey1", "PKey2", "Error", - "Z", "Y", + "Z", } decoder := newCompositePrimaryKey_Decoder(columns) @@ -434,7 +434,7 @@ func ReadCompositePrimaryKeysByZYError(ctx context.Context, db YODB, keys spanne return nil }) if err != nil { - return nil, newErrorWithCode(codes.Internal, "ReadCompositePrimaryKeysByZYError", "CompositePrimaryKeys", err) + return nil, newErrorWithCode(codes.Internal, "ReadCompositePrimaryKeysByYZError", "CompositePrimaryKeys", err) } return res, nil diff --git a/v2/test/testmodels/legacy_default/custom_composite_primary_key.yo.go b/v2/test/testmodels/legacy_default/custom_composite_primary_key.yo.go index 6a2932aa..a3272344 100644 --- a/v2/test/testmodels/legacy_default/custom_composite_primary_key.yo.go +++ b/v2/test/testmodels/legacy_default/custom_composite_primary_key.yo.go @@ -363,10 +363,10 @@ func ReadCustomCompositePrimaryKeysByZError(ctx context.Context, db YODB, keys s return res, nil } -// FindCustomCompositePrimaryKeysByZYError retrieves multiple rows from 'CustomCompositePrimaryKeys' as a slice of CustomCompositePrimaryKey. +// FindCustomCompositePrimaryKeysByYZError retrieves multiple rows from 'CustomCompositePrimaryKeys' as a slice of CustomCompositePrimaryKey. // // Generated from index 'CustomCompositePrimaryKeysByError3'. -func FindCustomCompositePrimaryKeysByZYError(ctx context.Context, db YODB, e int8) ([]*CustomCompositePrimaryKey, error) { +func FindCustomCompositePrimaryKeysByYZError(ctx context.Context, db YODB, e int8) ([]*CustomCompositePrimaryKey, error) { const sqlstr = "SELECT " + "Id, PKey1, PKey2, Error, X, Y, Z " + "FROM CustomCompositePrimaryKeys@{FORCE_INDEX=CustomCompositePrimaryKeysByError3} " + @@ -390,12 +390,12 @@ func FindCustomCompositePrimaryKeysByZYError(ctx context.Context, db YODB, e int if err == iterator.Done { break } - return nil, newError("FindCustomCompositePrimaryKeysByZYError", "CustomCompositePrimaryKeys", err) + return nil, newError("FindCustomCompositePrimaryKeysByYZError", "CustomCompositePrimaryKeys", err) } ccpk, err := decoder(row) if err != nil { - return nil, newErrorWithCode(codes.Internal, "FindCustomCompositePrimaryKeysByZYError", "CustomCompositePrimaryKeys", err) + return nil, newErrorWithCode(codes.Internal, "FindCustomCompositePrimaryKeysByYZError", "CustomCompositePrimaryKeys", err) } res = append(res, ccpk) @@ -404,21 +404,21 @@ func FindCustomCompositePrimaryKeysByZYError(ctx context.Context, db YODB, e int return res, nil } -// ReadCustomCompositePrimaryKeysByZYError retrieves multiples rows from 'CustomCompositePrimaryKeys' by KeySet as a slice. +// ReadCustomCompositePrimaryKeysByYZError retrieves multiples rows from 'CustomCompositePrimaryKeys' by KeySet as a slice. // // This does not retrieve all columns of 'CustomCompositePrimaryKeys' because an index has only columns // used for primary key, index key and storing columns. If you need more columns, add storing // columns or Read by primary key or Query with join. // // Generated from unique index 'CustomCompositePrimaryKeysByError3'. -func ReadCustomCompositePrimaryKeysByZYError(ctx context.Context, db YODB, keys spanner.KeySet) ([]*CustomCompositePrimaryKey, error) { +func ReadCustomCompositePrimaryKeysByYZError(ctx context.Context, db YODB, keys spanner.KeySet) ([]*CustomCompositePrimaryKey, error) { var res []*CustomCompositePrimaryKey columns := []string{ "PKey1", "PKey2", "Error", - "Z", "Y", + "Z", } decoder := newCustomCompositePrimaryKey_Decoder(columns) @@ -434,7 +434,7 @@ func ReadCustomCompositePrimaryKeysByZYError(ctx context.Context, db YODB, keys return nil }) if err != nil { - return nil, newErrorWithCode(codes.Internal, "ReadCustomCompositePrimaryKeysByZYError", "CustomCompositePrimaryKeys", err) + return nil, newErrorWithCode(codes.Internal, "ReadCustomCompositePrimaryKeysByYZError", "CustomCompositePrimaryKeys", err) } return res, nil diff --git a/v2/test/testmodels/legacy_default/full_text_search.yo.go b/v2/test/testmodels/legacy_default/full_text_search.yo.go new file mode 100644 index 00000000..2455bbc1 --- /dev/null +++ b/v2/test/testmodels/legacy_default/full_text_search.yo.go @@ -0,0 +1,176 @@ +// Code generated by yo. DO NOT EDIT. + +// Package models contains the types. +package models + +import ( + "context" + "fmt" + + "cloud.google.com/go/spanner" + "google.golang.org/grpc/codes" +) + +// FullTextSearch represents a row from 'FullTextSearch'. +type FullTextSearch struct { + ID int64 `spanner:"ID" json:"ID"` // ID + Content string `spanner:"Content" json:"Content"` // Content +} + +func FullTextSearchPrimaryKeys() []string { + return []string{ + "ID", + } +} + +func FullTextSearchColumns() []string { + return []string{ + "ID", + "Content", + } +} + +func FullTextSearchWritableColumns() []string { + return []string{ + "ID", + "Content", + } +} + +func (fts *FullTextSearch) columnsToPtrs(cols []string) ([]interface{}, error) { + ret := make([]interface{}, 0, len(cols)) + for _, col := range cols { + switch col { + case "ID": + ret = append(ret, yoDecode(&fts.ID)) + case "Content": + ret = append(ret, yoDecode(&fts.Content)) + default: + return nil, fmt.Errorf("unknown column: %s", col) + } + } + return ret, nil +} + +func (fts *FullTextSearch) columnsToValues(cols []string) ([]interface{}, error) { + ret := make([]interface{}, 0, len(cols)) + for _, col := range cols { + switch col { + case "ID": + ret = append(ret, yoEncode(fts.ID)) + case "Content": + ret = append(ret, yoEncode(fts.Content)) + default: + return nil, fmt.Errorf("unknown column: %s", col) + } + } + + return ret, nil +} + +// newFullTextSearch_Decoder returns a decoder which reads a row from *spanner.Row +// into FullTextSearch. The decoder is not goroutine-safe. Don't use it concurrently. +func newFullTextSearch_Decoder(cols []string) func(*spanner.Row) (*FullTextSearch, error) { + return func(row *spanner.Row) (*FullTextSearch, error) { + var fts FullTextSearch + ptrs, err := fts.columnsToPtrs(cols) + if err != nil { + return nil, err + } + + if err := row.Columns(ptrs...); err != nil { + return nil, err + } + + return &fts, nil + } +} + +// Insert returns a Mutation to insert a row into a table. If the row already +// exists, the write or transaction fails. +func (fts *FullTextSearch) Insert(ctx context.Context) *spanner.Mutation { + values, _ := fts.columnsToValues(FullTextSearchWritableColumns()) + return spanner.Insert("FullTextSearch", FullTextSearchWritableColumns(), values) +} + +// Update returns a Mutation to update a row in a table. If the row does not +// already exist, the write or transaction fails. +func (fts *FullTextSearch) Update(ctx context.Context) *spanner.Mutation { + values, _ := fts.columnsToValues(FullTextSearchWritableColumns()) + return spanner.Update("FullTextSearch", FullTextSearchWritableColumns(), values) +} + +// InsertOrUpdate returns a Mutation to insert a row into a table. If the row +// already exists, it updates it instead. Any column values not explicitly +// written are preserved. +func (fts *FullTextSearch) InsertOrUpdate(ctx context.Context) *spanner.Mutation { + values, _ := fts.columnsToValues(FullTextSearchWritableColumns()) + return spanner.InsertOrUpdate("FullTextSearch", FullTextSearchWritableColumns(), values) +} + +// Replace returns a Mutation to insert a row into a table, deleting any +// existing row. Unlike InsertOrUpdate, this means any values not explicitly +// written become NULL. +func (fts *FullTextSearch) Replace(ctx context.Context) *spanner.Mutation { + values, _ := fts.columnsToValues(FullTextSearchWritableColumns()) + return spanner.Replace("FullTextSearch", FullTextSearchWritableColumns(), values) +} + +// UpdateColumns returns a Mutation to update specified columns of a row in a table. +func (fts *FullTextSearch) UpdateColumns(ctx context.Context, cols ...string) (*spanner.Mutation, error) { + // add primary keys to columns to update by primary keys + colsWithPKeys := append(cols, FullTextSearchPrimaryKeys()...) + + values, err := fts.columnsToValues(colsWithPKeys) + if err != nil { + return nil, newErrorWithCode(codes.InvalidArgument, "FullTextSearch.UpdateColumns", "FullTextSearch", err) + } + + return spanner.Update("FullTextSearch", colsWithPKeys, values), nil +} + +// FindFullTextSearch gets a FullTextSearch by primary key +func FindFullTextSearch(ctx context.Context, db YODB, id int64) (*FullTextSearch, error) { + _key := spanner.Key{yoEncode(id)} + row, err := db.ReadRow(ctx, "FullTextSearch", _key, FullTextSearchColumns()) + if err != nil { + return nil, newError("FindFullTextSearch", "FullTextSearch", err) + } + + decoder := newFullTextSearch_Decoder(FullTextSearchColumns()) + fts, err := decoder(row) + if err != nil { + return nil, newErrorWithCode(codes.Internal, "FindFullTextSearch", "FullTextSearch", err) + } + + return fts, nil +} + +// ReadFullTextSearch retrieves multiples rows from FullTextSearch by KeySet as a slice. +func ReadFullTextSearch(ctx context.Context, db YODB, keys spanner.KeySet) ([]*FullTextSearch, error) { + var res []*FullTextSearch + + decoder := newFullTextSearch_Decoder(FullTextSearchColumns()) + + rows := db.Read(ctx, "FullTextSearch", keys, FullTextSearchColumns()) + err := rows.Do(func(row *spanner.Row) error { + fts, err := decoder(row) + if err != nil { + return err + } + res = append(res, fts) + + return nil + }) + if err != nil { + return nil, newErrorWithCode(codes.Internal, "ReadFullTextSearch", "FullTextSearch", err) + } + + return res, nil +} + +// Delete deletes the FullTextSearch from the database. +func (fts *FullTextSearch) Delete(ctx context.Context) *spanner.Mutation { + values, _ := fts.columnsToValues(FullTextSearchPrimaryKeys()) + return spanner.Delete("FullTextSearch", spanner.Key(values)) +}