Commit cfae1666 authored by marko@hundin.mysql.fi's avatar marko@hundin.mysql.fi

InnoDB: Handle quotes properly in the InnoDB SQL parser

parent 4da72c2e
...@@ -87,13 +87,6 @@ pars_get_lex_chars( ...@@ -87,13 +87,6 @@ pars_get_lex_chars(
int max_size); /* in: maximum number of characters which fit int max_size); /* in: maximum number of characters which fit
in the buffer */ 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. */ Called by yyparse on error. */
void void
......
This diff is collapsed.
...@@ -35,6 +35,19 @@ These instructions seem to work at least with bison-1.28 and flex-2.5.4 on ...@@ -35,6 +35,19 @@ These instructions seem to work at least with bison-1.28 and flex-2.5.4 on
Linux. 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* #define YYSTYPE que_node_t*
...@@ -45,18 +58,47 @@ Linux. ...@@ -45,18 +58,47 @@ Linux.
#include "mem0mem.h" #include "mem0mem.h"
#include "os0proc.h" #include "os0proc.h"
#define isatty(A) 0
#define malloc(A) mem_alloc(A) #define malloc(A) mem_alloc(A)
#define free(A) mem_free(A) #define free(A) mem_free(A)
#define realloc(P, A) mem_realloc(P, A, __FILE__, __LINE__) #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) #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] DIGIT [0-9]
ID [a-z_A-Z][a-z_A-Z0-9]* ID [a-z_A-Z][a-z_A-Z0-9]*
%x comment %x comment
%x quoted
%% %%
{DIGIT}+ { {DIGIT}+ {
...@@ -71,13 +113,19 @@ ID [a-z_A-Z][a-z_A-Z0-9]* ...@@ -71,13 +113,19 @@ ID [a-z_A-Z][a-z_A-Z0-9]*
return(PARS_FLOAT_LIT); return(PARS_FLOAT_LIT);
} }
"\'"[^\']*"\'" { "'" {
/* Remove the single quotes around the string */ BEGIN(quoted);
stringbuf_len = 0;
yylval = sym_tab_add_str_lit(pars_sym_tab_global, }
(byte*)yytext, <quoted>[^\']+ string_append(yytext, yyleng);
ut_strlen(yytext)); <quoted>"'"+ { string_append(yytext, yyleng / 2);
return(PARS_STR_LIT); if (yyleng % 2) {
BEGIN(INITIAL);
yylval = sym_tab_add_str_lit(
pars_sym_tab_global,
stringbuf, stringbuf_len);
return(PARS_STR_LIT);
}
} }
"NULL" { "NULL" {
...@@ -89,7 +137,7 @@ ID [a-z_A-Z][a-z_A-Z0-9]* ...@@ -89,7 +137,7 @@ ID [a-z_A-Z][a-z_A-Z0-9]*
"SQL" { "SQL" {
/* Implicit cursor name */ /* Implicit cursor name */
yylval = sym_tab_add_str_lit(pars_sym_tab_global, yylval = sym_tab_add_str_lit(pars_sym_tab_global,
(byte*)"\'SQL\'", 5); yytext, yyleng);
return(PARS_SQL_TOKEN); return(PARS_SQL_TOKEN);
} }
...@@ -485,17 +533,16 @@ ID [a-z_A-Z][a-z_A-Z0-9]* ...@@ -485,17 +533,16 @@ ID [a-z_A-Z][a-z_A-Z0-9]*
"/*" BEGIN(comment); /* eat up comment */ "/*" BEGIN(comment); /* eat up comment */
<comment>[^*\n]* <comment>[^*]*
<comment>[^*\n]*\n <comment>"*"+[^*/]*
<comment>"*"+[^*/\n]*
<comment>"*"+[^*/\n]*\n
<comment>"*"+"/" BEGIN(INITIAL); <comment>"*"+"/" BEGIN(INITIAL);
[ \t\n]+ /* eat up whitespace */ [ \t\n]+ /* eat up whitespace */
. { . {
printf("Unrecognized character: %s\n", yytext); fprintf(stderr,"Unrecognized character: %02x\n",
*yytext);
ut_error; ut_error;
......
...@@ -1707,17 +1707,6 @@ pars_get_lex_chars( ...@@ -1707,17 +1707,6 @@ pars_get_lex_chars(
pars_sym_tab_global->next_char_pos += len; 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. */ Called by yyparse on error. */
......
...@@ -127,19 +127,13 @@ sym_tab_add_str_lit( ...@@ -127,19 +127,13 @@ sym_tab_add_str_lit(
/*================*/ /*================*/
/* out: symbol table node */ /* out: symbol table node */
sym_tab_t* sym_tab, /* in: symbol table */ sym_tab_t* sym_tab, /* in: symbol table */
byte* str, /* in: string starting with a single byte* str, /* in: string with no quotes around
quote; the string literal will it */
extend to the next single quote, but
the quotes are not included in it */
ulint len) /* in: string length */ ulint len) /* in: string length */
{ {
sym_node_t* node; sym_node_t* node;
byte* data; byte* data;
ulint i;
ut_a(len > 1);
ut_a(str[0] == '\'');
node = mem_heap_alloc(sym_tab->heap, sizeof(sym_node_t)); node = mem_heap_alloc(sym_tab->heap, sizeof(sym_node_t));
node->common.type = QUE_NODE_SYMBOL; node->common.type = QUE_NODE_SYMBOL;
...@@ -151,23 +145,14 @@ sym_tab_add_str_lit( ...@@ -151,23 +145,14 @@ sym_tab_add_str_lit(
dtype_set(&(node->common.val.type), DATA_VARCHAR, DATA_ENGLISH, 0, 0); dtype_set(&(node->common.val.type), DATA_VARCHAR, DATA_ENGLISH, 0, 0);
for (i = 1;; i++) { if (len) {
ut_a(i < len); data = mem_heap_alloc(sym_tab->heap, len);
ut_memcpy(data, str, len);
if (str[i] == '\'') {
break;
}
}
if (i > 1) {
data = mem_heap_alloc(sym_tab->heap, i - 1);
ut_memcpy(data, str + 1, i - 1);
} else { } else {
data = NULL; 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->common.val_buf_size = 0;
node->prefetch_buf = NULL; node->prefetch_buf = NULL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment