forked from oceanbase/oceanbase
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparse_node.h
More file actions
462 lines (408 loc) · 15.2 KB
/
Copy pathparse_node.h
File metadata and controls
462 lines (408 loc) · 15.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#ifndef OCEANBASE_SQL_PARSER_PARSE_NODE_H_
#define OCEANBASE_SQL_PARSER_PARSE_NODE_H_
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdbool.h>
#include <setjmp.h>
#ifdef SQL_PARSER_COMPILATION
#include "ob_sql_mode.h"
#include "ob_item_type.h"
#else
#include "common/sql_mode/ob_sql_mode.h"
#include "objit/common/ob_item_type.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
#define MAX_ERROR_MSG 1024
struct ObCharsetInfo;
enum SelectParserOffset
{
PARSE_SELECT_WITH,
PARSE_SELECT_DISTINCT,
PARSE_SELECT_SELECT,
PARSE_SELECT_INTO, //into before from
PARSE_SELECT_FROM,
PARSE_SELECT_WHERE,
PARSE_SELECT_DYNAMIC_SW_CBY, // connect by node or start with node
PARSE_SELECT_DYNAMIC_CBY_SW, // connect by node or start with node
PARSE_SELECT_DYNAMIC_GROUP,
PARSE_SELECT_DYNAMIC_HAVING,
PARSE_SELECT_NAMED_WINDOWS,
PARSE_SELECT_SET,
PARSE_SELECT_FORMER,
PARSE_SELECT_LATER,
PARSE_SELECT_ORDER,
PARSE_SELECT_LIMIT,
PARSE_SELECT_FOR_UPD,
PARSE_SELECT_HINTS,
PARSE_SELECT_WHEN,
PARSE_SELECT_FETCH,
PARSE_SELECT_FETCH_TEMP, //use to temporary store fetch clause in parser
PARSE_SELECT_WITH_CHECK_OPTION,
PARSE_SELECT_INTO_EXTRA,// ATTENTION!! SELECT_INTO_EXTRA must be the last one
PARSE_SELECT_MAX_IDX
};
enum GrantParseOffset
{
PARSE_GRANT_ROLE_LIST,
PARSE_GRANT_ROLE_GRANTEE,
PARSE_GRANT_ROLE_OPT_WITH,
PARSE_GRANT_ROLE_MAX_IDX
};
enum GrantParseSysOffset
{
PARSE_GRANT_SYS_PRIV_ORACLE_LIST,
PARSE_GRANT_SYS_PRIV_ORACLE_GRANTEE,
PARSE_GRANT_SYS_PRIV_ORACLE_OPT_WITH,
PARSE_GRANT_SYS_PRIV_ORACLE_MAX_IDX
};
enum ParseMode
{
STD_MODE = 0,
FP_MODE, /* fast parse,保留hint,且做参数化*/
MULTI_MODE ,/* multi query ultra-fast parse */
FP_PARAMERIZE_AND_FILTER_HINT_MODE,/*过滤掉hint,并且做参数化*/
FP_NO_PARAMERIZE_AND_FILTER_HINT_MODE,/*过滤掉hint,并且不做参数化*/
TRIGGER_MODE, /* treat ':xxx' as identifier */
DYNAMIC_SQL_MODE, /*解析动态sql过程中,:idx和:identifier要根据语句类型确定是否检查placeholder的名字*/
DBMS_SQL_MODE,
UDR_SQL_MODE,
INS_MULTI_VALUES,
};
typedef struct
{
int err_code_;
char err_msg_[MAX_ERROR_MSG];
} ErrStat;
struct _ParseNode;
typedef struct _ObStmtLoc
{
int first_column_;
int last_column_;
int first_line_;
int last_line_;
} ObStmtLoc;
enum UdtUdfType
{
UDT_UDF_UNKNOWN,
UDT_UDF_CONS = 1,
UDT_UDF_MEMBER = 2,
UDT_UDF_STATIC = 4,
UDT_UDF_MAP = 8,
UDT_UDF_ORDER = 16,
};
typedef struct _ParseNode
{
ObItemType type_;
int32_t num_child_; /* attributes for non-terninal node, which has children */
int16_t param_num_; //记录该node对应的原始text中常量的个数, 暂时仅T_CAST_ARGUMENT使用
union {
uint32_t flag_;
struct {
uint32_t is_neg_ : 1;// 记录常量节点的父节点是否为T_OP_NEG节点, 1表示是, 0 表示不是
uint32_t is_hidden_const_ : 1; //1 表示某常量正常parse能识别但fast parse不能识别, 0 表示都能识别。
uint32_t is_tree_not_param_ :1; //1 表示该节点及其子节点常量均不能参数化, 0表示没该限制
uint32_t length_semantics_ :2; //2 for oracle [char|varbinary] (n b [bytes|char])
uint32_t is_val_paramed_item_idx_ :1; // T_PROJECT_STRING的values是否是select_item_param_infos数组的下标
uint32_t is_copy_raw_text_ : 1; // 是否回填常量节点的raw_text_,用于select item常量参数化
uint32_t is_column_varchar_ : 1; // 投影列是否是一个常量字符串,用于select item常量参数化
uint32_t is_trans_from_minus_: 1; // 负数常量节点是否是从减号操作转换而来,比如1 - 2,词法阶段会生成一个-2
uint32_t is_assigned_from_child_: 1; // 常量节点是否由子节点赋值得到,用于处理int64_min
uint32_t is_num_must_be_pos_: 1; //
uint32_t is_date_unit_ : 1; //1 表示是date unit常量,在反拼的时候需要反拼为字符串
uint32_t is_literal_bool_ : 1; // indicate node is a literal TRUE/FALSE
uint32_t is_empty_ : 1; // 表示是否缺省该节点,1表示缺省,0表示没有缺省, opt_asc_desc节点中使用到
uint32_t is_multiset_ : 1; // for cast(multiset(...) as ...)
uint32_t is_forbid_anony_parameter_ : 1; // 1 表示禁止匿名块参数化
uint32_t is_input_quoted_ : 1; // indicate name_ob input whether with double quote
uint32_t is_forbid_parameter_ : 1; //1 indicate forbid parameter
uint32_t reserved_;
};
};
/* attributes for terminal node, it is real value */
/* 数值类型的node将用到value_来存放其值,但是对于字符串和decimal类型,用str_value来存字符串指针,
* str_len_表示字符串的长度,不要用strlen(str_value_)来获取str_value_的值,因为str_value_不保证以'\0'结尾.
* 此外,为什么不将value_和str_len_作为union呢,这是因为在parse
* 一个数值类型的时候,不仅需要存储其value,还需要存储其原始字符串,举例:select
* 1111;这种语句,我们不仅要存int value的值,还得存'1111' 字符串*/
union {
int64_t value_;
int32_t int32_values_[2];
int16_t int16_values_[4];
};
const char *str_value_;
int64_t str_len_;
union {
int64_t pl_str_off_; // pl层, 记录str在原始字符串中的起始偏移
int64_t sql_str_off_; // sql层, 记录str在原始字符串中的起始偏移
};
/* 用于存放在词法阶段被特殊处理后丢失的文本串 eg: NULL, Date '2010-10-11',
* 该文本串在fast parse参数化后,如果该参数作为plan cache中stmtkey的一部分,
* 则需要使用原始的文本串,而不是丢失文本串后的值,否则会导致plan cache误匹配
* */
const char *raw_text_;
int64_t text_len_;
int64_t pos_; //记录?在带?的sql中的偏移
struct _ParseNode **children_; /* attributes for non-terminal node, which has children */
ObStmtLoc stmt_loc_; //临时放在这里,后面要移到parse_stmt_node.h中去
union {
int64_t raw_param_idx_; // 常量节点在fp_result.raw_params_中的下标
int64_t raw_sql_offset_; // 常量节点在sql中的字符偏移
};
#ifdef SQL_PARSER_COMPILATION
int token_off_;
int token_len_;
#endif
} ParseNode;
struct _ParamList;
typedef struct _ParamList
{
ParseNode *node_;
struct _ParamList *next_;
} ParamList;
//供parser使用的外部依赖对象类型
enum RefType
{
REF_REL = 0,
REF_PROC,
REF_FUNC,
};
//外部依赖对象链表
typedef struct _RefObjList
{
enum RefType type_;
ParseNode *node_;
struct _RefObjList *next_;
} RefObjList;
//解析PL中sql语句时需要使用的属性集合
typedef struct _PLParseInfo
{
bool is_pl_parse_;//用于标识当前parser逻辑是否为PLParse调用
bool is_pl_parse_expr_; //用于标识当前parser逻辑是否在解析PLParser的expr
bool is_forbid_pl_fp_;
bool is_inner_parse_;
int last_pl_symbol_pos_; //上一个pl变量的结束位置
int plsql_line_;
/*for mysql pl*/
void *pl_ns_; //ObPLBlockNS
RefObjList *ref_object_nodes_; //依赖对象链表头
RefObjList *tail_ref_object_node_; //依赖对象链表尾
} PLParseInfo;
//跟@如巅讨论,此处的定义后续会改成动态的,此处先定义128
#define MAX_QUESTION_MARK 128
typedef struct _ObQuestionMarkCtx
{
char **name_;
int count_;
int capacity_;
bool by_ordinal_;
bool by_name_;
bool by_defined_name_;
} ObQuestionMarkCtx;
// record the minus status while parsing the sql
// for example, 'select - -1 from dual'
// when parser sees the first '-', pos_ = 7, raw_sql_offset = 7, has_minus_ = true, is_cur_numeric_ = false
// after seeing the second '-', members are reseted, pos_ = 9, raw_sql_offset_ = 9, has_minus_ = true, is_cur_numeric = false
// after seeing '1', is_cur_numeric = true, then param node '-1' is returned
typedef struct _ObMinusStatuCtx
{
int pos_; // 负数在参数化后的sql中出现的位置
int raw_sql_offset_; // 负号在原始sql中出现的位置
bool has_minus_; // 保留一下负号的状态,在遇到数值类型的时候,词法返回一个负数节点
bool is_cur_numeric_; // 当前常量节点是否是数值节点
} ObMinusStatusCtx;
#ifdef SQL_PARSER_COMPILATION
// for comment_list_ in ParseResult
typedef struct TokenPosInfo
{
int token_off_;
int token_len_;
} TokenPosInfo;
#endif
//外部依赖对象链表
typedef struct _ParenthesesOffset
{
int left_parentheses_;
int right_parentheses_;
struct _ParenthesesOffset *next_;
} ParenthesesOffset;
//dml base runtime context definition
typedef struct _InsMultiValuesResult
{
ParenthesesOffset *ref_parentheses_;
ParenthesesOffset *tail_parentheses_;
int values_col_;
int values_count_;
int on_duplicate_pos_; // the start position of on duplicate key in insert ... on duplicate key update statement
int ret_code_;
} InsMultiValuesResult;
typedef struct
{
void *yyscan_info_;
const char *input_sql_;
int input_sql_len_;
int param_node_num_;
int token_num_;
void *malloc_pool_; // ObIAllocator
ObQuestionMarkCtx question_mark_ctx_;
ObSQLMode sql_mode_;
const struct ObCharsetInfo *charset_info_; //client charset
const struct ObCharsetInfo *charset_info_oracle_db_; //oracle DB charset
ParamList *param_nodes_;
ParamList *tail_param_node_;
struct {
uint32_t has_encount_comment_ : 1;
uint32_t is_fp_ : 1;
uint32_t is_multi_query_ : 1;
uint32_t is_ignore_hint_ : 1;//used for outline
uint32_t is_ignore_token_ : 1;//used for outline
uint32_t need_parameterize_ : 1;//used for outline, to support signature of outline can contain hint
uint32_t in_q_quote_ : 1;
uint32_t is_for_trigger_ : 1;
uint32_t is_dynamic_sql_ : 1;
uint32_t is_dbms_sql_ : 1;
uint32_t is_batched_multi_enabled_split_ : 1;
uint32_t is_not_utf8_connection_ : 1;
uint32_t may_bool_value_ : 1; // used for true/false in sql parser
uint32_t is_include_old_new_in_trigger_ : 1;
uint32_t is_normal_ps_prepare_ : 1;
uint32_t is_multi_values_parser_ : 1;
uint32_t is_for_udr_ : 1;
uint32_t is_for_remap_ : 1;
uint32_t contain_sensitive_data_ : 1;
uint32_t may_contain_sensitive_data_ : 1;
};
ParseNode *result_tree_;
jmp_buf *jmp_buf_;//handle fatal error
int extra_errno_;
char *error_msg_;
int start_col_;
int end_col_;
int line_;
int yycolumn_;
int yylineno_;
char *tmp_literal_;
/* for multi query fast parse (split queries) */
char *no_param_sql_;
int no_param_sql_len_;
int no_param_sql_buf_len_;
/*for pl*/
PLParseInfo pl_parse_info_;
/*for q-quote*/
ObMinusStatusCtx minus_ctx_; // for fast parser to parse negative value
int64_t last_escape_check_pos_; //解析quoted string%parse-param时的一个临时变量,处理连接gbk字符集时遇到的转义字符问题
int connection_collation_;//connection collation
bool mysql_compatible_comment_; //whether the parser is parsing "/*! xxxx */"
bool enable_compatible_comment_;
InsMultiValuesResult *ins_multi_value_res_;
#ifdef SQL_PARSER_COMPILATION
TokenPosInfo *comment_list_;
int comment_cnt_;
int comment_cap_;
int realloc_cnt_;
bool stop_add_comment_;
#endif
} ParseResult;
typedef struct _ObFastParseCtx
{
bool is_fp_;
} ObFastParseCtx;
typedef enum ObSizeUnitType
{
SIZE_UNIT_TYPE_INVALID = -1,
SIZE_UNIT_TYPE_K,
SIZE_UNIT_TYPE_M,
SIZE_UNIT_TYPE_G,
SIZE_UNIT_TYPE_T,
SIZE_UNIT_TYPE_P,
SIZE_UNIT_TYPE_E,
SIZE_UNIT_TYPE_MAX
} ObSizeUnitType;
extern int parse_init(ParseResult *p);
extern int parse_terminate(ParseResult *p);
extern int parse_sql(ParseResult *p, const char *pszSql, size_t iLen);
extern void destroy_tree(ParseNode *pRoot);
extern unsigned char escaped_char(unsigned char c, int *with_back_slash);
extern char *str_tolower(char *buff, int64_t len);
extern char *str_toupper(char *buff, int64_t len);
extern int64_t str_remove_space(char *buff, int64_t len);
//extern int64_t ob_parse_string(const char *src, char *dest, int64_t len, int quote_type);
extern ParseNode *new_node(void *malloc_pool, ObItemType type, int num);
extern ParseNode *new_non_terminal_node(void *malloc_pool, ObItemType node_tag, int num, ...);
extern ParseNode *new_terminal_node(void *malloc_pool, ObItemType type);
extern int obpl_parser_check_stack_overflow();
int get_deep_copy_size(const ParseNode *node, int64_t *size);
int deep_copy_parse_node(void *malloc_pool, const ParseNode *src, ParseNode *dst);
/// convert x'42ab' to binary string
void ob_parse_binary(const char *src, int64_t len, char* dest);
int64_t ob_parse_binary_len(int64_t len);
// convert b'10010110' to binary string
// @pre dest buffer is enough
void ob_parse_bit_string(const char* src, int64_t len, char* dest);
int64_t ob_parse_bit_string_len(int64_t len);
// calculate hash value of syntax tree recursively
// @param [in] node syntax tree root
// @return hash value of syntax tree
extern uint64_t parsenode_hash(const ParseNode *node, int *ret);
// compare syntax tree recursively
// @param [in] node1 first syntax tree
// @param [in] node2 second syntax tree
extern bool parsenode_equal(const ParseNode *node1, const ParseNode *node2, int *ret);
extern int64_t get_question_mark(ObQuestionMarkCtx *ctx, void *malloc_pool, const char *name);
extern int64_t get_question_mark_by_defined_name(ObQuestionMarkCtx *ctx, const char *name);
// compare ParseNode str_value_ to pattern
// @param [in] node ParseNode
// @param [in] pattern pattern_str
// @param [in] pat_len length of pattern
extern bool nodename_equal(const ParseNode *node, const char *pattern, int64_t pat_len);
#define OB_NODE_CAST_TYPE_IDX 0
#define OB_NODE_CAST_COLL_IDX 1
#define OB_NODE_CAST_N_PREC_IDX 2
#define OB_NODE_CAST_N_SCALE_IDX 3
#define OB_NODE_CAST_NUMBER_TYPE_IDX 1
#define OB_NODE_CAST_C_LEN_IDX 1
#define OB_NODE_CAST_GEO_TYPE_IDX 1
typedef enum ObNumberParseType
{
NPT_PERC_SCALE = 0,
NPT_STAR_SCALE,
NPT_STAR,
NPT_PERC,
NPT_EMPTY,
} ObNumberParseType;
#ifndef SQL_PARSER_COMPILATION
bool check_stack_overflow_c();
//查找外部pl变量的接口,获取变量在外部符号表中的下标,定义在ob_pl_stmt.cpp中
int lookup_pl_symbol(const void *pl_ns, const char *symbol, size_t len, int64_t *find_idx);
#endif
typedef struct _ParserLinkNode
{
struct _ParserLinkNode *next_;
struct _ParserLinkNode *prev_;
void *val_;
} ParserLinkNode;
ParserLinkNode *new_link_node(void *malloc);
typedef enum ObTranslateCharset
{
TRANSLATE_CHAR_CS = 0,
TRANSLATE_NCHAR_CS = 1,
} ObTranslateCharset;
#ifdef __cplusplus
}
#endif
#endif //OCEANBASE_SQL_PARSER_PARSE_NODE_H_