diff --git a/fdb-relational-core/src/main/java/com/apple/foundationdb/relational/recordlayer/query/visitors/ExpressionVisitor.java b/fdb-relational-core/src/main/java/com/apple/foundationdb/relational/recordlayer/query/visitors/ExpressionVisitor.java index cfc3ae9f01..802ed2eac3 100644 --- a/fdb-relational-core/src/main/java/com/apple/foundationdb/relational/recordlayer/query/visitors/ExpressionVisitor.java +++ b/fdb-relational-core/src/main/java/com/apple/foundationdb/relational/recordlayer/query/visitors/ExpressionVisitor.java @@ -60,6 +60,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; import com.google.common.collect.Streams; import com.google.protobuf.ZeroCopyByteString; import org.antlr.v4.runtime.ParserRuleContext; @@ -891,12 +892,23 @@ public Expression visitRecordConstructor(@Nonnull RelationalParser.RecordConstru } else { final var star = getDelegate().getSemanticAnalyzer().expandStar(Optional.of(id), getDelegate().getLogicalOperators()); final var resultValue = star.getUnderlying(); - return Expression.ofUnnamed(resultValue); + // Name the column after the qualifier (table name or alias) that was expanded. + return Expression.of(resultValue, id); } } if (ctx.STAR() != null) { final var star = getDelegate().getSemanticAnalyzer().expandStar(Optional.empty(), getDelegate().getLogicalOperators()); final var resultValue = star.getUnderlying(); + // Name the column after the sole for-each quantifier in scope. + // Both standard joins and PartiQL unnest expansions introduce multiple for-each + // quantifiers (attributes originating from different sources), so fall back to + // an unnamed column whenever there is more than one. + final var forEachOps = getDelegate().getLogicalOperators().forEachOnly(); + if (Iterables.size(forEachOps) == 1) { + return Iterables.getOnlyElement(forEachOps).getName() + .map(name -> Expression.of(resultValue, name)) + .orElse(Expression.ofUnnamed(resultValue)); + } return Expression.ofUnnamed(resultValue); } final var expressions = parseRecordFieldsUnderReorderings(ctx.expressionWithOptionalName()); diff --git a/yaml-tests/src/test/java/CheckResultMetadataTest.java b/yaml-tests/src/test/java/CheckResultMetadataTest.java index df4e85a87c..4a6e73dd56 100644 --- a/yaml-tests/src/test/java/CheckResultMetadataTest.java +++ b/yaml-tests/src/test/java/CheckResultMetadataTest.java @@ -116,7 +116,8 @@ static Stream shouldPass() { "array-of-struct-column", // array-of-struct with nested element field descriptors "struct-type-name", // struct type name as optional prefix in field list "field-named-array", // struct field named "array" — no clash with {array: ...} map syntax - "type-named-array" // struct type named "array" — no clash with {array: ...} map syntax + "type-named-array", // struct type named "array" — no clash with {array: ...} map syntax + "star-expression-metadata" // column names from SELECT (*) / SELECT (T.*) / SELECT (*) AS alias ); } diff --git a/yaml-tests/src/test/resources/check-result-metadata/shouldPass/star-expression-metadata.yamsql b/yaml-tests/src/test/resources/check-result-metadata/shouldPass/star-expression-metadata.yamsql new file mode 100644 index 0000000000..1b07d2067d --- /dev/null +++ b/yaml-tests/src/test/resources/check-result-metadata/shouldPass/star-expression-metadata.yamsql @@ -0,0 +1,186 @@ +# +# star-expression-metadata.yamsql +# +# This source file is part of the FoundationDB open source project +# +# Copyright 2015-2026 Apple Inc. and the FoundationDB project authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Tests the result-set column names produced by parenthesised-star SELECT expressions. +# +# Parenthesised-star forms — SELECT (*) and SELECT (T.*) — pack the entire row into a +# single struct-typed column. The outer column name is inferred as follows: +# +# SELECT (T.*) → column named T (explicit qualifier used as name) +# SELECT (*) single source → column named after the sole table/alias/function in scope +# SELECT (*) / (T.*) AS X → explicit alias overrides inferred name +# SELECT (*) multi-table → column is anonymous ("_0") — source is ambiguous +--- +schema_template: + create table foo(id bigint, val bigint, primary key(id)) + create table bar(bid bigint, bval bigint, primary key(bid)) + create type as struct s1(a bigint, b bigint) + create type as struct s2(c bigint, d s1 array) + create table t1(col1 bigint, col2 s2 array, primary key(col1)) +--- +transaction_setups: + tvf_sq: create temporary function sq(in x bigint) on commit drop function AS + SELECT id, val FROM foo WHERE id > x +--- +setup: + steps: + - query: INSERT INTO foo VALUES (1, 10) + - query: INSERT INTO bar VALUES (1, 20) + - query: INSERT INTO t1 VALUES (1, [(10, [(100, 200)])]) +--- +test_block: + name: table-source + tests: + - + # Case 1: SELECT (*) FROM FOO → single table in scope → column named FOO + - query: SELECT (*) FROM foo + - resultMetadata: [{FOO: [{ID: BIGINT}, {VAL: BIGINT}]}] + - result: [{FOO: {ID: 1, VAL: 10}}] + - + # Case 2: SELECT (FOO.*) FROM FOO → qualifier is used as column name + - query: SELECT (foo.*) FROM foo + - resultMetadata: [{FOO: [{ID: BIGINT}, {VAL: BIGINT}]}] + - result: [{FOO: {ID: 1, VAL: 10}}] + - + # Case 3: SELECT (*) FROM FOO AS BAR → table alias in scope → column named BAR + - query: SELECT (*) FROM foo AS bar + - resultMetadata: [{BAR: [{ID: BIGINT}, {VAL: BIGINT}]}] + - result: [{BAR: {ID: 1, VAL: 10}}] + - + # Case 4: SELECT (BAR.*) FROM FOO AS BAR → qualifier (the alias) is used as column name + - query: SELECT (bar.*) FROM foo AS bar + - resultMetadata: [{BAR: [{ID: BIGINT}, {VAL: BIGINT}]}] + - result: [{BAR: {ID: 1, VAL: 10}}] + - + # Case 5: SELECT (*) AS BAR FROM FOO → explicit alias overrides inferred name + - query: SELECT (*) AS bar FROM foo + - resultMetadata: [{BAR: [{ID: BIGINT}, {VAL: BIGINT}]}] + - result: [{BAR: {ID: 1, VAL: 10}}] + - + # Case 6: SELECT (FOO.*) AS BAR FROM FOO → explicit alias overrides qualifier name + - query: SELECT (foo.*) AS bar FROM foo + - resultMetadata: [{BAR: [{ID: BIGINT}, {VAL: BIGINT}]}] + - result: [{BAR: {ID: 1, VAL: 10}}] +--- +test_block: + name: subquery-source + tests: + - + # Subquery with alias → column named after the alias + - query: SELECT (*) FROM (SELECT id, val FROM foo) AS sub + - resultMetadata: [{SUB: [{ID: BIGINT}, {VAL: BIGINT}]}] + - result: [{SUB: {ID: 1, VAL: 10}}] + - + # (T.*) where T is a subquery alias → same rule as for a table alias + - query: SELECT (sub.*) FROM (SELECT id, val FROM foo) AS sub + - resultMetadata: [{SUB: [{ID: BIGINT}, {VAL: BIGINT}]}] + - result: [{SUB: {ID: 1, VAL: 10}}] +--- +test_block: + name: function-source + tests: + - + # TVF without alias → column named after the function + - query: SELECT (*) FROM sq(0) + - setupReference: tvf_sq + - resultMetadata: [{SQ: [{ID: BIGINT}, {VAL: BIGINT}]}] + - result: [{SQ: {ID: 1, VAL: 10}}] + - + # TVF with alias → alias wins + - query: SELECT (*) FROM sq(0) AS f + - setupReference: tvf_sq + - resultMetadata: [{F: [{ID: BIGINT}, {VAL: BIGINT}]}] + - result: [{F: {ID: 1, VAL: 10}}] +--- +test_block: + name: values-source + tests: + - + # VALUES without alias has no name → source is anonymous, column is _0 + - query: SELECT (*) FROM VALUES (1, 2), (3, 4) + - resultMetadata: [{_0: [{_0: INTEGER}, {_1: INTEGER}]}] + - unorderedResult: [{_0: {_0: 1, _1: 2}}, {_0: {_0: 3, _1: 4}}] + - + # VALUES with in-line table definition → column named after the table alias + - query: SELECT (*) FROM VALUES (1, 2), (3, 4) AS X(A, B) + - resultMetadata: [{X: [{A: INTEGER}, {B: INTEGER}]}] + - unorderedResult: [{X: {A: 1, B: 2}}, {X: {A: 3, B: 4}}] +--- +test_block: + name: ambiguous-join-source + tests: + - + # Two tables in scope → source is ambiguous, column is anonymous + - query: SELECT (*) FROM foo, bar WHERE foo.id = bar.bid + - resultMetadata: [{_0: [{ID: BIGINT}, {VAL: BIGINT}, {BID: BIGINT}, {BVAL: BIGINT}]}] + - result: [{_0: {ID: 1, VAL: 10, BID: 1, BVAL: 20}}] +--- +test_block: + name: partiql-unnest-source + tests: + - + # PartiQL unnest introduces two for-each quantifiers (t1 and k) → source is ambiguous, + # column is anonymous even though only one base table is in scope + - query: SELECT (*) FROM t1, t1.col2 AS k + - resultMetadata: + - _0: + - {COL1: BIGINT} + - COL2: {array: [{C: BIGINT}, {D: {array: [{A: BIGINT}, {B: BIGINT}]}}]} + - {C: BIGINT} + - D: {array: [{A: BIGINT}, {B: BIGINT}]} + - result: [{_0: {COL1: 1, COL2: [{C: 10, D: [{A: 100, B: 200}]}], C: 10, D: [{A: 100, B: 200}]}}] + - + # Wrapping the multi-level unnest in a subquery alias gives exactly one for-each + # quantifier in the outer scope → column named after the alias + - query: SELECT (*) FROM (SELECT * FROM t1, t1.col2 AS k, k.d AS m) AS p + - resultMetadata: + - P: + - {COL1: BIGINT} + - COL2: {array: [{C: BIGINT}, {D: {array: [{A: BIGINT}, {B: BIGINT}]}}]} + - {C: BIGINT} + - D: {array: [{A: BIGINT}, {B: BIGINT}]} + - {A: BIGINT} + - {B: BIGINT} + - result: [{P: {COL1: 1, COL2: [{C: 10, D: [{A: 100, B: 200}]}], C: 10, D: [{A: 100, B: 200}], A: 100, B: 200}}] + - + # Explicit (p.*) qualifier gives the same column name as the inferred case above + - query: SELECT (p.*) FROM (SELECT * FROM t1, t1.col2 AS k, k.d AS m) AS p + - resultMetadata: + - P: + - {COL1: BIGINT} + - COL2: {array: [{C: BIGINT}, {D: {array: [{A: BIGINT}, {B: BIGINT}]}}]} + - {C: BIGINT} + - D: {array: [{A: BIGINT}, {B: BIGINT}]} + - {A: BIGINT} + - {B: BIGINT} + - result: [{P: {COL1: 1, COL2: [{C: 10, D: [{A: 100, B: 200}]}], C: 10, D: [{A: 100, B: 200}], A: 100, B: 200}}] + - + # Nesting: inner (*) names the column after alias h; outer (*) names the column after alias q + - query: SELECT (*) FROM (SELECT (*) FROM (SELECT * FROM t1, t1.col2 AS k, k.d AS m) AS h) AS q + - resultMetadata: + - Q: + - H: + - {COL1: BIGINT} + - COL2: {array: [{C: BIGINT}, {D: {array: [{A: BIGINT}, {B: BIGINT}]}}]} + - {C: BIGINT} + - D: {array: [{A: BIGINT}, {B: BIGINT}]} + - {A: BIGINT} + - {B: BIGINT} + - result: [{Q: {H: {COL1: 1, COL2: [{C: 10, D: [{A: 100, B: 200}]}], C: 10, D: [{A: 100, B: 200}], A: 100, B: 200}}}] +... diff --git a/yaml-tests/src/test/resources/join-tests.yamsql b/yaml-tests/src/test/resources/join-tests.yamsql index 386647bdc5..ad10077ee6 100644 --- a/yaml-tests/src/test/resources/join-tests.yamsql +++ b/yaml-tests/src/test/resources/join-tests.yamsql @@ -200,7 +200,7 @@ test_block: - # ambiguous sub select is fine if the top-level query does not specify column names - query: select (*) from (select dept.name, project.name from emp, dept, project where emp.dept_id = dept.id and project.emp_id = emp.id) X; - - explain: "SCAN([IS DEPT]) | FLATMAP q0 -> { SCAN([IS PROJECT]) | FLATMAP q1 -> { SCAN([IS EMP]) | FILTER _.DEPT_ID EQUALS q0.ID AND q1.EMP_ID EQUALS _.ID AS q2 RETURN q1 } AS q1 RETURN ((q0.NAME AS _0, q1.NAME AS _1) AS _0) }" + - explain: "SCAN([IS DEPT]) | FLATMAP q0 -> { SCAN([IS PROJECT]) | FLATMAP q1 -> { SCAN([IS EMP]) | FILTER _.DEPT_ID EQUALS q0.ID AND q1.EMP_ID EQUALS _.ID AS q2 RETURN q1 } AS q1 RETURN ((q0.NAME AS _0, q1.NAME AS _1) AS X) }" - unorderedResult: [{{"Engineering", "OLAP"}}, {{"Sales", "Feedback"}}, {{"Marketing", "SEO"}}] @@ -504,7 +504,7 @@ test_block: - # ambiguous sub-select is fine if the top-level query does not specify column names (select (*)) - query: select (*) from (select dept.name, project.name from emp, dept, project where emp.dept_id = dept.id and project.emp_id = emp.id) X; - - explain: "SCAN([IS DEPT]) | FLATMAP q0 -> { SCAN([IS PROJECT]) | FLATMAP q1 -> { SCAN([IS EMP]) | FILTER _.DEPT_ID EQUALS q0.ID AND q1.EMP_ID EQUALS _.ID AS q2 RETURN q1 } AS q1 RETURN ((q0.NAME AS _0, q1.NAME AS _1) AS _0) }" + - explain: "SCAN([IS DEPT]) | FLATMAP q0 -> { SCAN([IS PROJECT]) | FLATMAP q1 -> { SCAN([IS EMP]) | FILTER _.DEPT_ID EQUALS q0.ID AND q1.EMP_ID EQUALS _.ID AS q2 RETURN q1 } AS q1 RETURN ((q0.NAME AS _0, q1.NAME AS _1) AS X) }" - unorderedResult: [{{"Engineering", "OLAP"}}, {{"Sales", "Feedback"}}, {{"Marketing", "SEO"}}] diff --git a/yaml-tests/src/test/resources/join-with-order-by-tests.yamsql b/yaml-tests/src/test/resources/join-with-order-by-tests.yamsql index 33f517e2db..858492a4cb 100644 --- a/yaml-tests/src/test/resources/join-with-order-by-tests.yamsql +++ b/yaml-tests/src/test/resources/join-with-order-by-tests.yamsql @@ -92,7 +92,7 @@ test_block: - query: select (t1.*), (t2.*) from t1, t2 where t1.a1 = 1 and t2.b1 = 1 and t1.a3 = t2.b3 - - explain: "ISCAN(t2$b1 [EQUALS promote(@c21 AS LONG)]) | FLATMAP q0 -> { ISCAN(t1$a1 [EQUALS promote(@c21 AS LONG)]) | FILTER _.a3 EQUALS q0.b3 AS q1 RETURN ((q1.id AS id, q1.a1 AS a1, q1.a2 AS a2, q1.a3 AS a3) AS _0, (q0.id AS id, q0.b1 AS b1, q0.b2 AS b2, q0.b3 AS b3) AS _1) }" + - explain: "ISCAN(t2$b1 [EQUALS promote(@c21 AS LONG)]) | FLATMAP q0 -> { ISCAN(t1$a1 [EQUALS promote(@c21 AS LONG)]) | FILTER _.a3 EQUALS q0.b3 AS q1 RETURN ((q1.id AS id, q1.a1 AS a1, q1.a2 AS a2, q1.a3 AS a3) AS t1, (q0.id AS id, q0.b1 AS b1, q0.b2 AS b2, q0.b3 AS b3) AS t2) }" - unorderedResult: [ { { id: 1001, a1: 1, a2: 10, a3: "a" }, { id: 2001, b1: 1, b2: 20, b3: "a" } }, { { id: 1001, a1: 1, a2: 10, a3: "a" }, { id: 2002, b1: 1, b2: 19, b3: "a" } }, @@ -108,7 +108,7 @@ test_block: from t1, t2 where t1.a1 = 1 and t2.b1 = 1 and t1.a3 = t2.b3 order by t1.a2 - - explain: "ISCAN(t1$a1_a2 [EQUALS promote(@c21 AS LONG)]) | FLATMAP q0 -> { COVERING(t2$b1_b3 [EQUALS promote(@c21 AS LONG)] -> [b1: KEY:[0], b3: KEY:[1], id: KEY:[2]]) | FILTER q0.a3 EQUALS _.b3 | FETCH AS q1 RETURN ((q0.id AS id, q0.a1 AS a1, q0.a2 AS a2, q0.a3 AS a3) AS _0, (q1.id AS id, q1.b1 AS b1, q1.b2 AS b2, q1.b3 AS b3) AS _1) }" + - explain: "ISCAN(t1$a1_a2 [EQUALS promote(@c21 AS LONG)]) | FLATMAP q0 -> { COVERING(t2$b1_b3 [EQUALS promote(@c21 AS LONG)] -> [b1: KEY:[0], b3: KEY:[1], id: KEY:[2]]) | FILTER q0.a3 EQUALS _.b3 | FETCH AS q1 RETURN ((q0.id AS id, q0.a1 AS a1, q0.a2 AS a2, q0.a3 AS a3) AS t1, (q1.id AS id, q1.b1 AS b1, q1.b2 AS b2, q1.b3 AS b3) AS t2) }" - result: [ { { id: 1001, a1: 1, a2: 10, a3: "a" }, { id: 2001, b1: 1, b2: 20, b3: "a" } }, { { id: 1001, a1: 1, a2: 10, a3: "a" }, { id: 2002, b1: 1, b2: 19, b3: "a" } }, @@ -124,7 +124,7 @@ test_block: from t1, t2 where t1.a1 = 1 and t2.b1 = 1 and t1.a3 = t2.b3 order by t1.a2 desc - - explain: "ISCAN(t1$a1_a2 [EQUALS promote(@c21 AS LONG)] REVERSE) | FLATMAP q0 -> { COVERING(t2$b1_b3 [EQUALS promote(@c21 AS LONG)] -> [b1: KEY:[0], b3: KEY:[1], id: KEY:[2]]) | FILTER q0.a3 EQUALS _.b3 | FETCH AS q1 RETURN ((q0.id AS id, q0.a1 AS a1, q0.a2 AS a2, q0.a3 AS a3) AS _0, (q1.id AS id, q1.b1 AS b1, q1.b2 AS b2, q1.b3 AS b3) AS _1) }" + - explain: "ISCAN(t1$a1_a2 [EQUALS promote(@c21 AS LONG)] REVERSE) | FLATMAP q0 -> { COVERING(t2$b1_b3 [EQUALS promote(@c21 AS LONG)] -> [b1: KEY:[0], b3: KEY:[1], id: KEY:[2]]) | FILTER q0.a3 EQUALS _.b3 | FETCH AS q1 RETURN ((q0.id AS id, q0.a1 AS a1, q0.a2 AS a2, q0.a3 AS a3) AS t1, (q1.id AS id, q1.b1 AS b1, q1.b2 AS b2, q1.b3 AS b3) AS t2) }" - result: [ { { id: 1004, a1: 1, a2: 13, a3: "b" }, { id: 2003, b1: 1, b2: 18, b3: "b" } }, { { id: 1004, a1: 1, a2: 13, a3: "b" }, { id: 2004, b1: 1, b2: 17, b3: "b" } }, @@ -141,7 +141,7 @@ test_block: from t1, t2 where t1.a1 = 1 and t2.b1 = 1 and t1.a3 = t2.b3 order by t1.a2 desc - - explain: "ISCAN(t1$a1_a2 [EQUALS promote(@c15 AS LONG)] REVERSE) | FLATMAP q0 -> { COVERING(t2$b1_b3 [EQUALS promote(@c15 AS LONG)] -> [b1: KEY:[0], b3: KEY:[1], id: KEY:[2]]) | FILTER q0.a3 EQUALS _.b3 | FETCH AS q1 RETURN ((q1.id AS id, q1.b1 AS b1, q1.b2 AS b2, q1.b3 AS b3) AS _0, q0.a2 AS a2) } | MAP (_._0 AS _0)" + - explain: "ISCAN(t1$a1_a2 [EQUALS promote(@c15 AS LONG)] REVERSE) | FLATMAP q0 -> { COVERING(t2$b1_b3 [EQUALS promote(@c15 AS LONG)] -> [b1: KEY:[0], b3: KEY:[1], id: KEY:[2]]) | FILTER q0.a3 EQUALS _.b3 | FETCH AS q1 RETURN ((q1.id AS id, q1.b1 AS b1, q1.b2 AS b2, q1.b3 AS b3) AS t2, q0.a2 AS a2) } | MAP (_.t2 AS t2)" - result: [ { { id: 2003, b1: 1, b2: 18, b3: "b" } }, { { id: 2004, b1: 1, b2: 17, b3: "b" } }, @@ -192,7 +192,7 @@ test_block: from t1_f(1) as x, t2_f(1) as y where x.a3 = y.b3 order by x.a2 desc - - explain: "ISCAN(t1$a1_a2 [EQUALS promote(@c15 AS LONG)] REVERSE) | FLATMAP q0 -> { COVERING(t2$b1_b3 [EQUALS promote(@c15 AS LONG)] -> [b1: KEY:[0], b3: KEY:[1], id: KEY:[2]]) | FILTER q0.a3 EQUALS _.b3 | FETCH AS q1 RETURN ((q0.__ROW_VERSION AS __ROW_VERSION, q0.id AS id, q0.a1 AS a1, q0.a2 AS a2, q0.a3 AS a3) AS _0, (q1.__ROW_VERSION AS __ROW_VERSION, q1.id AS id, q1.b1 AS b1, q1.b2 AS b2, q1.b3 AS b3) AS _1) }" + - explain: "ISCAN(t1$a1_a2 [EQUALS promote(@c15 AS LONG)] REVERSE) | FLATMAP q0 -> { COVERING(t2$b1_b3 [EQUALS promote(@c15 AS LONG)] -> [b1: KEY:[0], b3: KEY:[1], id: KEY:[2]]) | FILTER q0.a3 EQUALS _.b3 | FETCH AS q1 RETURN ((q0.__ROW_VERSION AS __ROW_VERSION, q0.id AS id, q0.a1 AS a1, q0.a2 AS a2, q0.a3 AS a3) AS x, (q1.__ROW_VERSION AS __ROW_VERSION, q1.id AS id, q1.b1 AS b1, q1.b2 AS b2, q1.b3 AS b3) AS y) }" - result: [ { { '__ROW_VERSION': !not_null _, id: 1004, a1: 1, a2: 13, a3: "b" }, { '__ROW_VERSION': !not_null _, id: 2003, b1: 1, b2: 18, b3: "b" } }, { { '__ROW_VERSION': !not_null _, id: 1004, a1: 1, a2: 13, a3: "b" }, { '__ROW_VERSION': !not_null _, id: 2004, b1: 1, b2: 17, b3: "b" } }, @@ -209,7 +209,7 @@ test_block: from t1_f(1) as x, t2_f(1) as y where x.a3 = y.b3 order by x.a2 desc - - explain: "ISCAN(t1$a1_a2 [EQUALS promote(@c9 AS LONG)] REVERSE) | FLATMAP q0 -> { COVERING(t2$b1_b3 [EQUALS promote(@c9 AS LONG)] -> [b1: KEY:[0], b3: KEY:[1], id: KEY:[2]]) | FILTER q0.a3 EQUALS _.b3 | FETCH AS q1 RETURN ((q1.__ROW_VERSION AS __ROW_VERSION, q1.id AS id, q1.b1 AS b1, q1.b2 AS b2, q1.b3 AS b3) AS _0, q0.a2 AS a2) } | MAP (_._0 AS _0)" + - explain: "ISCAN(t1$a1_a2 [EQUALS promote(@c9 AS LONG)] REVERSE) | FLATMAP q0 -> { COVERING(t2$b1_b3 [EQUALS promote(@c9 AS LONG)] -> [b1: KEY:[0], b3: KEY:[1], id: KEY:[2]]) | FILTER q0.a3 EQUALS _.b3 | FETCH AS q1 RETURN ((q1.__ROW_VERSION AS __ROW_VERSION, q1.id AS id, q1.b1 AS b1, q1.b2 AS b2, q1.b3 AS b3) AS y, q0.a2 AS a2) } | MAP (_.y AS y)" - initialVersionLessThan: 4.10.5.0 - error: 'XX000' - initialVersionAtLeast: 4.10.5.0 @@ -229,7 +229,7 @@ test_block: from t1_g(1) as x, t2_g(1) as y where x.a3 = y.b3 order by x.the_a2 desc - - explain: "ISCAN(t1$a1_a2 [EQUALS promote(@c15 AS LONG)] REVERSE) | FLATMAP q0 -> { COVERING(t2$b1_b3 [EQUALS promote(@c15 AS LONG)] -> [b1: KEY:[0], b3: KEY:[1], id: KEY:[2]]) | FILTER q0.a3 EQUALS _.b3 | FETCH AS q1 RETURN ((q0.__ROW_VERSION AS __ROW_VERSION, q0.id AS id, q0.a1 AS a1, q0.a2 AS a2, q0.a3 AS a3, q0.a2 AS the_a2) AS _0, (q1.__ROW_VERSION AS __ROW_VERSION, q1.id AS id, q1.b1 AS b1, q1.b2 AS b2, q1.b3 AS b3, q1.b2 AS the_b2) AS _1) }" + - explain: "ISCAN(t1$a1_a2 [EQUALS promote(@c15 AS LONG)] REVERSE) | FLATMAP q0 -> { COVERING(t2$b1_b3 [EQUALS promote(@c15 AS LONG)] -> [b1: KEY:[0], b3: KEY:[1], id: KEY:[2]]) | FILTER q0.a3 EQUALS _.b3 | FETCH AS q1 RETURN ((q0.__ROW_VERSION AS __ROW_VERSION, q0.id AS id, q0.a1 AS a1, q0.a2 AS a2, q0.a3 AS a3, q0.a2 AS the_a2) AS x, (q1.__ROW_VERSION AS __ROW_VERSION, q1.id AS id, q1.b1 AS b1, q1.b2 AS b2, q1.b3 AS b3, q1.b2 AS the_b2) AS y) }" - result: [ { { '__ROW_VERSION': !not_null _, id: 1004, a1: 1, a2: 13, a3: "b", the_a2: 13 }, { '__ROW_VERSION': !not_null _, id: 2003, b1: 1, b2: 18, b3: "b", the_b2: 18 } }, { { '__ROW_VERSION': !not_null _, id: 1004, a1: 1, a2: 13, a3: "b", the_a2: 13 }, { '__ROW_VERSION': !not_null _, id: 2004, b1: 1, b2: 17, b3: "b", the_b2: 17 } }, @@ -246,7 +246,7 @@ test_block: from t1_g(1) as x, t2_g(1) as y where x.a3 = y.b3 order by x.the_a2 desc - - explain: "ISCAN(t1$a1_a2 [EQUALS promote(@c9 AS LONG)] REVERSE) | FLATMAP q0 -> { COVERING(t2$b1_b3 [EQUALS promote(@c9 AS LONG)] -> [b1: KEY:[0], b3: KEY:[1], id: KEY:[2]]) | FILTER q0.a3 EQUALS _.b3 | FETCH AS q1 RETURN ((q1.__ROW_VERSION AS __ROW_VERSION, q1.id AS id, q1.b1 AS b1, q1.b2 AS b2, q1.b3 AS b3, q1.b2 AS the_b2) AS _0, q0.a2 AS the_a2) } | MAP (_._0 AS _0)" + - explain: "ISCAN(t1$a1_a2 [EQUALS promote(@c9 AS LONG)] REVERSE) | FLATMAP q0 -> { COVERING(t2$b1_b3 [EQUALS promote(@c9 AS LONG)] -> [b1: KEY:[0], b3: KEY:[1], id: KEY:[2]]) | FILTER q0.a3 EQUALS _.b3 | FETCH AS q1 RETURN ((q1.__ROW_VERSION AS __ROW_VERSION, q1.id AS id, q1.b1 AS b1, q1.b2 AS b2, q1.b3 AS b3, q1.b2 AS the_b2) AS y, q0.a2 AS the_a2) } | MAP (_.y AS y)" - initialVersionLessThan: 4.10.5.0 - error: 'XX000' - initialVersionAtLeast: 4.10.5.0 @@ -282,7 +282,7 @@ test_block: from t1, t2 where t1.a1 = 1 and t2.b1 = 1 and t2.b3 = t1.a3 order by t1.a1 asc, t1.a2 desc - - explain: "ISCAN(t1$a1_a2 [EQUALS promote(@c21 AS LONG)] REVERSE) | FLATMAP q0 -> { ISCAN(t2$b1_b3 [EQUALS promote(@c21 AS LONG), EQUALS q0.a3]) AS q1 RETURN ((q0.id AS id, q0.a1 AS a1, q0.a2 AS a2, q0.a3 AS a3) AS _0, (q1.id AS id, q1.b1 AS b1, q1.b2 AS b2, q1.b3 AS b3) AS _1) }" + - explain: "ISCAN(t1$a1_a2 [EQUALS promote(@c21 AS LONG)] REVERSE) | FLATMAP q0 -> { ISCAN(t2$b1_b3 [EQUALS promote(@c21 AS LONG), EQUALS q0.a3]) AS q1 RETURN ((q0.id AS id, q0.a1 AS a1, q0.a2 AS a2, q0.a3 AS a3) AS t1, (q1.id AS id, q1.b1 AS b1, q1.b2 AS b2, q1.b3 AS b3) AS t2) }" - result: [ { { id: 1004, a1: 1, a2: 13, a3: "b" }, { id: 2003, b1: 1, b2: 18, b3: "b" } }, { { id: 1004, a1: 1, a2: 13, a3: "b" }, { id: 2004, b1: 1, b2: 17, b3: "b" } }, @@ -298,7 +298,7 @@ test_block: from t1, t2 where t1.a1 = 1 and t2.b1 = 1 and t1.a3 = t2.b3 order by t2.b3 asc - - explain: "ISCAN(t2$b1_b3 [EQUALS promote(@c21 AS LONG)]) | FLATMAP q0 -> { ISCAN(t1$a1 [EQUALS promote(@c21 AS LONG)]) | FILTER _.a3 EQUALS q0.b3 AS q1 RETURN ((q1.id AS id, q1.a1 AS a1, q1.a2 AS a2, q1.a3 AS a3) AS _0, (q0.id AS id, q0.b1 AS b1, q0.b2 AS b2, q0.b3 AS b3) AS _1) }" + - explain: "ISCAN(t2$b1_b3 [EQUALS promote(@c21 AS LONG)]) | FLATMAP q0 -> { ISCAN(t1$a1 [EQUALS promote(@c21 AS LONG)]) | FILTER _.a3 EQUALS q0.b3 AS q1 RETURN ((q1.id AS id, q1.a1 AS a1, q1.a2 AS a2, q1.a3 AS a3) AS t1, (q0.id AS id, q0.b1 AS b1, q0.b2 AS b2, q0.b3 AS b3) AS t2) }" - result: [ { { id: 1001, a1: 1, a2: 10, a3: "a" }, { id: 2001, b1: 1, b2: 20, b3: "a" } }, { { id: 1003, a1: 1, a2: 12, a3: "a" }, { id: 2001, b1: 1, b2: 20, b3: "a" } }, @@ -314,7 +314,7 @@ test_block: from t1, t2 where t1.a1 = 1 and t2.b1 = 1 and t1.a3 = t2.b3 order by t2.b3 desc - - explain: "ISCAN(t2$b1_b3 [EQUALS promote(@c21 AS LONG)] REVERSE) | FLATMAP q0 -> { ISCAN(t1$a1 [EQUALS promote(@c21 AS LONG)]) | FILTER _.a3 EQUALS q0.b3 AS q1 RETURN ((q1.id AS id, q1.a1 AS a1, q1.a2 AS a2, q1.a3 AS a3) AS _0, (q0.id AS id, q0.b1 AS b1, q0.b2 AS b2, q0.b3 AS b3) AS _1) }" + - explain: "ISCAN(t2$b1_b3 [EQUALS promote(@c21 AS LONG)] REVERSE) | FLATMAP q0 -> { ISCAN(t1$a1 [EQUALS promote(@c21 AS LONG)]) | FILTER _.a3 EQUALS q0.b3 AS q1 RETURN ((q1.id AS id, q1.a1 AS a1, q1.a2 AS a2, q1.a3 AS a3) AS t1, (q0.id AS id, q0.b1 AS b1, q0.b2 AS b2, q0.b3 AS b3) AS t2) }" - result: [ { { id: 1002, a1: 1, a2: 11, a3: "b" }, { id: 2004, b1: 1, b2: 17, b3: "b" } }, { { id: 1004, a1: 1, a2: 13, a3: "b" }, { id: 2004, b1: 1, b2: 17, b3: "b" } }, @@ -330,7 +330,7 @@ test_block: from t1, t2 where t1.a1 = 1 and t2.b1 = 1 order by t1.a2 - - explain: "ISCAN(t1$a1_a2 [EQUALS promote(@c21 AS LONG)]) | FLATMAP q0 -> { ISCAN(t2$b1 [EQUALS promote(@c21 AS LONG)]) AS q1 RETURN ((q0.id AS id, q0.a1 AS a1, q0.a2 AS a2, q0.a3 AS a3) AS _0, (q1.id AS id, q1.b1 AS b1, q1.b2 AS b2, q1.b3 AS b3) AS _1) }" + - explain: "ISCAN(t1$a1_a2 [EQUALS promote(@c21 AS LONG)]) | FLATMAP q0 -> { ISCAN(t2$b1 [EQUALS promote(@c21 AS LONG)]) AS q1 RETURN ((q0.id AS id, q0.a1 AS a1, q0.a2 AS a2, q0.a3 AS a3) AS t1, (q1.id AS id, q1.b1 AS b1, q1.b2 AS b2, q1.b3 AS b3) AS t2) }" - result: [ { { id: 1001, a1: 1, a2: 10, a3: "a" }, { id: 2001, b1: 1, b2: 20, b3: "a" } }, { { id: 1001, a1: 1, a2: 10, a3: "a" }, { id: 2002, b1: 1, b2: 19, b3: "a" } }, @@ -373,7 +373,7 @@ test_block: - query: select (t1.*), (t3.*) from t1, t3 where t1.a1 = 1 and t3.aRef = t1.id - - explain: "ISCAN(t1$a1 [EQUALS promote(@c21 AS LONG)]) | FLATMAP q0 -> { ISCAN(t3$aRef [EQUALS q0.id]) AS q1 RETURN ((q0.id AS id, q0.a1 AS a1, q0.a2 AS a2, q0.a3 AS a3) AS _0, (q1.id AS id, q1.c1 AS c1, q1.c2 AS c2, q1.c3 AS c3, q1.aRef AS aRef) AS _1) }" + - explain: "ISCAN(t1$a1 [EQUALS promote(@c21 AS LONG)]) | FLATMAP q0 -> { ISCAN(t3$aRef [EQUALS q0.id]) AS q1 RETURN ((q0.id AS id, q0.a1 AS a1, q0.a2 AS a2, q0.a3 AS a3) AS t1, (q1.id AS id, q1.c1 AS c1, q1.c2 AS c2, q1.c3 AS c3, q1.aRef AS aRef) AS t3) }" - unorderedResult: [ { { id: 1001, a1: 1, a2: 10, a3: "a" }, { id: 3001, c1: 1, c2: 10, c3: "a", aRef: 1001 } }, { { id: 1002, a1: 1, a2: 11, a3: "b" }, { id: 3002, c1: 1, c2: 11, c3: "a", aRef: 1002 } }, @@ -385,7 +385,7 @@ test_block: from t1, t3 where t1.a1 = 1 and t3.aRef = t1.id order by t1.a2 desc - - explain: "ISCAN(t1$a1_a2 [EQUALS promote(@c21 AS LONG)] REVERSE) | FLATMAP q0 -> { ISCAN(t3$aRef [EQUALS q0.id]) AS q1 RETURN ((q0.id AS id, q0.a1 AS a1, q0.a2 AS a2, q0.a3 AS a3) AS _0, (q1.id AS id, q1.c1 AS c1, q1.c2 AS c2, q1.c3 AS c3, q1.aRef AS aRef) AS _1) }" + - explain: "ISCAN(t1$a1_a2 [EQUALS promote(@c21 AS LONG)] REVERSE) | FLATMAP q0 -> { ISCAN(t3$aRef [EQUALS q0.id]) AS q1 RETURN ((q0.id AS id, q0.a1 AS a1, q0.a2 AS a2, q0.a3 AS a3) AS t1, (q1.id AS id, q1.c1 AS c1, q1.c2 AS c2, q1.c3 AS c3, q1.aRef AS aRef) AS t3) }" - result: [ { { id: 1004, a1: 1, a2: 13, a3: "b" }, { id: 3004, c1: 1, c2: 13, c3: "b", aRef: 1004 } }, { { id: 1003, a1: 1, a2: 12, a3: "a" }, { id: 3003, c1: 1, c2: 12, c3: "b", aRef: 1003 } }, @@ -397,7 +397,7 @@ test_block: from t1, t3 where t1.a1 = 1 and t3.aRef = t1.id order by t3.c1, t3.c2 - - explain: "ISCAN(t3$c1_c2 <,>) | FLATMAP q0 -> { COVERING(t1$a1 [EQUALS promote(@c21 AS LONG)] -> [a1: KEY:[0], id: KEY:[1]]) | FILTER q0.aRef EQUALS _.id | FETCH AS q1 RETURN ((q1.id AS id, q1.a1 AS a1, q1.a2 AS a2, q1.a3 AS a3) AS _0, (q0.id AS id, q0.c1 AS c1, q0.c2 AS c2, q0.c3 AS c3, q0.aRef AS aRef) AS _1) }" + - explain: "ISCAN(t3$c1_c2 <,>) | FLATMAP q0 -> { COVERING(t1$a1 [EQUALS promote(@c21 AS LONG)] -> [a1: KEY:[0], id: KEY:[1]]) | FILTER q0.aRef EQUALS _.id | FETCH AS q1 RETURN ((q1.id AS id, q1.a1 AS a1, q1.a2 AS a2, q1.a3 AS a3) AS t1, (q0.id AS id, q0.c1 AS c1, q0.c2 AS c2, q0.c3 AS c3, q0.aRef AS aRef) AS t3) }" - result: [ { { id: 1001, a1: 1, a2: 10, a3: "a" }, { id: 3001, c1: 1, c2: 10, c3: "a", aRef: 1001 } }, { { id: 1002, a1: 1, a2: 11, a3: "b" }, { id: 3002, c1: 1, c2: 11, c3: "a", aRef: 1002 } }, @@ -410,7 +410,7 @@ test_block: from t1, t3 where t1.a1 = 1 and t1.id = t3.aRef order by t3.c1, t3.c2 - - explain: "ISCAN(t3$c1_c2 <,>) | FLATMAP q0 -> { ISCAN(t1$a1 [EQUALS promote(@c21 AS LONG), EQUALS q0.aRef]) AS q1 RETURN ((q1.id AS id, q1.a1 AS a1, q1.a2 AS a2, q1.a3 AS a3) AS _0, (q0.id AS id, q0.c1 AS c1, q0.c2 AS c2, q0.c3 AS c3, q0.aRef AS aRef) AS _1) }" + - explain: "ISCAN(t3$c1_c2 <,>) | FLATMAP q0 -> { ISCAN(t1$a1 [EQUALS promote(@c21 AS LONG), EQUALS q0.aRef]) AS q1 RETURN ((q1.id AS id, q1.a1 AS a1, q1.a2 AS a2, q1.a3 AS a3) AS t1, (q0.id AS id, q0.c1 AS c1, q0.c2 AS c2, q0.c3 AS c3, q0.aRef AS aRef) AS t3) }" - result: [ { { id: 1001, a1: 1, a2: 10, a3: "a" }, { id: 3001, c1: 1, c2: 10, c3: "a", aRef: 1001 } }, { { id: 1002, a1: 1, a2: 11, a3: "b" }, { id: 3002, c1: 1, c2: 11, c3: "a", aRef: 1002 } }, @@ -531,7 +531,7 @@ test_block: where t1.id = 1003 and t2.b3 >= t1.a3 and t2.b1 = 1 order by t2.b3 # The predicate on t1's primary key means that we can plan the t2 as the inner - - explain: "SCAN([EQUALS promote(@c21 AS LONG)]) | TFILTER t1 | FLATMAP q0 -> { ISCAN(t2$b1_b3 [EQUALS promote(@c36 AS LONG), [GREATER_THAN_OR_EQUALS q0.a3]]) AS q1 RETURN ((q0.id AS id, q0.a1 AS a1, q0.a2 AS a2, q0.a3 AS a3) AS _0, (q1.id AS id, q1.b1 AS b1, q1.b2 AS b2, q1.b3 AS b3) AS _1) }" + - explain: "SCAN([EQUALS promote(@c21 AS LONG)]) | TFILTER t1 | FLATMAP q0 -> { ISCAN(t2$b1_b3 [EQUALS promote(@c36 AS LONG), [GREATER_THAN_OR_EQUALS q0.a3]]) AS q1 RETURN ((q0.id AS id, q0.a1 AS a1, q0.a2 AS a2, q0.a3 AS a3) AS t1, (q1.id AS id, q1.b1 AS b1, q1.b2 AS b2, q1.b3 AS b3) AS t2) }" - result: [ { { id: 1003, a1: 1, a2: 12, a3: "a" }, { id: 2001, b1: 1, b2: 20, b3: "a" } }, { { id: 1003, a1: 1, a2: 12, a3: "a" }, { id: 2002, b1: 1, b2: 19, b3: "a" } }, @@ -563,7 +563,7 @@ test_block: and t1.a1 = t3.c1 and t1.a2 >= t3.c2 order by t1.a2 desc # Uniqueness constraint on t3.(c1, c2) means that we can ensure the max cardinality of the t3 quantifier is 1, so it can be planned as the outer - - explain: "ISCAN(t3$c1_c2 [EQUALS promote(@c21 AS LONG), EQUALS promote(@c27 AS LONG)]) | FLATMAP q0 -> { ISCAN(t1$a1_a2 [EQUALS q0.c1, [GREATER_THAN_OR_EQUALS q0.c2]] REVERSE) AS q1 RETURN ((q1.id AS id, q1.a1 AS a1, q1.a2 AS a2, q1.a3 AS a3) AS _0, (q0.id AS id, q0.c1 AS c1, q0.c2 AS c2, q0.c3 AS c3, q0.aRef AS aRef) AS _1) }" + - explain: "ISCAN(t3$c1_c2 [EQUALS promote(@c21 AS LONG), EQUALS promote(@c27 AS LONG)]) | FLATMAP q0 -> { ISCAN(t1$a1_a2 [EQUALS q0.c1, [GREATER_THAN_OR_EQUALS q0.c2]] REVERSE) AS q1 RETURN ((q1.id AS id, q1.a1 AS a1, q1.a2 AS a2, q1.a3 AS a3) AS t1, (q0.id AS id, q0.c1 AS c1, q0.c2 AS c2, q0.c3 AS c3, q0.aRef AS aRef) AS t3) }" - result: [ { { id: 1004, a1: 1, a2: 13, a3: "b" }, { id: 3003, c1: 1, c2: 12, c3: "b", aRef: 1003 } }, { { id: 1003, a1: 1, a2: 12, a3: "a" }, { id: 3003, c1: 1, c2: 12, c3: "b", aRef: 1003 } }, @@ -574,7 +574,7 @@ test_block: where t3.c1 = 1 and t1.a1 = t3.c1 and t1.a2 >= t3.c2 order by t3.c2 desc - - explain: "ISCAN(t3$c1_c2 [EQUALS promote(@c21 AS LONG)] REVERSE) | FLATMAP q0 -> { ISCAN(t1$a1_a2 [EQUALS q0.c1, [GREATER_THAN_OR_EQUALS q0.c2]]) AS q1 RETURN ((q1.id AS id, q1.a1 AS a1, q1.a2 AS a2, q1.a3 AS a3) AS _0, (q0.id AS id, q0.c1 AS c1, q0.c2 AS c2, q0.c3 AS c3, q0.aRef AS aRef) AS _1) }" + - explain: "ISCAN(t3$c1_c2 [EQUALS promote(@c21 AS LONG)] REVERSE) | FLATMAP q0 -> { ISCAN(t1$a1_a2 [EQUALS q0.c1, [GREATER_THAN_OR_EQUALS q0.c2]]) AS q1 RETURN ((q1.id AS id, q1.a1 AS a1, q1.a2 AS a2, q1.a3 AS a3) AS t1, (q0.id AS id, q0.c1 AS c1, q0.c2 AS c2, q0.c3 AS c3, q0.aRef AS aRef) AS t3) }" - result: [ { { id: 1004, a1: 1, a2: 13, a3: "b" }, { id: 3004, c1: 1, c2: 13, c3: "b", aRef: 1004 } }, @@ -704,7 +704,7 @@ test_block: where t1.a1 IN (1, 2) and t3.aRef = t1.id order by t1.a2 # Order by just a2 gives us an in-union - - explain: "[IN arrayDistinct(promote(@c21 AS ARRAY(LONG)))] INUNION q0 -> { COVERING(t1$a1_a2 [EQUALS q0] -> [a1: KEY:[0], a2: KEY:[1], id: KEY:[2]]) } COMPARE BY (_.a2, _.id, _.a1) | FETCH | FLATMAP q1 -> { ISCAN(t3$aRef [EQUALS q1.id]) AS q2 RETURN ((q1.id AS id, q1.a1 AS a1, q1.a2 AS a2, q1.a3 AS a3) AS _0, (q2.id AS id, q2.c1 AS c1, q2.c2 AS c2, q2.c3 AS c3, q2.aRef AS aRef) AS _1) }" + - explain: "[IN arrayDistinct(promote(@c21 AS ARRAY(LONG)))] INUNION q0 -> { COVERING(t1$a1_a2 [EQUALS q0] -> [a1: KEY:[0], a2: KEY:[1], id: KEY:[2]]) } COMPARE BY (_.a2, _.id, _.a1) | FETCH | FLATMAP q1 -> { ISCAN(t3$aRef [EQUALS q1.id]) AS q2 RETURN ((q1.id AS id, q1.a1 AS a1, q1.a2 AS a2, q1.a3 AS a3) AS t1, (q2.id AS id, q2.c1 AS c1, q2.c2 AS c2, q2.c3 AS c3, q2.aRef AS aRef) AS t3) }" - result: [ { { id: 1101, a1: 2, a2: 5, a3: "a" }, { id: 3101, c1: 2, c2: 7, c3: "c", aRef: 1101 } }, { { id: 1102, a1: 2, a2: 5, a3: "b" }, { id: 3102, c1: 2, c2: 8, c3: "d", aRef: 1102 } }, @@ -721,7 +721,7 @@ test_block: where t1.a1 IN (1, 2) and t3.aRef = t1.id order by t1.a1, t1.a2 # Order by a1, a2 also gives us an in join. - - explain: "[IN arrayDistinct(promote(@c21 AS ARRAY(LONG))) SORTED] | INJOIN q0 -> { ISCAN(t1$a1_a2 [EQUALS q0]) } | FLATMAP q1 -> { ISCAN(t3$aRef [EQUALS q1.id]) AS q2 RETURN ((q1.id AS id, q1.a1 AS a1, q1.a2 AS a2, q1.a3 AS a3) AS _0, (q2.id AS id, q2.c1 AS c1, q2.c2 AS c2, q2.c3 AS c3, q2.aRef AS aRef) AS _1) }" + - explain: "[IN arrayDistinct(promote(@c21 AS ARRAY(LONG))) SORTED] | INJOIN q0 -> { ISCAN(t1$a1_a2 [EQUALS q0]) } | FLATMAP q1 -> { ISCAN(t3$aRef [EQUALS q1.id]) AS q2 RETURN ((q1.id AS id, q1.a1 AS a1, q1.a2 AS a2, q1.a3 AS a3) AS t1, (q2.id AS id, q2.c1 AS c1, q2.c2 AS c2, q2.c3 AS c3, q2.aRef AS aRef) AS t3) }" - result: [ { { id: 1001, a1: 1, a2: 10, a3: "a" }, { id: 3001, c1: 1, c2: 10, c3: "a", aRef: 1001 } }, { { id: 1002, a1: 1, a2: 11, a3: "b" }, { id: 3002, c1: 1, c2: 11, c3: "a", aRef: 1002 } }, @@ -738,7 +738,7 @@ test_block: where t1.a1 IN (1, 2) and t3.aRef = t1.id order by t1.a1 asc, t1.a2 desc # Order by a1, a2 also gives us an in join. - - explain: "[IN arrayDistinct(promote(@c21 AS ARRAY(LONG))) SORTED] | INJOIN q0 -> { ISCAN(t1$a1_a2 [EQUALS q0] REVERSE) } | FLATMAP q1 -> { ISCAN(t3$aRef [EQUALS q1.id]) AS q2 RETURN ((q1.id AS id, q1.a1 AS a1, q1.a2 AS a2, q1.a3 AS a3) AS _0, (q2.id AS id, q2.c1 AS c1, q2.c2 AS c2, q2.c3 AS c3, q2.aRef AS aRef) AS _1) }" + - explain: "[IN arrayDistinct(promote(@c21 AS ARRAY(LONG))) SORTED] | INJOIN q0 -> { ISCAN(t1$a1_a2 [EQUALS q0] REVERSE) } | FLATMAP q1 -> { ISCAN(t3$aRef [EQUALS q1.id]) AS q2 RETURN ((q1.id AS id, q1.a1 AS a1, q1.a2 AS a2, q1.a3 AS a3) AS t1, (q2.id AS id, q2.c1 AS c1, q2.c2 AS c2, q2.c3 AS c3, q2.aRef AS aRef) AS t3) }" - result: [ { { id: 1004, a1: 1, a2: 13, a3: "b" }, { id: 3004, c1: 1, c2: 13, c3: "b", aRef: 1004 } }, { { id: 1003, a1: 1, a2: 12, a3: "a" }, { id: 3003, c1: 1, c2: 12, c3: "b", aRef: 1003 } }, @@ -755,7 +755,7 @@ test_block: where t1.a1 IN (1, 2) and t3.aRef = t1.id order by t1.a1 desc, t1.a2 asc # Order by a1, a2 also gives us an in join. - - explain: "[IN arrayDistinct(promote(@c21 AS ARRAY(LONG))) SORTED DESC] | INJOIN q0 -> { ISCAN(t1$a1_a2 [EQUALS q0]) } | FLATMAP q1 -> { ISCAN(t3$aRef [EQUALS q1.id]) AS q2 RETURN ((q1.id AS id, q1.a1 AS a1, q1.a2 AS a2, q1.a3 AS a3) AS _0, (q2.id AS id, q2.c1 AS c1, q2.c2 AS c2, q2.c3 AS c3, q2.aRef AS aRef) AS _1) }" + - explain: "[IN arrayDistinct(promote(@c21 AS ARRAY(LONG))) SORTED DESC] | INJOIN q0 -> { ISCAN(t1$a1_a2 [EQUALS q0]) } | FLATMAP q1 -> { ISCAN(t3$aRef [EQUALS q1.id]) AS q2 RETURN ((q1.id AS id, q1.a1 AS a1, q1.a2 AS a2, q1.a3 AS a3) AS t1, (q2.id AS id, q2.c1 AS c1, q2.c2 AS c2, q2.c3 AS c3, q2.aRef AS aRef) AS t3) }" - result: [ { { id: 1101, a1: 2, a2: 5, a3: "a" }, { id: 3101, c1: 2, c2: 7, c3: "c", aRef: 1101 } }, { { id: 1102, a1: 2, a2: 5, a3: "b" }, { id: 3102, c1: 2, c2: 8, c3: "d", aRef: 1102 } }, @@ -788,7 +788,7 @@ test_block: - query: select (a.*), (b.*) from t1_f(1) as a, t2_f(1) as b where a.a3 = b.b3 - - explain: "ISCAN(t2$b1 [EQUALS promote(@c15 AS LONG)]) | FLATMAP q0 -> { ISCAN(t1$a1 [EQUALS promote(@c15 AS LONG)]) | FILTER _.a3 EQUALS q0.b3 AS q1 RETURN ((q1.__ROW_VERSION AS __ROW_VERSION, q1.id AS id, q1.a1 AS a1, q1.a2 AS a2, q1.a3 AS a3) AS _0, (q0.__ROW_VERSION AS __ROW_VERSION, q0.id AS id, q0.b1 AS b1, q0.b2 AS b2, q0.b3 AS b3) AS _1) }" + - explain: "ISCAN(t2$b1 [EQUALS promote(@c15 AS LONG)]) | FLATMAP q0 -> { ISCAN(t1$a1 [EQUALS promote(@c15 AS LONG)]) | FILTER _.a3 EQUALS q0.b3 AS q1 RETURN ((q1.__ROW_VERSION AS __ROW_VERSION, q1.id AS id, q1.a1 AS a1, q1.a2 AS a2, q1.a3 AS a3) AS a, (q0.__ROW_VERSION AS __ROW_VERSION, q0.id AS id, q0.b1 AS b1, q0.b2 AS b2, q0.b3 AS b3) AS b) }" - unorderedResult: [ { { '__ROW_VERSION': !not_null _, id: 1001, a1: 1, a2: 10, a3: "a" }, { '__ROW_VERSION': !not_null _, id: 2001, b1: 1, b2: 20, b3: "a" } }, { { '__ROW_VERSION': !not_null _, id: 1001, a1: 1, a2: 10, a3: "a" }, { '__ROW_VERSION': !not_null _, id: 2002, b1: 1, b2: 19, b3: "a" } }, @@ -804,7 +804,7 @@ test_block: from t1_f(1) as a, t2_f(1) as b where a.a3 = b.b3 order by a.a2 - - explain: "ISCAN(t1$a1_a2 [EQUALS promote(@c15 AS LONG)]) | FLATMAP q0 -> { COVERING(t2$b1_b3 [EQUALS promote(@c15 AS LONG)] -> [b1: KEY:[0], b3: KEY:[1], id: KEY:[2]]) | FILTER q0.a3 EQUALS _.b3 | FETCH AS q1 RETURN ((q0.__ROW_VERSION AS __ROW_VERSION, q0.id AS id, q0.a1 AS a1, q0.a2 AS a2, q0.a3 AS a3) AS _0, (q1.__ROW_VERSION AS __ROW_VERSION, q1.id AS id, q1.b1 AS b1, q1.b2 AS b2, q1.b3 AS b3) AS _1) }" + - explain: "ISCAN(t1$a1_a2 [EQUALS promote(@c15 AS LONG)]) | FLATMAP q0 -> { COVERING(t2$b1_b3 [EQUALS promote(@c15 AS LONG)] -> [b1: KEY:[0], b3: KEY:[1], id: KEY:[2]]) | FILTER q0.a3 EQUALS _.b3 | FETCH AS q1 RETURN ((q0.__ROW_VERSION AS __ROW_VERSION, q0.id AS id, q0.a1 AS a1, q0.a2 AS a2, q0.a3 AS a3) AS a, (q1.__ROW_VERSION AS __ROW_VERSION, q1.id AS id, q1.b1 AS b1, q1.b2 AS b2, q1.b3 AS b3) AS b) }" - result: [ { { '__ROW_VERSION': !not_null _, id: 1001, a1: 1, a2: 10, a3: "a" }, { '__ROW_VERSION': !not_null _, id: 2001, b1: 1, b2: 20, b3: "a" } }, { { '__ROW_VERSION': !not_null _, id: 1001, a1: 1, a2: 10, a3: "a" }, { '__ROW_VERSION': !not_null _, id: 2002, b1: 1, b2: 19, b3: "a" } }, @@ -820,7 +820,7 @@ test_block: from t1_f(1) as a, t2_f(1) as b where a.a3 = b.b3 order by b.b3 - - explain: "ISCAN(t2$b1_b3 [EQUALS promote(@c15 AS LONG)]) | FLATMAP q0 -> { ISCAN(t1$a1 [EQUALS promote(@c15 AS LONG)]) | FILTER _.a3 EQUALS q0.b3 AS q1 RETURN ((q1.__ROW_VERSION AS __ROW_VERSION, q1.id AS id, q1.a1 AS a1, q1.a2 AS a2, q1.a3 AS a3) AS _0, (q0.__ROW_VERSION AS __ROW_VERSION, q0.id AS id, q0.b1 AS b1, q0.b2 AS b2, q0.b3 AS b3) AS _1) }" + - explain: "ISCAN(t2$b1_b3 [EQUALS promote(@c15 AS LONG)]) | FLATMAP q0 -> { ISCAN(t1$a1 [EQUALS promote(@c15 AS LONG)]) | FILTER _.a3 EQUALS q0.b3 AS q1 RETURN ((q1.__ROW_VERSION AS __ROW_VERSION, q1.id AS id, q1.a1 AS a1, q1.a2 AS a2, q1.a3 AS a3) AS a, (q0.__ROW_VERSION AS __ROW_VERSION, q0.id AS id, q0.b1 AS b1, q0.b2 AS b2, q0.b3 AS b3) AS b) }" - result: [ { { '__ROW_VERSION': !not_null _, id: 1001, a1: 1, a2: 10, a3: "a" }, { '__ROW_VERSION': !not_null _, id: 2001, b1: 1, b2: 20, b3: "a" } }, { { '__ROW_VERSION': !not_null _, id: 1003, a1: 1, a2: 12, a3: "a" }, { '__ROW_VERSION': !not_null _, id: 2001, b1: 1, b2: 20, b3: "a" } }, diff --git a/yaml-tests/src/test/resources/orderby.yamsql b/yaml-tests/src/test/resources/orderby.yamsql index f68730d413..54613f7652 100644 --- a/yaml-tests/src/test/resources/orderby.yamsql +++ b/yaml-tests/src/test/resources/orderby.yamsql @@ -279,13 +279,13 @@ test_block: # Ordering by a ambiguous projected column in subquery - query: select (T.*) from (select q as "nested", q.a as "ordered" from t2) as T order by "ordered" - supported_version: 4.10.1.0 - - explain: "ISCAN(I4 <,>) | MAP ((_.Q AS nested, _.Q.A AS ordered) AS _0)" + - explain: "ISCAN(I4 <,>) | MAP ((_.Q AS nested, _.Q.A AS ordered) AS T)" - result: [ {{{1, 2}, 1}}, {{{2, 1}, 2}}, {{{3, 2}, 3}}, {{{4, 1}, 4}}, {{{5, 2}, 5}}, {{{6, 1}, 6}}, {{{7, 2}, 7}}, {{{8, 1}, 8}} ] - # Ordering by a column in table function that has been projected in multiple ways - query: select (*) from t2_func() order by "ordered" - supported_version: 4.10.1.0 - - explain: "ISCAN(I4 <,>) | MAP ((_.Q AS nesting, _.Q.A AS ordered) AS _0)" + - explain: "ISCAN(I4 <,>) | MAP ((_.Q AS nesting, _.Q.A AS ordered) AS T2_FUNC)" - result: [ {{{1, 2}, 1}}, {{{2, 1}, 2}}, {{{3, 2}, 3}}, {{{4, 1}, 4}}, {{{5, 2}, 5}}, {{{6, 1}, 6}}, {{{7, 2}, 7}}, {{{8, 1}, 8}} ] - # Ordering by a column in table function that has been projected in multiple ways diff --git a/yaml-tests/src/test/resources/pseudo-field-clash.yamsql b/yaml-tests/src/test/resources/pseudo-field-clash.yamsql index a8533397c7..9f65a41bc3 100644 --- a/yaml-tests/src/test/resources/pseudo-field-clash.yamsql +++ b/yaml-tests/src/test/resources/pseudo-field-clash.yamsql @@ -243,7 +243,7 @@ test_block: - query: SELECT (t1.*), (t2.*), (t3.*) FROM t1, t2, t3 WHERE t2.id = t1.id AND t3.id = t1.id - - explain: "SCAN([IS T1]) | FLATMAP q0 -> { SCAN([IS T3, EQUALS q0.ID]) | FLATMAP q1 -> { SCAN([IS T2, EQUALS q0.ID]) AS q2 RETURN (q2 AS _0, q1 AS _1) } AS q3 RETURN (q0 AS _0, q3._0 AS _1, (q3._1.ID AS ID, q3._1.COL1 AS COL1, q3._1.COL2 AS COL2) AS _2) }" + - explain: "SCAN([IS T1]) | FLATMAP q0 -> { SCAN([IS T3, EQUALS q0.ID]) | FLATMAP q1 -> { SCAN([IS T2, EQUALS q0.ID]) AS q2 RETURN (q2 AS _0, q1 AS _1) } AS q3 RETURN (q0 AS T1, q3._0 AS T2, (q3._1.ID AS ID, q3._1.COL1 AS COL1, q3._1.COL2 AS COL2) AS T3) }" - unorderedResult: [ { { ID: 1, COL1: "a", '__ROW_VERSION': x'0000' }, { ID: 1, COL1: 10, '__ROW_VERSION': "aa" }, { ID: 1, COL1: 10, COL2: "aa" } }, { { ID: 2, COL1: "b", '__ROW_VERSION': x'0001' }, { ID: 2, COL1: 20, '__ROW_VERSION': "ab" }, { ID: 2, COL1: 20, COL2: "ab" } }, diff --git a/yaml-tests/src/test/resources/valid-identifiers.yamsql b/yaml-tests/src/test/resources/valid-identifiers.yamsql index 2d29a98006..8e71d2f205 100644 --- a/yaml-tests/src/test/resources/valid-identifiers.yamsql +++ b/yaml-tests/src/test/resources/valid-identifiers.yamsql @@ -460,7 +460,7 @@ test_block: - # named record construction with uid star - query: select struct "x$$" ("foo.tableA".*) from "foo.tableA" - - explain: "ISCAN(foo.tableA.idx3 <,>) | MAP (_ AS _0)" + - explain: "ISCAN(foo.tableA.idx3 <,>) | MAP (_ AS foo.tableA)" - result: [{{"foo.tableA.A1": 1 , "foo.tableA.A2": 10, "foo.tableA.A3": 1}}, {{"foo.tableA.A1": 2, "foo.tableA.A2": 10, "foo.tableA.A3": 2}}, {{"foo.tableA.A1": 3, "foo.tableA.A2": 10, "foo.tableA.A3": 3}}] - # named record construction with aliased expressions diff --git a/yaml-tests/src/test/resources/versions-tests.yamsql b/yaml-tests/src/test/resources/versions-tests.yamsql index 59ed76260c..91221b274b 100644 --- a/yaml-tests/src/test/resources/versions-tests.yamsql +++ b/yaml-tests/src/test/resources/versions-tests.yamsql @@ -228,7 +228,7 @@ test_block: - # Do not include __ROW_VERSION (as a pseudo-column) in nested (*) with identifier - query: select (t1.*) from t1 where col1 = 10; - - explain: "ISCAN(I1 [EQUALS promote(@c11 AS LONG)]) | MAP ((_.ID AS ID, _.COL1 AS COL1, _.COL2 AS COL2) AS _0)" + - explain: "ISCAN(I1 [EQUALS promote(@c11 AS LONG)]) | MAP ((_.ID AS ID, _.COL1 AS COL1, _.COL2 AS COL2) AS T1)" - result: [ { {ID: 1, COL1: 10, COL2: 1} }, { {ID: 2, COL1: 10, COL2: 2} }, @@ -250,7 +250,7 @@ test_block: - # Do not include __ROW_VERSION (as a pseudo-column) in a nested element when there is a type alias - query: select (a.*) from t1 as a where a.col1 = 10; - - explain: "ISCAN(I1 [EQUALS promote(@c15 AS LONG)]) | MAP ((_.ID AS ID, _.COL1 AS COL1, _.COL2 AS COL2) AS _0)" + - explain: "ISCAN(I1 [EQUALS promote(@c15 AS LONG)]) | MAP ((_.ID AS ID, _.COL1 AS COL1, _.COL2 AS COL2) AS A)" - result: [ { { ID: 1, COL1: 10, COL2: 1 } }, { { ID: 2, COL1: 10, COL2: 2 } }, @@ -291,7 +291,7 @@ test_block: - # Do not include __ROW_VERSION (as a pseudo-column) in nested (*) without identifier - query: select (*) from t1 where col1 = 10; - - explain: "ISCAN(I1 [EQUALS promote(@c9 AS LONG)]) | MAP ((_.ID AS ID, _.COL1 AS COL1, _.COL2 AS COL2) AS _0)" + - explain: "ISCAN(I1 [EQUALS promote(@c9 AS LONG)]) | MAP ((_.ID AS ID, _.COL1 AS COL1, _.COL2 AS COL2) AS T1)" - result: [ { {ID: 1, COL1: 10, COL2: 1} }, { {ID: 2, COL1: 10, COL2: 2} }, @@ -325,7 +325,7 @@ test_block: - result: [{VERSION: !not_null _, ID: 6, COL1: 20, COL2: 6}, {VERSION: !not_null _, ID: 7, COL1: 20, COL2: 7}, {VERSION: !not_null _, ID: 8, COL1: 20, COL2: 8}, {VERSION: !not_null _, ID: 9, COL1: 20, COL2: 9}, {VERSION: !not_null _, ID: 10, COL1: 20, COL2: 10}, {VERSION: !not_null _, ID: 11, COL1: 20, COL2: 11}, {VERSION: !not_null _, ID: 12, COL1: 20, COL2: 12}, {VERSION: !not_null _, ID: 13, COL1: 20, COL2: 13}] - - query: select "__ROW_VERSION" as version, (t1.*) from t1 where col1 = 20; - - explain: "ISCAN(I1 [EQUALS promote(@c15 AS LONG)]) | MAP (_.__ROW_VERSION AS VERSION, (_.ID AS ID, _.COL1 AS COL1, _.COL2 AS COL2) AS _1)" + - explain: "ISCAN(I1 [EQUALS promote(@c15 AS LONG)]) | MAP (_.__ROW_VERSION AS VERSION, (_.ID AS ID, _.COL1 AS COL1, _.COL2 AS COL2) AS T1)" - result: [{VERSION: !not_null _, {ID: 6, COL1: 20, COL2: 6}}, {VERSION: !not_null _, {ID: 7, COL1: 20, COL2: 7}}, {VERSION: !not_null _, {ID: 8, COL1: 20, COL2: 8}}, {VERSION: !not_null _, {ID: 9, COL1: 20, COL2: 9}}, {VERSION: !not_null _, {ID: 10, COL1: 20, COL2: 10}}, {VERSION: !not_null _, {ID: 11, COL1: 20, COL2: 11}}, {VERSION: !not_null _, {ID: 12, COL1: 20, COL2: 12}}, {VERSION: !not_null _, {ID: 13, COL1: 20, COL2: 13}}] - - query: select "__ROW_VERSION", t1.* from t1 where col1 = 20; @@ -333,7 +333,7 @@ test_block: - result: [{__ROW_VERSION: !not_null _, ID: 6, COL1: 20, COL2: 6}, {__ROW_VERSION: !not_null _, ID: 7, COL1: 20, COL2: 7}, {__ROW_VERSION: !not_null _, ID: 8, COL1: 20, COL2: 8}, {__ROW_VERSION: !not_null _, ID: 9, COL1: 20, COL2: 9}, {__ROW_VERSION: !not_null _, ID: 10, COL1: 20, COL2: 10}, {__ROW_VERSION: !not_null _, ID: 11, COL1: 20, COL2: 11}, {__ROW_VERSION: !not_null _, ID: 12, COL1: 20, COL2: 12}, {__ROW_VERSION: !not_null _, ID: 13, COL1: 20, COL2: 13}] - - query: select "__ROW_VERSION", (t1.*) from t1 where col1 = 20; - - explain: "ISCAN(I1 [EQUALS promote(@c13 AS LONG)]) | MAP (_.__ROW_VERSION AS __ROW_VERSION, (_.ID AS ID, _.COL1 AS COL1, _.COL2 AS COL2) AS _1)" + - explain: "ISCAN(I1 [EQUALS promote(@c13 AS LONG)]) | MAP (_.__ROW_VERSION AS __ROW_VERSION, (_.ID AS ID, _.COL1 AS COL1, _.COL2 AS COL2) AS T1)" - result: [{__ROW_VERSION: !not_null _, {ID: 6, COL1: 20, COL2: 6}}, {__ROW_VERSION: !not_null _, {ID: 7, COL1: 20, COL2: 7}}, {__ROW_VERSION: !not_null _, {ID: 8, COL1: 20, COL2: 8}}, {__ROW_VERSION: !not_null _, {ID: 9, COL1: 20, COL2: 9}}, {__ROW_VERSION: !not_null _, {ID: 10, COL1: 20, COL2: 10}}, {__ROW_VERSION: !not_null _, {ID: 11, COL1: 20, COL2: 11}}, {__ROW_VERSION: !not_null _, {ID: 12, COL1: 20, COL2: 12}}, {__ROW_VERSION: !not_null _, {ID: 13, COL1: 20, COL2: 13}}] - # Non-version query that should be able to make use of the covering index @@ -439,7 +439,7 @@ test_block: - # Simple star select ordered by newest first. The row version and data are packaged up. The row version should not be in the nested star - query: select (t1."__ROW_VERSION", (t1.*)) from t1 where col1 = 10 order by "__ROW_VERSION" desc; - - explain: "ISCAN(GROUPED_VERSION_INDEX [EQUALS promote(@c17 AS LONG)] REVERSE) | MAP ((_.__ROW_VERSION AS __ROW_VERSION, (_.ID AS ID, _.COL1 AS COL1, _.COL2 AS COL2) AS _1) AS _0)" + - explain: "ISCAN(GROUPED_VERSION_INDEX [EQUALS promote(@c17 AS LONG)] REVERSE) | MAP ((_.__ROW_VERSION AS __ROW_VERSION, (_.ID AS ID, _.COL1 AS COL1, _.COL2 AS COL2) AS T1) AS _0)" - result: [ { { '__ROW_VERSION': !not_null _, { ID: 4, COL1: 10, COL2: 4 }, }, }, { { '__ROW_VERSION': !not_null _, { ID: 2, COL1: 10, COL2: 2 }, }, }, @@ -581,7 +581,7 @@ test_block: - query: select "__ROW_VERSION", (a.*), (b.*) from t1 as a, (select * from t2) b where a.col2 = b.col1 - - explain: "ISCAN(I1 <,>) | FLATMAP q0 -> { ISCAN(T2_COL2 <,>) | FILTER q0.COL2 EQUALS _.COL1 AS q1 RETURN (q0.__ROW_VERSION AS __ROW_VERSION, (q0.ID AS ID, q0.COL1 AS COL1, q0.COL2 AS COL2) AS _1, (q1.ID AS ID, q1.COL1 AS COL1, q1.COL2 AS COL2) AS _2) }" + - explain: "ISCAN(I1 <,>) | FLATMAP q0 -> { ISCAN(T2_COL2 <,>) | FILTER q0.COL2 EQUALS _.COL1 AS q1 RETURN (q0.__ROW_VERSION AS __ROW_VERSION, (q0.ID AS ID, q0.COL1 AS COL1, q0.COL2 AS COL2) AS A, (q1.ID AS ID, q1.COL1 AS COL1, q1.COL2 AS COL2) AS B) }" - initialVersionLessThan: 4.10.1.0 # Prior to 4.10.1.0, we did not keep track of which quantifiers actually had the version, so this would default to # assuming that the row version column was ambiguous @@ -704,7 +704,7 @@ test_block: - query: select (t2.*), (t3.*) from t2, t3 where t2.col2 = 'b' and t3.col1 = 'b' - - explain: "ISCAN(T2_COL2 [EQUALS promote(@c21 AS STRING)]) | FLATMAP q0 -> { COVERING(T3_VERSION_WITH_COL1 <,> -> [COL1: VALUE:[0], ID: KEY:[2]]) | FILTER _.COL1 EQUALS promote(@c21 AS STRING) | FETCH AS q1 RETURN ((q0.ID AS ID, q0.COL1 AS COL1, q0.COL2 AS COL2) AS _0, (q1.ID AS ID, q1.COL1 AS COL1, q1.COL2 AS COL2) AS _1) }" + - explain: "ISCAN(T2_COL2 [EQUALS promote(@c21 AS STRING)]) | FLATMAP q0 -> { COVERING(T3_VERSION_WITH_COL1 <,> -> [COL1: VALUE:[0], ID: KEY:[2]]) | FILTER _.COL1 EQUALS promote(@c21 AS STRING) | FETCH AS q1 RETURN ((q0.ID AS ID, q0.COL1 AS COL1, q0.COL2 AS COL2) AS T2, (q1.ID AS ID, q1.COL1 AS COL1, q1.COL2 AS COL2) AS T3) }" - unorderedResult: [ { { ID: 3, COL1: 1, COL2: 'b' }, { ID: 3, COL1: 'b', COL2: 1 } }, { { ID: 4, COL1: 2, COL2: 'b' }, { ID: 3, COL1: 'b', COL2: 1 } }, @@ -748,7 +748,7 @@ test_block: from t2, t3 where t2.col2 = 'b' and t3.col1 = 'b' and t2."__ROW_VERSION" > t3."__ROW_VERSION" - - explain: "ISCAN(T2_COL2 [EQUALS promote(@c21 AS STRING)]) | FLATMAP q0 -> { ISCAN(T3_VERSION_WITH_COL1 <,>) | FILTER _.COL1 EQUALS promote(@c21 AS STRING) AND q0.__ROW_VERSION GREATER_THAN _.__ROW_VERSION AS q1 RETURN ((q0.ID AS ID, q0.COL1 AS COL1, q0.COL2 AS COL2) AS _0, (q1.ID AS ID, q1.COL1 AS COL1, q1.COL2 AS COL2) AS _1) }" + - explain: "ISCAN(T2_COL2 [EQUALS promote(@c21 AS STRING)]) | FLATMAP q0 -> { ISCAN(T3_VERSION_WITH_COL1 <,>) | FILTER _.COL1 EQUALS promote(@c21 AS STRING) AND q0.__ROW_VERSION GREATER_THAN _.__ROW_VERSION AS q1 RETURN ((q0.ID AS ID, q0.COL1 AS COL1, q0.COL2 AS COL2) AS T2, (q1.ID AS ID, q1.COL1 AS COL1, q1.COL2 AS COL2) AS T3) }" - initialVersionLessThan: 4.10.1.0 # Prior to 4.10.1.0, the two row version predicates would be transformed incorrectly so that they were # evaluated twice on the same record (i.e., `version([_]) > version([_])`) which is a contradiction, so we @@ -771,7 +771,7 @@ test_block: - query: select (A.*), (B.*) from t2_v(2) as A, t3_v(2) as B where A.col2 = B.col1 - - explain: "ISCAN(T3_VERSION_WITH_COL1 <,>) | FILTER _.COL2 EQUALS promote(@c15 AS LONG) | FLATMAP q0 -> { ISCAN(T2_COL2 [EQUALS q0.COL1]) | FILTER _.COL1 EQUALS promote(@c15 AS LONG) AS q1 RETURN ((q1.__ROW_VERSION AS __ROW_VERSION, q1.ID AS ID, q1.COL1 AS COL1, q1.COL2 AS COL2) AS _0, (q0.__ROW_VERSION AS __ROW_VERSION, q0.ID AS ID, q0.COL1 AS COL1, q0.COL2 AS COL2) AS _1) }" + - explain: "ISCAN(T3_VERSION_WITH_COL1 <,>) | FILTER _.COL2 EQUALS promote(@c15 AS LONG) | FLATMAP q0 -> { ISCAN(T2_COL2 [EQUALS q0.COL1]) | FILTER _.COL1 EQUALS promote(@c15 AS LONG) AS q1 RETURN ((q1.__ROW_VERSION AS __ROW_VERSION, q1.ID AS ID, q1.COL1 AS COL1, q1.COL2 AS COL2) AS A, (q0.__ROW_VERSION AS __ROW_VERSION, q0.ID AS ID, q0.COL1 AS COL1, q0.COL2 AS COL2) AS B) }" - unorderedResult: [ { { '__ROW_VERSION': !not_null _, ID: 4, COL1: 2, COL2: 'b' }, { '__ROW_VERSION': !not_null _, ID: 4, COL1: 'b', COL2: 2 } }, { { '__ROW_VERSION': !not_null _, ID: 2, COL1: 2, COL2: 'a' }, { '__ROW_VERSION': !not_null _, ID: 1, COL1: 'a', COL2: 2 } },