Skip to content

Commit f0889e6

Browse files
author
Steinar H. Gunderson
committed
WL #12074: Volcano iterator executor base [14/15, zero tables]
Support queries with zero tables, ie. not even a const table. (These are not allowed by ANSI SQL, but would seem a reasonably useful extension.) This requires a little bit of coaxing, since we allow having aggregation on such queries (which is maybe a less useful extension), and there's no “last table” to check the end_send function pointer on. Change-Id: I2cee6424e84c7dec32424c9966293131c07939c2
1 parent 20688bb commit f0889e6

File tree

3 files changed

+27
-10
lines changed

3 files changed

+27
-10
lines changed

sql/pfs_batch_mode.h

+5-2
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,10 @@ class PFSBatchMode {
4848
// off batch mode on the rightmost table.
4949
PFSBatchMode(QEP_TAB *qep_tab, JOIN *join)
5050
: m_qep_tab(qep_tab), m_join(join) {
51-
if (qep_tab->join() == nullptr) {
51+
if (qep_tab == nullptr) {
52+
// No tables at all.
53+
m_enable = false;
54+
} else if (qep_tab->join() == nullptr) {
5255
// The QEP_TAB isn't even part of a join (typically used when sorting
5356
// data for UPDATE or DELETE), so we can safely enable batch mode.
5457
m_enable = true;
@@ -72,7 +75,7 @@ class PFSBatchMode {
7275
// If we have e.g. a LIMIT of a join, the rightmost table could
7376
// be stuck in PFS batch mode (since the NestedLoopIterator never
7477
// saw end-of-file), so take it out if needed.
75-
if (m_join != nullptr) {
78+
if (m_join != nullptr && m_join->qep_tab != nullptr) {
7679
QEP_TAB *last_qep_tab = &m_join->qep_tab[m_join->primary_tables - 1];
7780
last_qep_tab->table()->file->end_psi_batch_mode_if_started();
7881
}

sql/sql_executor.cc

+21-8
Original file line numberDiff line numberDiff line change
@@ -1831,13 +1831,21 @@ void JOIN::create_iterators() {
18311831
// to true during optimization, and depending on when it was set, it could
18321832
// either mean to aggregate into a temporary table or aggregate on final
18331833
// send.
1834-
//
1835-
// Note that tmp_table_param.precomputed_group_by can be set even if we
1836-
// don't actually have any grouping (e.g., make_tmp_tables_info() does this
1837-
// even if there are no temporary tables made).
1838-
if (qep_tab[primary_tables + tmp_tables - 1].next_select == end_send_group ||
1839-
((grouped || group_optimized_away) &&
1840-
tmp_table_param.precomputed_group_by)) {
1834+
bool do_aggregate;
1835+
if (primary_tables == 0 && tmp_tables == 0) {
1836+
// We can't check qep_tab since there's no table, but in this specific case,
1837+
// it is safe to call get_end_select_func() at this point.
1838+
do_aggregate = (get_end_select_func() == end_send_group);
1839+
} else {
1840+
// Note that tmp_table_param.precomputed_group_by can be set even if we
1841+
// don't actually have any grouping (e.g., make_tmp_tables_info() does this
1842+
// even if there are no temporary tables made).
1843+
do_aggregate = (qep_tab[primary_tables + tmp_tables - 1].next_select ==
1844+
end_send_group) ||
1845+
((grouped || group_optimized_away) &&
1846+
tmp_table_param.precomputed_group_by);
1847+
}
1848+
if (do_aggregate) {
18411849
// Aggregate as we go, with output into a special slice of the same table.
18421850
DBUG_ASSERT(streaming_aggregation || tmp_table_param.precomputed_group_by);
18431851
#ifndef DBUG_OFF
@@ -1894,7 +1902,12 @@ static int ExecuteIteratorQuery(JOIN *join) {
18941902
return 1;
18951903
}
18961904

1897-
PFSBatchMode pfs_batch_mode(&join->qep_tab[join->const_tables], join);
1905+
QEP_TAB *first_qep_tab = nullptr;
1906+
if (join->qep_tab !=
1907+
nullptr) { // NOTE: There can be zero tables in a valid query.
1908+
first_qep_tab = &join->qep_tab[join->const_tables];
1909+
}
1910+
PFSBatchMode pfs_batch_mode(first_qep_tab, join);
18981911
for (;;) {
18991912
int error = join->root_iterator()->Read();
19001913

sql/sql_optimizer.cc

+1
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,7 @@ int JOIN::optimize() {
396396
count_field_types(select_lex, &tmp_table_param, all_fields, false, false);
397397
// Make plan visible for EXPLAIN
398398
set_plan_state(NO_TABLES);
399+
create_iterators();
399400
DBUG_RETURN(0);
400401
}
401402
error = -1; // Error is sent to client

0 commit comments

Comments
 (0)