mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
MDEV-69 SET optimizer_switch = REPLACE(...) causes ER_WRONG_VALUE_FOR_VAR
find_set() in typelib.c expected a zero-terminated string include/typelib.h: disable unused flags
This commit is contained in:
@@ -35,10 +35,10 @@ extern int find_type_or_exit(const char *x, TYPELIB *typelib,
|
||||
/** makes @c find_type() require the whole name, no prefix */
|
||||
#define FIND_TYPE_NO_PREFIX (1 << 0)
|
||||
/** always implicitely on, so unused, but old code may pass it */
|
||||
#define FIND_TYPE_NO_OVERWRITE (1 << 1)
|
||||
/** makes @c find_type() accept a number */
|
||||
#define FIND_TYPE_ALLOW_NUMBER (1 << 2)
|
||||
/** makes @c find_type() treat ',' as terminator */
|
||||
#define FIND_TYPE_NO_OVERWRITE 0
|
||||
/** makes @c find_type() accept a number. Not used either */
|
||||
#define FIND_TYPE_ALLOW_NUMBER 0
|
||||
/** makes @c find_type() treat ',' and '=' as terminators */
|
||||
#define FIND_TYPE_COMMA_TERM (1 << 3)
|
||||
|
||||
extern int find_type(const char *x, const TYPELIB *typelib, unsigned int flags);
|
||||
|
@@ -52,6 +52,10 @@ set session optimizer_switch="default";
|
||||
select @@session.optimizer_switch;
|
||||
@@session.optimizer_switch
|
||||
index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off
|
||||
set optimizer_switch = replace(@@optimizer_switch, '=off', '=on');
|
||||
select @@optimizer_switch;
|
||||
@@optimizer_switch
|
||||
index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=on,mrr_cost_based=on,mrr_sort_keys=on,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on,table_elimination=on
|
||||
set global optimizer_switch=1.1;
|
||||
ERROR 42000: Incorrect argument type to variable 'optimizer_switch'
|
||||
set global optimizer_switch=1e1;
|
||||
|
@@ -34,6 +34,9 @@ select * from information_schema.session_variables where variable_name='optimize
|
||||
set session optimizer_switch="default";
|
||||
select @@session.optimizer_switch;
|
||||
|
||||
set optimizer_switch = replace(@@optimizer_switch, '=off', '=on');
|
||||
select @@optimizer_switch;
|
||||
|
||||
#
|
||||
# incorrect assignments
|
||||
#
|
||||
|
@@ -20,7 +20,8 @@
|
||||
#include <m_ctype.h>
|
||||
|
||||
|
||||
#define is_field_separator(X) ((X) == ',' || (X) == '=')
|
||||
#define is_field_separator(F, X) \
|
||||
((F & FIND_TYPE_COMMA_TERM) && ((X) == ',' || (X) == '='))
|
||||
|
||||
int find_type_with_warning(const char *x, TYPELIB *typelib, const char *option)
|
||||
{
|
||||
@@ -58,14 +59,14 @@ int find_type_or_exit(const char *x, TYPELIB *typelib, const char *option)
|
||||
/**
|
||||
Search after a string in a list of strings. Endspace in x is not compared.
|
||||
|
||||
@param x String to find
|
||||
@param x pointer to string to find
|
||||
(not necessarily zero-terminated).
|
||||
by return it'll be advanced to point to the terminator.
|
||||
@param typelib TYPELIB (struct of pointer to values + count)
|
||||
@param flags flags to tune behaviour: a combination of
|
||||
FIND_TYPE_NO_PREFIX
|
||||
FIND_TYPE_ALLOW_NUMBER
|
||||
FIND_TYPE_COMMA_TERM.
|
||||
FIND_TYPE_NO_OVERWRITE can be passed but is
|
||||
superfluous (is always implicitely on).
|
||||
@param eol a pointer to the end of the string.
|
||||
|
||||
@retval
|
||||
-1 Too many matching values
|
||||
@@ -76,17 +77,20 @@ int find_type_or_exit(const char *x, TYPELIB *typelib, const char *option)
|
||||
*/
|
||||
|
||||
|
||||
int find_type(const char *x, const TYPELIB *typelib, uint flags)
|
||||
static int find_type_eol(const char **x, const TYPELIB *typelib, uint flags,
|
||||
const char *eol)
|
||||
{
|
||||
int find,pos;
|
||||
int UNINIT_VAR(findpos); /* guarded by find */
|
||||
const char *UNINIT_VAR(termptr);
|
||||
const char *i;
|
||||
const char *j;
|
||||
DBUG_ENTER("find_type");
|
||||
DBUG_PRINT("enter",("x: '%s' lib: 0x%lx", x, (long) typelib));
|
||||
CHARSET_INFO *cs= &my_charset_latin1;
|
||||
DBUG_ENTER("find_type_eol");
|
||||
DBUG_PRINT("enter",("x: '%s' lib: 0x%lx", *x, (long) typelib));
|
||||
|
||||
DBUG_ASSERT(!(flags & ~(FIND_TYPE_NO_PREFIX | FIND_TYPE_COMMA_TERM)));
|
||||
|
||||
DBUG_ASSERT(!(flags & ~(FIND_TYPE_NO_PREFIX | FIND_TYPE_ALLOW_NUMBER |
|
||||
FIND_TYPE_NO_OVERWRITE | FIND_TYPE_COMMA_TERM)));
|
||||
if (!typelib->count)
|
||||
{
|
||||
DBUG_PRINT("exit",("no count"));
|
||||
@@ -95,43 +99,53 @@ int find_type(const char *x, const TYPELIB *typelib, uint flags)
|
||||
find=0;
|
||||
for (pos=0 ; (j=typelib->type_names[pos]) ; pos++)
|
||||
{
|
||||
for (i=x ;
|
||||
*i && (!(flags & FIND_TYPE_COMMA_TERM) || !is_field_separator(*i)) &&
|
||||
my_toupper(&my_charset_latin1,*i) ==
|
||||
my_toupper(&my_charset_latin1,*j) ; i++, j++) ;
|
||||
for (i=*x ;
|
||||
i < eol && !is_field_separator(flags, *i) &&
|
||||
my_toupper(cs, *i) == my_toupper(cs, *j) ; i++, j++) ;
|
||||
if (! *j)
|
||||
{
|
||||
while (*i == ' ')
|
||||
while (i < eol && *i == ' ')
|
||||
i++; /* skip_end_space */
|
||||
if (! *i || ((flags & FIND_TYPE_COMMA_TERM) && is_field_separator(*i)))
|
||||
if (i >= eol || is_field_separator(flags, *i))
|
||||
{
|
||||
*x= i;
|
||||
DBUG_RETURN(pos+1);
|
||||
}
|
||||
if ((!*i &&
|
||||
(!(flags & FIND_TYPE_COMMA_TERM) || !is_field_separator(*i))) &&
|
||||
}
|
||||
if ((i >= eol && !is_field_separator(flags, *i)) &&
|
||||
(!*j || !(flags & FIND_TYPE_NO_PREFIX)))
|
||||
{
|
||||
find++;
|
||||
findpos=pos;
|
||||
termptr=i;
|
||||
}
|
||||
}
|
||||
if (find == 0 && (flags & FIND_TYPE_ALLOW_NUMBER) && x[0] == '#' &&
|
||||
strend(x)[-1] == '#' &&
|
||||
(findpos=atoi(x+1)-1) >= 0 && (uint) findpos < typelib->count)
|
||||
find=1;
|
||||
else if (find == 0 || ! x[0])
|
||||
if (find == 0 || *x == eol)
|
||||
{
|
||||
DBUG_PRINT("exit",("Couldn't find type"));
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
else if (find != 1 || (flags & FIND_TYPE_NO_PREFIX))
|
||||
{
|
||||
DBUG_PRINT("exit",("Too many possybilities"));
|
||||
DBUG_PRINT("exit",("Too many possibilities"));
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
*x= termptr;
|
||||
DBUG_RETURN(findpos+1);
|
||||
} /* find_type */
|
||||
} /* find_type_eol */
|
||||
|
||||
|
||||
/**
|
||||
Search after a string in a list of strings. Endspace in x is not compared.
|
||||
|
||||
Same as find_type_eol, but for zero-terminated strings,
|
||||
and without advancing the pointer.
|
||||
*/
|
||||
int find_type(const char *x, const TYPELIB *typelib, uint flags)
|
||||
{
|
||||
return find_type_eol(&x, typelib, flags, x + strlen(x));
|
||||
}
|
||||
|
||||
/**
|
||||
Get name of type nr
|
||||
|
||||
@@ -198,7 +212,7 @@ my_ulonglong find_typeset(char *x, TYPELIB *lib, int *err)
|
||||
{
|
||||
(*err)++;
|
||||
i= x;
|
||||
while (*x && !is_field_separator(*x))
|
||||
while (*x && *x != ',')
|
||||
x++;
|
||||
if (x[0] && x[1]) /* skip separator if found */
|
||||
x++;
|
||||
@@ -283,12 +297,10 @@ static TYPELIB on_off_default_typelib= {array_elements(on_off_default_names)-1,
|
||||
>0 Offset+1 in typelib for matched name
|
||||
*/
|
||||
|
||||
static uint parse_name(const TYPELIB *lib, const char **strpos, const char *end)
|
||||
static uint parse_name(const TYPELIB *lib, const char **pos, const char *end)
|
||||
{
|
||||
const char *pos= *strpos;
|
||||
uint find= find_type(pos, lib, FIND_TYPE_COMMA_TERM);
|
||||
for (; pos != end && *pos != '=' && *pos !=',' ; pos++);
|
||||
*strpos= pos;
|
||||
uint find= find_type_eol(pos, lib,
|
||||
FIND_TYPE_COMMA_TERM | FIND_TYPE_NO_PREFIX, end);
|
||||
return find;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user