Skip to content

Commit 07ec733

Browse files
committed
Bug#34852090: Incorrect result with VALUES in a correlated LATERAL subquery
Bug#35087820: VALUES Statement with dependent subquery is wrong When a table value constructor has to be read multiple times during a query, it will only return data the first time it is read. When it's read the second time, it will return EOF immediately. It is caused by a bug in TableValueConstructorIterator::Read() where it returns EOF immediately when the number of examined rows is equal to the number of rows in the table value constructor. Since this counter is intentionally not reset when the iterator is re-initialized, the table value constructor will keep returning EOF forever once every row has been read, and not start again from the beginning when it's re-initialized. Fixed by checking the position of the iterator over the row value list instead of the number of examined rows. Change-Id: I0e828eb0de0360a16cea9f77b578c68205cefbaf (cherry picked from commit 7dc427011ed66613edf61dd144867b8728918dcb)
1 parent fa9aa5e commit 07ec733

File tree

3 files changed

+56
-2
lines changed

3 files changed

+56
-2
lines changed

mysql-test/r/table_value_constructor.result

+27
Original file line numberDiff line numberDiff line change
@@ -675,3 +675,30 @@ NULL
675675
5
676676
DROP VIEW v1;
677677
DROP TABLE t1;
678+
#
679+
# Bug#35087820: VALUES Statement with dependent subquery is wrong
680+
#
681+
CREATE TABLE t(
682+
id INTEGER PRIMARY KEY,
683+
a VARCHAR(4),
684+
b VARCHAR(4),
685+
c VARCHAR(3));
686+
INSERT INTO t VALUES (1, 'a1', 'b1', 'c1'), (2, 'a2', 'b2', 'c2');
687+
SELECT
688+
id,
689+
(SELECT MAX(col1) FROM (VALUES ROW(a), ROW(b), ROW(c)) AS x(col1)) AS max
690+
FROM t;
691+
id max
692+
1 c1
693+
2 c2
694+
DROP TABLE t;
695+
#
696+
# Bug#34852090: Incorrect result with VALUES in
697+
# a correlated LATERAL subquery
698+
#
699+
WITH v1(x) AS (VALUES ROW (1), ROW (2), ROW (3))
700+
SELECT * FROM v1, LATERAL (VALUES ROW(v1.x)) AS v2;
701+
x column_0
702+
1 1
703+
2 2
704+
3 3

mysql-test/t/table_value_constructor.test

+27
Original file line numberDiff line numberDiff line change
@@ -475,3 +475,30 @@ INSERT INTO v1 VALUES(5) AS c(a);
475475
SELECT * FROM v1;
476476
DROP VIEW v1;
477477
DROP TABLE t1;
478+
479+
--echo #
480+
--echo # Bug#35087820: VALUES Statement with dependent subquery is wrong
481+
--echo #
482+
483+
CREATE TABLE t(
484+
id INTEGER PRIMARY KEY,
485+
a VARCHAR(4),
486+
b VARCHAR(4),
487+
c VARCHAR(3));
488+
INSERT INTO t VALUES (1, 'a1', 'b1', 'c1'), (2, 'a2', 'b2', 'c2');
489+
490+
--sorted_result
491+
SELECT
492+
id,
493+
(SELECT MAX(col1) FROM (VALUES ROW(a), ROW(b), ROW(c)) AS x(col1)) AS max
494+
FROM t;
495+
496+
DROP TABLE t;
497+
498+
--echo #
499+
--echo # Bug#34852090: Incorrect result with VALUES in
500+
--echo # a correlated LATERAL subquery
501+
--echo #
502+
503+
WITH v1(x) AS (VALUES ROW (1), ROW (2), ROW (3))
504+
SELECT * FROM v1, LATERAL (VALUES ROW(v1.x)) AS v2;

sql/iterators/ref_row_iterators.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -917,7 +917,7 @@ bool TableValueConstructorIterator::Init() {
917917
}
918918

919919
int TableValueConstructorIterator::Read() {
920-
if (*m_examined_rows == m_row_value_list.size()) return -1;
920+
if (m_row_it == m_row_value_list.end()) return -1;
921921

922922
// If the TVC has a single row, we don't create Item_values_column reference
923923
// objects during resolving. We will instead use the single row directly from
@@ -935,9 +935,9 @@ int TableValueConstructorIterator::Read() {
935935
// Item_values_column object cannot be const.
936936
ref->set_value(const_cast<Item *>(value));
937937
}
938-
++m_row_it;
939938
}
940939

940+
++m_row_it;
941941
++*m_examined_rows;
942942
return 0;
943943
}

0 commit comments

Comments
 (0)