diff --git a/sql/sql_class.cc b/sql/sql_class.cc index e386726f51f..b764026048a 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -90,7 +90,9 @@ extern "C" void free_user_var(user_var_entry *entry) bool Key_part_spec::operator==(const Key_part_spec& other) const { - return length == other.length && !strcmp(field_name, other.field_name); + return length == other.length && + field_name.length == other.field_name.length && + !strcmp(field_name.str, other.field_name.str); } /** diff --git a/sql/sql_class.h b/sql/sql_class.h index 310623c0d5c..4dea3acc5e7 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -145,9 +145,14 @@ typedef struct st_copy_info { class Key_part_spec :public Sql_alloc { public: - const char *field_name; + LEX_STRING field_name; uint length; - Key_part_spec(const char *name,uint len=0) :field_name(name), length(len) {} + Key_part_spec(const LEX_STRING &name, uint len) + : field_name(name), length(len) + {} + Key_part_spec(const char *name, const size_t name_len, uint len) + : length(len) + { field_name.str= (char *)name; field_name.length= name_len; } bool operator==(const Key_part_spec& other) const; /** Construct a copy of this Key_part_spec. field_name is copied @@ -200,15 +205,24 @@ public: enum Keytype type; KEY_CREATE_INFO key_create_info; List columns; - const char *name; + LEX_STRING name; bool generated; - Key(enum Keytype type_par, const char *name_arg, + Key(enum Keytype type_par, const LEX_STRING &name_arg, KEY_CREATE_INFO *key_info_arg, bool generated_arg, List &cols) :type(type_par), key_create_info(*key_info_arg), columns(cols), name(name_arg), generated(generated_arg) {} + Key(enum Keytype type_par, const char *name_arg, size_t name_len_arg, + KEY_CREATE_INFO *key_info_arg, bool generated_arg, + List &cols) + :type(type_par), key_create_info(*key_info_arg), columns(cols), + generated(generated_arg) + { + name.str= (char *)name_arg; + name.length= name_len_arg; + } Key(const Key &rhs, MEM_ROOT *mem_root); virtual ~Key() {} /* Equality comparison of keys (ignoring name) */ @@ -233,7 +247,7 @@ public: Table_ident *ref_table; List ref_columns; uint delete_opt, update_opt, match_opt; - Foreign_key(const char *name_arg, List &cols, + Foreign_key(const LEX_STRING &name_arg, List &cols, Table_ident *table, List &ref_cols, uint delete_opt_arg, uint update_opt_arg, uint match_opt_arg) :Key(FOREIGN_KEY, name_arg, &default_key_create_info, 0, cols), diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 2adbc44eb12..e588bb6deee 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -31,7 +31,13 @@ sys_var *trg_new_row_fake_var= (sys_var*) 0x01; +/** + LEX_STRING constant for null-string to be used in parser and other places. +*/ +const LEX_STRING null_lex_str= {NULL, 0}; + /* Longest standard keyword name */ + #define TOCK_NAME_LENGTH 24 /* diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 47f66faf048..a717894e359 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -951,6 +951,8 @@ extern sys_var *trg_new_row_fake_var; enum xa_option_words {XA_NONE, XA_JOIN, XA_RESUME, XA_ONE_PHASE, XA_SUSPEND, XA_FOR_MIGRATE}; +extern const LEX_STRING null_lex_str; + /* Class representing list of all tables used by statement. diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 20a0e65e27b..d9c9dda394d 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -6110,8 +6110,8 @@ bool add_field_to_list(THD *thd, LEX_STRING *field_name, enum_field_types type, if (type_modifier & PRI_KEY_FLAG) { Key *key; - lex->col_list.push_back(new Key_part_spec(field_name->str, 0)); - key= new Key(Key::PRIMARY, NullS, + lex->col_list.push_back(new Key_part_spec(*field_name, 0)); + key= new Key(Key::PRIMARY, null_lex_str, &default_key_create_info, 0, lex->col_list); lex->alter_info.key_list.push_back(key); @@ -6120,8 +6120,8 @@ bool add_field_to_list(THD *thd, LEX_STRING *field_name, enum_field_types type, if (type_modifier & (UNIQUE_FLAG | UNIQUE_KEY_FLAG)) { Key *key; - lex->col_list.push_back(new Key_part_spec(field_name->str, 0)); - key= new Key(Key::UNIQUE, NullS, + lex->col_list.push_back(new Key_part_spec(*field_name, 0)); + key= new Key(Key::UNIQUE, null_lex_str, &default_key_create_info, 0, lex->col_list); lex->alter_info.key_list.push_back(key); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index a93bfb1a562..6bfc0894d61 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2877,9 +2877,8 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, while ((key=key_iterator++)) { - DBUG_PRINT("info", ("key name: '%s' type: %d", key->name ? key->name : + DBUG_PRINT("info", ("key name: '%s' type: %d", key->name.str ? key->name.str : "(none)" , key->type)); - LEX_STRING key_name_str; if (key->type == Key::FOREIGN_KEY) { fk_key_count++; @@ -2888,7 +2887,8 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, fk_key->ref_columns.elements != fk_key->columns.elements) { my_error(ER_WRONG_FK_DEF, MYF(0), - (fk_key->name ? fk_key->name : "foreign key without name"), + (fk_key->name.str ? fk_key->name.str : + "foreign key without name"), ER(ER_KEY_REF_DO_NOT_MATCH_TABLE_REF)); DBUG_RETURN(TRUE); } @@ -2901,12 +2901,10 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, my_error(ER_TOO_MANY_KEY_PARTS,MYF(0),tmp); DBUG_RETURN(TRUE); } - key_name_str.str= (char*) key->name; - key_name_str.length= key->name ? strlen(key->name) : 0; - if (check_string_char_length(&key_name_str, "", NAME_CHAR_LEN, + if (check_string_char_length(&key->name, "", NAME_CHAR_LEN, system_charset_info, 1)) { - my_error(ER_TOO_LONG_IDENT, MYF(0), key->name); + my_error(ER_TOO_LONG_IDENT, MYF(0), key->name.str); DBUG_RETURN(TRUE); } key_iterator2.rewind (); @@ -2920,7 +2918,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, Then we do not need the generated shorter key. */ if ((key2->type != Key::FOREIGN_KEY && - key2->name != ignore_key && + key2->name.str != ignore_key && !foreign_key_prefix(key, key2))) { /* TODO: issue warning message */ @@ -2928,10 +2926,10 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, if (!key2->generated || (key->generated && key->columns.elements < key2->columns.elements)) - key->name= ignore_key; + key->name.str= ignore_key; else { - key2->name= ignore_key; + key2->name.str= ignore_key; key_parts-= key2->columns.elements; (*key_count)--; } @@ -2939,14 +2937,14 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, } } } - if (key->name != ignore_key) + if (key->name.str != ignore_key) key_parts+=key->columns.elements; else (*key_count)--; - if (key->name && !tmp_table && (key->type != Key::PRIMARY) && - !my_strcasecmp(system_charset_info,key->name,primary_key_name)) + if (key->name.str && !tmp_table && (key->type != Key::PRIMARY) && + !my_strcasecmp(system_charset_info, key->name.str, primary_key_name)) { - my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name); + my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name.str); DBUG_RETURN(TRUE); } } @@ -2969,12 +2967,12 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, uint key_length=0; Key_part_spec *column; - if (key->name == ignore_key) + if (key->name.str == ignore_key) { /* ignore redundant keys */ do key=key_iterator++; - while (key && key->name == ignore_key); + while (key && key->name.str == ignore_key); if (!key) break; } @@ -3087,22 +3085,22 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, field=0; while ((sql_field=it++) && my_strcasecmp(system_charset_info, - column->field_name, + column->field_name.str, sql_field->field_name)) field++; if (!sql_field) { - my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column->field_name); + my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column->field_name.str); DBUG_RETURN(TRUE); } while ((dup_column= cols2++) != column) { if (!my_strcasecmp(system_charset_info, - column->field_name, dup_column->field_name)) + column->field_name.str, dup_column->field_name.str)) { my_printf_error(ER_DUP_FIELDNAME, ER(ER_DUP_FIELDNAME),MYF(0), - column->field_name); + column->field_name.str); DBUG_RETURN(TRUE); } } @@ -3116,7 +3114,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, sql_field->charset->mbminlen > 1 || // ucs2 doesn't work yet (ft_key_charset && sql_field->charset != ft_key_charset)) { - my_error(ER_BAD_FT_COLUMN, MYF(0), column->field_name); + my_error(ER_BAD_FT_COLUMN, MYF(0), column->field_name.str); DBUG_RETURN(-1); } ft_key_charset=sql_field->charset; @@ -3144,7 +3142,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, { if (!(file->ha_table_flags() & HA_CAN_INDEX_BLOBS)) { - my_error(ER_BLOB_USED_AS_KEY, MYF(0), column->field_name); + my_error(ER_BLOB_USED_AS_KEY, MYF(0), column->field_name.str); DBUG_RETURN(TRUE); } if (f_is_geom(sql_field->pack_flag) && sql_field->geom_type == @@ -3152,7 +3150,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, column->length= 25; if (!column->length) { - my_error(ER_BLOB_KEY_WITHOUT_LENGTH, MYF(0), column->field_name); + my_error(ER_BLOB_KEY_WITHOUT_LENGTH, MYF(0), column->field_name.str); DBUG_RETURN(TRUE); } } @@ -3183,7 +3181,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, key_info->flags|= HA_NULL_PART_KEY; if (!(file->ha_table_flags() & HA_NULL_IN_KEY)) { - my_error(ER_NULL_COLUMN_IN_INDEX, MYF(0), column->field_name); + my_error(ER_NULL_COLUMN_IN_INDEX, MYF(0), column->field_name.str); DBUG_RETURN(TRUE); } if (key->type == Key::SPATIAL) @@ -3256,7 +3254,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, } else if (length == 0) { - my_error(ER_WRONG_KEY_COLUMN, MYF(0), column->field_name); + my_error(ER_WRONG_KEY_COLUMN, MYF(0), column->field_name.str); DBUG_RETURN(TRUE); } if (length > file->max_key_part_length() && key->type != Key::FULLTEXT) @@ -3314,7 +3312,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, key_name=primary_key_name; primary_key=1; } - else if (!(key_name = key->name)) + else if (!(key_name= key->name.str)) key_name=make_unique_key_name(sql_field->field_name, *key_info_buffer, key_info); if (check_if_keyname_exists(key_name, *key_info_buffer, key_info)) @@ -6244,6 +6242,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, } key_part_length /= key_part->field->charset()->mbmaxlen; key_parts.push_back(new Key_part_spec(cfield->field_name, + strlen(cfield->field_name), key_part_length)); } if (key_parts.elements) @@ -6273,7 +6272,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, else key_type= Key::MULTIPLE; - key= new Key(key_type, key_name, + key= new Key(key_type, key_name, strlen(key_name), &key_create_info, test(key_info->flags & HA_GENERATED_KEY), key_parts); @@ -6286,10 +6285,10 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, { if (key->type != Key::FOREIGN_KEY) new_key_list.push_back(key); - if (key->name && - !my_strcasecmp(system_charset_info,key->name,primary_key_name)) + if (key->name.str && + !my_strcasecmp(system_charset_info, key->name.str, primary_key_name)) { - my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name); + my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name.str); goto err; } } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 5a594b4a06a..907eb354e6d 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -56,8 +56,6 @@ int yylex(void *yylval, void *yythd); -const LEX_STRING null_lex_str= {0,0}; - #define yyoverflow(A,B,C,D,E,F) \ { \ ulong val= *(F); \ @@ -1147,6 +1145,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); IDENT_sys TEXT_STRING_sys TEXT_STRING_literal NCHAR_STRING opt_component key_cache_name sp_opt_label BIN_NUM label_ident TEXT_STRING_filesystem ident_or_empty + opt_constraint constraint opt_ident %type opt_table_alias @@ -1155,8 +1154,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); table_ident table_ident_nodb references xid %type - remember_name remember_end opt_ident opt_db text_or_password - opt_constraint constraint + remember_name remember_end opt_db text_or_password %type text_string opt_gconcat_separator @@ -1738,7 +1736,7 @@ create: my_parse_error(ER(ER_SYNTAX_ERROR)); MYSQL_YYABORT; } - key= new Key($2, $4.str, &lex->key_create_info, 0, + key= new Key($2, $4, &lex->key_create_info, 0, lex->col_list); if (key == NULL) MYSQL_YYABORT; @@ -4873,8 +4871,7 @@ key_def: '(' key_list ')' key_options { LEX *lex=Lex; - const char *key_name= $3 ? $3 : $1; - Key *key= new Key($2, key_name, &lex->key_create_info, 0, + Key *key= new Key($2, $3.str ? $3 : $1, &lex->key_create_info, 0, lex->col_list); if (key == NULL) MYSQL_YYABORT; @@ -4884,9 +4881,7 @@ key_def: | opt_constraint FOREIGN KEY_SYM opt_ident '(' key_list ')' references { LEX *lex=Lex; - const char *key_name= $1 ? $1 : $4; - const char *fkey_name = $4 ? $4 : key_name; - Key *key= new Foreign_key(fkey_name, lex->col_list, + Key *key= new Foreign_key($4.str ? $4 : $1, lex->col_list, $8, lex->ref_list, lex->fk_delete_opt, @@ -4895,7 +4890,7 @@ key_def: if (key == NULL) MYSQL_YYABORT; lex->alter_info.key_list.push_back(key); - key= new Key(Key::MULTIPLE, key_name, + key= new Key(Key::MULTIPLE, $1.str ? $1 : $4, &default_key_create_info, 1, lex->col_list); if (key == NULL) @@ -4925,7 +4920,7 @@ check_constraint: ; opt_constraint: - /* empty */ { $$=(char*) 0; } + /* empty */ { $$= null_lex_str; } | constraint { $$= $1; } ; @@ -5430,14 +5425,14 @@ opt_ref_list: ref_list: ref_list ',' ident { - Key_part_spec *key= new Key_part_spec($3.str); + Key_part_spec *key= new Key_part_spec($3, 0); if (key == NULL) MYSQL_YYABORT; Lex->ref_list.push_back(key); } | ident { - Key_part_spec *key= new Key_part_spec($1.str); + Key_part_spec *key= new Key_part_spec($1, 0); if (key == NULL) MYSQL_YYABORT; Lex->ref_list.push_back(key); @@ -5584,7 +5579,7 @@ key_list: key_part: ident { - $$= new Key_part_spec($1.str); + $$= new Key_part_spec($1, 0); if ($$ == NULL) MYSQL_YYABORT; } @@ -5595,15 +5590,15 @@ key_part: { my_error(ER_KEY_PART_0, MYF(0), $1.str); } - $$= new Key_part_spec($1.str,(uint) key_part_len); + $$= new Key_part_spec($1, (uint) key_part_len); if ($$ == NULL) MYSQL_YYABORT; } ; opt_ident: - /* empty */ { $$=(char*) 0; /* Default length */ } - | field_ident { $$=$1.str; } + /* empty */ { $$= null_lex_str; } + | field_ident { $$= $1; } ; opt_component: