diff options
author | unknown <bell@sanja.is.com.ua> | 2004-02-14 13:31:39 +0200 |
---|---|---|
committer | unknown <bell@sanja.is.com.ua> | 2004-02-14 13:31:39 +0200 |
commit | 6826a55b1da73770ce067972efafc00f9d2f6670 (patch) | |
tree | 5a43e43d6a139a343cb71c89c1209240d9287db0 /sql | |
parent | fab7113f8398ba41d5e54e32dc0b3259a6297dfc (diff) | |
parent | 4ec12a5e55d5f2db27a5c0ce93c7e74254d652a4 (diff) | |
download | mariadb-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.cc | 2 | ||||
-rw-r--r-- | sql/init.cc | 3 | ||||
-rw-r--r-- | sql/item.h | 2 | ||||
-rw-r--r-- | sql/item_func.cc | 2 | ||||
-rw-r--r-- | sql/item_sum.h | 4 | ||||
-rw-r--r-- | sql/mysql_priv.h | 2 | ||||
-rw-r--r-- | sql/sql_analyse.cc | 2 | ||||
-rw-r--r-- | sql/sql_class.h | 3 | ||||
-rw-r--r-- | sql/sql_lex.cc | 43 | ||||
-rw-r--r-- | sql/sql_parse.cc | 32 | ||||
-rw-r--r-- | sql/sql_prepare.cc | 10 | ||||
-rw-r--r-- | sql/sql_show.cc | 76 | ||||
-rw-r--r-- | sql/sql_string.cc | 2 | ||||
-rw-r--r-- | sql/sql_table.cc | 7 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 26 |
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)) |