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

Reply via email to