oceanbase

Форк
0
/
pl_parser_mysql_mode.l 
687 строк · 22.0 Кб
1
/** 
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.
11
 */ 
12

13
/*first: declare*/
14
%option noyywrap nounput noinput yylineno case-insensitive
15
%option noyyalloc noyyrealloc noyyfree
16
%option reentrant bison-bridge bison-locations
17
%option prefix="obpl_mysql_yy"
18
%option header-file="../../../src/pl/parser/pl_parser_mysql_mode_lex.h"
19
%{
20
#include "pl/parser/pl_parser_base.h"
21
#include "pl_parser_mysql_mode_tab.h"
22

23
extern void obpl_mysql_yyerror(YYLTYPE *yylloc, ObParseCtx *parse_ctx, char *s,...);
24
extern void obpl_mysql_parse_fatal_error(int32_t errcode, yyscan_t yyscanner, yyconst char *msg, ...);
25

26
#define YY_FATAL_ERROR(msg, args...) (obpl_mysql_parse_fatal_error(OB_PARSER_ERR_NO_MEMORY, yyscanner, msg, ##args))
27
#define YY_UNEXPECTED_ERROR(msg, args...) (obpl_mysql_parse_fatal_error(OB_PARSER_ERR_UNEXPECTED, yyscanner, msg, ##args))
28
#define YY_NAME_ERROR(msg, args...) (obpl_mysql_parse_fatal_error(OB_PARSER_ERR_ILLEGAL_NAME, yyscanner, msg, ##args))
29
%}
30

31
%x in_c_comment
32
%x sq
33
%x dq
34
%x bt
35
/* the adq is used to process dq in ANSI_QUOTES sql_mode*/
36
%x adq
37

38
U  [\x80-\xbf]
39
U_2  [\xc2-\xdf]
40
U_3  [\xe0-\xef]
41
U_4  [\xf0-\xf4]
42
GB_1 [\x81-\xfe]
43
GB_2 [\x40-\xfe]
44
GB_3 [\x30-\x39]
45
UTF8_GB_CHAR ({U_2}{U}|{U_3}{U}{U}|{U_4}{U}{U}{U}|{GB_1}{GB_2}|{GB_1}{GB_3}{GB_1}{GB_3})
46
space            [ \t\n\r\f]
47
non_newline      [^\n\r]
48
comment      ("--"{space}+{non_newline}*)|(#{non_newline}*)
49
whitespace       ({space}+|{comment})
50
c_cmt_begin      \/\*
51
c_cmt_end        \*+\/
52
identifer        (([A-Za-z0-9$_]|{UTF8_GB_CHAR})*)
53
int_num          [0-9]+
54
system_variable  (@@[A-Za-z_][A-Za-z0-9_]*)
55
user_variable    (@[A-Za-z0-9_\.$]*)|(@[`'\"][`'\"A-Za-z0-9_\.$/%]*)|(@%)
56

57
quote         '
58
sqbegin       {quote}
59
sqend         {quote}
60
sqdouble      {quote}{quote}
61
sqcontent     [^\\']+
62
qescape       [\\](.|\n)
63
sqnewline     {quote}{whitespace}{quote}
64

65
dquote         \"
66
dqbegin       {dquote}
67
dqend         {dquote}
68
dqdouble      {dquote}{dquote}
69
dqcontent     [^\\"]+
70
dqnewline     {dquote}{whitespace}{dquote}
71

72
backtick      `
73
btbegin       {backtick}
74
btend         {backtick}
75
btdouble      {backtick}{backtick}
76
btcontent     [^`]+
77

78
mysql_compatible_comment_with_version \/\*\![0-9]{5}
79
mysql_compatible_comment_without_version \/\*\!
80
mysql_compatible_comment_end \*\/
81

82
%%
83
ALTER                         { return ALTER; }
84
BINARY                        { return BINARY; }
85
CALL                          { return CALL; }
86
CREATE                        { return CREATE; }
87
DELETE                        { return DELETE; }
88
DO                            { return DO; }
89
DROP                          { return DROP; }
90
FUNCTION                      { return FUNCTION; }
91
INSERT                        { return INSERT; }
92
INTO                          { return INTO; }
93
PROCEDURE                     { return PROCEDURE; }
94
SELECT                        { return SELECT; }
95
SET                           { return SET; }
96
TABLE                         { return TABLE; }
97
UPDATE                        { return UPDATE; }
98
JSON                          { return JSON; }
99
REPLACE                       { return REPLACE; }
100
TRIGGER {
101
  ObParseCtx *parse_ctx = (ObParseCtx *)yyextra;
102
  parse_ctx->is_for_trigger_ = 1;
103
  return TRIGGER;
104
}
105
NULL {
106
  check_ptr(yylval);
107
  ObParseCtx *parse_ctx = (ObParseCtx *)yyextra;
108
  malloc_new_node(yylval->node, parse_ctx->mem_pool_, T_NULL, 0);
109
  return NULLX;
110
}
111

112
{int_num} {
113
  int32_t token_ret = INTNUM;
114
  ParseNode *node = NULL;
115
  check_ptr(yylval);
116
  ObParseCtx *parse_ctx = (ObParseCtx *)yyextra;
117
  malloc_new_node(node, parse_ctx->mem_pool_, T_INT, 0);
118
  yylval->node = node;
119
  node->str_value_ = parse_strdup(yytext, parse_ctx->mem_pool_, &(node->str_len_));
120
  check_ptr(node->str_value_);
121
  errno = 0;
122
  node->value_ = strtoll(node->str_value_, NULL, 10);
123
  if (ERANGE == errno) {
124
    /* if out of range, seem it as must NUMERIC type, now is double */
125
    node->type_ = T_NUMBER;
126
    token_ret = DECIMAL_VAL;
127
  }
128
  return token_ret;
129
}
130

131
[0-9]+E[-+]?[0-9]+ |
132
[0-9]+"."[0-9]*E[-+]?[0-9]+ |
133
"."[0-9]+E[-+]?[0-9]+ {
134
  ParseNode *node = NULL;
135
  ObParseCtx *parse_ctx = (ObParseCtx *)yyextra;
136
  malloc_new_node(node, parse_ctx->mem_pool_, T_DOUBLE, 0);
137
  check_ptr(yylval);
138
  yylval->node = node;
139
  node->str_value_ = parse_strdup(yytext, parse_ctx->mem_pool_, &(node->str_len_));
140
  check_ptr(node->str_value_);
141
  return DECIMAL_VAL;
142
}
143

144
[0-9]+"."[0-9]* |
145
"."[0-9]+ {
146
  ParseNode *node = NULL;
147
  ObParseCtx *parse_ctx = (ObParseCtx *)yyextra;
148
  malloc_new_node(node, parse_ctx->mem_pool_, T_NUMBER/* should be T_NUMBER,*/, 0);
149
  check_ptr(yylval);
150
  yylval->node = node;
151
  node->str_value_ = parse_strdup(yytext, parse_ctx->mem_pool_, &(node->str_len_));
152
  check_ptr(node->str_value_);
153
  return DECIMAL_VAL;
154
}
155

156
{sqbegin} {
157
  BEGIN(sq);
158
  ObParseCtx *parse_ctx = (ObParseCtx *)yyextra;
159
  ObScannerCtx *scanner_ctx = &(parse_ctx->scanner_ctx_);
160
  scanner_ctx->first_column_ = yylloc->first_column;
161
  prepare_literal_buffer(scanner_ctx, parse_ctx->stmt_len_ + 1, parse_ctx->mem_pool_);
162
  check_ptr(yylval);
163
  malloc_new_node(yylval->node, parse_ctx->mem_pool_, T_VARCHAR, 0);
164
  yylval->node->str_len_ = 0;
165
}
166

167

168
<sq>{sqend} {
169
  BEGIN(INITIAL);
170
  ObParseCtx *parse_ctx = (ObParseCtx *)yyextra;
171
  ObScannerCtx *scanner_ctx = &(parse_ctx->scanner_ctx_);
172
  char *tmp_literal = scanner_ctx->tmp_literal_;
173
  tmp_literal[yylval->node->str_len_] = '\0';
174
  yylloc->first_column = scanner_ctx->first_column_;
175
  yylval->node->str_value_ = parse_strndup(tmp_literal, yylval->node->str_len_ + 1, parse_ctx->mem_pool_);
176
  return STRING;
177
}
178

179
<sq>{sqdouble} {
180
  check_ptr(yylval);
181
  ObParseCtx *parse_ctx = (ObParseCtx *)yyextra;
182
  ObScannerCtx *scanner_ctx = &(parse_ctx->scanner_ctx_);
183
  char *tmp_literal = scanner_ctx->tmp_literal_;
184
  tmp_literal[yylval->node->str_len_++] = '\'';
185
}
186

187
<sq>{sqcontent} {
188
  check_ptr(yylval);
189
  ObParseCtx *parse_ctx = (ObParseCtx *)yyextra;
190
  ObScannerCtx *scanner_ctx = &(parse_ctx->scanner_ctx_);
191
  char *tmp_literal = scanner_ctx->tmp_literal_;
192
  memmove(tmp_literal + yylval->node->str_len_, yytext, yyleng);
193
  yylval->node->str_len_ += yyleng;
194
}
195

196
<sq>{qescape} {
197
  int with_back_slash = 1;
198
  ObParseCtx *parse_ctx = (ObParseCtx *)yyextra;
199
  ObScannerCtx *scanner_ctx = &(parse_ctx->scanner_ctx_);
200
  char *tmp_literal = scanner_ctx->tmp_literal_;
201
  check_ptr(yylval);
202
  unsigned char c = escaped_char(yytext[1], &with_back_slash);
203
  if (with_back_slash) {
204
    tmp_literal[yylval->node->str_len_++] = '\\';
205
  }
206
  tmp_literal[yylval->node->str_len_++] = c;
207
}
208

209
<sq>{sqnewline} {
210
  /*
211
     In case of two adjacent string literal, such as " 'a' 'b' ", the two string will be
212
     concatenate into 'ab'. However, the string 'a' will used as the column name if it appears
213
     in the select list, which means we must save it rather than just skipping the 'sqnewline'.
214

215
     One solution is to do this in the yacc and let the lexer produce all strings as individual
216
     tokens. However, it will generate ambiguity in the yacc according to our grammar definition.
217
     Instead, we remember the first string as a child of the 'T_VARCHAR' node which represents
218
     " 'a' 'b' ", whose str_value_ is 'ab'. This will save us from modifying our grammar and a
219
     a lot of troubles.
220
   */
221
  check_ptr(yylval);
222
  if (0 == yylval->node->num_child_) {
223
    ObParseCtx *parse_ctx = (ObParseCtx *)yyextra;
224
    ObScannerCtx *scanner_ctx = &(parse_ctx->scanner_ctx_);
225
    char *tmp_literal = scanner_ctx->tmp_literal_;
226
    tmp_literal[yylval->node->str_len_] = '\0';
227
    yylval->node->children_ = (ParseNode **)parse_malloc(sizeof(ParseNode *), parse_ctx->mem_pool_);
228
    if (OB_UNLIKELY(NULL == yylval->node->children_)) {
229
      YY_FATAL_ERROR("No more space for mallocing '%s'\n", yytext);
230
    }
231

232
    malloc_new_node(yylval->node->children_[0], parse_ctx->mem_pool_, T_CONCAT_STRING, 0);
233
    (*yylval->node->children_)->str_value_ = parse_strndup(tmp_literal, yylval->node->str_len_ + 1,
234
                                            parse_ctx->mem_pool_);
235
    (*yylval->node->children_)->str_len_ = yylval->node->str_len_;
236
    yylval->node->num_child_ = 1;
237
  }
238
}
239

240
<sq><<EOF>>  {
241
  obpl_mysql_yyerror(yylloc, yyextra, "unterminated quoted string\n");
242
  return END_P;
243
}
244

245
{dqbegin} {
246
  check_ptr(yylval);
247
  ObParseCtx *parse_ctx = (ObParseCtx *)yyextra;
248
  ObScannerCtx *scanner_ctx = &(parse_ctx->scanner_ctx_);
249
  scanner_ctx->first_column_ = yylloc->first_column;
250
  prepare_literal_buffer(scanner_ctx, parse_ctx->stmt_len_ + 1, parse_ctx->mem_pool_);
251
  bool is_ansi_quotes = false;
252
  IS_ANSI_QUOTES(scanner_ctx->sql_mode_, is_ansi_quotes);
253
  if (is_ansi_quotes) {
254
    BEGIN(adq);
255
    malloc_new_node(yylval->node, parse_ctx->mem_pool_, T_IDENT, 0);
256
    yylval->node->str_len_ = 0;
257
  } else {
258
    BEGIN(dq);
259
    malloc_new_node(yylval->node, parse_ctx->mem_pool_, T_VARCHAR, 0);
260
    yylval->node->str_len_ = 0;
261
  }
262
}
263

264
<dq>{dqend} {
265
  BEGIN(INITIAL);
266
  ObParseCtx *parse_ctx = (ObParseCtx *)yyextra;
267
  ObScannerCtx *scanner_ctx = &(parse_ctx->scanner_ctx_);
268
  yylloc->first_column = scanner_ctx->first_column_;
269
  char *tmp_literal = scanner_ctx->tmp_literal_;
270
  check_ptr(yylval);
271
  tmp_literal[yylval->node->str_len_] = '\0';
272
  yylval->node->str_value_ = parse_strndup(tmp_literal, yylval->node->str_len_ + 1, parse_ctx->mem_pool_);
273
  return STRING;
274
}
275

276
<dq>{dqdouble} {
277
  check_ptr(yylval);
278
  ObParseCtx *parse_ctx = (ObParseCtx *)yyextra;
279
  ObScannerCtx *scanner_ctx = &(parse_ctx->scanner_ctx_);
280
  char *tmp_literal = scanner_ctx->tmp_literal_;
281
  tmp_literal[yylval->node->str_len_++] = '\"';
282
}
283

284
<dq>{dqcontent} {
285
  check_ptr(yylval);
286
  ObParseCtx *parse_ctx = (ObParseCtx *)yyextra;
287
  ObScannerCtx *scanner_ctx = &(parse_ctx->scanner_ctx_);
288
  char *tmp_literal = scanner_ctx->tmp_literal_;
289
  memmove(tmp_literal + yylval->node->str_len_, yytext, yyleng);
290
  yylval->node->str_len_ += yyleng;
291
}
292

293
<dq>{qescape} {
294
  int with_back_slash = 1;
295
  ObParseCtx *parse_ctx = (ObParseCtx *)yyextra;
296
  ObScannerCtx *scanner_ctx = &(parse_ctx->scanner_ctx_);
297
  char *tmp_literal = scanner_ctx->tmp_literal_;
298
  check_ptr(yylval);
299
  unsigned char c = escaped_char(yytext[1], &with_back_slash);
300
  if (with_back_slash) {
301
    tmp_literal[yylval->node->str_len_++] = '\\';
302
  }
303
  tmp_literal[yylval->node->str_len_++] = c;
304
}
305

306
<dq>{dqnewline} {
307
  /* see 'sqnewline' */
308
  check_ptr(yylval);
309
  if (0 == yylval->node->num_child_) {
310
    ObParseCtx *parse_ctx = (ObParseCtx *)yyextra;
311
    ObScannerCtx *scanner_ctx = &(parse_ctx->scanner_ctx_);
312
    char *tmp_literal = scanner_ctx->tmp_literal_;
313
    tmp_literal[yylval->node->str_len_] = '\0';
314

315
    yylval->node->children_ = (ParseNode **)parse_malloc(sizeof(ParseNode *), parse_ctx->mem_pool_);
316
    if (OB_UNLIKELY(NULL == yylval->node->children_)) {
317
      YY_FATAL_ERROR("No more space for mallocing '%s'\n", yytext);
318
    }
319

320
    malloc_new_node(yylval->node->children_[0], parse_ctx->mem_pool_, T_CONCAT_STRING, 0);
321
    (*yylval->node->children_)->str_value_ = parse_strndup(tmp_literal, yylval->node->str_len_ + 1,
322
                                            parse_ctx->mem_pool_);
323
    (*yylval->node->children_)->str_len_ = yylval->node->str_len_;
324
    yylval->node->num_child_ = 1;
325
  }
326
}
327

328
<dq><<EOF>>  {
329
  obpl_mysql_yyerror(yylloc, yyextra, "unterminated doublequoted string\n");
330
  return END_P;
331
}
332

333
<adq>{dqend} {
334
  BEGIN(INITIAL);
335
  check_ptr(yylval);
336
  ObParseCtx *parse_ctx = (ObParseCtx *)yyextra;
337
  ObScannerCtx *scanner_ctx = &(parse_ctx->scanner_ctx_);
338
  char *tmp_literal = scanner_ctx->tmp_literal_;
339
  yylloc->first_column = scanner_ctx->first_column_;
340
  tmp_literal[yylval->node->str_len_] = '\0';
341

342
  char *dup_value = NULL;
343
  if (parse_ctx->is_not_utf8_connection_) {
344
    dup_value = parse_str_convert_utf8(parse_ctx->charset_info_, tmp_literal,
345
                                       parse_ctx->mem_pool_, &(yylval->node->str_len_),
346
                                       &(parse_ctx->global_errno_));
347
    check_identifier_convert_result(parse_ctx->global_errno_);
348
  } else {
349
    dup_value = parse_strndup(tmp_literal, yylval->node->str_len_ + 1, parse_ctx->mem_pool_);
350
  }
351
  check_ptr(dup_value);
352
  yylval->node->str_value_ = dup_value;
353
  return IDENT;
354
}
355

356
<adq>{dqdouble} {
357
  check_ptr(yylval);
358
  ObParseCtx *parse_ctx = (ObParseCtx *)yyextra;
359
  ObScannerCtx *scanner_ctx = &(parse_ctx->scanner_ctx_);
360
  char *tmp_literal = scanner_ctx->tmp_literal_;
361
  tmp_literal[yylval->node->str_len_++] = '"';
362
}
363

364
<adq>{dqcontent} {
365
  check_ptr(yylval);
366
  ObParseCtx *parse_ctx = (ObParseCtx *)yyextra;
367
  ObScannerCtx *scanner_ctx = &(parse_ctx->scanner_ctx_);
368
  char *tmp_literal = scanner_ctx->tmp_literal_;
369
  memmove(tmp_literal + yylval->node->str_len_, yytext, yyleng);
370
  yylval->node->str_len_ += yyleng;
371
}
372

373
<adq><<EOF>>  {
374
  obpl_mysql_yyerror(yylloc, yyextra, "unterminated doublequoted string\n");
375
  return END_P;
376
}
377

378
X'([0-9A-F])*'|0X([0-9A-F])+ {
379
  char *src = yytext + 2;
380
  size_t len = yyleng - 2;
381
  // https://dev.mysql.com/doc/refman/5.7/en/hexadecimal-literals.html
382
  // Values written using X'val' notation must contain an even number of digits or a syntax error occurs. To correct the problem, pad the value with a leading zero.
383
  // Values written using 0xval notation that contain an odd number of digits are treated as having an extra leading 0. For example, 0xaaa is interpreted as 0x0aaa.
384
  if ('\'' == src[len - 1]) {
385
    // Values written using X'val' notation
386
    --len;
387
    if (0 != len % 2) {
388
      obpl_mysql_yyerror(yylloc, yyextra, "hex string contain an even number of digits\n");
389
      return PARSER_SYNTAX_ERROR;
390
    }
391
  }
392
  ParseNode *node = NULL;
393
  ObParseCtx *parse_ctx = (ObParseCtx *)yyextra;
394
  check_ptr(yylval);
395
  malloc_new_node(node, parse_ctx->mem_pool_, T_HEX_STRING, 0);
396
  if (len > 0) {
397
    int64_t dest_len = ob_parse_binary_len(len);
398
    char *dest = (char *)parse_malloc(dest_len, parse_ctx->mem_pool_);
399
    check_ptr(dest);
400
    ob_parse_binary(src, len, dest);
401
    node->str_value_ = dest;
402
    node->str_len_ = dest_len;
403
  } else {
404
    node->str_value_ = NULL;
405
    node->str_len_ = 0;
406
  }
407
  yylval->node = node;
408
  return HEX_STRING_VALUE;
409
}
410

411
B'([01])*'|0B([01])+ {
412
  char* src = yytext + 2;
413
  size_t len = yyleng - 2;
414
  if(src[len - 1] == '\'') {
415
    --len;
416
  }
417
  ParseNode *node = NULL;
418
  ObParseCtx *parse_ctx = (ObParseCtx *)yyextra;
419
  check_ptr(yylval);
420
  malloc_new_node(node, parse_ctx->mem_pool_, T_HEX_STRING, 0);
421
  if (len > 0) {
422
    int64_t dest_len = ob_parse_bit_string_len(len);
423
    char *dest = (char*)parse_malloc(dest_len, parse_ctx->mem_pool_);
424
    check_ptr(dest);
425
    ob_parse_bit_string(src, len, dest);
426
    node->str_value_ = dest;
427
    node->str_len_ = dest_len;
428
  } else {
429
    node->str_value_ = NULL;
430
    node->str_len_ = 0;
431
  }
432
  yylval->node = node;
433
  return HEX_STRING_VALUE;
434
}
435

436
Date{whitespace}?'[^']*' {
437
  ObParseCtx *parse_ctx = (ObParseCtx *)yyextra;
438
  check_ptr(yylval);
439
  malloc_time_node_s(parse_ctx->mem_pool_, T_DATE);
440
  return DATE_VALUE;
441
}
442

443
Time{whitespace}?'[^']*' {
444
  ObParseCtx *parse_ctx = (ObParseCtx *)yyextra;
445
  malloc_time_node_s(parse_ctx->mem_pool_, T_TIME);
446
  check_ptr(yylval);
447
  return DATE_VALUE;
448
}
449

450
Timestamp{whitespace}?'[^']*' {
451
  ObParseCtx *parse_ctx = (ObParseCtx *)yyextra;
452
  check_ptr(yylval);
453
  malloc_time_node_s(parse_ctx->mem_pool_, T_TIMESTAMP);
454
  return DATE_VALUE;
455
}
456
Date{whitespace}?\"[^\"]*\" {
457
  ObParseCtx *parse_ctx = (ObParseCtx *)yyextra;
458
  malloc_time_node_d(parse_ctx->mem_pool_, T_DATE);
459
  check_ptr(yylval);
460
  return DATE_VALUE;
461
}
462

463
Time{whitespace}?\"[^\"]*\" {
464
  ObParseCtx *parse_ctx = (ObParseCtx *)yyextra;
465
  check_ptr(yylval);
466
  malloc_time_node_d(parse_ctx->mem_pool_, T_TIME);
467
  return DATE_VALUE;
468
}
469

470
Timestamp{whitespace}?\"[^\"]*\" {
471
  ObParseCtx *parse_ctx = (ObParseCtx *)yyextra;
472
  check_ptr(yylval);
473
  malloc_time_node_d(parse_ctx->mem_pool_, T_TIMESTAMP);
474
  return DATE_VALUE;
475
}
476

477
{system_variable} {
478
  ParseNode *node = NULL;
479
  ObParseCtx *parse_ctx = (ObParseCtx *)yyextra;
480
  check_ptr(yylval);
481
  malloc_new_node(node, parse_ctx->mem_pool_, T_SYSTEM_VARIABLE, 0);
482
  yylval->node = node;
483
  /* skip '@@' */
484
  node->str_value_ = parse_strdup(yytext + 2, parse_ctx->mem_pool_, &(node->str_len_));
485
  check_ptr(node->str_value_);
486
  node->value_ = 0;
487
  return SYSTEM_VARIABLE;
488
}
489

490
{user_variable} {
491
  ParseNode *node = NULL;
492
  ObParseCtx *parse_ctx = (ObParseCtx *)yyextra;
493
  check_ptr(yylval);
494
  malloc_new_node(node, parse_ctx->mem_pool_, T_USER_VARIABLE_IDENTIFIER, 0);
495
  yylval->node = node;
496
  /* skip '@' */
497
  node->str_value_ = parse_strdup(yytext + 1, parse_ctx->mem_pool_, &(node->str_len_));
498
  if (NULL != node->str_value_
499
      && *(yytext + 1) == *(yytext + node->str_len_)
500
      && (*(yytext + 1) == '\'' || *(yytext + 1) == '\"' || *(yytext + 1) == '`')) {
501
    node->str_value_ += 1;
502
    node->str_len_ -= 2;
503
  }
504
  check_ptr(node->str_value_);
505
  return USER_VARIABLE;
506
}
507

508
{btbegin} {
509
  BEGIN(bt); /*fast parameterize don't handle connent in ``*/
510
  check_ptr(yylval);
511
  ObParseCtx *parse_ctx = (ObParseCtx *)yyextra;
512
  ObScannerCtx *scanner_ctx = &(parse_ctx->scanner_ctx_);
513
  scanner_ctx->first_column_ = yylloc->first_column;
514
  prepare_literal_buffer(scanner_ctx, parse_ctx->stmt_len_ + 1, parse_ctx->mem_pool_);
515
  malloc_new_node(yylval->node, parse_ctx->mem_pool_, T_IDENT, 0);
516
  yylval->node->str_len_ = 0;
517
}
518

519
<bt>{btdouble} {
520
  check_ptr(yylval);
521
  ObParseCtx *parse_ctx = (ObParseCtx *)yyextra;
522
  ObScannerCtx *scanner_ctx = &(parse_ctx->scanner_ctx_);
523
  char *tmp_literal = scanner_ctx->tmp_literal_;
524
  tmp_literal[yylval->node->str_len_++] = '`';
525
}
526

527
<bt>{btcontent} {
528
  check_ptr(yylval);
529
  ObParseCtx *parse_ctx = (ObParseCtx *)yyextra;
530
  ObScannerCtx *scanner_ctx = &(parse_ctx->scanner_ctx_);
531
  char *tmp_literal = scanner_ctx->tmp_literal_;
532
  memmove(tmp_literal + yylval->node->str_len_, yytext, yyleng);
533
  yylval->node->str_len_ += yyleng;
534
}
535

536
<bt>{btend} {
537
  BEGIN(INITIAL);
538
  check_ptr(yylval);
539
  ObParseCtx *parse_ctx = (ObParseCtx *)yyextra;
540
  ObScannerCtx *scanner_ctx = &(parse_ctx->scanner_ctx_);
541
  char *tmp_literal = scanner_ctx->tmp_literal_;
542
  yylloc->first_column = scanner_ctx->first_column_;
543
  tmp_literal[yylval->node->str_len_] = '\0';
544

545
  char *dup_value = NULL;
546
  if (parse_ctx->is_not_utf8_connection_) {
547
    dup_value = parse_str_convert_utf8(parse_ctx->charset_info_, tmp_literal,
548
                                       parse_ctx->mem_pool_, &(yylval->node->str_len_),
549
                                       &(parse_ctx->global_errno_));
550
    check_identifier_convert_result(parse_ctx->global_errno_);
551
  } else {
552
    dup_value = parse_strndup(tmp_literal, yylval->node->str_len_ + 1, parse_ctx->mem_pool_);
553
  }
554
  check_ptr(dup_value);
555
  yylval->node->str_value_ = dup_value;
556
  return IDENT;
557
}
558

559
<bt><<EOF>> {
560
  obpl_mysql_yyerror(yylloc, yyextra, "unterminated backtick string\n");
561
  return END_P;
562
}
563

564
{mysql_compatible_comment_without_version} {
565
  //refer to src/sql/parser/sql_parser_mysql_mode.l for more info.
566
  ObParseCtx *parse_ctx = (ObParseCtx *)yyextra;
567
  parse_ctx->mysql_compatible_comment_ = true;
568
}
569

570
{mysql_compatible_comment_with_version} {
571
  ObParseCtx *parse_ctx = (ObParseCtx *)yyextra;
572
  parse_ctx->mysql_compatible_comment_ = true;
573
}
574

575
{mysql_compatible_comment_end} {
576
  ObParseCtx *parse_ctx = (ObParseCtx *)yyextra;
577
  if (parse_ctx->mysql_compatible_comment_) {
578
    parse_ctx->mysql_compatible_comment_ = false;
579
    BEGIN(INITIAL);
580
  } else {
581
    char c_ret = yytext[0];
582
    yyless(1);
583
    return c_ret;
584
  }
585
}
586

587
{c_cmt_begin} {
588
  BEGIN(in_c_comment);
589
}
590

591
<in_c_comment>{c_cmt_end} {
592
//  ((ParseResult *)yyextra)->has_encount_comment_ = true;
593
  BEGIN(INITIAL);
594
}
595

596
<in_c_comment><<EOF>>  {
597
  obpl_mysql_yyerror(yylloc, yyextra, "unterminated log_level string\n");
598
  return END_P;
599
}
600
<in_c_comment>[\n] { yylineno++; }
601
<in_c_comment>. {}
602

603
{comment} {
604
//  ((ParseResult *)yyextra)->has_encount_comment_ = true;
605
/* ignore */
606
}
607

608
{identifer} {
609
  int32_t token = mysql_sql_reserved_keyword_lookup(yytext);
610
  if (token < 0) {
611
    const NonReservedKeyword *word = NULL;
612
    if (NULL == (word = mysql_pl_non_reserved_keyword_lookup(yytext)))
613
    {
614
      token = IDENT;
615
      ParseNode *node = NULL;
616
      ObParseCtx *parse_ctx = (ObParseCtx *)yyextra;
617
      malloc_new_node(node, parse_ctx->mem_pool_, T_IDENT, 0);
618
      yylval->node = node;
619
      if (parse_ctx->is_not_utf8_connection_) {
620
        node->str_value_ = parse_str_convert_utf8(parse_ctx->charset_info_, yytext,
621
                                                  parse_ctx->mem_pool_, &(node->str_len_),
622
                                                  &(parse_ctx->global_errno_));
623
        check_identifier_convert_result(parse_ctx->global_errno_);
624
      } else {
625
        node->str_value_ = parse_strdup(yytext, parse_ctx->mem_pool_, &(node->str_len_));
626
      }
627
    } else {
628
      yylval->non_reserved_keyword = word;
629
      token = word->keyword_type;
630
    }
631
  } else {
632
    token = SQL_KEYWORD;
633
  }
634
  return token;
635
}
636

637
[-+&~|^/%*(),;.:!] { return yytext[0]; }
638

639
[ \t\r\n] { }
640
"--"[ \t].*;
641

642
"=>"    { return PARAM_ASSIGN_OPERATOR; }
643

644
<<EOF>> { return END_P; }
645
. { return yytext[0]; }
646
%%
647

648
//parser function
649
void obpl_mysql_parse_fatal_error(int32_t errcode, yyscan_t yyscanner, yyconst char *msg, ...)
650
{
651
  ObParseCtx *parse_ctx = obpl_mysql_yyget_extra(yyscanner);
652
  if (parse_ctx != NULL) {
653
    parse_ctx->global_errno_ = errcode;
654
    if (OB_LIKELY(NULL != msg)) {
655
      va_list ap;
656
      va_start(ap, msg);
657
      vsnprintf(parse_ctx->global_errmsg_, MAX_ERROR_MSG, msg, ap);
658
      va_end(ap);
659
    }
660
  }
661
  longjmp(parse_ctx->jmp_buf_, 1);//the secord param must be non-zero value
662
}
663

664
void *yyalloc(size_t bytes, void *yyscanner)
665
{
666
  void *ptr_ret = NULL;
667
  ObParseCtx *parse_ctx = yyget_extra(yyscanner);
668
  check_ptr(parse_ctx);
669
  ptr_ret = parse_malloc(bytes, parse_ctx->mem_pool_);
670
  return ptr_ret;
671
}
672

673
void *yyrealloc(void *ptr, size_t bytes, void *yyscanner)
674
{
675
  void *ptr_ret = NULL;
676
  ObParseCtx *parse_ctx = yyget_extra(yyscanner);
677
  check_ptr(parse_ctx);
678
  ptr_ret = parse_realloc(ptr, bytes, parse_ctx->mem_pool_);
679
  return ptr_ret;
680
}
681

682
void yyfree(void *ptr, void *yyscanner)
683
{
684
  (void)yyscanner;
685
  /* Do nothing -- we leave it to the garbage collector. */
686
  parse_free(ptr);
687
}
688

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.