2
* Copyright (c) 2021 OceanBase
3
* OceanBase CE is licensed under Mulan PubL v2.
4
* You can use this software according to the terms and conditions of the Mulan PubL v2.
5
* You may obtain a copy of Mulan PubL v2 at:
6
* http://license.coscl.org.cn/MulanPubL-2.0
7
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
8
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
9
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
10
* See the Mulan PubL v2 for more details.
15
%parse-param {ObParseCtx *parse_ctx}
16
%name-prefix "obpl_mysql_yy"
28
struct _ParseNode *node;
29
const struct _NonReservedKeyword *non_reserved_keyword;
34
#ifndef YYLTYPE_IS_DECLARED
35
#define YYLTYPE_IS_DECLARED 1
45
#endif /*YYLTYPE_IS_DECLARED*/
47
# define YYLLOC_DEFAULT(Current, Rhs, N) \
50
(Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
51
(Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
52
(Current).last_line = YYRHSLOC (Rhs, N).last_line; \
53
(Current).last_column = YYRHSLOC (Rhs, N).last_column; \
54
(Current).abs_first_column = YYRHSLOC (Rhs, 1).abs_first_column; \
55
(Current).abs_last_column = YYRHSLOC (Rhs, N).abs_last_column; \
57
(Current).first_line = (Current).last_line = \
58
YYRHSLOC (Rhs, 0).last_line; \
59
(Current).first_column = (Current).last_column = \
60
YYRHSLOC (Rhs, 0).last_column; \
61
(Current).abs_first_column = (Current).abs_last_column = \
62
YYRHSLOC (Rhs, 0).abs_last_column; \
68
#include "pl/parser/pl_parser_mysql_mode_lex.h"
69
#include "pl/parser/pl_parser_base.h"
71
typedef struct _YYLookaheadToken
74
/* The semantic value of the lookahead symbol. */
76
/* Location data for the lookahead symbol. */
80
extern ParseNode *obpl_mysql_read_sql_construct(ObParseCtx *parse_ctx, const char *prefix, YYLookaheadToken *la_token, int end_token_cnt, ...);
81
extern void obpl_mysql_yyerror(YYLTYPE *yylloc, ObParseCtx *parse_ctx, char *s, ...);
82
extern void obpl_mysql_parse_fatal_error(int32_t errcode, yyscan_t yyscanner, yyconst char *msg, ...);
84
int obpl_mysql_check_specific_node(const ParseNode *node, const ObItemType type, int *is_contain) {
85
int ret = OB_PARSER_SUCCESS;
86
if (obpl_parser_check_stack_overflow()) {
87
ret = OB_PARSER_ERR_SIZE_OVERFLOW;
88
} else if (OB_UNLIKELY(NULL == is_contain)) {
89
ret = OB_PARSER_ERR_UNEXPECTED;
94
if (OB_PARSER_SUCCESS == ret && OB_NOT_NULL(node)) {
95
if (type == node->type_) {
98
for (int64_t i = 0; OB_PARSER_SUCCESS == ret && !*is_contain && i < node->num_child_; ++i) {
99
ret = obpl_mysql_check_specific_node(node->children_[i], type, is_contain);
106
int obpl_mysql_wrap_node_into_subquery(ObParseCtx *_parse_ctx, ParseNode *node) {
107
int ret = OB_PARSER_SUCCESS;
108
if (OB_NOT_NULL(node) && OB_NOT_NULL(node->str_value_)) {
109
int max_query_len = node->str_len_ + 10;
110
char *subquery = (char *)parse_malloc(max_query_len, _parse_ctx->mem_pool_);
112
if (OB_UNLIKELY(NULL == subquery)) {
113
ret = OB_PARSER_ERR_NO_MEMORY;
114
} else if ((len = snprintf(subquery, max_query_len, "(SELECT %s)", node->str_value_)) <= 0) {
115
ret = OB_PARSER_ERR_UNEXPECTED;
117
ParseResult parse_result;
118
memset(&parse_result, 0, sizeof(ParseResult));
119
parse_result.input_sql_ = subquery;
120
parse_result.input_sql_len_ = len;
121
parse_result.malloc_pool_ = _parse_ctx->mem_pool_;
122
parse_result.pl_parse_info_.is_pl_parse_ = true;
123
parse_result.pl_parse_info_.is_pl_parse_expr_ = true;
124
parse_result.is_for_trigger_ = (1 == _parse_ctx->is_for_trigger_);
125
parse_result.question_mark_ctx_ = _parse_ctx->question_mark_ctx_;
126
parse_result.charset_info_ = _parse_ctx->charset_info_;
127
parse_result.charset_info_oracle_db_ = _parse_ctx->charset_info_oracle_db_;
128
parse_result.is_not_utf8_connection_ = _parse_ctx->is_not_utf8_connection_;
129
parse_result.connection_collation_ = _parse_ctx->connection_collation_;
130
parse_result.sql_mode_ = _parse_ctx->scanner_ctx_.sql_mode_;
131
if (0 == parse_sql_stmt(&parse_result)) {
132
*node = *parse_result.result_tree_->children_[0];
133
node->str_value_ = subquery;
134
node->str_len_ = len;
135
node->pl_str_off_ = -1;
142
void obpl_mysql_wrap_get_user_var_into_subquery(ObParseCtx *parse_ctx, ParseNode *node) {
143
int ret = OB_PARSER_SUCCESS;
144
int is_contain = false;
145
if (OB_PARSER_SUCCESS != (ret = obpl_mysql_check_specific_node(node, T_OP_GET_USER_VAR, &is_contain))) {
146
obpl_mysql_parse_fatal_error(ret, YYLEX_PARAM, "failed to check T_OP_GET_USER_VAR in parse tree");
147
} else if (is_contain) {
148
if (OB_PARSER_SUCCESS != (ret = obpl_mysql_wrap_node_into_subquery(parse_ctx, node))) {
149
obpl_mysql_parse_fatal_error(ret, YYLEX_PARAM, "failed to wrap T_OP_GET_USER_VAR into subquery");
154
#define YY_FATAL_ERROR(msg, args...) (obpl_mysql_parse_fatal_error(OB_PARSER_ERR_NO_MEMORY, YYLEX_PARAM, msg, ##args))
155
#define YY_UNEXPECTED_ERROR(msg, args...) (obpl_mysql_parse_fatal_error(OB_PARSER_ERR_UNEXPECTED, YYLEX_PARAM, msg, ##args))
157
#define do_parse_sql_stmt(node, _parse_ctx, start_loc, end_loc, end_tok_num, ...) \
159
YYLookaheadToken la_token; \
160
la_token.la_yychar = &yychar; \
161
la_token.la_yylval = &yylval; \
162
la_token.la_yylloc = &yylloc; \
163
_parse_ctx->scanner_ctx_.sql_start_loc = start_loc; \
164
_parse_ctx->scanner_ctx_.sql_end_loc = end_loc; \
165
node = obpl_mysql_read_sql_construct(_parse_ctx, "", &la_token, end_tok_num, ##__VA_ARGS__); \
166
if (NULL == node) { \
169
reset_current_location(_parse_ctx->scanner_ctx_.sql_start_loc, _parse_ctx->scanner_ctx_.sql_end_loc); \
172
#define do_parse_sql_expr_rule(node, _parse_ctx, end_tok_num, ...) \
174
ParseNode *select_node = NULL; \
175
YYLookaheadToken la_token; \
176
la_token.la_yychar = &yychar; \
177
la_token.la_yylval = &yylval; \
178
la_token.la_yylloc = &yylloc; \
179
_parse_ctx->scanner_ctx_.sql_start_loc = -1; \
180
_parse_ctx->scanner_ctx_.sql_end_loc = -1; \
181
select_node = obpl_mysql_read_sql_construct(_parse_ctx, "SELECT ", &la_token, end_tok_num, ##__VA_ARGS__); \
182
reset_current_location(_parse_ctx->scanner_ctx_.sql_start_loc, _parse_ctx->scanner_ctx_.sql_end_loc); \
183
if (select_node != NULL) { \
184
if (NULL == select_node->children_[2] || NULL == select_node->children_[2]->children_[0]) { \
187
node = select_node->children_[2]->children_[0]->children_[0]; \
195
/*these tokens can't be used for obj names*/
197
/* reserved key words */
198
%token ALTER BEFORE BY CALL CASE CONDITION CONTINUE CREATE CURRENT_USER CURSOR DECLARE
199
DEFAULT DELETE DETERMINISTIC DROP EACH ELSE ELSEIF EXISTS EXIT FETCH FOR FROM IF IN
200
INDEX INOUT INSERT INTO IS ITERATE LEAVE LIMIT LONG LOOP MODIFIES NOT ON OR OUT
201
PROCEDURE READS REPEAT REPLACE RESIGNAL RETURN SELECT SIGNAL SQL SQLEXCEPTION
202
SQLSTATE SQLWARNING TABLE THEN TRIGGER UPDATE USING WHEN WHILE
203
/* reserved key words only used in ob, in mysql these keywords are non reserved*/
204
%token COMMIT ROLLBACK DO UNTIL
206
%token SQL_KEYWORD SQL_TOKEN PARAM_ASSIGN_OPERATOR
207
%token PARSER_SYNTAX_ERROR /*used internal*/
208
%token <node> IDENT STRING INTNUM DECIMAL_VAL HEX_STRING_VALUE DATE_VALUE SYSTEM_VARIABLE USER_VARIABLE NULLX
209
%token <node> USER_NAME
210
//*data type keyword*/
211
%token TINYINT SMALLINT MEDIUMINT INTEGER BIGINT FLOAT DOUBLE PRECISION NUMBER NUMERIC BIT
212
DATETIME TIMESTAMP TIME DATE YEAR CHARACTER TEXT VARCHAR NCHAR NVARCHAR BINARY VARBINARY UNSIGNED
213
SIGNED ZEROFILL COLLATE SET CHARSET BOOL BOOLEAN BLOB ENUM TINYTEXT MEDIUMTEXT LONGTEXT TINYBLOB
214
MEDIUMBLOB LONGBLOB VARYING
216
/* non reserved key words */
217
%token <non_reserved_keyword>
218
AFTER AUTHID BEGIN_KEY BINARY_INTEGER BODY C CATALOG_NAME CLASS_ORIGIN CLOSE COLUMN_NAME COMMENT
219
CONSTRAINT_CATALOG CONSTRAINT_NAME CONSTRAINT_ORIGIN CONSTRAINT_SCHEMA CONTAINS COUNT CURSOR_NAME
220
DATA DEFINER END_KEY EXTEND FOLLOWS FOUND FUNCTION HANDLER INTERFACE INVOKER JSON LANGUAGE
221
MESSAGE_TEXT MYSQL_ERRNO NATIONAL NEXT NO OF OPEN PACKAGE PRAGMA PRECEDES RECORD RETURNS ROW ROWTYPE
222
SCHEMA_NAME SECURITY SUBCLASS_ORIGIN TABLE_NAME TYPE VALUE
227
%nonassoc LOWER_PARENS
231
%nonassoc AUTHID INTERFACE
234
%type <node> sql_keyword
235
%type <non_reserved_keyword> unreserved_keyword
236
%type <node> stmt_block stmt_list stmt outer_stmt sp_proc_outer_statement sp_proc_inner_statement sp_proc_independent_statement
237
%type <node> create_procedure_stmt sp_proc_stmt expr expr_list procedure_body default_expr
238
%type <node> create_function_stmt function_body
239
%type <node> drop_procedure_stmt drop_function_stmt
240
%type <node> alter_procedure_stmt alter_function_stmt opt_sp_alter_chistics
241
%type <node> sp_unlabeled_block
242
%type <node> sp_block_content opt_sp_decls sp_proc_stmts sp_decl sp_decls
243
%type <node> sp_labeled_block label_ident opt_sp_label
244
%type <node> sp_decl_idents sp_data_type opt_sp_decl_default opt_param_default
245
%type <node> sp_proc_stmt_if sp_if sp_proc_stmt_case sp_when_list sp_when sp_elseifs
246
%type <node> sp_proc_stmt_return
247
%type <node> sql_stmt ident simple_ident
248
%type <node> into_clause
249
%type <node> sp_name sp_call_name opt_sp_param_list opt_sp_fparam_list sp_param_list sp_fparam_list
250
%type <node> sp_param sp_fparam sp_alter_chistics
251
%type <node> opt_sp_definer sp_create_chistics sp_create_chistic sp_chistic opt_parentheses user opt_host_name
252
%type <node> param_type sp_cparams opt_sp_cparam_list cexpr sp_cparam opt_sp_cparam_with_assign
253
%type <ival> opt_sp_inout opt_if_exists
254
%type <node> call_sp_stmt do_sp_stmt
255
%type <node> sp_cond sp_hcond_list sp_hcond
256
%type <node> sp_unlabeled_control sp_labeled_control
257
%type <node> sp_proc_stmt_iterate
258
%type <node> sp_proc_stmt_leave
259
%type <node> sqlstate opt_value
260
%type <ival> sp_handler_type
261
%type <node> signal_stmt resignal_stmt
262
%type <node> signal_value opt_signal_value opt_set_signal_information signal_allowed_expr
263
%type <node> signal_information_item_list signal_information_item
264
%type <ival> scond_info_item_name
265
%type <node> sp_proc_stmt_open sp_proc_stmt_fetch sp_proc_stmt_close
266
%type <node> opt_package_stmts package_stmts package_stmt drop_package_stmt interface_pragma
267
%type <node> package_block package_body_block create_package_stmt create_package_body_stmt
268
%type <node> invoke_right proc_clause proc_clause_list opt_proc_clause
269
%type <node> decl_stmt_ext_list decl_stmt_ext func_decl proc_decl
270
%type <node> opt_tail_package_name
271
%type <ival> opt_replace
272
%type <node> create_trigger_stmt drop_trigger_stmt plsql_trigger_source
273
%type <node> trigger_definition trigger_event trigger_body pl_obj_access_ref opt_trigger_order
274
%type <ival> trigger_time
276
%type <node> scalar_data_type opt_charset collation opt_collation charset_name collation_name
277
%type <node> number_literal literal charset_key opt_float_precision opt_number_precision opt_binary
278
%type <node> string_list text_string
279
%type <ival> string_length_i opt_string_length_i opt_int_length_i opt_string_length_i_v2
280
%type <ival> opt_bit_length_i opt_datetime_fsp_i opt_unsigned_i opt_zerofill_i opt_year_i
281
%type <ival> int_type_i float_type_i datetime_type_i date_year_type_i text_type_i blob_type_i
282
%type <ival> nchar_type_i nvarchar_type_i
285
/*****************************************************************************
287
* MULTI STMT BLOCK start grammar
289
*****************************************************************************/
293
merge_nodes($$, parse_ctx->mem_pool_, T_STMT_LIST, $1);
294
parse_ctx->stmt_tree_ = $$;
302
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_LINK_NODE, 2, $1, $3);
303
parse_ctx->stmt_tree_ = $$;
308
parse_ctx->stmt_tree_ = $$;
310
/* | stmt_list ';' error
323
if(NULL != $1 && !parse_ctx->is_inner_parse_) {
325
// wrap nodes of following types into an anonymous block to mock SQL execution.
328
case T_SP_RESIGNAL: {
329
ParseNode *proc_stmts = NULL;
330
merge_nodes(proc_stmts, parse_ctx->mem_pool_, T_SP_PROC_STMT_LIST, $1);
331
ParseNode *block_content = NULL;
332
merge_nodes(block_content, parse_ctx->mem_pool_, T_SP_BLOCK_CONTENT, proc_stmts);
333
malloc_non_terminal_node($1, parse_ctx->mem_pool_, T_SP_ANONYMOUS_BLOCK, 1, block_content);
342
int32_t str_len = @1.last_column - @1.first_column + 1;
343
$$->pos_ = @1.first_column;
344
$$->str_len_ = str_len;
346
| /*Empty*/ { $$ = NULL; }
349
create_procedure_stmt { $$ = $1; }
350
| create_function_stmt { $$ = $1; }
351
| drop_procedure_stmt { $$ = $1; }
352
| drop_function_stmt { $$ = $1; }
353
| alter_procedure_stmt { $$ = $1; }
354
| alter_function_stmt { $$ = $1; }
355
| create_package_stmt { $$ = $1; }
356
| create_package_body_stmt { $$ = $1; }
357
| drop_package_stmt { $$ = $1; }
358
| sql_stmt { $$ = $1; }
359
| call_sp_stmt { $$ = $1; }
360
| do_sp_stmt { $$ = $1; }
361
| signal_stmt { $$ = $1; }
362
| resignal_stmt { $$ = $1; }
363
| package_block { $$ = $1; }
364
| package_body_block { $$ = $1; }
365
| create_trigger_stmt { $$ = $1; }
366
| drop_trigger_stmt { $$ = $1; }
367
| plsql_trigger_source
369
if (!parse_ctx->is_inner_parse_) {
370
obpl_mysql_yyerror(&@1, parse_ctx, "Syntax Error\n");
377
/*****************************************************************************
381
*****************************************************************************/
383
'(' sql_keyword { $$ = NULL; }
384
| SQL_KEYWORD { $$ = NULL; }
385
| TABLE { $$ = NULL; }
386
| INSERT { $$ = NULL; }
387
| DELETE { $$ = NULL; }
388
| UPDATE { $$ = NULL; }
392
sql_keyword /*sql stmt tail*/
394
//read sql query string直到读到token';'或者END_P
395
ParseNode *sql_stmt = NULL;
396
do_parse_sql_stmt(sql_stmt, parse_ctx, @1.first_column, @1.last_column, 2, ';', END_P);
397
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SQL_STMT, 1, sql_stmt);
399
| REPLACE /*sql stmt tail*/
401
//read sql query string直到读到token';'或者END_P
402
ParseNode *sql_stmt = NULL;
403
do_parse_sql_stmt(sql_stmt, parse_ctx, @1.first_column, @1.last_column, 2, ';', END_P);
404
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SQL_STMT, 1, sql_stmt);
406
| CREATE sql_keyword /*sql stmt tail*/
408
//read sql query string直到读到token';'或者END_P
409
ParseNode *sql_stmt = NULL;
410
do_parse_sql_stmt(sql_stmt, parse_ctx, @1.first_column, @1.last_column, 2, ';', END_P);
411
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SQL_STMT, 1, sql_stmt);
413
| CREATE OR REPLACE sql_keyword /*sql stmt tail*/
415
//read sql query string直到读到token';'或者END_P
416
ParseNode *sql_stmt = NULL;
417
do_parse_sql_stmt(sql_stmt, parse_ctx, @1.first_column, @1.last_column, 2, ';', END_P);
418
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SQL_STMT, 1, sql_stmt);
420
| DROP sql_keyword /*sql stmt tail*/
422
//read sql query string直到读到token';'或者END_P
423
ParseNode *sql_stmt = NULL;
424
do_parse_sql_stmt(sql_stmt, parse_ctx, @1.first_column, @1.last_column, 2, ';', END_P);
425
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SQL_STMT, 1, sql_stmt);
427
| ALTER sql_keyword /*sql stmt tail*/
429
//read sql query string直到读到token';'或者END_P
430
ParseNode *sql_stmt = NULL;
431
do_parse_sql_stmt(sql_stmt, parse_ctx, @1.first_column, @1.last_column, 2, ';', END_P);
432
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SQL_STMT, 1, sql_stmt);
434
| SET /*sql stmt tail*/
436
//read sql query string直到读到token';'或者END_P
437
ParseNode *sql_stmt = NULL;
438
do_parse_sql_stmt(sql_stmt, parse_ctx, @1.first_column, @1.last_column, 2, ';', END_P);
439
if (T_SET_PASSWORD == sql_stmt->type_ ||
440
T_SET_NAMES == sql_stmt->type_ ||
441
T_SET_CHARSET == sql_stmt->type_) {
442
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SQL_STMT, 1, sql_stmt);
446
if(T_VARIABLE_SET == $$->type_) {
447
for(int64_t i = 0; i < $$->num_child_; ++i) {
448
if(OB_UNLIKELY(NULL == $$->children_[i] || NULL == $$->children_[i]->children_[1])) {
449
YY_UNEXPECTED_ERROR("value node in SET statement is NULL");
451
obpl_mysql_wrap_get_user_var_into_subquery(parse_ctx, $$->children_[i]->children_[1]);
458
malloc_terminal_node($$, parse_ctx->mem_pool_, T_SQL_STMT);
459
$$->str_value_ = parse_strdup("COMMIT", parse_ctx->mem_pool_, &($$->str_len_));
460
if (OB_UNLIKELY(NULL == $$->str_value_)) {
461
YY_FATAL_ERROR("no more memory to malloc 'COMMIT; string\n");
466
malloc_terminal_node($$, parse_ctx->mem_pool_, T_SQL_STMT);
467
$$->str_value_ = parse_strdup("ROLLBACK", parse_ctx->mem_pool_, &($$->str_len_));
468
if (OB_UNLIKELY(NULL == $$->str_value_)) {
469
YY_FATAL_ERROR("no more memory to malloc 'ROLLBACK; string\n");
472
| SELECT //为了支持(select……)的用法,把SELECT也从sql_keyword分支里拿出来
474
//read sql query string直到读到token';'或者END_P
475
ParseNode *sql_stmt = NULL;
476
do_parse_sql_stmt(sql_stmt, parse_ctx, @1.first_column, @1.last_column, 2, ';', END_P);
477
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SQL_STMT, 1, sql_stmt);
479
| '(' SELECT %prec PARENS
481
//read sql query string直到读到token';'或者END_P
482
ParseNode *sql_stmt = NULL;
483
do_parse_sql_stmt(sql_stmt, parse_ctx, @1.first_column, @1.last_column, 2, ';', END_P);
484
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SQL_STMT, 1, sql_stmt);
492
obpl_mysql_yyerror(&@2, parse_ctx, "Syntax Error, Invalid expr to be evaluated\n");
494
} else if (T_OBJ_ACCESS_REF == $2->type_) {
495
ParseNode *cur_node = $2;
496
ParseNode *last_node = NULL;
497
while (NULL != cur_node->children_[1] && T_OBJ_ACCESS_REF == cur_node->children_[1]->type_) {
498
last_node = cur_node;
499
cur_node = cur_node->children_[1];
501
if (OB_UNLIKELY(NULL == cur_node || NULL != cur_node->children_[1] || NULL == cur_node->children_[0])) {
502
obpl_mysql_yyerror(&@2, parse_ctx, "Syntax Error, Invalid ObjAccess string\n");
504
} else if (T_IDENT == cur_node->children_[0]->type_
505
&& 6 == cur_node->children_[0]->str_len_
506
&& 0 == strncasecmp(cur_node->children_[0]->str_value_, "EXTEND", 6)) {
507
if (OB_UNLIKELY(NULL == last_node)) {
508
obpl_mysql_yyerror(&@2, parse_ctx, "Syntax Error, Invalid ObjAccess string\n");
511
last_node->children_[1] = NULL;
512
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_EXTEND, 2, $2, NULL);
514
} else if (T_FUN_SYS == cur_node->children_[0]->type_
515
&& NULL != cur_node->children_[0]->children_[0]
516
&& T_IDENT == cur_node->children_[0]->children_[0]->type_
517
&& 6 == cur_node->children_[0]->children_[0]->str_len_
518
&& 0 == strncasecmp(cur_node->children_[0]->children_[0]->str_value_, "EXTEND", 6)) {
519
if (OB_UNLIKELY(NULL == last_node)) {
520
obpl_mysql_yyerror(&@2, parse_ctx, "Syntax Error, Invalid ObjAccess string\n");
523
last_node->children_[1] = NULL;
524
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_EXTEND, 2, $2, cur_node->children_[0]);
527
ParseNode *do_expr_list = NULL;
528
merge_nodes(do_expr_list, parse_ctx->mem_pool_, T_EXPR_LIST, $2);
529
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_DO, 1, do_expr_list);
532
ParseNode *do_expr_list = NULL;
533
merge_nodes(do_expr_list, parse_ctx->mem_pool_, T_EXPR_LIST, $2);
534
for (int64_t i = 0; i < do_expr_list->num_child_; ++i) {
535
if (T_COLUMN_REF == do_expr_list->children_[i]->type_) {
536
obpl_mysql_yyerror(&@2, parse_ctx, "Syntax Error, DO statement cannot reference to a table\n");
541
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_DO, 1, do_expr_list);
544
| DO sp_proc_stmt_open { $$ = $2; }
545
| DO sp_proc_stmt_fetch { $$ = $2; }
546
| DO sp_proc_stmt_close { $$ = $2; }
550
CALL sp_call_name opt_sp_cparam_list
552
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_CALL_STMT, 2, $2, $3);
556
if (!parse_ctx->is_inner_parse_) {
557
obpl_mysql_yyerror(&@2, parse_ctx, "Syntax Error\n");
562
| CALL PROCEDURE sp_name '(' opt_sp_param_list ')' sp_create_chistics procedure_body
564
if (!parse_ctx->is_inner_parse_) {
565
obpl_mysql_yyerror(&@2, parse_ctx, "Syntax Error\n");
570
| CALL PROCEDURE sp_name '(' opt_sp_param_list ')' procedure_body
572
if (!parse_ctx->is_inner_parse_) {
573
obpl_mysql_yyerror(&@2, parse_ctx, "Syntax Error\n");
578
| CALL FUNCTION sp_name '(' opt_sp_fparam_list ')' RETURNS sp_data_type sp_create_chistics function_body
580
if (!parse_ctx->is_inner_parse_) {
581
obpl_mysql_yyerror(&@2, parse_ctx, "Syntax Error\n");
586
| CALL FUNCTION sp_name '(' opt_sp_fparam_list ')' RETURNS sp_data_type function_body
588
if (!parse_ctx->is_inner_parse_) {
589
obpl_mysql_yyerror(&@2, parse_ctx, "Syntax Error\n");
597
/* Empty */ { $$ = NULL; }
598
| '(' ')' { $$ = NULL; }
601
merge_nodes($$, parse_ctx->mem_pool_, T_SP_CPARAM_LIST, $2);
606
sp_cparams ',' sp_cparam
608
if ($1 == NULL || $3 == NULL) {
611
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_LINK_NODE, 2, $1, $3);
613
| sp_cparam { $$ = $1; }
617
cexpr opt_sp_cparam_with_assign
619
if (NULL == $1 && NULL != $2) {
626
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_CPARAM, 2, $1, $2);
629
copy_node_abs_location($1->stmt_loc_, @1);
633
opt_sp_cparam_with_assign:
634
/*EMPTY*/ { $$ = NULL; }
635
| PARAM_ASSIGN_OPERATOR cexpr
637
if (NULL == $2) YYERROR; $$ = $2;
639
copy_node_abs_location($2->stmt_loc_, @2);
645
//same as expr in sql rule, and terminate when read ';'
646
do_parse_sql_expr_rule($$, parse_ctx, 3, ',', ')', PARAM_ASSIGN_OPERATOR);
653
/*****************************************************************************
657
*****************************************************************************/
661
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_NAME, 2, $1, $3);
665
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_NAME, 2, NULL, $1);
670
ident '.' ident '.' ident
672
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_ACCESS_NAME, 3, $1, $3, $5);
676
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_ACCESS_NAME, 3, NULL, $1, $3);
680
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_ACCESS_NAME, 3, NULL, NULL, $1);
688
$$->pl_str_off_ = @1.first_column;
692
get_non_reserved_node($$, parse_ctx->mem_pool_, @1.first_column, @1.last_column);
693
$$->pl_str_off_ = @1.first_column;
700
| BEGIN_KEY %prec LOWER_PARENS
702
| BODY %prec LOWER_PARENS
718
| END_KEY %prec LOWER_PARENS
747
/*****************************************************************************
749
* CREATE PACKAGE grammar
751
*****************************************************************************/
753
CREATE opt_replace package_block
755
const char *stmt_str = parse_ctx->orig_stmt_str_ + @3.first_column;
756
int32_t str_len = @3.last_column - @3.first_column + 1;
757
$3->str_value_ = parse_strndup(stmt_str, str_len, parse_ctx->mem_pool_);
758
check_ptr($3->str_value_);
759
$3->str_len_ = str_len;
760
$3->pl_str_off_ = @3.first_column;
761
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_PACKAGE_CREATE, 1, $3);
762
$$->int32_values_[0] = $2;
763
$$->int32_values_[1] = 0;
768
PACKAGE sp_name opt_proc_clause opt_package_stmts END_KEY opt_tail_package_name
770
ParseNode *pkg_decl_stmts = NULL;
771
merge_nodes(pkg_decl_stmts, parse_ctx->mem_pool_, T_PACKAGE_STMTS, $4);
772
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_PACKAGE_BLOCK, 4, $2, $3, pkg_decl_stmts, $6);
773
if (parse_ctx->is_inner_parse_) {
774
const char *stmt_str = parse_ctx->orig_stmt_str_ + @4.first_column;
775
int32_t str_len = @6.last_column - @4.first_column + 1;
776
$$->str_value_ = parse_strndup(stmt_str, str_len, parse_ctx->mem_pool_);
777
check_ptr($$->str_value_);
778
$$->str_len_ = str_len;
779
$$->pl_str_off_ = @4.first_column;
787
malloc_terminal_node($$, parse_ctx->mem_pool_, T_SP_INVOKE);
788
$$->value_ = SP_CURRENT_USER;
792
malloc_terminal_node($$, parse_ctx->mem_pool_, T_SP_INVOKE);
793
$$->value_ = SP_DEFINER;
798
invoke_right { $$ = $1; }
802
proc_clause_list proc_clause
804
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_LINK_NODE, 2, $1, $2);
806
| proc_clause { $$ = $1; }
810
/*EMPTY*/ { $$ = NULL; }
813
merge_nodes($$, parse_ctx->mem_pool_, T_SP_CLAUSE_LIST, $1);
818
/*EMPTY*/ { $$ = 0; }
819
| OR REPLACE { $$ = 1; }
823
/*Empty*/ { $$ = NULL; }
826
merge_nodes($$, parse_ctx->mem_pool_, T_PACKAGE_STMTS, $1);
831
package_stmts package_stmt ';'
833
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_LINK_NODE, 2, $1, $2);
835
| package_stmt ';' { $$ = $1; }
839
| func_decl { $$ = $1; }
840
| proc_decl { $$ = $1; }
844
FUNCTION ident '(' opt_sp_param_list ')' RETURN sp_data_type
846
const char *stmt_str = parse_ctx->stmt_str_ + @1.first_column;
847
int32_t str_len = @7.last_column - @1.first_column + 1;
848
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SUB_FUNC_DECL, 5, $2, $4, $7, NULL, NULL);
850
$$->str_value_ = parse_strndup(stmt_str, str_len, parse_ctx->mem_pool_);
851
check_ptr($$->str_value_);
852
$$->str_len_ = str_len;
857
PROCEDURE ident '(' opt_sp_param_list ')'
859
const char *stmt_str = parse_ctx->stmt_str_ + @1.first_column;
860
int32_t str_len = @5.last_column - @1.first_column + 1;
861
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SUB_PROC_DECL, 3, $2, $4, NULL);
863
$$->str_value_ = parse_strndup(stmt_str, str_len, parse_ctx->mem_pool_);
864
check_ptr($$->str_value_);
865
$$->str_len_ = str_len;
869
opt_tail_package_name:
870
/*EMPTY*/ { $$ = NULL; }
874
/*****************************************************************************
876
* CREATE PACKAGE BODY grammar
878
*****************************************************************************/
879
create_package_body_stmt:
880
CREATE opt_replace package_body_block
883
const char *stmt_str = parse_ctx->orig_stmt_str_ + @3.first_column;
884
int32_t str_len = @3.last_column - @3.first_column + 1;
885
$3->str_value_ = parse_strndup(stmt_str, str_len, parse_ctx->mem_pool_);
886
check_ptr($3->str_value_);
887
$3->str_len_ = str_len;
888
$3->pl_str_off_ = @3.first_column;
889
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_PACKAGE_CREATE_BODY, 1, $3);
890
$$->int32_values_[0] = $2;
891
$$->int32_values_[1] = 0;
897
PACKAGE BODY sp_name decl_stmt_ext_list sp_proc_stmts END_KEY opt_tail_package_name %prec PARENS
899
ParseNode *proc_stmts = NULL;
900
ParseNode *decl_ext_list = NULL;
901
merge_nodes(decl_ext_list, parse_ctx->mem_pool_, T_PACKAGE_BODY_STMTS, $4);
902
merge_nodes(proc_stmts, parse_ctx->mem_pool_, T_SP_PROC_STMT_LIST, $5);
903
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_PACKAGE_BODY_BLOCK, 4, $3, decl_ext_list, proc_stmts, $7);
904
if (parse_ctx->is_inner_parse_) {
905
const char *stmt_str = parse_ctx->orig_stmt_str_ + @4.first_column;
906
int32_t str_len = @7.last_column - @4.first_column + 1;
907
$$->str_value_ = parse_strndup(stmt_str, str_len, parse_ctx->mem_pool_);
908
check_ptr($$->str_value_);
909
$$->str_len_ = str_len;
910
$$->pl_str_off_ = @4.first_column;
913
| PACKAGE BODY sp_name sp_proc_stmts END_KEY opt_tail_package_name %prec PARENS
915
ParseNode *proc_stmts = NULL;
916
ParseNode *decl_ext_list = NULL;
917
merge_nodes(proc_stmts, parse_ctx->mem_pool_, T_SP_PROC_STMT_LIST, $4);
918
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_PACKAGE_BODY_BLOCK, 4, $3, decl_ext_list, proc_stmts, $6);
919
if (parse_ctx->is_inner_parse_) {
920
const char *stmt_str = parse_ctx->orig_stmt_str_ + @4.first_column;
921
int32_t str_len = @6.last_column - @4.first_column + 1;
922
$$->str_value_ = parse_strndup(stmt_str, str_len, parse_ctx->mem_pool_);
923
check_ptr($$->str_value_);
924
$$->str_len_ = str_len;
925
$$->pl_str_off_ = @4.first_column;
928
| PACKAGE BODY sp_name decl_stmt_ext_list END_KEY opt_tail_package_name %prec PARENS
930
ParseNode *proc_stmts = NULL;
931
ParseNode *decl_ext_list = NULL;
932
merge_nodes(decl_ext_list, parse_ctx->mem_pool_, T_PACKAGE_BODY_STMTS, $4);
933
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_PACKAGE_BODY_BLOCK, 4, $3, decl_ext_list, proc_stmts, $6);
934
if (parse_ctx->is_inner_parse_) {
935
const char *stmt_str = parse_ctx->orig_stmt_str_ + @4.first_column;
936
int32_t str_len = @6.last_column - @4.first_column + 1;
937
$$->str_value_ = parse_strndup(stmt_str, str_len, parse_ctx->mem_pool_);
938
check_ptr($$->str_value_);
939
$$->str_len_ = str_len;
942
| PACKAGE BODY sp_name END_KEY opt_tail_package_name %prec PARENS
944
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_PACKAGE_BODY_BLOCK, 4, $3, NULL, NULL, $5);
945
if (parse_ctx->is_inner_parse_) {
946
const char *stmt_str = parse_ctx->orig_stmt_str_ + @4.first_column;
947
int32_t str_len = @5.last_column - @4.first_column + 1;
948
$$->str_value_ = parse_strndup(stmt_str, str_len, parse_ctx->mem_pool_);
949
check_ptr($$->str_value_);
950
$$->str_len_ = str_len;
951
$$->pl_str_off_ = @4.first_column;
956
/*****************************************************************************
958
* DROP PACKAGE grammar
960
*****************************************************************************/
964
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_PACKAGE_DROP, 1, $3);
967
| DROP PACKAGE BODY sp_name
969
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_PACKAGE_DROP, 1, $4);
975
PRAGMA INTERFACE '(' C ',' ident ')'
977
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_PRAGMA_INTERFACE, 1, $6);
982
decl_stmt_ext ';' { $$ = $1; }
983
| decl_stmt_ext_list decl_stmt_ext ';'
985
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_LINK_NODE, 2, $1, $2);
991
| func_decl { $$ = $1; }
992
| proc_decl { $$ = $1; }
993
| interface_pragma { $$ = $1; }
994
| func_decl /*is_or_as*/ function_body
997
const char *stmt_str = parse_ctx->stmt_str_ + @1.first_column;
998
int32_t str_len = @2.last_column - @1.first_column + 1;
999
$2->str_value_ = parse_strndup(stmt_str, str_len, parse_ctx->mem_pool_);
1000
check_ptr($2->str_value_);
1001
$2->str_len_ = str_len;
1002
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SUB_FUNC_DEF, 2, $1, $2);
1004
| proc_decl /*is_or_as*/ procedure_body
1007
const char *stmt_str = parse_ctx->stmt_str_ + @1.first_column;
1008
int32_t str_len = @2.last_column - @1.first_column + 1;
1009
$2->str_value_ = parse_strndup(stmt_str, str_len, parse_ctx->mem_pool_);
1010
check_ptr($2->str_value_);
1011
$2->str_len_ = str_len;
1012
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SUB_PROC_DEF, 2, $1, $2);
1016
/*****************************************************************************
1018
* CREATE TRIGGER grammar
1020
*****************************************************************************/
1022
CREATE opt_sp_definer plsql_trigger_source
1025
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_TG_CREATE, 2, $2, $3);
1026
$$->int32_values_[0] = 0; // or_replace = false
1027
$$->int32_values_[1] = 0; // editionable = false
1031
plsql_trigger_source:
1032
TRIGGER sp_name trigger_definition
1035
const char *stmt_str = parse_ctx->stmt_str_ + @1.first_column;
1036
int32_t str_len = @3.last_column - @1.first_column + 1;
1037
$3->str_value_ = parse_strndup(stmt_str, str_len, parse_ctx->mem_pool_);
1038
check_ptr($3->str_value_);
1039
$3->str_len_ = str_len;
1040
$3->pl_str_off_ = @1.first_column;
1041
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_TG_SOURCE, 2, $2, $3);
1046
trigger_time trigger_event ON sp_name FOR EACH ROW opt_trigger_order trigger_body
1048
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_TG_SIMPLE_DML, 4, $2, $4, $8, $9);
1049
$$->int16_values_[0] = $1;
1053
BEFORE { $$ = T_BEFORE; }
1054
| AFTER { $$ = T_AFTER; }
1058
INSERT { malloc_terminal_node($$, parse_ctx->mem_pool_, T_INSERT); }
1059
| DELETE { malloc_terminal_node($$, parse_ctx->mem_pool_, T_DELETE); }
1060
| UPDATE { malloc_terminal_node($$, parse_ctx->mem_pool_, T_UPDATE); }
1064
/*EMPTY*/ { $$ = NULL; }
1067
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_TG_ORDER, 1, $2);
1068
$$->value_ = 1; // FOLLOWS
1072
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_TG_ORDER, 1, $2);
1073
$$->value_ = 2; // PRECEDES
1080
const char *body_str = parse_ctx->stmt_str_ + @1.first_column;
1081
int32_t body_len = @1.last_column - @1.first_column + 1 + 2;
1082
char *dup_body = NULL;
1083
if (OB_LIKELY(NULL != (dup_body = (char *)parse_malloc(body_len + 1, parse_ctx->mem_pool_)))) {
1084
memmove(dup_body, body_str, body_len - 2);
1085
dup_body[body_len - 2] = ';';
1086
dup_body[body_len - 1] = '\n';
1087
dup_body[body_len] = '\0';
1089
check_ptr(dup_body);
1090
$$->str_value_ = dup_body;
1091
$$->str_len_ = body_len;
1092
$$->pl_str_off_ = @1.first_column;
1096
/*****************************************************************************
1098
* DROP TRIGGER grammar
1100
*****************************************************************************/
1102
DROP TRIGGER opt_if_exists sp_name
1104
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_TG_DROP, 1, $4);
1109
/*****************************************************************************
1111
* CREATE PROCEDURE grammar
1113
*****************************************************************************/
1114
create_procedure_stmt:
1115
CREATE opt_sp_definer PROCEDURE sp_name '(' opt_sp_param_list ')' sp_create_chistics procedure_body
1118
ParseNode *sp_clause_node = NULL;
1119
merge_nodes(sp_clause_node, parse_ctx->mem_pool_, T_SP_CLAUSE_LIST, $8);
1120
const char *stmt_str = parse_ctx->stmt_str_ + @3.first_column;
1121
int32_t str_len = @9.last_column - @3.first_column + 1;
1122
$9->str_value_ = parse_strndup(stmt_str, str_len, parse_ctx->mem_pool_);
1123
check_ptr($9->str_value_);
1124
$9->str_len_ = str_len;
1125
$9->raw_text_ = $9->str_value_ + @9.first_column - @3.first_column;
1126
$9->text_len_ = str_len - (@9.first_column - @3.first_column);
1128
const char *param_str = parse_ctx->stmt_str_ + @5.first_column + 1;
1129
int32_t param_len = @7.last_column - @5.last_column - 1;
1130
$6->str_value_ = parse_strndup(param_str, param_len, parse_ctx->mem_pool_);
1131
check_ptr($6->str_value_);
1132
$6->str_len_ = param_len;
1134
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_CREATE, 5, $2, $4, $6, sp_clause_node, $9);
1136
| CREATE opt_sp_definer PROCEDURE sp_name '(' opt_sp_param_list ')' procedure_body
1139
const char *stmt_str = parse_ctx->stmt_str_ + @3.first_column;
1140
int32_t str_len = @8.last_column - @3.first_column + 1;
1141
$8->str_value_ = parse_strndup(stmt_str, str_len, parse_ctx->mem_pool_);
1142
check_ptr($8->str_value_);
1143
$8->str_len_ = str_len;
1144
$8->raw_text_ = $8->str_value_ + @8.first_column - @3.first_column;
1145
$8->text_len_ = str_len - (@8.first_column - @3.first_column);
1147
const char *param_str = parse_ctx->stmt_str_ + @5.first_column + 1;
1148
int32_t param_len = @7.last_column - @5.last_column - 1;
1149
$6->str_value_ = parse_strndup(param_str, param_len, parse_ctx->mem_pool_);
1150
check_ptr($6->str_value_);
1151
$6->str_len_ = param_len;
1153
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_CREATE, 5, $2, $4, $6, NULL, $8);
1157
create_function_stmt:
1158
CREATE opt_sp_definer FUNCTION sp_name '(' opt_sp_fparam_list ')' RETURNS sp_data_type sp_create_chistics function_body
1161
ParseNode *sp_clause_node = NULL;
1162
merge_nodes(sp_clause_node, parse_ctx->mem_pool_, T_SP_CLAUSE_LIST, $10);
1163
const char *stmt_str = parse_ctx->stmt_str_ + @3.first_column;
1164
int32_t str_len = @11.last_column - @3.first_column + 1;
1165
$11->str_value_ = parse_strndup(stmt_str, str_len, parse_ctx->mem_pool_);
1166
check_ptr($11->str_value_);
1167
$11->str_len_ = str_len;
1168
$11->raw_text_ = $11->str_value_ + @11.first_column - @3.first_column;
1169
$11->text_len_ = str_len - (@11.first_column - @3.first_column);
1171
const char *param_str = parse_ctx->stmt_str_ + @5.first_column + 1;
1172
int32_t param_len = @7.last_column - @5.last_column - 1;
1173
$6->str_value_ = parse_strndup(param_str, param_len, parse_ctx->mem_pool_);
1174
check_ptr($6->str_value_);
1175
$6->str_len_ = param_len;
1177
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SF_CREATE, 6, $2, $4, $6, $9, sp_clause_node, $11);
1179
| CREATE opt_sp_definer FUNCTION sp_name '(' opt_sp_fparam_list ')' RETURNS sp_data_type function_body
1182
const char *stmt_str = parse_ctx->stmt_str_ + @3.first_column;
1183
int32_t str_len = @10.last_column - @3.first_column + 1;
1184
$10->str_value_ = parse_strndup(stmt_str, str_len, parse_ctx->mem_pool_);
1185
check_ptr($10->str_value_);
1186
$10->str_len_ = str_len;
1187
$10->raw_text_ = $10->str_value_ + @10.first_column - @3.first_column;
1188
$10->text_len_ = str_len - (@10.first_column - @3.first_column);
1190
const char *param_str = parse_ctx->stmt_str_ + @5.first_column + 1;
1191
int32_t param_len = @7.last_column - @5.last_column - 1;
1192
$6->str_value_ = parse_strndup(param_str, param_len, parse_ctx->mem_pool_);
1193
check_ptr($6->str_value_);
1194
$6->str_len_ = param_len;
1196
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SF_CREATE, 6, $2, $4, $6, $9, NULL, $10);
1201
/* empty */ { $$ = NULL; }
1202
| DEFINER '=' user opt_host_name
1204
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_USER_WITH_HOST_NAME, 2, $3, $4);
1206
| DEFINER '=' CURRENT_USER opt_parentheses
1208
ParseNode *user_node = NULL;
1209
malloc_terminal_node(user_node, parse_ctx->mem_pool_, T_IDENT);
1210
user_node->str_value_ = "CURRENT_USER";
1211
user_node->str_len_ = strlen("CURRENT_USER");
1212
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_USER_WITH_HOST_NAME, 2, user_node, NULL);
1239
/* empty */ { $$ = NULL; }
1240
| '(' ')' { $$ = NULL; }
1242
/*stored procedure param list*/
1244
/* empty */ { $$ = NULL; }
1247
merge_nodes($$, parse_ctx->mem_pool_, T_SP_PARAM_LIST, $1);
1252
sp_param_list ',' sp_param
1254
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_LINK_NODE, 2, $1, $3);
1256
| sp_param { $$ = $1; }
1260
opt_sp_inout ident param_type opt_param_default
1262
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_PARAM, 3, $2, $3, $4);
1267
/*stored function param list*/
1269
/* empty */ { $$ = NULL; }
1272
merge_nodes($$, parse_ctx->mem_pool_, T_SP_PARAM_LIST, $1);
1277
sp_fparam_list ',' sp_fparam
1279
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_LINK_NODE, 2, $1, $3);
1281
| sp_fparam { $$ = $1; }
1287
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_PARAM, 2, $1, $2);
1288
$$->value_ = MODE_IN;
1293
/* Empty */ { $$ = MODE_IN; }
1294
| IN { $$ = MODE_IN; }
1295
| OUT { $$ = MODE_OUT; }
1296
| INOUT { $$ = MODE_INOUT; }
1300
sp_data_type { $$ = $1; }
1305
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_COLUMN_REF, 3, NULL, NULL, $1);
1309
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_COLUMN_REF, 3, NULL, $1, $3);
1311
| '.' ident '.' ident
1313
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_COLUMN_REF, 3, NULL, $2, $4);
1315
| ident '.' ident '.' ident
1317
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_COLUMN_REF, 3, $1, $3, $5);
1322
sp_create_chistic { $$ = $1; }
1323
| sp_create_chistics sp_create_chistic
1325
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_LINK_NODE, 2, $1, $2);
1330
sp_chistic { $$ = $1; }
1333
malloc_terminal_node($$, parse_ctx->mem_pool_, T_SP_DETERMINISTIC);
1335
| NOT DETERMINISTIC { }
1341
malloc_terminal_node($$, parse_ctx->mem_pool_, T_COMMENT);
1342
$$->str_value_ = $2->str_value_;
1343
$$->str_len_ = $2->str_len_;
1345
| LANGUAGE SQL { /* Just parse it, we only have one language for now. */ $$ = NULL; }
1348
malloc_terminal_node($$, parse_ctx->mem_pool_, T_SP_DATA_ACCESS);
1349
$$->value_ = SP_NO_SQL;
1353
malloc_terminal_node($$, parse_ctx->mem_pool_, T_SP_DATA_ACCESS);
1354
$$->value_ = SP_CONTAINS_SQL;
1358
malloc_terminal_node($$, parse_ctx->mem_pool_, T_SP_DATA_ACCESS);
1359
$$->value_ = SP_READS_SQL_DATA;
1363
malloc_terminal_node($$, parse_ctx->mem_pool_, T_SP_DATA_ACCESS);
1364
$$->value_ = SP_MODIFIES_SQL_DATA;
1366
| SQL SECURITY DEFINER
1368
malloc_terminal_node($$, parse_ctx->mem_pool_, T_SP_INVOKE);
1369
$$->value_ = SP_DEFINER;
1371
| SQL SECURITY INVOKER
1373
malloc_terminal_node($$, parse_ctx->mem_pool_, T_SP_INVOKE);
1374
$$->value_ = SP_INVOKER;
1379
sp_proc_stmt { $$ = $1; }
1383
sp_proc_independent_statement { $$ = $1; }
1386
/*****************************************************************************
1388
* ALTER PROCEDURE grammar
1390
*****************************************************************************/
1391
alter_procedure_stmt:
1392
ALTER PROCEDURE sp_name opt_sp_alter_chistics
1394
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_ALTER, 2, $3, $4);
1399
ALTER FUNCTION sp_name opt_sp_alter_chistics
1401
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SF_ALTER, 2, $3, $4);
1405
opt_sp_alter_chistics:
1406
/* empty */ { $$ = NULL; }
1409
merge_nodes($$, parse_ctx->mem_pool_, T_SP_CLAUSE_LIST, $1);
1414
sp_chistic { $$ = $1; }
1415
| sp_alter_chistics sp_chistic
1417
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_LINK_NODE, 2, $1, $2);
1421
sp_proc_outer_statement
1424
copy_node_abs_location($$->stmt_loc_, @1);
1426
| sp_proc_inner_statement
1429
copy_node_abs_location($$->stmt_loc_, @1);
1433
sp_proc_outer_statement:
1437
const char *stmt_str = parse_ctx->stmt_str_ + @1.first_column;
1438
int32_t str_len = @1.last_column - @1.first_column + 1;
1439
$1->str_value_ = parse_strndup(stmt_str, str_len, parse_ctx->mem_pool_);
1440
check_ptr($1->str_value_);
1441
$1->str_len_ = str_len;
1445
sp_proc_inner_statement:
1446
sp_proc_independent_statement
1449
copy_node_abs_location($$->stmt_loc_, @1);
1451
| sp_proc_stmt_iterate
1454
copy_node_abs_location($$->stmt_loc_, @1);
1456
| sp_proc_stmt_leave
1459
copy_node_abs_location($$->stmt_loc_, @1);
1464
copy_node_abs_location($$->stmt_loc_, @1);
1466
| sp_proc_stmt_fetch
1469
copy_node_abs_location($$->stmt_loc_, @1);
1471
| sp_proc_stmt_close
1474
copy_node_abs_location($$->stmt_loc_, @1);
1478
sp_proc_independent_statement: //可以独立存在(不依赖于其他语句)的内部语句类型
1487
| sp_unlabeled_block
1495
| sp_unlabeled_control
1499
| sp_labeled_control
1503
| sp_proc_stmt_return
1510
IF sp_if END_KEY IF { $$ = $2; }
1514
expr THEN sp_proc_stmts sp_elseifs
1516
ParseNode *proc_stmts = NULL;
1517
merge_nodes(proc_stmts, parse_ctx->mem_pool_, T_SP_PROC_STMT_LIST, $3);
1518
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_IF, 3, $1, proc_stmts, $4);
1520
| expr THEN sp_proc_stmts %prec PARENS
1522
ParseNode *proc_stmts = NULL;
1523
merge_nodes(proc_stmts, parse_ctx->mem_pool_, T_SP_PROC_STMT_LIST, $3);
1524
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_IF, 3, $1, proc_stmts, NULL);
1529
CASE expr sp_when_list sp_elseifs END_KEY CASE
1531
ParseNode *when_list = NULL;
1532
merge_nodes(when_list, parse_ctx->mem_pool_, T_WHEN_LIST, $3);
1533
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_CASE, 3, $2, when_list, $4);
1535
| CASE expr sp_when_list END_KEY CASE
1537
ParseNode *when_list = NULL;
1538
merge_nodes(when_list, parse_ctx->mem_pool_, T_WHEN_LIST, $3);
1539
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_CASE, 3, $2, when_list, NULL);
1544
sp_when { $$ = $1; }
1545
| sp_when_list sp_when
1547
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_LINK_NODE, 2, $1, $2);
1552
WHEN expr THEN sp_proc_stmts %prec PARENS
1554
ParseNode *proc_stmts = NULL;
1555
merge_nodes(proc_stmts, parse_ctx->mem_pool_, T_SP_PROC_STMT_LIST, $4);
1556
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_WHEN, 2, $2, proc_stmts);
1563
// ParseNode *proc_stmts = NULL;
1564
// merge_nodes(proc_stmts, parse_ctx->mem_pool_, T_SP_PROC_STMT_LIST, $3);
1565
// malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_ELSE, 1, proc_stmts);
1569
ParseNode *proc_stmts = NULL;
1570
merge_nodes(proc_stmts, parse_ctx->mem_pool_, T_SP_PROC_STMT_LIST, $2);
1571
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_ELSE, 1, proc_stmts);
1573
| ELSE sp_proc_stmts
1575
ParseNode *proc_stmts = NULL;
1576
merge_nodes(proc_stmts, parse_ctx->mem_pool_, T_SP_PROC_STMT_LIST, $2);
1577
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_ELSE, 1, proc_stmts);
1582
sp_block_content { $$ = $1; }
1588
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_BLOCK_CONTENT, 2, NULL, NULL);
1590
| BEGIN_KEY sp_decls END_KEY
1592
ParseNode *decl_list = NULL;
1593
merge_nodes(decl_list, parse_ctx->mem_pool_, T_SP_DECL_LIST, $2);
1594
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_BLOCK_CONTENT, 2, decl_list, NULL);
1596
| BEGIN_KEY sp_proc_stmts END_KEY
1598
ParseNode *proc_stmts = NULL;
1599
merge_nodes(proc_stmts, parse_ctx->mem_pool_, T_SP_PROC_STMT_LIST, $2);
1600
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_BLOCK_CONTENT, 2, NULL, proc_stmts);
1602
| BEGIN_KEY sp_decls sp_proc_stmts END_KEY
1604
ParseNode *decl_list = NULL;
1605
ParseNode *proc_stmts = NULL;
1606
merge_nodes(decl_list, parse_ctx->mem_pool_, T_SP_DECL_LIST, $2);
1607
merge_nodes(proc_stmts, parse_ctx->mem_pool_, T_SP_PROC_STMT_LIST, $3);
1608
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_BLOCK_CONTENT, 2, decl_list, proc_stmts);
1613
label_ident ':' sp_block_content opt_sp_label
1615
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_LABELED_BLOCK, 3, $1, $3, $4);
1624
/* Empty */ { $$ = NULL }
1632
sp_proc_stmt ';' { $$ = $1; }
1633
| sp_proc_stmts sp_proc_stmt ';'
1635
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_LINK_NODE, 2, $1, $2);
1644
| opt_sp_decls sp_decl ';'
1646
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_LINK_NODE, 2, $1, $2);
1652
/*Empty*/ { $$ = NULL; }
1653
| opt_sp_decls sp_decl ';'
1655
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_LINK_NODE, 2, $1, $2);
1660
DECLARE sp_decl_idents sp_data_type opt_sp_decl_default
1662
ParseNode *decl_idents = NULL;
1663
merge_nodes(decl_idents, parse_ctx->mem_pool_, T_SP_DECL_IDENT_LIST, $2);
1664
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_DECL, 3, decl_idents, $3, $4);
1665
copy_node_abs_location($$->stmt_loc_, @1);
1667
| DECLARE ident CONDITION FOR sp_cond
1669
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_DECL_COND, 2, $2, $5);
1670
copy_node_abs_location($$->stmt_loc_, @1);
1672
| DECLARE sp_handler_type HANDLER FOR sp_hcond_list sp_proc_stmt
1674
ParseNode *hcond_list = NULL;
1675
ParseNode *proc_stmts = NULL;
1676
malloc_non_terminal_node(proc_stmts, parse_ctx->mem_pool_, T_SP_PROC_STMT_LIST, 1, $6);
1677
merge_nodes(hcond_list, parse_ctx->mem_pool_, T_SP_HCOND_LIST, $5);
1678
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_DECL_HANDLER, 2, hcond_list, proc_stmts);
1680
copy_node_abs_location($$->stmt_loc_, @1);
1682
| DECLARE ident CURSOR FOR sql_stmt
1684
if ($5->children_[0]->type_ != T_SELECT) {
1685
obpl_mysql_yyerror(&@5, parse_ctx, "Syntax Error\n");
1688
const char *stmt_str = parse_ctx->stmt_str_ + @5.first_column;
1689
int32_t str_len = @5.last_column - @5.first_column + 1;
1690
$5->str_value_ = parse_strndup(stmt_str, str_len, parse_ctx->mem_pool_);
1691
check_ptr($5->str_value_);
1692
$5->str_len_ = str_len;
1693
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_DECL_CURSOR, 4, $2, NULL, NULL, $5); //4参数和Oracle模式保持一致
1694
copy_node_abs_location($$->stmt_loc_, @1);
1699
EXIT { $$ = SP_HANDLER_TYPE_EXIT; }
1700
| CONTINUE { $$ = SP_HANDLER_TYPE_CONTINUE; }
1704
sp_hcond { $$ = $1; }
1705
| sp_hcond_list ',' sp_hcond
1707
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_LINK_NODE, 2, $1, $3);
1712
sp_cond { $$ = $1; }
1713
| ident { $$ = $1; }
1714
| SQLWARNING { malloc_terminal_node($$, parse_ctx->mem_pool_, T_SQL_WARNING); }
1715
| NOT FOUND { malloc_terminal_node($$, parse_ctx->mem_pool_, T_SQL_NOT_FOUND); }
1716
| SQLEXCEPTION { malloc_terminal_node($$, parse_ctx->mem_pool_, T_SQL_EXCEPTION); }
1722
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_CONDITION, 1, $1);
1726
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_CONDITION, 1, $1);
1731
SQLSTATE opt_value STRING
1734
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SQL_STATE, 1, $3);
1741
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_PROC_OPEN, 3, $2, NULL, NULL, NULL); //4参数和Oracle模式保持一致
1748
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_PROC_CLOSE, 1, $2);
1753
FETCH ident into_clause
1755
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_PROC_FETCH, 2, $2, $3);
1757
| FETCH FROM ident into_clause
1759
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_PROC_FETCH, 2, $3, $4);
1761
| FETCH NEXT FROM ident into_clause
1763
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_PROC_FETCH, 2, $4, $5);
1770
ParseNode *vars_list = NULL;
1771
merge_nodes(vars_list, parse_ctx->mem_pool_, T_SP_INTO_LIST, $2);
1772
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_INTO_VARIABLES, 1, vars_list);
1777
/*Empty*/ { $$ = NULL; }
1778
| VALUE { $$ = NULL; }
1782
| sp_decl_idents ',' ident
1784
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_LINK_NODE, 2, $1, $3);
1789
scalar_data_type { $$ = $1; }
1793
/*Empty*/ { $$ = NULL; }
1796
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_DECL_DEFAULT, 1, $2);
1801
/*Empty*/ { $$ = NULL; }
1802
| DEFAULT default_expr
1807
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_DECL_DEFAULT, 1, $2);
1809
const char *expr_str = parse_ctx->stmt_str_ + @2.first_column;
1810
int32_t expr_str_len = @2.last_column - @2.first_column + 1;
1811
$$->str_value_ = parse_strndup(expr_str, expr_str_len, parse_ctx->mem_pool_);
1812
check_ptr($$->str_value_);
1813
$$->str_len_ = expr_str_len;
1815
copy_node_abs_location($2->stmt_loc_, @2);
1822
do_parse_sql_expr_rule($$, parse_ctx, 3, ',', ')', ';');
1828
| expr_list ',' expr
1830
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_LINK_NODE, 2, $1, $3);
1836
//same as expr in sql rule, and terminate when read ';'
1837
do_parse_sql_expr_rule($$, parse_ctx, 9, INTO, USING, WHEN, THEN, ';', DO, LIMIT, ',', END_KEY);
1838
obpl_mysql_wrap_get_user_var_into_subquery(parse_ctx, $$);
1842
sp_unlabeled_control:
1843
LOOP sp_proc_stmts END_KEY LOOP
1845
ParseNode *proc_stmts = NULL;
1846
merge_nodes(proc_stmts, parse_ctx->mem_pool_, T_SP_PROC_STMT_LIST, $2);
1847
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_LOOP, 1, proc_stmts);
1849
| WHILE expr DO sp_proc_stmts END_KEY WHILE
1851
ParseNode *proc_stmts = NULL;
1852
merge_nodes(proc_stmts, parse_ctx->mem_pool_, T_SP_PROC_STMT_LIST, $4);
1853
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_WHILE, 2, $2, proc_stmts);
1855
| REPEAT sp_proc_stmts UNTIL expr END_KEY REPEAT %prec PARENS
1857
ParseNode *proc_stmts = NULL;
1858
merge_nodes(proc_stmts, parse_ctx->mem_pool_, T_SP_PROC_STMT_LIST, $2);
1859
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_REPEAT, 2, proc_stmts, $4);
1864
label_ident ':' sp_unlabeled_control opt_sp_label
1866
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_LABELED_CONTROL, 3, $1, $3, $4);
1873
if (NULL == $2) YYERROR;
1874
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_RETURN, 1, $2);
1878
sp_proc_stmt_iterate:
1881
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_ITERATE, 2, $2, NULL);
1888
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_LEAVE, 2, $2, NULL);
1893
DROP PROCEDURE opt_if_exists sp_name
1895
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_DROP, 1, $4);
1901
DROP FUNCTION opt_if_exists sp_name
1903
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SF_DROP, 1, $4);
1909
/*Empty*/ { $$ = 0; }
1910
| IF EXISTS { $$ = 1; }
1914
int_type_i opt_int_length_i opt_unsigned_i opt_zerofill_i
1916
malloc_terminal_node($$, parse_ctx->mem_pool_, ($3 || $4) ? $1 + (T_UTINYINT - T_TINYINT) : $1);
1917
$$->int16_values_[0] = $2;
1918
$$->int16_values_[2] = $4; /* 2 is the same index as float or number. */
1920
| float_type_i opt_float_precision opt_unsigned_i opt_zerofill_i
1922
if (T_FLOAT != $1 && NULL != $2 && -1 == $2->int16_values_[1]) {
1923
obpl_mysql_yyerror(&@2, parse_ctx, "double type not support double(M) syntax\n");
1926
malloc_terminal_node($$, parse_ctx->mem_pool_, ($3 || $4) ? $1 + (T_UFLOAT - T_FLOAT) : $1);
1928
$$->int16_values_[0] = $2->int16_values_[0];
1929
$$->int16_values_[1] = $2->int16_values_[1];
1931
/* malloc_terminal_node() has set memory to 0 filled, so there is no else. */
1932
$$->int16_values_[2] = $4;
1934
| NUMBER opt_number_precision opt_unsigned_i opt_zerofill_i
1936
malloc_terminal_node($$, parse_ctx->mem_pool_, ($3 || $4) ? T_UNUMBER : T_NUMBER);
1938
$$->int16_values_[0] = $2->int16_values_[0];
1939
$$->int16_values_[1] = $2->int16_values_[1];
1941
/* malloc_terminal_node() has set memory to 0 filled, so there is no else. */
1942
$$->int16_values_[2] = $4;
1944
| datetime_type_i opt_datetime_fsp_i
1946
malloc_terminal_node($$, parse_ctx->mem_pool_, $1);
1947
$$->int16_values_[1] = $2;
1951
malloc_terminal_node($$, parse_ctx->mem_pool_, $1);
1953
| CHARACTER opt_string_length_i opt_binary opt_charset opt_collation
1955
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_CHAR, 3, $4, $5, $3);
1959
$$->int32_values_[0] = $2;
1960
$$->int32_values_[1] = 0; /* is char */
1962
| nchar_type_i opt_string_length_i opt_binary opt_collation
1964
ParseNode *charset_node = NULL;
1965
malloc_terminal_node(charset_node, parse_ctx->mem_pool_, T_CHARSET);
1966
charset_node->str_value_ = parse_strdup("utf8mb4", parse_ctx->mem_pool_, &(charset_node->str_len_));
1967
if (OB_UNLIKELY(NULL == charset_node->str_value_)) {
1968
obpl_mysql_yyerror(NULL, parse_ctx, "memory space for string is not enough\n");
1972
malloc_non_terminal_node($$, parse_ctx->mem_pool_, $1, 3, charset_node, $4, $3);
1973
$$->int32_values_[0] = $2;
1974
$$->int32_values_[1] = 0; /* is char */
1976
/* | TEXT opt_binary opt_charset opt_collation
1979
// malloc_non_terminal_node($$, result->malloc_pool_, T_VARCHAR, 3, $3, $4, $2);
1980
// $$->int32_values_[0] = 256;
1981
// $$->int32_values_[1] = 0; /* is char */
1983
| CHARACTER VARYING string_length_i opt_binary opt_charset opt_collation
1985
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_VARCHAR, 3, $5, $6, $4);
1986
$$->int32_values_[0] = $3;
1987
$$->int32_values_[1] = 0; /* is char */
1989
| VARCHAR string_length_i opt_binary opt_charset opt_collation
1991
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_VARCHAR, 3, $4, $5, $3);
1992
$$->int32_values_[0] = $2;
1993
$$->int32_values_[1] = 0; /* is char */
1995
| nvarchar_type_i opt_string_length_i opt_binary opt_collation
1997
ParseNode *charset_node = NULL;
1998
malloc_terminal_node(charset_node, parse_ctx->mem_pool_, T_CHARSET);
1999
charset_node->str_value_ = parse_strdup("utf8mb4", parse_ctx->mem_pool_, &(charset_node->str_len_));
2000
if (OB_UNLIKELY(NULL == charset_node->str_value_)) {
2001
obpl_mysql_yyerror(NULL, parse_ctx, "memory space for string is not enough\n");
2005
malloc_non_terminal_node($$, parse_ctx->mem_pool_, $1, 3, charset_node, $4, $3);
2006
$$->int32_values_[0] = $2;
2007
$$->int32_values_[1] = 0; /* is char */
2009
| BINARY opt_string_length_i
2011
malloc_terminal_node($$, parse_ctx->mem_pool_, T_CHAR);
2015
$$->int32_values_[0] = $2;
2016
$$->int32_values_[1] = 1; /* is binary */
2018
| VARBINARY string_length_i
2020
malloc_terminal_node($$, parse_ctx->mem_pool_, T_VARCHAR);
2021
$$->int32_values_[0] = $2;
2022
$$->int32_values_[1] = 1; /* is binary */
2024
| STRING /* wrong or unsupported data type */
2026
malloc_terminal_node($$, parse_ctx->mem_pool_, T_INVALID);
2027
$$->str_value_ = $1->str_value_;
2028
$$->str_len_ = $1->str_len_;
2030
| BIT opt_bit_length_i
2032
malloc_terminal_node($$, parse_ctx->mem_pool_, T_BIT);
2033
$$->int16_values_[0] = $2;
2037
malloc_terminal_node($$, parse_ctx->mem_pool_, T_TINYINT);
2038
$$->int16_values_[0] = 1;
2039
$$->int16_values_[2] = 0; // zerofill always false
2043
malloc_terminal_node($$, parse_ctx->mem_pool_, T_TINYINT);
2044
$$->int16_values_[0] = 1;
2045
$$->int16_values_[2] = 0; // zerofill always false
2047
| blob_type_i opt_string_length_i_v2
2049
malloc_terminal_node($$, parse_ctx->mem_pool_, $1);
2050
if ($1 != T_TEXT && $2 != 0) {
2051
obpl_mysql_yyerror(&@2, parse_ctx, "not support to specify the length in parentheses\n");
2054
$$->int32_values_[0] = $2;
2055
$$->int32_values_[1] = 1; /* is binary */
2057
| text_type_i opt_string_length_i_v2 opt_binary opt_charset opt_collation
2059
malloc_non_terminal_node($$, parse_ctx->mem_pool_, $1, 3, $4, $5, $3);
2060
if ($1 != T_TEXT && $2 != 0) {
2061
obpl_mysql_yyerror(&@2, parse_ctx, "not support to specify the length in parentheses\n");
2064
$$->int32_values_[0] = $2;
2065
$$->int32_values_[1] = 0; /* is text */
2067
| ENUM '(' string_list ')' opt_binary opt_charset opt_collation
2069
ParseNode *string_list_node = NULL;
2070
merge_nodes(string_list_node, parse_ctx->mem_pool_, T_STRING_LIST, $3);
2071
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_ENUM, 4, $6, $7, $5, string_list_node);
2072
$$->int32_values_[0] = 0;//not used so far
2073
$$->int32_values_[1] = 0; /* is char */
2075
| SET '(' string_list ')' opt_binary opt_charset opt_collation
2077
ParseNode *string_list_node = NULL;
2078
merge_nodes(string_list_node, parse_ctx->mem_pool_, T_STRING_LIST, $3);
2079
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SET, 4, $6, $7, $5, string_list_node);
2080
$$->int32_values_[0] = 0;//not used so far
2081
$$->int32_values_[1] = 0; /* is char */
2085
if ($1 != NULL && $1->type_ == T_SP_OBJ_ACCESS_REF &&
2086
$1->num_child_ == 2 &&
2087
$1->children_[0] != NULL &&
2088
$1->children_[0]->type_ == T_SP_ACCESS_NAME &&
2089
$1->children_[0]->num_child_ == 3 &&
2090
$1->children_[0]->children_[0] == NULL &&
2091
$1->children_[0]->children_[1] == NULL &&
2092
nodename_equal($1->children_[0]->children_[2], "JSON", 4)) {
2093
malloc_terminal_node($$, parse_ctx->mem_pool_, T_JSON);
2094
$$->int32_values_[0] = 0;
2096
obpl_mysql_yyerror(&@1, parse_ctx, "Syntax Error\n");
2100
| pl_obj_access_ref '%' ROWTYPE
2102
if (parse_ctx->is_for_trigger_ && parse_ctx->is_inner_parse_) {
2103
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_ROWTYPE, 1, $1);
2105
obpl_mysql_yyerror(&@3, parse_ctx, "Syntax Error\n");
2114
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_OBJ_ACCESS_REF, 2, $1, NULL);
2118
TINYINT { $$ = T_TINYINT; }
2119
| SMALLINT { $$ = T_SMALLINT; }
2120
| MEDIUMINT { $$ = T_MEDIUMINT; }
2121
| INTEGER { $$ = T_INT32; }
2122
| BIGINT { $$ = T_INT; }
2126
FLOAT { $$ = T_FLOAT; }
2127
| DOUBLE { $$ = T_DOUBLE; }
2128
| DOUBLE PRECISION { $$ = T_DOUBLE; }
2132
DATETIME { $$ = T_DATETIME; }
2133
| TIMESTAMP { $$ = T_TIMESTAMP; }
2134
| TIME { $$ = T_TIME; }
2138
DATE { $$ = T_DATE; }
2139
| YEAR opt_year_i { $$ = T_YEAR; }
2143
NCHAR { $$ = T_CHAR; }
2144
| NATIONAL CHARACTER { $$ = T_CHAR; }
2148
NVARCHAR { $$ = T_VARCHAR; }
2149
| NCHAR VARCHAR { $$ = T_VARCHAR; }
2150
| NATIONAL VARCHAR { $$ = T_VARCHAR; }
2151
| NATIONAL CHARACTER VARYING { $$ = T_VARCHAR; }
2155
'(' INTNUM ')' { $$ = $2->value_; }
2156
| /*EMPTY*/ { $$ = -1; }
2160
'(' INTNUM ')' { $$ = $2->value_; }
2161
| /*EMPTY*/ { $$ = 1; }
2165
'(' INTNUM ',' INTNUM ')'
2167
malloc_terminal_node($$, parse_ctx->mem_pool_, T_LINK_NODE);
2168
$$->int16_values_[0] = $2->value_;
2169
$$->int16_values_[1] = $4->value_;
2173
malloc_terminal_node($$, parse_ctx->mem_pool_, T_LINK_NODE);
2174
$$->int16_values_[0] = $2->value_;
2175
$$->int16_values_[1] = -1;
2177
| '(' DECIMAL_VAL ')'
2179
malloc_terminal_node($$, parse_ctx->mem_pool_, T_LINK_NODE);
2181
$2->value_ = ob_strntoll($2->str_value_, $2->str_len_, 10, NULL, &err_no);
2182
$$->int16_values_[0] = $2->value_;
2183
$$->int16_values_[1] = -1;
2185
| /*EMPTY*/ { $$ = NULL; }
2188
opt_number_precision:
2189
'(' INTNUM ',' INTNUM ')'
2191
malloc_terminal_node($$, parse_ctx->mem_pool_, T_LINK_NODE);
2192
if($2->value_ > OB_MAX_PARSER_INT16_VALUE) {
2193
$$->int16_values_[0] = OB_MAX_PARSER_INT16_VALUE;
2195
$$->int16_values_[0] = $2->value_;
2197
if($4->value_ > OB_MAX_PARSER_INT16_VALUE) {
2198
$$->int16_values_[1] = OB_MAX_PARSER_INT16_VALUE;
2200
$$->int16_values_[1] = $4->value_;
2206
malloc_terminal_node($$, parse_ctx->mem_pool_, T_LINK_NODE);
2207
if($2->value_ > OB_MAX_PARSER_INT16_VALUE) {
2208
$$->int16_values_[0] = OB_MAX_PARSER_INT16_VALUE;
2210
$$->int16_values_[0] = $2->value_;
2212
$$->int16_values_[1] = 0;
2217
malloc_terminal_node($$, parse_ctx->mem_pool_, T_LINK_NODE);
2218
$$->int16_values_[0] = 10;
2219
$$->int16_values_[1] = 0;
2225
'(' INTNUM ')' { $$ = $2->value_; }
2226
| /*EMPTY*/ { $$ = 0; }
2254
number_literal { $$ = $1; }
2255
| DATE_VALUE { $$ = $1; }
2256
| HEX_STRING_VALUE { $$ = $1; }
2257
| NULLX { $$ = $1; }
2261
TINYTEXT { $$ = T_TINYTEXT; }
2262
| TEXT { $$ = T_TEXT; }
2263
| MEDIUMTEXT { $$ = T_MEDIUMTEXT; }
2264
| LONGTEXT { $$ = T_LONGTEXT; }
2265
| LONG VARCHAR { $$ = T_MEDIUMTEXT; }
2266
| LONG { $$ = T_MEDIUMTEXT; }
2270
TINYBLOB { $$ = T_TINYTEXT; }
2271
| BLOB { $$ = T_TEXT; }
2272
| MEDIUMBLOB { $$ = T_MEDIUMTEXT; }
2273
| LONGBLOB { $$ = T_LONGTEXT; }
2274
| LONG VARBINARY {$$ = T_MEDIUMTEXT; }
2277
opt_string_length_i_v2:
2278
string_length_i { $$ = $1; }
2279
| /*EMPTY*/ { $$ = 0; }
2282
'(' number_literal ')'
2285
// select cast('' as BINARY(-1));
2287
// select cast('' as CHARACTER(-1));
2290
if (T_NUMBER == $2->type_) {
2292
val = strtoll($2->str_value_, NULL, 10);
2293
if (ERANGE == errno) {
2294
$$ = OUT_OF_STR_LEN;// out of str_max_len
2295
} else if (val < 0) {
2296
obpl_mysql_yyerror(&@2, parse_ctx, "length cannot < 0\n");
2298
} else if (val > UINT32_MAX) {
2299
$$ = OUT_OF_STR_LEN;// out of str_max_len
2300
} else if (val > INT32_MAX) {
2301
$$ = DEFAULT_STR_LENGTH;
2305
} else if ($2->value_ < 0) {
2306
obpl_mysql_yyerror(&@2, parse_ctx, "length cannot < 0\n");
2308
} else if ($2->value_ > UINT32_MAX) {
2309
$$ = OUT_OF_STR_LEN;;
2310
} else if ($2->value_ > INT32_MAX) {
2311
$$ = DEFAULT_STR_LENGTH;
2315
// $$ = $2->param_num_;
2324
| string_list ',' text_string
2326
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_LINK_NODE, 2, $1, $3);
2353
UNSIGNED { $$ = 1; }
2354
| SIGNED { $$ = 0; }
2355
| /*EMPTY*/ { $$ = 0; }
2359
ZEROFILL { $$ = 1; }
2360
| /*EMPTY*/ { $$ = 0; }
2366
malloc_terminal_node($$, parse_ctx->mem_pool_, T_BINARY);
2369
| /*EMPTY*/ {$$ = 0; }
2376
$$->type_ = T_VARCHAR;
2390
$$->type_ = T_VARCHAR;
2392
$$->is_hidden_const_ = 1;
2398
$$->is_hidden_const_ = 0;
2402
malloc_terminal_node($$, parse_ctx->mem_pool_, T_VARCHAR);
2403
$$->str_value_ = parse_strdup("binary", parse_ctx->mem_pool_, &($$->str_len_));
2404
if (OB_UNLIKELY(NULL == $$->str_value_)) {
2405
YY_FATAL_ERROR("no more memory to malloc 'binary; string\n");
2408
$$->is_hidden_const_ = 1;
2413
charset_key charset_name
2416
malloc_terminal_node($$, parse_ctx->mem_pool_, T_CHARSET);
2417
$$->str_value_ = $2->str_value_;
2418
$$->str_len_ = $2->str_len_;
2420
| /*EMPTY*/ { $$ = NULL; }
2435
COLLATE collation_name
2437
malloc_terminal_node($$, parse_ctx->mem_pool_, T_COLLATION);
2438
$$->str_value_ = $2->str_value_;
2439
$$->str_len_ = $2->str_len_;
2440
$$->param_num_ = $2->param_num_;
2449
| /*EMPTY*/ { $$ = NULL; }
2453
SIGNAL signal_value opt_set_signal_information
2455
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_SIGNAL, 2, $2, $3);
2460
RESIGNAL opt_signal_value opt_set_signal_information
2462
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_RESIGNAL, 2, $2, $3);
2467
/*Empty*/ { $$ = NULL; }
2468
| signal_value { $$ = $1; }
2473
| sqlstate { $$ = $1; }
2476
opt_set_signal_information:
2477
/*Empty*/ { $$ = NULL; }
2478
| SET signal_information_item_list
2480
merge_nodes($$, parse_ctx->mem_pool_, T_SP_SIGNAL_INFO_LIST, $2);
2484
signal_information_item_list:
2485
signal_information_item { $$ = $1; }
2486
| signal_information_item_list ',' signal_information_item
2488
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_LINK_NODE, 2, $1, $3);
2492
signal_information_item:
2493
scond_info_item_name '=' signal_allowed_expr
2495
malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_SIGNAL_INFO_ITEM, 1, $3);
2501
literal { $$ = $1; }
2502
| variable { $$ = $1; }
2503
| simple_ident { $$ = $1; }
2504
| STRING { $$ = $1; }
2508
SYSTEM_VARIABLE { $$ = $1; }
2509
| USER_VARIABLE { $$ = $1; }
2512
scond_info_item_name:
2513
CLASS_ORIGIN { $$ = DIAG_CLASS_ORIGIN; }
2514
| SUBCLASS_ORIGIN { $$ = DIAG_SUBCLASS_ORIGIN; }
2515
| CONSTRAINT_CATALOG { $$ = DIAG_CONSTRAINT_CATALOG; }
2516
| CONSTRAINT_SCHEMA { $$ = DIAG_CONSTRAINT_SCHEMA; }
2517
| CONSTRAINT_NAME { $$ = DIAG_CONSTRAINT_NAME; }
2518
| CATALOG_NAME { $$ = DIAG_CATALOG_NAME; }
2519
| SCHEMA_NAME { $$ = DIAG_SCHEMA_NAME; }
2520
| TABLE_NAME { $$ = DIAG_TABLE_NAME; }
2521
| COLUMN_NAME { $$ = DIAG_COLUMN_NAME; }
2522
| CURSOR_NAME { $$ = DIAG_CURSOR_NAME; }
2523
| MESSAGE_TEXT { $$ = DIAG_MESSAGE_TEXT; }
2524
| MYSQL_ERRNO { $$ = DIAG_MYSQL_ERRNO; }
2530
* @param [out] pl_yychar, set the pl parser look-ahead token
2532
ParseNode *obpl_mysql_read_sql_construct(ObParseCtx *parse_ctx, const char *prefix, YYLookaheadToken *la_token, int end_token_cnt, ...)
2534
int errcode = OB_PARSER_SUCCESS;
2536
bool is_break = false;
2537
int sql_str_len = -1;
2538
int parenlevel = (*(la_token->la_yychar) == '(' || *(la_token->la_yychar) == '[') ? 1 : 0;
2539
const char *sql_str = NULL;
2540
ParseResult parse_result;
2541
ParseNode *sql_node = NULL;
2542
if (*(la_token->la_yychar) != -2) { //#define YYEMPTY (-2)
2543
parse_ctx->scanner_ctx_.sql_end_loc = la_token->la_yylloc->last_column;
2544
if (parse_ctx->scanner_ctx_.sql_start_loc < 0) {
2545
parse_ctx->scanner_ctx_.sql_start_loc = la_token->la_yylloc->first_column;
2549
*(la_token->la_yychar) = obpl_mysql_yylex(la_token->la_yylval, la_token->la_yylloc, parse_ctx->scanner_ctx_.yyscan_info_);
2550
if (parse_ctx->scanner_ctx_.sql_start_loc < 0) {
2551
//get sql rule start location
2552
parse_ctx->scanner_ctx_.sql_start_loc = la_token->la_yylloc->first_column;
2554
va_start(va, end_token_cnt);
2556
for (; !is_break && i < end_token_cnt; ++i) {
2557
int end_token = va_arg(va, int);
2558
if (end_token == *(la_token->la_yychar) && parenlevel <= 0) { //正常应该用==0,但是可能外面已经读出了左括号,所以这里用<=
2560
if (END_P == end_token) {
2561
parse_ctx->scanner_ctx_.sql_end_loc = la_token->la_yylloc->last_column;
2563
parse_ctx->scanner_ctx_.sql_end_loc = la_token->la_yylloc->first_column - 1;
2568
if (*(la_token->la_yychar) == '(' || *(la_token->la_yychar) == '[') {
2570
} else if (*(la_token->la_yychar) == ')' || *(la_token->la_yychar) == ']') {
2573
if (END_P == *(la_token->la_yychar)) {
2575
parse_ctx->scanner_ctx_.sql_end_loc = la_token->la_yylloc->last_column;
2578
//get sql rule end location
2579
parse_ctx->scanner_ctx_.sql_end_loc = la_token->la_yylloc->last_column;
2582
if (OB_PARSER_SUCCESS == errcode) {
2583
parse_ctx->scanner_ctx_.sql_end_loc = parse_ctx->stmt_len_ <= parse_ctx->scanner_ctx_.sql_end_loc ?
2584
parse_ctx->stmt_len_ - 1 : parse_ctx->scanner_ctx_.sql_end_loc;
2585
sql_str_len = parse_ctx->scanner_ctx_.sql_end_loc - parse_ctx->scanner_ctx_.sql_start_loc + 1;
2587
if (OB_PARSER_SUCCESS == errcode && sql_str_len > 0) {
2588
sql_str = strndup_with_prefix(prefix, parse_ctx->stmt_str_ + parse_ctx->scanner_ctx_.sql_start_loc,
2589
sql_str_len, parse_ctx->mem_pool_);
2590
if (NULL == sql_str) {
2591
YY_FATAL_ERROR("no memory to strdup sql string\n");
2594
memset(&parse_result, 0, sizeof(ParseResult));
2595
parse_result.input_sql_ = sql_str;
2596
parse_result.input_sql_len_ = sql_str_len + strlen(prefix);
2597
parse_result.malloc_pool_ = parse_ctx->mem_pool_;
2598
parse_result.pl_parse_info_.is_pl_parse_ = true;
2599
parse_result.pl_parse_info_.is_pl_parse_expr_ = false;
2600
parse_result.is_for_trigger_ = (1 == parse_ctx->is_for_trigger_);
2601
//将pl_parser的question_mark_size赋值给sql_parser,使得parser sql的question mark能够接着pl_parser的index
2602
parse_result.question_mark_ctx_ = parse_ctx->question_mark_ctx_;
2603
parse_result.charset_info_ = parse_ctx->charset_info_;
2604
parse_result.charset_info_oracle_db_ = parse_ctx->charset_info_oracle_db_;
2605
parse_result.is_not_utf8_connection_ = parse_ctx->is_not_utf8_connection_;
2606
parse_result.connection_collation_ = parse_ctx->connection_collation_;
2607
parse_result.sql_mode_ = parse_ctx->scanner_ctx_.sql_mode_;
2609
if (sql_str_len <= 0) {
2611
} else if (0 != parse_sql_stmt(&parse_result)) {
2612
if (parse_result.extra_errno_ != OB_PARSER_SUCCESS) {
2613
obpl_mysql_parse_fatal_error(parse_result.extra_errno_, YYLEX_PARAM, parse_result.error_msg_);
2616
memset(&sql_yylloc, 0, sizeof(YYLTYPE));
2617
sql_yylloc.first_column = parse_ctx->scanner_ctx_.sql_start_loc;
2618
sql_yylloc.last_column = parse_ctx->scanner_ctx_.sql_end_loc;
2619
sql_yylloc.first_line = la_token->la_yylloc->first_line;
2620
sql_yylloc.last_line = la_token->la_yylloc->last_line;
2621
obpl_mysql_yyerror(&sql_yylloc, parse_ctx, "Syntax Error\n");
2624
sql_node = parse_result.result_tree_->children_[0];
2625
//通过sql_parser的question_mark_size来更新pl_parser
2626
parse_ctx->question_mark_ctx_ = parse_result.question_mark_ctx_;
2631
void obpl_mysql_yyerror(YYLTYPE *yylloc, ObParseCtx *parse_ctx, char *s, ...)
2633
if (OB_LIKELY(NULL != parse_ctx)) {
2636
vsnprintf(parse_ctx->global_errmsg_, MAX_ERROR_MSG, s, ap);
2637
// vfprintf(stderr, s, ap);
2638
if (OB_LIKELY(NULL != yylloc)) {
2639
ObParseErrorInfo *error_info = (ObParseErrorInfo*)parse_malloc(sizeof(ObParseErrorInfo), parse_ctx->mem_pool_);
2640
if (NULL == error_info) {
2641
YY_FATAL_ERROR("No memory for malloc parse error info\n");
2643
memset(error_info, 0, sizeof(ObParseErrorInfo));
2644
error_info->stmt_loc_.first_column_ = yylloc->first_column;
2645
error_info->stmt_loc_.last_column_ = yylloc->last_column;
2646
error_info->stmt_loc_.first_line_ = yylloc->first_line;
2647
error_info->stmt_loc_.last_line_ = yylloc->last_line;
2648
parse_ctx->cur_error_info_ = error_info;