Commit b33115ec authored by unknown's avatar unknown

INSERT ... UPDATE ... VALUES()

parent a20b167c
......@@ -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 @@ class Field
GEOM_GEOMETRYCOLLECTION = 7
};
enum imagetype { itRAW, itMBR};
utype unireg_check;
uint32 field_length; // Length of field
uint16 flags;
......@@ -83,7 +83,7 @@ class Field
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) |
......
......@@ -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
......
......@@ -34,13 +34,13 @@ class Item {
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 @@ class Item_field :public Item_ident
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 @@ class Item_default_value : public Item_field
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 @@ class Item_default_value : public Item_field
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> &not_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]; }
};
......
......@@ -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 */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment