summaryrefslogtreecommitdiff
path: root/sql/sql_update.cc
diff options
context:
space:
mode:
authorunknown <monty@donna.mysql.com>2001-02-17 14:19:19 +0200
committerunknown <monty@donna.mysql.com>2001-02-17 14:19:19 +0200
commit132e667b0bbbe33137b6baeb59f3f22b7524f066 (patch)
treebfe39951a73e906579ab819bf5198ad8f3a64a36 /sql/sql_update.cc
parentb084cf1951eb271f662a9326c950f4cf0570258d (diff)
downloadmariadb-git-132e667b0bbbe33137b6baeb59f3f22b7524f066.tar.gz
Added Innobase to source distribution
Docs/manual.texi: Added Innobase documentation configure.in: Incremented version include/my_base.h: Added option for Innobase myisam/mi_check.c: cleanup mysql-test/t/bdb.test: cleanup mysql-test/t/innobase.test: Extended with new tests from bdb.test mysql-test/t/merge.test: Added test of SHOW create mysys/my_init.c: Fix for UNIXWARE 7 scripts/mysql_install_db.sh: Always write how to start mysqld scripts/safe_mysqld.sh: Fixed type sql/ha_innobase.cc: Update to new version sql/ha_innobase.h: Update to new version sql/handler.h: Added 'update_table_comment()' and 'append_create_info()' sql/sql_delete.cc: Fixes for Innobase sql/sql_select.cc: Fixes for Innobase sql/sql_show.cc: Append create information (for MERGE tables) sql/sql_update.cc: Fixes for Innobase
Diffstat (limited to 'sql/sql_update.cc')
-rw-r--r--sql/sql_update.cc65
1 files changed, 38 insertions, 27 deletions
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index b7b9b23d79d..d17b5768440 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -20,23 +20,21 @@
#include "mysql_priv.h"
#include "sql_acl.h"
-#define MAX_ULONG_BIT ((ulong) 1 << (sizeof(ulong)*8-1));
+#define MAX_ULONG_BIT ((ulong) 1 << (sizeof(ulong)*8-1))
/* Return 0 if row hasn't changed */
-static bool compare_record(TABLE *table)
+static bool compare_record(TABLE *table, ulong query_id)
{
if (!table->blob_fields)
return cmp_record(table,1);
- ulong current_query_id=current_thd->query_id;
-
if (memcmp(table->null_flags,
table->null_flags+table->rec_buff_length,
table->null_bytes))
return 1; // Diff in NULL value
for (Field **ptr=table->field ; *ptr ; ptr++)
{
- if ((*ptr)->query_id == current_query_id &&
+ if ((*ptr)->query_id == query_id &&
(*ptr)->cmp_binary_offset(table->rec_buff_length))
return 1;
}
@@ -53,7 +51,8 @@ int mysql_update(THD *thd,TABLE_LIST *table_list,List<Item> &fields,
bool using_limit=limit != HA_POS_ERROR;
bool used_key_is_modified, using_transactions;
int error=0;
- uint save_time_stamp, used_index;
+ uint save_time_stamp, used_index, want_privilege;
+ ulong query_id=thd->query_id, timestamp_query_id;
key_map old_used_keys;
TABLE *table;
SQL_SELECT *select;
@@ -67,35 +66,45 @@ int mysql_update(THD *thd,TABLE_LIST *table_list,List<Item> &fields,
table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
thd->proc_info="init";
+ /* Calculate "table->used_keys" based on the WHERE */
+ table->used_keys=table->keys_in_use;
+ table->quick_keys=0;
+ want_privilege=table->grant.want_privilege;
+ table->grant.want_privilege=(SELECT_ACL & ~table->grant.privilege);
+ if (setup_conds(thd,table_list,&conds))
+ DBUG_RETURN(-1); /* purecov: inspected */
+ old_used_keys=table->used_keys; // Keys used in WHERE
+
/*
- ** Find the offsets of the given fields and condition
+ Change the query_id for the timestamp column so that we can
+ check if this is modified directly
*/
+ if (table->timestamp_field)
+ {
+ timestamp_query_id=table->timestamp_field->query_id;
+ table->timestamp_field->query_id=thd->query_id-1;
+ }
+ /* Check the fields we are going to modify */
+ table->grant.want_privilege=want_privilege;
if (setup_fields(thd,table_list,fields,1,0))
- DBUG_RETURN(-1);
- table->grant.want_privilege=(SELECT_ACL & ~table->grant.privilege);
- if (table->timestamp_field && // Don't set timestamp if used
- table->timestamp_field->query_id == thd->query_id)
- table->time_stamp=0;
+ DBUG_RETURN(-1); /* purecov: inspected */
+ if (table->timestamp_field)
+ {
+ // Don't set timestamp column if this is modified
+ if (table->timestamp_field->query_id == thd->query_id)
+ table->time_stamp=0;
+ else
+ table->timestamp_field->query_id=timestamp_query_id;
+ }
- /* Change query_id so that ->used_keys is based on the WHERE */
- table->used_keys=table->keys_in_use;
- table->quick_keys=0;
- ulong query_id=thd->query_id;
- thd->query_id^= MAX_ULONG_BIT;
- if (setup_fields(thd,table_list,values,0,0) ||
- setup_conds(thd,table_list,&conds))
+ /* Check values */
+ table->grant.want_privilege=(SELECT_ACL & ~table->grant.privilege);
+ if (setup_fields(thd,table_list,values,0,0))
{
table->time_stamp=save_time_stamp; // Restore timestamp pointer
DBUG_RETURN(-1); /* purecov: inspected */
}
- old_used_keys=table->used_keys;
- /* Restore query_id for compare_record */
- thd->query_id=query_id;
- List_iterator<Item> it(fields);
- Item *item;
- while ((item=it++))
- ((Item_field*) item)->field->query_id=query_id;
// Don't count on usage of 'only index' when calculating which key to use
table->used_keys=0;
@@ -141,6 +150,7 @@ int mysql_update(THD *thd,TABLE_LIST *table_list,List<Item> &fields,
** We can't update table directly; We must first search after all
** matching rows before updating the table!
*/
+ table->file->extra(HA_EXTRA_DONT_USE_CURSOR_TO_UPDATE);
IO_CACHE tempfile;
if (open_cached_file(&tempfile, mysql_tmpdir,TEMP_PREFIX,
DISK_BUFFER_SIZE, MYF(MY_WME)))
@@ -218,6 +228,7 @@ int mysql_update(THD *thd,TABLE_LIST *table_list,List<Item> &fields,
thd->count_cuted_fields=1; /* calc cuted fields */
thd->cuted_fields=0L;
thd->proc_info="updating";
+ query_id=thd->query_id;
while (!(error=info.read_record(&info)) && !thd->killed)
{
@@ -227,7 +238,7 @@ int mysql_update(THD *thd,TABLE_LIST *table_list,List<Item> &fields,
if (fill_record(fields,values))
break;
found++;
- if (compare_record(table))
+ if (compare_record(table, query_id))
{
if (!(error=table->file->update_row((byte*) table->record[1],
(byte*) table->record[0])))