From 3da3c8d037d06949d177774e4586a97cdce00ca7 Mon Sep 17 00:00:00 2001 From: Daylon Wilkins Date: Wed, 2 Sep 2020 03:47:58 -0700 Subject: [PATCH] Added new column defaults --- bats/default-values.bats | 423 ++++++++++++++++++ go/cmd/dolt/commands/query_diff.go | 3 +- go/cmd/dolt/commands/sql.go | 6 +- go/cmd/dolt/commands/sqlserver/server.go | 3 +- go/go.mod | 4 +- go/go.sum | 6 + .../doltcore/diff/querydiff/query_differ.go | 3 +- .../doltcore/envtestutils/rebase_tag_test.go | 5 +- .../doltcore/merge/merge_schema_test.go | 2 +- go/libraries/doltcore/mvdata/data_mover.go | 5 +- go/libraries/doltcore/rowconv/joiner.go | 2 +- .../doltcore/rowconv/row_converter_test.go | 4 +- .../doltcore/schema/alterschema/addcolumn.go | 61 ++- .../schema/alterschema/addcolumn_test.go | 70 ++- .../schema/alterschema/modifycolumn.go | 9 +- .../schema/alterschema/modifycolumn_test.go | 10 +- go/libraries/doltcore/schema/col_coll_test.go | 30 +- go/libraries/doltcore/schema/column.go | 9 +- .../schema/encoding/schema_marshaling.go | 5 +- .../schema/encoding/schema_marshaling_test.go | 9 +- go/libraries/doltcore/schema/schema_test.go | 14 +- .../doltcore/schema/super_schema_test.go | 4 +- go/libraries/doltcore/sql/sqltestutil/data.go | 2 +- go/libraries/doltcore/sqle/common_test.go | 9 +- .../doltcore/sqle/conflicts_tables.go | 8 +- go/libraries/doltcore/sqle/database.go | 5 +- go/libraries/doltcore/sqle/diff_table.go | 12 +- .../sqle/enginetest/dolt_engine_test.go | 4 + go/libraries/doltcore/sqle/history_table.go | 3 +- .../doltcore/sqle/{ => schema}/schema.go | 131 ++++-- go/libraries/doltcore/sqle/sqlddl_test.go | 45 +- go/libraries/doltcore/sqle/sqlinsert_test.go | 3 +- go/libraries/doltcore/sqle/tables.go | 37 +- mysql-client-tests/node/index.js | 11 +- .../python/mysql.connector-test.py | 4 +- 35 files changed, 710 insertions(+), 251 deletions(-) create mode 100644 bats/default-values.bats rename go/libraries/doltcore/sqle/{ => schema}/schema.go (57%) diff --git a/bats/default-values.bats b/bats/default-values.bats new file mode 100644 index 0000000000..238de6bf00 --- /dev/null +++ b/bats/default-values.bats @@ -0,0 +1,423 @@ +#!/usr/bin/env bats +load $BATS_TEST_DIRNAME/helper/common.bash + +setup() { + setup_common + + dolt sql < 0 { - return errors.New("When adding a column that may not be null to a table with existing rows, a default value must be provided.") - } - } - - if !types.IsNull(defaultVal) && !typeInfo.IsValid(defaultVal) { - return fmt.Errorf("Default value (%v) is invalid for column (%v)", defaultVal, typeInfo.String()) - } - return nil } diff --git a/go/libraries/doltcore/schema/alterschema/addcolumn_test.go b/go/libraries/doltcore/schema/alterschema/addcolumn_test.go index 58c0e9961c..c4583aab70 100644 --- a/go/libraries/doltcore/schema/alterschema/addcolumn_test.go +++ b/go/libraries/doltcore/schema/alterschema/addcolumn_test.go @@ -42,7 +42,7 @@ func TestAddColumnToTable(t *testing.T) { newColName string colKind types.NomsKind nullable Nullable - defaultVal types.Value + defaultVal string order *ColumnOrder expectedSchema schema.Schema expectedRows []row.Row @@ -114,9 +114,9 @@ func TestAddColumnToTable(t *testing.T) { newColName: "newCol", colKind: types.StringKind, nullable: NotNull, - defaultVal: types.String("default"), + defaultVal: `("default")`, expectedSchema: dtestutils.AddColumnToSchema(dtestutils.TypedSchema, - schema.NewColumn("newCol", dtestutils.NextTag, types.StringKind, false, schema.NotNullConstraint{})), + schemaNewColumn("newCol", dtestutils.NextTag, types.StringKind, false, `("default")`, schema.NotNullConstraint{})), expectedRows: dtestutils.AddColToRows(t, dtestutils.TypedRows, dtestutils.NextTag, types.String("default")), }, { @@ -125,9 +125,9 @@ func TestAddColumnToTable(t *testing.T) { newColName: "newCol", colKind: types.IntKind, nullable: NotNull, - defaultVal: types.Int(42), + defaultVal: "42", expectedSchema: dtestutils.AddColumnToSchema(dtestutils.TypedSchema, - schema.NewColumn("newCol", dtestutils.NextTag, types.IntKind, false, schema.NotNullConstraint{})), + schemaNewColumn("newCol", dtestutils.NextTag, types.IntKind, false, "42", schema.NotNullConstraint{})), expectedRows: dtestutils.AddColToRows(t, dtestutils.TypedRows, dtestutils.NextTag, types.Int(42)), }, { @@ -136,9 +136,9 @@ func TestAddColumnToTable(t *testing.T) { newColName: "newCol", colKind: types.UintKind, nullable: NotNull, - defaultVal: types.Uint(64), + defaultVal: "64", expectedSchema: dtestutils.AddColumnToSchema(dtestutils.TypedSchema, - schema.NewColumn("newCol", dtestutils.NextTag, types.UintKind, false, schema.NotNullConstraint{})), + schemaNewColumn("newCol", dtestutils.NextTag, types.UintKind, false, "64", schema.NotNullConstraint{})), expectedRows: dtestutils.AddColToRows(t, dtestutils.TypedRows, dtestutils.NextTag, types.Uint(64)), }, { @@ -147,9 +147,9 @@ func TestAddColumnToTable(t *testing.T) { newColName: "newCol", colKind: types.FloatKind, nullable: NotNull, - defaultVal: types.Float(33.33), + defaultVal: "33.33", expectedSchema: dtestutils.AddColumnToSchema(dtestutils.TypedSchema, - schema.NewColumn("newCol", dtestutils.NextTag, types.FloatKind, false, schema.NotNullConstraint{})), + schemaNewColumn("newCol", dtestutils.NextTag, types.FloatKind, false, "33.33", schema.NotNullConstraint{})), expectedRows: dtestutils.AddColToRows(t, dtestutils.TypedRows, dtestutils.NextTag, types.Float(33.33)), }, { @@ -158,9 +158,9 @@ func TestAddColumnToTable(t *testing.T) { newColName: "newCol", colKind: types.BoolKind, nullable: NotNull, - defaultVal: types.Bool(true), + defaultVal: "true", expectedSchema: dtestutils.AddColumnToSchema(dtestutils.TypedSchema, - schema.NewColumn("newCol", dtestutils.NextTag, types.BoolKind, false, schema.NotNullConstraint{})), + schemaNewColumn("newCol", dtestutils.NextTag, types.BoolKind, false, "true", schema.NotNullConstraint{})), expectedRows: dtestutils.AddColToRows(t, dtestutils.TypedRows, dtestutils.NextTag, types.Bool(true)), }, { @@ -169,9 +169,9 @@ func TestAddColumnToTable(t *testing.T) { newColName: "newCol", colKind: types.UUIDKind, nullable: NotNull, - defaultVal: types.UUID(uuid.MustParse("00000000-0000-0000-0000-000000000000")), + defaultVal: `"00000000-0000-0000-0000-000000000000"`, expectedSchema: dtestutils.AddColumnToSchema(dtestutils.TypedSchema, - schema.NewColumn("newCol", dtestutils.NextTag, types.UUIDKind, false, schema.NotNullConstraint{})), + schemaNewColumn("newCol", dtestutils.NextTag, types.UUIDKind, false, `"00000000-0000-0000-0000-000000000000"`, schema.NotNullConstraint{})), expectedRows: dtestutils.AddColToRows(t, dtestutils.TypedRows, dtestutils.NextTag, types.UUID(uuid.MustParse("00000000-0000-0000-0000-000000000000"))), }, @@ -181,9 +181,9 @@ func TestAddColumnToTable(t *testing.T) { newColName: "newCol", colKind: types.IntKind, nullable: Null, - defaultVal: nil, + defaultVal: "", expectedSchema: dtestutils.AddColumnToSchema(dtestutils.TypedSchema, - schema.NewColumn("newCol", dtestutils.NextTag, types.IntKind, false)), + schemaNewColumn("newCol", dtestutils.NextTag, types.IntKind, false, "")), expectedRows: dtestutils.TypedRows, }, { @@ -192,9 +192,9 @@ func TestAddColumnToTable(t *testing.T) { newColName: "newCol", colKind: types.IntKind, nullable: Null, - defaultVal: types.Int(42), + defaultVal: "42", expectedSchema: dtestutils.AddColumnToSchema(dtestutils.TypedSchema, - schema.NewColumn("newCol", dtestutils.NextTag, types.IntKind, false)), + schemaNewColumn("newCol", dtestutils.NextTag, types.IntKind, false, "42")), expectedRows: dtestutils.AddColToRows(t, dtestutils.TypedRows, dtestutils.NextTag, types.Int(42)), }, { @@ -203,10 +203,10 @@ func TestAddColumnToTable(t *testing.T) { newColName: "newCol", colKind: types.IntKind, nullable: Null, - defaultVal: types.Int(42), + defaultVal: "42", order: &ColumnOrder{First: true}, expectedSchema: dtestutils.CreateSchema( - schema.NewColumn("newCol", dtestutils.NextTag, types.IntKind, false), + schemaNewColumn("newCol", dtestutils.NextTag, types.IntKind, false, "42"), schema.NewColumn("id", dtestutils.IdTag, types.UUIDKind, true, schema.NotNullConstraint{}), schema.NewColumn("name", dtestutils.NameTag, types.StringKind, false, schema.NotNullConstraint{}), schema.NewColumn("age", dtestutils.AgeTag, types.UintKind, false, schema.NotNullConstraint{}), @@ -221,13 +221,13 @@ func TestAddColumnToTable(t *testing.T) { newColName: "newCol", colKind: types.IntKind, nullable: Null, - defaultVal: types.Int(42), + defaultVal: "42", order: &ColumnOrder{After: "age"}, expectedSchema: dtestutils.CreateSchema( schema.NewColumn("id", dtestutils.IdTag, types.UUIDKind, true, schema.NotNullConstraint{}), schema.NewColumn("name", dtestutils.NameTag, types.StringKind, false, schema.NotNullConstraint{}), schema.NewColumn("age", dtestutils.AgeTag, types.UintKind, false, schema.NotNullConstraint{}), - schema.NewColumn("newCol", dtestutils.NextTag, types.IntKind, false), + schemaNewColumn("newCol", dtestutils.NextTag, types.IntKind, false, "42"), schema.NewColumn("is_married", dtestutils.IsMarriedTag, types.BoolKind, false, schema.NotNullConstraint{}), schema.NewColumn("title", dtestutils.TitleTag, types.StringKind, false), ), @@ -239,7 +239,7 @@ func TestAddColumnToTable(t *testing.T) { newColName: "newCol", colKind: types.IntKind, nullable: NotNull, - defaultVal: nil, + defaultVal: "", expectedErr: fmt.Sprintf("Cannot create column newCol, the tag %d was already used in table people", dtestutils.AgeTag), }, { @@ -248,27 +248,9 @@ func TestAddColumnToTable(t *testing.T) { newColName: "age", colKind: types.IntKind, nullable: NotNull, - defaultVal: types.Int(10), + defaultVal: "10", expectedErr: "A column with the name age already exists", }, - { - name: "non-nullable with nil default", - tag: dtestutils.NextTag, - newColName: "newCol", - colKind: types.IntKind, - nullable: NotNull, - defaultVal: nil, - expectedErr: "default value must be provided", - }, - { - name: "wrong type for default value", - tag: dtestutils.NextTag, - newColName: "newCol", - colKind: types.IntKind, - nullable: NotNull, - defaultVal: types.String("this shouldn't work"), - expectedErr: "Default value (this shouldn't work) is invalid for column (Int64)", - }, } for _, tt := range tests { @@ -346,3 +328,9 @@ func createEnvWithSeedData(t *testing.T) *env.DoltEnv { return dEnv } + +func schemaNewColumn(name string, tag uint64, kind types.NomsKind, partOfPK bool, defaultVal string, constraints ...schema.ColConstraint) schema.Column { + col := schema.NewColumn(name, tag, kind, partOfPK, constraints...) + col.Default = defaultVal + return col +} diff --git a/go/libraries/doltcore/schema/alterschema/modifycolumn.go b/go/libraries/doltcore/schema/alterschema/modifycolumn.go index bd7bedfc4d..5c98a0d3cf 100644 --- a/go/libraries/doltcore/schema/alterschema/modifycolumn.go +++ b/go/libraries/doltcore/schema/alterschema/modifycolumn.go @@ -33,7 +33,6 @@ func ModifyColumn( tbl *doltdb.Table, existingCol schema.Column, newCol schema.Column, - defaultVal types.Value, order *ColumnOrder, ) (*doltdb.Table, error) { @@ -42,7 +41,7 @@ func ModifyColumn( return nil, err } - if err := validateModifyColumn(ctx, tbl, existingCol, newCol, defaultVal); err != nil { + if err := validateModifyColumn(ctx, tbl, existingCol, newCol); err != nil { return nil, err } @@ -79,7 +78,7 @@ func ModifyColumn( } // validateModifyColumn returns an error if the column as specified cannot be added to the schema given. -func validateModifyColumn(ctx context.Context, tbl *doltdb.Table, existingCol schema.Column, modifiedCol schema.Column, defaultVal types.Value) error { +func validateModifyColumn(ctx context.Context, tbl *doltdb.Table, existingCol schema.Column, modifiedCol schema.Column) error { sch, err := tbl.GetSchema(ctx) if err != nil { return err @@ -104,10 +103,6 @@ func validateModifyColumn(ctx context.Context, tbl *doltdb.Table, existingCol sc return err } - if !types.IsNull(defaultVal) && defaultVal.Kind() != modifiedCol.Kind { - return fmt.Errorf("Type of default value (%v) doesn't match type of column (%v)", types.KindToString[defaultVal.Kind()], types.KindToString[modifiedCol.Kind]) - } - return nil } diff --git a/go/libraries/doltcore/schema/alterschema/modifycolumn_test.go b/go/libraries/doltcore/schema/alterschema/modifycolumn_test.go index cd1baac05b..6f909286ec 100644 --- a/go/libraries/doltcore/schema/alterschema/modifycolumn_test.go +++ b/go/libraries/doltcore/schema/alterschema/modifycolumn_test.go @@ -32,7 +32,6 @@ func TestModifyColumn(t *testing.T) { name string existingColumn schema.Column newColumn schema.Column - defaultVal types.Value order *ColumnOrder expectedSchema schema.Schema expectedRows []row.Row @@ -104,13 +103,6 @@ func TestModifyColumn(t *testing.T) { newColumn: schema.NewColumn("name", dtestutils.IdTag, types.UUIDKind, true, schema.NotNullConstraint{}), expectedErr: "A column with the name name already exists", }, - { - name: "wrong type for default value", - existingColumn: schema.NewColumn("id", dtestutils.IdTag, types.UUIDKind, true, schema.NotNullConstraint{}), - newColumn: schema.NewColumn("newId", dtestutils.IdTag, types.UUIDKind, true, schema.NotNullConstraint{}), - defaultVal: types.String("not a string"), - expectedErr: "Type of default value (String) doesn't match type of column (UUID)", - }, { name: "type change", existingColumn: schema.NewColumn("id", dtestutils.IdTag, types.UUIDKind, true, schema.NotNullConstraint{}), @@ -129,7 +121,7 @@ func TestModifyColumn(t *testing.T) { tbl, _, err := root.GetTable(ctx, tableName) assert.NoError(t, err) - updatedTable, err := ModifyColumn(ctx, tbl, tt.existingColumn, tt.newColumn, tt.defaultVal, tt.order) + updatedTable, err := ModifyColumn(ctx, tbl, tt.existingColumn, tt.newColumn, tt.order) if len(tt.expectedErr) > 0 { require.Error(t, err) assert.Contains(t, err.Error(), tt.expectedErr) diff --git a/go/libraries/doltcore/schema/col_coll_test.go b/go/libraries/doltcore/schema/col_coll_test.go index 570a6ef944..6599641342 100644 --- a/go/libraries/doltcore/schema/col_coll_test.go +++ b/go/libraries/doltcore/schema/col_coll_test.go @@ -26,10 +26,10 @@ import ( "github.com/liquidata-inc/dolt/go/store/types" ) -var firstNameCol = Column{"first", 0, types.StringKind, false, typeinfo.StringDefaultType, nil} -var lastNameCol = Column{"last", 1, types.StringKind, false, typeinfo.StringDefaultType, nil} -var firstNameCapsCol = Column{"FiRsT", 2, types.StringKind, false, typeinfo.StringDefaultType, nil} -var lastNameCapsCol = Column{"LAST", 3, types.StringKind, false, typeinfo.StringDefaultType, nil} +var firstNameCol = Column{"first", 0, types.StringKind, false, typeinfo.StringDefaultType, "", nil} +var lastNameCol = Column{"last", 1, types.StringKind, false, typeinfo.StringDefaultType, "", nil} +var firstNameCapsCol = Column{"FiRsT", 2, types.StringKind, false, typeinfo.StringDefaultType, "", nil} +var lastNameCapsCol = Column{"LAST", 3, types.StringKind, false, typeinfo.StringDefaultType, "", nil} func TestGetByNameAndTag(t *testing.T) { cols := []Column{firstNameCol, lastNameCol, firstNameCapsCol, lastNameCapsCol} @@ -111,7 +111,7 @@ func TestNewColCollectionErrorHandling(t *testing.T) { }{ { name: "tag collision", - cols: []Column{firstNameCol, lastNameCol, {"collision", 0, types.StringKind, false, typeinfo.StringDefaultType, nil}}, + cols: []Column{firstNameCol, lastNameCol, {"collision", 0, types.StringKind, false, typeinfo.StringDefaultType, "", nil}}, expectedErr: ErrColTagCollision, }, } @@ -127,18 +127,18 @@ func TestNewColCollectionErrorHandling(t *testing.T) { func TestAppendAndItrInSortOrder(t *testing.T) { cols := []Column{ - {"0", 0, types.StringKind, false, typeinfo.StringDefaultType, nil}, - {"2", 2, types.StringKind, false, typeinfo.StringDefaultType, nil}, - {"4", 4, types.StringKind, false, typeinfo.StringDefaultType, nil}, - {"3", 3, types.StringKind, false, typeinfo.StringDefaultType, nil}, - {"1", 1, types.StringKind, false, typeinfo.StringDefaultType, nil}, + {"0", 0, types.StringKind, false, typeinfo.StringDefaultType, "", nil}, + {"2", 2, types.StringKind, false, typeinfo.StringDefaultType, "", nil}, + {"4", 4, types.StringKind, false, typeinfo.StringDefaultType, "", nil}, + {"3", 3, types.StringKind, false, typeinfo.StringDefaultType, "", nil}, + {"1", 1, types.StringKind, false, typeinfo.StringDefaultType, "", nil}, } cols2 := []Column{ - {"7", 7, types.StringKind, false, typeinfo.StringDefaultType, nil}, - {"9", 9, types.StringKind, false, typeinfo.StringDefaultType, nil}, - {"5", 5, types.StringKind, false, typeinfo.StringDefaultType, nil}, - {"8", 8, types.StringKind, false, typeinfo.StringDefaultType, nil}, - {"6", 6, types.StringKind, false, typeinfo.StringDefaultType, nil}, + {"7", 7, types.StringKind, false, typeinfo.StringDefaultType, "", nil}, + {"9", 9, types.StringKind, false, typeinfo.StringDefaultType, "", nil}, + {"5", 5, types.StringKind, false, typeinfo.StringDefaultType, "", nil}, + {"8", 8, types.StringKind, false, typeinfo.StringDefaultType, "", nil}, + {"6", 6, types.StringKind, false, typeinfo.StringDefaultType, "", nil}, } colColl, _ := NewColCollection(cols...) diff --git a/go/libraries/doltcore/schema/column.go b/go/libraries/doltcore/schema/column.go index b7ced4e4ea..76f79b5338 100644 --- a/go/libraries/doltcore/schema/column.go +++ b/go/libraries/doltcore/schema/column.go @@ -42,6 +42,7 @@ var ( types.NullKind, false, typeinfo.UnknownType, + "", nil, } ) @@ -70,6 +71,9 @@ type Column struct { // TypeInfo states the type of this column. TypeInfo typeinfo.TypeInfo + // Default is the default value of this column. This is the string representation of a sql.Expression. + Default string + // Constraints are rules that can be checked on each column to say if the columns value is valid Constraints []ColConstraint } @@ -77,7 +81,7 @@ type Column struct { // NewColumn creates a Column instance with the default type info for the NomsKind func NewColumn(name string, tag uint64, kind types.NomsKind, partOfPK bool, constraints ...ColConstraint) Column { typeInfo := typeinfo.FromKind(kind) - col, err := NewColumnWithTypeInfo(name, tag, typeInfo, partOfPK, constraints...) + col, err := NewColumnWithTypeInfo(name, tag, typeInfo, partOfPK, "", constraints...) if err != nil { panic(err) } @@ -85,7 +89,7 @@ func NewColumn(name string, tag uint64, kind types.NomsKind, partOfPK bool, cons } // NewColumnWithTypeInfo creates a Column instance with the given type info. -func NewColumnWithTypeInfo(name string, tag uint64, typeInfo typeinfo.TypeInfo, partOfPK bool, constraints ...ColConstraint) (Column, error) { +func NewColumnWithTypeInfo(name string, tag uint64, typeInfo typeinfo.TypeInfo, partOfPK bool, defaultVal string, constraints ...ColConstraint) (Column, error) { for _, c := range constraints { if c == nil { return Column{}, errors.New("nil passed as a constraint") @@ -102,6 +106,7 @@ func NewColumnWithTypeInfo(name string, tag uint64, typeInfo typeinfo.TypeInfo, typeInfo.NomsKind(), partOfPK, typeInfo, + defaultVal, constraints, }, nil } diff --git a/go/libraries/doltcore/schema/encoding/schema_marshaling.go b/go/libraries/doltcore/schema/encoding/schema_marshaling.go index 39c0909ac1..c0dbb64b17 100644 --- a/go/libraries/doltcore/schema/encoding/schema_marshaling.go +++ b/go/libraries/doltcore/schema/encoding/schema_marshaling.go @@ -44,6 +44,8 @@ type encodedColumn struct { TypeInfo encodedTypeInfo `noms:"typeinfo,omitempty" json:"typeinfo,omitempty"` + Default string `noms:"default,omitempty" json:"default,omitempty"` + Constraints []encodedConstraint `noms:"col_constraints" json:"col_constraints"` // NB: all new fields must have the 'omitempty' annotation. See comment above @@ -81,6 +83,7 @@ func encodeColumn(col schema.Column) encodedColumn { col.KindString(), col.IsPartOfPK, encodeTypeInfo(col.TypeInfo), + col.Default, encodeAllColConstraints(col.Constraints), } } @@ -99,7 +102,7 @@ func (nfd encodedColumn) decodeColumn() (schema.Column, error) { return schema.Column{}, errors.New("cannot decode column due to unknown schema format") } colConstraints := decodeAllColConstraint(nfd.Constraints) - return schema.NewColumnWithTypeInfo(nfd.Name, nfd.Tag, typeInfo, nfd.IsPartOfPK, colConstraints...) + return schema.NewColumnWithTypeInfo(nfd.Name, nfd.Tag, typeInfo, nfd.IsPartOfPK, nfd.Default, colConstraints...) } type encodedConstraint struct { diff --git a/go/libraries/doltcore/schema/encoding/schema_marshaling_test.go b/go/libraries/doltcore/schema/encoding/schema_marshaling_test.go index 55c1641068..4bd2307a8f 100644 --- a/go/libraries/doltcore/schema/encoding/schema_marshaling_test.go +++ b/go/libraries/doltcore/schema/encoding/schema_marshaling_test.go @@ -40,6 +40,9 @@ func createTestSchema() schema.Schema { schema.NewColumn("last", 2, types.StringKind, false, schema.NotNullConstraint{}), schema.NewColumn("age", 3, types.UintKind, false), } + for i := range columns { + columns[i].Default = `""` + } colColl, _ := schema.NewColCollection(columns...) sch := schema.SchemaFromCols(colColl) @@ -145,7 +148,7 @@ func TestTypeInfoMarshalling(t *testing.T) { t.Run(sqlType.String(), func(t *testing.T) { ti, err := typeinfo.FromSqlType(sqlType) require.NoError(t, err) - col, err := schema.NewColumnWithTypeInfo("pk", 1, ti, true) + col, err := schema.NewColumnWithTypeInfo("pk", 1, ti, true, "") require.NoError(t, err) colColl, err := schema.NewColCollection(col) require.NoError(t, err) @@ -204,6 +207,8 @@ type testEncodedColumn struct { TypeInfo encodedTypeInfo `noms:"typeinfo" json:"typeinfo"` + Default string `noms:"default" json:"default"` + Constraints []encodedConstraint `noms:"col_constraints" json:"col_constraints"` } @@ -234,7 +239,7 @@ func (tec testEncodedColumn) decodeColumn() (schema.Column, error) { return schema.Column{}, errors.New("cannot decode column due to unknown schema format") } colConstraints := decodeAllColConstraint(tec.Constraints) - return schema.NewColumnWithTypeInfo(tec.Name, tec.Tag, typeInfo, tec.IsPartOfPK, colConstraints...) + return schema.NewColumnWithTypeInfo(tec.Name, tec.Tag, typeInfo, tec.IsPartOfPK, tec.Default, colConstraints...) } func (tsd testSchemaData) decodeSchema() (schema.Schema, error) { diff --git a/go/libraries/doltcore/schema/schema_test.go b/go/libraries/doltcore/schema/schema_test.go index 4e17758810..1d5ae31a7f 100644 --- a/go/libraries/doltcore/schema/schema_test.go +++ b/go/libraries/doltcore/schema/schema_test.go @@ -47,14 +47,14 @@ var ageVal = types.Uint(53) var titleVal = types.NullValue var pkCols = []Column{ - {lnColName, lnColTag, types.StringKind, true, typeinfo.StringDefaultType, nil}, - {fnColName, fnColTag, types.StringKind, true, typeinfo.StringDefaultType, nil}, + {lnColName, lnColTag, types.StringKind, true, typeinfo.StringDefaultType, "", nil}, + {fnColName, fnColTag, types.StringKind, true, typeinfo.StringDefaultType, "", nil}, } var nonPkCols = []Column{ - {addrColName, addrColTag, types.StringKind, false, typeinfo.StringDefaultType, nil}, - {ageColName, ageColTag, types.UintKind, false, typeinfo.FromKind(types.UintKind), nil}, - {titleColName, titleColTag, types.StringKind, false, typeinfo.StringDefaultType, nil}, - {reservedColName, reservedColTag, types.StringKind, false, typeinfo.StringDefaultType, nil}, + {addrColName, addrColTag, types.StringKind, false, typeinfo.StringDefaultType, "", nil}, + {ageColName, ageColTag, types.UintKind, false, typeinfo.FromKind(types.UintKind), "", nil}, + {titleColName, titleColTag, types.StringKind, false, typeinfo.StringDefaultType, "", nil}, + {reservedColName, reservedColTag, types.StringKind, false, typeinfo.StringDefaultType, "", nil}, } var allCols = append(append([]Column(nil), pkCols...), nonPkCols...) @@ -98,7 +98,7 @@ func TestValidateForInsert(t *testing.T) { }) t.Run("Name collision", func(t *testing.T) { - cols := append(allCols, Column{titleColName, 100, types.StringKind, false, typeinfo.StringDefaultType, nil}) + cols := append(allCols, Column{titleColName, 100, types.StringKind, false, typeinfo.StringDefaultType, "", nil}) colColl, err := NewColCollection(cols...) require.NoError(t, err) diff --git a/go/libraries/doltcore/schema/super_schema_test.go b/go/libraries/doltcore/schema/super_schema_test.go index 85b572bb65..159acb8f74 100644 --- a/go/libraries/doltcore/schema/super_schema_test.go +++ b/go/libraries/doltcore/schema/super_schema_test.go @@ -54,7 +54,7 @@ var nameCollisionWithSch1 = mustSchema([]Column{ var tagCollisionWithSch1 = mustSchema([]Column{ strCol("a", 1, true), - {"collision", 2, types.IntKind, false, typeinfo.Int32Type, nil}, + {"collision", 2, types.IntKind, false, typeinfo.Int32Type, "", nil}, }) type SuperSchemaTest struct { @@ -238,5 +238,5 @@ func mustColColl(cols []Column) *ColCollection { } func strCol(name string, tag uint64, isPK bool) Column { - return Column{name, tag, types.StringKind, isPK, typeinfo.StringDefaultType, nil} + return Column{name, tag, types.StringKind, isPK, typeinfo.StringDefaultType, "", nil} } diff --git a/go/libraries/doltcore/sql/sqltestutil/data.go b/go/libraries/doltcore/sql/sqltestutil/data.go index dbe2e0e7ca..21bdbf826f 100644 --- a/go/libraries/doltcore/sql/sqltestutil/data.go +++ b/go/libraries/doltcore/sql/sqltestutil/data.go @@ -119,7 +119,7 @@ func createAppearancesTestSchema() schema.Schema { } func newColumnWithTypeInfo(name string, tag uint64, info typeinfo.TypeInfo, partOfPk bool, constraints ...schema.ColConstraint) schema.Column { - col, err := schema.NewColumnWithTypeInfo(name, tag, info, partOfPk, constraints...) + col, err := schema.NewColumnWithTypeInfo(name, tag, info, partOfPk, "", constraints...) if err != nil { panic(fmt.Sprintf("unexpected error creating column: %s", err.Error())) } diff --git a/go/libraries/doltcore/sqle/common_test.go b/go/libraries/doltcore/sqle/common_test.go index 10ff5dd047..56b9857c03 100644 --- a/go/libraries/doltcore/sqle/common_test.go +++ b/go/libraries/doltcore/sqle/common_test.go @@ -31,6 +31,7 @@ import ( "github.com/liquidata-inc/dolt/go/libraries/doltcore/schema" "github.com/liquidata-inc/dolt/go/libraries/doltcore/schema/typeinfo" "github.com/liquidata-inc/dolt/go/libraries/doltcore/sql/sqltestutil" + sqleSchema "github.com/liquidata-inc/dolt/go/libraries/doltcore/sqle/schema" "github.com/liquidata-inc/dolt/go/store/types" ) @@ -113,9 +114,13 @@ func SubsetSchema(sch schema.Schema, colNames ...string) schema.Schema { } func schemaNewColumn(t *testing.T, name string, tag uint64, sqlType sql.Type, partOfPK bool, constraints ...schema.ColConstraint) schema.Column { + return schemaNewColumnWDefVal(t, name, tag, sqlType, partOfPK, "", constraints...) +} + +func schemaNewColumnWDefVal(t *testing.T, name string, tag uint64, sqlType sql.Type, partOfPK bool, defaultVal string, constraints ...schema.ColConstraint) schema.Column { typeInfo, err := typeinfo.FromSqlType(sqlType) require.NoError(t, err) - col, err := schema.NewColumnWithTypeInfo(name, tag, typeInfo, partOfPK, constraints...) + col, err := schema.NewColumnWithTypeInfo(name, tag, typeInfo, partOfPK, defaultVal, constraints...) require.NoError(t, err) return col } @@ -135,7 +140,7 @@ func CreateWorkingRootUpdate() map[string]envtestutils.TableUpdate { // Returns the dolt schema given as a sql.Schema, or panics. func mustSqlSchema(sch schema.Schema) sql.Schema { - sqlSchema, err := doltSchemaToSqlSchema("", sch) + sqlSchema, err := sqleSchema.FromDoltSchema("", sch) if err != nil { panic(err) } diff --git a/go/libraries/doltcore/sqle/conflicts_tables.go b/go/libraries/doltcore/sqle/conflicts_tables.go index a0dd76e464..45f2de8845 100644 --- a/go/libraries/doltcore/sqle/conflicts_tables.go +++ b/go/libraries/doltcore/sqle/conflicts_tables.go @@ -17,10 +17,10 @@ package sqle import ( "github.com/liquidata-inc/go-mysql-server/sql" - "github.com/liquidata-inc/dolt/go/libraries/doltcore/merge" - "github.com/liquidata-inc/dolt/go/store/types" - "github.com/liquidata-inc/dolt/go/libraries/doltcore/doltdb" + "github.com/liquidata-inc/dolt/go/libraries/doltcore/merge" + sqleSchema "github.com/liquidata-inc/dolt/go/libraries/doltcore/sqle/schema" + "github.com/liquidata-inc/dolt/go/store/types" ) var _ sql.Table = ConflictsTable{} @@ -61,7 +61,7 @@ func NewConflictsTable(ctx *sql.Context, db Database, tblName string) (sql.Table return nil, err } - sqlSch, err := doltSchemaToSqlSchema(doltdb.DoltConfTablePrefix+tblName, rd.GetSchema()) + sqlSch, err := sqleSchema.FromDoltSchema(doltdb.DoltConfTablePrefix+tblName, rd.GetSchema()) if err != nil { return nil, err diff --git a/go/libraries/doltcore/sqle/database.go b/go/libraries/doltcore/sqle/database.go index 3fbbec2517..fd1a0edea4 100644 --- a/go/libraries/doltcore/sqle/database.go +++ b/go/libraries/doltcore/sqle/database.go @@ -33,6 +33,7 @@ import ( "github.com/liquidata-inc/dolt/go/libraries/doltcore/env/actions/commitwalk" "github.com/liquidata-inc/dolt/go/libraries/doltcore/schema" "github.com/liquidata-inc/dolt/go/libraries/doltcore/schema/alterschema" + sqleSchema "github.com/liquidata-inc/dolt/go/libraries/doltcore/sqle/schema" "github.com/liquidata-inc/dolt/go/libraries/doltcore/sqle/sqlfmt" "github.com/liquidata-inc/dolt/go/store/hash" ) @@ -574,7 +575,7 @@ func (db Database) CreateTable(ctx *sql.Context, tableName string, sch sql.Schem } for _, col := range sch { - commentTag := extractTag(col) + commentTag := sqleSchema.ExtractTag(col) if commentTag == schema.InvalidTag { // we'll replace this invalid tag continue @@ -601,7 +602,7 @@ func (db Database) createTable(ctx *sql.Context, tableName string, sch sql.Schem return sql.ErrTableAlreadyExists.New(tableName) } - doltSch, err := SqlSchemaToDoltSchema(ctx, root, tableName, sch) + doltSch, err := sqleSchema.ToDoltSchema(ctx, root, tableName, sch) if err != nil { return err } diff --git a/go/libraries/doltcore/sqle/diff_table.go b/go/libraries/doltcore/sqle/diff_table.go index 6c02fecec6..d7c32d69d0 100644 --- a/go/libraries/doltcore/sqle/diff_table.go +++ b/go/libraries/doltcore/sqle/diff_table.go @@ -20,6 +20,7 @@ import ( "fmt" "github.com/liquidata-inc/go-mysql-server/sql" + "github.com/liquidata-inc/go-mysql-server/sql/parse" "github.com/liquidata-inc/dolt/go/libraries/doltcore/diff" "github.com/liquidata-inc/dolt/go/libraries/doltcore/doltdb" @@ -27,6 +28,7 @@ import ( "github.com/liquidata-inc/dolt/go/libraries/doltcore/rowconv" "github.com/liquidata-inc/dolt/go/libraries/doltcore/schema" "github.com/liquidata-inc/dolt/go/libraries/doltcore/sqle/expreval" + sqleSchema "github.com/liquidata-inc/dolt/go/libraries/doltcore/sqle/schema" "github.com/liquidata-inc/dolt/go/libraries/utils/set" "github.com/liquidata-inc/dolt/go/store/hash" "github.com/liquidata-inc/dolt/go/store/types" @@ -113,16 +115,22 @@ func NewDiffTable(ctx *sql.Context, db Database, tblName string) (sql.Table, err return nil, err } - sqlSch, err := doltSchemaToSqlSchema(diffTblName, j.GetSchema()) + sqlSch, err := sqleSchema.FromDoltSchema(diffTblName, j.GetSchema()) if err != nil { return nil, err } + // parses to literal, no need to pass through analyzer + defaultVal, err := parse.StringToColumnDefaultValue(ctx, fmt.Sprintf(`"%s"`, diffTypeModified)) + if err != nil { + return nil, err + } + sqlSch = append(sqlSch, &sql.Column{ Name: diffTypeColName, Type: sql.Text, - Default: diffTypeModified, + Default: defaultVal, Nullable: false, Source: diffTblName, }) diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go index 506552681b..c34d60a026 100755 --- a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go @@ -168,3 +168,7 @@ func TestInnerNestedInNaturalJoins(t *testing.T) { t.Skip("No primary key in test tables") enginetest.TestInnerNestedInNaturalJoins(t, newDoltHarness(t)) } + +func TestColumnDefaults(t *testing.T) { + enginetest.TestColumnDefaults(t, newDoltHarness(t)) +} diff --git a/go/libraries/doltcore/sqle/history_table.go b/go/libraries/doltcore/sqle/history_table.go index 6d74721901..b2e3bf846d 100644 --- a/go/libraries/doltcore/sqle/history_table.go +++ b/go/libraries/doltcore/sqle/history_table.go @@ -25,6 +25,7 @@ import ( "github.com/liquidata-inc/dolt/go/libraries/doltcore/doltdb" "github.com/liquidata-inc/dolt/go/libraries/doltcore/rowconv" "github.com/liquidata-inc/dolt/go/libraries/doltcore/schema" + sqleSchema "github.com/liquidata-inc/dolt/go/libraries/doltcore/sqle/schema" "github.com/liquidata-inc/dolt/go/libraries/doltcore/table" "github.com/liquidata-inc/dolt/go/libraries/utils/set" "github.com/liquidata-inc/dolt/go/store/hash" @@ -102,7 +103,7 @@ func NewHistoryTable(ctx *sql.Context, db Database, tblName string) (sql.Table, } tableName := doltdb.DoltHistoryTablePrefix + tblName - sqlSch, err := doltSchemaToSqlSchema(tableName, sch) + sqlSch, err := sqleSchema.FromDoltSchema(tableName, sch) if err != nil { return nil, err diff --git a/go/libraries/doltcore/sqle/schema.go b/go/libraries/doltcore/sqle/schema/schema.go similarity index 57% rename from go/libraries/doltcore/sqle/schema.go rename to go/libraries/doltcore/sqle/schema/schema.go index 1a723f3bab..96f113719e 100644 --- a/go/libraries/doltcore/sqle/schema.go +++ b/go/libraries/doltcore/sqle/schema/schema.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package sqle +package schema import ( "context" @@ -20,11 +20,13 @@ import ( "strconv" "strings" + sqle "github.com/liquidata-inc/go-mysql-server" "github.com/liquidata-inc/go-mysql-server/sql" "github.com/liquidata-inc/go-mysql-server/sql/parse" "github.com/liquidata-inc/vitess/go/vt/sqlparser" "github.com/liquidata-inc/dolt/go/libraries/doltcore/doltdb" + "github.com/liquidata-inc/dolt/go/libraries/doltcore/row" "github.com/liquidata-inc/dolt/go/libraries/doltcore/schema" "github.com/liquidata-inc/dolt/go/libraries/doltcore/schema/typeinfo" "github.com/liquidata-inc/dolt/go/libraries/doltcore/sqle/sqlfmt" @@ -33,31 +35,53 @@ import ( var ErrPartiallyDefinedTags = fmt.Errorf("must define tags for all or none of the schema columns") -// doltSchemaToSqlSchema returns the sql.Schema corresponding to the dolt schema given. -func doltSchemaToSqlSchema(tableName string, sch schema.Schema) (sql.Schema, error) { - cols := make([]*sql.Column, sch.GetAllCols().Size()) - - var i int - err := sch.GetAllCols().Iter(func(tag uint64, col schema.Column) (stop bool, err error) { - var innerErr error - cols[i], innerErr = doltColToSqlCol(tableName, col) - if innerErr != nil { - return true, innerErr +// ApplyDefaults applies the default values to the given indices, returning the resulting row. +func ApplyDefaults(ctx context.Context, doltSchema schema.Schema, sqlSchema sql.Schema, indicesOfColumns []int, dRow row.Row) (row.Row, error) { + if len(indicesOfColumns) == 0 { + return dRow, nil + } + sqlCtx, ok := ctx.(*sql.Context) + if !ok { + sqlCtx = sql.NewContext(ctx) + } + doltCols := doltSchema.GetAllCols() + oldSqlRow := make(sql.Row, len(sqlSchema)) + for i, tag := range doltCols.Tags { + val, ok := dRow.GetColVal(tag) + if ok { + var err error + oldSqlRow[i], err = doltCols.TagToCol[tag].TypeInfo.ConvertNomsValueToValue(val) + if err != nil { + return nil, err + } + } else { + oldSqlRow[i] = nil } - i++ - return false, nil - }) - - return cols, err + } + newSqlRow, err := sqle.ApplyDefaults(sqlCtx, sqlSchema, indicesOfColumns, oldSqlRow) + if err != nil { + return nil, err + } + newRow := make(row.TaggedValues) + for i, tag := range doltCols.Tags { + if newSqlRow[i] == nil { + continue + } + val, err := doltCols.TagToCol[tag].TypeInfo.ConvertValueToNomsValue(newSqlRow[i]) + if err != nil { + return nil, err + } + newRow[tag] = val + } + return row.New(dRow.Format(), doltSchema, newRow) } -// SqlSchemaToDoltResultSchema returns a dolt Schema from the sql schema given, suitable for use as a result set. For -// creating tables, use SqlSchemaToDoltSchema. -// todo: this function never returns an error -func SqlSchemaToDoltResultSchema(sqlSchema sql.Schema) (schema.Schema, error) { +// ToDoltResultSchema returns a dolt Schema from the sql schema given, suitable for use as a result set. For +// creating tables, use ToDoltSchema. +func ToDoltResultSchema(sqlSchema sql.Schema) (schema.Schema, error) { var cols []schema.Column for i, col := range sqlSchema { - convertedCol, err := SqlColToDoltCol(uint64(i), col) + convertedCol, err := ToDoltCol(uint64(i), col) if err != nil { return nil, err } @@ -93,7 +117,7 @@ func ParseCreateTableStatement(ctx context.Context, root *doltdb.RootValue, quer buf := sqlparser.NewTrackedBuffer(nil) tn.Format(buf) tableName := buf.String() - sch, err := SqlSchemaToDoltSchema(ctx, root, tableName, s) + sch, err := ToDoltSchema(ctx, root, tableName, s) if err != nil { return "", nil, err @@ -102,19 +126,44 @@ func ParseCreateTableStatement(ctx context.Context, root *doltdb.RootValue, quer return tableName, sch, err } -// SqlSchemaToDoltResultSchema returns a dolt Schema from the sql schema given, suitable for use in creating a table. -// For result set schemas, see SqlSchemaToDoltResultSchema. -func SqlSchemaToDoltSchema(ctx context.Context, root *doltdb.RootValue, tableName string, sqlSchema sql.Schema) (schema.Schema, error) { +func FromDoltSchema(tableName string, sch schema.Schema) (sql.Schema, error) { + cols := make([]*sqle.ColumnWithRawDefault, sch.GetAllCols().Size()) + + var i int + _ = sch.GetAllCols().Iter(func(tag uint64, col schema.Column) (stop bool, err error) { + sqlType := col.TypeInfo.ToSqlType() + cols[i] = &sqle.ColumnWithRawDefault{ + SqlColumn: &sql.Column{ + Name: col.Name, + Type: sqlType, + Default: nil, + Nullable: col.IsNullable(), + Source: tableName, + PrimaryKey: col.IsPartOfPK, + Comment: fmt.Sprintf("tag:%d", col.Tag), + }, + Default: col.Default, + } + i++ + return false, nil + }) + + return sqle.ResolveDefaults(tableName, cols) +} + +// ToDoltSchema returns a dolt Schema from the sql schema given, suitable for use in creating a table. +// For result set schemas, see ToDoltResultSchema. +func ToDoltSchema(ctx context.Context, root *doltdb.RootValue, tableName string, sqlSchema sql.Schema) (schema.Schema, error) { var cols []schema.Column var err error // Users must define all or none of the column tags - userDefinedTags := extractTag(sqlSchema[0]) != schema.InvalidTag + userDefinedTags := ExtractTag(sqlSchema[0]) != schema.InvalidTag var tags []uint64 if userDefinedTags { for _, col := range sqlSchema { - commentTag := extractTag(col) + commentTag := ExtractTag(col) tags = append(tags, commentTag) if commentTag == schema.InvalidTag { return nil, ErrPartiallyDefinedTags @@ -133,7 +182,7 @@ func SqlSchemaToDoltSchema(ctx context.Context, root *doltdb.RootValue, tableNam kinds = append(kinds, ti.NomsKind()) // check for user defined tags - if extractTag(col) != schema.InvalidTag { + if ExtractTag(col) != schema.InvalidTag { return nil, ErrPartiallyDefinedTags } } @@ -148,7 +197,7 @@ func SqlSchemaToDoltSchema(ctx context.Context, root *doltdb.RootValue, tableNam } for i, col := range sqlSchema { - convertedCol, err := SqlColToDoltCol(tags[i], col) + convertedCol, err := ToDoltCol(tags[i], col) if err != nil { return nil, err } @@ -168,22 +217,8 @@ func SqlSchemaToDoltSchema(ctx context.Context, root *doltdb.RootValue, tableNam return schema.SchemaFromCols(colColl), nil } -// doltColToSqlCol returns the SQL column corresponding to the dolt column given. -func doltColToSqlCol(tableName string, col schema.Column) (*sql.Column, error) { - sqlType := col.TypeInfo.ToSqlType() - return &sql.Column{ - Name: col.Name, - Type: sqlType, - Default: nil, - Nullable: col.IsNullable(), - Source: tableName, - PrimaryKey: col.IsPartOfPK, - Comment: fmt.Sprintf("tag:%d", col.Tag), - }, nil -} - -// doltColToSqlCol returns the dolt column corresponding to the SQL column given -func SqlColToDoltCol(tag uint64, col *sql.Column) (schema.Column, error) { +// ToDoltCol returns the dolt column corresponding to the SQL column given +func ToDoltCol(tag uint64, col *sql.Column) (schema.Column, error) { var constraints []schema.ColConstraint if !col.Nullable { constraints = append(constraints, schema.NotNullConstraint{}) @@ -193,11 +228,11 @@ func SqlColToDoltCol(tag uint64, col *sql.Column) (schema.Column, error) { return schema.Column{}, err } - return schema.NewColumnWithTypeInfo(col.Name, tag, typeInfo, col.PrimaryKey, constraints...) + return schema.NewColumnWithTypeInfo(col.Name, tag, typeInfo, col.PrimaryKey, col.Default.String(), constraints...) } -// Extracts the optional comment tag from a column type defn, or InvalidTag if it can't be extracted -func extractTag(col *sql.Column) uint64 { +// ExtractTag extracts the optional comment tag from a column type defn, or InvalidTag if it can't be extracted +func ExtractTag(col *sql.Column) uint64 { if len(col.Comment) == 0 { return schema.InvalidTag } diff --git a/go/libraries/doltcore/sqle/sqlddl_test.go b/go/libraries/doltcore/sqle/sqlddl_test.go index b272043f3d..9fbf8c5ade 100644 --- a/go/libraries/doltcore/sqle/sqlddl_test.go +++ b/go/libraries/doltcore/sqle/sqlddl_test.go @@ -31,6 +31,7 @@ import ( "github.com/liquidata-inc/dolt/go/libraries/doltcore/row" "github.com/liquidata-inc/dolt/go/libraries/doltcore/schema" . "github.com/liquidata-inc/dolt/go/libraries/doltcore/sql/sqltestutil" + sqleSchema "github.com/liquidata-inc/dolt/go/libraries/doltcore/sqle/schema" "github.com/liquidata-inc/dolt/go/store/types" ) @@ -237,8 +238,8 @@ func TestCreateTable(t *testing.T) { PRIMARY KEY (ip));`, expectedTable: "ip2nation", expectedSchema: dtestutils.CreateSchema( - schemaNewColumn(t, "ip", 100, sql.Uint32, true, schema.NotNullConstraint{}), - schemaNewColumn(t, "country", 101, sql.MustCreateStringWithDefaults(sqltypes.Char, 2), false, schema.NotNullConstraint{})), + schemaNewColumnWDefVal(t, "ip", 100, sql.Uint32, true, "0", schema.NotNullConstraint{}), + schemaNewColumnWDefVal(t, "country", 101, sql.MustCreateStringWithDefaults(sqltypes.Char, 2), false, `""`, schema.NotNullConstraint{})), }, { name: "Test ip2nationCountries", @@ -253,13 +254,13 @@ func TestCreateTable(t *testing.T) { lon float NOT NULL default 0.0 COMMENT 'tag:106', PRIMARY KEY (code));`, expectedSchema: dtestutils.CreateSchema( - schemaNewColumn(t, "code", 100, sql.MustCreateStringWithDefaults(sqltypes.VarChar, 4), true, schema.NotNullConstraint{}), - schemaNewColumn(t, "iso_code_2", 101, sql.MustCreateStringWithDefaults(sqltypes.VarChar, 2), false, schema.NotNullConstraint{}), - schemaNewColumn(t, "iso_code_3", 102, sql.MustCreateStringWithDefaults(sqltypes.VarChar, 3), false), - schemaNewColumn(t, "iso_country", 103, sql.MustCreateStringWithDefaults(sqltypes.VarChar, 255), false, schema.NotNullConstraint{}), - schemaNewColumn(t, "country", 104, sql.MustCreateStringWithDefaults(sqltypes.VarChar, 255), false, schema.NotNullConstraint{}), - schemaNewColumn(t, "lat", 105, sql.Float32, false, schema.NotNullConstraint{}), - schemaNewColumn(t, "lon", 106, sql.Float32, false, schema.NotNullConstraint{})), + schemaNewColumnWDefVal(t, "code", 100, sql.MustCreateStringWithDefaults(sqltypes.VarChar, 4), true, `""`, schema.NotNullConstraint{}), + schemaNewColumnWDefVal(t, "iso_code_2", 101, sql.MustCreateStringWithDefaults(sqltypes.VarChar, 2), false, `""`, schema.NotNullConstraint{}), + schemaNewColumnWDefVal(t, "iso_code_3", 102, sql.MustCreateStringWithDefaults(sqltypes.VarChar, 3), false, `""`), + schemaNewColumnWDefVal(t, "iso_country", 103, sql.MustCreateStringWithDefaults(sqltypes.VarChar, 255), false, `""`, schema.NotNullConstraint{}), + schemaNewColumnWDefVal(t, "country", 104, sql.MustCreateStringWithDefaults(sqltypes.VarChar, 255), false, `""`, schema.NotNullConstraint{}), + schemaNewColumnWDefVal(t, "lat", 105, sql.Float32, false, "0", schema.NotNullConstraint{}), + schemaNewColumnWDefVal(t, "lon", 106, sql.Float32, false, "0", schema.NotNullConstraint{})), }, } @@ -415,21 +416,21 @@ func TestAddColumn(t *testing.T) { name: "alter add column not null", query: "alter table people add (newColumn varchar(80) not null default 'default' comment 'tag:100')", expectedSchema: dtestutils.AddColumnToSchema(PeopleTestSchema, - schemaNewColumn(t, "newColumn", 100, sql.MustCreateStringWithDefaults(sqltypes.VarChar, 80), false, schema.NotNullConstraint{})), + schemaNewColumnWDefVal(t, "newColumn", 100, sql.MustCreateStringWithDefaults(sqltypes.VarChar, 80), false, `"default"`, schema.NotNullConstraint{})), expectedRows: dtestutils.AddColToRows(t, AllPeopleRows, 100, types.String("default")), }, { name: "alter add column not null with expression default", query: "alter table people add (newColumn int not null default 2+2/2 comment 'tag:100')", expectedSchema: dtestutils.AddColumnToSchema(PeopleTestSchema, - schemaNewColumn(t, "newColumn", 100, sql.Int32, false, schema.NotNullConstraint{})), + schemaNewColumnWDefVal(t, "newColumn", 100, sql.Int32, false, "(2 + 2 / 2)", schema.NotNullConstraint{})), expectedRows: dtestutils.AddColToRows(t, AllPeopleRows, 100, types.Int(3)), }, { name: "alter add column not null with negative expression", query: "alter table people add (newColumn float not null default -1.1 comment 'tag:100')", expectedSchema: dtestutils.AddColumnToSchema(PeopleTestSchema, - schemaNewColumn(t, "newColumn", 100, sql.Float32, false, schema.NotNullConstraint{})), + schemaNewColumnWDefVal(t, "newColumn", 100, sql.Float32, false, "-1.1", schema.NotNullConstraint{})), expectedRows: dtestutils.AddColToRows(t, AllPeopleRows, 100, types.Float(float32(-1.1))), }, { @@ -1231,8 +1232,8 @@ func TestParseCreateTableStatement(t *testing.T) { PRIMARY KEY (ip));`, expectedTable: "ip2nation", expectedSchema: dtestutils.CreateSchema( - schemaNewColumn(t, "ip", 100, sql.Uint32, true, schema.NotNullConstraint{}), - schemaNewColumn(t, "country", 101, sql.MustCreateStringWithDefaults(sqltypes.Char, 2), false, schema.NotNullConstraint{})), + schemaNewColumnWDefVal(t, "ip", 100, sql.Uint32, true, "0", schema.NotNullConstraint{}), + schemaNewColumnWDefVal(t, "country", 101, sql.MustCreateStringWithDefaults(sqltypes.Char, 2), false, `""`, schema.NotNullConstraint{})), }, { name: "Test ip2nationCountries", @@ -1247,13 +1248,13 @@ func TestParseCreateTableStatement(t *testing.T) { lon float NOT NULL default 0.0 COMMENT 'tag:106', PRIMARY KEY (code));`, expectedSchema: dtestutils.CreateSchema( - schemaNewColumn(t, "code", 100, sql.MustCreateStringWithDefaults(sqltypes.VarChar, 4), true, schema.NotNullConstraint{}), - schemaNewColumn(t, "iso_code_2", 101, sql.MustCreateStringWithDefaults(sqltypes.VarChar, 2), false, schema.NotNullConstraint{}), - schemaNewColumn(t, "iso_code_3", 102, sql.MustCreateStringWithDefaults(sqltypes.VarChar, 3), false), - schemaNewColumn(t, "iso_country", 103, sql.MustCreateStringWithDefaults(sqltypes.VarChar, 255), false, schema.NotNullConstraint{}), - schemaNewColumn(t, "country", 104, sql.MustCreateStringWithDefaults(sqltypes.VarChar, 255), false, schema.NotNullConstraint{}), - schemaNewColumn(t, "lat", 105, sql.Float32, false, schema.NotNullConstraint{}), - schemaNewColumn(t, "lon", 106, sql.Float32, false, schema.NotNullConstraint{})), + schemaNewColumnWDefVal(t, "code", 100, sql.MustCreateStringWithDefaults(sqltypes.VarChar, 4), true, `""`, schema.NotNullConstraint{}), + schemaNewColumnWDefVal(t, "iso_code_2", 101, sql.MustCreateStringWithDefaults(sqltypes.VarChar, 2), false, `""`, schema.NotNullConstraint{}), + schemaNewColumnWDefVal(t, "iso_code_3", 102, sql.MustCreateStringWithDefaults(sqltypes.VarChar, 3), false, `""`), + schemaNewColumnWDefVal(t, "iso_country", 103, sql.MustCreateStringWithDefaults(sqltypes.VarChar, 255), false, `""`, schema.NotNullConstraint{}), + schemaNewColumnWDefVal(t, "country", 104, sql.MustCreateStringWithDefaults(sqltypes.VarChar, 255), false, `""`, schema.NotNullConstraint{}), + schemaNewColumnWDefVal(t, "lat", 105, sql.Float32, false, "0", schema.NotNullConstraint{}), + schemaNewColumnWDefVal(t, "lon", 106, sql.Float32, false, "0", schema.NotNullConstraint{})), }, } @@ -1263,7 +1264,7 @@ func TestParseCreateTableStatement(t *testing.T) { ctx := context.Background() root, _ := dEnv.WorkingRoot(ctx) - tblName, sch, err := ParseCreateTableStatement(ctx, root, tt.query) + tblName, sch, err := sqleSchema.ParseCreateTableStatement(ctx, root, tt.query) if tt.expectedErr != "" { require.Error(t, err) diff --git a/go/libraries/doltcore/sqle/sqlinsert_test.go b/go/libraries/doltcore/sqle/sqlinsert_test.go index 200d87bb3a..c5bfda9431 100644 --- a/go/libraries/doltcore/sqle/sqlinsert_test.go +++ b/go/libraries/doltcore/sqle/sqlinsert_test.go @@ -28,6 +28,7 @@ import ( "github.com/liquidata-inc/dolt/go/libraries/doltcore/env" "github.com/liquidata-inc/dolt/go/libraries/doltcore/schema" . "github.com/liquidata-inc/dolt/go/libraries/doltcore/sql/sqltestutil" + sqleSchema "github.com/liquidata-inc/dolt/go/libraries/doltcore/sqle/schema" "github.com/liquidata-inc/dolt/go/store/types" ) @@ -439,7 +440,7 @@ func mustGetDoltSchema(sch sql.Schema, tableName string, testEnv *env.DoltEnv) s panic(err) } - doltSchema, err := SqlSchemaToDoltSchema(context.Background(), wrt, tableName, sch) + doltSchema, err := sqleSchema.ToDoltSchema(context.Background(), wrt, tableName, sch) if err != nil { panic(err) } diff --git a/go/libraries/doltcore/sqle/tables.go b/go/libraries/doltcore/sqle/tables.go index 08a7aa24df..17f6cac1bb 100644 --- a/go/libraries/doltcore/sqle/tables.go +++ b/go/libraries/doltcore/sqle/tables.go @@ -32,6 +32,7 @@ import ( "github.com/liquidata-inc/dolt/go/libraries/doltcore/schema/alterschema" "github.com/liquidata-inc/dolt/go/libraries/doltcore/schema/encoding" "github.com/liquidata-inc/dolt/go/libraries/doltcore/schema/typeinfo" + sqleSchema "github.com/liquidata-inc/dolt/go/libraries/doltcore/sqle/schema" "github.com/liquidata-inc/dolt/go/libraries/utils/set" "github.com/liquidata-inc/dolt/go/store/types" ) @@ -46,7 +47,11 @@ func init() { isTest := false for _, arg := range os.Args { lwr := strings.ToLower(arg) - if lwr == "-test.v" || lwr == "-test.run" || strings.HasPrefix(lwr, "-test.testlogfile") { + if lwr == "-test.v" || + lwr == "-test.run" || + strings.HasPrefix(lwr, "-test.testlogfile") || + strings.HasPrefix(lwr, "-test.timeout") || + strings.HasPrefix(lwr, "-test.count") { isTest = true break } @@ -159,7 +164,7 @@ func (t *DoltTable) sqlSchema() sql.Schema { } // TODO: fix panics - sqlSch, err := doltSchemaToSqlSchema(t.name, t.sch) + sqlSch, err := sqleSchema.FromDoltSchema(t.name, t.sch) if err != nil { panic(err) } @@ -389,7 +394,7 @@ func (t *AlterableDoltTable) AddColumn(ctx *sql.Context, column *sql.Column, ord return err } - tag := extractTag(column) + tag := sqleSchema.ExtractTag(column) if tag == schema.InvalidTag { // generate a tag if we don't have a user-defined tag ti, err := typeinfo.FromSqlType(column.Type) @@ -404,7 +409,7 @@ func (t *AlterableDoltTable) AddColumn(ctx *sql.Context, column *sql.Column, ord tag = tt[0] } - col, err := SqlColToDoltCol(tag, column) + col, err := sqleSchema.ToDoltCol(tag, column) if err != nil { return err } @@ -418,15 +423,7 @@ func (t *AlterableDoltTable) AddColumn(ctx *sql.Context, column *sql.Column, ord nullable = alterschema.Null } - var defaultVal types.Value - if column.Default != nil { - defaultVal, err = col.TypeInfo.ConvertValueToNomsValue(column.Default) - if err != nil { - return err - } - } - - updatedTable, err := alterschema.AddColumnToTable(ctx, root, table, t.name, col.Tag, col.Name, col.TypeInfo, nullable, defaultVal, orderToOrder(order)) + updatedTable, err := alterschema.AddColumnToTable(ctx, root, table, t.name, col.Tag, col.Name, col.TypeInfo, nullable, col.Default, orderToOrder(order)) if err != nil { return err } @@ -524,24 +521,16 @@ func (t *AlterableDoltTable) ModifyColumn(ctx *sql.Context, columnName string, c panic(fmt.Sprintf("Column %s not found. This is a bug.", columnName)) } - tag := extractTag(column) + tag := sqleSchema.ExtractTag(column) if tag != existingCol.Tag && tag != schema.InvalidTag { return errors.New("cannot change the tag of an existing column") } - col, err := SqlColToDoltCol(existingCol.Tag, column) + col, err := sqleSchema.ToDoltCol(existingCol.Tag, column) if err != nil { return err } - var defVal types.Value - if column.Default != nil { - defVal, err = col.TypeInfo.ConvertValueToNomsValue(column.Default) - if err != nil { - return err - } - } - fkCollection, err := root.GetForeignKeyCollection(ctx) if err != nil { return err @@ -554,7 +543,7 @@ func (t *AlterableDoltTable) ModifyColumn(ctx *sql.Context, columnName string, c } } - updatedTable, err := alterschema.ModifyColumn(ctx, table, existingCol, col, defVal, orderToOrder(order)) + updatedTable, err := alterschema.ModifyColumn(ctx, table, existingCol, col, orderToOrder(order)) if err != nil { return err } diff --git a/mysql-client-tests/node/index.js b/mysql-client-tests/node/index.js index f87c14eb4c..030a5cbc53 100644 --- a/mysql-client-tests/node/index.js +++ b/mysql-client-tests/node/index.js @@ -49,16 +49,7 @@ async function main() { ]; const results = [ - { - fieldCount: 0, - affectedRows: 0, - insertId: 0, - serverStatus: 0, - warningCount: 0, - message: '', - protocol41: true, - changedRows: 0 - }, + [], [ { Field: 'pk', Type: 'int', Null: 'NO', diff --git a/mysql-client-tests/python/mysql.connector-test.py b/mysql-client-tests/python/mysql.connector-test.py index bb4f336976..42ecdda309 100644 --- a/mysql-client-tests/python/mysql.connector-test.py +++ b/mysql-client-tests/python/mysql.connector-test.py @@ -2,12 +2,12 @@ import mysql.connector import sys QUERY_RESPONSE = [ - { "create table test (pk int, value int, primary key(pk))": '' }, + { "create table test (pk int, value int, primary key(pk))": [] }, { "describe test": [ ('pk', 'int', 'NO', 'PRI', '', ''), ('value', 'int', 'YES', '', '', '') ] }, - { "insert into test (pk, value) values (0,0)": '' }, + { "insert into test (pk, value) values (0,0)": [] }, { "select * from test": [(0,0)] } ]