mirror of
https://github.com/MariaDB/server.git
synced 2026-01-06 05:22:24 +03:00
Merge MySQL->MariaDB
* Finished Monty and Jani's merge * Some InnoDB tests still fail (because it's old xtradb code run against newer testsuite). They are expected to go after mergning with the latest xtradb.
This commit is contained in:
113
sql/sql_lex.cc
113
sql/sql_lex.cc
@@ -348,6 +348,7 @@ void lex_start(THD *thd)
|
||||
lex->nest_level=0 ;
|
||||
lex->allow_sum_func= 0;
|
||||
lex->in_sum_func= NULL;
|
||||
lex->protect_against_global_read_lock= FALSE;
|
||||
/*
|
||||
ok, there must be a better solution for this, long-term
|
||||
I tried "bzero" in the sql_yacc.yy code, but that for
|
||||
@@ -432,6 +433,16 @@ bool is_keyword(const char *name, uint len)
|
||||
return get_hash_symbol(name,len,0)!=0;
|
||||
}
|
||||
|
||||
/**
|
||||
Check if name is a sql function
|
||||
|
||||
@param name checked name
|
||||
|
||||
@return is this a native function or not
|
||||
@retval 0 name is a function
|
||||
@retval 1 name isn't a function
|
||||
*/
|
||||
|
||||
bool is_lex_native_function(const LEX_STRING *name)
|
||||
{
|
||||
DBUG_ASSERT(name != NULL);
|
||||
@@ -712,6 +723,53 @@ static inline uint int_token(const char *str,uint length)
|
||||
return ((uchar) str[-1] <= (uchar) cmp[-1]) ? smaller : bigger;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Given a stream that is advanced to the first contained character in
|
||||
an open comment, consume the comment. Optionally, if we are allowed,
|
||||
recurse so that we understand comments within this current comment.
|
||||
|
||||
At this level, we do not support version-condition comments. We might
|
||||
have been called with having just passed one in the stream, though. In
|
||||
that case, we probably want to tolerate mundane comments inside. Thus,
|
||||
the case for recursion.
|
||||
|
||||
@retval Whether EOF reached before comment is closed.
|
||||
*/
|
||||
bool consume_comment(Lex_input_stream *lip, int remaining_recursions_permitted)
|
||||
{
|
||||
reg1 uchar c;
|
||||
while (! lip->eof())
|
||||
{
|
||||
c= lip->yyGet();
|
||||
|
||||
if (remaining_recursions_permitted > 0)
|
||||
{
|
||||
if ((c == '/') && (lip->yyPeek() == '*'))
|
||||
{
|
||||
lip->yySkip(); /* Eat asterisk */
|
||||
consume_comment(lip, remaining_recursions_permitted-1);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (c == '*')
|
||||
{
|
||||
if (lip->yyPeek() == '/')
|
||||
{
|
||||
lip->yySkip(); /* Eat slash */
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (c == '\n')
|
||||
lip->yylineno++;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
MYSQLlex remember the following states from the following MYSQLlex()
|
||||
|
||||
@@ -735,12 +793,12 @@ int MYSQLlex(void *arg, void *yythd)
|
||||
uchar *state_map= cs->state_map;
|
||||
uchar *ident_map= cs->ident_map;
|
||||
|
||||
LINT_INIT(c);
|
||||
lip->yylval=yylval; // The global state
|
||||
|
||||
lip->start_token();
|
||||
state=lip->next_state;
|
||||
lip->next_state=MY_LEX_OPERATOR_OR_IDENT;
|
||||
LINT_INIT(c);
|
||||
for (;;)
|
||||
{
|
||||
switch (state) {
|
||||
@@ -1056,9 +1114,12 @@ int MYSQLlex(void *arg, void *yythd)
|
||||
}
|
||||
}
|
||||
#ifdef USE_MB
|
||||
else if (var_length < 1)
|
||||
break; // Error
|
||||
lip->skip_binary(var_length-1);
|
||||
else if (use_mb(cs))
|
||||
{
|
||||
if ((var_length= my_ismbchar(cs, lip->get_ptr() - 1,
|
||||
lip->get_end_of_query())))
|
||||
lip->skip_binary(var_length-1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (double_quotes)
|
||||
@@ -1213,6 +1274,8 @@ int MYSQLlex(void *arg, void *yythd)
|
||||
/* Reject '/' '*', since we might need to turn off the echo */
|
||||
lip->yyUnget();
|
||||
|
||||
lip->save_in_comment_state();
|
||||
|
||||
if (lip->yyPeekn(2) == '!')
|
||||
{
|
||||
lip->in_comment= DISCARD_COMMENT;
|
||||
@@ -1255,11 +1318,17 @@ int MYSQLlex(void *arg, void *yythd)
|
||||
/* Expand the content of the special comment as real code */
|
||||
lip->set_echo(TRUE);
|
||||
state=MY_LEX_START;
|
||||
break;
|
||||
break; /* Do not treat contents as a comment. */
|
||||
}
|
||||
else
|
||||
{
|
||||
comment_closed= ! consume_comment(lip, 1);
|
||||
/* version allowed to have one level of comment inside. */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Not a version comment. */
|
||||
state=MY_LEX_START;
|
||||
lip->set_echo(TRUE);
|
||||
break;
|
||||
@@ -1270,38 +1339,30 @@ int MYSQLlex(void *arg, void *yythd)
|
||||
lip->in_comment= PRESERVE_COMMENT;
|
||||
lip->yySkip(); // Accept /
|
||||
lip->yySkip(); // Accept *
|
||||
comment_closed= ! consume_comment(lip, 0);
|
||||
/* regular comments can have zero comments inside. */
|
||||
}
|
||||
/*
|
||||
Discard:
|
||||
- regular '/' '*' comments,
|
||||
- special comments '/' '*' '!' for a future version,
|
||||
by scanning until we find a closing '*' '/' marker.
|
||||
Note: There is no such thing as nesting comments,
|
||||
the first '*' '/' sequence seen will mark the end.
|
||||
|
||||
Nesting regular comments isn't allowed. The first
|
||||
'*' '/' returns the parser to the previous state.
|
||||
|
||||
/#!VERSI oned containing /# regular #/ is allowed #/
|
||||
|
||||
Inside one versioned comment, another versioned comment
|
||||
is treated as a regular discardable comment. It gets
|
||||
no special parsing.
|
||||
*/
|
||||
comment_closed= FALSE;
|
||||
while (! lip->eof())
|
||||
{
|
||||
c= lip->yyGet();
|
||||
if (c == '*')
|
||||
{
|
||||
if (lip->yyPeek() == '/')
|
||||
{
|
||||
lip->yySkip();
|
||||
comment_closed= TRUE;
|
||||
state = MY_LEX_START;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (c == '\n')
|
||||
lip->yylineno++;
|
||||
}
|
||||
|
||||
/* Unbalanced comments with a missing '*' '/' are a syntax error */
|
||||
if (! comment_closed)
|
||||
return (ABORT_SYM);
|
||||
state = MY_LEX_START; // Try again
|
||||
lip->in_comment= NO_COMMENT;
|
||||
lip->set_echo(TRUE);
|
||||
lip->restore_in_comment_state();
|
||||
break;
|
||||
case MY_LEX_END_LONG_COMMENT:
|
||||
if ((lip->in_comment != NO_COMMENT) && lip->yyPeek() == '/')
|
||||
|
||||
Reference in New Issue
Block a user