Skip to content

Commit 14c90a0

Browse files
Dag Wanvikdahlerlend
authored andcommitted
Bug#35471522 AccessPath* MoveCompositeIteratorsFromTablePath(AccessPath*, const Query_block& Bug#35228083 Assertion `false' failed|sql/sql_executor.cc [back-port]
Back-port to 8.0 branch. It differs slightly from original patch due to dependencies on unported code, but the diffs are trivial. Assert when ordering a unary (nested block) and the order by contains a window function: ( block LIMIT .. ) ORDER BY .. window-function .. The ORDER BY is somewhat conservatively not pushed into the nested block in this case due to the presence of the LIMIT. MoveCompositeIteratorsFromTablePath is missing a case for bottom_of_table_path->type being a window, so we see an assert in debug build. In production build I do not see a crash. The patch adds handling of this case which makes the repro not assert in debug builds. For explain, we saw another assert. To fix this, we added a new case calling a new function EstimateWindowCost. The issue also contains another repro which does not contain a window function which fails on the same assert. This is a similar bug but a distinct error: in the case the unexpected access path is a DYNAMIC_INDEX_RANGE_SCAN. The patch also solves this issue. Finally, there is another issue 35228083 which is a duplicate of the first repro (window function), so this patch solves that as well. Change-Id: I2cea641a3206dfdc276e85583c624c3c1e7b26a2
1 parent 6ac5df0 commit 14c90a0

File tree

5 files changed

+26
-3
lines changed

5 files changed

+26
-3
lines changed

sql/join_optimizer/access_path.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -951,7 +951,9 @@ unique_ptr_destroy_only<RowIterator> CreateIteratorFromAccessPath(
951951
path->materialize().table_path->type == AccessPath::CONST_TABLE ||
952952
path->materialize().table_path->type == AccessPath::INDEX_SCAN ||
953953
path->materialize().table_path->type ==
954-
AccessPath::INDEX_RANGE_SCAN);
954+
AccessPath::INDEX_RANGE_SCAN ||
955+
path->materialize().table_path->type ==
956+
AccessPath::DYNAMIC_INDEX_RANGE_SCAN);
955957

956958
MaterializePathParameters *param = path->materialize().param;
957959
if (job.children.is_null()) {

sql/join_optimizer/access_path.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1148,8 +1148,8 @@ struct AccessPath {
11481148
} stream;
11491149
struct {
11501150
// NOTE: The only legal access paths within table_path are
1151-
// TABLE_SCAN, REF, REF_OR_NULL, EQ_REF, ALTERNATIVE and
1152-
// CONST_TABLE (the latter is somewhat nonsensical).
1151+
// TABLE_SCAN, REF, REF_OR_NULL, EQ_REF, ALTERNATIVE,
1152+
// CONST_TABLE (somewhat nonsensical), INDEX_SCAN and DYNAMIC_INDEX_SCAN
11531153
AccessPath *table_path;
11541154

11551155
// Large, and has nontrivial destructors, so split out

sql/join_optimizer/cost_model.cc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -914,3 +914,13 @@ void EstimateLimitOffsetCost(AccessPath *path) {
914914
fraction_start_read * (child->cost - child->init_cost);
915915
}
916916
}
917+
918+
void EstimateWindowCost(AccessPath *path) {
919+
auto &win = path->window();
920+
AccessPath *child = win.child;
921+
922+
path->set_num_output_rows(child->num_output_rows());
923+
path->init_cost = child->init_cost;
924+
path->init_once_cost = child->init_once_cost;
925+
path->cost = child->cost + kWindowOneRowCost * child->num_output_rows();
926+
}

sql/join_optimizer/cost_model.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,9 @@ void EstimateStreamCost(AccessPath *path);
136136
/// Estimate the costs and row count for a LIMIT_OFFSET AccessPath.
137137
void EstimateLimitOffsetCost(AccessPath *path);
138138

139+
/// Estimate the costs and row count for a WINDOW AccessPath.
140+
void EstimateWindowCost(AccessPath *path);
141+
139142
inline double FindOutputRowsForJoin(double left_rows, double right_rows,
140143
const JoinPredicate *edge) {
141144
double fanout = right_rows * edge->selectivity;

sql/sql_executor.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1522,6 +1522,10 @@ static void RecalculateTablePathCost(AccessPath *path,
15221522
EstimateMaterializeCost(current_thd, path);
15231523
break;
15241524

1525+
case AccessPath::WINDOW:
1526+
EstimateWindowCost(path);
1527+
break;
1528+
15251529
default:
15261530
assert(false);
15271531
}
@@ -1548,6 +1552,7 @@ AccessPath *MoveCompositeIteratorsFromTablePath(
15481552
case AccessPath::CONST_TABLE:
15491553
case AccessPath::INDEX_SCAN:
15501554
case AccessPath::INDEX_RANGE_SCAN:
1555+
case AccessPath::DYNAMIC_INDEX_RANGE_SCAN:
15511556
// We found our real bottom.
15521557
path->materialize().table_path = sub_path;
15531558
if (explain) {
@@ -1609,6 +1614,9 @@ AccessPath *MoveCompositeIteratorsFromTablePath(
16091614
.param->query_blocks[0]
16101615
.subquery_path = path;
16111616
break;
1617+
case AccessPath::WINDOW:
1618+
bottom_of_table_path->window().child = path;
1619+
break;
16121620
default:
16131621
assert(false);
16141622
}

0 commit comments

Comments
 (0)