Changeset: 6547eab1674f for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=6547eab1674f Modified Files: sql/server/rel_psm.c sql/server/rel_semantic.c sql/server/rel_updates.c sql/server/sql_parser.h sql/server/sql_parser.y sql/server/sql_scan.c Branch: merge-statements Log Message:
Added SQL grammar for merge statements. diffs (228 lines): diff --git a/sql/server/rel_psm.c b/sql/server/rel_psm.c --- a/sql/server/rel_psm.c +++ b/sql/server/rel_psm.c @@ -666,7 +666,8 @@ sequential_block (mvc *sql, sql_subtype case SQL_INSERT: case SQL_UPDATE: case SQL_DELETE: - case SQL_TRUNCATE: { + case SQL_TRUNCATE: + case SQL_MERGE: { sql_rel *r = rel_updates(sql, s); if (!r) return NULL; diff --git a/sql/server/rel_semantic.c b/sql/server/rel_semantic.c --- a/sql/server/rel_semantic.c +++ b/sql/server/rel_semantic.c @@ -185,6 +185,7 @@ rel_semantic(mvc *sql, symbol *s) case SQL_UPDATE: case SQL_DELETE: case SQL_TRUNCATE: + case SQL_MERGE: case SQL_COPYFROM: case SQL_BINCOPYFROM: case SQL_COPYLOADER: diff --git a/sql/server/rel_updates.c b/sql/server/rel_updates.c --- a/sql/server/rel_updates.c +++ b/sql/server/rel_updates.c @@ -1975,6 +1975,7 @@ rel_updates(mvc *sql, symbol *s) sql->type = Q_UPDATE; } break; + case SQL_MERGE: default: sql->use_views = old; return sql_error(sql, 01, SQLSTATE(42000) "Updates statement unknown Symbol(%p)->token = %s", s, token2string(s->token)); diff --git a/sql/server/sql_parser.h b/sql/server/sql_parser.h --- a/sql/server/sql_parser.h +++ b/sql/server/sql_parser.h @@ -98,6 +98,7 @@ typedef enum tokens { SQL_DELETE, SQL_TRUNCATE, SQL_UPDATE, + SQL_MERGE, SQL_STORAGE, SQL_CROSS, SQL_JOIN, @@ -190,7 +191,9 @@ typedef enum tokens { SQL_PARTITION_EXPRESSION, SQL_RENAME_SCHEMA, SQL_RENAME_TABLE, - SQL_RENAME_COLUMN + SQL_RENAME_COLUMN, + SQL_MERGE_MATCH, + SQL_MERGE_NO_MATCH } tokens; typedef enum jt { diff --git a/sql/server/sql_parser.y b/sql/server/sql_parser.y --- a/sql/server/sql_parser.y +++ b/sql/server/sql_parser.y @@ -143,6 +143,7 @@ int yydebug=1; schema_element delete_stmt truncate_stmt + merge_stmt copyfrom_stmt table_def view_def @@ -176,6 +177,7 @@ int yydebug=1; joined_table join_spec search_condition + opt_search_condition and_exp update_statement update_stmt @@ -309,6 +311,9 @@ int yydebug=1; partition_range_to partition_on partition_expression + merge_match_clause + merge_update_or_delete + merge_insert %type <type> data_type @@ -445,6 +450,7 @@ int yydebug=1; routine_designator drop_routine_designator partition_list + merge_when_list %type <i_val> any_all_some @@ -550,7 +556,7 @@ int yydebug=1; %token USER CURRENT_USER SESSION_USER LOCAL LOCKED BEST EFFORT %token CURRENT_ROLE sqlSESSION -%token <sval> sqlDELETE UPDATE SELECT INSERT +%token <sval> sqlDELETE UPDATE SELECT INSERT MATCHED %token <sval> LATERAL LEFT RIGHT FULL OUTER NATURAL CROSS JOIN INNER %token <sval> COMMIT ROLLBACK SAVEPOINT RELEASE WORK CHAIN NO PRESERVE ROWS %token START TRANSACTION READ WRITE ONLY ISOLATION LEVEL @@ -2774,12 +2780,12 @@ sql: | update_statement ; -update_statement: -/* todo merge statement */ +update_statement: delete_stmt | truncate_stmt | insert_stmt | update_stmt + | merge_stmt | copyfrom_stmt ; @@ -3070,36 +3076,51 @@ update_stmt: $$ = _symbol_create_list( SQL_UPDATE, l ); } ; -/* todo merge statment - -Conditionally update rows of a table, or insert new rows into a table, or both. - - -<merge statement> ::= - MERGE INTO <target table> [ [ AS ] <merge correlation name> ] - USING <table reference> ON <search condition> <merge operation specification> - -<merge correlation name> ::= <correlation name> - -<merge operation specification> ::= <merge when clause>... - -<merge when clause> ::= <merge when matched clause> | <merge when not matched clause> - -<merge when matched clause> ::= WHEN MATCHED THEN <merge update specification> - -<merge when not matched clause> ::= WHEN NOT MATCHED THEN <merge insert specification> - -<merge update specification> ::= UPDATE SET <set clause list> - -<merge insert specification> ::= - INSERT [ <left paren> <insert column list> <right paren> ] - [ <override clause> ] VALUES <merge insert value list> - -<merge insert value list> ::= - <left paren> <merge insert value element> [ { <comma> <merge insert value element> }... ] <right paren> - -<merge insert value element> ::= <value expression> | <contextually typed value specification> -*/ +opt_search_condition: + AND search_condition { $$ = $2; } + ; + +merge_update_or_delete: + UPDATE SET assignment_commalist { dlist *l = L(); + append_list(l, $3); + $$ = _symbol_create_list( SQL_UPDATE, l ); } + | sqlDELETE { $$ = _symbol_create_list( SQL_DELETE, NULL ); } + ; + +merge_insert: + INSERT values_or_query_spec { dlist *l = L(); + append_symbol(l, $2); + $$ = _symbol_create_list( SQL_INSERT, l ); } + ; + +merge_match_clause: + WHEN MATCHED opt_search_condition THEN merge_update_or_delete + { dlist *l = L(); + append_symbol(l, $3); + append_symbol(l, $5); + $$ = _symbol_create_list( SQL_MERGE_MATCH, l ); } + | WHEN NOT MATCHED opt_search_condition THEN merge_insert + { dlist *l = L(); + append_symbol(l, $4); + append_symbol(l, $6); + $$ = _symbol_create_list( SQL_MERGE_NO_MATCH, l ); } + ; + +merge_when_list: + merge_match_clause { $$ = append_symbol(L(), $1); } + | merge_when_list merge_match_clause { $$ = append_symbol($1, $2); } + ; + +merge_stmt: + MERGE INTO qname opt_alias_name USING table_ref ON search_condition merge_when_list + + { dlist *l = L(); + append_list(l, $3); + append_string(l, $4); + append_symbol(l, $6); + append_symbol(l, $8); + append_list(l, $9); + $$ = _symbol_create_list( SQL_MERGE, l ); } insert_stmt: INSERT INTO qname values_or_query_spec @@ -6458,6 +6479,7 @@ char *token2string(int token) SQL(DELETE); SQL(TRUNCATE); SQL(UPDATE); + SQL(MERGE); SQL(CROSS); SQL(JOIN); SQL(SELECT); @@ -6536,6 +6558,8 @@ char *token2string(int token) SQL(RENAME_SCHEMA); SQL(RENAME_TABLE); SQL(RENAME_COLUMN); + SQL(MERGE_MATCH); + SQL(MERGE_NO_MATCH); } return "unknown"; /* just needed for broken compilers ! */ } diff --git a/sql/server/sql_scan.c b/sql/server/sql_scan.c --- a/sql/server/sql_scan.c +++ b/sql/server/sql_scan.c @@ -192,6 +192,7 @@ scanner_init_keywords(void) failed += keywords_insert("UPDATE", UPDATE); failed += keywords_insert("DELETE", sqlDELETE); failed += keywords_insert("TRUNCATE", TRUNCATE); + failed += keywords_insert("MATCHED", MATCHED); failed += keywords_insert("ACTION", ACTION); failed += keywords_insert("CASCADE", CASCADE); _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list