Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions enginetest/mysqlshim/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func (d Database) GetTableNames(ctx *sql.Context) ([]string, error) {
}

// CreateTable implements the interface sql.TableCreator.
func (d Database) CreateTable(ctx *sql.Context, name string, schema sql.PrimaryKeySchema, collation sql.CollationID) error {
func (d Database) CreateTable(ctx *sql.Context, name string, schema sql.PrimaryKeySchema, collation sql.CollationID, comment string) error {
colStmts := make([]string, len(schema.Schema))
var primaryKeyCols []string
for i, col := range schema.Schema {
Expand All @@ -103,8 +103,8 @@ func (d Database) CreateTable(ctx *sql.Context, name string, schema sql.PrimaryK
primaryKey := fmt.Sprintf(" PRIMARY KEY (`%s`)", strings.Join(primaryKeyCols, "`,`"))
colStmts = append(colStmts, primaryKey)
}
return d.shim.Exec(d.name, fmt.Sprintf("CREATE TABLE `%s` (\n%s\n) ENGINE=InnoDB DEFAULT COLLATE=%s;",
name, strings.Join(colStmts, ",\n"), sql.Collation_Default.String()))
return d.shim.Exec(d.name, fmt.Sprintf("CREATE TABLE `%s` (\n%s\n) ENGINE=InnoDB DEFAULT COLLATE=%s COMMENT='%s';",
name, strings.Join(colStmts, ",\n"), sql.Collation_Default.String(), comment))
}

// DropTable implements the interface sql.TableDropper.
Expand Down
2 changes: 1 addition & 1 deletion enginetest/mysqlshim/mysql_harness.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ func (m *MySQLHarness) Provider() sql.MutableDatabaseProvider {
// NewTable implements the interface Harness.
func (m *MySQLHarness) NewTable(db sql.Database, name string, schema sql.PrimaryKeySchema) (sql.Table, error) {
ctx := sql.NewEmptyContext()
err := db.(sql.TableCreator).CreateTable(ctx, name, schema, sql.Collation_Default)
err := db.(sql.TableCreator).CreateTable(ctx, name, schema, sql.Collation_Default, "")
if err != nil {
return nil, err
}
Expand Down
30 changes: 30 additions & 0 deletions enginetest/queries/create_table_queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,24 @@ import (
)

var CreateTableQueries = []WriteQueryTest{
{
WriteQuery: `create table tableWithComment (pk int) COMMENT 'Table Comments Work!'`,
Comment thread
fulghum marked this conversation as resolved.
ExpectedWriteResult: []sql.Row{{types.NewOkResult(0)}},
SelectQuery: "SHOW CREATE TABLE tableWithComment",
ExpectedSelect: []sql.Row{{"tableWithComment", "CREATE TABLE `tableWithComment` (\n `pk` int\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin COMMENT='Table Comments Work!'"}},
},
{
WriteQuery: `create table tableWithComment (pk int) COMMENT='Table Comments=Still Work'`,
ExpectedWriteResult: []sql.Row{{types.NewOkResult(0)}},
SelectQuery: "SHOW CREATE TABLE tableWithComment",
ExpectedSelect: []sql.Row{{"tableWithComment", "CREATE TABLE `tableWithComment` (\n `pk` int\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin COMMENT='Table Comments=Still Work'"}},
},
{
WriteQuery: `create table tableWithComment (pk int) COMMENT "~!@ #$ %^ &* ()"`,
ExpectedWriteResult: []sql.Row{{types.NewOkResult(0)}},
SelectQuery: "SHOW CREATE TABLE tableWithComment",
ExpectedSelect: []sql.Row{{"tableWithComment", "CREATE TABLE `tableWithComment` (\n `pk` int\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin COMMENT='~!@ #$ %^ &* ()'"}},
},
{
WriteQuery: `create table floattypedefs (a float(10), b float(10, 2), c double(10, 2))`,
ExpectedWriteResult: []sql.Row{{types.NewOkResult(0)}},
Expand Down Expand Up @@ -647,6 +665,18 @@ var CreateTableAutoIncrementTests = []ScriptTest{
}

var BrokenCreateTableQueries = []WriteQueryTest{
{
// TODO: We don't support table comments that contain single quotes due to how table options are parsed.
// Vitess parses them, but turns any double quotes into single quotes and puts all table options back
// into a string that GMS has to reparse. This means we can't tell if the single quote is the end of
// the quoted string, or if it was a single quote inside of double quotes and needs to be escaped.
// To fix this, Vitess should return the parsed table options as structured data, instead of as a
// single string.
WriteQuery: `create table tableWithComment (pk int) COMMENT "'"`,
ExpectedWriteResult: []sql.Row{{types.NewOkResult(0)}},
SelectQuery: "SHOW CREATE TABLE tableWithComment",
ExpectedSelect: []sql.Row{{"tableWithComment", "CREATE TABLE `tableWithComment` (\n `pk` int\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin COMMENT=''''"}},
},
{
WriteQuery: `create table t1 (b blob, primary key(b(1)))`,
ExpectedWriteResult: []sql.Row{{types.NewOkResult(0)}},
Expand Down
3 changes: 2 additions & 1 deletion memory/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,14 +228,15 @@ func (d *BaseDatabase) AddTable(name string, t MemTable) {
}

// CreateTable creates a table with the given name and schema
func (d *BaseDatabase) CreateTable(ctx *sql.Context, name string, schema sql.PrimaryKeySchema, collation sql.CollationID) error {
func (d *BaseDatabase) CreateTable(ctx *sql.Context, name string, schema sql.PrimaryKeySchema, collation sql.CollationID, comment string) error {
_, ok := d.tables[name]
if ok {
return sql.ErrTableAlreadyExists.New(name)
}

table := NewTableWithCollation(d, name, schema, d.fkColl, collation)
table.db = d
table.data.comment = comment
if d.primaryKeyIndexes {
table.EnablePrimaryKeyIndexes()
}
Expand Down
4 changes: 2 additions & 2 deletions memory/database_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func TestDatabase_AddTable(t *testing.T) {
pro := memory.NewDBProvider(db)
ctx := newContext(pro)

err := db.CreateTable(ctx, "test_table", sql.PrimaryKeySchema{}, sql.Collation_Default)
err := db.CreateTable(ctx, "test_table", sql.PrimaryKeySchema{}, sql.Collation_Default, "")
require.NoError(err)

tables = db.Tables()
Expand All @@ -46,6 +46,6 @@ func TestDatabase_AddTable(t *testing.T) {
require.True(ok)
require.NotNil(tt)

err = db.CreateTable(ctx, "test_table", sql.PrimaryKeySchema{}, sql.Collation_Default)
err = db.CreateTable(ctx, "test_table", sql.PrimaryKeySchema{}, sql.Collation_Default, "")
require.Error(err)
}
22 changes: 15 additions & 7 deletions memory/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ var _ MemTable = (*Table)(nil)
var _ sql.InsertableTable = (*Table)(nil)
var _ sql.UpdatableTable = (*Table)(nil)
var _ sql.DeletableTable = (*Table)(nil)
var _ sql.CommentedTable = (*Table)(nil)
var _ sql.ReplaceableTable = (*Table)(nil)
var _ sql.TruncateableTable = (*Table)(nil)
var _ sql.AlterableTable = (*Table)(nil)
Expand All @@ -91,7 +92,7 @@ func NewTable(db MemoryDatabase, name string, schema sql.PrimaryKeySchema, fkCol
if db != nil {
baseDatabase = db.Database()
}
return NewPartitionedTableWithCollation(baseDatabase, name, schema, fkColl, 0, sql.Collation_Default)
return NewPartitionedTableWithCollation(baseDatabase, name, schema, fkColl, 0, sql.Collation_Default, "")
}

// NewLocalTable returns a table suitable to use for transient non-memory applications
Expand All @@ -101,26 +102,26 @@ func NewLocalTable(db MemoryDatabase, name string, schema sql.PrimaryKeySchema,
if db != nil {
baseDatabase = db.Database()
}
tbl := NewPartitionedTableWithCollation(baseDatabase, name, schema, fkColl, 0, sql.Collation_Default)
tbl := NewPartitionedTableWithCollation(baseDatabase, name, schema, fkColl, 0, sql.Collation_Default, "")
tbl.ignoreSessionData = true
return tbl
}

// NewTableWithCollation creates a new Table with the given name, schema, and collation.
func NewTableWithCollation(db *BaseDatabase, name string, schema sql.PrimaryKeySchema, fkColl *ForeignKeyCollection, collation sql.CollationID) *Table {
return NewPartitionedTableWithCollation(db, name, schema, fkColl, 0, collation)
return NewPartitionedTableWithCollation(db, name, schema, fkColl, 0, collation, "")
}

// NewPartitionedTable creates a new Table with the given name, schema and number of partitions. Assigns the default
// collation, therefore if a different collation is desired, please use NewPartitionedTableWithCollation.
func NewPartitionedTable(db *BaseDatabase, name string, schema sql.PrimaryKeySchema, fkColl *ForeignKeyCollection, numPartitions int) *Table {
return NewPartitionedTableWithCollation(db, name, schema, fkColl, numPartitions, sql.Collation_Default)
return NewPartitionedTableWithCollation(db, name, schema, fkColl, numPartitions, sql.Collation_Default, "")
}

// NewPartitionedTable creates a new Table with the given name, schema and number of partitions. Assigns the default
// collation, therefore if a different collation is desired, please use NewPartitionedTableWithCollation.
func NewPartitionedTableRevision(db *BaseDatabase, name string, schema sql.PrimaryKeySchema, fkColl *ForeignKeyCollection, numPartitions int) *TableRevision {
tbl := NewPartitionedTableWithCollation(db, name, schema, fkColl, numPartitions, sql.Collation_Default)
tbl := NewPartitionedTableWithCollation(db, name, schema, fkColl, numPartitions, sql.Collation_Default, "")
tbl.ignoreSessionData = true
return &TableRevision{tbl}
}
Expand All @@ -137,8 +138,9 @@ func stripTblNames(e sql.Expression) (sql.Expression, transform.TreeIdentity, er
return e, transform.SameTree, nil
}

// NewPartitionedTableWithCollation creates a new Table with the given name, schema, number of partitions, and collation.
func NewPartitionedTableWithCollation(db *BaseDatabase, name string, schema sql.PrimaryKeySchema, fkColl *ForeignKeyCollection, numPartitions int, collation sql.CollationID) *Table {
// NewPartitionedTableWithCollation creates a new Table with the given name, schema, number of partitions, collation,
// and comment.
func NewPartitionedTableWithCollation(db *BaseDatabase, name string, schema sql.PrimaryKeySchema, fkColl *ForeignKeyCollection, numPartitions int, collation sql.CollationID, comment string) *Table {
var keys [][]byte
var partitions = map[string][]sql.Row{}

Expand Down Expand Up @@ -198,6 +200,7 @@ func NewPartitionedTableWithCollation(db *BaseDatabase, name string, schema sql.
data: &TableData{
dbName: dbName,
tableName: name,
comment: comment,
schema: schema,
fkColl: fkColl,
collation: collation,
Expand Down Expand Up @@ -233,6 +236,11 @@ func (t *Table) Collation() sql.CollationID {
return t.data.collation
}

// Comment implements the sql.CommentedTable interface.
func (t Table) Comment() string {
return t.data.comment
}

func (t Table) IgnoreSessionData() bool {
return t.ignoreSessionData
}
Expand Down
1 change: 1 addition & 0 deletions memory/table_data.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
type TableData struct {
dbName string
tableName string
comment string

// Schema / config data
schema sql.PrimaryKeySchema
Expand Down
5 changes: 5 additions & 0 deletions memory/table_editor.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ type tableEditor struct {
}

var _ sql.Table = (*tableEditor)(nil)
var _ sql.CommentedTable = (*tableEditor)(nil)
var _ sql.RowReplacer = (*tableEditor)(nil)
var _ sql.RowUpdater = (*tableEditor)(nil)
var _ sql.RowInserter = (*tableEditor)(nil)
Expand All @@ -63,6 +64,10 @@ func (t *tableEditor) Collation() sql.CollationID {
return t.editedTable.Collation()
}

func (t *tableEditor) Comment() string {
return t.editedTable.Comment()
}

func (t *tableEditor) Partitions(ctx *sql.Context) (sql.PartitionIter, error) {
return t.editedTable.Partitions(ctx)
}
Expand Down
7 changes: 7 additions & 0 deletions sql/analyzer/costed_index_scan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -883,6 +883,13 @@ func (i *indexSearchableTable) Collation() sql.CollationID {
return i.underlying.Collation()
}

func (i *indexSearchableTable) Comment() string {
if ct, ok := i.underlying.(sql.CommentedTable); ok {
return ct.Comment()
}
return ""
}

func (i *indexSearchableTable) Partitions(context *sql.Context) (sql.PartitionIter, error) {
//TODO implement me
panic("implement me")
Expand Down
7 changes: 5 additions & 2 deletions sql/databases.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,11 @@ type ReadOnlyDatabase interface {
// TableCreator is a Database that can create new tables.
type TableCreator interface {
Database
// CreateTable creates the table with the given name and schema.
CreateTable(ctx *Context, name string, schema PrimaryKeySchema, collation CollationID) error
// CreateTable creates the table with the given name, schema, collation, and comment. Integrators are
// responsible for persisting all provided table metadata. Comment may be optionally persisted, and if
// so, sql.Table implementations should also implement sql.CommentedTable so that the comment may be
// retrieved.
CreateTable(ctx *Context, name string, schema PrimaryKeySchema, collation CollationID, comment string) error
}

// IndexedTableCreator is a Database that can create new tables which have a Primary Key with columns that have
Expand Down
10 changes: 5 additions & 5 deletions sql/fulltext/fulltext.go
Original file line number Diff line number Diff line change
Expand Up @@ -609,7 +609,7 @@ func CreateFulltextIndexes(ctx *sql.Context, database Database, parent sql.Table
if err != nil {
return err
}
err = database.CreateTable(ctx, tableNames.Config, sql.NewPrimaryKeySchema(configSch), sql.Collation_Default)
err = database.CreateTable(ctx, tableNames.Config, sql.NewPrimaryKeySchema(configSch), sql.Collation_Default, "")
if err != nil {
return err
}
Expand All @@ -620,31 +620,31 @@ func CreateFulltextIndexes(ctx *sql.Context, database Database, parent sql.Table
if err != nil {
return err
}
err = database.CreateTable(ctx, tableNames.Position, sql.NewPrimaryKeySchema(positionSch), sql.Collation_Default)
err = database.CreateTable(ctx, tableNames.Position, sql.NewPrimaryKeySchema(positionSch), sql.Collation_Default, "")
if err != nil {
return err
}
docCountSch, err := NewSchema(SchemaDocCount, insertCols, tableNames.DocCount, collation)
if err != nil {
return err
}
err = database.CreateTable(ctx, tableNames.DocCount, sql.NewPrimaryKeySchema(docCountSch), sql.Collation_Default)
err = database.CreateTable(ctx, tableNames.DocCount, sql.NewPrimaryKeySchema(docCountSch), sql.Collation_Default, "")
if err != nil {
return err
}
globalCountSch, err := NewSchema(SchemaGlobalCount, nil, tableNames.GlobalCount, collation)
if err != nil {
return err
}
err = database.CreateTable(ctx, tableNames.GlobalCount, sql.NewPrimaryKeySchema(globalCountSch), sql.Collation_Default)
err = database.CreateTable(ctx, tableNames.GlobalCount, sql.NewPrimaryKeySchema(globalCountSch), sql.Collation_Default, "")
if err != nil {
return err
}
rowCountSch, err := NewSchema(SchemaRowCount, nil, tableNames.RowCount, collation)
if err != nil {
return err
}
err = database.CreateTable(ctx, tableNames.RowCount, sql.NewPrimaryKeySchema(rowCountSch), sql.Collation_Default)
err = database.CreateTable(ctx, tableNames.RowCount, sql.NewPrimaryKeySchema(rowCountSch), sql.Collation_Default, "")
if err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions sql/mysql_db/privileged_database_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -287,9 +287,9 @@ func (pdb PrivilegedDatabase) GetTableNamesAsOf(ctx *sql.Context, asOf interface
}

// CreateTable implements the interface sql.TableCreator.
func (pdb PrivilegedDatabase) CreateTable(ctx *sql.Context, name string, schema sql.PrimaryKeySchema, collation sql.CollationID) error {
func (pdb PrivilegedDatabase) CreateTable(ctx *sql.Context, name string, schema sql.PrimaryKeySchema, collation sql.CollationID, comment string) error {
if db, ok := pdb.db.(sql.TableCreator); ok {
return db.CreateTable(ctx, name, schema, collation)
return db.CreateTable(ctx, name, schema, collation, comment)
}
return sql.ErrCreateTableNotSupported.New(pdb.db.Name())
}
Expand Down
4 changes: 4 additions & 0 deletions sql/plan/ddl.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ type TableSpec struct {
ChDefs []*sql.CheckConstraint
IdxDefs []*IndexDefinition
Collation sql.CollationID
Comment string
}

func (c *TableSpec) WithSchema(schema sql.PrimaryKeySchema) *TableSpec {
Expand Down Expand Up @@ -153,6 +154,7 @@ type CreateTable struct {
checks sql.CheckConstraints
IdxDefs []*IndexDefinition
Collation sql.CollationID
Comment string
like sql.Node
temporary TempTableOption
selectNode sql.Node
Expand All @@ -179,6 +181,7 @@ func NewCreateTable(db sql.Database, name string, ifn IfNotExistsOption, temp Te
checks: tableSpec.ChDefs,
IdxDefs: tableSpec.IdxDefs,
Collation: tableSpec.Collation,
Comment: tableSpec.Comment,
ifNotExists: ifn,
temporary: temp,
}
Expand Down Expand Up @@ -494,6 +497,7 @@ func (c *CreateTable) TableSpec() *TableSpec {
ret = ret.WithIndices(c.IdxDefs)
ret = ret.WithCheckConstraints(c.checks)
ret.Collation = c.Collation
ret.Comment = c.Comment

return ret
}
Expand Down
2 changes: 1 addition & 1 deletion sql/plan/dummy_resolved_db.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func (d *DummyResolvedDB) GetTableNames(ctx *sql.Context) ([]string, error) { re

func (d *DummyResolvedDB) AddTable(name string, t sql.Table) {}

func (d *DummyResolvedDB) CreateTable(ctx *sql.Context, name string, schema sql.PrimaryKeySchema, collation sql.CollationID) error {
func (d *DummyResolvedDB) CreateTable(ctx *sql.Context, name string, schema sql.PrimaryKeySchema, collation sql.CollationID, comment string) error {
return nil
}

Expand Down
7 changes: 7 additions & 0 deletions sql/plan/indexed_table_access.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,13 @@ func (i *IndexedTableAccess) Collation() sql.CollationID {
return i.TableNode.Collation()
}

func (i *IndexedTableAccess) Comment() string {
if ct, ok := i.Table.(sql.CommentedTable); ok {
return ct.Comment()
}
return ""
}

func (i *IndexedTableAccess) Children() []sql.Node {
return nil
}
Expand Down
5 changes: 5 additions & 0 deletions sql/plan/procedure_resolved_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ func (t *ProcedureResolvedTable) Collation() sql.CollationID {
return t.ResolvedTable.Collation()
}

// Comment implements the sql.CommentedTable interface.
func (t *ProcedureResolvedTable) Comment() string {
return t.ResolvedTable.Comment()
}

// DebugString implements the sql.DebugStringer interface.
func (t *ProcedureResolvedTable) DebugString() string {
return sql.DebugString(t.ResolvedTable)
Expand Down
10 changes: 10 additions & 0 deletions sql/plan/process.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,8 @@ type ProcessTable struct {
OnRowNext NamedNotifyFunc
}

var _ sql.CommentedTable = (*ProcessTable)(nil)

// NewProcessTable returns a new ProcessTable.
func NewProcessTable(t sql.Table, onPartitionDone, onPartitionStart, OnRowNext NamedNotifyFunc) *ProcessTable {
return &ProcessTable{t, onPartitionDone, onPartitionStart, OnRowNext}
Expand All @@ -210,6 +212,14 @@ func (t *ProcessTable) Underlying() sql.Table {
return t.Table
}

// Comment implements sql.CommentedTable interface.
func (t *ProcessTable) Comment() string {
if ct, ok := t.Table.(sql.CommentedTable); ok {
return ct.Comment()
}
return ""
}

// PartitionRows implements the sql.Table interface.
func (t *ProcessTable) PartitionRows(ctx *sql.Context, p sql.Partition) (sql.RowIter, error) {
iter, err := t.Table.PartitionRows(ctx, p)
Expand Down
Loading