INSERT ... UPDATE ... VALUES()
This commit is contained in:
parent
0f653b6fed
commit
784fb81426
@ -48,4 +48,12 @@ a b c
|
||||
3 4 120
|
||||
5 0 30
|
||||
8 9 60
|
||||
INSERT t1 VALUES (2,1,11), (7,4,40) ON DUPLICATE KEY UPDATE c=c+VALUES(a);
|
||||
SELECT *, VALUES(a) FROM t1;
|
||||
a b c VALUES(a)
|
||||
1 2 10 NULL
|
||||
3 4 127 NULL
|
||||
5 0 30 NULL
|
||||
8 9 60 NULL
|
||||
2 1 11 NULL
|
||||
DROP TABLE t1;
|
||||
|
@ -21,4 +21,6 @@ INSERT t1 VALUES (5,6,30), (7,4,40), (8,9,60) ON DUPLICATE KEY UPDATE c=c+100;
|
||||
SELECT * FROM t1;
|
||||
INSERT t1 SET a=5 ON DUPLICATE KEY UPDATE b=0;
|
||||
SELECT * FROM t1;
|
||||
INSERT t1 VALUES (2,1,11), (7,4,40) ON DUPLICATE KEY UPDATE c=c+VALUES(a);
|
||||
SELECT *, VALUES(a) FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
@ -5462,9 +5462,9 @@ create_field::create_field(Field *old_field,Field *orig_field)
|
||||
char buff[MAX_FIELD_WIDTH],*pos;
|
||||
String tmp(buff,sizeof(buff), charset);
|
||||
|
||||
/* Get the value from record[2] (the default value row) */
|
||||
/* Get the value from default_values */
|
||||
my_ptrdiff_t diff= (my_ptrdiff_t) (orig_field->table->rec_buff_length*2);
|
||||
orig_field->move_field(diff); // Points now at record[2]
|
||||
orig_field->move_field(diff); // Points now at default_values
|
||||
bool is_null=orig_field->is_real_null();
|
||||
orig_field->val_str(&tmp,&tmp);
|
||||
orig_field->move_field(-diff); // Back to record[0]
|
||||
|
@ -57,7 +57,7 @@ public:
|
||||
GEOM_GEOMETRYCOLLECTION = 7
|
||||
};
|
||||
enum imagetype { itRAW, itMBR};
|
||||
|
||||
|
||||
utype unireg_check;
|
||||
uint32 field_length; // Length of field
|
||||
uint16 flags;
|
||||
@ -83,7 +83,7 @@ public:
|
||||
virtual void reset_fields() {}
|
||||
virtual void set_default()
|
||||
{
|
||||
my_ptrdiff_t offset = table->default_values() - table->record[0];
|
||||
my_ptrdiff_t offset = table->default_values - table->record[0];
|
||||
memcpy(ptr, ptr + offset, pack_length());
|
||||
if (null_ptr)
|
||||
*null_ptr= ((*null_ptr & (uchar) ~null_bit) |
|
||||
|
57
sql/item.cc
57
sql/item.cc
@ -1389,8 +1389,8 @@ bool Item_default_value::fix_fields(THD *thd, struct st_table_list *table_list,
|
||||
if (!def_field)
|
||||
return 1;
|
||||
memcpy(def_field, field_arg->field, field_arg->field->size_of());
|
||||
def_field->move_field(def_field->table->default_values() -
|
||||
def_field->table->record[0]);
|
||||
def_field->move_field(def_field->table->default_values -
|
||||
def_field->table->record[0]);
|
||||
set_field(def_field);
|
||||
return 0;
|
||||
}
|
||||
@ -1407,6 +1407,59 @@ void Item_default_value::print(String *str)
|
||||
str->append(')');
|
||||
}
|
||||
|
||||
bool Item_insert_value::eq(const Item *item, bool binary_cmp) const
|
||||
{
|
||||
return item->type() == INSERT_VALUE_ITEM &&
|
||||
((Item_default_value *)item)->arg->eq(arg, binary_cmp);
|
||||
}
|
||||
|
||||
|
||||
bool Item_insert_value::fix_fields(THD *thd, struct st_table_list *table_list, Item **items)
|
||||
{
|
||||
bool res= arg->fix_fields(thd, table_list, items);
|
||||
if (res)
|
||||
return res;
|
||||
/*
|
||||
arg->type() can be only REF_ITEM or FIELD_ITEM as arg is
|
||||
a simple_ident in sql_yacc.yy
|
||||
*/
|
||||
if (arg->type() == REF_ITEM)
|
||||
{
|
||||
Item_ref *ref= (Item_ref *)arg;
|
||||
if (ref->ref[0]->type() != FIELD_ITEM)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
arg= ref->ref[0];
|
||||
}
|
||||
Item_field *field_arg= (Item_field *)arg;
|
||||
if (field_arg->field->table->insert_values)
|
||||
{
|
||||
Field *def_field= (Field*) sql_alloc(field_arg->field->size_of());
|
||||
if (!def_field)
|
||||
return 1;
|
||||
memcpy(def_field, field_arg->field, field_arg->field->size_of());
|
||||
def_field->move_field(def_field->table->insert_values -
|
||||
def_field->table->record[0]);
|
||||
set_field(def_field);
|
||||
}
|
||||
else
|
||||
{
|
||||
Field *field=field_arg->field;
|
||||
/* charset doesn't matter here, it's to avoid sigsegv only */
|
||||
set_field(new Field_null(0,0,Field::NONE,field->field_name,field->table,
|
||||
default_charset_info));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Item_insert_value::print(String *str)
|
||||
{
|
||||
str->append("VALUE(");
|
||||
arg->print(str);
|
||||
str->append(')');
|
||||
}
|
||||
|
||||
/*
|
||||
If item is a const function, calculate it and return a const item
|
||||
The original item is freed if not returned
|
||||
|
29
sql/item.h
29
sql/item.h
@ -34,13 +34,13 @@ public:
|
||||
enum Type {FIELD_ITEM, FUNC_ITEM, SUM_FUNC_ITEM, STRING_ITEM,
|
||||
INT_ITEM, REAL_ITEM, NULL_ITEM, VARBIN_ITEM,
|
||||
COPY_STR_ITEM, FIELD_AVG_ITEM, DEFAULT_VALUE_ITEM,
|
||||
PROC_ITEM,COND_ITEM, REF_ITEM, FIELD_STD_ITEM,
|
||||
FIELD_VARIANCE_ITEM, CONST_ITEM,
|
||||
PROC_ITEM,COND_ITEM, REF_ITEM, FIELD_STD_ITEM,
|
||||
FIELD_VARIANCE_ITEM, INSERT_VALUE_ITEM,
|
||||
SUBSELECT_ITEM, ROW_ITEM, CACHE_ITEM};
|
||||
|
||||
enum cond_result { COND_UNDEF,COND_OK,COND_TRUE,COND_FALSE };
|
||||
enum coercion { COER_COERCIBLE=3, COER_IMPLICIT=2,
|
||||
COER_NOCOLL=1, COER_EXPLICIT=0 };
|
||||
enum coercion { COER_COERCIBLE=3, COER_IMPLICIT=2,
|
||||
COER_NOCOLL=1, COER_EXPLICIT=0 };
|
||||
|
||||
String str_value; /* used to store value */
|
||||
my_string name; /* Name from select */
|
||||
@ -201,6 +201,7 @@ public:
|
||||
bool is_null() { return field->is_null(); }
|
||||
Item *get_tmp_table_item(THD *thd);
|
||||
friend class Item_default_value;
|
||||
friend class Item_insert_value;
|
||||
};
|
||||
|
||||
class Item_null :public Item
|
||||
@ -734,7 +735,7 @@ public:
|
||||
Item *arg;
|
||||
Item_default_value() :
|
||||
Item_field((const char *)NULL, (const char *)NULL, (const char *)NULL), arg(NULL) {}
|
||||
Item_default_value(Item *a) :
|
||||
Item_default_value(Item *a) :
|
||||
Item_field((const char *)NULL, (const char *)NULL, (const char *)NULL), arg(a) {}
|
||||
enum Type type() const { return DEFAULT_VALUE_ITEM; }
|
||||
bool eq(const Item *item, bool binary_cmp) const;
|
||||
@ -754,6 +755,24 @@ public:
|
||||
table_map used_tables() const { return (table_map)0L; }
|
||||
};
|
||||
|
||||
class Item_insert_value : public Item_field
|
||||
{
|
||||
public:
|
||||
Item *arg;
|
||||
Item_insert_value(Item *a) :
|
||||
Item_field((const char *)NULL, (const char *)NULL, (const char *)NULL), arg(a) {}
|
||||
bool eq(const Item *item, bool binary_cmp) const;
|
||||
bool fix_fields(THD *, struct st_table_list *, Item **);
|
||||
void set_outer_resolving() { arg->set_outer_resolving(); }
|
||||
void print(String *str);
|
||||
virtual bool basic_const_item() const { return true; }
|
||||
int save_in_field(Field *field, bool no_conversions)
|
||||
{
|
||||
return Item_field::save_in_field(field, no_conversions);
|
||||
}
|
||||
table_map used_tables() const { return (table_map)0L; }
|
||||
};
|
||||
|
||||
class Item_cache: public Item
|
||||
{
|
||||
table_map used_table_map;
|
||||
|
@ -993,7 +993,7 @@ int dump_leaf(byte* key, uint32 count __attribute__((unused)),
|
||||
int error;
|
||||
/*
|
||||
The first item->rec_offset bytes are taken care of with
|
||||
restore_record(table,2) in setup()
|
||||
restore_record(table,default_values) in setup()
|
||||
*/
|
||||
memcpy(buf + item->rec_offset, key, item->tree->size_of_element);
|
||||
if ((error = item->table->file->write_row(buf)))
|
||||
@ -1075,7 +1075,7 @@ bool Item_sum_count_distinct::setup(THD *thd)
|
||||
void* cmp_arg;
|
||||
|
||||
// to make things easier for dump_leaf if we ever have to dump to MyISAM
|
||||
restore_record(table,2);
|
||||
restore_record(table,default_values);
|
||||
|
||||
if (table->fields == 1)
|
||||
{
|
||||
|
@ -1281,7 +1281,7 @@ static bool update_user_table(THD *thd, const char *host, const char *user,
|
||||
my_error(ER_PASSWORD_NO_MATCH,MYF(0)); /* purecov: deadcode */
|
||||
DBUG_RETURN(1); /* purecov: deadcode */
|
||||
}
|
||||
store_record(table,1);
|
||||
store_record(table,record[1]);
|
||||
table->field[2]->store(new_password,(uint) strlen(new_password), &my_charset_latin1);
|
||||
if ((error=table->file->update_row(table->record[1],table->record[0])))
|
||||
{
|
||||
@ -1372,7 +1372,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
|
||||
goto end;
|
||||
}
|
||||
old_row_exists = 0;
|
||||
restore_record(table,2); // cp empty row from record[2]
|
||||
restore_record(table,default_values); // cp empty row from default_values
|
||||
table->field[0]->store(combo.host.str,combo.host.length, &my_charset_latin1);
|
||||
table->field[1]->store(combo.user.str,combo.user.length, &my_charset_latin1);
|
||||
table->field[2]->store(password,(uint) strlen(password), &my_charset_latin1);
|
||||
@ -1380,7 +1380,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
|
||||
else
|
||||
{
|
||||
old_row_exists = 1;
|
||||
store_record(table,1); // Save copy for update
|
||||
store_record(table,record[1]); // Save copy for update
|
||||
if (combo.password.str) // If password given
|
||||
table->field[2]->store(password,(uint) strlen(password), &my_charset_latin1);
|
||||
}
|
||||
@ -1455,7 +1455,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
|
||||
We should NEVER delete from the user table, as a uses can still
|
||||
use mysqld even if he doesn't have any privileges in the user table!
|
||||
*/
|
||||
if (cmp_record(table,1) &&
|
||||
if (cmp_record(table,record[1]) &&
|
||||
(error=table->file->update_row(table->record[1],table->record[0])))
|
||||
{ // This should never happen
|
||||
table->file->print_error(error,MYF(0)); /* purecov: deadcode */
|
||||
@ -1539,7 +1539,7 @@ static int replace_db_table(TABLE *table, const char *db,
|
||||
goto abort;
|
||||
}
|
||||
old_row_exists = 0;
|
||||
restore_record(table,2); // cp empty row from record[2]
|
||||
restore_record(table,default_values); // cp empty row from default_values
|
||||
table->field[0]->store(combo.host.str,combo.host.length, &my_charset_latin1);
|
||||
table->field[1]->store(db,(uint) strlen(db), &my_charset_latin1);
|
||||
table->field[2]->store(combo.user.str,combo.user.length, &my_charset_latin1);
|
||||
@ -1547,7 +1547,7 @@ static int replace_db_table(TABLE *table, const char *db,
|
||||
else
|
||||
{
|
||||
old_row_exists = 1;
|
||||
store_record(table,1);
|
||||
store_record(table,record[1]);
|
||||
}
|
||||
|
||||
store_rights=get_rights_for_db(rights);
|
||||
@ -1827,7 +1827,7 @@ static int replace_column_table(GRANT_TABLE *g_t,
|
||||
continue; /* purecov: inspected */
|
||||
}
|
||||
old_row_exists = 0;
|
||||
restore_record(table,2); // Get empty record
|
||||
restore_record(table,default_values); // Get empty record
|
||||
key_restore(table,key,0,key_length);
|
||||
table->field[4]->store(xx->column.ptr(),xx->column.length(), &my_charset_latin1);
|
||||
}
|
||||
@ -1841,7 +1841,7 @@ static int replace_column_table(GRANT_TABLE *g_t,
|
||||
else
|
||||
privileges |= tmp;
|
||||
old_row_exists = 1;
|
||||
store_record(table,1); // copy original row
|
||||
store_record(table,record[1]); // copy original row
|
||||
}
|
||||
|
||||
table->field[6]->store((longlong) get_rights_for_column(privileges));
|
||||
@ -1895,7 +1895,7 @@ static int replace_column_table(GRANT_TABLE *g_t,
|
||||
{
|
||||
ulong privileges = (ulong) table->field[6]->val_int();
|
||||
privileges=fix_rights_for_column(privileges);
|
||||
store_record(table,1);
|
||||
store_record(table,record[1]);
|
||||
|
||||
if (privileges & rights) // is in this record the priv to be revoked ??
|
||||
{
|
||||
@ -1970,12 +1970,12 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
|
||||
DBUG_RETURN(-1); /* purecov: deadcode */
|
||||
}
|
||||
|
||||
restore_record(table,2); // Get empty record
|
||||
restore_record(table,default_values); // Get empty record
|
||||
table->field[0]->store(combo.host.str,combo.host.length, &my_charset_latin1);
|
||||
table->field[1]->store(db,(uint) strlen(db), &my_charset_latin1);
|
||||
table->field[2]->store(combo.user.str,combo.user.length, &my_charset_latin1);
|
||||
table->field[3]->store(table_name,(uint) strlen(table_name), &my_charset_latin1);
|
||||
store_record(table,1); // store at pos 1
|
||||
store_record(table,record[1]); // store at pos 1
|
||||
|
||||
if (table->file->index_read_idx(table->record[0],0,
|
||||
(byte*) table->field[0]->ptr,0,
|
||||
@ -1995,7 +1995,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
|
||||
DBUG_RETURN(-1); /* purecov: deadcode */
|
||||
}
|
||||
old_row_exists = 0;
|
||||
restore_record(table,1); // Get saved record
|
||||
restore_record(table,record[1]); // Get saved record
|
||||
}
|
||||
|
||||
store_table_rights= get_rights_for_table(rights);
|
||||
@ -2003,7 +2003,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
|
||||
if (old_row_exists)
|
||||
{
|
||||
ulong j,k;
|
||||
store_record(table,1);
|
||||
store_record(table,record[1]);
|
||||
j = (ulong) table->field[6]->val_int();
|
||||
k = (ulong) table->field[7]->val_int();
|
||||
|
||||
|
@ -184,6 +184,15 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
|
||||
thd->proc_info="init";
|
||||
thd->used_tables=0;
|
||||
values= its++;
|
||||
|
||||
if (duplic == DUP_UPDATE && !table->insert_values)
|
||||
{
|
||||
/* it should be allocated before Item::fix_fields() */
|
||||
table->insert_values=alloc_root(&table->mem_root, table->rec_buff_length);
|
||||
if (!table->insert_values)
|
||||
goto abort;
|
||||
}
|
||||
|
||||
if (check_insert_fields(thd,table,fields,*values,1) ||
|
||||
setup_tables(insert_table_list) ||
|
||||
setup_fields(thd, 0, insert_table_list, *values, 0, 0, 0) ||
|
||||
@ -248,7 +257,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
|
||||
{
|
||||
if (fields.elements || !value_count)
|
||||
{
|
||||
restore_record(table,2); // Get empty record
|
||||
restore_record(table,default_values); // Get empty record
|
||||
if (fill_record(fields,*values)|| thd->net.report_error ||
|
||||
check_null_fields(thd,table))
|
||||
{
|
||||
@ -264,9 +273,9 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
|
||||
else
|
||||
{
|
||||
if (thd->used_tables) // Column used in values()
|
||||
restore_record(table,2); // Get empty record
|
||||
restore_record(table,default_values); // Get empty record
|
||||
else
|
||||
table->record[0][0]=table->record[2][0]; // Fix delete marker
|
||||
table->record[0][0]=table->default_values[0]; // Fix delete marker
|
||||
if (fill_record(table->field,*values) || thd->net.report_error)
|
||||
{
|
||||
if (values_list.elements != 1 && ! thd->net.report_error)
|
||||
@ -333,7 +342,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
|
||||
thd->insert_id(id); // For update log
|
||||
else if (table->next_number_field)
|
||||
id=table->next_number_field->val_int(); // Return auto_increment value
|
||||
|
||||
|
||||
transactional_table= table->file->has_transactions();
|
||||
log_delayed= (transactional_table || table->tmp_table);
|
||||
if ((info.copied || info.deleted) && (error <= 0 || !transactional_table))
|
||||
@ -383,7 +392,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
|
||||
char buff[160];
|
||||
if (duplic == DUP_IGNORE)
|
||||
sprintf(buff,ER(ER_INSERT_INFO),info.records,
|
||||
(lock_type == TL_WRITE_DELAYED) ? 0 :
|
||||
(lock_type == TL_WRITE_DELAYED) ? 0 :
|
||||
info.records-info.copied,
|
||||
thd->cuted_fields);
|
||||
else
|
||||
@ -392,12 +401,14 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
|
||||
::send_ok(thd,info.copied+info.deleted,(ulonglong)id,buff);
|
||||
}
|
||||
free_underlaid_joins(thd, &thd->lex.select_lex);
|
||||
table->insert_values=0;
|
||||
DBUG_RETURN(0);
|
||||
|
||||
abort:
|
||||
if (lock_type == TL_WRITE_DELAYED)
|
||||
end_delayed_insert(thd);
|
||||
free_underlaid_joins(thd, &thd->lex.select_lex);
|
||||
table->insert_values=0;
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
|
||||
@ -482,7 +493,8 @@ int write_record(TABLE *table,COPY_INFO *info)
|
||||
that matches, is updated. If update causes a conflict again,
|
||||
an error is returned
|
||||
*/
|
||||
restore_record(table,1);
|
||||
store_record(table,insert_values);
|
||||
restore_record(table,record[1]);
|
||||
if (fill_record(*info->update_fields,*info->update_values))
|
||||
goto err;
|
||||
if ((error=table->file->update_row(table->record[1],table->record[0])))
|
||||
@ -1349,7 +1361,7 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
|
||||
if (check_insert_fields(thd,table,*fields,values,1))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
restore_record(table,2); // Get empty record
|
||||
restore_record(table,default_values); // Get empty record
|
||||
table->next_number_field=table->found_next_number_field;
|
||||
thd->count_cuted_fields=1; // calc cuted fields
|
||||
thd->cuted_fields=0;
|
||||
@ -1480,7 +1492,7 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
|
||||
}
|
||||
table->next_number_field=table->found_next_number_field;
|
||||
|
||||
restore_record(table,2); // Get empty record
|
||||
restore_record(table,default_values); // Get empty record
|
||||
thd->count_cuted_fields=1; // count warnings
|
||||
thd->cuted_fields=0;
|
||||
if (info.handle_duplicates == DUP_IGNORE ||
|
||||
|
@ -238,7 +238,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
|
||||
lf_info.log_delayed= log_delayed;
|
||||
read_info.set_io_cache_arg((void*) &lf_info);
|
||||
}
|
||||
restore_record(table,2);
|
||||
restore_record(table,default_values);
|
||||
|
||||
thd->count_cuted_fields=1; /* calc cuted fields */
|
||||
thd->cuted_fields=0L;
|
||||
|
@ -4376,7 +4376,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
|
||||
if (!(table->record[0]= (byte *) my_malloc(alloc_length*3, MYF(MY_WME))))
|
||||
goto err;
|
||||
table->record[1]= table->record[0]+alloc_length;
|
||||
table->record[2]= table->record[1]+alloc_length;
|
||||
table->default_values= table->record[1]+alloc_length;
|
||||
}
|
||||
copy_func[0]=0; // End marker
|
||||
|
||||
@ -4450,7 +4450,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
|
||||
|
||||
param->copy_field_end=copy;
|
||||
param->recinfo=recinfo;
|
||||
store_record(table,2); // Make empty default record
|
||||
store_record(table,default_values); // Make empty default record
|
||||
|
||||
if (thd->variables.tmp_table_size == ~(ulong) 0) // No limit
|
||||
table->max_rows= ~(ha_rows) 0;
|
||||
@ -5053,7 +5053,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
|
||||
|
||||
if (!found && on_expr)
|
||||
{ // OUTER JOIN
|
||||
restore_record(join_tab->table,2); // Make empty record
|
||||
restore_record(join_tab->table,default_values); // Make empty record
|
||||
mark_as_null_row(join_tab->table); // For group by without error
|
||||
if (!select_cond || select_cond->val_int())
|
||||
{
|
||||
@ -5199,10 +5199,10 @@ join_read_system(JOIN_TAB *tab)
|
||||
empty_record(table); // Make empty record
|
||||
return -1;
|
||||
}
|
||||
store_record(table,1);
|
||||
store_record(table,record[1]);
|
||||
}
|
||||
else if (!table->status) // Only happens with left join
|
||||
restore_record(table,1); // restore old record
|
||||
restore_record(table,record[1]); // restore old record
|
||||
table->null_row=0;
|
||||
return table->status ? -1 : 0;
|
||||
}
|
||||
@ -5239,12 +5239,12 @@ join_read_const(JOIN_TAB *tab)
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
store_record(table,1);
|
||||
store_record(table,record[1]);
|
||||
}
|
||||
else if (!(table->status & ~STATUS_NULL_ROW)) // Only happens with left join
|
||||
{
|
||||
table->status=0;
|
||||
restore_record(table,1); // restore old record
|
||||
restore_record(table,record[1]); // restore old record
|
||||
}
|
||||
table->null_row=0;
|
||||
return table->status ? -1 : 0;
|
||||
@ -5841,7 +5841,7 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
|
||||
join->tmp_table_param.group_buff,0,
|
||||
HA_READ_KEY_EXACT))
|
||||
{ /* Update old record */
|
||||
restore_record(table,1);
|
||||
restore_record(table,record[1]);
|
||||
update_tmptable_sum_func(join->sum_funcs,table);
|
||||
if ((error=table->file->update_row(table->record[1],
|
||||
table->record[0])))
|
||||
@ -5910,7 +5910,7 @@ end_unique_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
|
||||
table->file->print_error(error,MYF(0)); /* purecov: inspected */
|
||||
DBUG_RETURN(-1); /* purecov: inspected */
|
||||
}
|
||||
restore_record(table,1);
|
||||
restore_record(table,record[1]);
|
||||
update_tmptable_sum_func(join->sum_funcs,table);
|
||||
if ((error=table->file->update_row(table->record[1],
|
||||
table->record[0])))
|
||||
|
@ -694,7 +694,7 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild,
|
||||
if (protocol->send_records_num(&field_list, (ulonglong)file->records) ||
|
||||
protocol->send_fields(&field_list,0))
|
||||
DBUG_RETURN(1);
|
||||
restore_record(table,2); // Get empty record
|
||||
restore_record(table,default_values); // Get empty record
|
||||
|
||||
Field **ptr,*field;
|
||||
String *packet= &thd->packet;
|
||||
@ -959,7 +959,7 @@ mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild)
|
||||
!wild_case_compare(system_charset_info, field->field_name,wild))
|
||||
field_list.push_back(new Item_field(field));
|
||||
}
|
||||
restore_record(table,2); // Get empty record
|
||||
restore_record(table,default_values); // Get empty record
|
||||
if (thd->protocol->send_fields(&field_list,2))
|
||||
DBUG_VOID_RETURN;
|
||||
net_flush(&thd->net);
|
||||
@ -1041,7 +1041,7 @@ store_create_info(THD *thd, TABLE *table, String *packet)
|
||||
DBUG_ENTER("store_create_info");
|
||||
DBUG_PRINT("enter",("table: %s",table->real_name));
|
||||
|
||||
restore_record(table,2); // Get empty record
|
||||
restore_record(table,default_values); // Get empty record
|
||||
|
||||
List<Item> field_list;
|
||||
char tmp[MAX_FIELD_WIDTH];
|
||||
|
@ -1762,7 +1762,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
}
|
||||
|
||||
/* Full alter table */
|
||||
restore_record(table,2); // Empty record for DEFAULT
|
||||
restore_record(table,default_values); // Empty record for DEFAULT
|
||||
List_iterator<Alter_drop> drop_it(drop_list);
|
||||
List_iterator<create_field> def_it(fields);
|
||||
List_iterator<Alter_column> alter_it(alter_list);
|
||||
|
@ -429,7 +429,7 @@ int mysql_create_function(THD *thd,udf_func *udf)
|
||||
if (!(table = open_ltable(thd,&tables,TL_WRITE)))
|
||||
goto err;
|
||||
|
||||
restore_record(table,2); // Get default values for fields
|
||||
restore_record(table,default_values); // Get default values for fields
|
||||
table->field[0]->store(u_d->name.str, u_d->name.length, system_charset_info);
|
||||
table->field[1]->store((longlong) u_d->returns);
|
||||
table->field[2]->store(u_d->dl,(uint) strlen(u_d->dl), system_charset_info);
|
||||
|
@ -30,7 +30,7 @@ static bool safe_update_on_fly(JOIN_TAB *join_tab, List<Item> *fields);
|
||||
static bool compare_record(TABLE *table, ulong query_id)
|
||||
{
|
||||
if (!table->blob_fields)
|
||||
return cmp_record(table,1);
|
||||
return cmp_record(table,record[1]);
|
||||
/* Compare null bits */
|
||||
if (memcmp(table->null_flags,
|
||||
table->null_flags+table->rec_buff_length,
|
||||
@ -288,7 +288,7 @@ int mysql_update(THD *thd,
|
||||
{
|
||||
if (!(select && select->skipp_record()))
|
||||
{
|
||||
store_record(table,1);
|
||||
store_record(table,record[1]);
|
||||
if (fill_record(fields,values) || thd->net.report_error)
|
||||
break; /* purecov: inspected */
|
||||
found++;
|
||||
@ -731,7 +731,7 @@ bool multi_update::send_data(List<Item> ¬_used_values)
|
||||
if (table == table_to_update)
|
||||
{
|
||||
table->status|= STATUS_UPDATED;
|
||||
store_record(table,1);
|
||||
store_record(table,record[1]);
|
||||
if (fill_record(*fields_for_table[offset], *values_for_table[offset]))
|
||||
DBUG_RETURN(1);
|
||||
found++;
|
||||
@ -863,7 +863,7 @@ int multi_update::do_updates(bool from_send_error)
|
||||
if ((local_error= table->file->rnd_pos(table->record[0], ref_pos)))
|
||||
goto err;
|
||||
table->status|= STATUS_UPDATED;
|
||||
store_record(table,1);
|
||||
store_record(table,record[1]);
|
||||
|
||||
/* Copy data from temporary table to current table */
|
||||
for (copy_field_ptr=copy_field;
|
||||
|
@ -2174,12 +2174,12 @@ simple_expr:
|
||||
| '@' ident_or_text SET_VAR expr
|
||||
{
|
||||
$$= new Item_func_set_user_var($2,$4);
|
||||
Lex->uncacheable();;
|
||||
Lex->uncacheable();
|
||||
}
|
||||
| '@' ident_or_text
|
||||
{
|
||||
$$= new Item_func_get_user_var($2);
|
||||
Lex->uncacheable();;
|
||||
Lex->uncacheable();
|
||||
}
|
||||
| '@' '@' opt_var_ident_type ident_or_text
|
||||
{
|
||||
@ -2227,6 +2227,8 @@ simple_expr:
|
||||
{ $$= new Item_func_conv_charset3($3,$7,$5); }
|
||||
| DEFAULT '(' simple_ident ')'
|
||||
{ $$= new Item_default_value($3); }
|
||||
| VALUES '(' simple_ident ')'
|
||||
{ $$= new Item_insert_value($3); }
|
||||
| FUNC_ARG0 '(' ')'
|
||||
{ $$= ((Item*(*)(void))($1.symbol->create_func))();}
|
||||
| FUNC_ARG1 '(' expr ')'
|
||||
@ -2276,7 +2278,7 @@ simple_expr:
|
||||
| ENCRYPT '(' expr ')'
|
||||
{
|
||||
$$= new Item_func_encrypt($3);
|
||||
Lex->uncacheable();;
|
||||
Lex->uncacheable();
|
||||
}
|
||||
| ENCRYPT '(' expr ',' expr ')' { $$= new Item_func_encrypt($3,$5); }
|
||||
| DECODE_SYM '(' expr ',' TEXT_STRING_literal ')'
|
||||
|
@ -267,6 +267,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
|
||||
(ulong) (uint2korr(head+6)+uint2korr(head+14)),
|
||||
MYF(MY_NABP)))
|
||||
goto err_not_open; /* purecov: inspected */
|
||||
/* HACK: table->record[2] is used instead of table->default_values here */
|
||||
for (i=0 ; i < records ; i++, record+=rec_buff_length)
|
||||
{
|
||||
outparam->record[i]=(byte*) record;
|
||||
@ -276,11 +277,12 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
|
||||
|
||||
if (records == 2)
|
||||
{ /* fix for select */
|
||||
outparam->record[2]=outparam->record[1];
|
||||
outparam->default_values=outparam->record[1];
|
||||
if (db_stat & HA_READ_ONLY)
|
||||
outparam->record[1]=outparam->record[0]; /* purecov: inspected */
|
||||
}
|
||||
|
||||
outparam->insert_values=0; /* for INSERT ... UPDATE */
|
||||
|
||||
VOID(my_seek(file,pos,MY_SEEK_SET,MYF(0)));
|
||||
if (my_read(file,(byte*) head,288,MYF(MY_NABP))) goto err_not_open;
|
||||
if (crypted)
|
||||
|
@ -65,7 +65,9 @@ struct st_table {
|
||||
Field **field; /* Pointer to fields */
|
||||
Field_blob **blob_field; /* Pointer to blob fields */
|
||||
HASH name_hash; /* hash of field names */
|
||||
byte *record[3]; /* Pointer to records */
|
||||
byte *record[2]; /* Pointer to records */
|
||||
byte *default_values; /* record with default values for INSERT */
|
||||
byte *insert_values; /* used by INSERT ... UPDATE */
|
||||
uint fields; /* field count */
|
||||
uint reclength; /* Recordlength */
|
||||
uint rec_buff_length;
|
||||
@ -144,10 +146,9 @@ struct st_table {
|
||||
struct st_table_list *pos_in_table_list;
|
||||
};
|
||||
/* number of select if it is derived table */
|
||||
uint derived_select_number;
|
||||
uint derived_select_number;
|
||||
THD *in_use; /* Which thread uses this */
|
||||
struct st_table *next,*prev;
|
||||
byte *default_values() { return record[2]; }
|
||||
};
|
||||
|
||||
|
||||
|
12
sql/unireg.h
12
sql/unireg.h
@ -103,13 +103,13 @@
|
||||
#define SPECIAL_SAFE_MODE 2048
|
||||
|
||||
/* Extern defines */
|
||||
#define store_record(A,B) bmove_allign((A)->record[B],(A)->record[0],(size_t) (A)->reclength)
|
||||
#define restore_record(A,B) bmove_allign((A)->record[0],(A)->record[B],(size_t) (A)->reclength)
|
||||
#define cmp_record(A,B) memcmp((A)->record[0],(A)->record[B],(size_t) (A)->reclength)
|
||||
#define store_record(A,B) bmove_allign((A)->B,(A)->record[0],(size_t) (A)->reclength)
|
||||
#define restore_record(A,B) bmove_allign((A)->record[0],(A)->B,(size_t) (A)->reclength)
|
||||
#define cmp_record(A,B) memcmp((A)->record[0],(A)->B,(size_t) (A)->reclength)
|
||||
#define empty_record(A) { \
|
||||
bmove_allign((A)->record[0],(A)->record[2],(size_t) (A)->reclength); \
|
||||
bfill((A)->null_flags,(A)->null_bytes,255);\
|
||||
}
|
||||
restore_record((A),default_values); \
|
||||
bfill((A)->null_flags,(A)->null_bytes,255);\
|
||||
}
|
||||
|
||||
/* Defines for use with openfrm, openprt and openfrd */
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user