Commit 075f5978 authored by Yuchen Pei's avatar Yuchen Pei

MDEV-24813 [poc] Signal full table lock when cond is NULL

Will work in the following minimal example

--source include/have_innodb.inc
CREATE TABLE t (a INT PRIMARY KEY) ENGINE=InnoDB;
insert into t values (42);

BEGIN;
SELECT * FROM t LOCK IN SHARE MODE; # will acquire S lock
COMMIT;

DROP TABLE t;
parent 9811d23b
......@@ -338,8 +338,8 @@ bool init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
}
/* Condition pushdown to storage engine */
if ((table->file->ha_table_flags() & HA_CAN_TABLE_CONDITION_PUSHDOWN) &&
select && select->cond &&
(select->cond->used_tables() & table->map) &&
select && // select->cond &&
// (select->cond->used_tables() & table->map) &&
!table->file->pushed_cond)
table->file->cond_push(select->cond);
......
......@@ -2990,6 +2990,7 @@ ha_innobase::ha_innobase(
| HA_CONCURRENT_OPTIMIZE
| HA_CAN_SKIP_LOCKED
| (srv_force_primary_key ? HA_REQUIRE_PRIMARY_KEY : 0)
| HA_CAN_TABLE_CONDITION_PUSHDOWN
),
m_start_of_scan(),
m_mysql_has_locked()
......@@ -20426,6 +20427,12 @@ ha_innobase::idx_cond_push(
DBUG_RETURN(NULL);
}
const COND*
ha_innobase::cond_push(const COND *cond)
{
m_prebuilt->full_table_scan|= !cond;
return NULL;
}
/** Push a primary key filter.
@param[in] pk_filter filter against which primary keys
......
......@@ -403,6 +403,7 @@ class ha_innobase final : public handler
@param[in] idx_cond Index condition to be checked
@return idx_cond if pushed; NULL if not pushed */
Item* idx_cond_push(uint keyno, Item* idx_cond) override;
const COND* cond_push(const COND *cond) override;
/* @} */
/** Check if InnoDB is not storing virtual column metadata for a table.
......
......@@ -686,6 +686,11 @@ struct row_prebuilt_t {
/** The MySQL table object */
TABLE* m_mysql_table;
bool full_table_scan; /*!< Whether the full table will need to be
scanned. Set when the sql layer passes NULL cond in
cond_push. Will cause to use X/S locks in select rather than
IX/IS locks */
/** Get template by dict_table_t::cols[] number */
const mysql_row_templ_t* get_template_by_col(ulint col) const
{
......
......@@ -4714,8 +4714,10 @@ row_search_mvcc(
} else {
wait_table_again:
err = lock_table(prebuilt->table, nullptr,
prebuilt->select_lock_type == LOCK_S
? LOCK_IS : LOCK_IX, thr);
prebuilt->full_table_scan ?
prebuilt->select_lock_type :
(prebuilt->select_lock_type == LOCK_S
? LOCK_IS : LOCK_IX), thr);
if (err != DB_SUCCESS) {
......
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