diff --git a/embedded/sql/engine_test.go b/embedded/sql/engine_test.go index ac18f9e9e9..0459162faa 100644 --- a/embedded/sql/engine_test.go +++ b/embedded/sql/engine_test.go @@ -3202,6 +3202,69 @@ func TestQuery(t *testing.T) { }) } +func TestExtractFromTimestamp(t *testing.T) { + st, err := store.Open(t.TempDir(), store.DefaultOptions().WithMultiIndexing(true)) + require.NoError(t, err) + defer closeStore(t, st) + + engine, err := NewEngine(st, DefaultOptions().WithPrefix(sqlPrefix)) + require.NoError(t, err) + + t.Run("extract from constant expressions", func(t *testing.T) { + assertQueryShouldProduceResults( + t, + engine, + `SELECT + EXTRACT(YEAR FROM '2020-01-15'), + EXTRACT(MONTH FROM '2020-01-15'), + EXTRACT(DAY FROM '2020-01-15'::TIMESTAMP), + EXTRACT(HOUR FROM '2020-01-15 12:30:24'), + EXTRACT(MINUTE FROM '2020-01-15 12:30:24'), + EXTRACT(SECOND FROM '2020-01-15 12:30:24'::TIMESTAMP) + `, + `SELECT * FROM ( + VALUES (2020, 01, 15, 12, 30, 24) + )`, + ) + }) + + t.Run("extract from table", func(t *testing.T) { + _, _, err := engine.Exec( + context.Background(), + nil, + `CREATE TABLE events(ts TIMESTAMP PRIMARY KEY); + + INSERT INTO events(ts) VALUES + ('2021-07-04 14:45:30'::TIMESTAMP), + ('1999-12-31 23:59:59'::TIMESTAMP); + `, + nil, + ) + require.NoError(t, err) + + assertQueryShouldProduceResults( + t, + engine, + `SELECT + EXTRACT(YEAR FROM ts), + EXTRACT(MONTH FROM ts), + EXTRACT(DAY FROM ts), + EXTRACT(HOUR FROM ts), + EXTRACT(MINUTE FROM ts), + EXTRACT(SECOND FROM ts) + FROM events + ORDER BY ts + `, + `SELECT * FROM ( + VALUES + (1999, 12, 31, 23, 59, 59), + (2021, 07, 04, 14, 45, 30) + )`, + ) + }) + +} + func TestJSON(t *testing.T) { opts := store.DefaultOptions().WithMultiIndexing(true) opts.WithIndexOptions(opts.IndexOpts.WithMaxActiveSnapshots(1)) diff --git a/embedded/sql/parser.go b/embedded/sql/parser.go index 73f4cd2223..239bb417fb 100644 --- a/embedded/sql/parser.go +++ b/embedded/sql/parser.go @@ -28,7 +28,7 @@ import ( //go:generate go run golang.org/x/tools/cmd/goyacc -l -o sql_parser.go sql_grammar.y -var reservedWords = map[string]int{ +var keywords = map[string]int{ "CREATE": CREATE, "DROP": DROP, "USE": USE, @@ -118,6 +118,21 @@ var reservedWords = map[string]int{ "THEN": THEN, "ELSE": ELSE, "END": END, + "EXTRACT": EXTRACT, + "INTEGER": INTEGER_TYPE, + "BOOLEAN": BOOLEAN_TYPE, + "VARCHAR": VARCHAR_TYPE, + "TIMESTAMP": TIMESTAMP_TYPE, + "FLOAT": FLOAT_TYPE, + "BLOB": BLOB_TYPE, + "UUID": UUID_TYPE, + "JSON": JSON_TYPE, + "YEAR": YEAR, + "MONTH": MONTH, + "DAY": DAY, + "HOUR": HOUR, + "MINUTE": MINUTE, + "SECOND": SECOND, } var joinTypes = map[string]JoinType{ @@ -126,17 +141,6 @@ var joinTypes = map[string]JoinType{ "RIGHT": RightJoin, } -var types = map[string]SQLValueType{ - "INTEGER": IntegerType, - "BOOLEAN": BooleanType, - "VARCHAR": VarcharType, - "UUID": UUIDType, - "BLOB": BLOBType, - "TIMESTAMP": TimestampType, - "FLOAT": Float64Type, - "JSON": JSONType, -} - var aggregateFns = map[string]AggregateFn{ "COUNT": COUNT, "SUM": SUM, @@ -321,7 +325,7 @@ func (l *lexer) Lex(lval *yySymType) int { } lval.blob = val - return BLOB + return BLOB_LIT } if isLetter(ch) { @@ -334,16 +338,10 @@ func (l *lexer) Lex(lval *yySymType) int { w := fmt.Sprintf("%c%s", ch, tail) tid := strings.ToUpper(w) - sqlType, ok := types[tid] - if ok { - lval.sqlType = sqlType - return TYPE - } - val, ok := boolValues[tid] if ok { lval.boolean = val - return BOOLEAN + return BOOLEAN_LIT } afn, ok := aggregateFns[tid] @@ -358,13 +356,13 @@ func (l *lexer) Lex(lval *yySymType) int { return JOINTYPE } - tkn, ok := reservedWords[tid] + tkn, ok := keywords[tid] if ok { + lval.keyword = w return tkn } lval.id = strings.ToLower(w) - return IDENTIFIER } @@ -409,7 +407,7 @@ func (l *lexer) Lex(lval *yySymType) int { } lval.float = val - return FLOAT + return FLOAT_LIT } val, err := strconv.ParseUint(fmt.Sprintf("%c%s", ch, tail), 10, 64) @@ -419,7 +417,7 @@ func (l *lexer) Lex(lval *yySymType) int { } lval.integer = val - return INTEGER + return INTEGER_LIT } if isComparison(ch) { @@ -452,7 +450,7 @@ func (l *lexer) Lex(lval *yySymType) int { } lval.str = tail - return VARCHAR + return VARCHAR_LIT } if ch == ':' { @@ -566,7 +564,7 @@ func (l *lexer) Lex(lval *yySymType) int { return ERROR } lval.float = val - return FLOAT + return FLOAT_LIT } return DOT } @@ -681,3 +679,35 @@ func isDoubleQuote(ch byte) bool { func isDot(ch byte) bool { return ch == '.' } + +func newCreateTableStmt( + name string, + elems []TableElem, + ifNotExists bool, +) *CreateTableStmt { + colsSpecs := make([]*ColSpec, 0, 5) + var checks []CheckConstraint + + var pk PrimaryKeyConstraint + for _, e := range elems { + switch c := e.(type) { + case *ColSpec: + colsSpecs = append(colsSpecs, c) + case PrimaryKeyConstraint: + pk = c + case CheckConstraint: + if checks == nil { + checks = make([]CheckConstraint, 0, 5) + } + checks = append(checks, c) + } + } + + return &CreateTableStmt{ + ifNotExists: ifNotExists, + table: name, + colsSpec: colsSpecs, + pkColNames: pk, + checks: checks, + } +} diff --git a/embedded/sql/parser_test.go b/embedded/sql/parser_test.go index 5879e680f3..3382c2c1b7 100644 --- a/embedded/sql/parser_test.go +++ b/embedded/sql/parser_test.go @@ -70,12 +70,12 @@ func TestUseDatabaseStmt(t *testing.T) { expectedError error }{ { - input: "USE db1", + input: "USE DATABASE db1", expectedOutput: []SQLStmt{&UseDatabaseStmt{DB: "db1"}}, expectedError: nil, }, { - input: "USE DATABASE db1", + input: "USE db1", expectedOutput: []SQLStmt{&UseDatabaseStmt{DB: "db1"}}, expectedError: nil, }, @@ -291,7 +291,7 @@ func TestCreateTableStmt(t *testing.T) { { input: "CREATE TABLE table1()", expectedOutput: []SQLStmt{&CreateTableStmt{table: "table1"}}, - expectedError: errors.New("syntax error: unexpected ')', expecting CONSTRAINT or PRIMARY or CHECK or IDENTIFIER at position 21"), + expectedError: errors.New("syntax error: unexpected ')' at position 21"), }, { input: "CREATE TABLE table1(id INTEGER, balance FLOAT, CONSTRAINT non_negative_balance CHECK (balance >= 0), PRIMARY KEY id)", @@ -371,7 +371,7 @@ func TestCreateIndexStmt(t *testing.T) { { input: "CREATE INDEX ON \"table(\"primary\")", expectedOutput: []SQLStmt{&CreateIndexStmt{table: "table", cols: []string{"primary"}}}, - expectedError: errors.New("syntax error: unexpected ERROR, expecting IDENTIFIER at position 22"), + expectedError: errors.New("syntax error: unexpected ERROR at position 22"), }, { input: "CREATE INDEX IF NOT EXISTS ON table1(id)", @@ -451,7 +451,7 @@ func TestAlterTable(t *testing.T) { { input: "ALTER TABLE table1 RENAME COLUMN TO newtitle", expectedOutput: nil, - expectedError: errors.New("syntax error: unexpected TO, expecting IDENTIFIER at position 35"), + expectedError: errors.New("syntax error: unexpected TO at position 35"), }, } @@ -684,15 +684,20 @@ func TestInsertIntoStmt(t *testing.T) { }, expectedError: nil, }, + { + input: "INSERT INTO table1() VALUES (2, 'untitled')", + expectedOutput: nil, + expectedError: errors.New("syntax error: unexpected ')' at position 20"), + }, { input: "UPSERT INTO table1() VALUES (2, 'untitled')", expectedOutput: nil, - expectedError: errors.New("syntax error: unexpected ')', expecting IDENTIFIER at position 20"), + expectedError: errors.New("syntax error: unexpected ')' at position 20"), }, { input: "UPSERT INTO VALUES (2)", expectedOutput: nil, - expectedError: errors.New("syntax error: unexpected VALUES, expecting IDENTIFIER at position 18"), + expectedError: errors.New("syntax error: unexpected VALUES at position 18"), }, } @@ -2101,6 +2106,12 @@ func TestExpString(t *testing.T) { "CASE WHEN is_active THEN 'active' WHEN is_expired THEN 'expired' ELSE 'active' END", "'text' LIKE 'pattern'", "'text' NOT LIKE 'pattern'", + "EXTRACT(YEAR FROM ts)", + "EXTRACT(MONTH FROM ts)", + "EXTRACT(DAY FROM ts)", + "EXTRACT(HOUR FROM ts)", + "EXTRACT(MINUTE FROM ts)", + "EXTRACT(SECOND FROM ts)", } for i, e := range exps { @@ -2157,3 +2168,296 @@ func TestLogicOperatorPrecedence(t *testing.T) { }) } } + +func TestParseUnreservedKeywords(t *testing.T) { + type testCase struct { + input string + expectedOutput []SQLStmt + } + + unreservedKeywords := []string{ + "admin", + "of", + "drop", + "database", + "snapshot", + "index", + "alter", + "add", + "rename", + "constraint", + "key", + "grant", + "revoke", + "privileges", + "begin", + "transaction", + "commit", + "rollback", + "insert", + "delete", + "update", + "conflict", + "if", + "show", + "tables", + "year", + "month", + "day", + "hour", + "minute", + "second", + "users", + } + + colNameKeywords := []string{ + "between", + "blob", + "boolean", + "exists", + "extract", + "float", + "integer", + "json", + "timestamp", + "values", + "varchar", + } + + getTableCases := func(kw string) []testCase { + return []testCase{ + { + input: fmt.Sprintf("CREATE TABLE %s (id INTEGER PRIMARY KEY);", kw), + expectedOutput: []SQLStmt{ + &CreateTableStmt{ + table: kw, + ifNotExists: false, + colsSpec: []*ColSpec{ + { + colName: "id", + colType: IntegerType, + notNull: true, + primaryKey: true, + }, + }, + }, + }, + }, + { + input: fmt.Sprintf("DROP TABLE %s;", kw), + expectedOutput: []SQLStmt{ + &DropTableStmt{ + table: kw, + }, + }, + }, + { + input: fmt.Sprintf("CREATE INDEX ON %s (id)", kw), + expectedOutput: []SQLStmt{ + &CreateIndexStmt{ + table: kw, + cols: []string{"id"}, + }, + }, + }, + { + input: fmt.Sprintf("CREATE UNIQUE INDEX ON %s (id)", kw), + expectedOutput: []SQLStmt{ + &CreateIndexStmt{ + table: kw, + unique: true, + cols: []string{"id"}, + }, + }, + }, + { + input: "DROP INDEX " + kw + "." + "id", + expectedOutput: []SQLStmt{ + &DropIndexStmt{ + table: kw, + cols: []string{"id"}, + }, + }, + }, + { + input: "ALTER TABLE " + kw + " ADD COLUMN id INTEGER NULL", + expectedOutput: []SQLStmt{ + &AddColumnStmt{ + table: kw, + colSpec: &ColSpec{ + colName: "id", + colType: IntegerType, + }, + }, + }, + }, + { + input: fmt.Sprintf("ALTER TABLE %s RENAME TO %s", kw, kw), + expectedOutput: []SQLStmt{ + &RenameTableStmt{ + oldName: kw, + newName: kw, + }, + }, + }, + { + input: fmt.Sprintf("ALTER TABLE %s RENAME COLUMN timestamp TO ts", kw), + expectedOutput: []SQLStmt{ + &RenameColumnStmt{ + table: kw, + oldName: "timestamp", + newName: "ts", + }, + }, + }, + { + input: fmt.Sprintf("ALTER TABLE %s DROP COLUMN timestamp", kw), + expectedOutput: []SQLStmt{ + &DropColumnStmt{ + table: kw, + colName: "timestamp", + }, + }, + }, + { + input: fmt.Sprintf("ALTER TABLE %s DROP CONSTRAINT pk_constraint", kw), + expectedOutput: []SQLStmt{ + &DropConstraintStmt{ + table: kw, + constraintName: "pk_constraint", + }, + }, + }, + } + } + + for _, kw := range unreservedKeywords { + tableCases := getTableCases(kw) + + for _, tc := range tableCases { + stmt, err := ParseSQLString(tc.input) + require.NoError(t, err) + require.Equal(t, tc.expectedOutput, stmt) + } + } + + for _, kw := range colNameKeywords { + tableCases := getTableCases(kw) + + for _, tc := range tableCases { + _, err := ParseSQLString(tc.input) + require.Error(t, err) + } + } + + allColNameKeywords := append(unreservedKeywords, colNameKeywords...) + + colCases := []testCase{} + + for _, kw := range allColNameKeywords { + colCases = append(colCases, []testCase{ + { + input: fmt.Sprintf("CREATE INDEX ON users (%s)", kw), + expectedOutput: []SQLStmt{ + &CreateIndexStmt{ + table: "users", + cols: []string{kw}, + }, + }, + }, + { + input: fmt.Sprintf("CREATE UNIQUE INDEX ON users (%s, %s)", kw, kw), + expectedOutput: []SQLStmt{ + &CreateIndexStmt{ + unique: true, + table: "users", + cols: []string{kw, kw}, + }, + }, + }, + { + input: fmt.Sprintf("DROP INDEX ON users (%s, %s)", kw, kw), + expectedOutput: []SQLStmt{ + &DropIndexStmt{ + table: "users", + cols: []string{kw, kw}, + }, + }, + }, + { + input: "DROP INDEX users." + kw, + expectedOutput: []SQLStmt{ + &DropIndexStmt{ + table: "users", + cols: []string{kw}, + }, + }, + }, + { + input: fmt.Sprintf("ALTER TABLE users RENAME COLUMN %s TO %s", kw, kw), + expectedOutput: []SQLStmt{ + &RenameColumnStmt{ + table: "users", + oldName: kw, + newName: kw, + }, + }, + }, + { + input: "ALTER TABLE users DROP COLUMN " + kw, + expectedOutput: []SQLStmt{ + &DropColumnStmt{ + table: "users", + colName: kw, + }, + }, + }, + { + input: fmt.Sprintf("CREATE TABLE users (%s INTEGER)", kw), + expectedOutput: []SQLStmt{ + &CreateTableStmt{ + table: "users", + colsSpec: []*ColSpec{ + { + colName: kw, + colType: IntegerType, + }, + }, + }, + }, + }, + { + input: fmt.Sprintf("INSERT INTO users (%s) VALUES ('')", kw), + expectedOutput: []SQLStmt{ + &UpsertIntoStmt{ + tableRef: &tableRef{table: "users"}, + cols: []string{kw}, + isInsert: true, + ds: &valuesDataSource{ + rows: []*RowSpec{{Values: []ValueExp{NewVarchar("")}}}, + }, + }, + }, + }, + { + input: fmt.Sprintf("UPSERT INTO users (%s) VALUES ('')", kw), + expectedOutput: []SQLStmt{ + &UpsertIntoStmt{ + tableRef: &tableRef{table: "users"}, + cols: []string{kw}, + ds: &valuesDataSource{ + rows: []*RowSpec{{Values: []ValueExp{NewVarchar("")}}}, + }, + }, + }, + }, + }..., + ) + } + + for _, tc := range colCases { + stmt, err := ParseSQLString(tc.input) + require.NoError(t, err) + require.Equal(t, tc.expectedOutput, stmt) + } +} diff --git a/embedded/sql/sql_grammar.y b/embedded/sql/sql_grammar.y index e32f06733a..b33f92e791 100644 --- a/embedded/sql/sql_grammar.y +++ b/embedded/sql/sql_grammar.y @@ -40,9 +40,10 @@ func setResult(l yyLexer, stmts []SQLStmt) { str string boolean bool blob []byte + keyword string sqlType SQLValueType aggFn AggregateFn - ids []string + colNames []string col *ColSelector sel Selector targets []TargetEntry @@ -74,17 +75,21 @@ func setResult(l yyLexer, stmts []SQLStmt) { whenThenClauses []whenThenClause tableElem TableElem tableElems []TableElem + timestampField TimestampFieldType } -%token CREATE DROP USE DATABASE USER WITH PASSWORD READ READWRITE ADMIN SNAPSHOT HISTORY SINCE AFTER BEFORE UNTIL TX OF TIMESTAMP -%token TABLE UNIQUE INDEX ON ALTER ADD RENAME TO COLUMN CONSTRAINT PRIMARY KEY CHECK GRANT REVOKE GRANTS FOR PRIVILEGES -%token BEGIN TRANSACTION COMMIT ROLLBACK -%token INSERT UPSERT INTO VALUES DELETE UPDATE SET CONFLICT DO NOTHING RETURNING -%token SELECT DISTINCT FROM JOIN HAVING WHERE GROUP BY LIMIT OFFSET ORDER ASC DESC AS UNION ALL CASE WHEN THEN ELSE END -%token NOT LIKE IF EXISTS IN IS -%token AUTO_INCREMENT NULL CAST SCAST -%token SHOW DATABASES TABLES USERS -%token BETWEEN +%token CREATE DROP USE DATABASE USER WITH PASSWORD READ READWRITE ADMIN SNAPSHOT HISTORY SINCE AFTER BEFORE UNTIL TX OF +%token INTEGER_TYPE BOOLEAN_TYPE VARCHAR_TYPE UUID_TYPE BLOB_TYPE TIMESTAMP_TYPE FLOAT_TYPE JSON_TYPE +%token TABLE UNIQUE INDEX ON ALTER ADD RENAME TO COLUMN CONSTRAINT PRIMARY KEY CHECK GRANT REVOKE GRANTS FOR PRIVILEGES +%token BEGIN TRANSACTION COMMIT ROLLBACK +%token INSERT UPSERT INTO VALUES DELETE UPDATE SET CONFLICT DO NOTHING RETURNING +%token SELECT DISTINCT FROM JOIN HAVING WHERE GROUP BY LIMIT OFFSET ORDER ASC DESC AS UNION ALL CASE WHEN THEN ELSE END +%token NOT LIKE IF EXISTS IN IS +%token AUTO_INCREMENT NULL CAST SCAST +%token SHOW DATABASES TABLES USERS +%token BETWEEN +%token EXTRACT YEAR MONTH DAY HOUR MINUTE SECOND + %token NPARAM %token PPARAM %token JOINTYPE @@ -92,12 +97,11 @@ func setResult(l yyLexer, stmts []SQLStmt) { %token CMPOP %token NOT_MATCHES_OP %token IDENTIFIER -%token TYPE -%token INTEGER -%token FLOAT -%token VARCHAR -%token BOOLEAN -%token BLOB +%token INTEGER_LIT +%token FLOAT_LIT +%token VARCHAR_LIT +%token BOOLEAN_LIT +%token BLOB_LIT %token AGGREGATE_FUNC %token ERROR %token DOT @@ -124,7 +128,7 @@ func setResult(l yyLexer, stmts []SQLStmt) { %type sql sqlstmts %type sqlstmt ddlstmt dmlstmt dqlstmt select_stmt %type colSpec -%type ids one_or_more_ids opt_ids +%type col_names insert_cols one_or_more_col_names %type cols %type rows %type row @@ -155,7 +159,7 @@ mulExp unaryExp primary %type opt_as %type ordexps opt_orderby %type opt_ord -%type opt_indexon +%type opt_indexon %type opt_if_not_exists opt_auto_increment opt_not_null opt_not opt_primary_key %type update %type updates @@ -164,6 +168,10 @@ mulExp unaryExp primary %type sqlPrivilege %type sqlPrivileges %type when_then_clauses +%type timestamp_field +%type sql_type +%type unreserved_keyword colNameKeyword +%type qualifiedName tableName col_name %start sql @@ -211,9 +219,14 @@ ddlstmt: $$ = &RollbackStmt{} } | - CREATE DATABASE opt_if_not_exists IDENTIFIER + CREATE DATABASE IF NOT EXISTS IDENTIFIER + { + $$ = &CreateDatabaseStmt{ifNotExists: true, DB: $6} + } +| + CREATE DATABASE IDENTIFIER { - $$ = &CreateDatabaseStmt{ifNotExists: $3, DB: $4} + $$ = &CreateDatabaseStmt{ifNotExists: false, DB: $3} } | USE IDENTIFIER @@ -231,92 +244,72 @@ ddlstmt: $$ = &UseSnapshotStmt{period: $3} } | - CREATE TABLE opt_if_not_exists IDENTIFIER '(' tableElems ')' + CREATE TABLE IF NOT EXISTS tableName '(' tableElems ')' { - colsSpecs := make([]*ColSpec, 0, 5) - var checks []CheckConstraint - - var pk PrimaryKeyConstraint - - for _, e := range $6 { - switch c := e.(type) { - case *ColSpec: - colsSpecs = append(colsSpecs, c) - case PrimaryKeyConstraint: - pk = c - case CheckConstraint: - if checks == nil { - checks = make([]CheckConstraint, 0, 5) - } - checks = append(checks, c) - } - } - - $$ = &CreateTableStmt{ - ifNotExists: $3, - table: $4, - colsSpec: colsSpecs, - pkColNames: pk, - checks: checks, - } + $$ = newCreateTableStmt($6, $8, true) } | - DROP TABLE IDENTIFIER + CREATE TABLE tableName '(' tableElems ')' + { + $$ = newCreateTableStmt($3, $5, false) + } +| + DROP TABLE qualifiedName { $$ = &DropTableStmt{table: $3} } | - CREATE INDEX opt_if_not_exists ON IDENTIFIER '(' ids ')' + CREATE INDEX opt_if_not_exists ON tableName '(' col_names ')' { $$ = &CreateIndexStmt{ifNotExists: $3, table: $5, cols: $7} } | - CREATE UNIQUE INDEX opt_if_not_exists ON IDENTIFIER '(' ids ')' + CREATE UNIQUE INDEX opt_if_not_exists ON tableName '(' col_names ')' { $$ = &CreateIndexStmt{unique: true, ifNotExists: $4, table: $6, cols: $8} } | - DROP INDEX ON IDENTIFIER '(' ids ')' + DROP INDEX ON tableName '(' col_names ')' { $$ = &DropIndexStmt{table: $4, cols: $6} } | - DROP INDEX IDENTIFIER DOT IDENTIFIER + DROP INDEX tableName DOT col_name { $$ = &DropIndexStmt{table: $3, cols: []string{$5}} } | - ALTER TABLE IDENTIFIER ADD COLUMN colSpec + ALTER TABLE tableName ADD COLUMN colSpec { $$ = &AddColumnStmt{table: $3, colSpec: $6} } | - ALTER TABLE IDENTIFIER RENAME TO IDENTIFIER + ALTER TABLE tableName RENAME TO tableName { $$ = &RenameTableStmt{oldName: $3, newName: $6} } | - ALTER TABLE IDENTIFIER RENAME COLUMN IDENTIFIER TO IDENTIFIER + ALTER TABLE tableName RENAME COLUMN col_name TO col_name { $$ = &RenameColumnStmt{table: $3, oldName: $6, newName: $8} } | - ALTER TABLE IDENTIFIER DROP COLUMN IDENTIFIER + ALTER TABLE tableName DROP COLUMN col_name { $$ = &DropColumnStmt{table: $3, colName: $6} } | - ALTER TABLE IDENTIFIER DROP CONSTRAINT IDENTIFIER + ALTER TABLE tableName DROP CONSTRAINT IDENTIFIER { $$ = &DropConstraintStmt{table: $3, constraintName: $6} } | - CREATE USER IDENTIFIER WITH PASSWORD VARCHAR permission + CREATE USER IDENTIFIER WITH PASSWORD VARCHAR_LIT permission { $$ = &CreateUserStmt{username: $3, password: $6, permission: $7} } | - ALTER USER IDENTIFIER WITH PASSWORD VARCHAR permission + ALTER USER IDENTIFIER WITH PASSWORD VARCHAR_LIT permission { $$ = &AlterUserStmt{username: $3, password: $6, permission: $7} } @@ -326,15 +319,16 @@ ddlstmt: $$ = &DropUserStmt{username: $3} } | - GRANT sqlPrivileges ON DATABASE IDENTIFIER TO USER IDENTIFIER + GRANT sqlPrivileges ON DATABASE qualifiedName TO USER IDENTIFIER { $$ = &AlterPrivilegesStmt{database: $5, user: $8, privileges: $2, isGrant: true} } | - REVOKE sqlPrivileges ON DATABASE IDENTIFIER TO USER IDENTIFIER + REVOKE sqlPrivileges ON DATABASE qualifiedName TO USER IDENTIFIER { $$ = &AlterPrivilegesStmt{database: $5, user: $8, privileges: $2} } +; sqlPrivileges: ALL PRIVILEGES @@ -387,6 +381,7 @@ sqlPrivilege: { $$ = SQLPrivilegeAlter } +; permission: { @@ -407,6 +402,7 @@ permission: { $$ = PermissionAdmin } +; opt_if_not_exists: { @@ -417,27 +413,17 @@ opt_if_not_exists: { $$ = true } - -one_or_more_ids: - IDENTIFIER - { - $$ = []string{$1} - } -| - '(' ids ')' - { - $$ = $2 - } +; dmlstmt: - INSERT INTO tableRef '(' opt_ids ')' values_or_query opt_on_conflict + INSERT INTO tableRef insert_cols values_or_query opt_on_conflict { - $$ = &UpsertIntoStmt{isInsert: true, tableRef: $3, cols: $5, ds: $7, onConflict: $8} + $$ = &UpsertIntoStmt{isInsert: true, tableRef: $3, cols: $4, ds: $5, onConflict: $6} } | - UPSERT INTO tableRef '(' ids ')' values_or_query + UPSERT INTO tableRef insert_cols values_or_query { - $$ = &UpsertIntoStmt{tableRef: $3, cols: $5, ds: $7} + $$ = &UpsertIntoStmt{tableRef: $3, cols: $4, ds: $5} } | DELETE FROM tableRef opt_where opt_indexon opt_limit opt_offset @@ -489,16 +475,6 @@ update: $$ = &colUpdate{col: $1, op: $2, val: $3} } -opt_ids: - { - $$ = nil - } -| - ids - { - $$ = $1 - } - rows: row { @@ -516,17 +492,6 @@ row: $$ = &RowSpec{Values: $2} } -ids: - IDENTIFIER - { - $$ = []string{$1} - } -| - ids ',' IDENTIFIER - { - $$ = append($1, $3) - } - cols: col { @@ -560,32 +525,32 @@ values: } val: - INTEGER + INTEGER_LIT { $$ = &Integer{val: int64($1)} } | - FLOAT + FLOAT_LIT { $$ = &Float64{val: float64($1)} } | - VARCHAR + VARCHAR_LIT { $$ = &Varchar{val: $1} } | - BOOLEAN + BOOLEAN_LIT { $$ = &Bool{val:$1} } | - BLOB + BLOB_LIT { $$ = &Blob{val: $1} } | - CAST '(' exp AS TYPE ')' + CAST '(' exp AS sql_type ')' { $$ = &Cast{val: $3, t: $5} } @@ -609,6 +574,18 @@ val: { $$ = &NullValue{t: AnyType} } +; + +sql_type: + INTEGER_TYPE { $$ = IntegerType } + | BOOLEAN_TYPE { $$ = BooleanType } + | VARCHAR_TYPE { $$ = VarcharType } + | UUID_TYPE { $$ = UUIDType } + | BLOB_TYPE { $$ = BLOBType } + | TIMESTAMP_TYPE { $$ = TimestampType } + | FLOAT_TYPE { $$ = Float64Type } + | JSON_TYPE { $$ = JSONType } +; fnCall: IDENTIFIER '(' opt_values ')' @@ -638,17 +615,25 @@ tableElem: $$ = $1 } | - PRIMARY KEY one_or_more_ids + PRIMARY KEY one_or_more_col_names { $$ = PrimaryKeyConstraint($3) } ; colSpec: - IDENTIFIER TYPE opt_max_len opt_not_null opt_auto_increment opt_primary_key - { - $$ = &ColSpec{colName: $1, colType: $2, maxLen: int($3), notNull: $4 || $6, autoIncrement: $5, primaryKey: $6} + col_name sql_type opt_max_len opt_not_null opt_auto_increment opt_primary_key + { + $$ = &ColSpec{ + colName: $1, + colType: $2, + maxLen: int($3), + notNull: $4 || $6, + autoIncrement: $5, + primaryKey: $6, + } } +; opt_primary_key: { @@ -666,12 +651,12 @@ opt_max_len: $$ = 0 } | - '[' INTEGER ']' + '[' INTEGER_LIT ']' { $$ = $2 } | - '(' INTEGER ')' + '(' INTEGER_LIT ')' { $$ = $2 } @@ -849,26 +834,114 @@ selector: } jsonFields: - ARROW VARCHAR + ARROW VARCHAR_LIT { $$ = []string{$2} } | - jsonFields ARROW VARCHAR + jsonFields ARROW VARCHAR_LIT { $$ = append($$, $3) } col: - IDENTIFIER + col_name { $$ = &ColSelector{col: $1} } | - IDENTIFIER DOT IDENTIFIER + col_name DOT col_name { $$ = &ColSelector{table: $1, col: $3} } +; + +tableName: qualifiedName; + +col_name: + qualifiedName +| + colNameKeyword { $$ = $1 } +; + +col_names: + col_name { $$ = []string{$1} } +| + col_names ',' col_name { $$ = append($1, $3) } +; + +one_or_more_col_names: + col_name + { + $$ = []string{$1} + } +| + '(' col_names ')' + { + $$ = $2 + } +; + +insert_cols: + { $$ = nil } +| + '(' col_names ')' { $$ = $2 } +; + + +colNameKeyword: + BETWEEN + | BLOB_TYPE + | BOOLEAN_TYPE + | EXISTS + | EXTRACT + | FLOAT_TYPE + | INTEGER_TYPE + | JSON_TYPE + | TIMESTAMP_TYPE + | VALUES + | VARCHAR_TYPE +; + +qualifiedName: + IDENTIFIER { $$ = $1 } + | unreserved_keyword { $$ = string($1) } +; + +unreserved_keyword: + ADMIN + | OF + | DROP + | DATABASE + | SNAPSHOT + | INDEX + | ALTER + | ADD + | RENAME + | CONSTRAINT + | KEY + | GRANT + | REVOKE + | PRIVILEGES + | BEGIN + | TRANSACTION + | COMMIT + | ROLLBACK + | INSERT + | DELETE + | UPDATE + | CONFLICT + | IF + | SHOW + | TABLES + | YEAR + | MONTH + | DAY + | HOUR + | MINUTE + | SECOND + | USERS +; ds: tableRef opt_period opt_as @@ -920,7 +993,7 @@ ds: } tableRef: - IDENTIFIER + qualifiedName { $$ = &tableRef{table: $1} } @@ -1074,10 +1147,11 @@ opt_indexon: $$ = nil } | - USE INDEX ON one_or_more_ids + USE INDEX ON one_or_more_col_names { $$ = $4 } +; ordexps: exp opt_ord @@ -1110,15 +1184,16 @@ opt_as: $$ = "" } | - IDENTIFIER + qualifiedName { $$ = $1 } | - AS IDENTIFIER + AS qualifiedName { $$ = $2 } +; check: CHECK exp @@ -1272,10 +1347,16 @@ boundexp: $$ = $1 } | - boundexp SCAST TYPE + boundexp SCAST sql_type { $$ = &Cast{val: $1, t: $3} } +| + EXTRACT '(' timestamp_field FROM exp ')' + { + $$ = &ExtractFromTimestampExp{Field: $3, Exp: $5} + } +; opt_not: { @@ -1286,4 +1367,13 @@ opt_not: { $$ = true } +; +timestamp_field: + YEAR { $$ = TimestampFieldTypeYear; } + | MONTH { $$ = TimestampFieldTypeMonth; } + | DAY { $$ = TimestampFieldTypeDay; } + | HOUR { $$ = TimestampFieldTypeHour; } + | MINUTE { $$ = TimestampFieldTypeMinute; } + | SECOND { $$ = TimestampFieldTypeSecond; } +; diff --git a/embedded/sql/sql_parser.go b/embedded/sql/sql_parser.go index ebb50c6bca..ade0e7ea05 100644 --- a/embedded/sql/sql_parser.go +++ b/embedded/sql/sql_parser.go @@ -26,9 +26,10 @@ type yySymType struct { str string boolean bool blob []byte + keyword string sqlType SQLValueType aggFn AggregateFn - ids []string + colNames []string col *ColSelector sel Selector targets []TargetEntry @@ -60,6 +61,7 @@ type yySymType struct { whenThenClauses []whenThenClause tableElem TableElem tableElems []TableElem + timestampField TimestampFieldType } const CREATE = 57346 @@ -80,95 +82,108 @@ const BEFORE = 57360 const UNTIL = 57361 const TX = 57362 const OF = 57363 -const TIMESTAMP = 57364 -const TABLE = 57365 -const UNIQUE = 57366 -const INDEX = 57367 -const ON = 57368 -const ALTER = 57369 -const ADD = 57370 -const RENAME = 57371 -const TO = 57372 -const COLUMN = 57373 -const CONSTRAINT = 57374 -const PRIMARY = 57375 -const KEY = 57376 -const CHECK = 57377 -const GRANT = 57378 -const REVOKE = 57379 -const GRANTS = 57380 -const FOR = 57381 -const PRIVILEGES = 57382 -const BEGIN = 57383 -const TRANSACTION = 57384 -const COMMIT = 57385 -const ROLLBACK = 57386 -const INSERT = 57387 -const UPSERT = 57388 -const INTO = 57389 -const VALUES = 57390 -const DELETE = 57391 -const UPDATE = 57392 -const SET = 57393 -const CONFLICT = 57394 -const DO = 57395 -const NOTHING = 57396 -const RETURNING = 57397 -const SELECT = 57398 -const DISTINCT = 57399 -const FROM = 57400 -const JOIN = 57401 -const HAVING = 57402 -const WHERE = 57403 -const GROUP = 57404 -const BY = 57405 -const LIMIT = 57406 -const OFFSET = 57407 -const ORDER = 57408 -const ASC = 57409 -const DESC = 57410 -const AS = 57411 -const UNION = 57412 -const ALL = 57413 -const CASE = 57414 -const WHEN = 57415 -const THEN = 57416 -const ELSE = 57417 -const END = 57418 -const NOT = 57419 -const LIKE = 57420 -const IF = 57421 -const EXISTS = 57422 -const IN = 57423 -const IS = 57424 -const AUTO_INCREMENT = 57425 -const NULL = 57426 -const CAST = 57427 -const SCAST = 57428 -const SHOW = 57429 -const DATABASES = 57430 -const TABLES = 57431 -const USERS = 57432 -const BETWEEN = 57433 -const NPARAM = 57434 -const PPARAM = 57435 -const JOINTYPE = 57436 -const AND = 57437 -const OR = 57438 -const CMPOP = 57439 -const NOT_MATCHES_OP = 57440 -const IDENTIFIER = 57441 -const TYPE = 57442 -const INTEGER = 57443 -const FLOAT = 57444 -const VARCHAR = 57445 -const BOOLEAN = 57446 -const BLOB = 57447 -const AGGREGATE_FUNC = 57448 -const ERROR = 57449 -const DOT = 57450 -const ARROW = 57451 -const STMT_SEPARATOR = 57452 +const INTEGER_TYPE = 57364 +const BOOLEAN_TYPE = 57365 +const VARCHAR_TYPE = 57366 +const UUID_TYPE = 57367 +const BLOB_TYPE = 57368 +const TIMESTAMP_TYPE = 57369 +const FLOAT_TYPE = 57370 +const JSON_TYPE = 57371 +const TABLE = 57372 +const UNIQUE = 57373 +const INDEX = 57374 +const ON = 57375 +const ALTER = 57376 +const ADD = 57377 +const RENAME = 57378 +const TO = 57379 +const COLUMN = 57380 +const CONSTRAINT = 57381 +const PRIMARY = 57382 +const KEY = 57383 +const CHECK = 57384 +const GRANT = 57385 +const REVOKE = 57386 +const GRANTS = 57387 +const FOR = 57388 +const PRIVILEGES = 57389 +const BEGIN = 57390 +const TRANSACTION = 57391 +const COMMIT = 57392 +const ROLLBACK = 57393 +const INSERT = 57394 +const UPSERT = 57395 +const INTO = 57396 +const VALUES = 57397 +const DELETE = 57398 +const UPDATE = 57399 +const SET = 57400 +const CONFLICT = 57401 +const DO = 57402 +const NOTHING = 57403 +const RETURNING = 57404 +const SELECT = 57405 +const DISTINCT = 57406 +const FROM = 57407 +const JOIN = 57408 +const HAVING = 57409 +const WHERE = 57410 +const GROUP = 57411 +const BY = 57412 +const LIMIT = 57413 +const OFFSET = 57414 +const ORDER = 57415 +const ASC = 57416 +const DESC = 57417 +const AS = 57418 +const UNION = 57419 +const ALL = 57420 +const CASE = 57421 +const WHEN = 57422 +const THEN = 57423 +const ELSE = 57424 +const END = 57425 +const NOT = 57426 +const LIKE = 57427 +const IF = 57428 +const EXISTS = 57429 +const IN = 57430 +const IS = 57431 +const AUTO_INCREMENT = 57432 +const NULL = 57433 +const CAST = 57434 +const SCAST = 57435 +const SHOW = 57436 +const DATABASES = 57437 +const TABLES = 57438 +const USERS = 57439 +const BETWEEN = 57440 +const EXTRACT = 57441 +const YEAR = 57442 +const MONTH = 57443 +const DAY = 57444 +const HOUR = 57445 +const MINUTE = 57446 +const SECOND = 57447 +const NPARAM = 57448 +const PPARAM = 57449 +const JOINTYPE = 57450 +const AND = 57451 +const OR = 57452 +const CMPOP = 57453 +const NOT_MATCHES_OP = 57454 +const IDENTIFIER = 57455 +const INTEGER_LIT = 57456 +const FLOAT_LIT = 57457 +const VARCHAR_LIT = 57458 +const BOOLEAN_LIT = 57459 +const BLOB_LIT = 57460 +const AGGREGATE_FUNC = 57461 +const ERROR = 57462 +const DOT = 57463 +const ARROW = 57464 +const STMT_SEPARATOR = 57465 var yyToknames = [...]string{ "$end", @@ -192,7 +207,14 @@ var yyToknames = [...]string{ "UNTIL", "TX", "OF", - "TIMESTAMP", + "INTEGER_TYPE", + "BOOLEAN_TYPE", + "VARCHAR_TYPE", + "UUID_TYPE", + "BLOB_TYPE", + "TIMESTAMP_TYPE", + "FLOAT_TYPE", + "JSON_TYPE", "TABLE", "UNIQUE", "INDEX", @@ -262,6 +284,13 @@ var yyToknames = [...]string{ "TABLES", "USERS", "BETWEEN", + "EXTRACT", + "YEAR", + "MONTH", + "DAY", + "HOUR", + "MINUTE", + "SECOND", "NPARAM", "PPARAM", "JOINTYPE", @@ -270,12 +299,11 @@ var yyToknames = [...]string{ "CMPOP", "NOT_MATCHES_OP", "IDENTIFIER", - "TYPE", - "INTEGER", - "FLOAT", - "VARCHAR", - "BOOLEAN", - "BLOB", + "INTEGER_LIT", + "FLOAT_LIT", + "VARCHAR_LIT", + "BOOLEAN_LIT", + "BLOB_LIT", "AGGREGATE_FUNC", "ERROR", "DOT", @@ -304,301 +332,470 @@ var yyExca = [...]int16{ -1, 1, 1, -1, -2, 0, - -1, 102, - 78, 218, - 81, 218, - -2, 203, - -1, 287, - 59, 152, - -2, 147, - -1, 342, - 59, 152, - -2, 149, + -1, 139, + 85, 277, + 88, 277, + -2, 261, + -1, 370, + 66, 210, + -2, 205, + -1, 428, + 66, 210, + -2, 207, } const yyPrivate = 57344 -const yyLast = 540 +const yyLast = 1864 var yyAct = [...]int16{ - 139, 447, 335, 115, 281, 161, 212, 123, 347, 341, - 218, 209, 254, 152, 365, 346, 259, 6, 255, 330, - 71, 321, 155, 102, 107, 260, 99, 22, 137, 98, - 104, 420, 279, 370, 223, 369, 279, 312, 386, 421, - 279, 416, 414, 108, 279, 407, 396, 387, 100, 372, - 413, 105, 314, 325, 399, 126, 122, 279, 21, 138, - 395, 313, 96, 124, 125, 393, 280, 366, 354, 352, - 127, 351, 117, 118, 119, 120, 121, 116, 349, 311, - 309, 308, 302, 109, 278, 246, 367, 189, 348, 111, - 320, 301, 188, 295, 294, 293, 292, 188, 266, 221, - 222, 224, 198, 140, 191, 187, 186, 157, 178, 180, - 226, 108, 182, 151, 150, 24, 100, 172, 173, 105, - 175, 176, 177, 126, 122, 153, 446, 166, 440, 220, - 299, 124, 125, 386, 181, 252, 312, 279, 127, 197, - 117, 118, 119, 120, 121, 116, 172, 173, 160, 250, - 83, 109, 248, 185, 214, 189, 142, 111, 307, 275, - 268, 227, 249, 211, 195, 196, 405, 225, 215, 404, - 362, 32, 316, 247, 216, 163, 265, 262, 33, 264, - 252, 210, 390, 376, 375, 374, 353, 76, 253, 256, - 251, 231, 230, 234, 229, 237, 243, 333, 318, 156, - 240, 241, 242, 238, 239, 162, 274, 174, 273, 272, - 269, 271, 168, 263, 267, 257, 228, 207, 286, 206, - 199, 169, 284, 192, 108, 287, 270, 167, 171, 100, - 158, 296, 105, 297, 141, 130, 126, 122, 290, 285, - 288, 172, 173, 263, 124, 125, 306, 128, 91, 54, - 80, 127, 79, 117, 118, 119, 120, 121, 116, 300, - 77, 78, 75, 31, 109, 317, 70, 69, 217, 164, - 111, 165, 344, 58, 183, 403, 291, 233, 319, 331, - 22, 419, 402, 337, 232, 39, 298, 22, 60, 339, - 418, 190, 235, 129, 345, 236, 332, 327, 332, 65, - 334, 49, 256, 358, 397, 359, 360, 126, 122, 289, - 304, 21, 305, 363, 361, 124, 125, 22, 21, 356, - 357, 245, 127, 355, 117, 118, 119, 120, 121, 116, - 90, 364, 373, 55, 310, 109, 64, 380, 56, 57, - 59, 111, 382, 448, 449, 432, 336, 379, 21, 256, - 282, 439, 384, 381, 383, 389, 425, 391, 392, 410, - 394, 388, 398, 153, 66, 67, 424, 385, 159, 148, - 108, 52, 406, 62, 430, 100, 422, 408, 105, 400, - 88, 51, 126, 122, 50, 25, 43, 47, 82, 92, - 124, 125, 371, 225, 437, 412, 411, 127, 415, 117, - 118, 119, 120, 121, 116, 132, 315, 429, 200, 48, - 109, 94, 203, 204, 201, 202, 111, 326, 426, 219, - 427, 277, 10, 12, 11, 433, 145, 44, 276, 435, - 436, 46, 45, 378, 338, 193, 438, 441, 42, 53, - 444, 442, 131, 36, 445, 13, 84, 450, 81, 143, - 144, 283, 451, 40, 14, 15, 68, 350, 34, 7, - 35, 8, 9, 16, 17, 26, 30, 18, 19, 2, - 85, 86, 87, 38, 22, 136, 135, 73, 74, 205, - 194, 27, 29, 28, 322, 323, 324, 146, 37, 133, - 329, 328, 149, 147, 63, 213, 23, 244, 41, 377, - 154, 428, 170, 401, 417, 21, 431, 443, 368, 95, - 93, 106, 409, 110, 103, 101, 97, 303, 112, 423, - 179, 258, 261, 343, 342, 340, 134, 72, 89, 61, - 184, 113, 114, 434, 208, 20, 5, 4, 3, 1, + 190, 522, 167, 421, 153, 278, 213, 161, 364, 284, + 204, 360, 275, 246, 312, 427, 335, 359, 6, 334, + 408, 399, 54, 247, 108, 207, 248, 101, 136, 272, + 102, 490, 497, 135, 139, 144, 188, 112, 102, 404, + 102, 403, 362, 362, 141, 491, 484, 340, 396, 483, + 418, 492, 486, 54, 54, 54, 485, 480, 165, 472, + 362, 362, 362, 114, 340, 116, 479, 477, 465, 458, + 412, 363, 438, 339, 436, 435, 433, 395, 393, 392, + 385, 59, 311, 60, 361, 407, 397, 384, 378, 57, + 61, 377, 376, 375, 345, 262, 133, 58, 173, 171, + 177, 243, 170, 175, 172, 174, 241, 240, 62, 237, + 63, 64, 65, 230, 202, 66, 102, 67, 180, 68, + 69, 24, 521, 70, 71, 72, 73, 74, 75, 224, + 225, 176, 76, 77, 328, 78, 214, 227, 228, 229, + 382, 192, 205, 201, 515, 209, 232, 418, 191, 235, + 396, 212, 120, 39, 239, 224, 225, 242, 193, 391, + 354, 347, 79, 234, 329, 456, 218, 455, 98, 49, + 80, 474, 81, 88, 169, 254, 82, 83, 84, 85, + 86, 87, 233, 462, 102, 461, 437, 216, 226, 55, + 261, 32, 208, 220, 353, 99, 344, 282, 33, 337, + 210, 270, 221, 271, 128, 117, 280, 401, 115, 255, + 107, 106, 283, 292, 54, 219, 223, 281, 293, 291, + 274, 217, 274, 259, 260, 430, 22, 103, 224, 225, + 236, 454, 273, 277, 298, 489, 381, 104, 453, 251, + 22, 297, 332, 488, 336, 331, 295, 92, 102, 308, + 294, 256, 263, 343, 296, 245, 299, 21, 302, 244, + 102, 276, 94, 305, 306, 307, 342, 203, 102, 303, + 304, 21, 182, 338, 199, 348, 322, 323, 324, 325, + 326, 327, 443, 300, 369, 346, 301, 367, 374, 179, + 370, 349, 178, 350, 214, 214, 481, 31, 379, 380, + 446, 333, 10, 12, 11, 373, 310, 387, 368, 388, + 371, 389, 90, 91, 93, 127, 89, 523, 524, 508, + 394, 276, 422, 251, 365, 351, 352, 514, 372, 503, + 495, 205, 13, 183, 502, 383, 22, 471, 493, 390, + 211, 14, 15, 52, 96, 463, 7, 417, 8, 9, + 16, 17, 125, 51, 18, 19, 50, 25, 406, 119, + 129, 22, 336, 405, 398, 506, 423, 21, 341, 500, + 267, 268, 265, 266, 214, 414, 425, 264, 431, 413, + 356, 419, 285, 355, 512, 336, 36, 424, 444, 445, + 432, 447, 21, 358, 257, 181, 121, 449, 118, 251, + 400, 441, 53, 440, 276, 366, 457, 105, 34, 448, + 35, 450, 434, 269, 451, 187, 186, 439, 196, 258, + 459, 420, 416, 466, 197, 43, 47, 26, 30, 468, + 464, 38, 2, 122, 123, 124, 214, 469, 214, 214, + 473, 214, 475, 476, 470, 478, 467, 482, 194, 195, + 27, 29, 28, 37, 184, 48, 251, 97, 110, 111, + 276, 409, 410, 411, 415, 200, 276, 198, 279, 23, + 168, 56, 460, 44, 54, 321, 309, 46, 45, 291, + 41, 496, 498, 400, 42, 313, 314, 315, 316, 317, + 318, 319, 320, 357, 206, 499, 222, 452, 487, 40, + 214, 507, 504, 509, 505, 518, 402, 132, 511, 130, + 143, 494, 147, 516, 140, 519, 513, 517, 138, 134, + 520, 59, 525, 60, 386, 149, 501, 526, 231, 57, + 61, 249, 429, 428, 426, 185, 109, 58, 173, 171, + 177, 126, 170, 175, 172, 174, 95, 238, 62, 150, + 63, 64, 65, 151, 510, 66, 20, 67, 5, 68, + 69, 4, 3, 70, 71, 72, 73, 74, 75, 1, + 0, 176, 76, 77, 0, 78, 0, 0, 0, 22, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 145, 0, 0, 0, 0, + 137, 0, 79, 142, 0, 0, 0, 164, 160, 0, + 442, 0, 81, 88, 169, 152, 82, 83, 84, 85, + 86, 87, 162, 163, 0, 0, 0, 0, 0, 166, + 155, 156, 157, 158, 159, 154, 59, 0, 60, 0, + 0, 146, 0, 0, 57, 61, 0, 148, 0, 0, + 0, 189, 58, 173, 171, 177, 0, 170, 175, 172, + 174, 0, 0, 62, 0, 63, 64, 65, 0, 0, + 66, 0, 67, 0, 68, 69, 0, 0, 70, 71, + 72, 73, 74, 75, 0, 0, 176, 76, 77, 0, + 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 145, 0, 0, 0, 0, 137, 0, 79, 142, 0, + 0, 0, 164, 160, 0, 80, 0, 81, 88, 169, + 152, 82, 83, 84, 85, 86, 87, 162, 163, 0, + 0, 0, 0, 0, 166, 155, 156, 157, 158, 159, + 154, 59, 0, 60, 0, 0, 146, 0, 0, 57, + 61, 0, 148, 0, 0, 0, 0, 58, 173, 171, + 177, 0, 170, 175, 172, 174, 0, 0, 62, 0, + 63, 64, 65, 0, 0, 66, 0, 67, 0, 68, + 69, 0, 0, 70, 71, 72, 73, 74, 75, 0, + 0, 176, 76, 77, 0, 78, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 145, 0, 0, 0, 0, + 137, 0, 79, 142, 0, 0, 0, 164, 160, 0, + 80, 0, 81, 88, 169, 152, 82, 83, 84, 85, + 86, 87, 162, 163, 0, 0, 0, 0, 0, 166, + 155, 156, 157, 158, 159, 154, 59, 0, 60, 0, + 0, 146, 131, 0, 57, 61, 0, 148, 0, 0, + 0, 0, 58, 173, 171, 177, 0, 170, 175, 172, + 174, 0, 0, 62, 0, 63, 64, 65, 0, 0, + 66, 0, 67, 0, 68, 69, 0, 0, 70, 71, + 72, 73, 74, 75, 0, 0, 176, 76, 77, 0, + 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 145, 0, 0, 0, 0, 137, 0, 79, 142, 0, + 0, 0, 164, 160, 0, 80, 0, 81, 88, 169, + 152, 82, 83, 84, 85, 86, 87, 162, 163, 0, + 0, 0, 0, 0, 166, 155, 156, 157, 158, 159, + 154, 59, 0, 60, 0, 0, 146, 0, 0, 57, + 61, 0, 148, 0, 0, 0, 0, 58, 173, 171, + 177, 0, 170, 175, 172, 174, 0, 0, 62, 0, + 63, 64, 65, 0, 0, 66, 0, 67, 0, 68, + 69, 0, 0, 70, 71, 72, 73, 74, 75, 0, + 0, 176, 76, 77, 0, 78, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 79, 234, 0, 0, 0, 164, 160, 0, + 80, 0, 81, 88, 169, 152, 82, 83, 84, 85, + 86, 87, 162, 163, 0, 0, 0, 0, 0, 166, + 155, 156, 157, 158, 159, 154, 59, 0, 60, 0, + 0, 146, 0, 0, 57, 61, 0, 148, 0, 0, + 0, 0, 58, 173, 171, 177, 0, 170, 175, 172, + 174, 0, 0, 62, 0, 63, 64, 65, 0, 0, + 66, 0, 67, 0, 68, 69, 0, 0, 70, 71, + 72, 73, 74, 75, 0, 0, 176, 76, 77, 0, + 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 79, 234, 0, + 0, 0, 0, 0, 0, 80, 0, 81, 88, 169, + 254, 82, 83, 84, 85, 86, 87, 59, 0, 60, + 0, 0, 0, 0, 55, 57, 61, 0, 0, 0, + 0, 0, 0, 58, 0, 0, 0, 330, 0, 0, + 0, 0, 289, 0, 62, 0, 63, 64, 65, 0, + 0, 66, 0, 67, 0, 68, 69, 0, 0, 70, + 71, 72, 73, 74, 75, 0, 0, 0, 76, 77, + 0, 78, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 79, 0, + 0, 0, 0, 0, 0, 0, 80, 287, 288, 290, + 0, 0, 82, 83, 84, 85, 86, 87, 59, 0, + 60, 0, 0, 0, 0, 166, 57, 61, 0, 0, + 0, 0, 0, 0, 58, 173, 171, 177, 0, 170, + 175, 172, 174, 286, 0, 62, 0, 63, 64, 65, + 0, 0, 253, 250, 67, 252, 68, 69, 0, 0, + 70, 71, 72, 73, 74, 75, 0, 0, 176, 76, + 77, 0, 78, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, + 234, 0, 0, 0, 0, 0, 0, 80, 0, 81, + 88, 169, 254, 82, 83, 84, 85, 86, 87, 59, + 0, 60, 0, 0, 0, 0, 55, 57, 61, 0, + 0, 0, 0, 0, 0, 58, 173, 171, 177, 0, + 170, 175, 172, 174, 0, 0, 62, 0, 63, 64, + 65, 0, 0, 66, 0, 67, 0, 68, 69, 0, + 0, 70, 71, 72, 73, 74, 75, 0, 0, 176, + 76, 77, 0, 78, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 79, 234, 0, 0, 0, 0, 0, 0, 80, 0, + 81, 88, 169, 254, 82, 83, 84, 85, 86, 87, + 59, 0, 60, 0, 0, 0, 0, 55, 57, 61, + 0, 0, 0, 0, 0, 0, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 62, 0, 63, + 64, 65, 0, 0, 66, 0, 67, 0, 68, 69, + 0, 0, 70, 71, 72, 73, 74, 75, 0, 0, + 0, 76, 77, 0, 78, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 215, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 79, 0, 0, 0, 59, 0, 60, 0, 80, + 0, 81, 88, 57, 61, 82, 83, 84, 85, 86, + 87, 58, 0, 0, 0, 0, 0, 0, 55, 0, + 0, 0, 62, 113, 63, 64, 65, 0, 0, 66, + 0, 67, 0, 68, 69, 0, 0, 70, 71, 72, + 73, 74, 75, 0, 0, 0, 76, 77, 0, 78, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 79, 0, 0, 0, + 59, 0, 60, 0, 80, 0, 81, 88, 57, 61, + 82, 83, 84, 85, 86, 87, 58, 0, 0, 0, + 0, 0, 0, 55, 0, 0, 0, 62, 0, 63, + 64, 65, 0, 0, 66, 0, 67, 0, 68, 69, + 0, 0, 70, 71, 72, 73, 74, 75, 0, 0, + 0, 76, 77, 0, 78, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 79, 0, 0, 0, 59, 0, 60, 0, 80, + 0, 81, 88, 57, 61, 82, 83, 84, 85, 86, + 87, 58, 0, 0, 0, 0, 0, 0, 55, 0, + 0, 0, 62, 0, 63, 64, 65, 0, 0, 66, + 0, 67, 0, 68, 69, 0, 0, 70, 71, 72, + 73, 74, 75, 0, 0, 0, 76, 77, 0, 78, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, + 0, 0, 0, 0, 80, 0, 81, 88, 0, 0, + 82, 83, 84, 85, 86, 87, 0, 0, 0, 0, + 0, 0, 0, 55, } var yyPact = [...]int16{ - 418, -1000, -1000, -2, -1000, -1000, -1000, 343, -1000, -1000, - 458, 164, 435, 465, 382, 382, 337, 334, 313, 150, - 263, 250, 316, -1000, 418, -1000, 220, 220, 220, 431, - 168, -1000, 167, 461, 163, 161, 162, 153, 151, 422, - 348, 40, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 420, - 150, 150, 150, 329, -1000, 259, -1000, -1000, 149, -1000, - 350, 298, -1000, -1000, 148, 216, 136, 416, 220, 480, - -1000, -1000, 457, 39, 39, -1000, 135, 48, -1000, 421, - 478, 486, -1000, 382, 485, -4, -5, 302, 100, 224, - -1000, -1000, 131, 310, -1000, 38, 106, 173, 176, -1000, - 152, -1000, 130, -1000, 7, -10, -1000, -1000, 152, 223, - -1000, 152, 188, -1000, -1000, 44, -12, -1000, -1000, -1000, - -1000, -1000, -13, -1000, -1000, -1000, -1000, -21, -1000, 211, - -14, 124, 409, 470, -1000, 39, 39, -1000, 152, -1000, - -1000, -16, 121, 377, 384, 381, 469, 120, -1000, 118, - 82, 82, 489, 152, 64, -1000, 171, -1000, -1000, 11, - 152, -1000, -1000, 117, 152, 152, -1000, 223, 200, 223, - 214, 223, 223, 223, -1000, 223, 223, 223, 224, 248, - -1000, -1000, -34, 73, 43, 59, 36, 152, 152, 116, - -1000, 144, -20, 115, 57, -1000, -1000, -1000, 82, -1000, - 114, 112, 110, 109, 107, 56, 398, 391, -35, 27, - -1000, -53, 286, 426, -1000, 489, 100, 152, 489, 461, - 261, -22, -23, -24, -25, 106, -26, 106, -1000, 176, - -1000, 6, -1000, 202, 35, 223, -27, 6, 7, 7, - -1000, -1000, -1000, -37, 237, 152, -1000, -1000, 55, -1000, - -38, -39, 47, 265, -40, 26, -1000, -1000, -58, -1000, - -1000, -1000, 372, 72, 152, 99, 82, -28, 473, -66, - -1000, -1000, 387, -1000, -1000, 473, 483, 482, 231, 98, - 231, 281, 152, 408, 286, -1000, -1000, 178, 106, -30, - -41, 436, -48, -50, 87, -51, -1000, -1000, -1000, 223, - 6, -29, -1000, 227, 152, 152, 240, -1000, -1000, -1000, - 70, -1000, 152, -1000, 144, -32, -85, -1000, 357, -70, - 82, -1000, -1000, -1000, -1000, -1000, 86, -1000, 85, 84, - 407, -30, -1000, -1000, -1000, -1000, 152, -1000, -32, 281, - 302, -1000, 178, 308, -1000, -1000, -72, -1000, 152, 106, - 83, 106, 106, -54, 106, 6, -59, -73, -1000, 230, - -1000, 152, -65, -1000, -1000, -1000, -1000, 82, 198, 68, - 65, 152, -1000, -74, -1000, -1000, -1000, -1000, 325, 23, - -1000, -1000, -1000, 297, -1000, 11, -30, -1000, -69, -1000, - -77, -1000, -1000, -1000, -1000, -1000, -1000, 152, -1000, -1000, - -78, 207, -1000, 197, -90, -80, -1000, -1000, 323, 306, - 293, 489, -1000, -1000, 106, -1000, -1000, 374, -1000, -1000, - -1000, -1000, 320, 279, 152, 81, 404, -1000, -1000, 360, - -1000, 286, 288, -1000, 18, -1000, 152, -1000, 281, 152, - 81, -1000, -1000, 16, 276, -1000, 152, -1000, -1000, -1000, - 276, -1000, + 298, -1000, -1000, -9, -1000, -1000, -1000, 308, -1000, -1000, + 420, 184, 378, 423, 421, 421, 302, 299, 278, 1665, + 239, 217, 280, -1000, 298, -1000, 82, 1750, 151, 375, + 98, -1000, 97, 442, 1665, 1580, 95, 1665, 92, 365, + 312, 29, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 363, + 1665, 1665, 1665, 294, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 237, + -1000, -1000, 91, -1000, 314, 746, -1000, -1000, 208, -1000, + 205, -13, -1000, 362, 188, 151, 445, -1000, -1000, 397, + 631, 631, -1000, 1665, 37, -1000, 413, 415, 460, -1000, + 421, 458, -17, -17, 263, 79, 163, -1000, -1000, 87, + 275, -1000, 28, 1495, 77, 112, -1000, 861, -1000, 104, + -1000, 11, -18, -1000, -1000, 861, 976, -1000, 861, 137, + -1000, -1000, -22, 32, -24, -1000, -1000, -1000, -1000, -1000, + -25, -1000, -1000, -1000, -1000, 36, -30, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 172, 168, + 1293, 1665, 164, 361, 409, -1000, 631, 631, -1000, 861, + -1000, -1000, -36, 1394, 339, 335, 332, 403, 1665, -1000, + 1665, 177, 1394, 177, 462, 861, 74, -1000, 101, -1000, + -1000, 1192, 861, -1000, -1000, 1665, 861, 861, -1000, 976, + 150, 976, 198, 976, 976, 976, -1000, 976, 976, 976, + 163, 226, -1000, -1000, -1000, -50, 463, 176, 12, 48, + 1091, 861, 1394, 861, 86, 1665, -59, -1000, -1000, -1000, + 327, 463, 861, 83, -1000, -37, -1000, 1665, 45, -1000, + -1000, -1000, 1394, -1000, 1394, 1665, 1394, 1394, 81, 44, + 346, 343, 360, -47, -1000, -61, -1000, -1000, 253, 373, + -1000, 462, 79, 861, 462, 442, 273, -38, -39, -40, + -43, 1495, 1495, -1000, 112, -1000, 5, -1000, 145, 31, + 976, -44, 5, 11, 11, -1000, -1000, -1000, -52, 227, + 861, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 274, -1000, -1000, -1000, -1000, -1000, -1000, 43, -1000, + -53, -54, 244, -1000, -55, 27, -1000, -1000, -45, -1000, + 1293, 76, -92, -1000, 321, 1394, -46, 450, -62, -1000, + -1000, 342, -1000, -1000, 450, 456, 414, -1000, 288, 24, + -1000, 861, 1394, -1000, 250, 861, 354, 253, -1000, -1000, + 117, 1495, -47, -56, 391, -57, -58, 73, -60, -1000, + -1000, -1000, 976, 5, 516, -1000, 199, 861, 861, 219, + 861, -1000, -1000, -1000, 463, -1000, 861, 1293, -1000, -1000, + -1000, 1394, 147, 53, 51, 861, -63, 1394, -1000, -1000, + -1000, -1000, -1000, 1394, -1000, 72, 70, 285, -47, -64, + -1000, -1000, 861, -1000, 76, 250, 263, -1000, 117, 271, + -1000, -1000, -73, 1495, 58, 1495, 1495, -65, 1495, 5, + -66, -75, 217, -1000, 215, -1000, 861, -83, -86, -1000, + -76, -80, 153, -1000, 144, -103, -87, -1000, -1000, -81, + -1000, -1000, -1000, 277, -1000, -1000, -1000, -1000, -1000, 261, + -1000, 1192, -1000, -1000, -100, -1000, -1000, -1000, -1000, -1000, + -1000, 861, -1000, -1000, -1000, -1000, -1000, 329, -1000, -1000, + -1000, -1000, -1000, -1000, 267, 259, 462, 1495, -1000, -1000, + 324, 246, 861, 1394, 351, -1000, -1000, 253, 257, -1000, + 21, -1000, 861, 250, 861, 1394, -1000, -1000, -1, 243, + -1000, 861, -1000, -1000, -1000, 243, -1000, } var yyPgo = [...]int16{ - 0, 539, 469, 538, 537, 536, 17, 535, 25, 11, - 14, 534, 533, 15, 8, 18, 12, 532, 7, 531, - 530, 3, 529, 528, 10, 19, 419, 20, 527, 526, - 28, 525, 9, 524, 523, 522, 16, 521, 0, 520, - 13, 519, 518, 517, 516, 29, 515, 514, 23, 26, - 30, 24, 513, 512, 4, 2, 511, 510, 509, 508, - 5, 507, 506, 1, 6, 336, 504, 503, 502, 501, - 22, 500, 499, 21, 498, 285, 497, 496, + 0, 569, 432, 562, 561, 558, 18, 556, 26, 12, + 143, 21, 554, 17, 11, 16, 19, 553, 7, 549, + 547, 4, 546, 541, 9, 29, 382, 24, 536, 535, + 36, 534, 15, 533, 532, 531, 23, 13, 0, 528, + 10, 526, 525, 524, 519, 33, 518, 514, 34, 28, + 44, 35, 512, 511, 8, 3, 510, 509, 507, 506, + 6, 505, 501, 1, 5, 227, 498, 497, 496, 495, + 25, 494, 493, 20, 480, 153, 476, 475, 14, 471, + 470, 2, 27, 58, 469, } var yyR1 = [...]int8{ - 0, 1, 2, 2, 77, 77, 3, 3, 3, 4, + 0, 1, 2, 2, 84, 84, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 75, 75, 75, 74, 74, 74, 74, - 74, 74, 74, 73, 73, 73, 73, 65, 65, 10, - 10, 5, 5, 5, 5, 25, 25, 72, 72, 71, - 71, 70, 11, 11, 13, 13, 14, 9, 9, 12, - 12, 16, 16, 15, 15, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 18, 37, 37, 36, 36, - 36, 8, 69, 69, 59, 59, 59, 66, 66, 67, - 67, 67, 6, 6, 6, 6, 6, 6, 6, 6, - 7, 7, 23, 23, 22, 22, 57, 57, 58, 58, - 19, 19, 19, 19, 20, 20, 21, 21, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 26, 27, 28, - 28, 28, 29, 29, 29, 30, 30, 31, 31, 32, - 32, 33, 34, 34, 40, 40, 53, 53, 41, 41, - 54, 54, 55, 55, 62, 62, 64, 64, 61, 61, - 63, 63, 63, 60, 60, 60, 35, 35, 39, 39, - 56, 76, 76, 43, 43, 38, 44, 44, 45, 45, - 49, 49, 46, 46, 46, 46, 46, 46, 46, 47, - 47, 47, 47, 47, 48, 48, 48, 50, 50, 50, - 50, 51, 51, 52, 52, 42, 42, 42, 68, 68, + 4, 4, 4, 4, 4, 75, 75, 75, 74, 74, + 74, 74, 74, 74, 74, 73, 73, 73, 73, 65, + 65, 5, 5, 5, 5, 25, 25, 72, 72, 71, + 71, 70, 13, 13, 14, 12, 12, 16, 16, 15, + 15, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 78, 78, 78, 78, 78, 78, 78, 78, 18, + 37, 37, 36, 36, 36, 8, 69, 69, 59, 59, + 59, 66, 66, 67, 67, 67, 6, 6, 6, 6, + 6, 6, 6, 6, 7, 7, 23, 23, 22, 22, + 57, 57, 58, 58, 19, 19, 19, 19, 20, 20, + 21, 21, 82, 83, 83, 9, 9, 11, 11, 10, + 10, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 81, 81, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 26, 27, 28, 28, 28, + 29, 29, 29, 30, 30, 31, 31, 32, 32, 33, + 34, 34, 40, 40, 53, 53, 41, 41, 54, 54, + 55, 55, 62, 62, 64, 64, 61, 61, 63, 63, + 63, 60, 60, 60, 35, 35, 39, 39, 56, 76, + 76, 43, 43, 38, 44, 44, 45, 45, 49, 49, + 46, 46, 46, 46, 46, 46, 46, 47, 47, 47, + 47, 47, 48, 48, 48, 50, 50, 50, 50, 51, + 51, 52, 52, 42, 42, 42, 42, 68, 68, 77, + 77, 77, 77, 77, 77, } var yyR2 = [...]int8{ 0, 1, 2, 3, 0, 1, 1, 1, 1, 2, - 1, 1, 1, 4, 2, 3, 3, 7, 3, 8, - 9, 7, 5, 6, 6, 8, 6, 6, 7, 7, - 3, 8, 8, 2, 1, 3, 1, 1, 1, 1, - 1, 1, 1, 0, 1, 1, 1, 0, 3, 1, - 3, 8, 7, 7, 8, 2, 1, 0, 4, 1, - 3, 3, 0, 1, 1, 3, 3, 1, 3, 1, - 3, 0, 1, 1, 3, 1, 1, 1, 1, 1, - 6, 1, 1, 1, 1, 4, 1, 3, 1, 1, - 3, 6, 0, 2, 0, 3, 3, 0, 1, 0, - 1, 2, 1, 4, 2, 2, 3, 2, 2, 4, - 13, 3, 0, 1, 0, 1, 1, 1, 2, 4, - 1, 2, 4, 4, 2, 3, 1, 3, 3, 4, - 4, 4, 4, 4, 4, 2, 6, 1, 2, 0, - 2, 2, 0, 2, 2, 2, 1, 0, 1, 1, - 2, 6, 0, 1, 0, 2, 0, 3, 0, 2, - 0, 2, 0, 2, 0, 3, 0, 4, 2, 4, - 0, 1, 1, 0, 1, 2, 2, 4, 0, 1, - 5, 4, 5, 0, 2, 1, 3, 1, 3, 1, - 2, 1, 3, 3, 4, 5, 4, 3, 1, 4, - 6, 6, 1, 1, 3, 3, 1, 3, 3, 3, - 1, 2, 1, 3, 1, 1, 1, 3, 0, 1, + 1, 1, 1, 6, 3, 2, 3, 3, 9, 6, + 3, 8, 9, 7, 5, 6, 6, 8, 6, 6, + 7, 7, 3, 8, 8, 2, 1, 3, 1, 1, + 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, + 3, 6, 5, 7, 8, 2, 1, 0, 4, 1, + 3, 3, 1, 3, 3, 1, 3, 0, 1, 1, + 3, 1, 1, 1, 1, 1, 6, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, + 1, 3, 1, 1, 3, 6, 0, 2, 0, 3, + 3, 0, 1, 0, 1, 2, 1, 4, 2, 2, + 3, 2, 2, 4, 13, 3, 0, 1, 0, 1, + 1, 1, 2, 4, 1, 2, 4, 4, 2, 3, + 1, 3, 1, 1, 1, 1, 3, 1, 3, 0, + 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 3, 4, 4, 4, + 4, 4, 4, 2, 6, 1, 2, 0, 2, 2, + 0, 2, 2, 2, 1, 0, 1, 1, 2, 6, + 0, 1, 0, 2, 0, 3, 0, 2, 0, 2, + 0, 2, 0, 3, 0, 4, 2, 4, 0, 1, + 1, 0, 1, 2, 2, 4, 0, 1, 5, 4, + 5, 0, 2, 1, 3, 1, 3, 1, 2, 1, + 3, 3, 4, 5, 4, 3, 1, 4, 6, 6, + 1, 1, 3, 3, 1, 3, 3, 3, 1, 2, + 1, 3, 1, 1, 1, 3, 6, 0, 1, 1, + 1, 1, 1, 1, 1, } var yyChk = [...]int16{ - -1000, -1, -2, -3, -4, -5, -6, 41, 43, 44, - 4, 6, 5, 27, 36, 37, 45, 46, 49, 50, - -7, 87, 56, -77, 117, 42, 7, 23, 25, 24, - 8, 99, 7, 14, 23, 25, 8, 23, 8, -75, - 71, -74, 56, 4, 45, 50, 49, 5, 27, -75, - 47, 47, 58, -26, 99, 70, 88, 89, 23, 90, - 38, -22, 57, -2, -65, 79, -65, -65, 25, 99, - 99, -27, -28, 16, 17, 99, 26, 99, 99, 99, - 99, 26, 40, 110, 26, -26, -26, -26, 51, -23, - 71, 99, 39, -57, 113, -58, -38, -44, -45, -49, - 77, -46, -48, -47, -50, 80, -56, -51, 72, 112, - -52, 118, -42, -19, -17, -21, 106, 101, 102, 103, - 104, 105, 85, -18, 92, 93, 84, 99, 99, 77, - 99, 26, -65, 9, -29, 19, 18, -30, 20, -38, - -30, 99, 108, 28, 29, 5, 9, 7, -75, 7, - 118, 118, -40, 61, -71, -70, 99, -6, 99, 58, - 110, -60, 99, 69, 96, 95, -49, 97, 82, 91, - -68, 98, 111, 112, 77, 113, 114, 115, 118, -39, - -38, -51, -38, 86, -20, 109, 118, 118, 118, 108, - 80, 118, 99, 26, 10, -30, -30, -38, 118, 99, - 31, 30, 31, 31, 32, 10, 99, 99, -11, -9, - 99, -9, -64, 6, -38, -40, 110, 97, -24, -26, - 118, 88, 89, 23, 90, -18, 99, -38, 99, -45, - -49, -48, 84, 77, -48, 78, 81, -48, -50, -50, - -51, -51, -51, -6, -76, 73, 119, 100, 109, 103, - 113, -21, 99, -38, -16, -15, -38, 99, -37, -36, - -8, -35, 33, 99, 35, 32, 118, 99, 103, -9, - -8, 99, 99, 99, 99, 103, 30, 30, 119, 110, - 119, -54, 64, 25, -64, -70, -38, -64, -27, 48, - -6, 15, 118, 118, 118, 118, -60, -60, 84, 95, - -48, 118, 119, -43, 73, 75, -38, 103, 119, 119, - 69, 119, 110, 119, 110, 34, 100, -38, 99, -9, - 118, -73, 11, 12, 13, 119, 30, -73, 8, 8, - -25, 48, -6, 99, -25, -55, 65, -38, 26, -54, - -31, -32, -33, -34, 94, -60, -13, -14, 118, 119, - 21, 119, 119, 99, 119, -48, -6, -15, 76, -38, - -38, 74, 100, -38, -36, -10, 99, 118, -59, 120, - 118, 35, 119, -9, 99, 99, 99, -72, 26, -13, - -38, -10, -55, -40, -32, 59, 110, 119, -16, -60, - 99, -60, -60, 119, -60, 119, 119, 74, -38, 119, - -9, -67, 84, 77, 101, 101, -38, 119, 52, -53, - 62, -24, -14, 119, 119, -38, 119, -66, 83, 84, - 121, 119, 53, -41, 60, 63, -64, -60, -69, 33, - 54, -62, 66, -38, -12, -21, 26, 34, -54, 63, - 110, -38, -55, -61, -38, -21, 110, -63, 67, 68, - -38, -63, + -1000, -1, -2, -3, -4, -5, -6, 48, 50, 51, + 4, 6, 5, 34, 43, 44, 52, 53, 56, 57, + -7, 94, 63, -84, 130, 49, 7, 30, 32, 31, + 8, 113, 7, 14, 30, 32, 8, 30, 8, -75, + 78, -74, 63, 4, 52, 57, 56, 5, 34, -75, + 54, 54, 65, -26, -81, 113, -79, 13, 21, 5, + 7, 14, 32, 34, 35, 36, 39, 41, 43, 44, + 47, 48, 49, 50, 51, 52, 56, 57, 59, 86, + 94, 96, 100, 101, 102, 103, 104, 105, 97, 77, + 95, 96, 30, 97, 45, -22, 64, -2, 86, 113, + 86, -82, -81, -65, 86, 32, 113, 113, -27, -28, + 16, 17, -81, 33, -82, 113, -82, 113, 33, 47, + 123, 33, -26, -26, -26, 58, -23, 78, 113, 46, + -57, 126, -58, -38, -44, -45, -49, 84, -46, -48, + -47, -50, 87, -56, -51, 79, 125, -52, 131, -42, + -19, -17, 99, -21, 119, 114, 115, 116, 117, 118, + 92, -18, 106, 107, 91, -83, 113, -81, -80, 98, + 26, 23, 28, 22, 29, 27, 55, 24, 84, 84, + 131, 33, 84, -65, 9, -29, 19, 18, -30, 20, + -38, -30, -82, 121, 35, 36, 5, 9, 7, -75, + 7, -10, 131, -10, -40, 68, -71, -70, 113, -6, + 113, 65, 123, -60, -81, 76, 110, 109, -49, 111, + 89, 98, -68, 112, 124, 125, 84, 126, 127, 128, + 131, -39, -38, -51, 87, -38, 93, 131, -20, 122, + 131, 131, 121, 131, 87, 87, -37, -36, -8, -35, + 40, -83, 42, 39, 99, -82, 87, 33, 10, -30, + -30, -38, 131, -83, 38, 37, 38, 38, 39, 10, + -81, -81, -25, 55, -6, -9, -83, -25, -64, 6, + -38, -40, 123, 111, -24, -26, 131, 95, 96, 30, + 97, -18, -38, -81, -45, -49, -48, 91, 84, -48, + 85, 88, -48, -50, -50, -51, -51, -51, -6, -76, + 80, 132, -78, 22, 23, 24, 25, 26, 27, 28, + 29, -77, 100, 101, 102, 103, 104, 105, 122, 116, + 126, -21, -38, -83, -16, -15, -38, 113, -82, 132, + 123, 41, -78, -38, 113, 131, -82, 116, -9, -8, + -82, -83, -83, 113, 116, 37, 37, -72, 33, -13, + -14, 131, 123, 132, -54, 71, 32, -64, -70, -38, + -64, -27, 55, -6, 15, 131, 131, 131, 131, -60, + -60, 91, 109, -48, 131, 132, -43, 80, 82, -38, + 65, 116, 132, 132, 76, 132, 123, 131, -36, -11, + -83, 131, -59, 133, 131, 42, -9, 131, -73, 11, + 12, 13, 132, 37, -73, 8, 8, 59, 123, -16, + -83, -55, 72, -38, 33, -54, -31, -32, -33, -34, + 108, -60, -13, 132, 21, 132, 132, 113, 132, -48, + -6, -15, 94, 83, -38, -38, 81, -38, -78, -38, + -37, -9, -67, 91, 84, 114, 114, -38, 132, -9, + -83, 113, 113, 60, -14, 132, -38, -11, -55, -40, + -32, 66, 132, -60, 113, -60, -60, 132, -60, 132, + 132, 81, -38, 132, 132, 132, 132, -66, 90, 91, + 134, 132, 132, 61, -53, 69, -24, 132, -38, -69, + 40, -41, 67, 70, -64, -60, 41, -62, 73, -38, + -12, -21, 33, -54, 70, 123, -38, -55, -61, -38, + -21, 123, -63, 74, 75, -38, -63, } var yyDef = [...]int16{ 0, -2, 1, 4, 6, 7, 8, 10, 11, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 102, 0, 114, 2, 5, 9, 47, 47, 47, 0, - 0, 14, 0, 139, 0, 0, 0, 0, 0, 0, - 0, 34, 36, 37, 38, 39, 40, 41, 42, 0, - 0, 0, 0, 0, 137, 112, 104, 105, 0, 107, - 108, 0, 115, 3, 0, 0, 0, 0, 47, 0, - 15, 16, 142, 0, 0, 18, 0, 0, 30, 0, - 0, 0, 33, 0, 0, 0, 0, 154, 0, 0, - 113, 106, 0, 111, 116, 117, 173, 185, 187, 189, - 0, 191, -2, 198, 206, 0, 202, 210, 178, 0, - 212, 0, 214, 215, 216, 120, 0, 75, 76, 77, - 78, 79, 0, 81, 82, 83, 84, 126, 13, 0, - 0, 0, 0, 0, 138, 0, 0, 140, 0, 146, - 141, 0, 0, 0, 0, 0, 0, 0, 35, 0, - 62, 0, 166, 0, 154, 59, 0, 103, 109, 0, - 0, 118, 174, 0, 0, 0, 190, 0, 0, 0, - 0, 0, 0, 0, 219, 0, 0, 0, 0, 0, - 179, 211, 0, 0, 121, 0, 0, 0, 71, 0, - 48, 0, 0, 0, 0, 143, 144, 145, 0, 22, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, - 67, 0, 160, 0, 155, 166, 0, 0, 166, 139, - 0, 0, 0, 0, 0, 173, 137, 173, 175, 186, - 188, 192, 193, 0, 0, 0, 0, 197, 204, 205, - 207, 208, 209, 0, 183, 0, 213, 217, 0, 124, - 0, 0, 126, 0, 0, 72, 73, 127, 0, 86, - 88, 89, 0, 0, 0, 0, 0, 0, 43, 0, - 23, 24, 0, 26, 27, 43, 0, 0, 0, 0, - 0, 162, 0, 0, 160, 60, 61, -2, 173, 0, - 0, 0, 0, 0, 0, 0, 135, 119, 194, 0, - 196, 0, 199, 0, 0, 0, 0, 125, 122, 123, - 0, 85, 0, 17, 0, 0, 94, 176, 0, 0, - 0, 28, 44, 45, 46, 21, 0, 29, 0, 0, - 57, 0, 56, 68, 52, 53, 0, 161, 0, 162, - 154, 148, -2, 0, 153, 128, 0, 64, 71, 173, - 0, 173, 173, 0, 173, 195, 0, 0, 180, 0, - 184, 0, 0, 74, 87, 90, 49, 0, 99, 0, - 0, 0, 19, 0, 25, 31, 32, 51, 0, 55, - 163, 167, 54, 156, 150, 0, 0, 129, 0, 130, - 0, 131, 132, 133, 134, 200, 201, 0, 181, 80, - 0, 97, 100, 0, 0, 0, 177, 20, 0, 158, - 0, 166, 65, 66, 173, 182, 50, 92, 98, 101, - 95, 96, 0, 164, 0, 0, 0, 136, 91, 0, - 58, 160, 0, 159, 157, 69, 0, 93, 162, 0, - 0, 151, 110, 165, 170, 70, 0, 168, 171, 172, - 170, 169, + 106, 0, 118, 2, 5, 9, 0, 0, 49, 0, + 0, 15, 0, 197, 0, 0, 0, 0, 0, 0, + 0, 36, 38, 39, 40, 41, 42, 43, 44, 0, + 0, 0, 0, 0, 195, 152, 153, 154, 155, 156, + 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, 185, 116, + 108, 109, 0, 111, 112, 0, 119, 3, 0, 14, + 176, 0, 132, 0, 0, 49, 0, 16, 17, 200, + 0, 0, 20, 0, 0, 32, 0, 0, 0, 35, + 0, 0, 139, 139, 212, 0, 0, 117, 110, 0, + 115, 120, 121, 231, 243, 245, 247, 0, 249, -2, + 256, 264, 144, 260, 268, 236, 0, 270, 0, 272, + 273, 274, 145, 124, 0, 71, 72, 73, 74, 75, + 0, 77, 78, 79, 80, 130, 152, 133, 134, 141, + 142, 143, 146, 147, 148, 149, 150, 151, 0, 0, + 0, 0, 0, 0, 0, 196, 0, 0, 198, 0, + 204, 199, 0, 0, 0, 0, 0, 0, 0, 37, + 0, 0, 0, 0, 224, 0, 212, 59, 0, 107, + 113, 0, 0, 122, 232, 0, 0, 0, 248, 0, + 0, 0, 0, 0, 0, 0, 278, 0, 0, 0, + 0, 0, 237, 269, 144, 0, 0, 0, 125, 0, + 0, 0, 0, 67, 0, 0, 0, 90, 92, 93, + 0, 0, 0, 163, 145, 0, 50, 0, 0, 201, + 202, 203, 0, 24, 0, 0, 0, 0, 0, 0, + 0, 0, 57, 0, 56, 0, 135, 52, 218, 0, + 213, 224, 0, 0, 224, 197, 0, 0, 178, 0, + 185, 231, 231, 233, 244, 246, 250, 251, 0, 0, + 0, 0, 255, 262, 263, 265, 266, 267, 0, 241, + 0, 271, 275, 81, 82, 83, 84, 85, 86, 87, + 88, 0, 279, 280, 281, 282, 283, 284, 0, 128, + 0, 0, 0, 131, 0, 68, 69, 13, 0, 19, + 0, 0, 98, 234, 0, 0, 0, 45, 0, 25, + 26, 0, 28, 29, 45, 0, 0, 51, 0, 55, + 62, 67, 0, 140, 220, 0, 0, 218, 60, 61, + -2, 231, 0, 0, 0, 0, 0, 0, 0, 193, + 123, 252, 0, 254, 0, 257, 0, 0, 0, 0, + 0, 129, 126, 127, 0, 89, 0, 0, 91, 94, + 137, 0, 103, 0, 0, 0, 0, 0, 30, 46, + 47, 48, 23, 0, 31, 0, 0, 0, 0, 0, + 136, 53, 0, 219, 0, 220, 212, 206, -2, 0, + 211, 186, 0, 231, 0, 231, 231, 0, 231, 253, + 0, 0, 177, 238, 0, 242, 0, 0, 0, 70, + 0, 0, 101, 104, 0, 0, 0, 235, 21, 0, + 27, 33, 34, 0, 63, 64, 221, 225, 54, 214, + 208, 0, 187, 188, 0, 189, 190, 191, 192, 258, + 259, 0, 239, 276, 76, 18, 138, 96, 102, 105, + 99, 100, 22, 58, 216, 0, 224, 231, 240, 95, + 0, 222, 0, 0, 0, 194, 97, 218, 0, 217, + 215, 65, 0, 220, 0, 0, 209, 114, 223, 228, + 66, 0, 226, 229, 230, 228, 227, } -var yyTok1 = [...]int8{ +var yyTok1 = [...]uint8{ 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 115, 3, 3, - 118, 119, 113, 111, 110, 112, 116, 114, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 128, 3, 3, + 131, 132, 126, 124, 123, 125, 129, 127, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 120, 3, 121, + 3, 133, 3, 134, } -var yyTok2 = [...]int8{ +var yyTok2 = [...]uint8{ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, @@ -609,7 +806,9 @@ var yyTok2 = [...]int8{ 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, - 102, 103, 104, 105, 106, 107, 108, 109, 117, + 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, + 122, 130, } var yyTok3 = [...]int8{ @@ -992,239 +1191,214 @@ yydefault: yyVAL.stmt = &RollbackStmt{} } case 13: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] { - yyVAL.stmt = &CreateDatabaseStmt{ifNotExists: yyDollar[3].boolean, DB: yyDollar[4].id} + yyVAL.stmt = &CreateDatabaseStmt{ifNotExists: true, DB: yyDollar[6].id} } case 14: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] { - yyVAL.stmt = &UseDatabaseStmt{DB: yyDollar[2].id} + yyVAL.stmt = &CreateDatabaseStmt{ifNotExists: false, DB: yyDollar[3].id} } case 15: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] { - yyVAL.stmt = &UseDatabaseStmt{DB: yyDollar[3].id} + yyVAL.stmt = &UseDatabaseStmt{DB: yyDollar[2].id} } case 16: yyDollar = yyS[yypt-3 : yypt+1] { - yyVAL.stmt = &UseSnapshotStmt{period: yyDollar[3].period} + yyVAL.stmt = &UseDatabaseStmt{DB: yyDollar[3].id} } case 17: - yyDollar = yyS[yypt-7 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] { - colsSpecs := make([]*ColSpec, 0, 5) - var checks []CheckConstraint - - var pk PrimaryKeyConstraint - - for _, e := range yyDollar[6].tableElems { - switch c := e.(type) { - case *ColSpec: - colsSpecs = append(colsSpecs, c) - case PrimaryKeyConstraint: - pk = c - case CheckConstraint: - if checks == nil { - checks = make([]CheckConstraint, 0, 5) - } - checks = append(checks, c) - } - } - - yyVAL.stmt = &CreateTableStmt{ - ifNotExists: yyDollar[3].boolean, - table: yyDollar[4].id, - colsSpec: colsSpecs, - pkColNames: pk, - checks: checks, - } + yyVAL.stmt = &UseSnapshotStmt{period: yyDollar[3].period} } case 18: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-9 : yypt+1] { - yyVAL.stmt = &DropTableStmt{table: yyDollar[3].id} + yyVAL.stmt = newCreateTableStmt(yyDollar[6].str, yyDollar[8].tableElems, true) } case 19: - yyDollar = yyS[yypt-8 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] { - yyVAL.stmt = &CreateIndexStmt{ifNotExists: yyDollar[3].boolean, table: yyDollar[5].id, cols: yyDollar[7].ids} + yyVAL.stmt = newCreateTableStmt(yyDollar[3].str, yyDollar[5].tableElems, false) } case 20: - yyDollar = yyS[yypt-9 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] { - yyVAL.stmt = &CreateIndexStmt{unique: true, ifNotExists: yyDollar[4].boolean, table: yyDollar[6].id, cols: yyDollar[8].ids} + yyVAL.stmt = &DropTableStmt{table: yyDollar[3].str} } case 21: - yyDollar = yyS[yypt-7 : yypt+1] + yyDollar = yyS[yypt-8 : yypt+1] { - yyVAL.stmt = &DropIndexStmt{table: yyDollar[4].id, cols: yyDollar[6].ids} + yyVAL.stmt = &CreateIndexStmt{ifNotExists: yyDollar[3].boolean, table: yyDollar[5].str, cols: yyDollar[7].colNames} } case 22: - yyDollar = yyS[yypt-5 : yypt+1] + yyDollar = yyS[yypt-9 : yypt+1] { - yyVAL.stmt = &DropIndexStmt{table: yyDollar[3].id, cols: []string{yyDollar[5].id}} + yyVAL.stmt = &CreateIndexStmt{unique: true, ifNotExists: yyDollar[4].boolean, table: yyDollar[6].str, cols: yyDollar[8].colNames} } case 23: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-7 : yypt+1] { - yyVAL.stmt = &AddColumnStmt{table: yyDollar[3].id, colSpec: yyDollar[6].colSpec} + yyVAL.stmt = &DropIndexStmt{table: yyDollar[4].str, cols: yyDollar[6].colNames} } case 24: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-5 : yypt+1] { - yyVAL.stmt = &RenameTableStmt{oldName: yyDollar[3].id, newName: yyDollar[6].id} + yyVAL.stmt = &DropIndexStmt{table: yyDollar[3].str, cols: []string{yyDollar[5].str}} } case 25: - yyDollar = yyS[yypt-8 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] { - yyVAL.stmt = &RenameColumnStmt{table: yyDollar[3].id, oldName: yyDollar[6].id, newName: yyDollar[8].id} + yyVAL.stmt = &AddColumnStmt{table: yyDollar[3].str, colSpec: yyDollar[6].colSpec} } case 26: yyDollar = yyS[yypt-6 : yypt+1] { - yyVAL.stmt = &DropColumnStmt{table: yyDollar[3].id, colName: yyDollar[6].id} + yyVAL.stmt = &RenameTableStmt{oldName: yyDollar[3].str, newName: yyDollar[6].str} } case 27: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-8 : yypt+1] { - yyVAL.stmt = &DropConstraintStmt{table: yyDollar[3].id, constraintName: yyDollar[6].id} + yyVAL.stmt = &RenameColumnStmt{table: yyDollar[3].str, oldName: yyDollar[6].str, newName: yyDollar[8].str} } case 28: + yyDollar = yyS[yypt-6 : yypt+1] + { + yyVAL.stmt = &DropColumnStmt{table: yyDollar[3].str, colName: yyDollar[6].str} + } + case 29: + yyDollar = yyS[yypt-6 : yypt+1] + { + yyVAL.stmt = &DropConstraintStmt{table: yyDollar[3].str, constraintName: yyDollar[6].id} + } + case 30: yyDollar = yyS[yypt-7 : yypt+1] { yyVAL.stmt = &CreateUserStmt{username: yyDollar[3].id, password: yyDollar[6].str, permission: yyDollar[7].permission} } - case 29: + case 31: yyDollar = yyS[yypt-7 : yypt+1] { yyVAL.stmt = &AlterUserStmt{username: yyDollar[3].id, password: yyDollar[6].str, permission: yyDollar[7].permission} } - case 30: + case 32: yyDollar = yyS[yypt-3 : yypt+1] { yyVAL.stmt = &DropUserStmt{username: yyDollar[3].id} } - case 31: + case 33: yyDollar = yyS[yypt-8 : yypt+1] { - yyVAL.stmt = &AlterPrivilegesStmt{database: yyDollar[5].id, user: yyDollar[8].id, privileges: yyDollar[2].sqlPrivileges, isGrant: true} + yyVAL.stmt = &AlterPrivilegesStmt{database: yyDollar[5].str, user: yyDollar[8].id, privileges: yyDollar[2].sqlPrivileges, isGrant: true} } - case 32: + case 34: yyDollar = yyS[yypt-8 : yypt+1] { - yyVAL.stmt = &AlterPrivilegesStmt{database: yyDollar[5].id, user: yyDollar[8].id, privileges: yyDollar[2].sqlPrivileges} + yyVAL.stmt = &AlterPrivilegesStmt{database: yyDollar[5].str, user: yyDollar[8].id, privileges: yyDollar[2].sqlPrivileges} } - case 33: + case 35: yyDollar = yyS[yypt-2 : yypt+1] { yyVAL.sqlPrivileges = allPrivileges } - case 34: + case 36: yyDollar = yyS[yypt-1 : yypt+1] { yyVAL.sqlPrivileges = []SQLPrivilege{yyDollar[1].sqlPrivilege} } - case 35: + case 37: yyDollar = yyS[yypt-3 : yypt+1] { yyVAL.sqlPrivileges = append(yyDollar[3].sqlPrivileges, yyDollar[1].sqlPrivilege) } - case 36: + case 38: yyDollar = yyS[yypt-1 : yypt+1] { yyVAL.sqlPrivilege = SQLPrivilegeSelect } - case 37: + case 39: yyDollar = yyS[yypt-1 : yypt+1] { yyVAL.sqlPrivilege = SQLPrivilegeCreate } - case 38: + case 40: yyDollar = yyS[yypt-1 : yypt+1] { yyVAL.sqlPrivilege = SQLPrivilegeInsert } - case 39: + case 41: yyDollar = yyS[yypt-1 : yypt+1] { yyVAL.sqlPrivilege = SQLPrivilegeUpdate } - case 40: + case 42: yyDollar = yyS[yypt-1 : yypt+1] { yyVAL.sqlPrivilege = SQLPrivilegeDelete } - case 41: + case 43: yyDollar = yyS[yypt-1 : yypt+1] { yyVAL.sqlPrivilege = SQLPrivilegeDrop } - case 42: + case 44: yyDollar = yyS[yypt-1 : yypt+1] { yyVAL.sqlPrivilege = SQLPrivilegeAlter } - case 43: + case 45: yyDollar = yyS[yypt-0 : yypt+1] { yyVAL.permission = PermissionReadWrite } - case 44: + case 46: yyDollar = yyS[yypt-1 : yypt+1] { yyVAL.permission = PermissionReadOnly } - case 45: + case 47: yyDollar = yyS[yypt-1 : yypt+1] { yyVAL.permission = PermissionReadWrite } - case 46: + case 48: yyDollar = yyS[yypt-1 : yypt+1] { yyVAL.permission = PermissionAdmin } - case 47: + case 49: yyDollar = yyS[yypt-0 : yypt+1] { yyVAL.boolean = false } - case 48: - yyDollar = yyS[yypt-3 : yypt+1] - { - yyVAL.boolean = true - } - case 49: - yyDollar = yyS[yypt-1 : yypt+1] - { - yyVAL.ids = []string{yyDollar[1].id} - } case 50: yyDollar = yyS[yypt-3 : yypt+1] { - yyVAL.ids = yyDollar[2].ids + yyVAL.boolean = true } case 51: - yyDollar = yyS[yypt-8 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] { - yyVAL.stmt = &UpsertIntoStmt{isInsert: true, tableRef: yyDollar[3].tableRef, cols: yyDollar[5].ids, ds: yyDollar[7].ds, onConflict: yyDollar[8].onConflict} + yyVAL.stmt = &UpsertIntoStmt{isInsert: true, tableRef: yyDollar[3].tableRef, cols: yyDollar[4].colNames, ds: yyDollar[5].ds, onConflict: yyDollar[6].onConflict} } case 52: - yyDollar = yyS[yypt-7 : yypt+1] + yyDollar = yyS[yypt-5 : yypt+1] { - yyVAL.stmt = &UpsertIntoStmt{tableRef: yyDollar[3].tableRef, cols: yyDollar[5].ids, ds: yyDollar[7].ds} + yyVAL.stmt = &UpsertIntoStmt{tableRef: yyDollar[3].tableRef, cols: yyDollar[4].colNames, ds: yyDollar[5].ds} } case 53: yyDollar = yyS[yypt-7 : yypt+1] { - yyVAL.stmt = &DeleteFromStmt{tableRef: yyDollar[3].tableRef, where: yyDollar[4].exp, indexOn: yyDollar[5].ids, limit: yyDollar[6].exp, offset: yyDollar[7].exp} + yyVAL.stmt = &DeleteFromStmt{tableRef: yyDollar[3].tableRef, where: yyDollar[4].exp, indexOn: yyDollar[5].colNames, limit: yyDollar[6].exp, offset: yyDollar[7].exp} } case 54: yyDollar = yyS[yypt-8 : yypt+1] { - yyVAL.stmt = &UpdateStmt{tableRef: yyDollar[2].tableRef, updates: yyDollar[4].updates, where: yyDollar[5].exp, indexOn: yyDollar[6].ids, limit: yyDollar[7].exp, offset: yyDollar[8].exp} + yyVAL.stmt = &UpdateStmt{tableRef: yyDollar[2].tableRef, updates: yyDollar[4].updates, where: yyDollar[5].exp, indexOn: yyDollar[6].colNames, limit: yyDollar[7].exp, offset: yyDollar[8].exp} } case 55: yyDollar = yyS[yypt-2 : yypt+1] @@ -1262,211 +1436,238 @@ yydefault: yyVAL.update = &colUpdate{col: yyDollar[1].id, op: yyDollar[2].cmpOp, val: yyDollar[3].exp} } case 62: - yyDollar = yyS[yypt-0 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] { - yyVAL.ids = nil + yyVAL.rows = []*RowSpec{yyDollar[1].row} } case 63: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] { - yyVAL.ids = yyDollar[1].ids + yyVAL.rows = append(yyDollar[1].rows, yyDollar[3].row) } case 64: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] { - yyVAL.rows = []*RowSpec{yyDollar[1].row} + yyVAL.row = &RowSpec{Values: yyDollar[2].values} } case 65: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] { - yyVAL.rows = append(yyDollar[1].rows, yyDollar[3].row) + yyVAL.cols = []*ColSelector{yyDollar[1].col} } case 66: yyDollar = yyS[yypt-3 : yypt+1] { - yyVAL.row = &RowSpec{Values: yyDollar[2].values} + yyVAL.cols = append(yyDollar[1].cols, yyDollar[3].col) } case 67: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-0 : yypt+1] { - yyVAL.ids = []string{yyDollar[1].id} + yyVAL.values = nil } case 68: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] { - yyVAL.ids = append(yyDollar[1].ids, yyDollar[3].id) + yyVAL.values = yyDollar[1].values } case 69: yyDollar = yyS[yypt-1 : yypt+1] { - yyVAL.cols = []*ColSelector{yyDollar[1].col} + yyVAL.values = []ValueExp{yyDollar[1].exp} } case 70: yyDollar = yyS[yypt-3 : yypt+1] { - yyVAL.cols = append(yyDollar[1].cols, yyDollar[3].col) + yyVAL.values = append(yyDollar[1].values, yyDollar[3].exp) } case 71: - yyDollar = yyS[yypt-0 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] { - yyVAL.values = nil + yyVAL.value = &Integer{val: int64(yyDollar[1].integer)} } case 72: yyDollar = yyS[yypt-1 : yypt+1] { - yyVAL.values = yyDollar[1].values + yyVAL.value = &Float64{val: float64(yyDollar[1].float)} } case 73: yyDollar = yyS[yypt-1 : yypt+1] { - yyVAL.values = []ValueExp{yyDollar[1].exp} + yyVAL.value = &Varchar{val: yyDollar[1].str} } case 74: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] { - yyVAL.values = append(yyDollar[1].values, yyDollar[3].exp) + yyVAL.value = &Bool{val: yyDollar[1].boolean} } case 75: yyDollar = yyS[yypt-1 : yypt+1] { - yyVAL.value = &Integer{val: int64(yyDollar[1].integer)} + yyVAL.value = &Blob{val: yyDollar[1].blob} } case 76: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] { - yyVAL.value = &Float64{val: float64(yyDollar[1].float)} + yyVAL.value = &Cast{val: yyDollar[3].exp, t: yyDollar[5].sqlType} } case 77: yyDollar = yyS[yypt-1 : yypt+1] { - yyVAL.value = &Varchar{val: yyDollar[1].str} + yyVAL.value = yyDollar[1].value } case 78: yyDollar = yyS[yypt-1 : yypt+1] { - yyVAL.value = &Bool{val: yyDollar[1].boolean} + yyVAL.value = &Param{id: yyDollar[1].id} } case 79: yyDollar = yyS[yypt-1 : yypt+1] { - yyVAL.value = &Blob{val: yyDollar[1].blob} + yyVAL.value = &Param{id: fmt.Sprintf("param%d", yyDollar[1].pparam), pos: yyDollar[1].pparam} } case 80: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] { - yyVAL.value = &Cast{val: yyDollar[3].exp, t: yyDollar[5].sqlType} + yyVAL.value = &NullValue{t: AnyType} } case 81: yyDollar = yyS[yypt-1 : yypt+1] { - yyVAL.value = yyDollar[1].value + yyVAL.sqlType = IntegerType } case 82: yyDollar = yyS[yypt-1 : yypt+1] { - yyVAL.value = &Param{id: yyDollar[1].id} + yyVAL.sqlType = BooleanType } case 83: yyDollar = yyS[yypt-1 : yypt+1] { - yyVAL.value = &Param{id: fmt.Sprintf("param%d", yyDollar[1].pparam), pos: yyDollar[1].pparam} + yyVAL.sqlType = VarcharType } case 84: yyDollar = yyS[yypt-1 : yypt+1] { - yyVAL.value = &NullValue{t: AnyType} + yyVAL.sqlType = UUIDType } case 85: + yyDollar = yyS[yypt-1 : yypt+1] + { + yyVAL.sqlType = BLOBType + } + case 86: + yyDollar = yyS[yypt-1 : yypt+1] + { + yyVAL.sqlType = TimestampType + } + case 87: + yyDollar = yyS[yypt-1 : yypt+1] + { + yyVAL.sqlType = Float64Type + } + case 88: + yyDollar = yyS[yypt-1 : yypt+1] + { + yyVAL.sqlType = JSONType + } + case 89: yyDollar = yyS[yypt-4 : yypt+1] { yyVAL.value = &FnCall{fn: yyDollar[1].id, params: yyDollar[3].values} } - case 86: + case 90: yyDollar = yyS[yypt-1 : yypt+1] { yyVAL.tableElems = []TableElem{yyDollar[1].tableElem} } - case 87: + case 91: yyDollar = yyS[yypt-3 : yypt+1] { yyVAL.tableElems = append(yyDollar[1].tableElems, yyDollar[3].tableElem) } - case 88: + case 92: yyDollar = yyS[yypt-1 : yypt+1] { yyVAL.tableElem = yyDollar[1].colSpec } - case 89: + case 93: yyDollar = yyS[yypt-1 : yypt+1] { yyVAL.tableElem = yyDollar[1].check } - case 90: + case 94: yyDollar = yyS[yypt-3 : yypt+1] { - yyVAL.tableElem = PrimaryKeyConstraint(yyDollar[3].ids) + yyVAL.tableElem = PrimaryKeyConstraint(yyDollar[3].colNames) } - case 91: + case 95: yyDollar = yyS[yypt-6 : yypt+1] { - yyVAL.colSpec = &ColSpec{colName: yyDollar[1].id, colType: yyDollar[2].sqlType, maxLen: int(yyDollar[3].integer), notNull: yyDollar[4].boolean || yyDollar[6].boolean, autoIncrement: yyDollar[5].boolean, primaryKey: yyDollar[6].boolean} + yyVAL.colSpec = &ColSpec{ + colName: yyDollar[1].str, + colType: yyDollar[2].sqlType, + maxLen: int(yyDollar[3].integer), + notNull: yyDollar[4].boolean || yyDollar[6].boolean, + autoIncrement: yyDollar[5].boolean, + primaryKey: yyDollar[6].boolean, + } } - case 92: + case 96: yyDollar = yyS[yypt-0 : yypt+1] { yyVAL.boolean = false } - case 93: + case 97: yyDollar = yyS[yypt-2 : yypt+1] { yyVAL.boolean = true } - case 94: + case 98: yyDollar = yyS[yypt-0 : yypt+1] { yyVAL.integer = 0 } - case 95: + case 99: yyDollar = yyS[yypt-3 : yypt+1] { yyVAL.integer = yyDollar[2].integer } - case 96: + case 100: yyDollar = yyS[yypt-3 : yypt+1] { yyVAL.integer = yyDollar[2].integer } - case 97: + case 101: yyDollar = yyS[yypt-0 : yypt+1] { yyVAL.boolean = false } - case 98: + case 102: yyDollar = yyS[yypt-1 : yypt+1] { yyVAL.boolean = true } - case 99: + case 103: yyDollar = yyS[yypt-0 : yypt+1] { yyVAL.boolean = false } - case 100: + case 104: yyDollar = yyS[yypt-1 : yypt+1] { yyVAL.boolean = false } - case 101: + case 105: yyDollar = yyS[yypt-2 : yypt+1] { yyVAL.boolean = true } - case 102: + case 106: yyDollar = yyS[yypt-1 : yypt+1] { yyVAL.stmt = yyDollar[1].stmt } - case 103: + case 107: yyDollar = yyS[yypt-4 : yypt+1] { yyVAL.stmt = &UnionStmt{ @@ -1475,56 +1676,56 @@ yydefault: right: yyDollar[4].stmt.(DataSource), } } - case 104: + case 108: yyDollar = yyS[yypt-2 : yypt+1] { yyVAL.stmt = &SelectStmt{ ds: &FnDataSourceStmt{fnCall: &FnCall{fn: "databases"}}, } } - case 105: + case 109: yyDollar = yyS[yypt-2 : yypt+1] { yyVAL.stmt = &SelectStmt{ ds: &FnDataSourceStmt{fnCall: &FnCall{fn: "tables"}}, } } - case 106: + case 110: yyDollar = yyS[yypt-3 : yypt+1] { yyVAL.stmt = &SelectStmt{ ds: &FnDataSourceStmt{fnCall: &FnCall{fn: "table", params: []ValueExp{&Varchar{val: yyDollar[3].id}}}}, } } - case 107: + case 111: yyDollar = yyS[yypt-2 : yypt+1] { yyVAL.stmt = &SelectStmt{ ds: &FnDataSourceStmt{fnCall: &FnCall{fn: "users"}}, } } - case 108: + case 112: yyDollar = yyS[yypt-2 : yypt+1] { yyVAL.stmt = &SelectStmt{ ds: &FnDataSourceStmt{fnCall: &FnCall{fn: "grants"}}, } } - case 109: + case 113: yyDollar = yyS[yypt-4 : yypt+1] { yyVAL.stmt = &SelectStmt{ ds: &FnDataSourceStmt{fnCall: &FnCall{fn: "grants", params: []ValueExp{&Varchar{val: yyDollar[4].id}}}}, } } - case 110: + case 114: yyDollar = yyS[yypt-13 : yypt+1] { yyVAL.stmt = &SelectStmt{ distinct: yyDollar[2].distinct, targets: yyDollar[3].targets, ds: yyDollar[5].ds, - indexOn: yyDollar[6].ids, + indexOn: yyDollar[6].colNames, joins: yyDollar[7].joins, where: yyDollar[8].exp, groupBy: yyDollar[9].cols, @@ -1534,7 +1735,7 @@ yydefault: offset: yyDollar[13].exp, } } - case 111: + case 115: yyDollar = yyS[yypt-3 : yypt+1] { yyVAL.stmt = &SelectStmt{ @@ -1543,350 +1744,395 @@ yydefault: ds: &valuesDataSource{rows: []*RowSpec{{}}}, } } - case 112: + case 116: yyDollar = yyS[yypt-0 : yypt+1] { yyVAL.distinct = true } - case 113: + case 117: yyDollar = yyS[yypt-1 : yypt+1] { yyVAL.distinct = false } - case 114: + case 118: yyDollar = yyS[yypt-0 : yypt+1] { yyVAL.distinct = false } - case 115: + case 119: yyDollar = yyS[yypt-1 : yypt+1] { yyVAL.distinct = true } - case 116: + case 120: yyDollar = yyS[yypt-1 : yypt+1] { yyVAL.targets = nil } - case 117: + case 121: yyDollar = yyS[yypt-1 : yypt+1] { yyVAL.targets = yyDollar[1].targets } - case 118: + case 122: yyDollar = yyS[yypt-2 : yypt+1] { yyVAL.targets = []TargetEntry{{Exp: yyDollar[1].exp, As: yyDollar[2].id}} } - case 119: + case 123: yyDollar = yyS[yypt-4 : yypt+1] { yyVAL.targets = append(yyDollar[1].targets, TargetEntry{Exp: yyDollar[3].exp, As: yyDollar[4].id}) } - case 120: + case 124: yyDollar = yyS[yypt-1 : yypt+1] { yyVAL.sel = yyDollar[1].col } - case 121: + case 125: yyDollar = yyS[yypt-2 : yypt+1] { yyVAL.sel = &JSONSelector{ColSelector: yyDollar[1].col, fields: yyDollar[2].jsonFields} } - case 122: + case 126: yyDollar = yyS[yypt-4 : yypt+1] { yyVAL.sel = &AggColSelector{aggFn: yyDollar[1].aggFn, col: "*"} } - case 123: + case 127: yyDollar = yyS[yypt-4 : yypt+1] { yyVAL.sel = &AggColSelector{aggFn: yyDollar[1].aggFn, table: yyDollar[3].col.table, col: yyDollar[3].col.col} } - case 124: + case 128: yyDollar = yyS[yypt-2 : yypt+1] { yyVAL.jsonFields = []string{yyDollar[2].str} } - case 125: + case 129: yyDollar = yyS[yypt-3 : yypt+1] { yyVAL.jsonFields = append(yyVAL.jsonFields, yyDollar[3].str) } - case 126: + case 130: yyDollar = yyS[yypt-1 : yypt+1] { - yyVAL.col = &ColSelector{col: yyDollar[1].id} + yyVAL.col = &ColSelector{col: yyDollar[1].str} } - case 127: + case 131: yyDollar = yyS[yypt-3 : yypt+1] { - yyVAL.col = &ColSelector{table: yyDollar[1].id, col: yyDollar[3].id} + yyVAL.col = &ColSelector{table: yyDollar[1].str, col: yyDollar[3].str} } - case 128: + case 134: + yyDollar = yyS[yypt-1 : yypt+1] + { + yyVAL.str = yyDollar[1].keyword + } + case 135: + yyDollar = yyS[yypt-1 : yypt+1] + { + yyVAL.colNames = []string{yyDollar[1].str} + } + case 136: + yyDollar = yyS[yypt-3 : yypt+1] + { + yyVAL.colNames = append(yyDollar[1].colNames, yyDollar[3].str) + } + case 137: + yyDollar = yyS[yypt-1 : yypt+1] + { + yyVAL.colNames = []string{yyDollar[1].str} + } + case 138: + yyDollar = yyS[yypt-3 : yypt+1] + { + yyVAL.colNames = yyDollar[2].colNames + } + case 139: + yyDollar = yyS[yypt-0 : yypt+1] + { + yyVAL.colNames = nil + } + case 140: + yyDollar = yyS[yypt-3 : yypt+1] + { + yyVAL.colNames = yyDollar[2].colNames + } + case 152: + yyDollar = yyS[yypt-1 : yypt+1] + { + yyVAL.str = yyDollar[1].id + } + case 153: + yyDollar = yyS[yypt-1 : yypt+1] + { + yyVAL.str = string(yyDollar[1].keyword) + } + case 186: yyDollar = yyS[yypt-3 : yypt+1] { yyDollar[1].tableRef.period = yyDollar[2].period yyDollar[1].tableRef.as = yyDollar[3].id yyVAL.ds = yyDollar[1].tableRef } - case 129: + case 187: yyDollar = yyS[yypt-4 : yypt+1] { yyVAL.ds = &valuesDataSource{inferTypes: true, rows: yyDollar[3].rows} } - case 130: + case 188: yyDollar = yyS[yypt-4 : yypt+1] { yyDollar[2].stmt.(*SelectStmt).as = yyDollar[4].id yyVAL.ds = yyDollar[2].stmt.(DataSource) } - case 131: + case 189: yyDollar = yyS[yypt-4 : yypt+1] { yyVAL.ds = &FnDataSourceStmt{fnCall: &FnCall{fn: "databases"}, as: yyDollar[4].id} } - case 132: + case 190: yyDollar = yyS[yypt-4 : yypt+1] { yyVAL.ds = &FnDataSourceStmt{fnCall: &FnCall{fn: "tables"}, as: yyDollar[4].id} } - case 133: + case 191: yyDollar = yyS[yypt-4 : yypt+1] { yyVAL.ds = &FnDataSourceStmt{fnCall: &FnCall{fn: "table", params: []ValueExp{&Varchar{val: yyDollar[3].id}}}} } - case 134: + case 192: yyDollar = yyS[yypt-4 : yypt+1] { yyVAL.ds = &FnDataSourceStmt{fnCall: &FnCall{fn: "users"}, as: yyDollar[4].id} } - case 135: + case 193: yyDollar = yyS[yypt-2 : yypt+1] { yyVAL.ds = &FnDataSourceStmt{fnCall: yyDollar[1].value.(*FnCall), as: yyDollar[2].id} } - case 136: + case 194: yyDollar = yyS[yypt-6 : yypt+1] { yyVAL.ds = &tableRef{table: yyDollar[4].id, history: true, as: yyDollar[6].id} } - case 137: + case 195: yyDollar = yyS[yypt-1 : yypt+1] { - yyVAL.tableRef = &tableRef{table: yyDollar[1].id} + yyVAL.tableRef = &tableRef{table: yyDollar[1].str} } - case 138: + case 196: yyDollar = yyS[yypt-2 : yypt+1] { yyVAL.period = period{start: yyDollar[1].openPeriod, end: yyDollar[2].openPeriod} } - case 139: + case 197: yyDollar = yyS[yypt-0 : yypt+1] { yyVAL.openPeriod = nil } - case 140: + case 198: yyDollar = yyS[yypt-2 : yypt+1] { yyVAL.openPeriod = &openPeriod{inclusive: true, instant: yyDollar[2].periodInstant} } - case 141: + case 199: yyDollar = yyS[yypt-2 : yypt+1] { yyVAL.openPeriod = &openPeriod{instant: yyDollar[2].periodInstant} } - case 142: + case 200: yyDollar = yyS[yypt-0 : yypt+1] { yyVAL.openPeriod = nil } - case 143: + case 201: yyDollar = yyS[yypt-2 : yypt+1] { yyVAL.openPeriod = &openPeriod{inclusive: true, instant: yyDollar[2].periodInstant} } - case 144: + case 202: yyDollar = yyS[yypt-2 : yypt+1] { yyVAL.openPeriod = &openPeriod{instant: yyDollar[2].periodInstant} } - case 145: + case 203: yyDollar = yyS[yypt-2 : yypt+1] { yyVAL.periodInstant = periodInstant{instantType: txInstant, exp: yyDollar[2].exp} } - case 146: + case 204: yyDollar = yyS[yypt-1 : yypt+1] { yyVAL.periodInstant = periodInstant{instantType: timeInstant, exp: yyDollar[1].exp} } - case 147: + case 205: yyDollar = yyS[yypt-0 : yypt+1] { yyVAL.joins = nil } - case 148: + case 206: yyDollar = yyS[yypt-1 : yypt+1] { yyVAL.joins = yyDollar[1].joins } - case 149: + case 207: yyDollar = yyS[yypt-1 : yypt+1] { yyVAL.joins = []*JoinSpec{yyDollar[1].join} } - case 150: + case 208: yyDollar = yyS[yypt-2 : yypt+1] { yyVAL.joins = append([]*JoinSpec{yyDollar[1].join}, yyDollar[2].joins...) } - case 151: + case 209: yyDollar = yyS[yypt-6 : yypt+1] { - yyVAL.join = &JoinSpec{joinType: yyDollar[1].joinType, ds: yyDollar[3].ds, indexOn: yyDollar[4].ids, cond: yyDollar[6].exp} + yyVAL.join = &JoinSpec{joinType: yyDollar[1].joinType, ds: yyDollar[3].ds, indexOn: yyDollar[4].colNames, cond: yyDollar[6].exp} } - case 152: + case 210: yyDollar = yyS[yypt-0 : yypt+1] { yyVAL.joinType = InnerJoin } - case 153: + case 211: yyDollar = yyS[yypt-1 : yypt+1] { yyVAL.joinType = yyDollar[1].joinType } - case 154: + case 212: yyDollar = yyS[yypt-0 : yypt+1] { yyVAL.exp = nil } - case 155: + case 213: yyDollar = yyS[yypt-2 : yypt+1] { yyVAL.exp = yyDollar[2].exp } - case 156: + case 214: yyDollar = yyS[yypt-0 : yypt+1] { yyVAL.cols = nil } - case 157: + case 215: yyDollar = yyS[yypt-3 : yypt+1] { yyVAL.cols = yyDollar[3].cols } - case 158: + case 216: yyDollar = yyS[yypt-0 : yypt+1] { yyVAL.exp = nil } - case 159: + case 217: yyDollar = yyS[yypt-2 : yypt+1] { yyVAL.exp = yyDollar[2].exp } - case 160: + case 218: yyDollar = yyS[yypt-0 : yypt+1] { yyVAL.exp = nil } - case 161: + case 219: yyDollar = yyS[yypt-2 : yypt+1] { yyVAL.exp = yyDollar[2].exp } - case 162: + case 220: yyDollar = yyS[yypt-0 : yypt+1] { yyVAL.exp = nil } - case 163: + case 221: yyDollar = yyS[yypt-2 : yypt+1] { yyVAL.exp = yyDollar[2].exp } - case 164: + case 222: yyDollar = yyS[yypt-0 : yypt+1] { yyVAL.ordexps = nil } - case 165: + case 223: yyDollar = yyS[yypt-3 : yypt+1] { yyVAL.ordexps = yyDollar[3].ordexps } - case 166: + case 224: yyDollar = yyS[yypt-0 : yypt+1] { - yyVAL.ids = nil + yyVAL.colNames = nil } - case 167: + case 225: yyDollar = yyS[yypt-4 : yypt+1] { - yyVAL.ids = yyDollar[4].ids + yyVAL.colNames = yyDollar[4].colNames } - case 168: + case 226: yyDollar = yyS[yypt-2 : yypt+1] { yyVAL.ordexps = []*OrdExp{{exp: yyDollar[1].exp, descOrder: yyDollar[2].opt_ord}} } - case 169: + case 227: yyDollar = yyS[yypt-4 : yypt+1] { yyVAL.ordexps = append(yyDollar[1].ordexps, &OrdExp{exp: yyDollar[3].exp, descOrder: yyDollar[4].opt_ord}) } - case 170: + case 228: yyDollar = yyS[yypt-0 : yypt+1] { yyVAL.opt_ord = false } - case 171: + case 229: yyDollar = yyS[yypt-1 : yypt+1] { yyVAL.opt_ord = false } - case 172: + case 230: yyDollar = yyS[yypt-1 : yypt+1] { yyVAL.opt_ord = true } - case 173: + case 231: yyDollar = yyS[yypt-0 : yypt+1] { yyVAL.id = "" } - case 174: + case 232: yyDollar = yyS[yypt-1 : yypt+1] { - yyVAL.id = yyDollar[1].id + yyVAL.id = yyDollar[1].str } - case 175: + case 233: yyDollar = yyS[yypt-2 : yypt+1] { - yyVAL.id = yyDollar[2].id + yyVAL.id = yyDollar[2].str } - case 176: + case 234: yyDollar = yyS[yypt-2 : yypt+1] { yyVAL.check = CheckConstraint{exp: yyDollar[2].exp} } - case 177: + case 235: yyDollar = yyS[yypt-4 : yypt+1] { yyVAL.check = CheckConstraint{name: yyDollar[2].id, exp: yyDollar[4].exp} } - case 178: + case 236: yyDollar = yyS[yypt-0 : yypt+1] { yyVAL.exp = nil } - case 179: + case 237: yyDollar = yyS[yypt-1 : yypt+1] { yyVAL.exp = yyDollar[1].exp } - case 180: + case 238: yyDollar = yyS[yypt-5 : yypt+1] { yyVAL.exp = &CaseWhenExp{ @@ -1895,62 +2141,62 @@ yydefault: elseExp: yyDollar[4].exp, } } - case 181: + case 239: yyDollar = yyS[yypt-4 : yypt+1] { yyVAL.whenThenClauses = []whenThenClause{{when: yyDollar[2].exp, then: yyDollar[4].exp}} } - case 182: + case 240: yyDollar = yyS[yypt-5 : yypt+1] { yyVAL.whenThenClauses = append(yyDollar[1].whenThenClauses, whenThenClause{when: yyDollar[3].exp, then: yyDollar[5].exp}) } - case 183: + case 241: yyDollar = yyS[yypt-0 : yypt+1] { yyVAL.exp = nil } - case 184: + case 242: yyDollar = yyS[yypt-2 : yypt+1] { yyVAL.exp = yyDollar[2].exp } - case 185: + case 243: yyDollar = yyS[yypt-1 : yypt+1] { yyVAL.exp = yyDollar[1].exp } - case 186: + case 244: yyDollar = yyS[yypt-3 : yypt+1] { yyVAL.exp = &BinBoolExp{left: yyDollar[1].exp, op: Or, right: yyDollar[3].exp} } - case 188: + case 246: yyDollar = yyS[yypt-3 : yypt+1] { yyVAL.exp = &BinBoolExp{left: yyDollar[1].exp, op: And, right: yyDollar[3].exp} } - case 190: + case 248: yyDollar = yyS[yypt-2 : yypt+1] { yyVAL.exp = &NotBoolExp{exp: yyDollar[2].exp} } - case 192: + case 250: yyDollar = yyS[yypt-3 : yypt+1] { yyVAL.exp = &CmpBoolExp{left: yyDollar[1].exp, op: yyDollar[2].cmpOp, right: yyDollar[3].exp} } - case 193: + case 251: yyDollar = yyS[yypt-3 : yypt+1] { yyVAL.exp = &CmpBoolExp{left: yyDollar[1].exp, op: EQ, right: &NullValue{t: AnyType}} } - case 194: + case 252: yyDollar = yyS[yypt-4 : yypt+1] { yyVAL.exp = &CmpBoolExp{left: yyDollar[1].exp, op: NE, right: &NullValue{t: AnyType}} } - case 195: + case 253: yyDollar = yyS[yypt-5 : yypt+1] { yyVAL.exp = &BinBoolExp{ @@ -1967,62 +2213,62 @@ yydefault: }, } } - case 196: + case 254: yyDollar = yyS[yypt-4 : yypt+1] { yyVAL.exp = &LikeBoolExp{val: yyDollar[1].exp, notLike: yyDollar[2].boolean, pattern: yyDollar[4].exp} } - case 197: + case 255: yyDollar = yyS[yypt-3 : yypt+1] { yyVAL.exp = &LikeBoolExp{val: yyDollar[1].exp, notLike: true, pattern: yyDollar[3].exp} } - case 199: + case 257: yyDollar = yyS[yypt-4 : yypt+1] { yyVAL.exp = &ExistsBoolExp{q: (yyDollar[3].stmt).(DataSource)} } - case 200: + case 258: yyDollar = yyS[yypt-6 : yypt+1] { yyVAL.exp = &InSubQueryExp{val: yyDollar[1].exp, notIn: yyDollar[2].boolean, q: yyDollar[5].stmt.(*SelectStmt)} } - case 201: + case 259: yyDollar = yyS[yypt-6 : yypt+1] { yyVAL.exp = &InListExp{val: yyDollar[1].exp, notIn: yyDollar[2].boolean, values: yyDollar[5].values} } - case 202: + case 260: yyDollar = yyS[yypt-1 : yypt+1] { yyVAL.exp = yyDollar[1].exp } - case 204: + case 262: yyDollar = yyS[yypt-3 : yypt+1] { yyVAL.exp = &NumExp{left: yyDollar[1].exp, op: ADDOP, right: yyDollar[3].exp} } - case 205: + case 263: yyDollar = yyS[yypt-3 : yypt+1] { yyVAL.exp = &NumExp{left: yyDollar[1].exp, op: SUBSOP, right: yyDollar[3].exp} } - case 207: + case 265: yyDollar = yyS[yypt-3 : yypt+1] { yyVAL.exp = &NumExp{left: yyDollar[1].exp, op: MULTOP, right: yyDollar[3].exp} } - case 208: + case 266: yyDollar = yyS[yypt-3 : yypt+1] { yyVAL.exp = &NumExp{left: yyDollar[1].exp, op: DIVOP, right: yyDollar[3].exp} } - case 209: + case 267: yyDollar = yyS[yypt-3 : yypt+1] { yyVAL.exp = &NumExp{left: yyDollar[1].exp, op: MODOP, right: yyDollar[3].exp} } - case 211: + case 269: yyDollar = yyS[yypt-2 : yypt+1] { i, isInt := yyDollar[2].exp.(*Integer) @@ -2033,36 +2279,71 @@ yydefault: yyVAL.exp = &NumExp{left: &Integer{val: 0}, op: SUBSOP, right: yyDollar[2].exp} } } - case 213: + case 271: yyDollar = yyS[yypt-3 : yypt+1] { yyVAL.exp = yyDollar[2].exp } - case 215: + case 273: yyDollar = yyS[yypt-1 : yypt+1] { yyVAL.exp = yyDollar[1].sel } - case 216: + case 274: yyDollar = yyS[yypt-1 : yypt+1] { yyVAL.exp = yyDollar[1].value } - case 217: + case 275: yyDollar = yyS[yypt-3 : yypt+1] { yyVAL.exp = &Cast{val: yyDollar[1].exp, t: yyDollar[3].sqlType} } - case 218: + case 276: + yyDollar = yyS[yypt-6 : yypt+1] + { + yyVAL.exp = &ExtractFromTimestampExp{Field: yyDollar[3].timestampField, Exp: yyDollar[5].exp} + } + case 277: yyDollar = yyS[yypt-0 : yypt+1] { yyVAL.boolean = false } - case 219: + case 278: yyDollar = yyS[yypt-1 : yypt+1] { yyVAL.boolean = true } + case 279: + yyDollar = yyS[yypt-1 : yypt+1] + { + yyVAL.timestampField = TimestampFieldTypeYear + } + case 280: + yyDollar = yyS[yypt-1 : yypt+1] + { + yyVAL.timestampField = TimestampFieldTypeMonth + } + case 281: + yyDollar = yyS[yypt-1 : yypt+1] + { + yyVAL.timestampField = TimestampFieldTypeDay + } + case 282: + yyDollar = yyS[yypt-1 : yypt+1] + { + yyVAL.timestampField = TimestampFieldTypeHour + } + case 283: + yyDollar = yyS[yypt-1 : yypt+1] + { + yyVAL.timestampField = TimestampFieldTypeMinute + } + case 284: + yyDollar = yyS[yypt-1 : yypt+1] + { + yyVAL.timestampField = TimestampFieldTypeSecond + } } goto yystack /* stack new state and value */ } diff --git a/embedded/sql/stmt.go b/embedded/sql/stmt.go index 08b86ce71f..5f424cac7d 100644 --- a/embedded/sql/stmt.go +++ b/embedded/sql/stmt.go @@ -2166,7 +2166,6 @@ func (v *Integer) requiresType(t SQLValueType, cols map[string]ColDescriptor, pa if t != IntegerType && t != JSONType { return fmt.Errorf("%w: %v can not be interpreted as type %v", ErrInvalidTypes, IntegerType, t) } - return nil } @@ -4780,6 +4779,124 @@ func (bexp *CmpBoolExp) String() string { return fmt.Sprintf("(%s %s %s)", bexp.left.String(), opStr, bexp.right.String()) } +type TimestampFieldType string + +const ( + TimestampFieldTypeYear TimestampFieldType = "YEAR" + TimestampFieldTypeMonth TimestampFieldType = "MONTH" + TimestampFieldTypeDay TimestampFieldType = "DAY" + TimestampFieldTypeHour TimestampFieldType = "HOUR" + TimestampFieldTypeMinute TimestampFieldType = "MINUTE" + TimestampFieldTypeSecond TimestampFieldType = "SECOND" +) + +type ExtractFromTimestampExp struct { + Field TimestampFieldType + Exp ValueExp +} + +func (te *ExtractFromTimestampExp) inferType(cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) (SQLValueType, error) { + inferredType, err := te.Exp.inferType(cols, params, implicitTable) + if err != nil { + return "", err + } + + if inferredType != TimestampType && + inferredType != VarcharType && + inferredType != AnyType { + return "", fmt.Errorf("timestamp expression must be of type %v or %v, but was: %v", TimestampType, VarcharType, inferredType) + } + return IntegerType, nil +} + +func (te *ExtractFromTimestampExp) requiresType(t SQLValueType, cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) error { + if t != IntegerType && t != Float64Type { + return fmt.Errorf("%w: %v can not be interpreted as type %v", ErrInvalidTypes, BooleanType, t) + } + return te.Exp.requiresType(TimestampType, cols, params, implicitTable) +} + +func (te *ExtractFromTimestampExp) substitute(params map[string]interface{}) (ValueExp, error) { + exp, err := te.Exp.substitute(params) + if err != nil { + return nil, err + } + return &ExtractFromTimestampExp{ + Field: te.Field, + Exp: exp, + }, nil +} + +func (te *ExtractFromTimestampExp) selectors() []Selector { + return te.Exp.selectors() +} + +func (te *ExtractFromTimestampExp) reduce(tx *SQLTx, row *Row, implicitTable string) (TypedValue, error) { + v, err := te.Exp.reduce(tx, row, implicitTable) + if err != nil { + return nil, err + } + + if v.IsNull() { + return NewNull(IntegerType), nil + } + + if t := v.Type(); t != TimestampType && t != VarcharType { + return nil, fmt.Errorf("%w: expected type %v but found type %v", ErrInvalidTypes, TimestampType, t) + } + + if v.Type() == VarcharType { + converterFunc, err := getConverter(VarcharType, TimestampType) + if err != nil { + return nil, err + } + casted, err := converterFunc(v) + if err != nil { + return nil, err + } + v = casted + } + + t, _ := v.RawValue().(time.Time) + + year, month, day := t.Date() + + switch te.Field { + case TimestampFieldTypeYear: + return NewInteger(int64(year)), nil + case TimestampFieldTypeMonth: + return NewInteger(int64(month)), nil + case TimestampFieldTypeDay: + return NewInteger(int64(day)), nil + case TimestampFieldTypeHour: + return NewInteger(int64(t.Hour())), nil + case TimestampFieldTypeMinute: + return NewInteger(int64(t.Minute())), nil + case TimestampFieldTypeSecond: + return NewInteger(int64(t.Second())), nil + } + return nil, fmt.Errorf("unknown timestamp field type: %s", te.Field) +} + +func (te *ExtractFromTimestampExp) reduceSelectors(row *Row, implicitTable string) ValueExp { + return &ExtractFromTimestampExp{ + Field: te.Field, + Exp: te.Exp.reduceSelectors(row, implicitTable), + } +} + +func (te *ExtractFromTimestampExp) isConstant() bool { + return false +} + +func (te *ExtractFromTimestampExp) selectorRanges(table *Table, asTable string, params map[string]interface{}, rangesByColID map[uint32]*typedValueRange) error { + return nil +} + +func (te *ExtractFromTimestampExp) String() string { + return fmt.Sprintf("EXTRACT(%s FROM %s)", te.Field, te.Exp) +} + func updateRangeFor(colID uint32, val TypedValue, cmp CmpOperator, rangesByColID map[uint32]*typedValueRange) error { currRange, ranged := rangesByColID[colID] var newRange *typedValueRange diff --git a/embedded/sql/stmt_test.go b/embedded/sql/stmt_test.go index ab4f9ab6b9..4c38c13566 100644 --- a/embedded/sql/stmt_test.go +++ b/embedded/sql/stmt_test.go @@ -988,6 +988,49 @@ func TestInferTypeCaseWhenExp(t *testing.T) { }) } +func TestExtractFromTimestampType(t *testing.T) { + t.Run("infer type", func(t *testing.T) { + for _, arg := range []string{"NOW()", "'2020-01-01'", "NULL"} { + e, err := ParseExpFromString( + fmt.Sprintf("EXTRACT(YEAR FROM %s)", arg), + ) + require.NoError(t, err) + + inferredType, err := e.inferType( + nil, + nil, + "", + ) + require.NoError(t, err) + require.Equal(t, IntegerType, inferredType) + } + }) + + t.Run("requires type", func(t *testing.T) { + e, err := ParseExpFromString( + "EXTRACT(YEAR FROM NOW())", + ) + require.NoError(t, err) + + err = e.requiresType(Float64Type, nil, nil, "") + require.NoError(t, err) + + err = e.requiresType(IntegerType, nil, nil, "") + require.NoError(t, err) + + e, err = ParseExpFromString( + "EXTRACT(YEAR FROM '2020-01-01')", + ) + require.NoError(t, err) + + err = e.requiresType(Float64Type, nil, nil, "") + require.Error(t, err) + + err = e.requiresType(IntegerType, nil, nil, "") + require.Error(t, err) + }) +} + func TestLikeBoolExpEdgeCases(t *testing.T) { exp := &LikeBoolExp{} @@ -1118,6 +1161,7 @@ func TestIsConstant(t *testing.T) { require.False(t, (&FnCall{}).isConstant()) require.False(t, (&ExistsBoolExp{}).isConstant()) + require.False(t, (&ExtractFromTimestampExp{}).isConstant()) } func TestTimestamapType(t *testing.T) { diff --git a/pkg/database/database_test.go b/pkg/database/database_test.go index aec2138dbb..5dee246782 100644 --- a/pkg/database/database_test.go +++ b/pkg/database/database_test.go @@ -596,7 +596,7 @@ func TestTxByID(t *testing.T) { _, _, err = db.SQLExec(context.Background(), nil, &schema.SQLExecRequest{Sql: "CREATE TABLE mytable(id INTEGER AUTO_INCREMENT, PRIMARY KEY id)"}) require.NoError(t, err) - _, ctx1, err := db.SQLExec(context.Background(), nil, &schema.SQLExecRequest{Sql: "INSERT INTO mytable() VALUES ()"}) + _, ctx1, err := db.SQLExec(context.Background(), nil, &schema.SQLExecRequest{Sql: "INSERT INTO mytable VALUES ()"}) require.NoError(t, err) require.Len(t, ctx1, 1)