diff --git a/parser/parser.go b/parser/parser.go index b5b1acb4a6..894ab18b85 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -1403,7 +1403,7 @@ var ( 58380: 661, // SelectStmtFromDualTable (30x) 58381: 662, // SelectStmtFromTable (30x) 58170: 663, // FieldLen (26x) - 58238: 664, // Int64Num (25x) + 58238: 664, // Int64Num (24x) 58314: 665, // OptWindowingClause (22x) 57522: 666, // sqlCalcFoundRows (22x) 58476: 667, // UnionSelect (22x) @@ -6890,7 +6890,7 @@ var ( // 1345 {14, 14, 3: 14, 14, 14, 12: 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 40: 14, 42: 14, 60: 14, 65: 14, 14, 68: 14, 70: 14, 14, 14, 14, 14, 398: 14, 401: 14, 14, 417: 14, 562: 14, 14, 573: 14}, {424: 2240, 647: 3454, 664: 3460}, - {424: 2240, 647: 3454, 664: 3459}, + {424: 2240, 647: 3459}, {12, 12, 3: 12, 12, 12, 12: 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 40: 12, 42: 12, 60: 12, 65: 12, 12, 68: 12, 70: 12, 12, 12, 12, 12, 398: 12, 401: 12, 12, 417: 12, 562: 12, 12, 573: 12}, {13, 13, 3: 13, 13, 13, 12: 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 40: 13, 42: 13, 60: 13, 65: 13, 13, 68: 13, 70: 13, 13, 13, 13, 13, 398: 13, 401: 13, 13, 417: 13, 562: 13, 13, 573: 13}, // 1350 @@ -18061,7 +18061,16 @@ yynewstate: } case 2099: { - parser.yyVAL.item = -yyS[yypt-0].item.(int64) + unsigned_num := getUint64FromNUM(yyS[yypt-0].item) + if unsigned_num > 9223372036854775808 { + yylex.AppendError(yylex.Errorf("the Signed Value should be at the range of [-9223372036854775808, 9223372036854775807].")) + return 1 + } else if unsigned_num == 9223372036854775808 { + signed_one := int64(1) + parser.yyVAL.item = signed_one << 63 + } else { + parser.yyVAL.item = -int64(unsigned_num) + } } case 2100: { diff --git a/parser/parser.y b/parser/parser.y index c220897af1..383aaa95d0 100644 --- a/parser/parser.y +++ b/parser/parser.y @@ -11452,9 +11452,18 @@ SignedNum: { $$ = $2 } -| '-' Int64Num +| '-' NUM { - $$ = -$2.(int64) + unsigned_num := getUint64FromNUM($2) + if unsigned_num > 9223372036854775808 { + yylex.AppendError(yylex.Errorf("the Signed Value should be at the range of [-9223372036854775808, 9223372036854775807].")) + return 1 + } else if unsigned_num == 9223372036854775808 { + signed_one := int64(1) + $$ = signed_one << 63 + } else { + $$ = -int64(unsigned_num) + } } DropSequenceStmt: diff --git a/parser/parser_test.go b/parser/parser_test.go index 3a8278eab7..7f5b7895ae 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -861,6 +861,13 @@ AAAAAAAAAAAA5gm5Mg== // for alter instance. {"ALTER INSTANCE RELOAD TLS", true, "ALTER INSTANCE RELOAD TLS"}, {"ALTER INSTANCE RELOAD TLS NO ROLLBACK ON ERROR", true, "ALTER INSTANCE RELOAD TLS NO ROLLBACK ON ERROR"}, + + // for create sequence with signed value especially with Two's Complement Min. + // for issue #17948 + {"CREATE SEQUENCE seq INCREMENT - 9223372036854775807", true, "CREATE SEQUENCE `seq` INCREMENT BY -9223372036854775807"}, + {"CREATE SEQUENCE seq INCREMENT - 9223372036854775808", true, "CREATE SEQUENCE `seq` INCREMENT BY -9223372036854775808"}, + {"CREATE SEQUENCE seq INCREMENT -9223372036854775808", true, "CREATE SEQUENCE `seq` INCREMENT BY -9223372036854775808"}, + {"CREATE SEQUENCE seq INCREMENT -9223372036854775809", false, ""}, } s.RunTest(c, table) }