mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
BitKeeper/etc/logging_ok: auto-union sql/item.cc: Auto merged sql/item.h: Auto merged sql/mysql_priv.h: Auto merged sql/sql_acl.cc: Auto merged sql/sql_base.cc: Manual merge
This commit is contained in:
@ -26,6 +26,7 @@ bk@admin.bk
|
|||||||
bk@mysql.r18.ru
|
bk@mysql.r18.ru
|
||||||
carsten@tsort.bitbybit.dk
|
carsten@tsort.bitbybit.dk
|
||||||
davida@isil.mysql.com
|
davida@isil.mysql.com
|
||||||
|
dlenev@brandersnatch.localdomain
|
||||||
dlenev@build.mysql.com
|
dlenev@build.mysql.com
|
||||||
dlenev@mysql.com
|
dlenev@mysql.com
|
||||||
gerberb@ou800.zenez.com
|
gerberb@ou800.zenez.com
|
||||||
|
26
sql/item.cc
26
sql/item.cc
@ -103,9 +103,12 @@ void Item::print_item_w_name(String *str)
|
|||||||
|
|
||||||
Item_ident::Item_ident(const char *db_name_par,const char *table_name_par,
|
Item_ident::Item_ident(const char *db_name_par,const char *table_name_par,
|
||||||
const char *field_name_par)
|
const char *field_name_par)
|
||||||
:changed_during_fix_field(0), db_name(db_name_par),
|
:
|
||||||
table_name(table_name_par), field_name(field_name_par),
|
orig_db_name(db_name_par), orig_table_name(table_name_par),
|
||||||
depended_from(0)
|
orig_field_name(field_name_par), changed_during_fix_field(0),
|
||||||
|
db_name(db_name_par), table_name(table_name_par),
|
||||||
|
field_name(field_name_par), cached_field_index(NO_CACHED_FIELD_INDEX),
|
||||||
|
cached_table(0), depended_from(0)
|
||||||
{
|
{
|
||||||
name = (char*) field_name_par;
|
name = (char*) field_name_par;
|
||||||
}
|
}
|
||||||
@ -113,10 +116,15 @@ Item_ident::Item_ident(const char *db_name_par,const char *table_name_par,
|
|||||||
// Constructor used by Item_field & Item_ref (see Item comment)
|
// Constructor used by Item_field & Item_ref (see Item comment)
|
||||||
Item_ident::Item_ident(THD *thd, Item_ident *item)
|
Item_ident::Item_ident(THD *thd, Item_ident *item)
|
||||||
:Item(thd, item),
|
:Item(thd, item),
|
||||||
|
orig_db_name(item->orig_db_name),
|
||||||
|
orig_table_name(item->orig_table_name),
|
||||||
|
orig_field_name(item->orig_field_name),
|
||||||
changed_during_fix_field(0),
|
changed_during_fix_field(0),
|
||||||
db_name(item->db_name),
|
db_name(item->db_name),
|
||||||
table_name(item->table_name),
|
table_name(item->table_name),
|
||||||
field_name(item->field_name),
|
field_name(item->field_name),
|
||||||
|
cached_field_index(item->cached_field_index),
|
||||||
|
cached_table(item->cached_table),
|
||||||
depended_from(item->depended_from)
|
depended_from(item->depended_from)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@ -128,6 +136,9 @@ void Item_ident::cleanup()
|
|||||||
*changed_during_fix_field= this;
|
*changed_during_fix_field= this;
|
||||||
changed_during_fix_field= 0;
|
changed_during_fix_field= 0;
|
||||||
}
|
}
|
||||||
|
db_name= orig_db_name;
|
||||||
|
table_name= orig_table_name;
|
||||||
|
field_name= orig_field_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Item_ident::remove_dependence_processor(byte * arg)
|
bool Item_ident::remove_dependence_processor(byte * arg)
|
||||||
@ -309,6 +320,15 @@ Item_field::Item_field(Field *f)
|
|||||||
fixed= 1;
|
fixed= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Item_field::Item_field(THD *thd, Field *f)
|
||||||
|
:Item_ident(NullS, thd->strdup(f->table_name),
|
||||||
|
thd->strdup(f->field_name))
|
||||||
|
{
|
||||||
|
set_field(f);
|
||||||
|
collation.set(DERIVATION_IMPLICIT);
|
||||||
|
fixed= 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Constructor need to process subselect with temporary tables (see Item)
|
// Constructor need to process subselect with temporary tables (see Item)
|
||||||
Item_field::Item_field(THD *thd, Item_field *item)
|
Item_field::Item_field(THD *thd, Item_field *item)
|
||||||
:Item_ident(thd, item),
|
:Item_ident(thd, item),
|
||||||
|
27
sql/item.h
27
sql/item.h
@ -257,15 +257,37 @@ public:
|
|||||||
virtual Item_num *neg()= 0;
|
virtual Item_num *neg()= 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define NO_CACHED_FIELD_INDEX ((uint)(-1))
|
||||||
|
|
||||||
class st_select_lex;
|
class st_select_lex;
|
||||||
class Item_ident :public Item
|
class Item_ident :public Item
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
We have to store initial values of db_name, table_name and field_name
|
||||||
|
to be able to restore them during cleanup() because they can be
|
||||||
|
updated during fix_fields() to values from Field object and life-time
|
||||||
|
of those is shorter than life-time of Item_field.
|
||||||
|
*/
|
||||||
|
const char *orig_db_name;
|
||||||
|
const char *orig_table_name;
|
||||||
|
const char *orig_field_name;
|
||||||
Item **changed_during_fix_field;
|
Item **changed_during_fix_field;
|
||||||
public:
|
public:
|
||||||
const char *db_name;
|
const char *db_name;
|
||||||
const char *table_name;
|
const char *table_name;
|
||||||
const char *field_name;
|
const char *field_name;
|
||||||
|
/*
|
||||||
|
Cached value of index for this field in table->field array, used by prep.
|
||||||
|
stmts for speeding up their re-execution. Holds NO_CACHED_FIELD_INDEX
|
||||||
|
if index value is not known.
|
||||||
|
*/
|
||||||
|
uint cached_field_index;
|
||||||
|
/*
|
||||||
|
Cached pointer to table which contains this field, used for the same reason
|
||||||
|
by prep. stmt. too in case then we have not-fully qualified field.
|
||||||
|
0 - means no cached value.
|
||||||
|
*/
|
||||||
|
TABLE_LIST *cached_table;
|
||||||
st_select_lex *depended_from;
|
st_select_lex *depended_from;
|
||||||
Item_ident(const char *db_name_par,const char *table_name_par,
|
Item_ident(const char *db_name_par,const char *table_name_par,
|
||||||
const char *field_name_par);
|
const char *field_name_par);
|
||||||
@ -297,6 +319,11 @@ public:
|
|||||||
{ collation.set(DERIVATION_IMPLICIT); }
|
{ collation.set(DERIVATION_IMPLICIT); }
|
||||||
// Constructor need to process subselect with temporary tables (see Item)
|
// Constructor need to process subselect with temporary tables (see Item)
|
||||||
Item_field(THD *thd, Item_field *item);
|
Item_field(THD *thd, Item_field *item);
|
||||||
|
/*
|
||||||
|
Constructor used inside setup_wild(), ensures that field and table
|
||||||
|
names will live as long as Item_field (important in prep. stmt.)
|
||||||
|
*/
|
||||||
|
Item_field(THD *thd, Field *field);
|
||||||
Item_field(Field *field);
|
Item_field(Field *field);
|
||||||
enum Type type() const { return FIELD_ITEM; }
|
enum Type type() const { return FIELD_ITEM; }
|
||||||
bool eq(const Item *item, bool binary_cmp) const;
|
bool eq(const Item *item, bool binary_cmp) const;
|
||||||
|
@ -552,7 +552,8 @@ extern const Field *not_found_field;
|
|||||||
Field *find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
|
Field *find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
|
||||||
TABLE_LIST **where, bool report_error);
|
TABLE_LIST **where, bool report_error);
|
||||||
Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint length,
|
Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint length,
|
||||||
bool check_grant,bool allow_rowid);
|
bool check_grant,bool allow_rowid,
|
||||||
|
uint *cached_field_index_ptr);
|
||||||
#ifdef HAVE_OPENSSL
|
#ifdef HAVE_OPENSSL
|
||||||
#include <openssl/des.h>
|
#include <openssl/des.h>
|
||||||
struct st_des_keyblock
|
struct st_des_keyblock
|
||||||
|
@ -2194,8 +2194,10 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
|
|||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
while ((column = column_iter++))
|
while ((column = column_iter++))
|
||||||
{
|
{
|
||||||
|
uint unused_field_idx= NO_CACHED_FIELD_INDEX;
|
||||||
if (!find_field_in_table(thd,table,column->column.ptr(),
|
if (!find_field_in_table(thd,table,column->column.ptr(),
|
||||||
column->column.length(),0,0))
|
column->column.length(),0,0,
|
||||||
|
&unused_field_idx))
|
||||||
{
|
{
|
||||||
my_error(ER_BAD_FIELD_ERROR, MYF(0),
|
my_error(ER_BAD_FIELD_ERROR, MYF(0),
|
||||||
column->column.c_ptr(), table_list->alias);
|
column->column.c_ptr(), table_list->alias);
|
||||||
|
@ -1793,33 +1793,42 @@ bool rm_temporary_table(enum db_type base, char *path)
|
|||||||
#define WRONG_GRANT (Field*) -1
|
#define WRONG_GRANT (Field*) -1
|
||||||
|
|
||||||
Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint length,
|
Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint length,
|
||||||
bool check_grants, bool allow_rowid)
|
bool check_grants, bool allow_rowid,
|
||||||
|
uint *cached_field_index_ptr)
|
||||||
{
|
{
|
||||||
Field *field;
|
Field **field_ptr, *field;
|
||||||
if (table->name_hash.records)
|
uint cached_field_index= *cached_field_index_ptr;
|
||||||
|
|
||||||
|
/* We assume here that table->field < NO_CACHED_FIELD_INDEX = UINT_MAX */
|
||||||
|
if (cached_field_index < table->fields &&
|
||||||
|
!my_strcasecmp(system_charset_info,
|
||||||
|
table->field[cached_field_index]->field_name, name))
|
||||||
|
field_ptr= table->field + cached_field_index;
|
||||||
|
else if (table->name_hash.records)
|
||||||
|
field_ptr= (Field**)hash_search(&table->name_hash,(byte*) name,
|
||||||
|
length);
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if ((field=(Field*) hash_search(&table->name_hash,(byte*) name,
|
if (!(field_ptr= table->field))
|
||||||
length)))
|
return (Field *)0;
|
||||||
goto found;
|
for (; *field_ptr; ++field_ptr)
|
||||||
|
if (!my_strcasecmp(system_charset_info, (*field_ptr)->field_name, name))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (field_ptr && *field_ptr)
|
||||||
|
{
|
||||||
|
*cached_field_index_ptr= field_ptr - table->field;
|
||||||
|
field= *field_ptr;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Field **ptr;
|
if (!allow_rowid ||
|
||||||
if (!(ptr=table->field))
|
my_strcasecmp(system_charset_info, name, "_rowid") ||
|
||||||
return (Field *)0;
|
!(field=table->rowid_field))
|
||||||
while ((field = *ptr++))
|
return (Field*) 0;
|
||||||
{
|
|
||||||
if (!my_strcasecmp(system_charset_info, field->field_name, name))
|
|
||||||
goto found;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (allow_rowid &&
|
|
||||||
!my_strcasecmp(system_charset_info, name, "_rowid") &&
|
|
||||||
(field=table->rowid_field))
|
|
||||||
goto found;
|
|
||||||
return (Field*) 0;
|
|
||||||
|
|
||||||
found:
|
|
||||||
if (thd->set_query_id)
|
if (thd->set_query_id)
|
||||||
{
|
{
|
||||||
if (field->query_id != thd->query_id)
|
if (field->query_id != thd->query_id)
|
||||||
@ -1874,6 +1883,31 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
|
|||||||
uint length=(uint) strlen(name);
|
uint length=(uint) strlen(name);
|
||||||
char name_buff[NAME_LEN+1];
|
char name_buff[NAME_LEN+1];
|
||||||
|
|
||||||
|
|
||||||
|
if (item->cached_table)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
This shortcut is used by prepared statements. We assuming that
|
||||||
|
TABLE_LIST *tables is not changed during query execution (which
|
||||||
|
is true for all queries except RENAME but luckily RENAME doesn't
|
||||||
|
use fields...) so we can rely on reusing pointer to its member.
|
||||||
|
With this optimisation we also miss case when addition of one more
|
||||||
|
field makes some prepared query ambiguous and so erronous, but we
|
||||||
|
accept this trade off.
|
||||||
|
*/
|
||||||
|
found= find_field_in_table(thd,tables->table,name,length,
|
||||||
|
test(tables->table->grant.want_privilege),
|
||||||
|
1, &(item->cached_field_index));
|
||||||
|
|
||||||
|
if (found)
|
||||||
|
{
|
||||||
|
(*where)= tables;
|
||||||
|
if (found == WRONG_GRANT)
|
||||||
|
return (Field*) 0;
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (db && lower_case_table_names)
|
if (db && lower_case_table_names)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -1898,10 +1932,10 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
|
|||||||
Field *find=find_field_in_table(thd,tables->table,name,length,
|
Field *find=find_field_in_table(thd,tables->table,name,length,
|
||||||
test(tables->table->grant.
|
test(tables->table->grant.
|
||||||
want_privilege),
|
want_privilege),
|
||||||
1);
|
1, &(item->cached_field_index));
|
||||||
if (find)
|
if (find)
|
||||||
{
|
{
|
||||||
(*where)= tables;
|
(*where)= item->cached_table= tables;
|
||||||
if (find == WRONG_GRANT)
|
if (find == WRONG_GRANT)
|
||||||
return (Field*) 0;
|
return (Field*) 0;
|
||||||
if (db || !thd->where)
|
if (db || !thd->where)
|
||||||
@ -1955,12 +1989,12 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
|
|||||||
|
|
||||||
Field *field=find_field_in_table(thd,tables->table,name,length,
|
Field *field=find_field_in_table(thd,tables->table,name,length,
|
||||||
test(tables->table->grant.want_privilege),
|
test(tables->table->grant.want_privilege),
|
||||||
allow_rowid);
|
allow_rowid, &(item->cached_field_index));
|
||||||
if (field)
|
if (field)
|
||||||
{
|
{
|
||||||
if (field == WRONG_GRANT)
|
if (field == WRONG_GRANT)
|
||||||
return (Field*) 0;
|
return (Field*) 0;
|
||||||
(*where)= tables;
|
(*where)= item->cached_table= tables;
|
||||||
if (found)
|
if (found)
|
||||||
{
|
{
|
||||||
if (!thd->where) // Returns first found
|
if (!thd->where) // Returns first found
|
||||||
@ -2308,7 +2342,7 @@ insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name,
|
|||||||
!find_field_in_table(thd, natural_join_table, field->field_name,
|
!find_field_in_table(thd, natural_join_table, field->field_name,
|
||||||
strlen(field->field_name), 0, 0))
|
strlen(field->field_name), 0, 0))
|
||||||
{
|
{
|
||||||
Item_field *item= new Item_field(field);
|
Item_field *item= new Item_field(thd, field);
|
||||||
if (!found++)
|
if (!found++)
|
||||||
(void) it->replace(item); // Replace '*'
|
(void) it->replace(item); // Replace '*'
|
||||||
else
|
else
|
||||||
|
@ -30,11 +30,11 @@ static void fix_type_pointers(const char ***array, TYPELIB *point_to_type,
|
|||||||
static uint find_field(TABLE *form,uint start,uint length);
|
static uint find_field(TABLE *form,uint start,uint length);
|
||||||
|
|
||||||
|
|
||||||
static byte* get_field_name(Field *buff,uint *length,
|
static byte* get_field_name(Field **buff,uint *length,
|
||||||
my_bool not_used __attribute__((unused)))
|
my_bool not_used __attribute__((unused)))
|
||||||
{
|
{
|
||||||
*length= (uint) strlen(buff->field_name);
|
*length= (uint) strlen((*buff)->field_name);
|
||||||
return (byte*) buff->field_name;
|
return (byte*) (*buff)->field_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -479,7 +479,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
|
|||||||
if (outparam->timestamp_field == reg_field)
|
if (outparam->timestamp_field == reg_field)
|
||||||
outparam->timestamp_field_offset=i;
|
outparam->timestamp_field_offset=i;
|
||||||
if (use_hash)
|
if (use_hash)
|
||||||
(void) my_hash_insert(&outparam->name_hash,(byte*) *field_ptr); // Will never fail
|
(void) my_hash_insert(&outparam->name_hash,(byte*) field_ptr); // Will never fail
|
||||||
}
|
}
|
||||||
*field_ptr=0; // End marker
|
*field_ptr=0; // End marker
|
||||||
|
|
||||||
|
@ -65,7 +65,8 @@ struct st_table {
|
|||||||
handler *file;
|
handler *file;
|
||||||
Field **field; /* Pointer to fields */
|
Field **field; /* Pointer to fields */
|
||||||
Field_blob **blob_field; /* Pointer to blob fields */
|
Field_blob **blob_field; /* Pointer to blob fields */
|
||||||
HASH name_hash; /* hash of field names */
|
/* hash of field names (contains pointers to elements of field array) */
|
||||||
|
HASH name_hash;
|
||||||
byte *record[2]; /* Pointer to records */
|
byte *record[2]; /* Pointer to records */
|
||||||
byte *default_values; /* Default values for INSERT */
|
byte *default_values; /* Default values for INSERT */
|
||||||
byte *insert_values; /* used by INSERT ... UPDATE */
|
byte *insert_values; /* used by INSERT ... UPDATE */
|
||||||
|
Reference in New Issue
Block a user