diff --git a/src/sql/parser/ob_fast_parser.cpp b/src/sql/parser/ob_fast_parser.cpp index cac77df03..7368fb77a 100644 --- a/src/sql/parser/ob_fast_parser.cpp +++ b/src/sql/parser/ob_fast_parser.cpp @@ -2654,6 +2654,10 @@ int ObFastParserMysql::process_identifier(bool is_number_begin) int64_t next_idf_pos = raw_sql_.cur_pos_; while (-1 != (next_idf_pos = is_identifier_flags(next_idf_pos))) { raw_sql_.cur_pos_ = next_idf_pos; + if ('.' == raw_sql_.char_at(raw_sql_.cur_pos_)) { + raw_sql_.scan(); + next_idf_pos++; + } } } } diff --git a/src/sql/parser/sql_parser_base.h b/src/sql/parser/sql_parser_base.h index ed219780e..b2cd06484 100644 --- a/src/sql/parser/sql_parser_base.h +++ b/src/sql/parser/sql_parser_base.h @@ -240,6 +240,30 @@ do { setup_token_pos_info(node, word_start - 1, word_end - word_start + 1); \ } while (0) +#define gen_expr_node(node, name, len, p, off) \ + do { \ + char *src = (char*)parse_malloc(len + 1, p->malloc_pool_); \ + check_malloc(src); \ + memmove(src, name, len); \ + src[len] = '\0'; \ + const NonReservedKeyword *word = NULL; \ + if (NULL == (word = mysql_non_reserved_keyword_lookup(src))) \ + { \ + if (p->is_not_utf8_connection_) { \ + node->str_value_ = parse_str_convert_utf8(p->charset_info_, src, p->malloc_pool_, &(node->str_len_), &(p->extra_errno_)); \ + check_identifier_convert_result(p->extra_errno_); \ + } else { \ + node->str_value_ = parse_strdup(src, p->malloc_pool_, &(node->str_len_)); \ + } \ + } else { \ + node->str_value_ = parse_strndup(src, len, p->malloc_pool_); \ + node->str_len_ = len; \ + } \ + check_malloc(node->str_value_); \ + node->sql_str_off_ = off; \ + setup_token_pos_info(node, off, node->str_len_); \ + } while (0) + //oracle下生成非保留关键字结点请使用该宏,区别于mysql的是做了大写的转换 #define get_oracle_non_reserved_node(node, malloc_pool, expr_start, expr_end) \ do { \ diff --git a/src/sql/parser/sql_parser_mysql_mode.l b/src/sql/parser/sql_parser_mysql_mode.l index ae764543d..5e15deb96 100644 --- a/src/sql/parser/sql_parser_mysql_mode.l +++ b/src/sql/parser/sql_parser_mysql_mode.l @@ -60,6 +60,7 @@ common_hint_begin (\/\*\+({space}*hint{space}+)?) c_cmt_begin \/\* c_cmt_end \*+\/ comment ({sql_comment}) +start_identifier (([A-Za-z0-9$_]*[A-Za-z$_][A-Za-z0-9$_]*|{NOTASCII_GB_CHAR})+) identifier (([A-Za-z0-9$_]|{NOTASCII_GB_CHAR})+) system_variable (@@[A-Za-z_][A-Za-z0-9_]*)|(@@[`][`A-Za-z_][`A-Za-z_]*) user_variable (@[A-Za-z0-9_\.$]*)|(@[`'\"][`'\"A-Za-z0-9_\.$/%]*) @@ -1617,6 +1618,65 @@ BEGIN(in_c_comment); return USER_VARIABLE; } +{start_identifier}"."{identifier}"."{identifier} { + ParseResult *result = (ParseResult *)yyextra; + check_value(yylval); + if (IS_FAST_PARAMETERIZE) { + REPUT_NEG_SIGN(result); + return ID_DOT_ID_DOT_ID; + } else { + ParseNode *node = NULL, *db_node = NULL, *tb_node = NULL, *col_node = NULL; + malloc_new_node(db_node, result->malloc_pool_, T_IDENT, 0); + malloc_new_node(tb_node, result->malloc_pool_, T_IDENT, 0); + malloc_new_node(col_node, result->malloc_pool_, T_IDENT, 0); + + char *db_name = yytext; + char *tb_name = strstr(db_name, ".") + 1; + char *col_name = strstr(tb_name, ".") + 1; + size_t db_len = tb_name - db_name - 1; + size_t tb_len = col_name - tb_name - 1; + size_t col_len = strlen(col_name); + + gen_expr_node(db_node, db_name, db_len, result, yylloc->first_column - 1); + gen_expr_node(tb_node, tb_name, tb_len, result, yylloc->first_column + db_len); + gen_expr_node(col_node, col_name, col_len, result, yylloc->first_column + db_len + tb_len + 1); + malloc_new_node(node, result->malloc_pool_, T_IDENT, 3); + node->children_[0] = db_node; + node->children_[1] = tb_node; + node->children_[2] = col_node; + node->str_value_ = parse_strdup(col_node->str_value_, result->malloc_pool_, &(node->str_len_)); + yylval->node = node; + return ID_DOT_ID_DOT_ID; + } +} + +{start_identifier}"."{identifier} { + ParseResult *result = (ParseResult *)yyextra; + check_value(yylval); + if (IS_FAST_PARAMETERIZE) { + REPUT_NEG_SIGN(result); + return ID_DOT_ID; + } else { + ParseNode *node = NULL, *tb_node = NULL, *col_node = NULL; + malloc_new_node(tb_node, result->malloc_pool_, T_IDENT, 0); + malloc_new_node(col_node, result->malloc_pool_, T_IDENT, 0); + + char *tb_name = yytext; + char *col_name = strstr(tb_name, ".") + 1; + size_t tb_len = col_name - tb_name - 1; + size_t col_len = strlen(col_name); + + gen_expr_node(tb_node, tb_name, tb_len, result, yylloc->first_column - 1); + gen_expr_node(col_node, col_name, col_len, result, yylloc->first_column + tb_len); + malloc_new_node(node, result->malloc_pool_, T_IDENT, 2); + node->children_[0] = tb_node; + node->children_[1] = col_node; + node->str_value_ = parse_strdup(col_node->str_value_, result->malloc_pool_, &(node->str_len_)); + yylval->node = node; + return ID_DOT_ID; + } +} + {identifier} { const NonReservedKeyword *word = NULL; if (IS_FAST_PARAMETERIZE) { diff --git a/src/sql/parser/sql_parser_mysql_mode.y b/src/sql/parser/sql_parser_mysql_mode.y index 6baf403dc..6d77750f9 100644 --- a/src/sql/parser/sql_parser_mysql_mode.y +++ b/src/sql/parser/sql_parser_mysql_mode.y @@ -72,7 +72,8 @@ extern void obsql_oracle_parse_fatal_error(int32_t errcode, yyscan_t yyscanner, %token REMAP_TABLE_NAME %token REMAP_DATABASE_TABLE_NAME %token OUTLINE_DEFAULT_TOKEN/*use for outline parser to just filter hint of query_sql*/ - +%token ID_DOT_ID_DOT_ID +%token ID_DOT_ID /*empty_query:: // (1) 对于只有空格或者;的查询语句需要报错:如:"" 或者 " " 或者 ";" 或者 " ; " 都需要报错:err_msg:Query was empty errno:1065 // (2) 对于只含有注释或者空格或者;的查询语句则需要返回成功:如:"#fadfadf " 或者"/**\/" 或者 "/**\/ ;" 返回成功 @@ -533,6 +534,7 @@ END_P SET_VAR DELIMITER %type create_tenant_snapshot_stmt snapshot_name drop_tenant_snapshot_stmt clone_tenant_stmt clone_snapshot_option clone_tenant_option clone_tenant_option_list %type ttl_definition ttl_expr ttl_unit +%type id_dot_id id_dot_id_dot_id %start sql_stmt %% //////////////////////////////////////////////////////////////// @@ -870,6 +872,21 @@ column_name malloc_non_terminal_node($$, result->malloc_pool_, T_COLUMN_REF, 3, NULL, table_name, col_name); dup_node_string(col_name, $$, result->malloc_pool_); } +| id_dot_id +{ + ParseNode* db_node = NULL; + ParseNode* tb_node = $1->children_[0]; + ParseNode* col_node = $1->children_[1]; + malloc_non_terminal_node($$, result->malloc_pool_, T_COLUMN_REF, 3, db_node, tb_node, col_node); + dup_node_string(col_node, $$, result->malloc_pool_); + #ifndef SQL_PARSER_COMPILATION + if (3 == tb_node->str_len_) { + if (0 == strcasecmp("NEW", tb_node->str_value_) || 0 == strcasecmp("OLD", tb_node->str_value_)) { + lookup_pl_exec_symbol($$, result, @1.first_column, @1.last_column, true, false, false); + } + } + #endif +} | relation_name '.' '*' { ParseNode *node = NULL; @@ -898,6 +915,14 @@ column_name malloc_non_terminal_node($$, result->malloc_pool_, T_COLUMN_REF, 3, $1, table_name, col_name); dup_node_string(col_name, $$, result->malloc_pool_); } +| id_dot_id_dot_id +{ + ParseNode* db_node = $1->children_[0]; + ParseNode* tb_node = $1->children_[1]; + ParseNode* col_node = $1->children_[2]; + malloc_non_terminal_node($$, result->malloc_pool_, T_COLUMN_REF, 3, db_node, tb_node, col_node); + dup_node_string(col_node, $$, result->malloc_pool_); +} | relation_name '.' relation_name '.' '*' { ParseNode *node = NULL; @@ -905,6 +930,15 @@ column_name malloc_non_terminal_node($$, result->malloc_pool_, T_COLUMN_REF, 3, $1, $3, node); $$->value_ = 0; } +| id_dot_id '.' '*' +{ + ParseNode* db_node = $1->children_[0]; + ParseNode* tb_node = $1->children_[1]; + ParseNode* col_node = NULL; + malloc_terminal_node(col_node, result->malloc_pool_, T_STAR); + malloc_non_terminal_node($$, result->malloc_pool_, T_COLUMN_REF, 3, db_node, tb_node, col_node); + $$->value_ = 0; +} | '.' relation_name '.' column_name { malloc_non_terminal_node($$, result->malloc_pool_, T_COLUMN_REF, 3, NULL, $2, $4); @@ -926,6 +960,14 @@ column_name malloc_non_terminal_node($$, result->malloc_pool_, T_COLUMN_REF, 3, NULL, table_name, col_name); dup_node_string(col_name, $$, result->malloc_pool_); } +| '.' id_dot_id +{ + ParseNode* db_node = NULL; + ParseNode* tb_node = $2->children_[0]; + ParseNode* col_node = $2->children_[1]; + malloc_non_terminal_node($$, result->malloc_pool_, T_COLUMN_REF, 3, db_node, tb_node, col_node); + dup_node_string(col_node, $$, result->malloc_pool_); +} | FORCE { if (result->pl_parse_info_.is_pl_parse_) { @@ -1680,6 +1722,28 @@ simple_expr collation %prec NEG } malloc_non_terminal_node($$, result->malloc_pool_, T_REMOTE_SEQUENCE, 4, $1, $3, $5, $6); } +| id_dot_id USER_VARIABLE +{ + ParseNode* db_node = NULL; + ParseNode* tb_node = $1->children_[0]; + ParseNode* col_node = $1->children_[1]; + ParseNode *dblink_node = $2; + if (NULL != dblink_node) { + dblink_node->type_ = T_DBLINK_NAME; + } + malloc_non_terminal_node($$, result->malloc_pool_, T_REMOTE_SEQUENCE, 4, db_node, tb_node, col_node, $2); +} +| id_dot_id_dot_id USER_VARIABLE +{ + ParseNode* db_node = $1->children_[0]; + ParseNode* tb_node = $1->children_[1]; + ParseNode* col_node = $1->children_[2]; + ParseNode *dblink_node = $2; + if (NULL != dblink_node) { + dblink_node->type_ = T_DBLINK_NAME; + } + malloc_non_terminal_node($$, result->malloc_pool_, T_REMOTE_SEQUENCE, 4, db_node, tb_node, col_node, dblink_node); +} ; expr: expr AND expr %prec AND @@ -2838,6 +2902,23 @@ MOD '(' expr ',' expr ')' malloc_non_terminal_node(udf_node, result->malloc_pool_, T_FUN_UDF, 4, $3, params, $1, NULL); store_pl_ref_object_symbol(udf_node, result, REF_FUNC); } +| id_dot_id '(' opt_expr_as_list ')' +{ + ParseNode *params = NULL; + ParseNode *function = NULL; + ParseNode *sub_obj_access_ref = NULL; + ParseNode *udf_node = NULL; + ParseNode *id_node = $1; + if (NULL != $3) + { + merge_nodes(params, result, T_EXPR_LIST, $3); + } + malloc_non_terminal_node(function, result->malloc_pool_, T_FUN_SYS, 2, id_node->children_[1], params); + malloc_non_terminal_node(sub_obj_access_ref, result->malloc_pool_, T_OBJ_ACCESS_REF, 2, function, NULL); + malloc_non_terminal_node($$, result->malloc_pool_, T_OBJ_ACCESS_REF, 2, id_node->children_[0], sub_obj_access_ref); + malloc_non_terminal_node(udf_node, result->malloc_pool_, T_FUN_UDF, 4, $3, params, id_node->children_[0], NULL); + store_pl_ref_object_symbol(udf_node, result, REF_FUNC); +} | sys_interval_func { $$ = $1; @@ -5288,6 +5369,22 @@ column_name malloc_non_terminal_node($$, result->malloc_pool_, T_COLUMN_REF, 3, $1, $3, $5); dup_node_string($5, $$, result->malloc_pool_); } +| id_dot_id +{ + ParseNode* db_node = NULL; + ParseNode* tb_node = $1->children_[0]; + ParseNode* col_node = $1->children_[1]; + malloc_non_terminal_node($$, result->malloc_pool_, T_COLUMN_REF, 3, db_node, tb_node, col_node); + dup_node_string(col_node, $$, result->malloc_pool_); +} +| id_dot_id_dot_id +{ + ParseNode* db_node = $1->children_[0]; + ParseNode* tb_node = $1->children_[1]; + ParseNode* col_node = $1->children_[2]; + malloc_non_terminal_node($$, result->malloc_pool_, T_COLUMN_REF, 3, db_node, tb_node, col_node); + dup_node_string(col_node, $$, result->malloc_pool_); +} ; column_definition_list: @@ -9007,6 +9104,14 @@ column_name malloc_non_terminal_node($$, result->malloc_pool_, T_COLUMN_REF, 3, NULL, table_name, col_name); dup_node_string(col_name, $$, result->malloc_pool_); } +| id_dot_id +{ + ParseNode* db_node = NULL; + ParseNode* tb_node = $1->children_[0]; + ParseNode* col_node = $1->children_[1]; + malloc_non_terminal_node($$, result->malloc_pool_, T_COLUMN_REF, 3, db_node, tb_node, col_node); + dup_node_string(col_node, $$, result->malloc_pool_); +} | relation_name '.' '*' { ParseNode *node = NULL; @@ -9035,6 +9140,14 @@ column_name malloc_non_terminal_node($$, result->malloc_pool_, T_COLUMN_REF, 3, $1, table_name, col_name); dup_node_string(col_name, $$, result->malloc_pool_); } +| id_dot_id_dot_id +{ + ParseNode* db_node = $1->children_[0]; + ParseNode* tb_node = $1->children_[1]; + ParseNode* col_node = $1->children_[2]; + malloc_non_terminal_node($$, result->malloc_pool_, T_COLUMN_REF, 3, db_node, tb_node, col_node); + dup_node_string(col_node, $$, result->malloc_pool_); +} | relation_name '.' relation_name '.' '*' { ParseNode *node = NULL; @@ -9042,6 +9155,15 @@ column_name malloc_non_terminal_node($$, result->malloc_pool_, T_COLUMN_REF, 3, $1, $3, node); $$->value_ = 0; } +| id_dot_id '.' '*' +{ + ParseNode* db_node = $1->children_[0]; + ParseNode* tb_node = $1->children_[1]; + ParseNode* col_node = NULL; + malloc_terminal_node(col_node, result->malloc_pool_, T_STAR); + malloc_non_terminal_node($$, result->malloc_pool_, T_COLUMN_REF, 3, db_node, tb_node, col_node); + $$->value_ = 0; +} | '.' relation_name '.' column_name { malloc_non_terminal_node($$, result->malloc_pool_, T_COLUMN_REF, 3, NULL, $2, $4); @@ -9063,6 +9185,14 @@ column_name malloc_non_terminal_node($$, result->malloc_pool_, T_COLUMN_REF, 3, NULL, table_name, col_name); dup_node_string(col_name, $$, result->malloc_pool_); } +| '.' id_dot_id +{ + ParseNode* db_node = NULL; + ParseNode* tb_node = $2->children_[0]; + ParseNode* col_node = $2->children_[1]; + malloc_non_terminal_node($$, result->malloc_pool_, T_COLUMN_REF, 3, db_node, tb_node, col_node); + dup_node_string(col_node, $$, result->malloc_pool_); +} ; @@ -11812,6 +11942,14 @@ relation_name opt_with_star malloc_non_terminal_node($$, result->malloc_pool_, T_RELATION_FACTOR, 2, $1, $3); dup_node_string($3, $$, result->malloc_pool_); } +| id_dot_id opt_with_star +{ + (void)($2); + ParseNode* db_node = $1->children_[0]; + ParseNode* tb_node = $1->children_[1]; + malloc_non_terminal_node($$, result->malloc_pool_, T_RELATION_FACTOR, 2, db_node, tb_node); + dup_node_string(tb_node, $$, result->malloc_pool_); +} ; opt_with_star: @@ -11843,6 +11981,13 @@ relation_name opt_dblink malloc_non_terminal_node($$, result->malloc_pool_, T_RELATION_FACTOR, 2, $1, table_name); dup_node_string(table_name, $$, result->malloc_pool_); } +| id_dot_id opt_dblink +{ + ParseNode* db_node = $1->children_[0]; + ParseNode* tb_node = $1->children_[1]; + malloc_non_terminal_node($$, result->malloc_pool_, T_RELATION_FACTOR, 3, db_node, tb_node, $2); + dup_node_string(tb_node, $$, result->malloc_pool_); +} ; dot_relation_factor: @@ -14490,6 +14635,12 @@ priv_level: { malloc_non_terminal_node($$, result->malloc_pool_, T_PRIV_LEVEL, 2, $1, $3); } +| id_dot_id +{ + ParseNode* db_node = $1->children_[0]; + ParseNode* tb_node = $1->children_[1]; + malloc_non_terminal_node($$, result->malloc_pool_, T_PRIV_LEVEL, 2, db_node, tb_node); +} ; grant_options: @@ -17231,6 +17382,12 @@ recover_table_relation_name: { malloc_non_terminal_node($$, result->malloc_pool_, T_RELATION_FACTOR, 3, $1, $3, NULL); } +| id_dot_id +{ + ParseNode* db_node = $1->children_[0]; + ParseNode* tb_node = $1->children_[1]; + malloc_non_terminal_node($$, result->malloc_pool_, T_RELATION_FACTOR, 3, db_node, tb_node, NULL); +} | relation_name '.' '*' { malloc_non_terminal_node($$, result->malloc_pool_, T_RELATION_FACTOR, 3, $1, NULL, NULL); @@ -17331,10 +17488,22 @@ relation_name REMAP_TABLE_NAME { malloc_non_terminal_node($$, result->malloc_pool_, T_RELATION_FACTOR, 5, $1, $3, NULL, NULL, $4); } +| id_dot_id REMAP_TABLE_NAME +{ + ParseNode* db_node = $1->children_[0]; + ParseNode* tb_node = $1->children_[1]; + malloc_non_terminal_node($$, result->malloc_pool_, T_RELATION_FACTOR, 5, db_node, tb_node, NULL, NULL, $2); +} | relation_name '.' relation_name ':' relation_name { malloc_non_terminal_node($$, result->malloc_pool_, T_RELATION_FACTOR, 5, $1, $3, NULL, NULL, $5); } +| id_dot_id ':' relation_name +{ + ParseNode* db_node = $1->children_[0]; + ParseNode* tb_node = $1->children_[1]; + malloc_non_terminal_node($$, result->malloc_pool_, T_RELATION_FACTOR, 5, db_node, tb_node, NULL, NULL, $3); +} | relation_name '.' relation_name REMAP_DATABASE_TABLE_NAME { if ($4->type_ != T_LINK_NODE || $4->num_child_ != 2) { @@ -17344,10 +17513,29 @@ relation_name REMAP_TABLE_NAME malloc_non_terminal_node($$, result->malloc_pool_, T_RELATION_FACTOR, 5, $1, $3, NULL, $4->children_[0], $4->children_[1]); } } +| id_dot_id REMAP_DATABASE_TABLE_NAME +{ + ParseNode* db_node = $1->children_[0]; + ParseNode* tb_node = $1->children_[1]; + if ($2->type_ != T_LINK_NODE || $2->num_child_ != 2) { + yyerror(&@1, result, "get unexpected error in remap table"); + YYABORT_PARSE_SQL_ERROR; + } else { + malloc_non_terminal_node($$, result->malloc_pool_, T_RELATION_FACTOR, 5, db_node, tb_node, NULL, $2->children_[0], $2->children_[1]); + } +} | relation_name '.' relation_name ':' relation_name '.' relation_name { malloc_non_terminal_node($$, result->malloc_pool_, T_RELATION_FACTOR, 5, $1, $3, NULL, $5, $7); } +| id_dot_id ':' id_dot_id +{ + ParseNode* db_node1 = $1->children_[0]; + ParseNode* tb_node1 = $1->children_[1]; + ParseNode* db_node2 = $3->children_[0]; + ParseNode* tb_node2 = $3->children_[1]; + malloc_non_terminal_node($$, result->malloc_pool_, T_RELATION_FACTOR, 5, db_node1, tb_node1, NULL, db_node2, tb_node2); +} | relation_name '.' '*' REMAP_TABLE_NAME '.' '*' { malloc_non_terminal_node($$, result->malloc_pool_, T_RELATION_FACTOR, 5, $1, NULL, NULL, $4, NULL); @@ -17360,10 +17548,22 @@ relation_name REMAP_TABLE_NAME { malloc_non_terminal_node($$, result->malloc_pool_, T_RELATION_FACTOR, 5, $1, $3, $4, NULL, $5); } +| id_dot_id REMAP_TABLE_NAME REMAP_TABLE_NAME +{ + ParseNode* db_node = $1->children_[0]; + ParseNode* tb_node = $1->children_[1]; + malloc_non_terminal_node($$, result->malloc_pool_, T_RELATION_FACTOR, 5, db_node, tb_node, $2, NULL, $3); +} | relation_name '.' relation_name ':' relation_name ':' relation_name { malloc_non_terminal_node($$, result->malloc_pool_, T_RELATION_FACTOR, 5, $1, $3, $5, NULL, $7); } +| id_dot_id ':' relation_name ':' relation_name +{ + ParseNode* db_node = $1->children_[0]; + ParseNode* tb_node = $1->children_[1]; + malloc_non_terminal_node($$, result->malloc_pool_, T_RELATION_FACTOR, 5, db_node, tb_node, $3, NULL, $5); +} | relation_name '.' relation_name REMAP_TABLE_NAME REMAP_DATABASE_TABLE_NAME { if ($5->type_ != T_LINK_NODE || $5->num_child_ != 2) { @@ -17373,10 +17573,29 @@ relation_name REMAP_TABLE_NAME malloc_non_terminal_node($$, result->malloc_pool_, T_RELATION_FACTOR, 5, $1, $3, $4, $5->children_[0], $5->children_[1]); } } +| id_dot_id REMAP_TABLE_NAME REMAP_DATABASE_TABLE_NAME +{ + ParseNode* db_node = $1->children_[0]; + ParseNode* tb_node = $1->children_[1]; + if ($3->type_ != T_LINK_NODE || $3->num_child_ != 2) { + yyerror(&@1, result, "get unexpected error in remap table"); + YYABORT_PARSE_SQL_ERROR; + } else { + malloc_non_terminal_node($$, result->malloc_pool_, T_RELATION_FACTOR, 5, db_node, tb_node, $2, $3->children_[0], $3->children_[1]); + } +} | relation_name '.' relation_name ':' relation_name ':' relation_name '.' relation_name { malloc_non_terminal_node($$, result->malloc_pool_, T_RELATION_FACTOR, 5, $1, $3, $5, $7, $9); } +| id_dot_id ':' relation_name ':' id_dot_id +{ + ParseNode* db_node1 = $1->children_[0]; + ParseNode* tb_node1 = $1->children_[1]; + ParseNode* db_node2 = $5->children_[0]; + ParseNode* tb_node2 = $5->children_[1]; + malloc_non_terminal_node($$, result->malloc_pool_, T_RELATION_FACTOR, 5, db_node1, tb_node1, $3, db_node2, tb_node2); +} ; table_relation_name: @@ -18601,6 +18820,21 @@ new_or_old_column_ref: lookup_pl_exec_symbol($$, result, @1.first_column, @3.last_column, true, false, false); #endif } +| id_dot_id +{ + if (!result->is_for_trigger_) { + yyerror(&@1, result, ""); + YYERROR; + } + ParseNode* db_node = NULL; + ParseNode* tb_node = $1->children_[0]; + ParseNode* col_node = $1->children_[1]; + malloc_non_terminal_node($$, result->malloc_pool_, T_COLUMN_REF, 3, db_node, tb_node, col_node); + dup_node_string(col_node, $$, result->malloc_pool_); +#ifndef SQL_PARSER_COMPILATION + lookup_pl_exec_symbol($$, result, @1.first_column, @1.last_column, true, false, false); +#endif +} column_name: NAME_OB @@ -18619,6 +18853,13 @@ NAME_OB { $$ = $1; } } ; +id_dot_id: +ID_DOT_ID { $$ = $1; } +; +id_dot_id_dot_id: +ID_DOT_ID_DOT_ID { $$ = $1; } +; + function_name: NAME_OB { diff --git a/tools/deploy/mysql_test/r/mysql/selectotherdb.result b/tools/deploy/mysql_test/r/mysql/selectotherdb.result index 6ae8f5a64..9a15f3448 100644 --- a/tools/deploy/mysql_test/r/mysql/selectotherdb.result +++ b/tools/deploy/mysql_test/r/mysql/selectotherdb.result @@ -1,2 +1,2 @@ SELECT name FROM master.dbo.sysdatabases WHERE status <> 512; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your OceanBase version for the right syntax to use near '.sysdatabases WHERE status <> 512' at line 1 +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your OceanBase version for the right syntax to use near 'master.dbo.sysdatabases WHERE status <> 512' at line 1