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
1 change: 1 addition & 0 deletions go/test/endtoend/vtgate/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,7 @@ func TestMain(m *testing.M) {
return 1
}

clusterInstance.VtGateExtraArgs = append(clusterInstance.VtGateExtraArgs, "-enable_system_settings=true")
// Start vtgate
err = clusterInstance.StartVtgate()
if err != nil {
Expand Down
33 changes: 32 additions & 1 deletion go/test/endtoend/vtgate/misc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,7 @@ func TestSubQueryOnTopOfSubQuery(t *testing.T) {
exec(t, conn, `insert into t1(id1, id2) values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5)`)
exec(t, conn, `insert into t2(id3, id4) values (1, 3), (2, 4)`)

assertMatches(t, conn, "select id1 from t1 where id1 not in (select id3 from t2) and id2 in (select id4 from t2)", `[[INT64(3)] [INT64(4)]]`)
assertMatches(t, conn, "select id1 from t1 where id1 not in (select id3 from t2) and id2 in (select id4 from t2) order by id1", `[[INT64(3)] [INT64(4)]]`)
}

func TestFunctionInDefault(t *testing.T) {
Expand All @@ -517,9 +517,40 @@ func TestFunctionInDefault(t *testing.T) {
require.NoError(t, err)
defer conn.Close()

// set the sql mode ALLOW_INVALID_DATES
exec(t, conn, `SET sql_mode = 'ALLOW_INVALID_DATES'`)

_, err = conn.ExecuteFetch(`create table function_default (x varchar(25) DEFAULT (TRIM(" check ")))`, 1000, true)
// this query fails because mysql57 does not support functions in default clause
require.Error(t, err)

// verify that currenet_timestamp and it's aliases work as default values
exec(t, conn, `create table function_default (
ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
dt DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
ts2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
dt2 DATETIME DEFAULT CURRENT_TIMESTAMP,
ts3 TIMESTAMP DEFAULT 0,
dt3 DATETIME DEFAULT 0,
ts4 TIMESTAMP DEFAULT 0 ON UPDATE CURRENT_TIMESTAMP,
dt4 DATETIME DEFAULT 0 ON UPDATE CURRENT_TIMESTAMP,
ts5 TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
ts6 TIMESTAMP NULL ON UPDATE CURRENT_TIMESTAMP,
dt5 DATETIME ON UPDATE CURRENT_TIMESTAMP,
dt6 DATETIME NOT NULL ON UPDATE CURRENT_TIMESTAMP,
ts7 TIMESTAMP(6) DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
ts8 TIMESTAMP DEFAULT NOW(),
ts9 TIMESTAMP DEFAULT LOCALTIMESTAMP,
ts10 TIMESTAMP DEFAULT LOCALTIME,
ts11 TIMESTAMP DEFAULT LOCALTIMESTAMP(),
ts12 TIMESTAMP DEFAULT LOCALTIME()
)`)
exec(t, conn, "drop table function_default")

_, err = conn.ExecuteFetch(`create table function_default (ts TIMESTAMP DEFAULT UTC_TIMESTAMP)`, 1000, true)
// this query fails because utc_timestamp is not supported in default clause
require.Error(t, err)

exec(t, conn, `create table function_default (x varchar(25) DEFAULT "check")`)
exec(t, conn, "drop table function_default")
}
Expand Down
1 change: 1 addition & 0 deletions go/test/endtoend/vtgate/mysql80/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ func TestMain(m *testing.M) {
return 1
}

clusterInstance.VtGateExtraArgs = append(clusterInstance.VtGateExtraArgs, "-enable_system_settings=true")
// Start vtgate
err = clusterInstance.StartVtgate()
if err != nil {
Expand Down
29 changes: 29 additions & 0 deletions go/test/endtoend/vtgate/mysql80/misc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,38 @@ func TestFunctionInDefault(t *testing.T) {
require.NoError(t, err)
defer conn.Close()

// set the sql mode ALLOW_INVALID_DATES
exec(t, conn, `SET sql_mode = 'ALLOW_INVALID_DATES'`)

exec(t, conn, `create table function_default (x varchar(25) DEFAULT (TRIM(" check ")))`)
exec(t, conn, "drop table function_default")

exec(t, conn, `create table function_default (
ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
dt DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
ts2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
dt2 DATETIME DEFAULT CURRENT_TIMESTAMP,
ts3 TIMESTAMP DEFAULT 0,
dt3 DATETIME DEFAULT 0,
ts4 TIMESTAMP DEFAULT 0 ON UPDATE CURRENT_TIMESTAMP,
dt4 DATETIME DEFAULT 0 ON UPDATE CURRENT_TIMESTAMP,
ts5 TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
ts6 TIMESTAMP NULL ON UPDATE CURRENT_TIMESTAMP,
dt5 DATETIME ON UPDATE CURRENT_TIMESTAMP,
dt6 DATETIME NOT NULL ON UPDATE CURRENT_TIMESTAMP,
ts7 TIMESTAMP(6) DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
ts8 TIMESTAMP DEFAULT NOW(),
ts9 TIMESTAMP DEFAULT LOCALTIMESTAMP,
ts10 TIMESTAMP DEFAULT LOCALTIME,
ts11 TIMESTAMP DEFAULT LOCALTIMESTAMP(),
ts12 TIMESTAMP DEFAULT LOCALTIME()
)`)
exec(t, conn, "drop table function_default")

// this query works because utc_timestamp will get parenthesised before reaching MySQL. However, this syntax is not supported in MySQL 8.0
exec(t, conn, `create table function_default (ts TIMESTAMP DEFAULT UTC_TIMESTAMP)`)
exec(t, conn, "drop table function_default")

exec(t, conn, `create table function_default (x varchar(25) DEFAULT "check")`)
exec(t, conn, "drop table function_default")
}
Expand Down
41 changes: 18 additions & 23 deletions go/vt/sqlparser/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -2203,62 +2203,57 @@ func (ct *ColumnType) Format(buf *TrackedBuffer) {
buf.astPrintf(ct, "(%s)", strings.Join(ct.EnumValues, ", "))
}

opts := make([]string, 0, 16)
if ct.Unsigned {
opts = append(opts, keywordStrings[UNSIGNED])
buf.astPrintf(ct, " %s", keywordStrings[UNSIGNED])
}
if ct.Zerofill {
opts = append(opts, keywordStrings[ZEROFILL])
buf.astPrintf(ct, " %s", keywordStrings[ZEROFILL])
}
if ct.Charset != "" {
opts = append(opts, keywordStrings[CHARACTER], keywordStrings[SET], ct.Charset)
buf.astPrintf(ct, " %s %s %s", keywordStrings[CHARACTER], keywordStrings[SET], ct.Charset)
}
if ct.Collate != "" {
opts = append(opts, keywordStrings[COLLATE], ct.Collate)
buf.astPrintf(ct, " %s %s", keywordStrings[COLLATE], ct.Collate)
}
if ct.NotNull {
opts = append(opts, keywordStrings[NOT], keywordStrings[NULL])
buf.astPrintf(ct, " %s %s", keywordStrings[NOT], keywordStrings[NULL])
}
if ct.Default != nil {
opts = append(opts, keywordStrings[DEFAULT])
buf.astPrintf(ct, " %s", keywordStrings[DEFAULT])
_, isLiteral := ct.Default.(*Literal)
_, isNullVal := ct.Default.(*NullVal)
if isLiteral || isNullVal {
opts = append(opts, String(ct.Default))
if isLiteral || isNullVal || isExprAliasForCurrentTimeStamp(ct.Default) {
buf.astPrintf(ct, " %v", ct.Default)
} else {
opts = append(opts, "("+String(ct.Default)+")")
buf.astPrintf(ct, " (%v)", ct.Default)
}
}
if ct.OnUpdate != nil {
opts = append(opts, keywordStrings[ON], keywordStrings[UPDATE], String(ct.OnUpdate))
buf.astPrintf(ct, " %s %s %v", keywordStrings[ON], keywordStrings[UPDATE], ct.OnUpdate)
}
if ct.Autoincrement {
opts = append(opts, keywordStrings[AUTO_INCREMENT])
buf.astPrintf(ct, " %s", keywordStrings[AUTO_INCREMENT])
}
if ct.Comment != nil {
opts = append(opts, keywordStrings[COMMENT_KEYWORD], String(ct.Comment))
buf.astPrintf(ct, " %s %v", keywordStrings[COMMENT_KEYWORD], ct.Comment)
}
if ct.KeyOpt == colKeyPrimary {
opts = append(opts, keywordStrings[PRIMARY], keywordStrings[KEY])
buf.astPrintf(ct, " %s %s", keywordStrings[PRIMARY], keywordStrings[KEY])
}
if ct.KeyOpt == colKeyUnique {
opts = append(opts, keywordStrings[UNIQUE])
buf.astPrintf(ct, " %s", keywordStrings[UNIQUE])
}
if ct.KeyOpt == colKeyUniqueKey {
opts = append(opts, keywordStrings[UNIQUE], keywordStrings[KEY])
buf.astPrintf(ct, " %s %s", keywordStrings[UNIQUE], keywordStrings[KEY])
}
if ct.KeyOpt == colKeySpatialKey {
opts = append(opts, keywordStrings[SPATIAL], keywordStrings[KEY])
buf.astPrintf(ct, " %s %s", keywordStrings[SPATIAL], keywordStrings[KEY])
}
if ct.KeyOpt == colKeyFulltextKey {
opts = append(opts, keywordStrings[FULLTEXT], keywordStrings[KEY])
buf.astPrintf(ct, " %s %s", keywordStrings[FULLTEXT], keywordStrings[KEY])
}
if ct.KeyOpt == colKey {
opts = append(opts, keywordStrings[KEY])
}

if len(opts) != 0 {
buf.astPrintf(ct, " %s", strings.Join(opts, " "))
buf.astPrintf(ct, " %s", keywordStrings[KEY])
}
}

Expand Down
11 changes: 11 additions & 0 deletions go/vt/sqlparser/ast_funcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -1264,6 +1264,17 @@ func (lock LockOptionType) ToString() string {
}
}

// isExprAliasForCurrentTimeStamp returns true if the Expr provided is an alias for CURRENT_TIMESTAMP
func isExprAliasForCurrentTimeStamp(expr Expr) bool {
switch node := expr.(type) {
case *FuncExpr:
return node.Name.EqualString("current_timestamp") || node.Name.EqualString("now") || node.Name.EqualString("localtimestamp") || node.Name.EqualString("localtime")
case *CurTimeFuncExpr:
return node.Name.EqualString("current_timestamp") || node.Name.EqualString("now") || node.Name.EqualString("localtimestamp") || node.Name.EqualString("localtime")
}
return false
}

// AtCount represents the '@' count in ColIdent
type AtCount int

Expand Down
34 changes: 17 additions & 17 deletions go/vt/sqlparser/parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2639,7 +2639,7 @@ func TestCreateTable(t *testing.T) {
" s1 varchar default 'c',\n" +
" s2 varchar default 'this is a string',\n" +
" `s3` varchar default null,\n" +
" s4 timestamp default (current_timestamp()),\n" +
" s4 timestamp default current_timestamp(),\n" +
" s5 bit(1) default B'0'\n" +
")",
}, {
Expand All @@ -2666,7 +2666,7 @@ func TestCreateTable(t *testing.T) {
" email varchar unique,\n" +
" full_name varchar key,\n" +
" time1 timestamp on update current_timestamp(),\n" +
" time2 timestamp default (current_timestamp()) on update current_timestamp()\n" +
" time2 timestamp default current_timestamp() on update current_timestamp()\n" +
")",
}, {
// test current_timestamp with and without ()
Expand All @@ -2678,11 +2678,11 @@ func TestCreateTable(t *testing.T) {
" time5 timestamp(3) default current_timestamp(3) on update current_timestamp(3)\n" +
")",
output: "create table t (\n" +
" time1 timestamp default (current_timestamp()),\n" +
" time2 timestamp default (current_timestamp()),\n" +
" time3 timestamp default (current_timestamp()) on update current_timestamp(),\n" +
" time4 timestamp default (current_timestamp()) on update current_timestamp(),\n" +
" time5 timestamp(3) default (current_timestamp(3)) on update current_timestamp(3)\n" +
" time1 timestamp default current_timestamp(),\n" +
" time2 timestamp default current_timestamp(),\n" +
" time3 timestamp default current_timestamp() on update current_timestamp(),\n" +
" time4 timestamp default current_timestamp() on update current_timestamp(),\n" +
" time5 timestamp(3) default current_timestamp(3) on update current_timestamp(3)\n" +
")",
}, {
// test utc_timestamp with and without ()
Expand Down Expand Up @@ -2740,11 +2740,11 @@ func TestCreateTable(t *testing.T) {
" time5 timestamp(6) default localtime(6) on update localtime(6)\n" +
")",
output: "create table t (\n" +
" time1 timestamp default (localtime()),\n" +
" time2 timestamp default (localtime()),\n" +
" time3 timestamp default (localtime()) on update localtime(),\n" +
" time4 timestamp default (localtime()) on update localtime(),\n" +
" time5 timestamp(6) default (localtime(6)) on update localtime(6)\n" +
" time1 timestamp default localtime(),\n" +
" time2 timestamp default localtime(),\n" +
" time3 timestamp default localtime() on update localtime(),\n" +
" time4 timestamp default localtime() on update localtime(),\n" +
" time5 timestamp(6) default localtime(6) on update localtime(6)\n" +
")",
}, {
// test localtimestamp with and without ()
Expand All @@ -2756,11 +2756,11 @@ func TestCreateTable(t *testing.T) {
" time5 timestamp(1) default localtimestamp(1) on update localtimestamp(1)\n" +
")",
output: "create table t (\n" +
" time1 timestamp default (localtimestamp()),\n" +
" time2 timestamp default (localtimestamp()),\n" +
" time3 timestamp default (localtimestamp()) on update localtimestamp(),\n" +
" time4 timestamp default (localtimestamp()) on update localtimestamp(),\n" +
" time5 timestamp(1) default (localtimestamp(1)) on update localtimestamp(1)\n" +
" time1 timestamp default localtimestamp(),\n" +
" time2 timestamp default localtimestamp(),\n" +
" time3 timestamp default localtimestamp() on update localtimestamp(),\n" +
" time4 timestamp default localtimestamp() on update localtimestamp(),\n" +
" time5 timestamp(1) default localtimestamp(1) on update localtimestamp(1)\n" +
")",
}, {
// test current_date with and without ()
Expand Down