mirror of
https://github.com/MariaDB/server.git
synced 2025-01-19 05:22:25 +01:00
InnoDB: Handle quotes properly in the InnoDB SQL parser
This commit is contained in:
parent
4da72c2eb1
commit
cfae16667e
5 changed files with 555 additions and 495 deletions
|
@ -87,13 +87,6 @@ pars_get_lex_chars(
|
|||
int max_size); /* in: maximum number of characters which fit
|
||||
in the buffer */
|
||||
/*****************************************************************
|
||||
Instructs the lexical analyzer to stop when it receives the EOF integer. */
|
||||
|
||||
int
|
||||
yywrap(void);
|
||||
/*========*/
|
||||
/* out: returns TRUE */
|
||||
/*****************************************************************
|
||||
Called by yyparse on error. */
|
||||
|
||||
void
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -35,6 +35,19 @@ These instructions seem to work at least with bison-1.28 and flex-2.5.4 on
|
|||
Linux.
|
||||
*******************************************************/
|
||||
|
||||
%option nostdinit
|
||||
%option 8bit
|
||||
%option warn
|
||||
%option pointer
|
||||
%option never-interactive
|
||||
%option nodefault
|
||||
%option noinput
|
||||
%option nounput
|
||||
%option noyywrap
|
||||
%option noyy_scan_buffer
|
||||
%option noyy_scan_bytes
|
||||
%option noyy_scan_string
|
||||
|
||||
%{
|
||||
#define YYSTYPE que_node_t*
|
||||
|
||||
|
@ -45,18 +58,47 @@ Linux.
|
|||
#include "mem0mem.h"
|
||||
#include "os0proc.h"
|
||||
|
||||
#define isatty(A) 0
|
||||
#define malloc(A) mem_alloc(A)
|
||||
#define free(A) mem_free(A)
|
||||
#define realloc(P, A) mem_realloc(P, A, __FILE__, __LINE__)
|
||||
#define exit(A) ut_a(0)
|
||||
#define exit(A) ut_error
|
||||
|
||||
#define YY_INPUT(buf, result, max_size) pars_get_lex_chars(buf, &result, max_size)
|
||||
|
||||
/* String buffer for removing quotes */
|
||||
static ulint stringbuf_len_alloc = 0; /* Allocated length */
|
||||
static ulint stringbuf_len = 0; /* Current length */
|
||||
static char* stringbuf; /* Start of buffer */
|
||||
/* Appends a string to the buffer. */
|
||||
static
|
||||
void
|
||||
string_append(
|
||||
/*==========*/
|
||||
const char* str, /* in: string to be appended */
|
||||
ulint len) /* in: length of the string */
|
||||
{
|
||||
if (stringbuf_len + len > stringbuf_len_alloc) {
|
||||
if (stringbuf_len_alloc == 0) {
|
||||
stringbuf_len_alloc++;
|
||||
}
|
||||
while (stringbuf_len + len > stringbuf_len_alloc) {
|
||||
stringbuf_len_alloc <<= 1;
|
||||
}
|
||||
stringbuf = stringbuf
|
||||
? realloc(stringbuf, stringbuf_len_alloc)
|
||||
: malloc(stringbuf_len_alloc);
|
||||
}
|
||||
|
||||
memcpy(stringbuf + stringbuf_len, str, len);
|
||||
stringbuf_len += len;
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
DIGIT [0-9]
|
||||
ID [a-z_A-Z][a-z_A-Z0-9]*
|
||||
%x comment
|
||||
%x quoted
|
||||
%%
|
||||
|
||||
{DIGIT}+ {
|
||||
|
@ -71,13 +113,19 @@ ID [a-z_A-Z][a-z_A-Z0-9]*
|
|||
return(PARS_FLOAT_LIT);
|
||||
}
|
||||
|
||||
"\'"[^\']*"\'" {
|
||||
/* Remove the single quotes around the string */
|
||||
|
||||
yylval = sym_tab_add_str_lit(pars_sym_tab_global,
|
||||
(byte*)yytext,
|
||||
ut_strlen(yytext));
|
||||
return(PARS_STR_LIT);
|
||||
"'" {
|
||||
BEGIN(quoted);
|
||||
stringbuf_len = 0;
|
||||
}
|
||||
<quoted>[^\']+ string_append(yytext, yyleng);
|
||||
<quoted>"'"+ { string_append(yytext, yyleng / 2);
|
||||
if (yyleng % 2) {
|
||||
BEGIN(INITIAL);
|
||||
yylval = sym_tab_add_str_lit(
|
||||
pars_sym_tab_global,
|
||||
stringbuf, stringbuf_len);
|
||||
return(PARS_STR_LIT);
|
||||
}
|
||||
}
|
||||
|
||||
"NULL" {
|
||||
|
@ -89,7 +137,7 @@ ID [a-z_A-Z][a-z_A-Z0-9]*
|
|||
"SQL" {
|
||||
/* Implicit cursor name */
|
||||
yylval = sym_tab_add_str_lit(pars_sym_tab_global,
|
||||
(byte*)"\'SQL\'", 5);
|
||||
yytext, yyleng);
|
||||
return(PARS_SQL_TOKEN);
|
||||
}
|
||||
|
||||
|
@ -485,17 +533,16 @@ ID [a-z_A-Z][a-z_A-Z0-9]*
|
|||
|
||||
"/*" BEGIN(comment); /* eat up comment */
|
||||
|
||||
<comment>[^*\n]*
|
||||
<comment>[^*\n]*\n
|
||||
<comment>"*"+[^*/\n]*
|
||||
<comment>"*"+[^*/\n]*\n
|
||||
<comment>[^*]*
|
||||
<comment>"*"+[^*/]*
|
||||
<comment>"*"+"/" BEGIN(INITIAL);
|
||||
|
||||
[ \t\n]+ /* eat up whitespace */
|
||||
|
||||
|
||||
. {
|
||||
printf("Unrecognized character: %s\n", yytext);
|
||||
fprintf(stderr,"Unrecognized character: %02x\n",
|
||||
*yytext);
|
||||
|
||||
ut_error;
|
||||
|
||||
|
|
|
@ -1707,17 +1707,6 @@ pars_get_lex_chars(
|
|||
pars_sym_tab_global->next_char_pos += len;
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
Instructs the lexical analyzer to stop when it receives the EOF integer. */
|
||||
|
||||
int
|
||||
yywrap(void)
|
||||
/*========*/
|
||||
/* out: returns TRUE */
|
||||
{
|
||||
return(1);
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
Called by yyparse on error. */
|
||||
|
||||
|
|
|
@ -127,19 +127,13 @@ sym_tab_add_str_lit(
|
|||
/*================*/
|
||||
/* out: symbol table node */
|
||||
sym_tab_t* sym_tab, /* in: symbol table */
|
||||
byte* str, /* in: string starting with a single
|
||||
quote; the string literal will
|
||||
extend to the next single quote, but
|
||||
the quotes are not included in it */
|
||||
byte* str, /* in: string with no quotes around
|
||||
it */
|
||||
ulint len) /* in: string length */
|
||||
{
|
||||
sym_node_t* node;
|
||||
byte* data;
|
||||
ulint i;
|
||||
|
||||
ut_a(len > 1);
|
||||
ut_a(str[0] == '\'');
|
||||
|
||||
node = mem_heap_alloc(sym_tab->heap, sizeof(sym_node_t));
|
||||
|
||||
node->common.type = QUE_NODE_SYMBOL;
|
||||
|
@ -151,23 +145,14 @@ sym_tab_add_str_lit(
|
|||
|
||||
dtype_set(&(node->common.val.type), DATA_VARCHAR, DATA_ENGLISH, 0, 0);
|
||||
|
||||
for (i = 1;; i++) {
|
||||
ut_a(i < len);
|
||||
|
||||
if (str[i] == '\'') {
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i > 1) {
|
||||
data = mem_heap_alloc(sym_tab->heap, i - 1);
|
||||
ut_memcpy(data, str + 1, i - 1);
|
||||
if (len) {
|
||||
data = mem_heap_alloc(sym_tab->heap, len);
|
||||
ut_memcpy(data, str, len);
|
||||
} else {
|
||||
data = NULL;
|
||||
}
|
||||
|
||||
dfield_set_data(&(node->common.val), data, i - 1);
|
||||
dfield_set_data(&(node->common.val), data, len);
|
||||
|
||||
node->common.val_buf_size = 0;
|
||||
node->prefetch_buf = NULL;
|
||||
|
|
Loading…
Reference in a new issue