mirror of
				https://github.com/MariaDB/server.git
				synced 2025-11-03 20:36:16 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			614 lines
		
	
	
	
		
			9.9 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			614 lines
		
	
	
	
		
			9.9 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
/*****************************************************************************
 | 
						|
 | 
						|
Copyright (c) 1997, 2014, Oracle and/or its affiliates. All Rights Reserved.
 | 
						|
Copyright (c) 2017, 2019, MariaDB Corporation.
 | 
						|
 | 
						|
This program is free software; you can redistribute it and/or modify it under
 | 
						|
the terms of the GNU General Public License as published by the Free Software
 | 
						|
Foundation; version 2 of the License.
 | 
						|
 | 
						|
This program is distributed in the hope that it will be useful, but WITHOUT
 | 
						|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
						|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 | 
						|
 | 
						|
You should have received a copy of the GNU General Public License along with
 | 
						|
this program; if not, write to the Free Software Foundation, Inc.,
 | 
						|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
 | 
						|
 | 
						|
*****************************************************************************/
 | 
						|
 | 
						|
/******************************************************
 | 
						|
SQL parser lexical analyzer: input file for the GNU Flex lexer generator
 | 
						|
 | 
						|
The InnoDB parser is frozen because MySQL takes care of SQL parsing.
 | 
						|
Therefore we normally keep the InnoDB parser C files as they are, and do
 | 
						|
not automatically generate them from pars0grm.y and pars0lex.l.
 | 
						|
 | 
						|
How to make the InnoDB parser and lexer C files:
 | 
						|
 | 
						|
1. Run ./make_flex.sh to generate lexer files.
 | 
						|
 | 
						|
2. Run ./make_bison.sh to generate parser files.
 | 
						|
 | 
						|
These instructions seem to work at least with bison-1.875d and flex-2.5.31 on
 | 
						|
Linux.
 | 
						|
 | 
						|
Created 12/14/1997 Heikki Tuuri
 | 
						|
*******************************************************/
 | 
						|
 | 
						|
%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
 | 
						|
%option nounistd
 | 
						|
 | 
						|
%{
 | 
						|
#define YYSTYPE que_node_t*
 | 
						|
 | 
						|
#include "univ.i"
 | 
						|
#include "pars0pars.h"
 | 
						|
#include "pars0grm.h"
 | 
						|
#include "pars0sym.h"
 | 
						|
#include "mem0mem.h"
 | 
						|
 | 
						|
#define malloc(A)	ut_malloc_nokey(A)
 | 
						|
#define free(A)		ut_free(A)
 | 
						|
#define realloc(P, A)	ut_realloc(P, A)
 | 
						|
#define exit(A) 	ut_error
 | 
						|
 | 
						|
#define YY_INPUT(buf, result, max_size) \
 | 
						|
	result = pars_get_lex_chars(buf, 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 == NULL) {
 | 
						|
		stringbuf = static_cast<char*>(malloc(1));
 | 
						|
		stringbuf_len_alloc = 1;
 | 
						|
	}
 | 
						|
 | 
						|
	if (stringbuf_len + len > stringbuf_len_alloc) {
 | 
						|
		while (stringbuf_len + len > stringbuf_len_alloc) {
 | 
						|
			stringbuf_len_alloc <<= 1;
 | 
						|
		}
 | 
						|
 | 
						|
		stringbuf = static_cast<char*>(
 | 
						|
			realloc(stringbuf, 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]*
 | 
						|
TABLE_NAME	[a-z_A-Z][@a-z_A-Z0-9]*\/(#sql-|[a-z_A-Z])[a-z_A-Z0-9]*
 | 
						|
BOUND_LIT	\:[a-z_A-Z0-9]+
 | 
						|
BOUND_ID	\$[a-z_A-Z0-9]+
 | 
						|
 | 
						|
%x comment
 | 
						|
%x quoted
 | 
						|
%x id
 | 
						|
%%
 | 
						|
 | 
						|
{DIGIT}+	{
 | 
						|
			yylval = sym_tab_add_int_lit(pars_sym_tab_global,
 | 
						|
								atoi(yytext));
 | 
						|
			return(PARS_INT_LIT);
 | 
						|
}
 | 
						|
 | 
						|
{DIGIT}+"."{DIGIT}* {
 | 
						|
			ut_error;	/* not implemented */
 | 
						|
 | 
						|
			return(PARS_FLOAT_LIT);
 | 
						|
}
 | 
						|
 | 
						|
{BOUND_LIT}	{
 | 
						|
			ulint	type;
 | 
						|
 | 
						|
			yylval = sym_tab_add_bound_lit(pars_sym_tab_global,
 | 
						|
				yytext + 1, &type);
 | 
						|
 | 
						|
			return((int) type);
 | 
						|
}
 | 
						|
 | 
						|
{BOUND_ID}	{
 | 
						|
			yylval = sym_tab_add_bound_id(pars_sym_tab_global,
 | 
						|
				yytext + 1);
 | 
						|
 | 
						|
			return(PARS_ID_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"'"		{
 | 
						|
/* Quoted character string literals are handled in an explicit
 | 
						|
start state 'quoted'.  This state is entered and the buffer for
 | 
						|
the scanned string is emptied upon encountering a starting quote.
 | 
						|
 | 
						|
In the state 'quoted', only two actions are possible (defined below). */
 | 
						|
			BEGIN(quoted);
 | 
						|
			stringbuf_len = 0;
 | 
						|
}
 | 
						|
<quoted>[^\']+	{
 | 
						|
			/* Got a sequence of characters other than "'":
 | 
						|
			append to string buffer */
 | 
						|
			string_append(yytext, yyleng);
 | 
						|
}
 | 
						|
<quoted>"'"+	{
 | 
						|
			/* Got a sequence of "'" characters:
 | 
						|
			append half of them to string buffer,
 | 
						|
			as "''" represents a single "'".
 | 
						|
			We apply truncating division,
 | 
						|
			so that "'''" will result in "'". */
 | 
						|
 | 
						|
			string_append(yytext, yyleng / 2);
 | 
						|
 | 
						|
			/* If we got an odd number of quotes, then the
 | 
						|
			last quote we got is the terminating quote.
 | 
						|
			At the end of the string, we return to the
 | 
						|
			initial start state and report the scanned
 | 
						|
			string literal. */
 | 
						|
 | 
						|
			if (yyleng % 2) {
 | 
						|
				BEGIN(INITIAL);
 | 
						|
				yylval = sym_tab_add_str_lit(
 | 
						|
					pars_sym_tab_global,
 | 
						|
					(byte*) stringbuf, stringbuf_len);
 | 
						|
				return(PARS_STR_LIT);
 | 
						|
			}
 | 
						|
}
 | 
						|
 | 
						|
\"		{
 | 
						|
/* Quoted identifiers are handled in an explicit start state 'id'.
 | 
						|
This state is entered and the buffer for the scanned string is emptied
 | 
						|
upon encountering a starting quote.
 | 
						|
 | 
						|
In the state 'id', only two actions are possible (defined below). */
 | 
						|
			BEGIN(id);
 | 
						|
			stringbuf_len = 0;
 | 
						|
}
 | 
						|
<id>[^\"]+	{
 | 
						|
			/* Got a sequence of characters other than '"':
 | 
						|
			append to string buffer */
 | 
						|
			string_append(yytext, yyleng);
 | 
						|
}
 | 
						|
<id>\"+	{
 | 
						|
			/* Got a sequence of '"' characters:
 | 
						|
			append half of them to string buffer,
 | 
						|
			as '""' represents a single '"'.
 | 
						|
			We apply truncating division,
 | 
						|
			so that '"""' will result in '"'. */
 | 
						|
 | 
						|
			string_append(yytext, yyleng / 2);
 | 
						|
 | 
						|
			/* If we got an odd number of quotes, then the
 | 
						|
			last quote we got is the terminating quote.
 | 
						|
			At the end of the string, we return to the
 | 
						|
			initial start state and report the scanned
 | 
						|
			identifier. */
 | 
						|
 | 
						|
			if (yyleng % 2) {
 | 
						|
				BEGIN(INITIAL);
 | 
						|
				yylval = sym_tab_add_id(
 | 
						|
					pars_sym_tab_global,
 | 
						|
					(byte*) stringbuf, stringbuf_len);
 | 
						|
 | 
						|
				return(PARS_ID_TOKEN);
 | 
						|
			}
 | 
						|
}
 | 
						|
 | 
						|
"NULL"		{
 | 
						|
			yylval = sym_tab_add_null_lit(pars_sym_tab_global);
 | 
						|
 | 
						|
			return(PARS_NULL_LIT);
 | 
						|
}
 | 
						|
 | 
						|
"SQL"		{
 | 
						|
			/* Implicit cursor name */
 | 
						|
			yylval = sym_tab_add_str_lit(pars_sym_tab_global,
 | 
						|
							(byte*) yytext, yyleng);
 | 
						|
			return(PARS_SQL_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"AND"		{
 | 
						|
			return(PARS_AND_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"OR"		{
 | 
						|
			return(PARS_OR_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"NOT"		{
 | 
						|
			return(PARS_NOT_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"PROCEDURE"	{
 | 
						|
			return(PARS_PROCEDURE_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"IN"		{
 | 
						|
			return(PARS_IN_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"INT"		{
 | 
						|
			return(PARS_INT_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"CHAR"		{
 | 
						|
			return(PARS_CHAR_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"IS"		{
 | 
						|
			return(PARS_IS_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"BEGIN"		{
 | 
						|
			return(PARS_BEGIN_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"END"		{
 | 
						|
			return(PARS_END_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"IF"		{
 | 
						|
			return(PARS_IF_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"THEN"		{
 | 
						|
			return(PARS_THEN_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"ELSE"		{
 | 
						|
			return(PARS_ELSE_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"ELSIF"		{
 | 
						|
			return(PARS_ELSIF_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"LOOP"		{
 | 
						|
			return(PARS_LOOP_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"WHILE"		{
 | 
						|
			return(PARS_WHILE_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"RETURN"	{
 | 
						|
			return(PARS_RETURN_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"SELECT"	{
 | 
						|
			return(PARS_SELECT_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"COUNT"		{
 | 
						|
			return(PARS_COUNT_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"FROM"		{
 | 
						|
			return(PARS_FROM_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"WHERE"		{
 | 
						|
			return(PARS_WHERE_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"FOR"		{
 | 
						|
			return(PARS_FOR_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"ORDER"		{
 | 
						|
			return(PARS_ORDER_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"BY"		{
 | 
						|
			return(PARS_BY_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"ASC"		{
 | 
						|
			return(PARS_ASC_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"DESC"		{
 | 
						|
			return(PARS_DESC_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"INSERT"	{
 | 
						|
			return(PARS_INSERT_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"INTO"		{
 | 
						|
			return(PARS_INTO_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"VALUES"	{
 | 
						|
			return(PARS_VALUES_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"UPDATE"	{
 | 
						|
			return(PARS_UPDATE_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"SET"		{
 | 
						|
			return(PARS_SET_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"DELETE"	{
 | 
						|
			return(PARS_DELETE_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"CURRENT"	{
 | 
						|
			return(PARS_CURRENT_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"OF"		{
 | 
						|
			return(PARS_OF_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"CREATE"	{
 | 
						|
			return(PARS_CREATE_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"TABLE"		{
 | 
						|
			return(PARS_TABLE_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"INDEX"		{
 | 
						|
			return(PARS_INDEX_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"UNIQUE"	{
 | 
						|
			return(PARS_UNIQUE_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"CLUSTERED"	{
 | 
						|
			return(PARS_CLUSTERED_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"ON"		{
 | 
						|
			return(PARS_ON_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"DECLARE"	{
 | 
						|
			return(PARS_DECLARE_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"CURSOR"	{
 | 
						|
			return(PARS_CURSOR_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"OPEN"	{
 | 
						|
			return(PARS_OPEN_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"FETCH"	{
 | 
						|
			return(PARS_FETCH_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"CLOSE"	{
 | 
						|
			return(PARS_CLOSE_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"NOTFOUND"	{
 | 
						|
			return(PARS_NOTFOUND_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"TO_BINARY"	{
 | 
						|
			return(PARS_TO_BINARY_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"SUBSTR"	{
 | 
						|
			return(PARS_SUBSTR_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"CONCAT"	{
 | 
						|
			return(PARS_CONCAT_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"INSTR"		{
 | 
						|
			return(PARS_INSTR_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"LENGTH"	{
 | 
						|
			return(PARS_LENGTH_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"COMMIT"	{
 | 
						|
			return(PARS_COMMIT_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"ROLLBACK"	{
 | 
						|
			return(PARS_ROLLBACK_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"WORK"		{
 | 
						|
			return(PARS_WORK_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"EXIT"		{
 | 
						|
			return(PARS_EXIT_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"FUNCTION"	{
 | 
						|
			return(PARS_FUNCTION_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"LOCK"	{
 | 
						|
			return(PARS_LOCK_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"SHARE"	{
 | 
						|
			return(PARS_SHARE_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"MODE"	{
 | 
						|
			return(PARS_MODE_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"LIKE"  {
 | 
						|
                        return(PARS_LIKE_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"BIGINT"	{
 | 
						|
			return(PARS_BIGINT_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
{ID}		{
 | 
						|
			yylval = sym_tab_add_id(pars_sym_tab_global,
 | 
						|
							(byte*) yytext,
 | 
						|
							strlen(yytext));
 | 
						|
			return(PARS_ID_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
{TABLE_NAME}	{
 | 
						|
			yylval = sym_tab_add_id(pars_sym_tab_global,
 | 
						|
							(byte*) yytext,
 | 
						|
							strlen(yytext));
 | 
						|
			return(PARS_TABLE_NAME_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
".."		{
 | 
						|
			return(PARS_DDOT_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
":="		{
 | 
						|
			return(PARS_ASSIGN_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"<="		{
 | 
						|
			return(PARS_LE_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
">="		{
 | 
						|
			return(PARS_GE_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"<>"		{
 | 
						|
			return(PARS_NE_TOKEN);
 | 
						|
}
 | 
						|
 | 
						|
"("		{
 | 
						|
 | 
						|
			return((int)(*yytext));
 | 
						|
}
 | 
						|
 | 
						|
"="		{
 | 
						|
 | 
						|
			return((int)(*yytext));
 | 
						|
}
 | 
						|
 | 
						|
">"		{
 | 
						|
 | 
						|
			return((int)(*yytext));
 | 
						|
}
 | 
						|
 | 
						|
"<"		{
 | 
						|
 | 
						|
			return((int)(*yytext));
 | 
						|
}
 | 
						|
 | 
						|
","		{
 | 
						|
 | 
						|
			return((int)(*yytext));
 | 
						|
}
 | 
						|
 | 
						|
";"		{
 | 
						|
 | 
						|
			return((int)(*yytext));
 | 
						|
}
 | 
						|
 | 
						|
")"		{
 | 
						|
 | 
						|
			return((int)(*yytext));
 | 
						|
}
 | 
						|
 | 
						|
"+" 		{
 | 
						|
 | 
						|
			return((int)(*yytext));
 | 
						|
}
 | 
						|
 | 
						|
"-"		{
 | 
						|
 | 
						|
			return((int)(*yytext));
 | 
						|
}
 | 
						|
 | 
						|
"*"		{
 | 
						|
 | 
						|
			return((int)(*yytext));
 | 
						|
}
 | 
						|
 | 
						|
"/"		{
 | 
						|
 | 
						|
			return((int)(*yytext));
 | 
						|
}
 | 
						|
 | 
						|
"%"		{
 | 
						|
 | 
						|
			return((int)(*yytext));
 | 
						|
}
 | 
						|
 | 
						|
"{"		{
 | 
						|
 | 
						|
			return((int)(*yytext));
 | 
						|
}
 | 
						|
 | 
						|
"}"		{
 | 
						|
 | 
						|
			return((int)(*yytext));
 | 
						|
}
 | 
						|
 | 
						|
"?"		{
 | 
						|
 | 
						|
			return((int)(*yytext));
 | 
						|
}
 | 
						|
 | 
						|
"/*"			BEGIN(comment); /* eat up comment */
 | 
						|
 | 
						|
<comment>[^*]*
 | 
						|
<comment>"*"+[^*/]*
 | 
						|
<comment>"*"+"/"        BEGIN(INITIAL);
 | 
						|
 | 
						|
[ \t\n]+		/* eat up whitespace */
 | 
						|
 | 
						|
 | 
						|
.		{
 | 
						|
			fprintf(stderr,"Unrecognized character: %02x\n",
 | 
						|
				*yytext);
 | 
						|
 | 
						|
			ut_error;
 | 
						|
 | 
						|
			return(0);
 | 
						|
}
 | 
						|
 | 
						|
%%
 | 
						|
 | 
						|
/**********************************************************************
 | 
						|
Release any resources used by the lexer. */
 | 
						|
void
 | 
						|
pars_lexer_close(void)
 | 
						|
/*==================*/
 | 
						|
{
 | 
						|
	yylex_destroy();
 | 
						|
	free(stringbuf);
 | 
						|
	stringbuf = NULL;
 | 
						|
	stringbuf_len_alloc = stringbuf_len = 0;
 | 
						|
}
 |