[CP] [CP] grammar compatibility: support insert duplicate update with row alias
This commit is contained in:
@ -131,7 +131,7 @@ extern void obsql_oracle_parse_fatal_error(int32_t errcode, yyscan_t yyscanner,
|
||||
//%nonassoc STRING_VALUE
|
||||
%left '(' ')'
|
||||
%nonassoc SQL_CACHE SQL_NO_CACHE CHARSET DATABASE_ID REPLICA_NUM/*for shift/reduce conflict between opt_query_expresion_option_list and SQL_CACHE*/
|
||||
%nonassoc HIGHER_PARENS TRANSACTION SIZE AUTO SKEWONLY DEFAULT/*for simple_expr conflict*/
|
||||
%nonassoc HIGHER_PARENS TRANSACTION SIZE AUTO SKEWONLY DEFAULT AS/*for simple_expr conflict*/
|
||||
%left '.'
|
||||
%right NOT NOT2
|
||||
%right BINARY COLLATE
|
||||
@ -403,7 +403,7 @@ END_P SET_VAR DELIMITER
|
||||
%type <node> opt_generated_keyname opt_generated_option_list opt_generated_column_attribute_list generated_column_attribute opt_storage_type
|
||||
%type <node> data_type special_table_type opt_if_not_exists opt_if_exists opt_charset collation opt_collation cast_data_type
|
||||
%type <node> replace_with_opt_hint insert_with_opt_hint column_list opt_on_duplicate_key_clause opt_into opt_replace opt_temporary opt_algorithm opt_sql_security opt_definer view_algorithm no_param_column_ref
|
||||
%type <node> insert_vals_list insert_vals value_or_values
|
||||
%type <node> insert_vals_list insert_vals value_or_values opt_insert_row_alias
|
||||
%type <node> select_with_parens select_no_parens select_clause select_into no_table_select_with_order_and_limit simple_select_with_order_and_limit select_with_parens_with_order_and_limit select_clause_set select_clause_set_left select_clause_set_right select_clause_set_with_order_and_limit
|
||||
%type <node> simple_select no_table_select limit_clause select_expr_list
|
||||
%type <node> with_select with_clause with_list common_table_expr opt_column_alias_name_list alias_name_list column_alias_name
|
||||
@ -8793,12 +8793,39 @@ dml_table_name values_clause
|
||||
NULL, /*duplicate key node*/
|
||||
NULL /*error logging caluse*/);
|
||||
}
|
||||
| dml_table_name SET update_asgn_list
|
||||
| dml_table_name SET update_asgn_list opt_insert_row_alias
|
||||
{
|
||||
ParseNode *val_list = NULL;
|
||||
ParseNode *into_node = NULL;
|
||||
merge_nodes(val_list, result, T_ASSIGN_LIST, $3);
|
||||
malloc_non_terminal_node(into_node, result->malloc_pool_, T_INSERT_INTO_CLAUSE, 1, $1);
|
||||
if ($4 != NULL) {
|
||||
ParseNode *subquery_node = NULL;
|
||||
ParseNode *values_node = NULL;
|
||||
ParseNode *values_list_node = NULL;
|
||||
ParseNode *select_node = NULL;
|
||||
ParseNode *column_list_node = new_node(result->malloc_pool_, T_COLUMN_LIST, val_list->num_child_);
|
||||
ParseNode *value_vector_node = new_node(result->malloc_pool_, T_VALUE_VECTOR, val_list->num_child_);
|
||||
for (int32_t i = 0; i < val_list->num_child_; i++) {
|
||||
ParseNode *assign_item = val_list->children_[i];
|
||||
if (assign_item->num_child_ != 2) {
|
||||
yyerror(&@3, result, "assign_item child num is invalid\n");
|
||||
YYERROR;
|
||||
} else {
|
||||
column_list_node->children_[i]=assign_item->children_[0];
|
||||
value_vector_node->children_[i]=assign_item->children_[1];
|
||||
}
|
||||
}
|
||||
malloc_non_terminal_node(into_node, result->malloc_pool_, T_INSERT_INTO_CLAUSE, 2, $1, column_list_node);
|
||||
malloc_non_terminal_node(values_list_node, result->malloc_pool_, T_VALUES_ROW_LIST, 1, value_vector_node);
|
||||
malloc_non_terminal_node(values_node, result->malloc_pool_, T_VALUES_TABLE_EXPRESSION, 1, values_list_node);
|
||||
malloc_select_values_stmt(subquery_node, result, values_node, NULL, NULL);
|
||||
malloc_select_values_stmt(select_node, result, subquery_node, NULL, NULL);
|
||||
select_node->children_[PARSE_SELECT_FROM]->children_[0]->children_[1] = $4;
|
||||
val_list = select_node;
|
||||
val_list->reserved_ = 1;
|
||||
} else {
|
||||
malloc_non_terminal_node(into_node, result->malloc_pool_, T_INSERT_INTO_CLAUSE, 1, $1);
|
||||
}
|
||||
malloc_non_terminal_node($$, result->malloc_pool_, T_SINGLE_TABLE_INSERT, 4,
|
||||
into_node, /*insert_into_clause*/
|
||||
val_list, /*values_list*/
|
||||
@ -8808,10 +8835,27 @@ dml_table_name values_clause
|
||||
;
|
||||
|
||||
values_clause:
|
||||
value_or_values insert_vals_list
|
||||
value_or_values insert_vals_list opt_insert_row_alias
|
||||
{
|
||||
(void)($1);
|
||||
merge_nodes($$, result, T_VALUE_LIST, $2);
|
||||
if ($3 != NULL) {
|
||||
ParseNode *subquery_node = NULL;
|
||||
ParseNode *values_node = NULL;
|
||||
ParseNode *values_list_node = NULL;
|
||||
if ($2->type_ == T_LINK_NODE) {
|
||||
$2->type_ = T_VALUES_ROW_LIST;
|
||||
values_list_node = $2;
|
||||
} else {
|
||||
malloc_non_terminal_node(values_list_node, result->malloc_pool_, T_VALUES_ROW_LIST, 1, $2);
|
||||
}
|
||||
malloc_non_terminal_node(values_node, result->malloc_pool_, T_VALUES_TABLE_EXPRESSION, 1, values_list_node);
|
||||
malloc_select_values_stmt(subquery_node, result, values_node, NULL, NULL);
|
||||
malloc_select_values_stmt($$, result, subquery_node, NULL, NULL);
|
||||
$$->children_[PARSE_SELECT_FROM]->children_[0]->children_[1] = $3;
|
||||
$$->reserved_ = 1;
|
||||
} else {
|
||||
merge_nodes($$, result, T_VALUE_LIST, $2);
|
||||
}
|
||||
}
|
||||
| select_stmt
|
||||
{
|
||||
@ -8819,6 +8863,19 @@ value_or_values insert_vals_list
|
||||
}
|
||||
;
|
||||
|
||||
opt_insert_row_alias:
|
||||
AS table_subquery_alias
|
||||
{
|
||||
(void)($1);
|
||||
if (OB_UNLIKELY(T_STAR == $2->type_)) {
|
||||
yyerror(&@2, result, "table.* as label is invalid\n");
|
||||
YYERROR;
|
||||
} else {
|
||||
$$ = $2;
|
||||
}
|
||||
}
|
||||
| /*emtpy*/ {$$ = NULL;};
|
||||
|
||||
value_or_values:
|
||||
VALUE
|
||||
{
|
||||
|
Reference in New Issue
Block a user