summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/main/partition_error.result9
-rw-r--r--mysql-test/main/partition_error.test18
-rw-r--r--sql/ha_partition.cc111
-rw-r--r--sql/ha_partition.h6
-rw-r--r--sql/handler.h4
5 files changed, 106 insertions, 42 deletions
diff --git a/mysql-test/main/partition_error.result b/mysql-test/main/partition_error.result
index 349e9771367..868eb3b0924 100644
--- a/mysql-test/main/partition_error.result
+++ b/mysql-test/main/partition_error.result
@@ -1866,3 +1866,12 @@ pUpTo10 p-10sp1 This is a long comment (2050 ascii characters) 50 pUpTo10 part
pMax pMaxsp0 This is a long comment (2050 ascii characters) 50 pMax partition comment .80-!
pMax pMaxsp1 This is a long comment (2050 ascii characters) 50 pMax partition comment .80-!
DROP TABLE t1;
+CREATE OR REPLACE TABLE t1 (
+pk INT PRIMARY KEY,
+c CHAR(3) NOT NULL,
+v CHAR(4) AS (c) VIRTUAL
+) WITH SYSTEM VERSIONING PARTITION BY HASH(pk);
+INSERT INTO t1 (pk,c) VALUES (1,'foo'),(2,'bar');
+UPDATE t1 SET v = 'qux' WHERE pk = 2;
+ERROR HY000: The value specified for generated column 'v' in table 't1' ignored
+DROP TABLE t1;
diff --git a/mysql-test/main/partition_error.test b/mysql-test/main/partition_error.test
index 3ee54605c36..8739c93fe92 100644
--- a/mysql-test/main/partition_error.test
+++ b/mysql-test/main/partition_error.test
@@ -2074,3 +2074,21 @@ SELECT PARTITION_NAME, SUBPARTITION_NAME, PARTITION_COMMENT FROM INFORMATION_SCH
WHERE TABLE_NAME = 't1' AND TABLE_SCHEMA = 'test';
DROP TABLE t1;
+
+#
+# MDEV-16429
+# Assertion `!table || (!table->read_set
+# || bitmap_is_set(table->read_set, field_index))'
+# fails upon attempt to update virtual column on partitioned versioned table
+#
+CREATE OR REPLACE TABLE t1 (
+ pk INT PRIMARY KEY,
+ c CHAR(3) NOT NULL,
+ v CHAR(4) AS (c) VIRTUAL
+) WITH SYSTEM VERSIONING PARTITION BY HASH(pk);
+
+INSERT INTO t1 (pk,c) VALUES (1,'foo'),(2,'bar');
+-- error ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN
+UPDATE t1 SET v = 'qux' WHERE pk = 2;
+
+DROP TABLE t1;
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index edadbd7b6d7..f5c9bb9e77b 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -8471,6 +8471,24 @@ err_handler:
}
+static int extra_cb(handler *h, void *operation)
+{
+ return h->extra(*(enum ha_extra_function*)operation);
+}
+
+
+static int start_keyread_cb(handler* h, void *p)
+{
+ return h->ha_start_keyread(*(uint*)p);
+}
+
+
+static int end_keyread_cb(handler* h, void *unused)
+{
+ return h->ha_end_keyread();
+}
+
+
/**
General function to prepare handler for certain behavior.
@@ -8799,11 +8817,12 @@ int ha_partition::extra(enum ha_extra_function operation)
switch (operation) {
/* Category 1), used by most handlers */
- case HA_EXTRA_KEYREAD:
case HA_EXTRA_NO_KEYREAD:
+ DBUG_RETURN(loop_partitions(end_keyread_cb, NULL));
+ case HA_EXTRA_KEYREAD:
case HA_EXTRA_FLUSH:
case HA_EXTRA_PREPARE_FOR_FORCED_CLOSE:
- DBUG_RETURN(loop_extra(operation));
+ DBUG_RETURN(loop_partitions(extra_cb, &operation));
case HA_EXTRA_PREPARE_FOR_RENAME:
case HA_EXTRA_FORCE_REOPEN:
DBUG_RETURN(loop_extra_alter(operation));
@@ -8815,7 +8834,7 @@ int ha_partition::extra(enum ha_extra_function operation)
case HA_EXTRA_KEYREAD_PRESERVE_FIELDS:
{
if (!m_myisam)
- DBUG_RETURN(loop_extra(operation));
+ DBUG_RETURN(loop_partitions(extra_cb, &operation));
}
break;
@@ -8842,7 +8861,7 @@ int ha_partition::extra(enum ha_extra_function operation)
case HA_EXTRA_REMEMBER_POS:
case HA_EXTRA_RESTORE_POS:
{
- DBUG_RETURN(loop_extra(operation));
+ DBUG_RETURN(loop_partitions(extra_cb, &operation));
}
case HA_EXTRA_NO_READCHECK:
{
@@ -8874,7 +8893,7 @@ int ha_partition::extra(enum ha_extra_function operation)
m_extra_cache_size= 0;
m_extra_prepare_for_update= FALSE;
m_extra_cache_part_id= NO_CURRENT_PART_ID;
- DBUG_RETURN(loop_extra(operation));
+ DBUG_RETURN(loop_partitions(extra_cb, &operation));
}
case HA_EXTRA_IGNORE_NO_KEY:
case HA_EXTRA_NO_IGNORE_NO_KEY:
@@ -8895,11 +8914,11 @@ int ha_partition::extra(enum ha_extra_function operation)
At this time, this is safe by limitation of ha_partition
*/
- DBUG_RETURN(loop_extra(operation));
+ DBUG_RETURN(loop_partitions(extra_cb, &operation));
}
/* Category 7), used by federated handlers */
case HA_EXTRA_INSERT_WITH_UPDATE:
- DBUG_RETURN(loop_extra(operation));
+ DBUG_RETURN(loop_partitions(extra_cb, &operation));
/* Category 8) Operations only used by NDB */
case HA_EXTRA_DELETE_CANNOT_BATCH:
case HA_EXTRA_UPDATE_CANNOT_BATCH:
@@ -8909,13 +8928,13 @@ int ha_partition::extra(enum ha_extra_function operation)
}
/* Category 9) Operations only used by MERGE */
case HA_EXTRA_ADD_CHILDREN_LIST:
- DBUG_RETURN(loop_extra(operation));
+ DBUG_RETURN(loop_partitions(extra_cb, &operation));
case HA_EXTRA_ATTACH_CHILDREN:
{
int result;
uint num_locks;
handler **file;
- if ((result= loop_extra(operation)))
+ if ((result= loop_partitions(extra_cb, &operation)))
DBUG_RETURN(result);
/* Recalculate lock count as each child may have different set of locks */
@@ -8930,9 +8949,9 @@ int ha_partition::extra(enum ha_extra_function operation)
break;
}
case HA_EXTRA_IS_ATTACHED_CHILDREN:
- DBUG_RETURN(loop_extra(operation));
+ DBUG_RETURN(loop_partitions(extra_cb, &operation));
case HA_EXTRA_DETACH_CHILDREN:
- DBUG_RETURN(loop_extra(operation));
+ DBUG_RETURN(loop_partitions(extra_cb, &operation));
case HA_EXTRA_MARK_AS_LOG_TABLE:
/*
http://dev.mysql.com/doc/refman/5.1/en/partitioning-limitations.html
@@ -8944,7 +8963,7 @@ int ha_partition::extra(enum ha_extra_function operation)
case HA_EXTRA_BEGIN_ALTER_COPY:
case HA_EXTRA_END_ALTER_COPY:
case HA_EXTRA_FAKE_START_STMT:
- DBUG_RETURN(loop_extra(operation));
+ DBUG_RETURN(loop_partitions(extra_cb, &operation));
default:
{
/* Temporary crash to discover what is wrong */
@@ -8952,7 +8971,7 @@ int ha_partition::extra(enum ha_extra_function operation)
break;
}
}
- DBUG_RETURN(0);
+ DBUG_RETURN(1);
}
@@ -8990,25 +9009,41 @@ int ha_partition::reset(void)
}
/*
- Special extra method for HA_EXTRA_CACHE with cachesize as extra parameter
+ Special extra method with additional parameter
+ See @ref ha_partition::extra
- SYNOPSIS
- extra_opt()
- operation Must be HA_EXTRA_CACHE
- cachesize Size of cache in full table scan
+ @param[in] operation operation to execute
+ @param[in] arg extra argument
- RETURN VALUE
- >0 Error code
- 0 Success
+ @return status
+ @retval 0 success
+ @retval >0 error code
+
+ @detail
+ Operations supported by extra_opt:
+ HA_EXTRA_KEYREAD:
+ arg is interpreted as key index
+ HA_EXTRA_CACHE:
+ arg is interpreted as size of cache in full table scan
+
+ For detailed description refer to @ref ha_partition::extra
*/
-int ha_partition::extra_opt(enum ha_extra_function operation, ulong cachesize)
+int ha_partition::extra_opt(enum ha_extra_function operation, ulong arg)
{
- DBUG_ENTER("ha_partition::extra_opt()");
+ DBUG_ENTER("ha_partition::extra_opt");
- DBUG_ASSERT(HA_EXTRA_CACHE == operation);
- prepare_extra_cache(cachesize);
- DBUG_RETURN(0);
+ switch (operation)
+ {
+ case HA_EXTRA_KEYREAD:
+ DBUG_RETURN(loop_partitions(start_keyread_cb, &arg));
+ case HA_EXTRA_CACHE:
+ prepare_extra_cache(arg);
+ DBUG_RETURN(0);
+ default:
+ DBUG_ASSERT(0);
+ }
+ DBUG_RETURN(1);
}
@@ -9071,28 +9106,28 @@ int ha_partition::loop_extra_alter(enum ha_extra_function operation)
if ((tmp= (*file)->extra(operation)))
result= tmp;
}
- if ((tmp= loop_extra(operation)))
+ if ((tmp= loop_partitions(extra_cb, &operation)))
result= tmp;
DBUG_RETURN(result);
}
-/*
- Call extra on all partitions
- SYNOPSIS
- loop_extra()
- operation extra operation type
+/**
+ Call callback(part, param) on all partitions
- RETURN VALUE
- >0 Error code
- 0 Success
+ @param callback a callback to call for each partition
+ @param param a void*-parameter passed to callback
+
+ @return Operation status
+ @retval >0 Error code
+ @retval 0 Success
*/
-int ha_partition::loop_extra(enum ha_extra_function operation)
+int ha_partition::loop_partitions(handler_callback callback, void *param)
{
int result= 0, tmp;
uint i;
- DBUG_ENTER("ha_partition::loop_extra()");
+ DBUG_ENTER("ha_partition::loop_partitions");
for (i= bitmap_get_first_set(&m_part_info->lock_partitions);
i < m_tot_parts;
@@ -9103,7 +9138,7 @@ int ha_partition::loop_extra(enum ha_extra_function operation)
In this case calling 'extra' can crash.
*/
if (bitmap_is_set(&m_opened_partitions, i) &&
- (tmp= m_file[i]->extra(operation)))
+ (tmp= callback(m_file[i], param)))
result= tmp;
}
/* Add all used partitions to be called in reset(). */
diff --git a/sql/ha_partition.h b/sql/ha_partition.h
index 8a251016703..8a374fe87b7 100644
--- a/sql/ha_partition.h
+++ b/sql/ha_partition.h
@@ -844,7 +844,7 @@ public:
int change_partitions_to_open(List<String> *partition_names);
int open_read_partitions(char *name_buff, size_t name_buff_size);
virtual int extra(enum ha_extra_function operation);
- virtual int extra_opt(enum ha_extra_function operation, ulong cachesize);
+ virtual int extra_opt(enum ha_extra_function operation, ulong arg);
virtual int reset(void);
virtual uint count_query_cache_dependant_tables(uint8 *tables_type);
virtual my_bool
@@ -854,6 +854,8 @@ public:
uint *n);
private:
+ typedef int handler_callback(handler *, void *);
+
my_bool reg_query_cache_dependant_table(THD *thd,
char *engine_key,
uint engine_key_len,
@@ -864,7 +866,7 @@ private:
**block_table,
handler *file, uint *n);
static const uint NO_CURRENT_PART_ID= NOT_A_PARTITION_ID;
- int loop_extra(enum ha_extra_function operation);
+ int loop_partitions(handler_callback callback, void *param);
int loop_extra_alter(enum ha_extra_function operations);
void late_extra_cache(uint partition_id);
void late_extra_no_cache(uint partition_id);
diff --git a/sql/handler.h b/sql/handler.h
index e3ab87b941b..8f31f741eab 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -3097,7 +3097,7 @@ public:
bool keyread_enabled() { return keyread < MAX_KEY; }
int ha_start_keyread(uint idx)
{
- int res= keyread_enabled() ? 0 : extra(HA_EXTRA_KEYREAD);
+ int res= keyread_enabled() ? 0 : extra_opt(HA_EXTRA_KEYREAD, idx);
keyread= idx;
return res;
}
@@ -3609,7 +3609,7 @@ public:
{ return 0; }
virtual int extra(enum ha_extra_function operation)
{ return 0; }
- virtual int extra_opt(enum ha_extra_function operation, ulong cache_size)
+ virtual int extra_opt(enum ha_extra_function operation, ulong arg)
{ return extra(operation); }
/**