summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <bell@sanja.is.com.ua>2004-02-14 13:31:39 +0200
committerunknown <bell@sanja.is.com.ua>2004-02-14 13:31:39 +0200
commit6826a55b1da73770ce067972efafc00f9d2f6670 (patch)
tree5a43e43d6a139a343cb71c89c1209240d9287db0 /sql
parentfab7113f8398ba41d5e54e32dc0b3259a6297dfc (diff)
parent4ec12a5e55d5f2db27a5c0ce93c7e74254d652a4 (diff)
downloadmariadb-git-6826a55b1da73770ce067972efafc00f9d2f6670.tar.gz
merge
sql/item.h: Auto merged sql/item_sum.h: Auto merged sql/sql_class.h: Auto merged sql/sql_lex.cc: Auto merged sql/sql_prepare.cc: Auto merged
Diffstat (limited to 'sql')
-rw-r--r--sql/gstream.cc2
-rw-r--r--sql/init.cc3
-rw-r--r--sql/item.h2
-rw-r--r--sql/item_func.cc2
-rw-r--r--sql/item_sum.h4
-rw-r--r--sql/mysql_priv.h2
-rw-r--r--sql/sql_analyse.cc2
-rw-r--r--sql/sql_class.h3
-rw-r--r--sql/sql_lex.cc43
-rw-r--r--sql/sql_parse.cc32
-rw-r--r--sql/sql_prepare.cc10
-rw-r--r--sql/sql_show.cc76
-rw-r--r--sql/sql_string.cc2
-rw-r--r--sql/sql_table.cc7
-rw-r--r--sql/sql_yacc.yy26
15 files changed, 140 insertions, 76 deletions
diff --git a/sql/gstream.cc b/sql/gstream.cc
index a97ed9cae03..17b85af22bd 100644
--- a/sql/gstream.cc
+++ b/sql/gstream.cc
@@ -101,7 +101,7 @@ int GTextReadStream::get_next_number(double *d)
char *endptr;
- *d = strtod(cur, &endptr);
+ *d = my_strtod(cur, &endptr);
if (endptr)
{
diff --git a/sql/init.cc b/sql/init.cc
index 033dfd72843..084db57f8aa 100644
--- a/sql/init.cc
+++ b/sql/init.cc
@@ -34,9 +34,6 @@ void unireg_init(ulong options)
current_pid=(ulong) getpid(); /* Save for later ref */
init_time(); /* Init time-functions (read zone) */
-#ifdef USE_MY_ATOF
- init_my_atof(); /* use our atof */
-#endif
#ifndef EMBEDDED_LIBRARY
my_abort_hook=unireg_abort; /* Abort with close of databases */
#endif
diff --git a/sql/item.h b/sql/item.h
index 2ad85832747..9bdde1c9847 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -449,7 +449,7 @@ class Item_real :public Item
public:
const double value;
// Item_real() :value(0) {}
- Item_real(const char *str_arg,uint length) :value(atof(str_arg))
+ Item_real(const char *str_arg,uint length) :value(my_atof(str_arg))
{
name=(char*) str_arg;
decimals=(uint8) nr_of_decimals(str_arg);
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 34a61ba0353..82ff9de4a56 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -2254,7 +2254,7 @@ double user_var_entry::val(my_bool *null_value)
case INT_RESULT:
return (double) *(longlong*) value;
case STRING_RESULT:
- return atof(value); // This is null terminated
+ return my_atof(value); // This is null terminated
case ROW_RESULT:
DBUG_ASSERT(1); // Impossible
break;
diff --git a/sql/item_sum.h b/sql/item_sum.h
index 06989f30ae5..840ed1d1f7d 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -738,7 +738,7 @@ class Item_func_group_concat : public Item_sum
enum Sumfunctype sum_func () const {return GROUP_CONCAT_FUNC;}
const char *func_name() const { return "group_concat"; }
- enum Type type() const { return SUM_FUNC_ITEM; }
+ enum Type type() const { return SUM_FUNC_ITEM; }
virtual Item_result result_type () const { return STRING_RESULT; }
void clear();
bool add();
@@ -750,7 +750,7 @@ class Item_func_group_concat : public Item_sum
double val()
{
String *res; res=val_str(&str_value);
- return res ? atof(res->c_ptr()) : 0.0;
+ return res ? my_atof(res->c_ptr()) : 0.0;
}
longlong val_int()
{
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 73cc8b9ce03..ed56924775e 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -764,6 +764,8 @@ uint find_type(TYPELIB *lib, const char *find, uint length, bool part_match);
uint check_word(TYPELIB *lib, const char *val, const char *end,
const char **end_of_word);
+bool is_keyword(const char *name, uint len);
+
#define MY_DB_OPT_FILE "db.opt"
bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create);
diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc
index 9e73e06d9c6..3c9563165fe 100644
--- a/sql/sql_analyse.cc
+++ b/sql/sql_analyse.cc
@@ -225,7 +225,7 @@ bool test_if_number(NUM_INFO *info, const char *str, uint str_len)
info->decimals++;
if (str == end)
{
- info->dval = atod(begin);
+ info->dval = my_atof(begin);
return 1;
}
}
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 93703acc97b..a3f3737e46f 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -591,8 +591,7 @@ public:
struct st_mysql_bind *client_params;
char *extra_data;
ulong extra_length;
- char *query_rest;
- uint32 query_rest_length;
+ String query_rest;
#endif
NET net; // client connection descriptor
MEM_ROOT warn_root; // For warnings and errors
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index f145a232809..7679bccebfd 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -181,6 +181,23 @@ static int find_keyword(LEX *lex, uint len, bool function)
return 0;
}
+/*
+ Check if name is a keyword
+
+ SYNOPSIS
+ is_keyword()
+ name checked name
+ len length of checked name
+
+ RETURN VALUES
+ 0 name is a keyword
+ 1 name isn't a keyword
+*/
+
+bool is_keyword(const char *name, uint len)
+{
+ return get_hash_symbol(name,len,0)!=0;
+}
/* make a copy of token before ptr and set yytoklen */
@@ -427,7 +444,6 @@ inline static uint int_token(const char *str,uint length)
return ((uchar) str[-1] <= (uchar) cmp[-1]) ? smaller : bigger;
}
-
/*
yylex remember the following states from the following yylex()
@@ -678,10 +694,9 @@ int yylex(void *arg, void *yythd)
char quote_char= c; // Used char
lex->tok_start=lex->ptr; // Skip first `
while ((c=yyGet()))
- {
-#ifdef USE_MB
- if (my_mbcharlen(cs, c) == 1)
-#endif
+ {
+ int l;
+ if ((l= my_mbcharlen(cs, c)) == 1)
{
if (c == (uchar) NAMES_SEP_CHAR)
break; /* Old .frm format can't handle this char */
@@ -695,15 +710,12 @@ int yylex(void *arg, void *yythd)
}
}
#ifdef USE_MB
- else
+ else if (l > 1)
{
- int l;
- if ((l = my_ismbchar(cs,
- (const char *)lex->ptr-1,
- (const char *)lex->end_of_query)) == 0)
- break;
lex->ptr += l-1;
}
+ else
+ break;
#endif
}
if (double_quotes)
@@ -886,8 +898,13 @@ int yylex(void *arg, void *yythd)
}
/* fall true */
case MY_LEX_EOL:
- lex->next_state=MY_LEX_END; // Mark for next loop
- return(END_OF_INPUT);
+ if (lex->ptr >= lex->end_of_query)
+ {
+ lex->next_state=MY_LEX_END; // Mark for next loop
+ return(END_OF_INPUT);
+ }
+ state=MY_LEX_CHAR;
+ break;
case MY_LEX_END:
lex->next_state=MY_LEX_END;
return(0); // We found end of input last time
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 81d6b80678d..69ee43d53d1 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -48,7 +48,6 @@
extern "C" int gethostname(char *name, int namelen);
#endif
-char *memdup_mysql(struct st_mysql *mysql, const char*data, int length);
static int check_for_max_user_connections(THD *thd, USER_CONN *uc);
static void decrease_user_connections(USER_CONN *uc);
static bool check_db_used(THD *thd,TABLE_LIST *tables);
@@ -1420,8 +1419,17 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
#ifndef EMBEDDED_LIBRARY
mysql_parse(thd, packet, length);
#else
- thd->query_rest= (char*)memdup_mysql(thd->mysql, packet, length);
- thd->query_rest_length= length;
+ /*
+ 'packet' can point inside the query_rest's buffer
+ so we have to do memmove here
+ */
+ if (thd->query_rest.length() > length)
+ {
+ memmove(thd->query_rest.c_ptr(), packet, length);
+ thd->query_rest.length(length);
+ }
+ else
+ thd->query_rest.copy(length);
break;
#endif /*EMBEDDED_LIBRARY*/
}
@@ -3854,23 +3862,7 @@ mysql_parse(THD *thd, char *inBuf, uint length)
if (query_cache_send_result_to_client(thd, inBuf, length) <= 0)
{
LEX *lex=lex_start(thd, (uchar*) inBuf, length);
- if (!yyparse((void *)thd) && ! thd->is_fatal_error &&
- /*
- If this is not a multiple query, ensure that it has been
- successfully parsed until the last character. This is to prevent
- against a wrong (too big) length passed to mysql_real_query(),
- mysql_prepare()... which can generate garbage characters at the
- end. If the query was initially multiple, found_colon will be false
- only when we are in the last query; this last query had already
- been end-spaces-stripped by alloc_query() in dispatch_command(); as
- end spaces are the only thing we accept at the end of a query, and
- they have been stripped already, here we can require that nothing
- remains after parsing.
- */
- (thd->lex->found_colon ||
- (char*)(thd->lex->ptr) == (thd->query+thd->query_length+1) ||
- /* yyerror() will show the garbage chars to the user */
- (yyerror("syntax error"), 0)))
+ if (!yyparse((void *)thd) && ! thd->is_fatal_error)
{
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (mqh_used && thd->user_connect &&
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 9be11b6154c..a3c1b5a46eb 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -947,15 +947,7 @@ bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length)
lex->safe_to_cache_query= 0;
lex->param_count= 0;
- if (yyparse((void *)thd) || thd->is_fatal_error ||
- /*
- Check for wrong (too big) length passed to mysql_prepare() resulting in
- garbage at the end of the query. There is a similar check in mysql_parse().
- */
- (!thd->lex->found_colon &&
- (char*)(thd->lex->ptr) != (thd->query+thd->query_length+1) &&
- /* yyerror() will show the garbage chars to the user */
- (yyerror("syntax error"), 1)) || send_prepare_results(stmt))
+ if (yyparse((void *)thd) || thd->is_fatal_error || send_prepare_results(stmt))
goto yyparse_err;
lex_end(lex);
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 4da2522bd3f..f076e2fe802 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -1085,8 +1085,7 @@ mysqld_dump_create_info(THD *thd, TABLE *table, int fd)
DBUG_RETURN(0);
}
-/* possible TODO: call find_keyword() from sql_lex.cc here */
-static bool require_quotes(const char *name, uint length)
+static inline const char *require_quotes(const char *name, uint length)
{
uint i, d, c;
for (i=0; i<length; i+=d)
@@ -1094,7 +1093,37 @@ static bool require_quotes(const char *name, uint length)
c=((uchar *)name)[i];
d=my_mbcharlen(system_charset_info, c);
if (d==1 && !system_charset_info->ident_map[c])
- return 1;
+ return name+i;
+ }
+ return 0;
+}
+
+/*
+ Looking for char in multibyte string
+
+ SYNOPSIS
+ look_for_char()
+ name string for looking at
+ length length of name
+ q '\'' or '\"' for looking for
+
+ RETURN VALUES
+ # pointer to found char in string
+ 0 string doesn't contain required char
+*/
+
+static inline const char *look_for_char(const char *name,
+ uint length, char q)
+{
+ const char *cur= name;
+ const char *end= cur+length;
+ uint symbol_length;
+ for (; cur<end; cur+= symbol_length)
+ {
+ char c= *cur;
+ symbol_length= my_mbcharlen(system_charset_info, c);
+ if (symbol_length==1 && c==q)
+ return cur;
}
return 0;
}
@@ -1103,21 +1132,52 @@ void
append_identifier(THD *thd, String *packet, const char *name, uint length)
{
char qtype;
+ uint part_len;
+ const char *qplace;
if (thd->variables.sql_mode & MODE_ANSI_QUOTES)
qtype= '\"';
else
qtype= '`';
- if ((thd->options & OPTION_QUOTE_SHOW_CREATE) ||
- require_quotes(name, length))
+ if (is_keyword(name,length))
{
- packet->append(&qtype, 1);
+ packet->append(&qtype, 1, system_charset_info);
packet->append(name, length, system_charset_info);
- packet->append(&qtype, 1);
+ packet->append(&qtype, 1, system_charset_info);
}
else
{
- packet->append(name, length, system_charset_info);
+ if (!(qplace= require_quotes(name, length)))
+ {
+ if (!(thd->options & OPTION_QUOTE_SHOW_CREATE))
+ packet->append(name, length, system_charset_info);
+ else
+ {
+ packet->append(&qtype, 1, system_charset_info);
+ packet->append(name, length, system_charset_info);
+ packet->append(&qtype, 1, system_charset_info);
+ }
+ }
+ else
+ {
+ packet->shrink(packet->length()+length+2);
+ packet->append(&qtype, 1, system_charset_info);
+ if (*qplace != qtype)
+ qplace= look_for_char(qplace+1,length-(qplace-name)-1,qtype);
+ while (qplace)
+ {
+ if ((part_len= qplace-name))
+ {
+ packet->append(name, part_len, system_charset_info);
+ length-= part_len;
+ }
+ packet->append(qplace, 1, system_charset_info);
+ name= qplace;
+ qplace= look_for_char(name+1,length-1,qtype);
+ }
+ packet->append(name, length, system_charset_info);
+ packet->append(&qtype, 1, system_charset_info);
+ }
}
}
diff --git a/sql/sql_string.cc b/sql/sql_string.cc
index 093b85b46b7..e76c7902210 100644
--- a/sql/sql_string.cc
+++ b/sql/sql_string.cc
@@ -453,7 +453,7 @@ bool String::append(const char *s,uint32 arg_length, CHARSET_INFO *cs)
if (!arg_length) // Default argument
if (!(arg_length= (uint32) strlen(s)))
return FALSE;
- if (str_charset->mbmaxlen > 1)
+ if (cs != str_charset && str_charset->mbmaxlen > 1)
{
uint32 add_length=arg_length * str_charset->mbmaxlen;
if (realloc(str_length+ add_length))
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 4e66154e2a2..404d2b56e06 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -877,7 +877,12 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
column->field_name);
DBUG_RETURN(-1);
}
- key_part_info->length=(uint8) length;
+ if (length > file->max_key_part_length())
+ {
+ my_error(ER_WRONG_SUB_KEY,MYF(0));
+ DBUG_RETURN(-1);
+ }
+ key_part_info->length=(uint16) length;
/* Use packed keys for long strings on the first column */
if (!(db_options & HA_OPTION_NO_PACK_KEYS) &&
(length >= KEY_DEFAULT_PACK_LENGTH &&
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index bdeaf5a0b86..0e68fcc016d 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -2152,13 +2152,13 @@ select_init:
SELECT_LEX * sel= lex->current_select;
if (sel->set_braces(1))
{
- send_error(lex->thd, ER_SYNTAX_ERROR);
+ yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
}
if (sel->linkage == UNION_TYPE &&
!sel->master_unit()->first_select()->braces)
{
- send_error(lex->thd, ER_SYNTAX_ERROR);
+ yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
}
/* select in braces, can't contain global parameters */
@@ -2174,13 +2174,13 @@ select_init2:
SELECT_LEX * sel= lex->current_select;
if (lex->current_select->set_braces(0))
{
- send_error(lex->thd, ER_SYNTAX_ERROR);
+ yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
}
if (sel->linkage == UNION_TYPE &&
sel->master_unit()->first_select()->braces)
{
- send_error(lex->thd, ER_SYNTAX_ERROR);
+ yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
}
}
@@ -2734,7 +2734,7 @@ simple_expr:
{
if ($1->type() != Item::ROW_ITEM)
{
- send_error(Lex->thd, ER_SYNTAX_ERROR);
+ yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
}
$$= new Item_func_interval((Item_row *)$1);
@@ -3070,7 +3070,7 @@ in_sum_expr:
LEX *lex= Lex;
if (lex->current_select->inc_in_sum_expr())
{
- send_error(lex->thd, ER_SYNTAX_ERROR);
+ yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
}
}
@@ -3241,8 +3241,8 @@ select_derived:
if (((int)lex->sql_command >= (int)SQLCOM_HA_OPEN &&
lex->sql_command <= (int)SQLCOM_HA_READ) ||
lex->sql_command == (int)SQLCOM_KILL)
- {
- send_error(lex->thd, ER_SYNTAX_ERROR);
+ {
+ yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
}
if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE ||
@@ -3877,7 +3877,7 @@ opt_insert_update:
for a moment */
if (Lex->sql_command != SQLCOM_INSERT)
{
- send_error(Lex->thd, ER_SYNTAX_ERROR);
+ yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
}
}
@@ -4484,7 +4484,7 @@ param_marker:
}
else
{
- yyerror("You have an error in your SQL syntax");
+ yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
}
}
@@ -5527,7 +5527,7 @@ union_list:
}
if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE)
{
- send_error(lex->thd, ER_SYNTAX_ERROR);
+ yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
}
if (mysql_new_select(lex, 0))
@@ -5627,8 +5627,8 @@ subselect_start:
if (((int)lex->sql_command >= (int)SQLCOM_HA_OPEN &&
lex->sql_command <= (int)SQLCOM_HA_READ) ||
lex->sql_command == (int)SQLCOM_KILL)
- {
- send_error(lex->thd, ER_SYNTAX_ERROR);
+ {
+ yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
}
if (mysql_new_select(Lex, 1))