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
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list