Commit 5e522f36 authored by unknown's avatar unknown
Browse files

InnoDB: Handle quotes properly in the InnoDB SQL parser


innobase/include/pars0pars.h:
  Remove dummy yywrap() function (use %noyywrap in pars0lex.l)
innobase/pars/lexyy.c:
  New version corresponding to pars0lex.l
innobase/pars/pars0lex.l:
  Add %option statements
  Add string_append()
  Allow quotes within quotes
  Simplify the patterns for matching comments
innobase/pars/pars0pars.c:
  Remove dummy yywrap() function (use %noyywrap in pars0lex.l)
innobase/pars/pars0sym.c:
  Remove quote handling from sym_tab_add_str_lit()
parent 41aa345d
Loading
Loading
Loading
Loading
+0 −7
Original line number Diff line number Diff line
@@ -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
+495 −449

File changed.

Preview size limit exceeded, changes collapsed.

+62 −15
Original line number Diff line number Diff line
@@ -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,14 +113,20 @@ 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));
"'"		{
			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"		{
			yylval = sym_tab_add_null_lit(pars_sym_tab_global);
@@ -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;

+0 −11
Original line number Diff line number Diff line
@@ -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. */

+6 −21
Original line number Diff line number Diff line
@@ -127,18 +127,12 @@ 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));

@@ -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;