You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ko...@apache.org on 2025/05/29 11:04:18 UTC
(ignite-3) branch main updated: IGNITE-25471 Sql. Introduce custom infrastructure for rel explanation (#5916)
This is an automated email from the ASF dual-hosted git repository.
korlov pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git
The following commit(s) were added to refs/heads/main by this push:
new e1074283d8f IGNITE-25471 Sql. Introduce custom infrastructure for rel explanation (#5916)
e1074283d8f is described below
commit e1074283d8f247e498ee310bdee7d5ba069c5da0
Author: korlov42 <ko...@apache.org>
AuthorDate: Thu May 29 14:04:13 2025 +0300
IGNITE-25471 Sql. Introduce custom infrastructure for rel explanation (#5916)
---
.../internal/sql/engine/ItOrToUnionRuleTest.java | 14 +-
.../internal/sql/engine/ItSecondaryIndexTest.java | 2 +-
.../integrationTest/sql/group1/explain/modify.test | 200 +++++-----
.../integrationTest/sql/group1/explain/scan.test | 135 ++++---
.../internal/sql/engine/prepare/ExplainUtils.java | 45 ---
.../sql/engine/prepare/KeyValueGetPlan.java | 1 +
.../sql/engine/prepare/KeyValueModifyPlan.java | 1 +
.../internal/sql/engine/prepare/MultiStepPlan.java | 1 +
.../sql/engine/prepare/SelectCountPlan.java | 1 +
.../sql/engine/rel/AbstractIgniteJoin.java | 8 +
.../internal/sql/engine/rel/AbstractIndexScan.java | 13 +
.../internal/sql/engine/rel/IgniteAggregate.java | 17 +
.../engine/rel/IgniteCorrelatedNestedLoopJoin.java | 6 +
.../internal/sql/engine/rel/IgniteExchange.java | 6 +
.../internal/sql/engine/rel/IgniteFilter.java | 6 +
.../internal/sql/engine/rel/IgniteIndexScan.java | 12 +
.../internal/sql/engine/rel/IgniteKeyValueGet.java | 7 +
.../sql/engine/rel/IgniteKeyValueModify.java | 23 +-
.../internal/sql/engine/rel/IgniteLimit.java | 14 +
.../internal/sql/engine/rel/IgniteMergeJoin.java | 5 +-
.../internal/sql/engine/rel/IgniteProject.java | 6 +
.../ignite/internal/sql/engine/rel/IgniteRel.java | 13 +
.../internal/sql/engine/rel/IgniteSelectCount.java | 16 +
.../ignite/internal/sql/engine/rel/IgniteSort.java | 14 +
.../sql/engine/rel/IgniteSystemViewScan.java | 7 +
.../sql/engine/rel/IgniteTableFunctionScan.java | 6 +
.../internal/sql/engine/rel/IgniteTableModify.java | 12 +-
.../internal/sql/engine/rel/IgniteTableScan.java | 7 +
.../sql/engine/rel/IgniteTrimExchange.java | 6 +
.../internal/sql/engine/rel/IgniteValues.java | 7 +
.../engine/rel/ProjectableFilterableTableScan.java | 39 +-
.../rel/agg/IgniteColocatedSortAggregate.java | 6 +
.../sql/engine/rel/agg/IgniteMapSortAggregate.java | 6 +
.../engine/rel/agg/IgniteReduceAggregateBase.java | 24 +-
.../engine/rel/agg/IgniteReduceSortAggregate.java | 6 +
.../sql/engine/rel/explain/ExplainUtils.java | 83 ++++
.../sql/engine/rel/explain/IgniteRelWriter.java | 223 +++++++++++
.../engine/rel/explain/RelTreeToTextWriter.java | 439 +++++++++++++++++++++
.../sql/engine/rel/set/IgniteIntersect.java | 6 +
.../internal/sql/engine/rel/set/IgniteMinus.java | 6 +
.../src/test/resources/tpcds/plan/q64.plan | 289 +++++++-------
.../test/resources/tpcds/plan/q64_colocated.plan | 289 +++++++-------
.../src/test/resources/tpch/plan/q1.plan | 21 +-
.../src/test/resources/tpch/plan/q21.plan | 81 ++--
.../src/test/resources/tpch/plan/q5.plan | 43 +-
.../src/test/resources/tpch/plan/q7.plan | 46 +--
.../src/test/resources/tpch/plan/q8.plan | 62 +--
.../src/test/resources/tpch/plan/q9.plan | 41 +-
.../internal/sql/engine/util/QueryChecker.java | 9 +-
49 files changed, 1670 insertions(+), 660 deletions(-)
diff --git a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItOrToUnionRuleTest.java b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItOrToUnionRuleTest.java
index b2b8e83a425..d1c8e209e69 100644
--- a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItOrToUnionRuleTest.java
+++ b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItOrToUnionRuleTest.java
@@ -99,7 +99,7 @@ public class ItOrToUnionRuleTest extends BaseSqlIntegrationTest {
+ "WHERE category = 'Video' "
+ "OR subcategory ='Camera Lens'")
.disableRules("LogicalTableScanConverterRule")
- .matches(containsUnion(true))
+ .matches(containsUnion())
.matches(containsIndexScan("PUBLIC", "PRODUCTS", "IDX_CATEGORY"))
.matches(containsIndexScan("PUBLIC", "PRODUCTS", "IDX_SUBCATEGORY"))
.returns(3, "Photo", 1, "Camera Lens", 12, "Lens 1")
@@ -120,7 +120,7 @@ public class ItOrToUnionRuleTest extends BaseSqlIntegrationTest {
+ "WHERE category = 'Photo' "
+ "OR (subcat_id > 12 AND subcat_id < 22)")
.disableRules("LogicalTableScanConverterRule")
- .matches(containsUnion(true))
+ .matches(containsUnion())
.matches(containsIndexScan("PUBLIC", "PRODUCTS", "IDX_CATEGORY"))
.matches(containsIndexScan("PUBLIC", "PRODUCTS", "IDX_SUBCAT_ID"))
.returns(1, "Photo", 1, "Camera Media", 11, "Media 1")
@@ -143,7 +143,7 @@ public class ItOrToUnionRuleTest extends BaseSqlIntegrationTest {
+ "WHERE subcategory = 'Camera Lens' "
+ "OR subcategory = 'Other'")
.disableRules("LogicalTableScanConverterRule")
- .matches(not(containsUnion(true)))
+ .matches(not(containsUnion()))
.matches(containsIndexScan("PUBLIC", "PRODUCTS", "IDX_SUBCATEGORY"))
.matches(containsString("searchBounds: [MultiBounds"))
.returns(3, "Photo", 1, "Camera Lens", 12, "Lens 1")
@@ -162,7 +162,7 @@ public class ItOrToUnionRuleTest extends BaseSqlIntegrationTest {
+ "FROM products "
+ "WHERE cat_id > 1 "
+ "OR subcat_id < 10")
- .matches(not(containsUnion(true)))
+ .matches(not(containsUnion()))
.matches(containsTableScan("PUBLIC", "PRODUCTS"))
.returns(5, "Video", 2, "Camera Media", 21, "Media 3")
.returns(6, "Video", 2, "Camera Lens", 22, "Lens 3")
@@ -177,7 +177,7 @@ public class ItOrToUnionRuleTest extends BaseSqlIntegrationTest {
@Test
public void testUnionRuleNotApplicable() {
assertQuery("SELECT * FROM products WHERE name = 'Canon' OR subcat_id = 22")
- .matches(not(containsUnion(true)))
+ .matches(not(containsUnion()))
.matches(containsTableScan("PUBLIC", "PRODUCTS"))
.returns(7, "Video", 1, null, 0, "Canon")
.returns(6, "Video", 2, "Camera Lens", 22, "Lens 3")
@@ -193,7 +193,7 @@ public class ItOrToUnionRuleTest extends BaseSqlIntegrationTest {
+ "FROM products "
+ "WHERE name = 'Canon' "
+ "OR category = 'Video'")
- .matches(not(containsUnion(true)))
+ .matches(not(containsUnion()))
.matches(containsTableScan("PUBLIC", "PRODUCTS"))
.returns(5, "Video", 2, "Camera Media", 21, "Media 3")
.returns(6, "Video", 2, "Camera Lens", 22, "Lens 3")
@@ -210,7 +210,7 @@ public class ItOrToUnionRuleTest extends BaseSqlIntegrationTest {
+ "FROM products "
+ "WHERE name = 'Canon' "
+ "OR name = 'Sony'")
- .matches(not(containsUnion(true)))
+ .matches(not(containsUnion()))
.matches(containsTableScan("PUBLIC", "PRODUCTS"))
.returns(7, "Video", 1, null, 0, "Canon")
.check();
diff --git a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItSecondaryIndexTest.java b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItSecondaryIndexTest.java
index 0982f6f1744..50ce4f1792f 100644
--- a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItSecondaryIndexTest.java
+++ b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItSecondaryIndexTest.java
@@ -599,7 +599,7 @@ public class ItSecondaryIndexTest extends BaseSqlIntegrationTest {
public void testOrCondition5() {
assertQuery("SELECT * FROM Developer WHERE depId=1 OR name='Mozart'")
.disableRules("LogicalTableScanConverterRule")
- .matches(containsUnion(true))
+ .matches(containsUnion())
.matches(containsIndexScan("PUBLIC", "DEVELOPER", DEPID_IDX))
.returns(1, "Mozart", 3, "Vienna", 33)
.returns(3, "Bach", 1, "Leipzig", 55)
diff --git a/modules/sql-engine/src/integrationTest/sql/group1/explain/modify.test b/modules/sql-engine/src/integrationTest/sql/group1/explain/modify.test
index 0a385815757..20244004a21 100644
--- a/modules/sql-engine/src/integrationTest/sql/group1/explain/modify.test
+++ b/modules/sql-engine/src/integrationTest/sql/group1/explain/modify.test
@@ -7,8 +7,9 @@ INSERT INTO test_table VALUES (1, 2, 3)
----
KeyValueModify
table: PUBLIC.TEST_TABLE
- operation: PUT
- expressions: [1, 2, 3]
+ fieldNames: [ROWCOUNT]
+ sourceExpression: [1, 2, 3]
+ type: INSERT
est: (rows=1)
# insert single tuple with literals different order
@@ -17,8 +18,9 @@ INSERT INTO test_table (c2, c3, c1) VALUES (1, 2, 3)
----
KeyValueModify
table: PUBLIC.TEST_TABLE
- operation: PUT
- expressions: [3, 1, 2]
+ fieldNames: [ROWCOUNT]
+ sourceExpression: [3, 1, 2]
+ type: INSERT
est: (rows=1)
# insert single tuple mixed
@@ -27,8 +29,9 @@ INSERT INTO test_table VALUES (1, LENGTH(rand_uuid()::VARCHAR), 3)
----
KeyValueModify
table: PUBLIC.TEST_TABLE
- operation: PUT
- expressions: [1, LENGTH(CAST(RAND_UUID()):VARCHAR CHARACTER SET "UTF-8" NOT NULL), 3]
+ fieldNames: [ROWCOUNT]
+ sourceExpression: [1, LENGTH(CAST(RAND_UUID()):VARCHAR CHARACTER SET "UTF-8" NOT NULL), 3]
+ type: INSERT
est: (rows=1)
# https://issues.apache.org/jira/browse/IGNITE-25454
@@ -42,26 +45,27 @@ plan
INSERT INTO test_table VALUES (1, 2, 3), (2, 2, 3)
----
Project
- fields: [ROWCOUNT]
- exprs: [CAST($f0):BIGINT NOT NULL]
+ fieldNames: [ROWCOUNT]
+ projection: [CAST($f0):BIGINT NOT NULL]
est: (rows=1)
ColocatedHashAggregate
+ fieldNames: [$f0]
group: []
- aggs: [$SUM0(ROWCOUNT)]
+ aggregation: [$SUM0(ROWCOUNT)]
est: (rows=1)
Exchange
distribution: single
est: (rows=2)
TableModify
- table: [PUBLIC, TEST_TABLE]
- operation: INSERT
- flattened: false
+ table: PUBLIC.TEST_TABLE
+ fieldNames: [ROWCOUNT]
+ type: INSERT
est: (rows=2)
TrimExchange
distribution: affinity[tableId=18, zoneId=18][0]
est: (rows=2)
Values
- type: [#0: C1 INTEGER, #1: C2 INTEGER, #2: C3 INTEGER]
+ fieldNames: [C1, C2, C3]
tuples: [[1, 2, 3], [2, 2, 3]]
est: (rows=2)
@@ -76,44 +80,44 @@ plan
INSERT INTO test_table VALUES (1, LENGTH(rand_uuid()::VARCHAR), 3), (2, LENGTH(rand_uuid()::VARCHAR), 3)
----
Project
- fields: [ROWCOUNT]
- exprs: [CAST($f0):BIGINT NOT NULL]
+ fieldNames: [ROWCOUNT]
+ projection: [CAST($f0):BIGINT NOT NULL]
est: (rows=2)
ColocatedHashAggregate
+ fieldNames: [$f0]
group: []
- aggs: [$SUM0(ROWCOUNT)]
+ aggregation: [$SUM0(ROWCOUNT)]
est: (rows=2)
Exchange
distribution: single
est: (rows=2)
TableModify
- table: [PUBLIC, TEST_TABLE]
- operation: INSERT
- flattened: false
+ table: PUBLIC.TEST_TABLE
+ fieldNames: [ROWCOUNT]
+ type: INSERT
est: (rows=2)
UnionAll
- all: true
est: (rows=2)
Exchange
distribution: affinity[tableId=18, zoneId=18][0]
est: (rows=1)
Project
- fields: [EXPR$0, EXPR$1, EXPR$2]
- exprs: [1, LENGTH(CAST(RAND_UUID()):VARCHAR CHARACTER SET "UTF-8" NOT NULL), 3]
+ fieldNames: [EXPR$0, EXPR$1, EXPR$2]
+ projection: [1, LENGTH(CAST(RAND_UUID()):VARCHAR CHARACTER SET "UTF-8" NOT NULL), 3]
est: (rows=1)
Values
- type: [#0: ZERO INTEGER]
+ fieldNames: [ZERO]
tuples: [[0]]
est: (rows=1)
Exchange
distribution: affinity[tableId=18, zoneId=18][0]
est: (rows=1)
Project
- fields: [EXPR$0, EXPR$1, EXPR$2]
- exprs: [2, LENGTH(CAST(RAND_UUID()):VARCHAR CHARACTER SET "UTF-8" NOT NULL), 3]
+ fieldNames: [EXPR$0, EXPR$1, EXPR$2]
+ projection: [2, LENGTH(CAST(RAND_UUID()):VARCHAR CHARACTER SET "UTF-8" NOT NULL), 3]
est: (rows=1)
Values
- type: [#0: ZERO INTEGER]
+ fieldNames: [ZERO]
tuples: [[0]]
est: (rows=1)
@@ -122,25 +126,26 @@ plan
DELETE FROM test_table WHERE c1 = 1
----
Project
- fields: [ROWCOUNT]
- exprs: [CAST($f0):BIGINT NOT NULL]
+ fieldNames: [ROWCOUNT]
+ projection: [CAST($f0):BIGINT NOT NULL]
est: (rows=1)
ColocatedHashAggregate
+ fieldNames: [$f0]
group: []
- aggs: [$SUM0(ROWCOUNT)]
+ aggregation: [$SUM0(ROWCOUNT)]
est: (rows=1)
Exchange
distribution: single
est: (rows=1)
TableModify
- table: [PUBLIC, TEST_TABLE]
- operation: DELETE
- flattened: false
+ table: PUBLIC.TEST_TABLE
+ fieldNames: [ROWCOUNT]
+ type: DELETE
est: (rows=1)
TableScan
table: PUBLIC.TEST_TABLE
- filters: =(C1, 1)
- fields: [C1]
+ predicate: =(C1, 1)
+ fieldNames: [C1]
est: (rows=1)
# delete by key complex
@@ -148,52 +153,54 @@ plan
DELETE FROM test_table WHERE c1 in (1, 2, 3)
----
Project
- fields: [ROWCOUNT]
- exprs: [CAST($f0):BIGINT NOT NULL]
+ fieldNames: [ROWCOUNT]
+ projection: [CAST($f0):BIGINT NOT NULL]
est: (rows=1)
ColocatedHashAggregate
+ fieldNames: [$f0]
group: []
- aggs: [$SUM0(ROWCOUNT)]
+ aggregation: [$SUM0(ROWCOUNT)]
est: (rows=1)
Exchange
distribution: single
est: (rows=1)
TableModify
- table: [PUBLIC, TEST_TABLE]
- operation: DELETE
- flattened: false
+ table: PUBLIC.TEST_TABLE
+ fieldNames: [ROWCOUNT]
+ type: DELETE
est: (rows=1)
TableScan
table: PUBLIC.TEST_TABLE
- filters: SEARCH(C1, Sarg[1, 2, 3])
- fields: [C1]
+ predicate: SEARCH(C1, Sarg[1, 2, 3])
+ fieldNames: [C1]
est: (rows=1)
+
# delete with predicate by arbitrary column
plan
DELETE FROM test_table WHERE c3 in (1, 2, 3)
----
Project
- fields: [ROWCOUNT]
- exprs: [CAST($f0):BIGINT NOT NULL]
+ fieldNames: [ROWCOUNT]
+ projection: [CAST($f0):BIGINT NOT NULL]
est: (rows=1)
ColocatedHashAggregate
+ fieldNames: [$f0]
group: []
- aggs: [$SUM0(ROWCOUNT)]
+ aggregation: [$SUM0(ROWCOUNT)]
est: (rows=1)
Exchange
distribution: single
est: (rows=1)
TableModify
- table: [PUBLIC, TEST_TABLE]
- operation: DELETE
- flattened: false
+ table: PUBLIC.TEST_TABLE
+ fieldNames: [ROWCOUNT]
+ type: DELETE
est: (rows=1)
TableScan
table: PUBLIC.TEST_TABLE
- filters: SEARCH(C3, Sarg[1, 2, 3])
- fields: [C1]
- projects: [C1]
+ predicate: SEARCH(C3, Sarg[1, 2, 3])
+ fieldNames: [C1]
est: (rows=1)
# update with predicate by key simple
@@ -201,28 +208,27 @@ plan
UPDATE test_table SET c2 = 2 WHERE c1 = 1
----
Project
- fields: [ROWCOUNT]
- exprs: [CAST($f0):BIGINT NOT NULL]
+ fieldNames: [ROWCOUNT]
+ projection: [CAST($f0):BIGINT NOT NULL]
est: (rows=1)
ColocatedHashAggregate
+ fieldNames: [$f0]
group: []
- aggs: [$SUM0(ROWCOUNT)]
+ aggregation: [$SUM0(ROWCOUNT)]
est: (rows=1)
Exchange
distribution: single
est: (rows=1)
TableModify
- table: [PUBLIC, TEST_TABLE]
- operation: UPDATE
- updateColumnList: [C2]
- sourceExpressionList: [C2]
- flattened: false
+ table: PUBLIC.TEST_TABLE
+ fieldNames: [ROWCOUNT]
+ type: UPDATE
est: (rows=1)
TableScan
table: PUBLIC.TEST_TABLE
- filters: =(C1, 1)
- fields: [C1, C2, C3, EXPR$0]
- projects: [C1, C2, C3, 2]
+ predicate: =(C1, 1)
+ fieldNames: [C1, C2, C3, EXPR$0]
+ projection: [C1, C2, C3, 2]
est: (rows=1)
# update with predicate by key complex
@@ -230,28 +236,27 @@ plan
UPDATE test_table SET c2 = 2 WHERE c1 in (1, 2, 3)
----
Project
- fields: [ROWCOUNT]
- exprs: [CAST($f0):BIGINT NOT NULL]
+ fieldNames: [ROWCOUNT]
+ projection: [CAST($f0):BIGINT NOT NULL]
est: (rows=1)
ColocatedHashAggregate
+ fieldNames: [$f0]
group: []
- aggs: [$SUM0(ROWCOUNT)]
+ aggregation: [$SUM0(ROWCOUNT)]
est: (rows=1)
Exchange
distribution: single
est: (rows=1)
TableModify
- table: [PUBLIC, TEST_TABLE]
- operation: UPDATE
- updateColumnList: [C2]
- sourceExpressionList: [C2]
- flattened: false
+ table: PUBLIC.TEST_TABLE
+ fieldNames: [ROWCOUNT]
+ type: UPDATE
est: (rows=1)
TableScan
table: PUBLIC.TEST_TABLE
- filters: SEARCH(C1, Sarg[1, 2, 3])
- fields: [C1, C2, C3, EXPR$0]
- projects: [C1, C2, C3, 2]
+ predicate: SEARCH(C1, Sarg[1, 2, 3])
+ fieldNames: [C1, C2, C3, EXPR$0]
+ projection: [C1, C2, C3, 2]
est: (rows=1)
# update with predicate by arbitrary column
@@ -259,28 +264,27 @@ plan
UPDATE test_table SET c2 = 2 WHERE c3 in (1, 2, 3)
----
Project
- fields: [ROWCOUNT]
- exprs: [CAST($f0):BIGINT NOT NULL]
+ fieldNames: [ROWCOUNT]
+ projection: [CAST($f0):BIGINT NOT NULL]
est: (rows=1)
ColocatedHashAggregate
+ fieldNames: [$f0]
group: []
- aggs: [$SUM0(ROWCOUNT)]
+ aggregation: [$SUM0(ROWCOUNT)]
est: (rows=1)
Exchange
distribution: single
est: (rows=1)
TableModify
- table: [PUBLIC, TEST_TABLE]
- operation: UPDATE
- updateColumnList: [C2]
- sourceExpressionList: [C2]
- flattened: false
+ table: PUBLIC.TEST_TABLE
+ fieldNames: [ROWCOUNT]
+ type: UPDATE
est: (rows=1)
TableScan
table: PUBLIC.TEST_TABLE
- filters: SEARCH(C3, Sarg[1, 2, 3])
- fields: [C1, C2, C3, EXPR$0]
- projects: [C1, C2, C3, 2]
+ predicate: SEARCH(C3, Sarg[1, 2, 3])
+ fieldNames: [C1, C2, C3, EXPR$0]
+ projection: [C1, C2, C3, 2]
est: (rows=1)
# https://issues.apache.org/jira/browse/IGNITE-25454
@@ -298,42 +302,42 @@ USING (SELECT c1, c2, c3 FROM test_table) src
WHEN NOT MATCHED THEN INSERT VALUES (1, 2, 3)
----
Project
- fields: [ROWCOUNT]
- exprs: [CAST($f0):BIGINT NOT NULL]
+ fieldNames: [ROWCOUNT]
+ projection: [CAST($f0):BIGINT NOT NULL]
est: (rows=1)
ColocatedHashAggregate
+ fieldNames: [$f0]
group: []
- aggs: [$SUM0(ROWCOUNT)]
+ aggregation: [$SUM0(ROWCOUNT)]
est: (rows=1)
Exchange
distribution: single
est: (rows=1)
TableModify
- table: [PUBLIC, TEST_TABLE]
- operation: MERGE
- updateColumnList: [C2]
- flattened: false
+ table: PUBLIC.TEST_TABLE
+ fieldNames: [ROWCOUNT]
+ type: MERGE
est: (rows=1)
Exchange
distribution: affinity[tableId=18, zoneId=18][0]
est: (rows=1)
Project
- fields: [$f0, $f1, $f2, C10, C20, C30, $f6]
- exprs: [1, 2, 3, C1, C2, C3, *(C20, 2)]
+ fieldNames: [$f0, $f1, $f2, C10, C20, C30, $f6]
+ projection: [1, 2, 3, C1, C2, C3, *(C20, 2)]
est: (rows=1)
HashJoin
- condition: =(C1, $f3)
- joinType: right
+ predicate: =(C1, $f3)
+ type: right
est: (rows=1)
TableScan
table: PUBLIC.TEST_TABLE
- fields: [C1, C2, C3]
+ fieldNames: [C1, C2, C3]
est: (rows=1)
Exchange
distribution: affinity[tableId=18, zoneId=18][1]
est: (rows=1)
TableScan
table: PUBLIC.TEST_TABLE
- fields: [C2, $f3]
- projects: [C2, *(C1, 2)]
+ fieldNames: [C2, $f3]
+ projection: [C2, *(C1, 2)]
est: (rows=1)
diff --git a/modules/sql-engine/src/integrationTest/sql/group1/explain/scan.test b/modules/sql-engine/src/integrationTest/sql/group1/explain/scan.test
index c1c7af33d49..40c5eb63594 100644
--- a/modules/sql-engine/src/integrationTest/sql/group1/explain/scan.test
+++ b/modules/sql-engine/src/integrationTest/sql/group1/explain/scan.test
@@ -10,7 +10,7 @@ Exchange
est: (rows=1)
TableScan
table: PUBLIC.TEST_TABLE
- fields: [C1, C2, C3]
+ fieldNames: [C1, C2, C3]
est: (rows=1)
# select with trimming projection, no renames
@@ -22,7 +22,7 @@ Exchange
est: (rows=1)
TableScan
table: PUBLIC.TEST_TABLE
- fields: [C1, C2]
+ fieldNames: [C1, C2]
est: (rows=1)
# select with trimming projection and renames
@@ -34,7 +34,7 @@ Exchange
est: (rows=1)
TableScan
table: PUBLIC.TEST_TABLE
- fields: [RENAMED_C1, C2]
+ fieldNames: [RENAMED_C1, C2]
est: (rows=1)
# select with expression projection, no renames
@@ -46,8 +46,8 @@ Exchange
est: (rows=1)
TableScan
table: PUBLIC.TEST_TABLE
- fields: [EXPR$0, C2]
- projects: [+(C1, C3), C2]
+ fieldNames: [EXPR$0, C2]
+ projection: [+(C1, C3), C2]
est: (rows=1)
# select with expression projection and renames
@@ -59,8 +59,8 @@ Exchange
est: (rows=1)
TableScan
table: PUBLIC.TEST_TABLE
- fields: [SUM_OF_C1_AND_C3, C2]
- projects: [+(C1, C3), C2]
+ fieldNames: [SUM_OF_C1_AND_C3, C2]
+ projection: [+(C1, C3), C2]
est: (rows=1)
# Similar set of tests but for IndexScan
@@ -78,7 +78,7 @@ Exchange
table: PUBLIC.TEST_TABLE
index: TEST_TABLE_IDX
type: SORTED
- fields: [C1, C2, C3]
+ fieldNames: [C1, C2, C3]
collation: [C1 ASC, C2 ASC, C3 ASC]
est: (rows=1)
@@ -93,7 +93,7 @@ Exchange
table: PUBLIC.TEST_TABLE
index: TEST_TABLE_IDX
type: SORTED
- fields: [C1, C2]
+ fieldNames: [C1, C2]
collation: [C1 ASC, C2 ASC]
est: (rows=1)
@@ -108,8 +108,8 @@ Exchange
table: PUBLIC.TEST_TABLE
index: TEST_TABLE_IDX
type: SORTED
- fields: [RENAMED_C1, C2]
- collation: [C1 ASC, C2 ASC]
+ fieldNames: [RENAMED_C1, C2]
+ collation: [RENAMED_C1 ASC, C2 ASC]
est: (rows=1)
# select with expression projection, no renames
@@ -123,8 +123,8 @@ Exchange
table: PUBLIC.TEST_TABLE
index: TEST_TABLE_IDX
type: SORTED
- fields: [EXPR$0, C2]
- projects: [+(C1, C3), C2]
+ fieldNames: [EXPR$0, C2]
+ projection: [+(C1, C3), C2]
collation: []
est: (rows=1)
@@ -139,8 +139,8 @@ Exchange
table: PUBLIC.TEST_TABLE
index: TEST_TABLE_IDX
type: SORTED
- fields: [SUM_OF_C1_AND_C3, C2]
- projects: [+(C1, C3), C2]
+ fieldNames: [SUM_OF_C1_AND_C3, C2]
+ projection: [+(C1, C3), C2]
collation: []
est: (rows=1)
@@ -151,7 +151,7 @@ SELECT * FROM test_table WHERE c1 = 1
----
KeyValueGet
table: PUBLIC.TEST_TABLE
- fields: [C1, C2, C3]
+ fieldNames: [C1, C2, C3]
key: [1]
est: (rows=1)
@@ -161,7 +161,7 @@ SELECT c1, c2 FROM test_table WHERE c1 = 1
----
KeyValueGet
table: PUBLIC.TEST_TABLE
- fields: [C1, C2]
+ fieldNames: [C1, C2]
key: [1]
est: (rows=1)
@@ -171,7 +171,7 @@ SELECT c1 AS renamed_c1, c2 FROM test_table WHERE c1 = 1
----
KeyValueGet
table: PUBLIC.TEST_TABLE
- fields: [C1, C2]
+ fieldNames: [C1, C2]
key: [1]
est: (rows=1)
@@ -181,8 +181,8 @@ SELECT c1 + c3, c2 FROM test_table WHERE c1 = 1
----
KeyValueGet
table: PUBLIC.TEST_TABLE
- fields: [EXPR$0, C2]
- projects: [+(C1, C3), C2]
+ fieldNames: [EXPR$0, C2]
+ projection: [+(C1, C3), C2]
key: [1]
est: (rows=1)
@@ -192,8 +192,8 @@ SELECT c1 + c3 AS sum_of_c1_and_c3, c2 FROM test_table WHERE c1 = 1
----
KeyValueGet
table: PUBLIC.TEST_TABLE
- fields: [SUM_OF_C1_AND_C3, C2]
- projects: [+(C1, C3), C2]
+ fieldNames: [SUM_OF_C1_AND_C3, C2]
+ projection: [+(C1, C3), C2]
key: [1]
est: (rows=1)
@@ -204,7 +204,7 @@ SELECT * FROM system.system_views
----
SystemViewScan
table: SYSTEM.SYSTEM_VIEWS
- fields: [VIEW_ID, SCHEMA_NAME, VIEW_NAME, VIEW_TYPE, ID, SCHEMA, NAME, TYPE]
+ fieldNames: [VIEW_ID, SCHEMA_NAME, VIEW_NAME, VIEW_TYPE, ID, SCHEMA, NAME, TYPE]
est: (rows=100)
# select with trimming projection, no renames
@@ -213,7 +213,7 @@ SELECT view_id, view_name FROM system.system_views
----
SystemViewScan
table: SYSTEM.SYSTEM_VIEWS
- fields: [VIEW_ID, VIEW_NAME]
+ fieldNames: [VIEW_ID, VIEW_NAME]
est: (rows=100)
# select with trimming projection and renames
@@ -222,7 +222,7 @@ SELECT view_id AS renamed_view_id, view_name FROM system.system_views
----
SystemViewScan
table: SYSTEM.SYSTEM_VIEWS
- fields: [RENAMED_VIEW_ID, VIEW_NAME]
+ fieldNames: [RENAMED_VIEW_ID, VIEW_NAME]
est: (rows=100)
# select with expression projection, no renames
@@ -231,8 +231,8 @@ SELECT view_id + 5, view_name FROM system.system_views
----
SystemViewScan
table: SYSTEM.SYSTEM_VIEWS
- fields: [EXPR$0, VIEW_NAME]
- projects: [+(VIEW_ID, 5), VIEW_NAME]
+ fieldNames: [EXPR$0, VIEW_NAME]
+ projection: [+(VIEW_ID, 5), VIEW_NAME]
est: (rows=100)
# select with expression projection and renames
@@ -241,8 +241,8 @@ SELECT view_id + 5 AS adjusted_view_id, view_name FROM system.system_views
----
SystemViewScan
table: SYSTEM.SYSTEM_VIEWS
- fields: [ADJUSTED_VIEW_ID, VIEW_NAME]
- projects: [+(VIEW_ID, 5), VIEW_NAME]
+ fieldNames: [ADJUSTED_VIEW_ID, VIEW_NAME]
+ projection: [+(VIEW_ID, 5), VIEW_NAME]
est: (rows=100)
# Complex query where column of source table is renamed, and this renamed column is referenced by
@@ -256,32 +256,33 @@ SELECT
FROM (SELECT c1, c1 as renamed_c1 FROM test_table) as t
----
Project
- fields: [EXPR$0]
- exprs: [EXPR$0]
+ fieldNames: [EXPR$0]
+ projection: [EXPR$0]
est: (rows=1)
CorrelatedNestedLoopJoin
- condition: true
- joinType: left
- variablesSet: [$cor0]
+ predicate: true
+ type: left
+ correlates: [$cor0]
est: (rows=1)
Exchange
distribution: single
est: (rows=1)
TableScan
table: PUBLIC.TEST_TABLE
- fields: [RENAMED_C1]
+ fieldNames: [RENAMED_C1]
est: (rows=1)
ColocatedHashAggregate
+ fieldNames: [EXPR$0]
group: []
- aggs: [EXPR$0=COUNT()]
+ aggregation: [COUNT()]
est: (rows=1)
Exchange
distribution: single
est: (rows=1)
TableScan
table: PUBLIC.TEST_TABLE
- filters: =(C1, $cor0.RENAMED_C1)
- fields: [C1]
+ predicate: =(C1, $cor0.RENAMED_C1)
+ fieldNames: [C1]
est: (rows=1)
# Complex query where expression involving a column of source table is renamed, and this renamed expression is referenced by
@@ -295,33 +296,34 @@ SELECT
FROM (SELECT c1, c1 * 2 as doubled_c1 FROM test_table) as t
----
Project
- fields: [EXPR$0]
- exprs: [EXPR$0]
+ fieldNames: [EXPR$0]
+ projection: [EXPR$0]
est: (rows=1)
CorrelatedNestedLoopJoin
- condition: true
- joinType: left
- variablesSet: [$cor0]
+ predicate: true
+ type: left
+ correlates: [$cor0]
est: (rows=1)
Exchange
distribution: single
est: (rows=1)
TableScan
table: PUBLIC.TEST_TABLE
- fields: [DOUBLED_C1]
- projects: [*(C1, 2)]
+ fieldNames: [DOUBLED_C1]
+ projection: [*(C1, 2)]
est: (rows=1)
ColocatedHashAggregate
+ fieldNames: [EXPR$0]
group: []
- aggs: [EXPR$0=COUNT()]
+ aggregation: [COUNT()]
est: (rows=1)
Exchange
distribution: single
est: (rows=1)
TableScan
table: PUBLIC.TEST_TABLE
- filters: =(C1, $cor0.DOUBLED_C1)
- fields: [C1]
+ predicate: =(C1, $cor0.DOUBLED_C1)
+ fieldNames: [C1]
est: (rows=1)
# table scan with simple predicate
@@ -333,9 +335,8 @@ Exchange
est: (rows=1)
TableScan
table: PUBLIC.TEST_TABLE
- filters: =(C3, 1)
- fields: [C1]
- projects: [C1]
+ predicate: =(C3, 1)
+ fieldNames: [C1]
est: (rows=1)
# table scan with complex predicate
@@ -347,9 +348,8 @@ Exchange
est: (rows=1)
TableScan
table: PUBLIC.TEST_TABLE
- filters: AND(SEARCH(C3, Sarg[1, 2, 3]), >(CAST(CURRENT_TIMESTAMP):TIMESTAMP(0) NOT NULL, 1970-01-01 00:00:00))
- fields: [C1]
- projects: [C1]
+ predicate: AND(SEARCH(C3, Sarg[1, 2, 3]), >(CAST(CURRENT_TIMESTAMP):TIMESTAMP(0) NOT NULL, 1970-01-01 00:00:00))
+ fieldNames: [C1]
est: (rows=1)
# index scan with simple predicate
@@ -363,9 +363,9 @@ Exchange
table: PUBLIC.TEST_TABLE
index: TEST_TABLE_IDX
type: SORTED
+ predicate: >(C1, 1)
searchBounds: [RangeBounds [lowerBound=1, upperBound=null:INTEGER, lowerInclude=false, upperInclude=false]]
- filters: >(C1, 1)
- fields: [C1]
+ fieldNames: [C1]
collation: [C1 ASC]
est: (rows=1)
@@ -380,9 +380,9 @@ Exchange
table: PUBLIC.TEST_TABLE
index: TEST_TABLE_IDX
type: SORTED
+ predicate: AND(SEARCH(C1, Sarg[1, 2, 3]), >(CAST(CURRENT_TIMESTAMP):TIMESTAMP(0) NOT NULL, 1970-01-01 00:00:00))
searchBounds: [MultiBounds [bounds=ArrayList [ExactBounds [bound=1], ExactBounds [bound=2], ExactBounds [bound=3]]]]
- filters: AND(SEARCH(C1, Sarg[1, 2, 3]), >(CAST(CURRENT_TIMESTAMP):TIMESTAMP(0) NOT NULL, 1970-01-01 00:00:00))
- fields: [C1]
+ fieldNames: [C1]
collation: [C1 ASC]
est: (rows=1)
@@ -400,10 +400,9 @@ Exchange
table: PUBLIC.TEST_TABLE
index: HASH_IDX
type: HASH
+ predicate: =(C2, 10)
searchBounds: [ExactBounds [bound=10]]
- filters: =(C2, 10)
- fields: [C1]
- projects: [C1]
+ fieldNames: [C1]
est: (rows=1)
statement ok
@@ -420,7 +419,7 @@ Exchange
table: PUBLIC.TEST_TABLE
index: TEST_TABLE_DIFFERENT_COLLATION_IDX
type: SORTED
- fields: [C1, C2]
+ fieldNames: [C1, C2]
collation: [C2 DESC NULLS LAST]
est: (rows=1)
@@ -430,8 +429,8 @@ SELECT view_id, view_name FROM system.system_views WHERE view_id = 5
----
SystemViewScan
table: SYSTEM.SYSTEM_VIEWS
- filters: =(VIEW_ID, 5)
- fields: [VIEW_ID, VIEW_NAME]
+ predicate: =(VIEW_ID, 5)
+ fieldNames: [VIEW_ID, VIEW_NAME]
est: (rows=33)
# table scan with complex predicate
@@ -440,8 +439,8 @@ SELECT view_id, view_name FROM system.system_views WHERE view_id IN (1, 2, 3) AN
----
SystemViewScan
table: SYSTEM.SYSTEM_VIEWS
- filters: AND(SEARCH(VIEW_ID, Sarg[1, 2, 3]), >(CAST(CURRENT_TIMESTAMP):TIMESTAMP(0) NOT NULL, 1970-01-01 00:00:00))
- fields: [VIEW_ID, VIEW_NAME]
+ predicate: AND(SEARCH(VIEW_ID, Sarg[1, 2, 3]), >(CAST(CURRENT_TIMESTAMP):TIMESTAMP(0) NOT NULL, 1970-01-01 00:00:00))
+ fieldNames: [VIEW_ID, VIEW_NAME]
est: (rows=38)
# table function scan
@@ -449,8 +448,8 @@ plan
SELECT * FROM system_range(1, 10)
----
TableFunctionScan
+ fieldNames: [X]
invocation: SYSTEM_RANGE(1, 10)
- rowType: RecordType(BIGINT X)
est: (rows=100)
# another table function scan
@@ -458,6 +457,6 @@ plan
SELECT * FROM system_range(1, LENGTH(rand_uuid()::VARCHAR))
----
TableFunctionScan
+ fieldNames: [X]
invocation: SYSTEM_RANGE(1, LENGTH(CAST(RAND_UUID()):VARCHAR CHARACTER SET "UTF-8" NOT NULL))
- rowType: RecordType(BIGINT X)
est: (rows=100)
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/ExplainUtils.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/ExplainUtils.java
deleted file mode 100644
index 456dd6f0abc..00000000000
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/ExplainUtils.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-
-package org.apache.ignite.internal.sql.engine.prepare;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import org.apache.calcite.rel.RelWriter;
-import org.apache.ignite.internal.sql.engine.rel.IgniteRel;
-
-/** Set of utility method used during EXPLAIN evaluation. */
-public final class ExplainUtils {
- private ExplainUtils() {
- throw new AssertionError("Should not be called");
- }
-
- /** Returns {@code true} when printer is compiling EXPLAIN output, return {@code false} otherwise (i.e. node is being serialised). */
- public static boolean forExplain(RelWriter pw) {
- return pw instanceof ExplainRelAsTextWriter;
- }
-
- /** Converts given relation to string representation suitable for EXPLAIN command output. */
- public static String toString(IgniteRel rel) {
- StringWriter sw = new StringWriter();
- RelWriter planWriter = new ExplainRelAsTextWriter(new PrintWriter(sw));
-
- rel.explain(planWriter);
-
- return sw.toString();
- }
-}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/KeyValueGetPlan.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/KeyValueGetPlan.java
index b8a290b36ef..e3b924e36d9 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/KeyValueGetPlan.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/KeyValueGetPlan.java
@@ -49,6 +49,7 @@ import org.apache.ignite.internal.sql.engine.exec.exp.SqlRowProvider;
import org.apache.ignite.internal.sql.engine.exec.row.RowSchema;
import org.apache.ignite.internal.sql.engine.rel.IgniteKeyValueGet;
import org.apache.ignite.internal.sql.engine.rel.IgniteRel;
+import org.apache.ignite.internal.sql.engine.rel.explain.ExplainUtils;
import org.apache.ignite.internal.sql.engine.schema.IgniteTable;
import org.apache.ignite.internal.sql.engine.util.Cloner;
import org.apache.ignite.internal.sql.engine.util.Commons;
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/KeyValueModifyPlan.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/KeyValueModifyPlan.java
index b6f2585da06..e0954f6b153 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/KeyValueModifyPlan.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/KeyValueModifyPlan.java
@@ -35,6 +35,7 @@ import org.apache.ignite.internal.sql.engine.exec.UpdatableTable;
import org.apache.ignite.internal.sql.engine.exec.exp.SqlRowProvider;
import org.apache.ignite.internal.sql.engine.rel.IgniteKeyValueModify;
import org.apache.ignite.internal.sql.engine.rel.IgniteRel;
+import org.apache.ignite.internal.sql.engine.rel.explain.ExplainUtils;
import org.apache.ignite.internal.sql.engine.schema.IgniteTable;
import org.apache.ignite.internal.sql.engine.util.Cloner;
import org.apache.ignite.internal.sql.engine.util.Commons;
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/MultiStepPlan.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/MultiStepPlan.java
index 1806e1402c5..6a27730ecd9 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/MultiStepPlan.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/MultiStepPlan.java
@@ -19,6 +19,7 @@ package org.apache.ignite.internal.sql.engine.prepare;
import org.apache.ignite.internal.sql.engine.SqlQueryType;
import org.apache.ignite.internal.sql.engine.rel.IgniteRel;
+import org.apache.ignite.internal.sql.engine.rel.explain.ExplainUtils;
import org.apache.ignite.internal.sql.engine.util.Cloner;
import org.apache.ignite.internal.sql.engine.util.Commons;
import org.apache.ignite.sql.ResultSetMetadata;
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/SelectCountPlan.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/SelectCountPlan.java
index d777c704882..3d489f9c52a 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/SelectCountPlan.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/SelectCountPlan.java
@@ -43,6 +43,7 @@ import org.apache.ignite.internal.sql.engine.exec.exp.SqlProjection;
import org.apache.ignite.internal.sql.engine.exec.row.RowSchema;
import org.apache.ignite.internal.sql.engine.rel.IgniteRel;
import org.apache.ignite.internal.sql.engine.rel.IgniteSelectCount;
+import org.apache.ignite.internal.sql.engine.rel.explain.ExplainUtils;
import org.apache.ignite.internal.sql.engine.schema.IgniteTable;
import org.apache.ignite.internal.sql.engine.util.Cloner;
import org.apache.ignite.internal.sql.engine.util.Commons;
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/AbstractIgniteJoin.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/AbstractIgniteJoin.java
index b812d7d16d7..9cfe5f055a0 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/AbstractIgniteJoin.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/AbstractIgniteJoin.java
@@ -46,6 +46,7 @@ import org.apache.calcite.util.Pair;
import org.apache.calcite.util.Util;
import org.apache.calcite.util.mapping.IntPair;
import org.apache.calcite.util.mapping.Mappings;
+import org.apache.ignite.internal.sql.engine.rel.explain.IgniteRelWriter;
import org.apache.ignite.internal.sql.engine.trait.DistributionFunction;
import org.apache.ignite.internal.sql.engine.trait.IgniteDistribution;
import org.apache.ignite.internal.sql.engine.trait.TraitUtils;
@@ -276,4 +277,11 @@ public abstract class AbstractIgniteJoin extends Join implements TraitsAwareIgni
(left2Right ? right : left).getRowType().getFieldCount()
);
}
+
+ @Override
+ public IgniteRelWriter explain(IgniteRelWriter writer) {
+ return writer
+ .addPredicate(condition, getRowType())
+ .addJoinType(joinType);
+ }
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/AbstractIndexScan.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/AbstractIndexScan.java
index fa16fa297cf..0dc9ae66d28 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/AbstractIndexScan.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/AbstractIndexScan.java
@@ -38,6 +38,7 @@ import org.apache.ignite.internal.sql.engine.externalize.RelInputEx;
import org.apache.ignite.internal.sql.engine.metadata.cost.IgniteCost;
import org.apache.ignite.internal.sql.engine.prepare.bounds.MultiBounds;
import org.apache.ignite.internal.sql.engine.prepare.bounds.SearchBounds;
+import org.apache.ignite.internal.sql.engine.rel.explain.IgniteRelWriter;
import org.apache.ignite.internal.sql.engine.schema.IgniteIndex;
import org.apache.ignite.internal.sql.engine.schema.IgniteIndex.Type;
import org.apache.ignite.internal.sql.engine.util.Commons;
@@ -184,4 +185,16 @@ public abstract class AbstractIndexScan extends ProjectableFilterableTableScan {
public List<SearchBounds> searchBounds() {
return searchBounds;
}
+
+ @Override
+ public IgniteRelWriter explainAttributes(IgniteRelWriter writer) {
+ super.explainAttributes(writer)
+ .addIndex(idxName, type);
+
+ if (searchBounds != null) {
+ writer.addSearchBounds(searchBounds);
+ }
+
+ return writer;
+ }
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteAggregate.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteAggregate.java
index 0447d3945b3..568c089deff 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteAggregate.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteAggregate.java
@@ -29,9 +29,11 @@ import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.core.Aggregate;
import org.apache.calcite.rel.core.AggregateCall;
import org.apache.calcite.rel.metadata.RelMetadataQuery;
+import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.util.ImmutableBitSet;
import org.apache.ignite.internal.sql.engine.metadata.cost.IgniteCost;
import org.apache.ignite.internal.sql.engine.metadata.cost.IgniteCostFactory;
+import org.apache.ignite.internal.sql.engine.rel.explain.IgniteRelWriter;
/**
* IgniteAggregate.
@@ -140,4 +142,19 @@ public abstract class IgniteAggregate extends Aggregate implements IgniteRel {
0
);
}
+
+ @Override
+ public IgniteRelWriter explain(IgniteRelWriter writer) {
+ RelDataType rowType = getInput().getRowType();
+
+ writer
+ .addGroup(groupSet, rowType)
+ .addAggregation(aggCalls, rowType);
+
+ if (getGroupType() != Group.SIMPLE) {
+ writer.addGroupSets(groupSets, rowType);
+ }
+
+ return writer;
+ }
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteCorrelatedNestedLoopJoin.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteCorrelatedNestedLoopJoin.java
index 58aa8ea7b8f..4a7246eba39 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteCorrelatedNestedLoopJoin.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteCorrelatedNestedLoopJoin.java
@@ -38,6 +38,7 @@ import org.apache.calcite.rex.RexNode;
import org.apache.calcite.util.Pair;
import org.apache.ignite.internal.sql.engine.metadata.cost.IgniteCost;
import org.apache.ignite.internal.sql.engine.metadata.cost.IgniteCostFactory;
+import org.apache.ignite.internal.sql.engine.rel.explain.IgniteRelWriter;
import org.apache.ignite.internal.sql.engine.trait.TraitUtils;
import org.apache.ignite.internal.sql.engine.util.Commons;
@@ -189,4 +190,9 @@ public class IgniteCorrelatedNestedLoopJoin extends AbstractIgniteJoin {
public String getRelTypeName() {
return REL_TYPE_NAME;
}
+
+ @Override
+ public IgniteRelWriter explain(IgniteRelWriter writer) {
+ return super.explain(writer).addCorrelatedVariables(variablesSet);
+ }
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteExchange.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteExchange.java
index a9797bf6bd6..5b07686175d 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteExchange.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteExchange.java
@@ -32,6 +32,7 @@ import org.apache.calcite.rel.core.Exchange;
import org.apache.calcite.rel.metadata.RelMetadataQuery;
import org.apache.ignite.internal.sql.engine.metadata.cost.IgniteCost;
import org.apache.ignite.internal.sql.engine.metadata.cost.IgniteCostFactory;
+import org.apache.ignite.internal.sql.engine.rel.explain.IgniteRelWriter;
import org.apache.ignite.internal.sql.engine.trait.IgniteDistribution;
/**
@@ -111,4 +112,9 @@ public class IgniteExchange extends Exchange implements IgniteRel {
public String getRelTypeName() {
return REL_TYPE_NAME;
}
+
+ @Override
+ public IgniteRelWriter explain(IgniteRelWriter writer) {
+ return writer.addDistribution(distribution(), getRowType());
+ }
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteFilter.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteFilter.java
index 93fa7c34b3d..00f060cedad 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteFilter.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteFilter.java
@@ -31,6 +31,7 @@ import org.apache.calcite.rel.metadata.RelMetadataQuery;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.util.Pair;
import org.apache.ignite.internal.sql.engine.metadata.cost.IgniteCost;
+import org.apache.ignite.internal.sql.engine.rel.explain.IgniteRelWriter;
import org.apache.ignite.internal.sql.engine.trait.TraitUtils;
import org.apache.ignite.internal.sql.engine.trait.TraitsAwareIgniteRel;
@@ -112,4 +113,9 @@ public class IgniteFilter extends Filter implements TraitsAwareIgniteRel {
@Override public String getRelTypeName() {
return REL_TYPE_NAME;
}
+
+ @Override
+ public IgniteRelWriter explain(IgniteRelWriter writer) {
+ return writer.addPredicate(condition, getInput().getRowType());
+ }
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteIndexScan.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteIndexScan.java
index 185eaf2e278..2d8f1075ca9 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteIndexScan.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteIndexScan.java
@@ -29,6 +29,7 @@ import org.apache.calcite.rel.RelWriter;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.util.ImmutableBitSet;
import org.apache.ignite.internal.sql.engine.prepare.bounds.SearchBounds;
+import org.apache.ignite.internal.sql.engine.rel.explain.IgniteRelWriter;
import org.apache.ignite.internal.sql.engine.schema.IgniteIndex;
import org.apache.ignite.internal.sql.engine.schema.IgniteIndex.Type;
import org.jetbrains.annotations.Nullable;
@@ -184,4 +185,15 @@ public class IgniteIndexScan extends AbstractIndexScan implements SourceAwareIgn
public String getRelTypeName() {
return REL_TYPE_NAME;
}
+
+ @Override
+ public IgniteRelWriter explain(IgniteRelWriter writer) {
+ explainAttributes(writer);
+
+ if (type == Type.SORTED) {
+ writer.addCollation(collation, getRowType());
+ }
+
+ return writer;
+ }
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteKeyValueGet.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteKeyValueGet.java
index 0bbf4d84678..9ab1de2f56d 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteKeyValueGet.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteKeyValueGet.java
@@ -28,6 +28,7 @@ import org.apache.calcite.rex.RexNode;
import org.apache.calcite.util.ImmutableBitSet;
import org.apache.ignite.internal.sql.engine.exec.TxAttributes;
import org.apache.ignite.internal.sql.engine.exec.mapping.MappingService;
+import org.apache.ignite.internal.sql.engine.rel.explain.IgniteRelWriter;
import org.apache.ignite.internal.tx.InternalTransaction;
import org.jetbrains.annotations.Nullable;
@@ -129,4 +130,10 @@ public class IgniteKeyValueGet extends ProjectableFilterableTableScan implements
public List<RexNode> keyExpressions() {
return keyExpressions;
}
+
+ @Override
+ public IgniteRelWriter explain(IgniteRelWriter writer) {
+ return explainAttributes(writer)
+ .addKeyExpression(keyExpressions);
+ }
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteKeyValueModify.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteKeyValueModify.java
index 1f1d163ce5b..67dfbcea1b6 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteKeyValueModify.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteKeyValueModify.java
@@ -17,8 +17,6 @@
package org.apache.ignite.internal.sql.engine.rel;
-import static org.apache.ignite.internal.sql.engine.prepare.ExplainUtils.forExplain;
-
import java.util.List;
import org.apache.calcite.plan.RelOptCluster;
import org.apache.calcite.plan.RelOptTable;
@@ -28,12 +26,14 @@ import org.apache.calcite.rel.AbstractRelNode;
import org.apache.calcite.rel.RelInput;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.RelWriter;
+import org.apache.calcite.rel.core.TableModify;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.rex.RexShuttle;
import org.apache.calcite.sql.SqlKind;
import org.apache.ignite.internal.sql.engine.exec.TxAttributes;
import org.apache.ignite.internal.sql.engine.exec.mapping.MappingService;
+import org.apache.ignite.internal.sql.engine.rel.explain.IgniteRelWriter;
import org.apache.ignite.internal.tx.InternalTransaction;
/**
@@ -56,7 +56,13 @@ public class IgniteKeyValueModify extends AbstractRelNode implements IgniteRel {
/** Enumeration of supported modification operations. */
public enum Operation {
- PUT
+ PUT(TableModify.Operation.INSERT);
+
+ private final TableModify.Operation op;
+
+ Operation(TableModify.Operation op) {
+ this.op = op;
+ }
}
private final RelOptTable table;
@@ -125,8 +131,7 @@ public class IgniteKeyValueModify extends AbstractRelNode implements IgniteRel {
@Override public RelWriter explainTerms(RelWriter pw) {
return super.explainTerms(pw)
- .itemIf("table", table.getQualifiedName(), !forExplain(pw))
- .itemIf("table", table, forExplain(pw))
+ .item("table", table.getQualifiedName())
.item("operation", operation)
.item("expressions", expressions);
}
@@ -146,4 +151,12 @@ public class IgniteKeyValueModify extends AbstractRelNode implements IgniteRel {
public List<RexNode> expressions() {
return expressions;
}
+
+ @Override
+ public IgniteRelWriter explain(IgniteRelWriter writer) {
+ return writer
+ .addTable(table)
+ .addSourceExpressions(expressions)
+ .addModifyOperationType(operation.op);
+ }
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteLimit.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteLimit.java
index 60b1ec07a6b..55283d9df8b 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteLimit.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteLimit.java
@@ -36,6 +36,7 @@ import org.apache.calcite.rex.RexNode;
import org.apache.calcite.rex.RexShuttle;
import org.apache.calcite.util.Pair;
import org.apache.ignite.internal.sql.engine.metadata.cost.IgniteCost;
+import org.apache.ignite.internal.sql.engine.rel.explain.IgniteRelWriter;
import org.apache.ignite.internal.sql.engine.trait.IgniteDistributions;
import org.apache.ignite.internal.sql.engine.trait.TraitUtils;
import org.jetbrains.annotations.Nullable;
@@ -208,4 +209,17 @@ public class IgniteLimit extends SingleRel implements IgniteRel {
public String getRelTypeName() {
return REL_TYPE_NAME;
}
+
+ @Override
+ public IgniteRelWriter explain(IgniteRelWriter writer) {
+ if (offset != null) {
+ writer.addOffset(offset);
+ }
+
+ if (fetch != null) {
+ writer.addFetch(fetch);
+ }
+
+ return writer;
+ }
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteMergeJoin.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteMergeJoin.java
index ab23020b95a..aeea60471e0 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteMergeJoin.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteMergeJoin.java
@@ -51,7 +51,6 @@ import org.apache.calcite.util.mapping.IntPair;
import org.apache.ignite.internal.sql.engine.externalize.RelInputEx;
import org.apache.ignite.internal.sql.engine.metadata.cost.IgniteCost;
import org.apache.ignite.internal.sql.engine.metadata.cost.IgniteCostFactory;
-import org.apache.ignite.internal.sql.engine.prepare.ExplainUtils;
import org.apache.ignite.internal.sql.engine.trait.TraitUtils;
import org.apache.ignite.internal.sql.engine.util.Commons;
@@ -302,8 +301,8 @@ public class IgniteMergeJoin extends AbstractIgniteJoin {
@Override
public RelWriter explainTerms(RelWriter pw) {
return super.explainTerms(pw)
- .itemIf("leftCollation", leftCollation, !ExplainUtils.forExplain(pw))
- .itemIf("rightCollation", rightCollation, !ExplainUtils.forExplain(pw));
+ .item("leftCollation", leftCollation)
+ .item("rightCollation", rightCollation);
}
/** {@inheritDoc} */
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteProject.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteProject.java
index 1671d38c2b0..0232cd8f47f 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteProject.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteProject.java
@@ -52,6 +52,7 @@ import org.apache.calcite.util.Pair;
import org.apache.calcite.util.Util;
import org.apache.calcite.util.mapping.Mappings;
import org.apache.ignite.internal.sql.engine.metadata.cost.IgniteCost;
+import org.apache.ignite.internal.sql.engine.rel.explain.IgniteRelWriter;
import org.apache.ignite.internal.sql.engine.trait.IgniteDistribution;
import org.apache.ignite.internal.sql.engine.trait.TraitUtils;
import org.apache.ignite.internal.sql.engine.trait.TraitsAwareIgniteRel;
@@ -251,4 +252,9 @@ public class IgniteProject extends Project implements TraitsAwareIgniteRel {
public String getRelTypeName() {
return REL_TYPE_NAME;
}
+
+ @Override
+ public IgniteRelWriter explain(IgniteRelWriter writer) {
+ return writer.addProjection(exps, getInput().getRowType());
+ }
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteRel.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteRel.java
index 79080bc93ed..5f780967aa0 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteRel.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteRel.java
@@ -23,6 +23,7 @@ import org.apache.calcite.plan.RelTraitSet;
import org.apache.calcite.rel.PhysicalNode;
import org.apache.calcite.rel.RelCollation;
import org.apache.calcite.util.Pair;
+import org.apache.ignite.internal.sql.engine.rel.explain.IgniteRelWriter;
import org.apache.ignite.internal.sql.engine.trait.IgniteDistribution;
import org.apache.ignite.internal.sql.engine.trait.TraitUtils;
@@ -46,6 +47,18 @@ public interface IgniteRel extends PhysicalNode {
*/
IgniteRel clone(RelOptCluster cluster, List<IgniteRel> inputs);
+ /**
+ * Writes attributes of the relation to a given {@link IgniteRelWriter writer}.
+ *
+ * <p>Every rel should include their own attributes while inputs will be processed from outside.
+ *
+ * @param writer Writer to write relation attributes.
+ * @return The same write for chaining.
+ */
+ default IgniteRelWriter explain(IgniteRelWriter writer) {
+ return writer;
+ }
+
/**
* Get node distribution.
*/
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteSelectCount.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteSelectCount.java
index d16d5923cad..29cf8522736 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteSelectCount.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteSelectCount.java
@@ -29,11 +29,14 @@ import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.RelWriter;
import org.apache.calcite.rel.metadata.RelMetadataQuery;
import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.rex.RexShuttle;
import org.apache.calcite.rex.RexUtil;
+import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.ignite.internal.sql.engine.exec.mapping.MappingService;
import org.apache.ignite.internal.sql.engine.metadata.cost.IgniteCostFactory;
+import org.apache.ignite.internal.sql.engine.rel.explain.IgniteRelWriter;
import org.apache.ignite.internal.sql.engine.util.Commons;
import org.checkerframework.checker.nullness.qual.Nullable;
@@ -152,4 +155,17 @@ public class IgniteSelectCount extends AbstractRelNode implements IgniteRel {
return costFactory.makeTinyCost();
}
+
+ @Override
+ public IgniteRelWriter explain(IgniteRelWriter writer) {
+ RelDataTypeFactory typeFactory = getCluster().getTypeFactory();
+
+ RelDataType rowType = typeFactory.builder()
+ .add("$COUNT_ALL", typeFactory.createSqlType(SqlTypeName.BIGINT))
+ .build();
+
+ return writer
+ .addTable(table)
+ .addProjection(expressions, rowType);
+ }
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteSort.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteSort.java
index ba30ebdae83..96caf9227af 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteSort.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteSort.java
@@ -38,6 +38,7 @@ import org.apache.calcite.util.Pair;
import org.apache.calcite.util.Util;
import org.apache.ignite.internal.sql.engine.metadata.cost.IgniteCost;
import org.apache.ignite.internal.sql.engine.metadata.cost.IgniteCostFactory;
+import org.apache.ignite.internal.sql.engine.rel.explain.IgniteRelWriter;
import org.apache.ignite.internal.sql.engine.trait.IgniteDistributions;
import org.apache.ignite.internal.sql.engine.trait.TraitUtils;
import org.jetbrains.annotations.Nullable;
@@ -197,4 +198,17 @@ public class IgniteSort extends Sort implements IgniteRel {
public String getRelTypeName() {
return REL_TYPE_NAME;
}
+
+ @Override
+ public IgniteRelWriter explain(IgniteRelWriter writer) {
+ if (offset != null) {
+ writer.addOffset(offset);
+ }
+
+ if (fetch != null) {
+ writer.addFetch(fetch);
+ }
+
+ return writer.addCollation(collation, getRowType());
+ }
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteSystemViewScan.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteSystemViewScan.java
index 5c516cb580d..94ce468aa92 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteSystemViewScan.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteSystemViewScan.java
@@ -28,6 +28,7 @@ import org.apache.calcite.rel.RelWriter;
import org.apache.calcite.rel.hint.RelHint;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.util.ImmutableBitSet;
+import org.apache.ignite.internal.sql.engine.rel.explain.IgniteRelWriter;
import org.jetbrains.annotations.Nullable;
/**
@@ -143,4 +144,10 @@ public class IgniteSystemViewScan extends ProjectableFilterableTableScan impleme
public String getRelTypeName() {
return REL_TYPE_NAME;
}
+
+ @Override
+ public IgniteRelWriter explain(
+ IgniteRelWriter writer) {
+ return explainAttributes(writer);
+ }
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteTableFunctionScan.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteTableFunctionScan.java
index e6a9a841673..1376d53d231 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteTableFunctionScan.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteTableFunctionScan.java
@@ -34,6 +34,7 @@ import org.apache.calcite.rel.metadata.RelMetadataQuery;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rex.RexNode;
import org.apache.ignite.internal.sql.engine.exec.mapping.QuerySplitter;
+import org.apache.ignite.internal.sql.engine.rel.explain.IgniteRelWriter;
/**
* Relational operator for table function scan.
@@ -148,4 +149,9 @@ public class IgniteTableFunctionScan extends TableFunctionScan implements Source
public String getRelTypeName() {
return REL_TYPE_NAME;
}
+
+ @Override
+ public IgniteRelWriter explain(IgniteRelWriter writer) {
+ return writer.addInvocation(getCall());
+ }
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteTableModify.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteTableModify.java
index b1957d98959..26b65da4be3 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteTableModify.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteTableModify.java
@@ -17,8 +17,6 @@
package org.apache.ignite.internal.sql.engine.rel;
-import static org.apache.ignite.internal.sql.engine.prepare.ExplainUtils.forExplain;
-
import java.util.List;
import org.apache.calcite.plan.RelOptCluster;
import org.apache.calcite.plan.RelOptTable;
@@ -29,6 +27,7 @@ import org.apache.calcite.rel.RelWriter;
import org.apache.calcite.rel.core.TableModify;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.rex.RexShuttle;
+import org.apache.ignite.internal.sql.engine.rel.explain.IgniteRelWriter;
import org.apache.ignite.internal.sql.engine.schema.IgniteTable;
import org.apache.ignite.internal.sql.engine.util.Commons;
import org.jetbrains.annotations.Nullable;
@@ -198,7 +197,7 @@ public class IgniteTableModify extends TableModify implements SourceAwareIgniteR
public RelWriter explainTerms(RelWriter pw) {
// for correct rel obtaining from ExecutionServiceImpl#physNodesCache.
return super.explainTerms(pw)
- .itemIf("tableId", Integer.toString(getTable().unwrap(IgniteTable.class).id()), !forExplain(pw))
+ .item("tableId", Integer.toString(getTable().unwrap(IgniteTable.class).id()))
.itemIf("sourceId", sourceId, sourceId != -1);
}
@@ -214,4 +213,11 @@ public class IgniteTableModify extends TableModify implements SourceAwareIgniteR
public String getRelTypeName() {
return REL_TYPE_NAME;
}
+
+ @Override
+ public IgniteRelWriter explain(IgniteRelWriter writer) {
+ return writer
+ .addTable(table)
+ .addModifyOperationType(getOperation());
+ }
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteTableScan.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteTableScan.java
index 180cdd13c0a..6991a31f9e5 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteTableScan.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteTableScan.java
@@ -28,6 +28,7 @@ import org.apache.calcite.rel.RelWriter;
import org.apache.calcite.rel.hint.RelHint;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.util.ImmutableBitSet;
+import org.apache.ignite.internal.sql.engine.rel.explain.IgniteRelWriter;
import org.jetbrains.annotations.Nullable;
/**
@@ -173,4 +174,10 @@ public class IgniteTableScan extends ProjectableFilterableTableScan implements S
@Override public String getRelTypeName() {
return REL_TYPE_NAME;
}
+
+ @Override
+ public IgniteRelWriter explain(
+ IgniteRelWriter writer) {
+ return explainAttributes(writer);
+ }
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteTrimExchange.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteTrimExchange.java
index 2eabf8735a9..42e8cab3fe7 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteTrimExchange.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteTrimExchange.java
@@ -32,6 +32,7 @@ import org.apache.calcite.rel.RelWriter;
import org.apache.calcite.rel.core.Exchange;
import org.apache.calcite.rel.metadata.RelMetadataQuery;
import org.apache.ignite.internal.sql.engine.metadata.cost.IgniteCost;
+import org.apache.ignite.internal.sql.engine.rel.explain.IgniteRelWriter;
import org.apache.ignite.internal.sql.engine.trait.IgniteDistribution;
/**
@@ -143,4 +144,9 @@ public class IgniteTrimExchange extends Exchange implements SourceAwareIgniteRel
public String getRelTypeName() {
return REL_TYPE_NAME;
}
+
+ @Override
+ public IgniteRelWriter explain(IgniteRelWriter writer) {
+ return writer.addDistribution(distribution(), getRowType());
+ }
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteValues.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteValues.java
index d3a7ee56618..e301b0b02ea 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteValues.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/IgniteValues.java
@@ -30,6 +30,8 @@ import org.apache.calcite.rel.core.Values;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rex.RexLiteral;
import org.apache.ignite.internal.sql.engine.exec.mapping.QuerySplitter;
+import org.apache.ignite.internal.sql.engine.rel.explain.IgniteRelWriter;
+import org.apache.ignite.internal.sql.engine.util.Commons;
/**
* IgniteValues.
@@ -138,4 +140,9 @@ public class IgniteValues extends Values implements SourceAwareIgniteRel {
public String getRelTypeName() {
return REL_TYPE_NAME;
}
+
+ @Override
+ public IgniteRelWriter explain(IgniteRelWriter writer) {
+ return writer.addTuples(Commons.cast(tuples));
+ }
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/ProjectableFilterableTableScan.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/ProjectableFilterableTableScan.java
index a5d25e3819c..7956b24ae05 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/ProjectableFilterableTableScan.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/ProjectableFilterableTableScan.java
@@ -18,7 +18,6 @@
package org.apache.ignite.internal.sql.engine.rel;
import static org.apache.calcite.sql.validate.SqlValidatorUtil.ATTEMPT_SUGGESTER;
-import static org.apache.ignite.internal.sql.engine.prepare.ExplainUtils.forExplain;
import static org.apache.ignite.internal.sql.engine.util.RexUtils.builder;
import static org.apache.ignite.internal.sql.engine.util.RexUtils.replaceLocalRefs;
@@ -43,10 +42,12 @@ import org.apache.calcite.rex.RexLocalRef;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.rex.RexShuttle;
import org.apache.calcite.rex.RexUtil;
+import org.apache.calcite.sql.SqlKind;
import org.apache.calcite.util.ControlFlowException;
import org.apache.calcite.util.ImmutableBitSet;
import org.apache.calcite.util.mapping.Mappings;
import org.apache.ignite.internal.sql.engine.metadata.cost.IgniteCost;
+import org.apache.ignite.internal.sql.engine.rel.explain.IgniteRelWriter;
import org.apache.ignite.internal.sql.engine.schema.IgniteDataSource;
import org.apache.ignite.internal.sql.engine.schema.IgniteTable;
import org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory;
@@ -133,9 +134,8 @@ public abstract class ProjectableFilterableTableScan extends TableScan {
@Override
public RelWriter explainTerms(RelWriter pw) {
return explainTerms0(pw
- .itemIf("table", table.getQualifiedName(), !forExplain(pw))
- .itemIf("table", table, forExplain(pw))
- .itemIf("tableId", Integer.toString(table.unwrap(IgniteDataSource.class).id()), !forExplain(pw)));
+ .item("table", table.getQualifiedName())
+ .item("tableId", Integer.toString(table.unwrap(IgniteDataSource.class).id())));
}
/** {@inheritDoc} */
@@ -157,10 +157,9 @@ public abstract class ProjectableFilterableTableScan extends TableScan {
RexUtil.expandSearch(getCluster().getRexBuilder(), null, condition));
}
- return pw.itemIf("fields", getRowType().getFieldNames(), forExplain(pw))
- .itemIf("names", names, names != null && !forExplain(pw))
+ return pw.itemIf("names", names, names != null)
.itemIf("projects", projects, projects != null)
- .itemIf("requiredColumns", requiredColumns, !forExplain(pw) && requiredColumns != null);
+ .itemIf("requiredColumns", requiredColumns, requiredColumns != null);
}
/** {@inheritDoc} */
@@ -239,4 +238,30 @@ public abstract class ProjectableFilterableTableScan extends TableScan {
return RexUtil.composeConjunction(builder(getCluster()), conjunctions, true);
}
+
+ protected IgniteRelWriter explainAttributes(IgniteRelWriter writer) {
+ writer.addTable(table);
+
+ if (condition != null || projects != null) {
+ RelDataType rowType = getTable().getRowType();
+ if (requiredColumns != null && requiredColumns.cardinality() < rowType.getFieldCount()) {
+ RelDataTypeFactory tf = getCluster().getTypeFactory();
+ IgniteDataSource dataSource = getTable().unwrap(IgniteDataSource.class);
+
+ assert dataSource != null;
+
+ rowType = dataSource.getRowType(tf, requiredColumns);
+ }
+
+ if (condition != null) {
+ writer.addPredicate(condition, rowType);
+ }
+
+ if (projects != null && projects.stream().anyMatch(p -> !p.isA(SqlKind.LOCAL_REF))) {
+ writer.addProjection(projects, rowType);
+ }
+ }
+
+ return writer;
+ }
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/agg/IgniteColocatedSortAggregate.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/agg/IgniteColocatedSortAggregate.java
index e4b54340917..05ae5bb3bb2 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/agg/IgniteColocatedSortAggregate.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/agg/IgniteColocatedSortAggregate.java
@@ -33,6 +33,7 @@ import org.apache.calcite.rel.metadata.RelMetadataQuery;
import org.apache.calcite.util.ImmutableBitSet;
import org.apache.ignite.internal.sql.engine.rel.IgniteRel;
import org.apache.ignite.internal.sql.engine.rel.IgniteRelVisitor;
+import org.apache.ignite.internal.sql.engine.rel.explain.IgniteRelWriter;
import org.apache.ignite.internal.sql.engine.trait.TraitUtils;
/**
@@ -117,4 +118,9 @@ public class IgniteColocatedSortAggregate extends IgniteColocatedAggregateBase i
@Override public String getRelTypeName() {
return REL_TYPE_NAME;
}
+
+ @Override
+ public IgniteRelWriter explain(IgniteRelWriter writer) {
+ return super.explain(writer).addCollation(collation, getRowType());
+ }
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/agg/IgniteMapSortAggregate.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/agg/IgniteMapSortAggregate.java
index 5d456773129..430c1f6a13e 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/agg/IgniteMapSortAggregate.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/agg/IgniteMapSortAggregate.java
@@ -35,6 +35,7 @@ import org.apache.calcite.util.ImmutableBitSet;
import org.apache.ignite.internal.sql.engine.rel.IgniteConvention;
import org.apache.ignite.internal.sql.engine.rel.IgniteRel;
import org.apache.ignite.internal.sql.engine.rel.IgniteRelVisitor;
+import org.apache.ignite.internal.sql.engine.rel.explain.IgniteRelWriter;
import org.apache.ignite.internal.sql.engine.trait.TraitUtils;
import org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory;
import org.apache.ignite.internal.sql.engine.util.Commons;
@@ -145,4 +146,9 @@ public class IgniteMapSortAggregate extends IgniteMapAggregateBase implements Ig
@Override public String getRelTypeName() {
return REL_TYPE_NAME;
}
+
+ @Override
+ public IgniteRelWriter explain(IgniteRelWriter writer) {
+ return super.explain(writer).addCollation(collation, getRowType());
+ }
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/agg/IgniteReduceAggregateBase.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/agg/IgniteReduceAggregateBase.java
index c9fd91ded94..adb9e4ae22b 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/agg/IgniteReduceAggregateBase.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/agg/IgniteReduceAggregateBase.java
@@ -17,8 +17,6 @@
package org.apache.ignite.internal.sql.engine.rel.agg;
-import static org.apache.ignite.internal.sql.engine.prepare.ExplainUtils.forExplain;
-
import java.util.List;
import org.apache.calcite.linq4j.Ord;
import org.apache.calcite.plan.RelOptCluster;
@@ -36,6 +34,7 @@ import org.apache.calcite.util.ImmutableBitSet;
import org.apache.calcite.util.Pair;
import org.apache.calcite.util.Util;
import org.apache.ignite.internal.sql.engine.rel.IgniteConvention;
+import org.apache.ignite.internal.sql.engine.rel.explain.IgniteRelWriter;
import org.apache.ignite.internal.sql.engine.trait.IgniteDistributions;
import org.apache.ignite.internal.sql.engine.trait.TraitUtils;
import org.apache.ignite.internal.sql.engine.trait.TraitsAwareIgniteRel;
@@ -106,7 +105,7 @@ public abstract class IgniteReduceAggregateBase extends SingleRel implements Tra
.itemIf("rowType", rowType, pw.getDetailLevel() == SqlExplainLevel.ALL_ATTRIBUTES)
.item("group", groupSet)
.itemIf("groups", groupSets, Group.induce(groupSet, groupSets) != Group.SIMPLE)
- .itemIf("aggs", aggCalls, pw.nest() && (!forExplain(pw) || !aggCalls.isEmpty()));
+ .itemIf("aggs", aggCalls, pw.nest());
if (!pw.nest()) {
for (Ord<AggregateCall> ord : Ord.zip(aggCalls)) {
@@ -175,4 +174,23 @@ public abstract class IgniteReduceAggregateBase extends SingleRel implements Tra
// cluster parallelism at the model (devide source rows by nodes for partitioned data).
return mq.getRowCount(getInput());
}
+
+ @Override
+ public IgniteRelWriter explain(IgniteRelWriter writer) {
+ RelDataType rowType = getInput().getRowType();
+
+ writer
+ .addGroup(groupSet, rowType)
+ .addAggregation(aggCalls, rowType);
+
+ if (getGroupType() != Group.SIMPLE) {
+ writer.addGroupSets(groupSets, rowType);
+ }
+
+ return writer;
+ }
+
+ public Group getGroupType() {
+ return Group.induce(groupSet, groupSets);
+ }
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/agg/IgniteReduceSortAggregate.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/agg/IgniteReduceSortAggregate.java
index 094eec595f0..4ead13badeb 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/agg/IgniteReduceSortAggregate.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/agg/IgniteReduceSortAggregate.java
@@ -35,6 +35,7 @@ import org.apache.ignite.internal.sql.engine.metadata.cost.IgniteCost;
import org.apache.ignite.internal.sql.engine.metadata.cost.IgniteCostFactory;
import org.apache.ignite.internal.sql.engine.rel.IgniteRel;
import org.apache.ignite.internal.sql.engine.rel.IgniteRelVisitor;
+import org.apache.ignite.internal.sql.engine.rel.explain.IgniteRelWriter;
import org.apache.ignite.internal.sql.engine.trait.TraitUtils;
/**
@@ -147,4 +148,9 @@ public class IgniteReduceSortAggregate extends IgniteReduceAggregateBase impleme
public String getRelTypeName() {
return REL_TYPE_NAME;
}
+
+ @Override
+ public IgniteRelWriter explain(IgniteRelWriter writer) {
+ return super.explain(writer).addCollation(collation, getRowType());
+ }
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/explain/ExplainUtils.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/explain/ExplainUtils.java
new file mode 100644
index 00000000000..06b6144ed45
--- /dev/null
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/explain/ExplainUtils.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.ignite.internal.sql.engine.rel.explain;
+
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rex.RexBiVisitor;
+import org.apache.calcite.rex.RexInputRef;
+import org.apache.calcite.rex.RexLocalRef;
+import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.rex.RexShuttle;
+import org.apache.calcite.rex.RexSlot;
+import org.apache.calcite.rex.RexVisitor;
+import org.apache.ignite.internal.sql.engine.rel.IgniteRel;
+import org.jetbrains.annotations.Nullable;
+
+/** Set of utility method used during EXPLAIN evaluation. */
+public final class ExplainUtils {
+ private ExplainUtils() {
+ throw new AssertionError("Should not be called");
+ }
+
+ /** Converts given relation to string representation suitable for EXPLAIN command output. */
+ public static String toString(IgniteRel rel) {
+ return RelTreeToTextWriter.dumpTree(rel);
+ }
+
+ static RexShuttle inputRefRewriter(RelDataType rowType) {
+ return new RexShuttle() {
+ @Override
+ public RexNode visitLocalRef(RexLocalRef ref) {
+ return new NamedRexSlot(rowType.getFieldNames().get(ref.getIndex()), ref.getIndex(), ref.getType());
+ }
+
+ @Override
+ public RexNode visitInputRef(RexInputRef ref) {
+ return new NamedRexSlot(rowType.getFieldNames().get(ref.getIndex()), ref.getIndex(), ref.getType());
+ }
+ };
+ }
+
+ private static class NamedRexSlot extends RexSlot {
+ NamedRexSlot(String name, int index, RelDataType type) {
+ super(name, index, type);
+ }
+
+ @Override
+ public <R> R accept(RexVisitor<R> visitor) {
+ throw new AssertionError("Should not be called");
+ }
+
+ @Override
+ public <R, P> R accept(RexBiVisitor<R, P> visitor, P arg) {
+ throw new AssertionError("Should not be called");
+ }
+
+ @Override
+ public boolean equals(@Nullable Object obj) {
+ return this == obj
+ || obj instanceof NamedRexSlot
+ && index == ((NamedRexSlot) obj).index;
+ }
+
+ @Override
+ public int hashCode() {
+ return index;
+ }
+ }
+}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/explain/IgniteRelWriter.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/explain/IgniteRelWriter.java
new file mode 100644
index 00000000000..dea62dad2ea
--- /dev/null
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/explain/IgniteRelWriter.java
@@ -0,0 +1,223 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.ignite.internal.sql.engine.rel.explain;
+
+import java.util.List;
+import java.util.Set;
+import org.apache.calcite.plan.RelOptTable;
+import org.apache.calcite.rel.RelCollation;
+import org.apache.calcite.rel.core.AggregateCall;
+import org.apache.calcite.rel.core.CorrelationId;
+import org.apache.calcite.rel.core.JoinRelType;
+import org.apache.calcite.rel.core.TableModify.Operation;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rex.RexLiteral;
+import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.util.ImmutableBitSet;
+import org.apache.ignite.internal.sql.engine.prepare.bounds.SearchBounds;
+import org.apache.ignite.internal.sql.engine.rel.IgniteCorrelatedNestedLoopJoin;
+import org.apache.ignite.internal.sql.engine.rel.IgniteKeyValueGet;
+import org.apache.ignite.internal.sql.engine.rel.IgniteKeyValueModify;
+import org.apache.ignite.internal.sql.engine.rel.IgniteRel;
+import org.apache.ignite.internal.sql.engine.rel.IgniteTableFunctionScan;
+import org.apache.ignite.internal.sql.engine.schema.IgniteIndex;
+import org.apache.ignite.internal.sql.engine.trait.IgniteDistribution;
+
+/**
+ * A fluent interface for explaining the structure and metadata of an {@link IgniteRel}
+ * (relational operator) node.
+ */
+@SuppressWarnings("UnusedReturnValue")
+public interface IgniteRelWriter {
+
+ /**
+ * Adds a list of projection expressions to the current relational node.
+ *
+ * @param projections List of {@link RexNode} expressions representing the projected output.
+ * @param rowType The row type against which field indexes in the projections should be resolved.
+ * @return This writer instance for chaining.
+ */
+ IgniteRelWriter addProjection(List<RexNode> projections, RelDataType rowType);
+
+ /**
+ * Adds a filtering predicate applied to the input rows of the relational node.
+ *
+ * @param condition A {@link RexNode} representing the filtering condition.
+ * @param rowType The row type against which field indexes in the predicate should be resolved.
+ * @return This writer instance for chaining.
+ */
+ IgniteRelWriter addPredicate(RexNode condition, RelDataType rowType);
+
+ /**
+ * Adds table metadata to the current relational node.
+ *
+ * @param table A {@link RelOptTable} representing the referenced table.
+ * @return This writer instance for chaining.
+ */
+ IgniteRelWriter addTable(RelOptTable table);
+
+ /**
+ * Adds index metadata, including name and type, associated with the relational node.
+ *
+ * @param name The name of the index.
+ * @param type The type of the index, from {@link IgniteIndex.Type}.
+ * @return This writer instance for chaining.
+ */
+ IgniteRelWriter addIndex(String name, IgniteIndex.Type type);
+
+ /**
+ * Adds collation (sort order) information for the node’s output rows.
+ *
+ * @param collation The {@link RelCollation} defining sort directions.
+ * @param rowType The row type against which field indexes in the collation should be resolved.
+ * @return This writer instance for chaining.
+ */
+ IgniteRelWriter addCollation(RelCollation collation, RelDataType rowType);
+
+ /**
+ * Adds literal tuples that represent either static data or example results.
+ *
+ * @param tuples A list of row tuples, each consisting of {@link RexLiteral} values.
+ * @return This writer instance for chaining.
+ */
+ IgniteRelWriter addTuples(List<List<RexLiteral>> tuples);
+
+ /**
+ * Adds a child relational node (i.e., an input) to the current node.
+ *
+ * @param rel The child {@link IgniteRel} node.
+ * @return This writer instance for chaining.
+ */
+ IgniteRelWriter addChild(IgniteRel rel);
+
+ /**
+ * Adds join type metadata for join operations.
+ *
+ * @param joinType The {@link JoinRelType} (e.g., INNER, LEFT, SEMI).
+ * @return This writer instance for chaining.
+ */
+ IgniteRelWriter addJoinType(JoinRelType joinType);
+
+ /**
+ * Adds distribution information that describes how the rows are distributed across nodes.
+ *
+ * @param distribution The {@link IgniteDistribution} strategy.
+ * @param rowType The row type against which field indexes in the distribution should be resolved.
+ * @return This writer instance for chaining.
+ */
+ IgniteRelWriter addDistribution(IgniteDistribution distribution, RelDataType rowType);
+
+ /**
+ * Adds source expressions used for row computations. Mainly used by {@link IgniteKeyValueModify}.
+ *
+ * @param expressions List of {@link RexNode} expressions representing source values.
+ * @return This writer instance for chaining.
+ */
+ IgniteRelWriter addSourceExpressions(List<RexNode> expressions);
+
+ /**
+ * Adds the type of data modification operation (e.g., INSERT, UPDATE, DELETE).
+ *
+ * @param operation The type of modification operation.
+ * @return This writer instance for chaining.
+ */
+ IgniteRelWriter addModifyOperationType(Operation operation);
+
+ /**
+ * Adds grouping key information used in aggregation operations.
+ *
+ * @param groupSet The {@link ImmutableBitSet} representing grouping key indexes.
+ * @param rowType The row type against which field indexes in the group set should be resolved.
+ * @return This writer instance for chaining.
+ */
+ IgniteRelWriter addGroup(ImmutableBitSet groupSet, RelDataType rowType);
+
+ /**
+ * Adds multiple group sets used for advanced grouping (e.g., ROLLUP or CUBE).
+ *
+ * @param groupSets List of {@link ImmutableBitSet} instances.
+ * @param rowType The row type against which field indexes in the group set should be resolved.
+ * @return This writer instance for chaining.
+ */
+ IgniteRelWriter addGroupSets(List<ImmutableBitSet> groupSets, RelDataType rowType);
+
+ /**
+ * Adds aggregation function calls applied to grouped data.
+ *
+ * @param aggCalls List of {@link AggregateCall} objects defining aggregations.
+ * @param rowType The row type against which field indexes in the aggregate should be resolved.
+ * @return This writer instance for chaining.
+ */
+ IgniteRelWriter addAggregation(List<AggregateCall> aggCalls, RelDataType rowType);
+
+ /**
+ * Adds expressions forming a key for {@link IgniteKeyValueGet lookup-by-a-key} node.
+ *
+ * @param expressions List of {@link RexNode} expressions representing key.
+ * @return This writer instance for chaining.
+ */
+ IgniteRelWriter addKeyExpression(List<RexNode> expressions);
+
+ /**
+ * Adds correlated variables which are set by {@link IgniteCorrelatedNestedLoopJoin}.
+ *
+ * @param variablesSet Set of {@link CorrelationId} identifiers.
+ * @return This writer instance for chaining.
+ */
+ IgniteRelWriter addCorrelatedVariables(Set<CorrelationId> variablesSet);
+
+ /**
+ * Adds search bounds used for index look ups.
+ *
+ * @param searchBounds List of {@link SearchBounds} representing boundaries of the range scan or point look up.
+ * @return This writer instance for chaining.
+ */
+ IgniteRelWriter addSearchBounds(List<SearchBounds> searchBounds);
+
+ /**
+ * Adds an invocation of an expressions. Mainly used by {@link IgniteTableFunctionScan} rel.
+ *
+ * @param call A {@link RexNode} representing the invocation.
+ * @return This writer instance for chaining.
+ */
+ IgniteRelWriter addInvocation(RexNode call);
+
+ /**
+ * Adds an expressions denoting how many rows should be skipped before emitting a result.
+ *
+ * @param offset A {@link RexNode} representing the number of rows to skip.
+ * @return This writer instance for chaining.
+ */
+ IgniteRelWriter addOffset(RexNode offset);
+
+ /**
+ * Adds an expressions denoting how many rows should be returned.
+ *
+ * @param fetch A {@link RexNode} representing the number of rows to return.
+ * @return This writer instance for chaining.
+ */
+ IgniteRelWriter addFetch(RexNode fetch);
+
+ /**
+ * Adds a notion whether set operation does rows deduplication or not.
+ *
+ * @param all A flag denoting whether rows will be de-duplicated.
+ * @return This writer instance for chaining.
+ */
+ IgniteRelWriter addAll(boolean all);
+}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/explain/RelTreeToTextWriter.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/explain/RelTreeToTextWriter.java
new file mode 100644
index 00000000000..d8af939ab78
--- /dev/null
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/explain/RelTreeToTextWriter.java
@@ -0,0 +1,439 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.ignite.internal.sql.engine.rel.explain;
+
+import static org.apache.ignite.internal.sql.engine.rel.explain.ExplainUtils.inputRefRewriter;
+
+import it.unimi.dsi.fastutil.objects.ObjectIntPair;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Deque;
+import java.util.EnumMap;
+import java.util.List;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import org.apache.calcite.avatica.util.Spacer;
+import org.apache.calcite.linq4j.Ord;
+import org.apache.calcite.plan.RelOptTable;
+import org.apache.calcite.rel.RelCollation;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.core.AggregateCall;
+import org.apache.calcite.rel.core.CorrelationId;
+import org.apache.calcite.rel.core.JoinRelType;
+import org.apache.calcite.rel.core.SetOp;
+import org.apache.calcite.rel.core.TableModify;
+import org.apache.calcite.rel.metadata.RelMetadataQuery;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rex.RexLiteral;
+import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.rex.RexShuttle;
+import org.apache.calcite.util.ImmutableBitSet;
+import org.apache.ignite.internal.sql.engine.prepare.bounds.SearchBounds;
+import org.apache.ignite.internal.sql.engine.rel.IgniteRel;
+import org.apache.ignite.internal.sql.engine.schema.IgniteIndex;
+import org.apache.ignite.internal.sql.engine.trait.IgniteDistribution;
+import org.apache.ignite.internal.sql.engine.util.Commons;
+import org.apache.ignite.lang.util.IgniteNameUtils;
+import org.apache.ignite.table.QualifiedNameHelper;
+
+class RelTreeToTextWriter {
+ private static final int NEXT_OPERATOR_INDENT = 2;
+ private static final int OPERATOR_ATTRIBUTES_INDENT = 2 * NEXT_OPERATOR_INDENT;
+
+ private static boolean needToAddFieldNames(IgniteRel rel) {
+ List<RelNode> inputs = rel.getInputs();
+
+ // Current rel is leaf node of the plan, therefore it's data source.
+ // Every data source introduces their own row type, so let's include field names.
+ if (inputs.isEmpty()) {
+ return true;
+ }
+
+ // Set operations doesn't change the row.
+ if (rel instanceof SetOp) {
+ return false;
+ }
+
+ // In case of rel with single input we can do fast check.
+ // Reference comparison is correct because typeFactory must intern every type.
+ if (inputs.size() == 1 && rel.getRowType() == inputs.get(0).getRowType()) {
+ // We want to include field names only if there were changes in number of columns, their order, or their names.
+ // Therefore if row types are not equal we should double check that changes were not [only] in the column types.
+ return false;
+ }
+
+ assert inputs.size() == 1 || inputs.size() == 2;
+
+ List<String> inputNames = new ArrayList<>(inputs.get(0).getRowType().getFieldNames());
+
+ // Join might do rename when both side contains the column with the same name.
+ if (inputs.size() == 2) {
+ inputNames.addAll(inputs.get(1).getRowType().getFieldNames());
+ }
+
+ return !rel.getRowType().getFieldNames().equals(inputNames);
+ }
+
+ private static RelInfoHolder collectRelInfo(IgniteRel rel) {
+ RelInfoHolder infoHolder = new RelInfoHolder(rel);
+
+ rel.explain(infoHolder);
+
+ if (!infoHolder.attributes.containsKey(AttributeName.FIELD_NAMES) && needToAddFieldNames(rel)) {
+ infoHolder.attributes.put(AttributeName.FIELD_NAMES, rel.getRowType().getFieldNames().toString());
+ }
+
+ rel.getInputs().forEach(input -> infoHolder.addChild((IgniteRel) input));
+
+ return infoHolder;
+ }
+
+ private enum AttributeName {
+ TABLE("table"),
+ INDEX_NAME("index"),
+ INDEX_TYPE("type"),
+ PREDICATE("predicate"),
+ SEARCH_BOUNDS("searchBounds"),
+ FIELD_NAMES("fieldNames"),
+ PROJECTION("projection"),
+ COLLATION("collation"),
+ TUPLES("tuples"),
+ JOIN_TYPE("type"),
+ DISTRIBUTION("distribution"),
+ SOURCE_EXPRESSIONS("sourceExpression"),
+ MODIFY_OPERATION_TYPE("type"),
+ GROUP("group"),
+ GROUP_SETS("groupSets"),
+ AGGREGATION("aggregation"),
+ KEY_EXPRESSIONS("key"),
+ CORRELATED_VARIABLES("correlates"),
+ INVOCATION("invocation"),
+ OFFSET("offset"),
+ FETCH("fetch"),
+ ALL("all");
+
+ private final String label;
+
+ AttributeName(String label) {
+ this.label = label;
+ }
+ }
+
+ private static class RelInfoHolder implements IgniteRelWriter {
+ private final IgniteRel rel;
+
+ private final EnumMap<AttributeName, String> attributes = new EnumMap<>(AttributeName.class);
+ private final List<RelInfoHolder> inputs = new ArrayList<>();
+
+ RelInfoHolder(IgniteRel rel) {
+ this.rel = rel;
+ }
+
+ @Override
+ public IgniteRelWriter addChild(IgniteRel rel) {
+ RelInfoHolder infoHolder = collectRelInfo(rel);
+
+ inputs.add(infoHolder);
+
+ return this;
+ }
+
+ @Override
+ public IgniteRelWriter addProjection(List<RexNode> projections, RelDataType rowType) {
+ RexShuttle inputRefRewriter = inputRefRewriter(rowType);
+
+ Function<RexNode, RexNode> f = in -> in.accept(inputRefRewriter);
+
+ attributes.put(AttributeName.PROJECTION, Commons.transform(projections, f).toString());
+
+ return this;
+ }
+
+ @Override
+ public IgniteRelWriter addPredicate(RexNode condition, RelDataType rowType) {
+ attributes.put(AttributeName.PREDICATE, condition.accept(inputRefRewriter(rowType)).toString());
+
+ return this;
+ }
+
+ @Override
+ public IgniteRelWriter addTable(RelOptTable table) {
+ List<String> parts = table.getQualifiedName();
+
+ assert parts.size() == 2 : parts;
+
+ attributes.put(AttributeName.TABLE, QualifiedNameHelper.fromNormalized(parts.get(0), parts.get(1)).toCanonicalForm());
+
+ return this;
+ }
+
+ @Override
+ public IgniteRelWriter addIndex(String name, IgniteIndex.Type type) {
+ attributes.put(AttributeName.INDEX_NAME, IgniteNameUtils.quoteIfNeeded(name));
+ attributes.put(AttributeName.INDEX_TYPE, type.name());
+
+ return this;
+ }
+
+ @Override
+ public IgniteRelWriter addCollation(RelCollation collation, RelDataType rowType) {
+ attributes.put(AttributeName.COLLATION, beautifyCollation(collation, rowType).toString());
+
+ return this;
+ }
+
+ @Override
+ public IgniteRelWriter addTuples(List<List<RexLiteral>> tuples) {
+ attributes.put(AttributeName.TUPLES, tuples.toString());
+
+ return this;
+ }
+
+ @Override
+ public IgniteRelWriter addJoinType(JoinRelType joinType) {
+ attributes.put(AttributeName.JOIN_TYPE, joinType.lowerName);
+
+ return this;
+ }
+
+ @Override
+ public IgniteRelWriter addDistribution(IgniteDistribution distribution, RelDataType rowType) {
+ attributes.put(AttributeName.DISTRIBUTION, distribution.toString());
+
+ return this;
+ }
+
+ @Override
+ public IgniteRelWriter addSourceExpressions(List<RexNode> expressions) {
+ attributes.put(AttributeName.SOURCE_EXPRESSIONS, expressions.toString());
+
+ return this;
+ }
+
+ @Override
+ public IgniteRelWriter addModifyOperationType(TableModify.Operation operation) {
+ attributes.put(AttributeName.MODIFY_OPERATION_TYPE, operation.toString());
+
+ return this;
+ }
+
+ @Override
+ public IgniteRelWriter addGroup(ImmutableBitSet groupSet, RelDataType rowType) {
+ attributes.put(AttributeName.GROUP, beautifyBitSet(groupSet, rowType).toString());
+
+ return this;
+ }
+
+ @Override
+ public IgniteRelWriter addGroupSets(List<ImmutableBitSet> groupSets, RelDataType rowType) {
+ List<List<String>> sets = groupSets.stream()
+ .map(groupSet -> beautifyBitSet(groupSet, rowType))
+ .collect(Collectors.toList());
+
+ attributes.put(AttributeName.GROUP_SETS, sets.toString());
+
+ return this;
+ }
+
+ @Override
+ public IgniteRelWriter addAggregation(List<AggregateCall> aggCalls, RelDataType rowType) {
+ RexShuttle inputRefRewriter = inputRefRewriter(rowType);
+
+ List<String> calls = aggCalls.stream()
+ .map(call -> beautifyAggCall(call, inputRefRewriter, rowType))
+ .collect(Collectors.toList());
+
+ attributes.put(AttributeName.AGGREGATION, calls.toString());
+
+ return this;
+ }
+
+ @Override
+ public IgniteRelWriter addKeyExpression(List<RexNode> expressions) {
+ attributes.put(AttributeName.KEY_EXPRESSIONS, expressions.toString());
+
+ return this;
+ }
+
+ @Override
+ public IgniteRelWriter addCorrelatedVariables(Set<CorrelationId> variablesSet) {
+ attributes.put(AttributeName.CORRELATED_VARIABLES, variablesSet.toString());
+
+ return this;
+ }
+
+ @Override
+ public IgniteRelWriter addSearchBounds(List<SearchBounds> searchBounds) {
+ attributes.put(AttributeName.SEARCH_BOUNDS, searchBounds.toString());
+
+ return this;
+ }
+
+ @Override
+ public IgniteRelWriter addInvocation(RexNode call) {
+ attributes.put(AttributeName.INVOCATION, call.toString());
+
+ return this;
+ }
+
+ @Override
+ public IgniteRelWriter addOffset(RexNode offset) {
+ attributes.put(AttributeName.OFFSET, offset.toString());
+
+ return this;
+ }
+
+ @Override
+ public IgniteRelWriter addFetch(RexNode fetch) {
+ attributes.put(AttributeName.FETCH, fetch.toString());
+
+ return this;
+ }
+
+ @Override
+ public IgniteRelWriter addAll(boolean all) {
+ attributes.put(AttributeName.ALL, String.valueOf(all));
+
+ return this;
+ }
+ }
+
+ static String dumpTree(IgniteRel rootRel) {
+ RelInfoHolder root = collectRelInfo(rootRel);
+
+ Deque<ObjectIntPair<RelInfoHolder>> explanationStack = new ArrayDeque<>();
+ explanationStack.add(ObjectIntPair.of(root, 0));
+
+ StringBuilder sb = new StringBuilder();
+ Spacer spacer = new Spacer();
+ while (!explanationStack.isEmpty()) {
+ ObjectIntPair<RelInfoHolder> infoHolderWithLevel = explanationStack.pollLast();
+
+ RelInfoHolder infoHolder = infoHolderWithLevel.first();
+ int level = infoHolderWithLevel.secondInt();
+
+ for (int i = infoHolder.inputs.size() - 1; i >= 0; i--) {
+ explanationStack.add(ObjectIntPair.of(infoHolder.inputs.get(i), level + 1));
+ }
+
+ spacer.set(level * NEXT_OPERATOR_INDENT);
+
+ spacer.spaces(sb).append(infoHolder.rel.getRelTypeName());
+
+ spacer.add(OPERATOR_ATTRIBUTES_INDENT);
+
+ for (AttributeName name : AttributeName.values()) {
+ String attributeValue = infoHolder.attributes.get(name);
+
+ if (attributeValue == null) {
+ continue;
+ }
+
+ sb.append(System.lineSeparator());
+
+ spacer.spaces(sb);
+
+ sb.append(name.label).append(": ").append(attributeValue);
+ }
+
+ sb.append(System.lineSeparator());
+ spacer.spaces(sb);
+
+ RelMetadataQuery mq = infoHolder.rel.getCluster().getMetadataQuery();
+ sb.append("est: (rows=").append(
+ BigDecimal.valueOf(mq.getRowCount(infoHolder.rel)).setScale(0, RoundingMode.HALF_UP)
+ ).append(')');
+
+ spacer.subtract(OPERATOR_ATTRIBUTES_INDENT);
+
+ sb.append(System.lineSeparator());
+ }
+
+ return sb.toString();
+ }
+
+ private static List<String> beautifyBitSet(ImmutableBitSet bitSet, RelDataType rowType) {
+ return bitSet.stream()
+ .mapToObj(rowType.getFieldNames()::get)
+ .collect(Collectors.toList());
+ }
+
+ private static String beautifyAggCall(AggregateCall call, RexShuttle inputRefRewriter, RelDataType rowType) {
+ StringBuilder buf = new StringBuilder(call.getAggregation().toString());
+ buf.append('(');
+
+ if (call.isApproximate()) {
+ buf.append("APPROXIMATE ");
+ }
+ if (call.isDistinct()) {
+ buf.append(call.getArgList().isEmpty() ? "DISTINCT" : "DISTINCT ");
+ }
+ int i = -1;
+ for (RexNode rexNode : call.rexList) {
+ if (++i > 0) {
+ buf.append(", ");
+ }
+ buf.append(rexNode.accept(inputRefRewriter));
+ }
+ for (Integer arg : call.getArgList()) {
+ if (++i > 0) {
+ buf.append(", ");
+ }
+ buf.append(rowType.getFieldNames().get(arg));
+ }
+ buf.append(')');
+ if (call.distinctKeys != null) {
+ buf.append(" WITHIN DISTINCT (");
+ for (Ord<Integer> key : Ord.zip(call.distinctKeys)) {
+ buf.append(key.i > 0 ? ", " : "");
+ buf.append(rowType.getFieldNames().get(key.e));
+ }
+ buf.append(')');
+ }
+ if (call.hasCollation()) {
+ buf.append(" WITHIN GROUP (");
+ buf.append(beautifyCollation(call.collation, rowType));
+ buf.append(')');
+ }
+ if (call.hasFilter()) {
+ buf.append(" FILTER ");
+ buf.append(rowType.getFieldNames().get(call.filterArg));
+ }
+ return buf.toString();
+ }
+
+ private static List<String> beautifyCollation(RelCollation collation, RelDataType rowType) {
+ return collation.getFieldCollations().stream().map(fc -> {
+ StringBuilder sb = new StringBuilder(rowType.getFieldNames().get(fc.getFieldIndex()))
+ .append(' ').append(fc.direction.shortString);
+
+ if (fc.nullDirection != fc.direction.defaultNullDirection()) {
+ sb.append(" NULLS ").append(fc.nullDirection);
+ }
+
+ return sb.toString();
+ }).collect(Collectors.toList());
+ }
+
+ private RelTreeToTextWriter() {
+ throw new AssertionError("Should not be called");
+ }
+}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/set/IgniteIntersect.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/set/IgniteIntersect.java
index 99f3051151b..8cd40d84e6c 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/set/IgniteIntersect.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/set/IgniteIntersect.java
@@ -27,6 +27,7 @@ import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.core.Intersect;
import org.apache.calcite.rel.metadata.RelMetadataQuery;
import org.apache.ignite.internal.sql.engine.rel.IgniteConvention;
+import org.apache.ignite.internal.sql.engine.rel.explain.IgniteRelWriter;
import org.apache.ignite.internal.sql.engine.trait.TraitUtils;
/**
@@ -67,4 +68,9 @@ public abstract class IgniteIntersect extends Intersect implements IgniteSetOp {
public boolean all() {
return all;
}
+
+ @Override
+ public IgniteRelWriter explain(IgniteRelWriter writer) {
+ return writer.addAll(all);
+ }
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/set/IgniteMinus.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/set/IgniteMinus.java
index 26ab768070d..d6f534e5f59 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/set/IgniteMinus.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/set/IgniteMinus.java
@@ -27,6 +27,7 @@ import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.core.Minus;
import org.apache.calcite.rel.metadata.RelMetadataQuery;
import org.apache.ignite.internal.sql.engine.rel.IgniteConvention;
+import org.apache.ignite.internal.sql.engine.rel.explain.IgniteRelWriter;
import org.apache.ignite.internal.sql.engine.trait.TraitUtils;
/**
@@ -78,4 +79,9 @@ public abstract class IgniteMinus extends Minus implements IgniteSetOp {
public boolean all() {
return all;
}
+
+ @Override
+ public IgniteRelWriter explain(IgniteRelWriter writer) {
+ return writer.addAll(all);
+ }
}
diff --git a/modules/sql-engine/src/test/resources/tpcds/plan/q64.plan b/modules/sql-engine/src/test/resources/tpcds/plan/q64.plan
index 0054340b8e0..04cdf2ea539 100644
--- a/modules/sql-engine/src/test/resources/tpcds/plan/q64.plan
+++ b/modules/sql-engine/src/test/resources/tpcds/plan/q64.plan
@@ -2,472 +2,489 @@ Sort
collation: [PRODUCT_NAME ASC, STORE_NAME ASC, CNT0 ASC, S11 ASC, S12 ASC]
est: (rows=21)
Project
- fields: [PRODUCT_NAME, STORE_NAME, STORE_ZIP, B_STREET_NUMBER, B_STREET_NAME, B_CITY, B_ZIP, C_STREET_NUMBER, C_STREET_NAME, C_CITY, C_ZIP, SYEAR, CNT, S11, S21, S31, S12, S22, S32, SYEAR0, CNT0]
- exprs: [PRODUCT_NAME, STORE_NAME, STORE_ZIP, B_STREET_NUMBER, B_STREET_NAME, B_CITY, B_ZIP, C_STREET_NUMBER, C_STREET_NAME, C_CITY, C_ZIP, SYEAR, CNT, S1, S2, S3, S10, S20, S30, SYEAR0, CNT0]
+ fieldNames: [PRODUCT_NAME, STORE_NAME, STORE_ZIP, B_STREET_NUMBER, B_STREET_NAME, B_CITY, B_ZIP, C_STREET_NUMBER, C_STREET_NAME, C_CITY, C_ZIP, SYEAR, CNT, S11, S21, S31, S12, S22, S32, SYEAR0, CNT0]
+ projection: [PRODUCT_NAME, STORE_NAME, STORE_ZIP, B_STREET_NUMBER, B_STREET_NAME, B_CITY, B_ZIP, C_STREET_NUMBER, C_STREET_NAME, C_CITY, C_ZIP, SYEAR, CNT, S1, S2, S3, S10, S20, S30, SYEAR0, CNT0]
est: (rows=21)
HashJoin
- condition: AND(=(ITEM_SK, ITEM_SK0), <=(CNT0, CNT), =(STORE_NAME, STORE_NAME0), =(STORE_ZIP, STORE_ZIP0))
- joinType: inner
+ predicate: AND(=(ITEM_SK, ITEM_SK0), <=(CNT0, CNT), =(STORE_NAME, STORE_NAME0), =(STORE_ZIP, STORE_ZIP0))
+ fieldNames: [PRODUCT_NAME, ITEM_SK, STORE_NAME, STORE_ZIP, B_STREET_NUMBER, B_STREET_NAME, B_CITY, B_ZIP, C_STREET_NUMBER, C_STREET_NAME, C_CITY, C_ZIP, SYEAR, FSYEAR, S2YEAR, CNT, S1, S2, S3, PRODUCT_NAME0, ITEM_SK0, STORE_NAME0, STORE_ZIP0, B_STREET_NUMBER0, B_STREET_NAME0, B_CITY0, B_ZIP0, C_STREET_NUMBER0, C_STREET_NAME0, C_CITY0, C_ZIP0, SYEAR0, FSYEAR0, S2YEAR0, CNT0, S10, S20, S30]
+ type: inner
est: (rows=21)
ColocatedHashAggregate
+ fieldNames: [PRODUCT_NAME, ITEM_SK, STORE_NAME, STORE_ZIP, B_STREET_NUMBER, B_STREET_NAME, B_CITY, B_ZIP, C_STREET_NUMBER, C_STREET_NAME, C_CITY, C_ZIP, SYEAR, FSYEAR, S2YEAR, CNT, S1, S2, S3]
group: [PRODUCT_NAME, ITEM_SK, STORE_NAME, STORE_ZIP, B_STREET_NUMBER, B_STREET_NAME, B_CITY, B_ZIP, C_STREET_NUMBER, C_STREET_NAME, C_CITY, C_ZIP, SYEAR, FSYEAR, S2YEAR]
- aggs: [CNT=COUNT(), S1=SUM(SS_WHOLESALE_COST), S2=SUM(SS_LIST_PRICE), S3=SUM(SS_COUPON_AMT)]
+ aggregation: [COUNT(), SUM(SS_WHOLESALE_COST), SUM(SS_LIST_PRICE), SUM(SS_COUPON_AMT)]
est: (rows=2887)
Project
- fields: [PRODUCT_NAME, ITEM_SK, STORE_NAME, STORE_ZIP, B_STREET_NUMBER, B_STREET_NAME, B_CITY, B_ZIP, C_STREET_NUMBER, C_STREET_NAME, C_CITY, C_ZIP, SYEAR, FSYEAR, S2YEAR, SS_WHOLESALE_COST, SS_LIST_PRICE, SS_COUPON_AMT]
- exprs: [I_PRODUCT_NAME, I_ITEM_SK, S_STORE_NAME, S_ZIP, CA_STREET_NUMBER, CA_STREET_NAME, CA_CITY, CA_ZIP, CA_STREET_NUMBER0, CA_STREET_NAME0, CA_CITY0, CA_ZIP0, D_YEAR00, D_YEAR, D_YEAR0, SS_WHOLESALE_COST, SS_LIST_PRICE, SS_COUPON_AMT]
+ fieldNames: [PRODUCT_NAME, ITEM_SK, STORE_NAME, STORE_ZIP, B_STREET_NUMBER, B_STREET_NAME, B_CITY, B_ZIP, C_STREET_NUMBER, C_STREET_NAME, C_CITY, C_ZIP, SYEAR, FSYEAR, S2YEAR, SS_WHOLESALE_COST, SS_LIST_PRICE, SS_COUPON_AMT]
+ projection: [I_PRODUCT_NAME, I_ITEM_SK, S_STORE_NAME, S_ZIP, CA_STREET_NUMBER, CA_STREET_NAME, CA_CITY, CA_ZIP, CA_STREET_NUMBER0, CA_STREET_NAME0, CA_CITY0, CA_ZIP0, D_YEAR00, D_YEAR, D_YEAR0, SS_WHOLESALE_COST, SS_LIST_PRICE, SS_COUPON_AMT]
est: (rows=2992)
HashJoin
- condition: AND(=(SS_ITEM_SK, SR_ITEM_SK), =(SS_TICKET_NUMBER, SR_TICKET_NUMBER))
- joinType: inner
+ predicate: AND(=(SS_ITEM_SK, SR_ITEM_SK), =(SS_TICKET_NUMBER, SR_TICKET_NUMBER))
+ type: inner
est: (rows=2992)
Exchange
distribution: single
est: (rows=287514)
TableScan
table: PUBLIC.STORE_RETURNS
- fields: [SR_ITEM_SK, SR_TICKET_NUMBER]
+ fieldNames: [SR_ITEM_SK, SR_TICKET_NUMBER]
est: (rows=287514)
HashJoin
- condition: =(C_FIRST_SALES_DATE_SK, D_DATE_SK)
- joinType: inner
+ predicate: =(C_FIRST_SALES_DATE_SK, D_DATE_SK)
+ fieldNames: [D_DATE_SK, D_YEAR, D_DATE_SK0, D_YEAR0, CA_ADDRESS_SK, CA_STREET_NUMBER, CA_STREET_NAME, CA_CITY, CA_ZIP, CA_ADDRESS_SK0, CA_STREET_NUMBER0, CA_STREET_NAME0, CA_CITY0, CA_ZIP0, HD_DEMO_SK, HD_INCOME_BAND_SK, HD_DEMO_SK0, HD_INCOME_BAND_SK0, CD_DEMO_SK, CD_MARITAL_STATUS, CD_DEMO_SK0, CD_MARITAL_STATUS0, C_CUSTOMER_SK, C_CURRENT_CDEMO_SK, C_CURRENT_HDEMO_SK, C_CURRENT_ADDR_SK, C_FIRST_SHIPTO_DATE_SK, C_FIRST_SALES_DATE_SK, SS_SOLD_DATE_SK, SS_ITEM_SK, SS_CUSTO [...]
+ type: inner
est: (rows=90684167)
Exchange
distribution: single
est: (rows=73049)
TableScan
table: PUBLIC.DATE_DIM
- fields: [D_DATE_SK, D_YEAR]
+ fieldNames: [D_DATE_SK, D_YEAR]
est: (rows=73049)
HashJoin
- condition: =(C_FIRST_SHIPTO_DATE_SK, D_DATE_SK)
- joinType: inner
+ predicate: =(C_FIRST_SHIPTO_DATE_SK, D_DATE_SK)
+ fieldNames: [D_DATE_SK, D_YEAR, CA_ADDRESS_SK, CA_STREET_NUMBER, CA_STREET_NAME, CA_CITY, CA_ZIP, CA_ADDRESS_SK0, CA_STREET_NUMBER0, CA_STREET_NAME0, CA_CITY0, CA_ZIP0, HD_DEMO_SK, HD_INCOME_BAND_SK, HD_DEMO_SK0, HD_INCOME_BAND_SK0, CD_DEMO_SK, CD_MARITAL_STATUS, CD_DEMO_SK0, CD_MARITAL_STATUS0, C_CUSTOMER_SK, C_CURRENT_CDEMO_SK, C_CURRENT_HDEMO_SK, C_CURRENT_ADDR_SK, C_FIRST_SHIPTO_DATE_SK, C_FIRST_SALES_DATE_SK, SS_SOLD_DATE_SK, SS_ITEM_SK, SS_CUSTOMER_SK, SS_CDEMO_SK [...]
+ type: inner
est: (rows=90684167)
Exchange
distribution: single
est: (rows=73049)
TableScan
table: PUBLIC.DATE_DIM
- fields: [D_DATE_SK, D_YEAR]
+ fieldNames: [D_DATE_SK, D_YEAR]
est: (rows=73049)
HashJoin
- condition: =(SS_STORE_SK, S_STORE_SK)
- joinType: inner
+ predicate: =(SS_STORE_SK, S_STORE_SK)
+ type: inner
est: (rows=90684167)
HashJoin
- condition: =(SS_PROMO_SK, P_PROMO_SK)
- joinType: inner
+ predicate: =(SS_PROMO_SK, P_PROMO_SK)
+ type: inner
est: (rows=90684167)
HashJoin
- condition: =(SS_ADDR_SK, CA_ADDRESS_SK)
- joinType: inner
+ predicate: =(SS_ADDR_SK, CA_ADDRESS_SK)
+ fieldNames: [CA_ADDRESS_SK, CA_STREET_NUMBER, CA_STREET_NAME, CA_CITY, CA_ZIP, CA_ADDRESS_SK0, CA_STREET_NUMBER0, CA_STREET_NAME0, CA_CITY0, CA_ZIP0, HD_DEMO_SK, HD_INCOME_BAND_SK, HD_DEMO_SK0, HD_INCOME_BAND_SK0, CD_DEMO_SK, CD_MARITAL_STATUS, CD_DEMO_SK0, CD_MARITAL_STATUS0, C_CUSTOMER_SK, C_CURRENT_CDEMO_SK, C_CURRENT_HDEMO_SK, C_CURRENT_ADDR_SK, C_FIRST_SHIPTO_DATE_SK, C_FIRST_SALES_DATE_SK, SS_SOLD_DATE_SK, SS_ITEM_SK, SS_CUSTOMER_SK, SS_CDEMO_SK, SS_HDEMO_SK [...]
+ type: inner
est: (rows=90684167)
Exchange
distribution: single
est: (rows=50000)
TableScan
table: PUBLIC.CUSTOMER_ADDRESS
- fields: [CA_ADDRESS_SK, CA_STREET_NUMBER, CA_STREET_NAME, CA_CITY, CA_ZIP]
+ fieldNames: [CA_ADDRESS_SK, CA_STREET_NUMBER, CA_STREET_NAME, CA_CITY, CA_ZIP]
est: (rows=50000)
HashJoin
- condition: =(C_CURRENT_ADDR_SK, CA_ADDRESS_SK)
- joinType: inner
+ predicate: =(C_CURRENT_ADDR_SK, CA_ADDRESS_SK)
+ type: inner
est: (rows=90684167)
Exchange
distribution: single
est: (rows=50000)
TableScan
table: PUBLIC.CUSTOMER_ADDRESS
- fields: [CA_ADDRESS_SK, CA_STREET_NUMBER, CA_STREET_NAME, CA_CITY, CA_ZIP]
+ fieldNames: [CA_ADDRESS_SK, CA_STREET_NUMBER, CA_STREET_NAME, CA_CITY, CA_ZIP]
est: (rows=50000)
HashJoin
- condition: =(HD_INCOME_BAND_SK, IB_INCOME_BAND_SK0)
- joinType: inner
+ predicate: =(HD_INCOME_BAND_SK, IB_INCOME_BAND_SK0)
+ fieldNames: [HD_DEMO_SK, HD_INCOME_BAND_SK, HD_DEMO_SK0, HD_INCOME_BAND_SK0, CD_DEMO_SK, CD_MARITAL_STATUS, CD_DEMO_SK0, CD_MARITAL_STATUS0, C_CUSTOMER_SK, C_CURRENT_CDEMO_SK, C_CURRENT_HDEMO_SK, C_CURRENT_ADDR_SK, C_FIRST_SHIPTO_DATE_SK, C_FIRST_SALES_DATE_SK, SS_SOLD_DATE_SK, SS_ITEM_SK, SS_CUSTOMER_SK, SS_CDEMO_SK, SS_HDEMO_SK, SS_ADDR_SK, SS_STORE_SK, SS_PROMO_SK, SS_TICKET_NUMBER, SS_WHOLESALE_COST, SS_LIST_PRICE, SS_COUPON_AMT, I_ITEM_SK, I_CURRENT_PRICE [...]
+ type: inner
est: (rows=90684167)
HashJoin
- condition: =(SS_HDEMO_SK, HD_DEMO_SK)
- joinType: inner
+ predicate: =(SS_HDEMO_SK, HD_DEMO_SK)
+ fieldNames: [HD_DEMO_SK, HD_INCOME_BAND_SK, HD_DEMO_SK0, HD_INCOME_BAND_SK0, CD_DEMO_SK, CD_MARITAL_STATUS, CD_DEMO_SK0, CD_MARITAL_STATUS0, C_CUSTOMER_SK, C_CURRENT_CDEMO_SK, C_CURRENT_HDEMO_SK, C_CURRENT_ADDR_SK, C_FIRST_SHIPTO_DATE_SK, C_FIRST_SALES_DATE_SK, SS_SOLD_DATE_SK, SS_ITEM_SK, SS_CUSTOMER_SK, SS_CDEMO_SK, SS_HDEMO_SK, SS_ADDR_SK, SS_STORE_SK, SS_PROMO_SK, SS_TICKET_NUMBER, SS_WHOLESALE_COST, SS_LIST_PRICE, SS_COUPON_AMT, I_ITEM_SK, I_CURRENT_PRI [...]
+ type: inner
est: (rows=90684167)
Exchange
distribution: single
est: (rows=7200)
TableScan
table: PUBLIC.HOUSEHOLD_DEMOGRAPHICS
- fields: [HD_DEMO_SK, HD_INCOME_BAND_SK]
+ fieldNames: [HD_DEMO_SK, HD_INCOME_BAND_SK]
est: (rows=7200)
HashJoin
- condition: =(HD_INCOME_BAND_SK, IB_INCOME_BAND_SK)
- joinType: inner
+ predicate: =(HD_INCOME_BAND_SK, IB_INCOME_BAND_SK)
+ type: inner
est: (rows=90684167)
HashJoin
- condition: =(C_CURRENT_HDEMO_SK, HD_DEMO_SK)
- joinType: inner
+ predicate: =(C_CURRENT_HDEMO_SK, HD_DEMO_SK)
+ type: inner
est: (rows=90684167)
Exchange
distribution: single
est: (rows=7200)
TableScan
table: PUBLIC.HOUSEHOLD_DEMOGRAPHICS
- fields: [HD_DEMO_SK, HD_INCOME_BAND_SK]
+ fieldNames: [HD_DEMO_SK, HD_INCOME_BAND_SK]
est: (rows=7200)
HashJoin
- condition: AND(<>(CD_MARITAL_STATUS, CD_MARITAL_STATUS0), =(SS_CDEMO_SK, CD_DEMO_SK))
- joinType: inner
+ predicate: AND(<>(CD_MARITAL_STATUS, CD_MARITAL_STATUS0), =(SS_CDEMO_SK, CD_DEMO_SK))
+ fieldNames: [CD_DEMO_SK, CD_MARITAL_STATUS, CD_DEMO_SK0, CD_MARITAL_STATUS0, C_CUSTOMER_SK, C_CURRENT_CDEMO_SK, C_CURRENT_HDEMO_SK, C_CURRENT_ADDR_SK, C_FIRST_SHIPTO_DATE_SK, C_FIRST_SALES_DATE_SK, SS_SOLD_DATE_SK, SS_ITEM_SK, SS_CUSTOMER_SK, SS_CDEMO_SK, SS_HDEMO_SK, SS_ADDR_SK, SS_STORE_SK, SS_PROMO_SK, SS_TICKET_NUMBER, SS_WHOLESALE_COST, SS_LIST_PRICE, SS_COUPON_AMT, I_ITEM_SK, I_CURRENT_PRICE, I_COLOR, I_PRODUCT_NAME, CS_ITEM_SK, SALE, REFUND, D_D [...]
+ type: inner
est: (rows=90684167)
Exchange
distribution: single
est: (rows=1920800)
TableScan
table: PUBLIC.CUSTOMER_DEMOGRAPHICS
- fields: [CD_DEMO_SK, CD_MARITAL_STATUS]
+ fieldNames: [CD_DEMO_SK, CD_MARITAL_STATUS]
est: (rows=1920800)
HashJoin
- condition: =(C_CURRENT_CDEMO_SK, CD_DEMO_SK)
- joinType: inner
+ predicate: =(C_CURRENT_CDEMO_SK, CD_DEMO_SK)
+ type: inner
est: (rows=129548810)
Exchange
distribution: single
est: (rows=1920800)
TableScan
table: PUBLIC.CUSTOMER_DEMOGRAPHICS
- fields: [CD_DEMO_SK, CD_MARITAL_STATUS]
+ fieldNames: [CD_DEMO_SK, CD_MARITAL_STATUS]
est: (rows=1920800)
HashJoin
- condition: =(SS_CUSTOMER_SK, C_CUSTOMER_SK)
- joinType: inner
+ predicate: =(SS_CUSTOMER_SK, C_CUSTOMER_SK)
+ type: inner
est: (rows=129548810)
Exchange
distribution: single
est: (rows=100000)
TableScan
table: PUBLIC.CUSTOMER
- fields: [C_CUSTOMER_SK, C_CURRENT_CDEMO_SK, C_CURRENT_HDEMO_SK, C_CURRENT_ADDR_SK, C_FIRST_SHIPTO_DATE_SK, C_FIRST_SALES_DATE_SK]
+ fieldNames: [C_CUSTOMER_SK, C_CURRENT_CDEMO_SK, C_CURRENT_HDEMO_SK, C_CURRENT_ADDR_SK, C_FIRST_SHIPTO_DATE_SK, C_FIRST_SALES_DATE_SK]
est: (rows=100000)
HashJoin
- condition: =(SS_SOLD_DATE_SK, D_DATE_SK)
- joinType: inner
+ predicate: =(SS_SOLD_DATE_SK, D_DATE_SK)
+ type: inner
est: (rows=129548810)
HashJoin
- condition: =(SS_ITEM_SK, CS_ITEM_SK)
- joinType: inner
+ predicate: =(SS_ITEM_SK, CS_ITEM_SK)
+ type: inner
est: (rows=389035465)
HashJoin
- condition: =(SS_ITEM_SK, I_ITEM_SK)
- joinType: inner
+ predicate: =(SS_ITEM_SK, I_ITEM_SK)
+ type: inner
est: (rows=180025)
Exchange
distribution: single
est: (rows=2880404)
TableScan
table: PUBLIC.STORE_SALES
- fields: [SS_SOLD_DATE_SK, SS_ITEM_SK, SS_CUSTOMER_SK, SS_CDEMO_SK, SS_HDEMO_SK, SS_ADDR_SK, SS_STORE_SK, SS_PROMO_SK, SS_TICKET_NUMBER, SS_WHOLESALE_COST, SS_LIST_PRICE, SS_COUPON_AMT]
+ fieldNames: [SS_SOLD_DATE_SK, SS_ITEM_SK, SS_CUSTOMER_SK, SS_CDEMO_SK, SS_HDEMO_SK, SS_ADDR_SK, SS_STORE_SK, SS_PROMO_SK, SS_TICKET_NUMBER, SS_WHOLESALE_COST, SS_LIST_PRICE, SS_COUPON_AMT]
est: (rows=2880404)
Exchange
distribution: single
est: (rows=1125)
TableScan
table: PUBLIC.ITEM
- filters: AND(SEARCH(I_COLOR, Sarg[_UTF-8'azure':VARCHAR(20) CHARACTER SET "UTF-8", _UTF-8'blush':VARCHAR(20) CHARACTER SET "UTF-8", _UTF-8'gainsboro':VARCHAR(20) CHARACTER SET "UTF-8", _UTF-8'hot':VARCHAR(20) CHARACTER SET "UTF-8", _UTF-8'lemon':VARCHAR(20) CHARACTER SET "UTF-8", _UTF-8'misty':VARCHAR(20) CHARACTER SET "UTF-8"]:VARCHAR(20) CHARACTER SET "UTF-8"), >=(CAST(I_CURRENT_PRICE):DECIMAL(12, 2), 80.00), <=(CAST(I_CURRENT_PRICE):DE [...]
- fields: [I_ITEM_SK, I_CURRENT_PRICE, I_COLOR, I_PRODUCT_NAME]
+ predicate: AND(SEARCH(I_COLOR, Sarg[_UTF-8'azure':VARCHAR(20) CHARACTER SET "UTF-8", _UTF-8'blush':VARCHAR(20) CHARACTER SET "UTF-8", _UTF-8'gainsboro':VARCHAR(20) CHARACTER SET "UTF-8", _UTF-8'hot':VARCHAR(20) CHARACTER SET "UTF-8", _UTF-8'lemon':VARCHAR(20) CHARACTER SET "UTF-8", _UTF-8'misty':VARCHAR(20) CHARACTER SET "UTF-8"]:VARCHAR(20) CHARACTER SET "UTF-8"), >=(CAST(I_CURRENT_PRICE):DECIMAL(12, 2), 80.00), <=(CAST(I_CURRENT_PRICE): [...]
+ fieldNames: [I_ITEM_SK, I_CURRENT_PRICE, I_COLOR, I_PRODUCT_NAME]
est: (rows=1125)
Filter
- condition: >(SALE, *(2, REFUND))
+ predicate: >(SALE, *(2, REFUND))
est: (rows=14407)
ReduceHashAggregate
- rowType: RecordType(INTEGER CS_ITEM_SK, DECIMAL(32767, 2) SALE, DECIMAL(32767, 2) REFUND)
+ fieldNames: [CS_ITEM_SK, SALE, REFUND]
group: [CS_ITEM_SK]
- aggs: [SALE=SUM(_ACC0), REFUND=SUM(_ACC1)]
+ aggregation: [SUM(_ACC0), SUM(_ACC1)]
est: (rows=28813)
Exchange
distribution: single
est: (rows=28813)
MapHashAggregate
+ fieldNames: [CS_ITEM_SK, _ACC0, _ACC1, _GROUP_ID]
group: [CS_ITEM_SK]
- aggs: [SALE=SUM(CS_EXT_LIST_PRICE), REFUND=SUM($f2)]
+ aggregation: [SUM(CS_EXT_LIST_PRICE), SUM($f2)]
est: (rows=28813)
Project
- fields: [CS_ITEM_SK, CS_EXT_LIST_PRICE, $f2]
- exprs: [CS_ITEM_SK, CS_EXT_LIST_PRICE, +(+(CR_REFUNDED_CASH, CR_REVERSED_CHARGE), CR_STORE_CREDIT)]
+ fieldNames: [CS_ITEM_SK, CS_EXT_LIST_PRICE, $f2]
+ projection: [CS_ITEM_SK, CS_EXT_LIST_PRICE, +(+(CR_REFUNDED_CASH, CR_REVERSED_CHARGE), CR_STORE_CREDIT)]
est: (rows=144067)
HashJoin
- condition: AND(=(CS_ITEM_SK, CR_ITEM_SK), =(CS_ORDER_NUMBER, CR_ORDER_NUMBER))
- joinType: inner
+ predicate: AND(=(CS_ITEM_SK, CR_ITEM_SK), =(CS_ORDER_NUMBER, CR_ORDER_NUMBER))
+ type: inner
est: (rows=144067)
TableScan
table: PUBLIC.CATALOG_SALES
- fields: [CS_ITEM_SK, CS_ORDER_NUMBER, CS_EXT_LIST_PRICE]
+ fieldNames: [CS_ITEM_SK, CS_ORDER_NUMBER, CS_EXT_LIST_PRICE]
est: (rows=1441548)
Exchange
distribution: affinity[tableId=51, zoneId=51][0, 1]
est: (rows=144067)
TableScan
table: PUBLIC.CATALOG_RETURNS
- fields: [CR_ITEM_SK, CR_ORDER_NUMBER, CR_REFUNDED_CASH, CR_REVERSED_CHARGE, CR_STORE_CREDIT]
+ fieldNames: [CR_ITEM_SK, CR_ORDER_NUMBER, CR_REFUNDED_CASH, CR_REVERSED_CHARGE, CR_STORE_CREDIT]
est: (rows=144067)
Exchange
distribution: single
est: (rows=24325)
TableScan
table: PUBLIC.DATE_DIM
- filters: =(D_YEAR, 1999)
- fields: [D_DATE_SK, D_YEAR]
+ predicate: =(D_YEAR, 1999)
+ fieldNames: [D_DATE_SK, D_YEAR]
est: (rows=24325)
Exchange
distribution: single
est: (rows=20)
TableScan
table: PUBLIC.INCOME_BAND
- fields: [IB_INCOME_BAND_SK]
+ fieldNames: [IB_INCOME_BAND_SK]
est: (rows=20)
Exchange
distribution: single
est: (rows=20)
TableScan
table: PUBLIC.INCOME_BAND
- fields: [IB_INCOME_BAND_SK]
+ fieldNames: [IB_INCOME_BAND_SK]
est: (rows=20)
Exchange
distribution: single
est: (rows=300)
TableScan
table: PUBLIC.PROMOTION
- fields: [P_PROMO_SK]
+ fieldNames: [P_PROMO_SK]
est: (rows=300)
Exchange
distribution: single
est: (rows=12)
TableScan
table: PUBLIC.STORE
- fields: [S_STORE_SK, S_STORE_NAME, S_ZIP]
+ fieldNames: [S_STORE_SK, S_STORE_NAME, S_ZIP]
est: (rows=12)
ColocatedHashAggregate
+ fieldNames: [PRODUCT_NAME, ITEM_SK, STORE_NAME, STORE_ZIP, B_STREET_NUMBER, B_STREET_NAME, B_CITY, B_ZIP, C_STREET_NUMBER, C_STREET_NAME, C_CITY, C_ZIP, SYEAR, FSYEAR, S2YEAR, CNT, S1, S2, S3]
group: [PRODUCT_NAME, ITEM_SK, STORE_NAME, STORE_ZIP, B_STREET_NUMBER, B_STREET_NAME, B_CITY, B_ZIP, C_STREET_NUMBER, C_STREET_NAME, C_CITY, C_ZIP, SYEAR, FSYEAR, S2YEAR]
- aggs: [CNT=COUNT(), S1=SUM(SS_WHOLESALE_COST), S2=SUM(SS_LIST_PRICE), S3=SUM(SS_COUPON_AMT)]
+ aggregation: [COUNT(), SUM(SS_WHOLESALE_COST), SUM(SS_LIST_PRICE), SUM(SS_COUPON_AMT)]
est: (rows=2887)
Project
- fields: [PRODUCT_NAME, ITEM_SK, STORE_NAME, STORE_ZIP, B_STREET_NUMBER, B_STREET_NAME, B_CITY, B_ZIP, C_STREET_NUMBER, C_STREET_NAME, C_CITY, C_ZIP, SYEAR, FSYEAR, S2YEAR, SS_WHOLESALE_COST, SS_LIST_PRICE, SS_COUPON_AMT]
- exprs: [I_PRODUCT_NAME, I_ITEM_SK, S_STORE_NAME, S_ZIP, CA_STREET_NUMBER, CA_STREET_NAME, CA_CITY, CA_ZIP, CA_STREET_NUMBER0, CA_STREET_NAME0, CA_CITY0, CA_ZIP0, D_YEAR00, D_YEAR, D_YEAR0, SS_WHOLESALE_COST, SS_LIST_PRICE, SS_COUPON_AMT]
+ fieldNames: [PRODUCT_NAME, ITEM_SK, STORE_NAME, STORE_ZIP, B_STREET_NUMBER, B_STREET_NAME, B_CITY, B_ZIP, C_STREET_NUMBER, C_STREET_NAME, C_CITY, C_ZIP, SYEAR, FSYEAR, S2YEAR, SS_WHOLESALE_COST, SS_LIST_PRICE, SS_COUPON_AMT]
+ projection: [I_PRODUCT_NAME, I_ITEM_SK, S_STORE_NAME, S_ZIP, CA_STREET_NUMBER, CA_STREET_NAME, CA_CITY, CA_ZIP, CA_STREET_NUMBER0, CA_STREET_NAME0, CA_CITY0, CA_ZIP0, D_YEAR00, D_YEAR, D_YEAR0, SS_WHOLESALE_COST, SS_LIST_PRICE, SS_COUPON_AMT]
est: (rows=2992)
HashJoin
- condition: AND(=(SS_ITEM_SK, SR_ITEM_SK), =(SS_TICKET_NUMBER, SR_TICKET_NUMBER))
- joinType: inner
+ predicate: AND(=(SS_ITEM_SK, SR_ITEM_SK), =(SS_TICKET_NUMBER, SR_TICKET_NUMBER))
+ type: inner
est: (rows=2992)
Exchange
distribution: single
est: (rows=287514)
TableScan
table: PUBLIC.STORE_RETURNS
- fields: [SR_ITEM_SK, SR_TICKET_NUMBER]
+ fieldNames: [SR_ITEM_SK, SR_TICKET_NUMBER]
est: (rows=287514)
HashJoin
- condition: =(C_FIRST_SALES_DATE_SK, D_DATE_SK)
- joinType: inner
+ predicate: =(C_FIRST_SALES_DATE_SK, D_DATE_SK)
+ fieldNames: [D_DATE_SK, D_YEAR, D_DATE_SK0, D_YEAR0, CA_ADDRESS_SK, CA_STREET_NUMBER, CA_STREET_NAME, CA_CITY, CA_ZIP, CA_ADDRESS_SK0, CA_STREET_NUMBER0, CA_STREET_NAME0, CA_CITY0, CA_ZIP0, HD_DEMO_SK, HD_INCOME_BAND_SK, HD_DEMO_SK0, HD_INCOME_BAND_SK0, CD_DEMO_SK, CD_MARITAL_STATUS, CD_DEMO_SK0, CD_MARITAL_STATUS0, C_CUSTOMER_SK, C_CURRENT_CDEMO_SK, C_CURRENT_HDEMO_SK, C_CURRENT_ADDR_SK, C_FIRST_SHIPTO_DATE_SK, C_FIRST_SALES_DATE_SK, SS_SOLD_DATE_SK, SS_ITEM_SK, SS_CUSTO [...]
+ type: inner
est: (rows=90684167)
Exchange
distribution: single
est: (rows=73049)
TableScan
table: PUBLIC.DATE_DIM
- fields: [D_DATE_SK, D_YEAR]
+ fieldNames: [D_DATE_SK, D_YEAR]
est: (rows=73049)
HashJoin
- condition: =(C_FIRST_SHIPTO_DATE_SK, D_DATE_SK)
- joinType: inner
+ predicate: =(C_FIRST_SHIPTO_DATE_SK, D_DATE_SK)
+ fieldNames: [D_DATE_SK, D_YEAR, CA_ADDRESS_SK, CA_STREET_NUMBER, CA_STREET_NAME, CA_CITY, CA_ZIP, CA_ADDRESS_SK0, CA_STREET_NUMBER0, CA_STREET_NAME0, CA_CITY0, CA_ZIP0, HD_DEMO_SK, HD_INCOME_BAND_SK, HD_DEMO_SK0, HD_INCOME_BAND_SK0, CD_DEMO_SK, CD_MARITAL_STATUS, CD_DEMO_SK0, CD_MARITAL_STATUS0, C_CUSTOMER_SK, C_CURRENT_CDEMO_SK, C_CURRENT_HDEMO_SK, C_CURRENT_ADDR_SK, C_FIRST_SHIPTO_DATE_SK, C_FIRST_SALES_DATE_SK, SS_SOLD_DATE_SK, SS_ITEM_SK, SS_CUSTOMER_SK, SS_CDEMO_SK [...]
+ type: inner
est: (rows=90684167)
Exchange
distribution: single
est: (rows=73049)
TableScan
table: PUBLIC.DATE_DIM
- fields: [D_DATE_SK, D_YEAR]
+ fieldNames: [D_DATE_SK, D_YEAR]
est: (rows=73049)
HashJoin
- condition: =(SS_STORE_SK, S_STORE_SK)
- joinType: inner
+ predicate: =(SS_STORE_SK, S_STORE_SK)
+ type: inner
est: (rows=90684167)
HashJoin
- condition: =(SS_PROMO_SK, P_PROMO_SK)
- joinType: inner
+ predicate: =(SS_PROMO_SK, P_PROMO_SK)
+ type: inner
est: (rows=90684167)
HashJoin
- condition: =(SS_ADDR_SK, CA_ADDRESS_SK)
- joinType: inner
+ predicate: =(SS_ADDR_SK, CA_ADDRESS_SK)
+ fieldNames: [CA_ADDRESS_SK, CA_STREET_NUMBER, CA_STREET_NAME, CA_CITY, CA_ZIP, CA_ADDRESS_SK0, CA_STREET_NUMBER0, CA_STREET_NAME0, CA_CITY0, CA_ZIP0, HD_DEMO_SK, HD_INCOME_BAND_SK, HD_DEMO_SK0, HD_INCOME_BAND_SK0, CD_DEMO_SK, CD_MARITAL_STATUS, CD_DEMO_SK0, CD_MARITAL_STATUS0, C_CUSTOMER_SK, C_CURRENT_CDEMO_SK, C_CURRENT_HDEMO_SK, C_CURRENT_ADDR_SK, C_FIRST_SHIPTO_DATE_SK, C_FIRST_SALES_DATE_SK, SS_SOLD_DATE_SK, SS_ITEM_SK, SS_CUSTOMER_SK, SS_CDEMO_SK, SS_HDEMO_SK [...]
+ type: inner
est: (rows=90684167)
Exchange
distribution: single
est: (rows=50000)
TableScan
table: PUBLIC.CUSTOMER_ADDRESS
- fields: [CA_ADDRESS_SK, CA_STREET_NUMBER, CA_STREET_NAME, CA_CITY, CA_ZIP]
+ fieldNames: [CA_ADDRESS_SK, CA_STREET_NUMBER, CA_STREET_NAME, CA_CITY, CA_ZIP]
est: (rows=50000)
HashJoin
- condition: =(C_CURRENT_ADDR_SK, CA_ADDRESS_SK)
- joinType: inner
+ predicate: =(C_CURRENT_ADDR_SK, CA_ADDRESS_SK)
+ type: inner
est: (rows=90684167)
Exchange
distribution: single
est: (rows=50000)
TableScan
table: PUBLIC.CUSTOMER_ADDRESS
- fields: [CA_ADDRESS_SK, CA_STREET_NUMBER, CA_STREET_NAME, CA_CITY, CA_ZIP]
+ fieldNames: [CA_ADDRESS_SK, CA_STREET_NUMBER, CA_STREET_NAME, CA_CITY, CA_ZIP]
est: (rows=50000)
HashJoin
- condition: =(HD_INCOME_BAND_SK, IB_INCOME_BAND_SK0)
- joinType: inner
+ predicate: =(HD_INCOME_BAND_SK, IB_INCOME_BAND_SK0)
+ fieldNames: [HD_DEMO_SK, HD_INCOME_BAND_SK, HD_DEMO_SK0, HD_INCOME_BAND_SK0, CD_DEMO_SK, CD_MARITAL_STATUS, CD_DEMO_SK0, CD_MARITAL_STATUS0, C_CUSTOMER_SK, C_CURRENT_CDEMO_SK, C_CURRENT_HDEMO_SK, C_CURRENT_ADDR_SK, C_FIRST_SHIPTO_DATE_SK, C_FIRST_SALES_DATE_SK, SS_SOLD_DATE_SK, SS_ITEM_SK, SS_CUSTOMER_SK, SS_CDEMO_SK, SS_HDEMO_SK, SS_ADDR_SK, SS_STORE_SK, SS_PROMO_SK, SS_TICKET_NUMBER, SS_WHOLESALE_COST, SS_LIST_PRICE, SS_COUPON_AMT, I_ITEM_SK, I_CURRENT_PRICE [...]
+ type: inner
est: (rows=90684167)
HashJoin
- condition: =(SS_HDEMO_SK, HD_DEMO_SK)
- joinType: inner
+ predicate: =(SS_HDEMO_SK, HD_DEMO_SK)
+ fieldNames: [HD_DEMO_SK, HD_INCOME_BAND_SK, HD_DEMO_SK0, HD_INCOME_BAND_SK0, CD_DEMO_SK, CD_MARITAL_STATUS, CD_DEMO_SK0, CD_MARITAL_STATUS0, C_CUSTOMER_SK, C_CURRENT_CDEMO_SK, C_CURRENT_HDEMO_SK, C_CURRENT_ADDR_SK, C_FIRST_SHIPTO_DATE_SK, C_FIRST_SALES_DATE_SK, SS_SOLD_DATE_SK, SS_ITEM_SK, SS_CUSTOMER_SK, SS_CDEMO_SK, SS_HDEMO_SK, SS_ADDR_SK, SS_STORE_SK, SS_PROMO_SK, SS_TICKET_NUMBER, SS_WHOLESALE_COST, SS_LIST_PRICE, SS_COUPON_AMT, I_ITEM_SK, I_CURRENT_PRI [...]
+ type: inner
est: (rows=90684167)
Exchange
distribution: single
est: (rows=7200)
TableScan
table: PUBLIC.HOUSEHOLD_DEMOGRAPHICS
- fields: [HD_DEMO_SK, HD_INCOME_BAND_SK]
+ fieldNames: [HD_DEMO_SK, HD_INCOME_BAND_SK]
est: (rows=7200)
HashJoin
- condition: =(HD_INCOME_BAND_SK, IB_INCOME_BAND_SK)
- joinType: inner
+ predicate: =(HD_INCOME_BAND_SK, IB_INCOME_BAND_SK)
+ type: inner
est: (rows=90684167)
HashJoin
- condition: =(C_CURRENT_HDEMO_SK, HD_DEMO_SK)
- joinType: inner
+ predicate: =(C_CURRENT_HDEMO_SK, HD_DEMO_SK)
+ type: inner
est: (rows=90684167)
Exchange
distribution: single
est: (rows=7200)
TableScan
table: PUBLIC.HOUSEHOLD_DEMOGRAPHICS
- fields: [HD_DEMO_SK, HD_INCOME_BAND_SK]
+ fieldNames: [HD_DEMO_SK, HD_INCOME_BAND_SK]
est: (rows=7200)
HashJoin
- condition: AND(<>(CD_MARITAL_STATUS, CD_MARITAL_STATUS0), =(SS_CDEMO_SK, CD_DEMO_SK))
- joinType: inner
+ predicate: AND(<>(CD_MARITAL_STATUS, CD_MARITAL_STATUS0), =(SS_CDEMO_SK, CD_DEMO_SK))
+ fieldNames: [CD_DEMO_SK, CD_MARITAL_STATUS, CD_DEMO_SK0, CD_MARITAL_STATUS0, C_CUSTOMER_SK, C_CURRENT_CDEMO_SK, C_CURRENT_HDEMO_SK, C_CURRENT_ADDR_SK, C_FIRST_SHIPTO_DATE_SK, C_FIRST_SALES_DATE_SK, SS_SOLD_DATE_SK, SS_ITEM_SK, SS_CUSTOMER_SK, SS_CDEMO_SK, SS_HDEMO_SK, SS_ADDR_SK, SS_STORE_SK, SS_PROMO_SK, SS_TICKET_NUMBER, SS_WHOLESALE_COST, SS_LIST_PRICE, SS_COUPON_AMT, I_ITEM_SK, I_CURRENT_PRICE, I_COLOR, I_PRODUCT_NAME, CS_ITEM_SK, SALE, REFUND, D_D [...]
+ type: inner
est: (rows=90684167)
Exchange
distribution: single
est: (rows=1920800)
TableScan
table: PUBLIC.CUSTOMER_DEMOGRAPHICS
- fields: [CD_DEMO_SK, CD_MARITAL_STATUS]
+ fieldNames: [CD_DEMO_SK, CD_MARITAL_STATUS]
est: (rows=1920800)
HashJoin
- condition: =(C_CURRENT_CDEMO_SK, CD_DEMO_SK)
- joinType: inner
+ predicate: =(C_CURRENT_CDEMO_SK, CD_DEMO_SK)
+ type: inner
est: (rows=129548810)
Exchange
distribution: single
est: (rows=1920800)
TableScan
table: PUBLIC.CUSTOMER_DEMOGRAPHICS
- fields: [CD_DEMO_SK, CD_MARITAL_STATUS]
+ fieldNames: [CD_DEMO_SK, CD_MARITAL_STATUS]
est: (rows=1920800)
HashJoin
- condition: =(SS_CUSTOMER_SK, C_CUSTOMER_SK)
- joinType: inner
+ predicate: =(SS_CUSTOMER_SK, C_CUSTOMER_SK)
+ type: inner
est: (rows=129548810)
Exchange
distribution: single
est: (rows=100000)
TableScan
table: PUBLIC.CUSTOMER
- fields: [C_CUSTOMER_SK, C_CURRENT_CDEMO_SK, C_CURRENT_HDEMO_SK, C_CURRENT_ADDR_SK, C_FIRST_SHIPTO_DATE_SK, C_FIRST_SALES_DATE_SK]
+ fieldNames: [C_CUSTOMER_SK, C_CURRENT_CDEMO_SK, C_CURRENT_HDEMO_SK, C_CURRENT_ADDR_SK, C_FIRST_SHIPTO_DATE_SK, C_FIRST_SALES_DATE_SK]
est: (rows=100000)
HashJoin
- condition: =(SS_SOLD_DATE_SK, D_DATE_SK)
- joinType: inner
+ predicate: =(SS_SOLD_DATE_SK, D_DATE_SK)
+ type: inner
est: (rows=129548810)
HashJoin
- condition: =(SS_ITEM_SK, CS_ITEM_SK)
- joinType: inner
+ predicate: =(SS_ITEM_SK, CS_ITEM_SK)
+ type: inner
est: (rows=389035465)
HashJoin
- condition: =(SS_ITEM_SK, I_ITEM_SK)
- joinType: inner
+ predicate: =(SS_ITEM_SK, I_ITEM_SK)
+ type: inner
est: (rows=180025)
Exchange
distribution: single
est: (rows=2880404)
TableScan
table: PUBLIC.STORE_SALES
- fields: [SS_SOLD_DATE_SK, SS_ITEM_SK, SS_CUSTOMER_SK, SS_CDEMO_SK, SS_HDEMO_SK, SS_ADDR_SK, SS_STORE_SK, SS_PROMO_SK, SS_TICKET_NUMBER, SS_WHOLESALE_COST, SS_LIST_PRICE, SS_COUPON_AMT]
+ fieldNames: [SS_SOLD_DATE_SK, SS_ITEM_SK, SS_CUSTOMER_SK, SS_CDEMO_SK, SS_HDEMO_SK, SS_ADDR_SK, SS_STORE_SK, SS_PROMO_SK, SS_TICKET_NUMBER, SS_WHOLESALE_COST, SS_LIST_PRICE, SS_COUPON_AMT]
est: (rows=2880404)
Exchange
distribution: single
est: (rows=1125)
TableScan
table: PUBLIC.ITEM
- filters: AND(SEARCH(I_COLOR, Sarg[_UTF-8'azure':VARCHAR(20) CHARACTER SET "UTF-8", _UTF-8'blush':VARCHAR(20) CHARACTER SET "UTF-8", _UTF-8'gainsboro':VARCHAR(20) CHARACTER SET "UTF-8", _UTF-8'hot':VARCHAR(20) CHARACTER SET "UTF-8", _UTF-8'lemon':VARCHAR(20) CHARACTER SET "UTF-8", _UTF-8'misty':VARCHAR(20) CHARACTER SET "UTF-8"]:VARCHAR(20) CHARACTER SET "UTF-8"), >=(CAST(I_CURRENT_PRICE):DECIMAL(12, 2), 80.00), <=(CAST(I_CURRENT_PRICE):DE [...]
- fields: [I_ITEM_SK, I_CURRENT_PRICE, I_COLOR, I_PRODUCT_NAME]
+ predicate: AND(SEARCH(I_COLOR, Sarg[_UTF-8'azure':VARCHAR(20) CHARACTER SET "UTF-8", _UTF-8'blush':VARCHAR(20) CHARACTER SET "UTF-8", _UTF-8'gainsboro':VARCHAR(20) CHARACTER SET "UTF-8", _UTF-8'hot':VARCHAR(20) CHARACTER SET "UTF-8", _UTF-8'lemon':VARCHAR(20) CHARACTER SET "UTF-8", _UTF-8'misty':VARCHAR(20) CHARACTER SET "UTF-8"]:VARCHAR(20) CHARACTER SET "UTF-8"), >=(CAST(I_CURRENT_PRICE):DECIMAL(12, 2), 80.00), <=(CAST(I_CURRENT_PRICE): [...]
+ fieldNames: [I_ITEM_SK, I_CURRENT_PRICE, I_COLOR, I_PRODUCT_NAME]
est: (rows=1125)
Filter
- condition: >(SALE, *(2, REFUND))
+ predicate: >(SALE, *(2, REFUND))
est: (rows=14407)
ReduceHashAggregate
- rowType: RecordType(INTEGER CS_ITEM_SK, DECIMAL(32767, 2) SALE, DECIMAL(32767, 2) REFUND)
+ fieldNames: [CS_ITEM_SK, SALE, REFUND]
group: [CS_ITEM_SK]
- aggs: [SALE=SUM(_ACC0), REFUND=SUM(_ACC1)]
+ aggregation: [SUM(_ACC0), SUM(_ACC1)]
est: (rows=28813)
Exchange
distribution: single
est: (rows=28813)
MapHashAggregate
+ fieldNames: [CS_ITEM_SK, _ACC0, _ACC1, _GROUP_ID]
group: [CS_ITEM_SK]
- aggs: [SALE=SUM(CS_EXT_LIST_PRICE), REFUND=SUM($f2)]
+ aggregation: [SUM(CS_EXT_LIST_PRICE), SUM($f2)]
est: (rows=28813)
Project
- fields: [CS_ITEM_SK, CS_EXT_LIST_PRICE, $f2]
- exprs: [CS_ITEM_SK, CS_EXT_LIST_PRICE, +(+(CR_REFUNDED_CASH, CR_REVERSED_CHARGE), CR_STORE_CREDIT)]
+ fieldNames: [CS_ITEM_SK, CS_EXT_LIST_PRICE, $f2]
+ projection: [CS_ITEM_SK, CS_EXT_LIST_PRICE, +(+(CR_REFUNDED_CASH, CR_REVERSED_CHARGE), CR_STORE_CREDIT)]
est: (rows=144067)
HashJoin
- condition: AND(=(CS_ITEM_SK, CR_ITEM_SK), =(CS_ORDER_NUMBER, CR_ORDER_NUMBER))
- joinType: inner
+ predicate: AND(=(CS_ITEM_SK, CR_ITEM_SK), =(CS_ORDER_NUMBER, CR_ORDER_NUMBER))
+ type: inner
est: (rows=144067)
TableScan
table: PUBLIC.CATALOG_SALES
- fields: [CS_ITEM_SK, CS_ORDER_NUMBER, CS_EXT_LIST_PRICE]
+ fieldNames: [CS_ITEM_SK, CS_ORDER_NUMBER, CS_EXT_LIST_PRICE]
est: (rows=1441548)
Exchange
distribution: affinity[tableId=51, zoneId=51][0, 1]
est: (rows=144067)
TableScan
table: PUBLIC.CATALOG_RETURNS
- fields: [CR_ITEM_SK, CR_ORDER_NUMBER, CR_REFUNDED_CASH, CR_REVERSED_CHARGE, CR_STORE_CREDIT]
+ fieldNames: [CR_ITEM_SK, CR_ORDER_NUMBER, CR_REFUNDED_CASH, CR_REVERSED_CHARGE, CR_STORE_CREDIT]
est: (rows=144067)
Exchange
distribution: single
est: (rows=24325)
TableScan
table: PUBLIC.DATE_DIM
- filters: =(D_YEAR, +(1999, 1))
- fields: [D_DATE_SK, D_YEAR]
+ predicate: =(D_YEAR, +(1999, 1))
+ fieldNames: [D_DATE_SK, D_YEAR]
est: (rows=24325)
Exchange
distribution: single
est: (rows=20)
TableScan
table: PUBLIC.INCOME_BAND
- fields: [IB_INCOME_BAND_SK]
+ fieldNames: [IB_INCOME_BAND_SK]
est: (rows=20)
Exchange
distribution: single
est: (rows=20)
TableScan
table: PUBLIC.INCOME_BAND
- fields: [IB_INCOME_BAND_SK]
+ fieldNames: [IB_INCOME_BAND_SK]
est: (rows=20)
Exchange
distribution: single
est: (rows=300)
TableScan
table: PUBLIC.PROMOTION
- fields: [P_PROMO_SK]
+ fieldNames: [P_PROMO_SK]
est: (rows=300)
Exchange
distribution: single
est: (rows=12)
TableScan
table: PUBLIC.STORE
- fields: [S_STORE_SK, S_STORE_NAME, S_ZIP]
+ fieldNames: [S_STORE_SK, S_STORE_NAME, S_ZIP]
est: (rows=12)
diff --git a/modules/sql-engine/src/test/resources/tpcds/plan/q64_colocated.plan b/modules/sql-engine/src/test/resources/tpcds/plan/q64_colocated.plan
index 063f1df99b5..d2dcc91fa18 100644
--- a/modules/sql-engine/src/test/resources/tpcds/plan/q64_colocated.plan
+++ b/modules/sql-engine/src/test/resources/tpcds/plan/q64_colocated.plan
@@ -2,466 +2,483 @@ Sort
collation: [PRODUCT_NAME ASC, STORE_NAME ASC, CNT0 ASC, S11 ASC, S12 ASC]
est: (rows=21)
Project
- fields: [PRODUCT_NAME, STORE_NAME, STORE_ZIP, B_STREET_NUMBER, B_STREET_NAME, B_CITY, B_ZIP, C_STREET_NUMBER, C_STREET_NAME, C_CITY, C_ZIP, SYEAR, CNT, S11, S21, S31, S12, S22, S32, SYEAR0, CNT0]
- exprs: [PRODUCT_NAME, STORE_NAME, STORE_ZIP, B_STREET_NUMBER, B_STREET_NAME, B_CITY, B_ZIP, C_STREET_NUMBER, C_STREET_NAME, C_CITY, C_ZIP, SYEAR, CNT, S1, S2, S3, S10, S20, S30, SYEAR0, CNT0]
+ fieldNames: [PRODUCT_NAME, STORE_NAME, STORE_ZIP, B_STREET_NUMBER, B_STREET_NAME, B_CITY, B_ZIP, C_STREET_NUMBER, C_STREET_NAME, C_CITY, C_ZIP, SYEAR, CNT, S11, S21, S31, S12, S22, S32, SYEAR0, CNT0]
+ projection: [PRODUCT_NAME, STORE_NAME, STORE_ZIP, B_STREET_NUMBER, B_STREET_NAME, B_CITY, B_ZIP, C_STREET_NUMBER, C_STREET_NAME, C_CITY, C_ZIP, SYEAR, CNT, S1, S2, S3, S10, S20, S30, SYEAR0, CNT0]
est: (rows=21)
HashJoin
- condition: AND(=(ITEM_SK, ITEM_SK0), <=(CNT0, CNT), =(STORE_NAME, STORE_NAME0), =(STORE_ZIP, STORE_ZIP0))
- joinType: inner
+ predicate: AND(=(ITEM_SK, ITEM_SK0), <=(CNT0, CNT), =(STORE_NAME, STORE_NAME0), =(STORE_ZIP, STORE_ZIP0))
+ fieldNames: [PRODUCT_NAME, ITEM_SK, STORE_NAME, STORE_ZIP, B_STREET_NUMBER, B_STREET_NAME, B_CITY, B_ZIP, C_STREET_NUMBER, C_STREET_NAME, C_CITY, C_ZIP, SYEAR, FSYEAR, S2YEAR, CNT, S1, S2, S3, PRODUCT_NAME0, ITEM_SK0, STORE_NAME0, STORE_ZIP0, B_STREET_NUMBER0, B_STREET_NAME0, B_CITY0, B_ZIP0, C_STREET_NUMBER0, C_STREET_NAME0, C_CITY0, C_ZIP0, SYEAR0, FSYEAR0, S2YEAR0, CNT0, S10, S20, S30]
+ type: inner
est: (rows=21)
ColocatedHashAggregate
+ fieldNames: [PRODUCT_NAME, ITEM_SK, STORE_NAME, STORE_ZIP, B_STREET_NUMBER, B_STREET_NAME, B_CITY, B_ZIP, C_STREET_NUMBER, C_STREET_NAME, C_CITY, C_ZIP, SYEAR, FSYEAR, S2YEAR, CNT, S1, S2, S3]
group: [PRODUCT_NAME, ITEM_SK, STORE_NAME, STORE_ZIP, B_STREET_NUMBER, B_STREET_NAME, B_CITY, B_ZIP, C_STREET_NUMBER, C_STREET_NAME, C_CITY, C_ZIP, SYEAR, FSYEAR, S2YEAR]
- aggs: [CNT=COUNT(), S1=SUM(SS_WHOLESALE_COST), S2=SUM(SS_LIST_PRICE), S3=SUM(SS_COUPON_AMT)]
+ aggregation: [COUNT(), SUM(SS_WHOLESALE_COST), SUM(SS_LIST_PRICE), SUM(SS_COUPON_AMT)]
est: (rows=2887)
Project
- fields: [PRODUCT_NAME, ITEM_SK, STORE_NAME, STORE_ZIP, B_STREET_NUMBER, B_STREET_NAME, B_CITY, B_ZIP, C_STREET_NUMBER, C_STREET_NAME, C_CITY, C_ZIP, SYEAR, FSYEAR, S2YEAR, SS_WHOLESALE_COST, SS_LIST_PRICE, SS_COUPON_AMT]
- exprs: [I_PRODUCT_NAME, I_ITEM_SK, S_STORE_NAME, S_ZIP, CA_STREET_NUMBER, CA_STREET_NAME, CA_CITY, CA_ZIP, CA_STREET_NUMBER0, CA_STREET_NAME0, CA_CITY0, CA_ZIP0, D_YEAR00, D_YEAR, D_YEAR0, SS_WHOLESALE_COST, SS_LIST_PRICE, SS_COUPON_AMT]
+ fieldNames: [PRODUCT_NAME, ITEM_SK, STORE_NAME, STORE_ZIP, B_STREET_NUMBER, B_STREET_NAME, B_CITY, B_ZIP, C_STREET_NUMBER, C_STREET_NAME, C_CITY, C_ZIP, SYEAR, FSYEAR, S2YEAR, SS_WHOLESALE_COST, SS_LIST_PRICE, SS_COUPON_AMT]
+ projection: [I_PRODUCT_NAME, I_ITEM_SK, S_STORE_NAME, S_ZIP, CA_STREET_NUMBER, CA_STREET_NAME, CA_CITY, CA_ZIP, CA_STREET_NUMBER0, CA_STREET_NAME0, CA_CITY0, CA_ZIP0, D_YEAR00, D_YEAR, D_YEAR0, SS_WHOLESALE_COST, SS_LIST_PRICE, SS_COUPON_AMT]
est: (rows=2992)
HashJoin
- condition: AND(=(SS_ITEM_SK, SR_ITEM_SK), =(SS_TICKET_NUMBER, SR_TICKET_NUMBER))
- joinType: inner
+ predicate: AND(=(SS_ITEM_SK, SR_ITEM_SK), =(SS_TICKET_NUMBER, SR_TICKET_NUMBER))
+ type: inner
est: (rows=2992)
Exchange
distribution: single
est: (rows=287514)
TableScan
table: PUBLIC.STORE_RETURNS
- fields: [SR_ITEM_SK, SR_TICKET_NUMBER]
+ fieldNames: [SR_ITEM_SK, SR_TICKET_NUMBER]
est: (rows=287514)
HashJoin
- condition: =(C_FIRST_SALES_DATE_SK, D_DATE_SK)
- joinType: inner
+ predicate: =(C_FIRST_SALES_DATE_SK, D_DATE_SK)
+ fieldNames: [D_DATE_SK, D_YEAR, D_DATE_SK0, D_YEAR0, CA_ADDRESS_SK, CA_STREET_NUMBER, CA_STREET_NAME, CA_CITY, CA_ZIP, CA_ADDRESS_SK0, CA_STREET_NUMBER0, CA_STREET_NAME0, CA_CITY0, CA_ZIP0, HD_DEMO_SK, HD_INCOME_BAND_SK, HD_DEMO_SK0, HD_INCOME_BAND_SK0, CD_DEMO_SK, CD_MARITAL_STATUS, CD_DEMO_SK0, CD_MARITAL_STATUS0, C_CUSTOMER_SK, C_CURRENT_CDEMO_SK, C_CURRENT_HDEMO_SK, C_CURRENT_ADDR_SK, C_FIRST_SHIPTO_DATE_SK, C_FIRST_SALES_DATE_SK, SS_SOLD_DATE_SK, SS_ITEM_SK, SS_CUSTO [...]
+ type: inner
est: (rows=90684167)
Exchange
distribution: single
est: (rows=73049)
TableScan
table: PUBLIC.DATE_DIM
- fields: [D_DATE_SK, D_YEAR]
+ fieldNames: [D_DATE_SK, D_YEAR]
est: (rows=73049)
HashJoin
- condition: =(C_FIRST_SHIPTO_DATE_SK, D_DATE_SK)
- joinType: inner
+ predicate: =(C_FIRST_SHIPTO_DATE_SK, D_DATE_SK)
+ fieldNames: [D_DATE_SK, D_YEAR, CA_ADDRESS_SK, CA_STREET_NUMBER, CA_STREET_NAME, CA_CITY, CA_ZIP, CA_ADDRESS_SK0, CA_STREET_NUMBER0, CA_STREET_NAME0, CA_CITY0, CA_ZIP0, HD_DEMO_SK, HD_INCOME_BAND_SK, HD_DEMO_SK0, HD_INCOME_BAND_SK0, CD_DEMO_SK, CD_MARITAL_STATUS, CD_DEMO_SK0, CD_MARITAL_STATUS0, C_CUSTOMER_SK, C_CURRENT_CDEMO_SK, C_CURRENT_HDEMO_SK, C_CURRENT_ADDR_SK, C_FIRST_SHIPTO_DATE_SK, C_FIRST_SALES_DATE_SK, SS_SOLD_DATE_SK, SS_ITEM_SK, SS_CUSTOMER_SK, SS_CDEMO_SK [...]
+ type: inner
est: (rows=90684167)
Exchange
distribution: single
est: (rows=73049)
TableScan
table: PUBLIC.DATE_DIM
- fields: [D_DATE_SK, D_YEAR]
+ fieldNames: [D_DATE_SK, D_YEAR]
est: (rows=73049)
HashJoin
- condition: =(SS_STORE_SK, S_STORE_SK)
- joinType: inner
+ predicate: =(SS_STORE_SK, S_STORE_SK)
+ type: inner
est: (rows=90684167)
HashJoin
- condition: =(SS_PROMO_SK, P_PROMO_SK)
- joinType: inner
+ predicate: =(SS_PROMO_SK, P_PROMO_SK)
+ type: inner
est: (rows=90684167)
HashJoin
- condition: =(SS_ADDR_SK, CA_ADDRESS_SK)
- joinType: inner
+ predicate: =(SS_ADDR_SK, CA_ADDRESS_SK)
+ fieldNames: [CA_ADDRESS_SK, CA_STREET_NUMBER, CA_STREET_NAME, CA_CITY, CA_ZIP, CA_ADDRESS_SK0, CA_STREET_NUMBER0, CA_STREET_NAME0, CA_CITY0, CA_ZIP0, HD_DEMO_SK, HD_INCOME_BAND_SK, HD_DEMO_SK0, HD_INCOME_BAND_SK0, CD_DEMO_SK, CD_MARITAL_STATUS, CD_DEMO_SK0, CD_MARITAL_STATUS0, C_CUSTOMER_SK, C_CURRENT_CDEMO_SK, C_CURRENT_HDEMO_SK, C_CURRENT_ADDR_SK, C_FIRST_SHIPTO_DATE_SK, C_FIRST_SALES_DATE_SK, SS_SOLD_DATE_SK, SS_ITEM_SK, SS_CUSTOMER_SK, SS_CDEMO_SK, SS_HDEMO_SK [...]
+ type: inner
est: (rows=90684167)
Exchange
distribution: single
est: (rows=50000)
TableScan
table: PUBLIC.CUSTOMER_ADDRESS
- fields: [CA_ADDRESS_SK, CA_STREET_NUMBER, CA_STREET_NAME, CA_CITY, CA_ZIP]
+ fieldNames: [CA_ADDRESS_SK, CA_STREET_NUMBER, CA_STREET_NAME, CA_CITY, CA_ZIP]
est: (rows=50000)
HashJoin
- condition: =(C_CURRENT_ADDR_SK, CA_ADDRESS_SK)
- joinType: inner
+ predicate: =(C_CURRENT_ADDR_SK, CA_ADDRESS_SK)
+ type: inner
est: (rows=90684167)
Exchange
distribution: single
est: (rows=50000)
TableScan
table: PUBLIC.CUSTOMER_ADDRESS
- fields: [CA_ADDRESS_SK, CA_STREET_NUMBER, CA_STREET_NAME, CA_CITY, CA_ZIP]
+ fieldNames: [CA_ADDRESS_SK, CA_STREET_NUMBER, CA_STREET_NAME, CA_CITY, CA_ZIP]
est: (rows=50000)
HashJoin
- condition: =(HD_INCOME_BAND_SK, IB_INCOME_BAND_SK0)
- joinType: inner
+ predicate: =(HD_INCOME_BAND_SK, IB_INCOME_BAND_SK0)
+ fieldNames: [HD_DEMO_SK, HD_INCOME_BAND_SK, HD_DEMO_SK0, HD_INCOME_BAND_SK0, CD_DEMO_SK, CD_MARITAL_STATUS, CD_DEMO_SK0, CD_MARITAL_STATUS0, C_CUSTOMER_SK, C_CURRENT_CDEMO_SK, C_CURRENT_HDEMO_SK, C_CURRENT_ADDR_SK, C_FIRST_SHIPTO_DATE_SK, C_FIRST_SALES_DATE_SK, SS_SOLD_DATE_SK, SS_ITEM_SK, SS_CUSTOMER_SK, SS_CDEMO_SK, SS_HDEMO_SK, SS_ADDR_SK, SS_STORE_SK, SS_PROMO_SK, SS_TICKET_NUMBER, SS_WHOLESALE_COST, SS_LIST_PRICE, SS_COUPON_AMT, I_ITEM_SK, I_CURRENT_PRICE [...]
+ type: inner
est: (rows=90684167)
HashJoin
- condition: =(SS_HDEMO_SK, HD_DEMO_SK)
- joinType: inner
+ predicate: =(SS_HDEMO_SK, HD_DEMO_SK)
+ fieldNames: [HD_DEMO_SK, HD_INCOME_BAND_SK, HD_DEMO_SK0, HD_INCOME_BAND_SK0, CD_DEMO_SK, CD_MARITAL_STATUS, CD_DEMO_SK0, CD_MARITAL_STATUS0, C_CUSTOMER_SK, C_CURRENT_CDEMO_SK, C_CURRENT_HDEMO_SK, C_CURRENT_ADDR_SK, C_FIRST_SHIPTO_DATE_SK, C_FIRST_SALES_DATE_SK, SS_SOLD_DATE_SK, SS_ITEM_SK, SS_CUSTOMER_SK, SS_CDEMO_SK, SS_HDEMO_SK, SS_ADDR_SK, SS_STORE_SK, SS_PROMO_SK, SS_TICKET_NUMBER, SS_WHOLESALE_COST, SS_LIST_PRICE, SS_COUPON_AMT, I_ITEM_SK, I_CURRENT_PRI [...]
+ type: inner
est: (rows=90684167)
Exchange
distribution: single
est: (rows=7200)
TableScan
table: PUBLIC.HOUSEHOLD_DEMOGRAPHICS
- fields: [HD_DEMO_SK, HD_INCOME_BAND_SK]
+ fieldNames: [HD_DEMO_SK, HD_INCOME_BAND_SK]
est: (rows=7200)
HashJoin
- condition: =(HD_INCOME_BAND_SK, IB_INCOME_BAND_SK)
- joinType: inner
+ predicate: =(HD_INCOME_BAND_SK, IB_INCOME_BAND_SK)
+ type: inner
est: (rows=90684167)
HashJoin
- condition: =(C_CURRENT_HDEMO_SK, HD_DEMO_SK)
- joinType: inner
+ predicate: =(C_CURRENT_HDEMO_SK, HD_DEMO_SK)
+ type: inner
est: (rows=90684167)
Exchange
distribution: single
est: (rows=7200)
TableScan
table: PUBLIC.HOUSEHOLD_DEMOGRAPHICS
- fields: [HD_DEMO_SK, HD_INCOME_BAND_SK]
+ fieldNames: [HD_DEMO_SK, HD_INCOME_BAND_SK]
est: (rows=7200)
HashJoin
- condition: AND(<>(CD_MARITAL_STATUS, CD_MARITAL_STATUS0), =(SS_CDEMO_SK, CD_DEMO_SK))
- joinType: inner
+ predicate: AND(<>(CD_MARITAL_STATUS, CD_MARITAL_STATUS0), =(SS_CDEMO_SK, CD_DEMO_SK))
+ fieldNames: [CD_DEMO_SK, CD_MARITAL_STATUS, CD_DEMO_SK0, CD_MARITAL_STATUS0, C_CUSTOMER_SK, C_CURRENT_CDEMO_SK, C_CURRENT_HDEMO_SK, C_CURRENT_ADDR_SK, C_FIRST_SHIPTO_DATE_SK, C_FIRST_SALES_DATE_SK, SS_SOLD_DATE_SK, SS_ITEM_SK, SS_CUSTOMER_SK, SS_CDEMO_SK, SS_HDEMO_SK, SS_ADDR_SK, SS_STORE_SK, SS_PROMO_SK, SS_TICKET_NUMBER, SS_WHOLESALE_COST, SS_LIST_PRICE, SS_COUPON_AMT, I_ITEM_SK, I_CURRENT_PRICE, I_COLOR, I_PRODUCT_NAME, CS_ITEM_SK, SALE, REFUND, D_D [...]
+ type: inner
est: (rows=90684167)
Exchange
distribution: single
est: (rows=1920800)
TableScan
table: PUBLIC.CUSTOMER_DEMOGRAPHICS
- fields: [CD_DEMO_SK, CD_MARITAL_STATUS]
+ fieldNames: [CD_DEMO_SK, CD_MARITAL_STATUS]
est: (rows=1920800)
HashJoin
- condition: =(C_CURRENT_CDEMO_SK, CD_DEMO_SK)
- joinType: inner
+ predicate: =(C_CURRENT_CDEMO_SK, CD_DEMO_SK)
+ type: inner
est: (rows=129548810)
Exchange
distribution: single
est: (rows=1920800)
TableScan
table: PUBLIC.CUSTOMER_DEMOGRAPHICS
- fields: [CD_DEMO_SK, CD_MARITAL_STATUS]
+ fieldNames: [CD_DEMO_SK, CD_MARITAL_STATUS]
est: (rows=1920800)
HashJoin
- condition: =(SS_CUSTOMER_SK, C_CUSTOMER_SK)
- joinType: inner
+ predicate: =(SS_CUSTOMER_SK, C_CUSTOMER_SK)
+ type: inner
est: (rows=129548810)
Exchange
distribution: single
est: (rows=100000)
TableScan
table: PUBLIC.CUSTOMER
- fields: [C_CUSTOMER_SK, C_CURRENT_CDEMO_SK, C_CURRENT_HDEMO_SK, C_CURRENT_ADDR_SK, C_FIRST_SHIPTO_DATE_SK, C_FIRST_SALES_DATE_SK]
+ fieldNames: [C_CUSTOMER_SK, C_CURRENT_CDEMO_SK, C_CURRENT_HDEMO_SK, C_CURRENT_ADDR_SK, C_FIRST_SHIPTO_DATE_SK, C_FIRST_SALES_DATE_SK]
est: (rows=100000)
HashJoin
- condition: =(SS_SOLD_DATE_SK, D_DATE_SK)
- joinType: inner
+ predicate: =(SS_SOLD_DATE_SK, D_DATE_SK)
+ type: inner
est: (rows=129548810)
HashJoin
- condition: =(SS_ITEM_SK, CS_ITEM_SK)
- joinType: inner
+ predicate: =(SS_ITEM_SK, CS_ITEM_SK)
+ type: inner
est: (rows=389035465)
HashJoin
- condition: =(SS_ITEM_SK, I_ITEM_SK)
- joinType: inner
+ predicate: =(SS_ITEM_SK, I_ITEM_SK)
+ type: inner
est: (rows=180025)
Exchange
distribution: single
est: (rows=2880404)
TableScan
table: PUBLIC.STORE_SALES
- fields: [SS_SOLD_DATE_SK, SS_ITEM_SK, SS_CUSTOMER_SK, SS_CDEMO_SK, SS_HDEMO_SK, SS_ADDR_SK, SS_STORE_SK, SS_PROMO_SK, SS_TICKET_NUMBER, SS_WHOLESALE_COST, SS_LIST_PRICE, SS_COUPON_AMT]
+ fieldNames: [SS_SOLD_DATE_SK, SS_ITEM_SK, SS_CUSTOMER_SK, SS_CDEMO_SK, SS_HDEMO_SK, SS_ADDR_SK, SS_STORE_SK, SS_PROMO_SK, SS_TICKET_NUMBER, SS_WHOLESALE_COST, SS_LIST_PRICE, SS_COUPON_AMT]
est: (rows=2880404)
Exchange
distribution: single
est: (rows=1125)
TableScan
table: PUBLIC.ITEM
- filters: AND(SEARCH(I_COLOR, Sarg[_UTF-8'azure':VARCHAR(20) CHARACTER SET "UTF-8", _UTF-8'blush':VARCHAR(20) CHARACTER SET "UTF-8", _UTF-8'gainsboro':VARCHAR(20) CHARACTER SET "UTF-8", _UTF-8'hot':VARCHAR(20) CHARACTER SET "UTF-8", _UTF-8'lemon':VARCHAR(20) CHARACTER SET "UTF-8", _UTF-8'misty':VARCHAR(20) CHARACTER SET "UTF-8"]:VARCHAR(20) CHARACTER SET "UTF-8"), >=(CAST(I_CURRENT_PRICE):DECIMAL(12, 2), 80.00), <=(CAST(I_CURRENT_PRICE):DE [...]
- fields: [I_ITEM_SK, I_CURRENT_PRICE, I_COLOR, I_PRODUCT_NAME]
+ predicate: AND(SEARCH(I_COLOR, Sarg[_UTF-8'azure':VARCHAR(20) CHARACTER SET "UTF-8", _UTF-8'blush':VARCHAR(20) CHARACTER SET "UTF-8", _UTF-8'gainsboro':VARCHAR(20) CHARACTER SET "UTF-8", _UTF-8'hot':VARCHAR(20) CHARACTER SET "UTF-8", _UTF-8'lemon':VARCHAR(20) CHARACTER SET "UTF-8", _UTF-8'misty':VARCHAR(20) CHARACTER SET "UTF-8"]:VARCHAR(20) CHARACTER SET "UTF-8"), >=(CAST(I_CURRENT_PRICE):DECIMAL(12, 2), 80.00), <=(CAST(I_CURRENT_PRICE): [...]
+ fieldNames: [I_ITEM_SK, I_CURRENT_PRICE, I_COLOR, I_PRODUCT_NAME]
est: (rows=1125)
Filter
- condition: >(SALE, *(2, REFUND))
+ predicate: >(SALE, *(2, REFUND))
est: (rows=14407)
ReduceHashAggregate
- rowType: RecordType(INTEGER CS_ITEM_SK, DECIMAL(32767, 2) SALE, DECIMAL(32767, 2) REFUND)
+ fieldNames: [CS_ITEM_SK, SALE, REFUND]
group: [CS_ITEM_SK]
- aggs: [SALE=SUM(_ACC0), REFUND=SUM(_ACC1)]
+ aggregation: [SUM(_ACC0), SUM(_ACC1)]
est: (rows=28813)
Exchange
distribution: single
est: (rows=28813)
MapHashAggregate
+ fieldNames: [CS_ITEM_SK, _ACC0, _ACC1, _GROUP_ID]
group: [CS_ITEM_SK]
- aggs: [SALE=SUM(CS_EXT_LIST_PRICE), REFUND=SUM($f2)]
+ aggregation: [SUM(CS_EXT_LIST_PRICE), SUM($f2)]
est: (rows=28813)
Project
- fields: [CS_ITEM_SK, CS_EXT_LIST_PRICE, $f2]
- exprs: [CS_ITEM_SK, CS_EXT_LIST_PRICE, +(+(CR_REFUNDED_CASH, CR_REVERSED_CHARGE), CR_STORE_CREDIT)]
+ fieldNames: [CS_ITEM_SK, CS_EXT_LIST_PRICE, $f2]
+ projection: [CS_ITEM_SK, CS_EXT_LIST_PRICE, +(+(CR_REFUNDED_CASH, CR_REVERSED_CHARGE), CR_STORE_CREDIT)]
est: (rows=144067)
HashJoin
- condition: AND(=(CS_ITEM_SK, CR_ITEM_SK), =(CS_ORDER_NUMBER, CR_ORDER_NUMBER))
- joinType: inner
+ predicate: AND(=(CS_ITEM_SK, CR_ITEM_SK), =(CS_ORDER_NUMBER, CR_ORDER_NUMBER))
+ type: inner
est: (rows=144067)
TableScan
table: PUBLIC.CATALOG_SALES
- fields: [CS_ITEM_SK, CS_ORDER_NUMBER, CS_EXT_LIST_PRICE]
+ fieldNames: [CS_ITEM_SK, CS_ORDER_NUMBER, CS_EXT_LIST_PRICE]
est: (rows=1441548)
TableScan
table: PUBLIC.CATALOG_RETURNS
- fields: [CR_ITEM_SK, CR_ORDER_NUMBER, CR_REFUNDED_CASH, CR_REVERSED_CHARGE, CR_STORE_CREDIT]
+ fieldNames: [CR_ITEM_SK, CR_ORDER_NUMBER, CR_REFUNDED_CASH, CR_REVERSED_CHARGE, CR_STORE_CREDIT]
est: (rows=144067)
Exchange
distribution: single
est: (rows=24325)
TableScan
table: PUBLIC.DATE_DIM
- filters: =(D_YEAR, 1999)
- fields: [D_DATE_SK, D_YEAR]
+ predicate: =(D_YEAR, 1999)
+ fieldNames: [D_DATE_SK, D_YEAR]
est: (rows=24325)
Exchange
distribution: single
est: (rows=20)
TableScan
table: PUBLIC.INCOME_BAND
- fields: [IB_INCOME_BAND_SK]
+ fieldNames: [IB_INCOME_BAND_SK]
est: (rows=20)
Exchange
distribution: single
est: (rows=20)
TableScan
table: PUBLIC.INCOME_BAND
- fields: [IB_INCOME_BAND_SK]
+ fieldNames: [IB_INCOME_BAND_SK]
est: (rows=20)
Exchange
distribution: single
est: (rows=300)
TableScan
table: PUBLIC.PROMOTION
- fields: [P_PROMO_SK]
+ fieldNames: [P_PROMO_SK]
est: (rows=300)
Exchange
distribution: single
est: (rows=12)
TableScan
table: PUBLIC.STORE
- fields: [S_STORE_SK, S_STORE_NAME, S_ZIP]
+ fieldNames: [S_STORE_SK, S_STORE_NAME, S_ZIP]
est: (rows=12)
ColocatedHashAggregate
+ fieldNames: [PRODUCT_NAME, ITEM_SK, STORE_NAME, STORE_ZIP, B_STREET_NUMBER, B_STREET_NAME, B_CITY, B_ZIP, C_STREET_NUMBER, C_STREET_NAME, C_CITY, C_ZIP, SYEAR, FSYEAR, S2YEAR, CNT, S1, S2, S3]
group: [PRODUCT_NAME, ITEM_SK, STORE_NAME, STORE_ZIP, B_STREET_NUMBER, B_STREET_NAME, B_CITY, B_ZIP, C_STREET_NUMBER, C_STREET_NAME, C_CITY, C_ZIP, SYEAR, FSYEAR, S2YEAR]
- aggs: [CNT=COUNT(), S1=SUM(SS_WHOLESALE_COST), S2=SUM(SS_LIST_PRICE), S3=SUM(SS_COUPON_AMT)]
+ aggregation: [COUNT(), SUM(SS_WHOLESALE_COST), SUM(SS_LIST_PRICE), SUM(SS_COUPON_AMT)]
est: (rows=2887)
Project
- fields: [PRODUCT_NAME, ITEM_SK, STORE_NAME, STORE_ZIP, B_STREET_NUMBER, B_STREET_NAME, B_CITY, B_ZIP, C_STREET_NUMBER, C_STREET_NAME, C_CITY, C_ZIP, SYEAR, FSYEAR, S2YEAR, SS_WHOLESALE_COST, SS_LIST_PRICE, SS_COUPON_AMT]
- exprs: [I_PRODUCT_NAME, I_ITEM_SK, S_STORE_NAME, S_ZIP, CA_STREET_NUMBER, CA_STREET_NAME, CA_CITY, CA_ZIP, CA_STREET_NUMBER0, CA_STREET_NAME0, CA_CITY0, CA_ZIP0, D_YEAR00, D_YEAR, D_YEAR0, SS_WHOLESALE_COST, SS_LIST_PRICE, SS_COUPON_AMT]
+ fieldNames: [PRODUCT_NAME, ITEM_SK, STORE_NAME, STORE_ZIP, B_STREET_NUMBER, B_STREET_NAME, B_CITY, B_ZIP, C_STREET_NUMBER, C_STREET_NAME, C_CITY, C_ZIP, SYEAR, FSYEAR, S2YEAR, SS_WHOLESALE_COST, SS_LIST_PRICE, SS_COUPON_AMT]
+ projection: [I_PRODUCT_NAME, I_ITEM_SK, S_STORE_NAME, S_ZIP, CA_STREET_NUMBER, CA_STREET_NAME, CA_CITY, CA_ZIP, CA_STREET_NUMBER0, CA_STREET_NAME0, CA_CITY0, CA_ZIP0, D_YEAR00, D_YEAR, D_YEAR0, SS_WHOLESALE_COST, SS_LIST_PRICE, SS_COUPON_AMT]
est: (rows=2992)
HashJoin
- condition: AND(=(SS_ITEM_SK, SR_ITEM_SK), =(SS_TICKET_NUMBER, SR_TICKET_NUMBER))
- joinType: inner
+ predicate: AND(=(SS_ITEM_SK, SR_ITEM_SK), =(SS_TICKET_NUMBER, SR_TICKET_NUMBER))
+ type: inner
est: (rows=2992)
Exchange
distribution: single
est: (rows=287514)
TableScan
table: PUBLIC.STORE_RETURNS
- fields: [SR_ITEM_SK, SR_TICKET_NUMBER]
+ fieldNames: [SR_ITEM_SK, SR_TICKET_NUMBER]
est: (rows=287514)
HashJoin
- condition: =(C_FIRST_SALES_DATE_SK, D_DATE_SK)
- joinType: inner
+ predicate: =(C_FIRST_SALES_DATE_SK, D_DATE_SK)
+ fieldNames: [D_DATE_SK, D_YEAR, D_DATE_SK0, D_YEAR0, CA_ADDRESS_SK, CA_STREET_NUMBER, CA_STREET_NAME, CA_CITY, CA_ZIP, CA_ADDRESS_SK0, CA_STREET_NUMBER0, CA_STREET_NAME0, CA_CITY0, CA_ZIP0, HD_DEMO_SK, HD_INCOME_BAND_SK, HD_DEMO_SK0, HD_INCOME_BAND_SK0, CD_DEMO_SK, CD_MARITAL_STATUS, CD_DEMO_SK0, CD_MARITAL_STATUS0, C_CUSTOMER_SK, C_CURRENT_CDEMO_SK, C_CURRENT_HDEMO_SK, C_CURRENT_ADDR_SK, C_FIRST_SHIPTO_DATE_SK, C_FIRST_SALES_DATE_SK, SS_SOLD_DATE_SK, SS_ITEM_SK, SS_CUSTO [...]
+ type: inner
est: (rows=90684167)
Exchange
distribution: single
est: (rows=73049)
TableScan
table: PUBLIC.DATE_DIM
- fields: [D_DATE_SK, D_YEAR]
+ fieldNames: [D_DATE_SK, D_YEAR]
est: (rows=73049)
HashJoin
- condition: =(C_FIRST_SHIPTO_DATE_SK, D_DATE_SK)
- joinType: inner
+ predicate: =(C_FIRST_SHIPTO_DATE_SK, D_DATE_SK)
+ fieldNames: [D_DATE_SK, D_YEAR, CA_ADDRESS_SK, CA_STREET_NUMBER, CA_STREET_NAME, CA_CITY, CA_ZIP, CA_ADDRESS_SK0, CA_STREET_NUMBER0, CA_STREET_NAME0, CA_CITY0, CA_ZIP0, HD_DEMO_SK, HD_INCOME_BAND_SK, HD_DEMO_SK0, HD_INCOME_BAND_SK0, CD_DEMO_SK, CD_MARITAL_STATUS, CD_DEMO_SK0, CD_MARITAL_STATUS0, C_CUSTOMER_SK, C_CURRENT_CDEMO_SK, C_CURRENT_HDEMO_SK, C_CURRENT_ADDR_SK, C_FIRST_SHIPTO_DATE_SK, C_FIRST_SALES_DATE_SK, SS_SOLD_DATE_SK, SS_ITEM_SK, SS_CUSTOMER_SK, SS_CDEMO_SK [...]
+ type: inner
est: (rows=90684167)
Exchange
distribution: single
est: (rows=73049)
TableScan
table: PUBLIC.DATE_DIM
- fields: [D_DATE_SK, D_YEAR]
+ fieldNames: [D_DATE_SK, D_YEAR]
est: (rows=73049)
HashJoin
- condition: =(SS_STORE_SK, S_STORE_SK)
- joinType: inner
+ predicate: =(SS_STORE_SK, S_STORE_SK)
+ type: inner
est: (rows=90684167)
HashJoin
- condition: =(SS_PROMO_SK, P_PROMO_SK)
- joinType: inner
+ predicate: =(SS_PROMO_SK, P_PROMO_SK)
+ type: inner
est: (rows=90684167)
HashJoin
- condition: =(SS_ADDR_SK, CA_ADDRESS_SK)
- joinType: inner
+ predicate: =(SS_ADDR_SK, CA_ADDRESS_SK)
+ fieldNames: [CA_ADDRESS_SK, CA_STREET_NUMBER, CA_STREET_NAME, CA_CITY, CA_ZIP, CA_ADDRESS_SK0, CA_STREET_NUMBER0, CA_STREET_NAME0, CA_CITY0, CA_ZIP0, HD_DEMO_SK, HD_INCOME_BAND_SK, HD_DEMO_SK0, HD_INCOME_BAND_SK0, CD_DEMO_SK, CD_MARITAL_STATUS, CD_DEMO_SK0, CD_MARITAL_STATUS0, C_CUSTOMER_SK, C_CURRENT_CDEMO_SK, C_CURRENT_HDEMO_SK, C_CURRENT_ADDR_SK, C_FIRST_SHIPTO_DATE_SK, C_FIRST_SALES_DATE_SK, SS_SOLD_DATE_SK, SS_ITEM_SK, SS_CUSTOMER_SK, SS_CDEMO_SK, SS_HDEMO_SK [...]
+ type: inner
est: (rows=90684167)
Exchange
distribution: single
est: (rows=50000)
TableScan
table: PUBLIC.CUSTOMER_ADDRESS
- fields: [CA_ADDRESS_SK, CA_STREET_NUMBER, CA_STREET_NAME, CA_CITY, CA_ZIP]
+ fieldNames: [CA_ADDRESS_SK, CA_STREET_NUMBER, CA_STREET_NAME, CA_CITY, CA_ZIP]
est: (rows=50000)
HashJoin
- condition: =(C_CURRENT_ADDR_SK, CA_ADDRESS_SK)
- joinType: inner
+ predicate: =(C_CURRENT_ADDR_SK, CA_ADDRESS_SK)
+ type: inner
est: (rows=90684167)
Exchange
distribution: single
est: (rows=50000)
TableScan
table: PUBLIC.CUSTOMER_ADDRESS
- fields: [CA_ADDRESS_SK, CA_STREET_NUMBER, CA_STREET_NAME, CA_CITY, CA_ZIP]
+ fieldNames: [CA_ADDRESS_SK, CA_STREET_NUMBER, CA_STREET_NAME, CA_CITY, CA_ZIP]
est: (rows=50000)
HashJoin
- condition: =(HD_INCOME_BAND_SK, IB_INCOME_BAND_SK0)
- joinType: inner
+ predicate: =(HD_INCOME_BAND_SK, IB_INCOME_BAND_SK0)
+ fieldNames: [HD_DEMO_SK, HD_INCOME_BAND_SK, HD_DEMO_SK0, HD_INCOME_BAND_SK0, CD_DEMO_SK, CD_MARITAL_STATUS, CD_DEMO_SK0, CD_MARITAL_STATUS0, C_CUSTOMER_SK, C_CURRENT_CDEMO_SK, C_CURRENT_HDEMO_SK, C_CURRENT_ADDR_SK, C_FIRST_SHIPTO_DATE_SK, C_FIRST_SALES_DATE_SK, SS_SOLD_DATE_SK, SS_ITEM_SK, SS_CUSTOMER_SK, SS_CDEMO_SK, SS_HDEMO_SK, SS_ADDR_SK, SS_STORE_SK, SS_PROMO_SK, SS_TICKET_NUMBER, SS_WHOLESALE_COST, SS_LIST_PRICE, SS_COUPON_AMT, I_ITEM_SK, I_CURRENT_PRICE [...]
+ type: inner
est: (rows=90684167)
HashJoin
- condition: =(SS_HDEMO_SK, HD_DEMO_SK)
- joinType: inner
+ predicate: =(SS_HDEMO_SK, HD_DEMO_SK)
+ fieldNames: [HD_DEMO_SK, HD_INCOME_BAND_SK, HD_DEMO_SK0, HD_INCOME_BAND_SK0, CD_DEMO_SK, CD_MARITAL_STATUS, CD_DEMO_SK0, CD_MARITAL_STATUS0, C_CUSTOMER_SK, C_CURRENT_CDEMO_SK, C_CURRENT_HDEMO_SK, C_CURRENT_ADDR_SK, C_FIRST_SHIPTO_DATE_SK, C_FIRST_SALES_DATE_SK, SS_SOLD_DATE_SK, SS_ITEM_SK, SS_CUSTOMER_SK, SS_CDEMO_SK, SS_HDEMO_SK, SS_ADDR_SK, SS_STORE_SK, SS_PROMO_SK, SS_TICKET_NUMBER, SS_WHOLESALE_COST, SS_LIST_PRICE, SS_COUPON_AMT, I_ITEM_SK, I_CURRENT_PRI [...]
+ type: inner
est: (rows=90684167)
Exchange
distribution: single
est: (rows=7200)
TableScan
table: PUBLIC.HOUSEHOLD_DEMOGRAPHICS
- fields: [HD_DEMO_SK, HD_INCOME_BAND_SK]
+ fieldNames: [HD_DEMO_SK, HD_INCOME_BAND_SK]
est: (rows=7200)
HashJoin
- condition: =(HD_INCOME_BAND_SK, IB_INCOME_BAND_SK)
- joinType: inner
+ predicate: =(HD_INCOME_BAND_SK, IB_INCOME_BAND_SK)
+ type: inner
est: (rows=90684167)
HashJoin
- condition: =(C_CURRENT_HDEMO_SK, HD_DEMO_SK)
- joinType: inner
+ predicate: =(C_CURRENT_HDEMO_SK, HD_DEMO_SK)
+ type: inner
est: (rows=90684167)
Exchange
distribution: single
est: (rows=7200)
TableScan
table: PUBLIC.HOUSEHOLD_DEMOGRAPHICS
- fields: [HD_DEMO_SK, HD_INCOME_BAND_SK]
+ fieldNames: [HD_DEMO_SK, HD_INCOME_BAND_SK]
est: (rows=7200)
HashJoin
- condition: AND(<>(CD_MARITAL_STATUS, CD_MARITAL_STATUS0), =(SS_CDEMO_SK, CD_DEMO_SK))
- joinType: inner
+ predicate: AND(<>(CD_MARITAL_STATUS, CD_MARITAL_STATUS0), =(SS_CDEMO_SK, CD_DEMO_SK))
+ fieldNames: [CD_DEMO_SK, CD_MARITAL_STATUS, CD_DEMO_SK0, CD_MARITAL_STATUS0, C_CUSTOMER_SK, C_CURRENT_CDEMO_SK, C_CURRENT_HDEMO_SK, C_CURRENT_ADDR_SK, C_FIRST_SHIPTO_DATE_SK, C_FIRST_SALES_DATE_SK, SS_SOLD_DATE_SK, SS_ITEM_SK, SS_CUSTOMER_SK, SS_CDEMO_SK, SS_HDEMO_SK, SS_ADDR_SK, SS_STORE_SK, SS_PROMO_SK, SS_TICKET_NUMBER, SS_WHOLESALE_COST, SS_LIST_PRICE, SS_COUPON_AMT, I_ITEM_SK, I_CURRENT_PRICE, I_COLOR, I_PRODUCT_NAME, CS_ITEM_SK, SALE, REFUND, D_D [...]
+ type: inner
est: (rows=90684167)
Exchange
distribution: single
est: (rows=1920800)
TableScan
table: PUBLIC.CUSTOMER_DEMOGRAPHICS
- fields: [CD_DEMO_SK, CD_MARITAL_STATUS]
+ fieldNames: [CD_DEMO_SK, CD_MARITAL_STATUS]
est: (rows=1920800)
HashJoin
- condition: =(C_CURRENT_CDEMO_SK, CD_DEMO_SK)
- joinType: inner
+ predicate: =(C_CURRENT_CDEMO_SK, CD_DEMO_SK)
+ type: inner
est: (rows=129548810)
Exchange
distribution: single
est: (rows=1920800)
TableScan
table: PUBLIC.CUSTOMER_DEMOGRAPHICS
- fields: [CD_DEMO_SK, CD_MARITAL_STATUS]
+ fieldNames: [CD_DEMO_SK, CD_MARITAL_STATUS]
est: (rows=1920800)
HashJoin
- condition: =(SS_CUSTOMER_SK, C_CUSTOMER_SK)
- joinType: inner
+ predicate: =(SS_CUSTOMER_SK, C_CUSTOMER_SK)
+ type: inner
est: (rows=129548810)
Exchange
distribution: single
est: (rows=100000)
TableScan
table: PUBLIC.CUSTOMER
- fields: [C_CUSTOMER_SK, C_CURRENT_CDEMO_SK, C_CURRENT_HDEMO_SK, C_CURRENT_ADDR_SK, C_FIRST_SHIPTO_DATE_SK, C_FIRST_SALES_DATE_SK]
+ fieldNames: [C_CUSTOMER_SK, C_CURRENT_CDEMO_SK, C_CURRENT_HDEMO_SK, C_CURRENT_ADDR_SK, C_FIRST_SHIPTO_DATE_SK, C_FIRST_SALES_DATE_SK]
est: (rows=100000)
HashJoin
- condition: =(SS_SOLD_DATE_SK, D_DATE_SK)
- joinType: inner
+ predicate: =(SS_SOLD_DATE_SK, D_DATE_SK)
+ type: inner
est: (rows=129548810)
HashJoin
- condition: =(SS_ITEM_SK, CS_ITEM_SK)
- joinType: inner
+ predicate: =(SS_ITEM_SK, CS_ITEM_SK)
+ type: inner
est: (rows=389035465)
HashJoin
- condition: =(SS_ITEM_SK, I_ITEM_SK)
- joinType: inner
+ predicate: =(SS_ITEM_SK, I_ITEM_SK)
+ type: inner
est: (rows=180025)
Exchange
distribution: single
est: (rows=2880404)
TableScan
table: PUBLIC.STORE_SALES
- fields: [SS_SOLD_DATE_SK, SS_ITEM_SK, SS_CUSTOMER_SK, SS_CDEMO_SK, SS_HDEMO_SK, SS_ADDR_SK, SS_STORE_SK, SS_PROMO_SK, SS_TICKET_NUMBER, SS_WHOLESALE_COST, SS_LIST_PRICE, SS_COUPON_AMT]
+ fieldNames: [SS_SOLD_DATE_SK, SS_ITEM_SK, SS_CUSTOMER_SK, SS_CDEMO_SK, SS_HDEMO_SK, SS_ADDR_SK, SS_STORE_SK, SS_PROMO_SK, SS_TICKET_NUMBER, SS_WHOLESALE_COST, SS_LIST_PRICE, SS_COUPON_AMT]
est: (rows=2880404)
Exchange
distribution: single
est: (rows=1125)
TableScan
table: PUBLIC.ITEM
- filters: AND(SEARCH(I_COLOR, Sarg[_UTF-8'azure':VARCHAR(20) CHARACTER SET "UTF-8", _UTF-8'blush':VARCHAR(20) CHARACTER SET "UTF-8", _UTF-8'gainsboro':VARCHAR(20) CHARACTER SET "UTF-8", _UTF-8'hot':VARCHAR(20) CHARACTER SET "UTF-8", _UTF-8'lemon':VARCHAR(20) CHARACTER SET "UTF-8", _UTF-8'misty':VARCHAR(20) CHARACTER SET "UTF-8"]:VARCHAR(20) CHARACTER SET "UTF-8"), >=(CAST(I_CURRENT_PRICE):DECIMAL(12, 2), 80.00), <=(CAST(I_CURRENT_PRICE):DE [...]
- fields: [I_ITEM_SK, I_CURRENT_PRICE, I_COLOR, I_PRODUCT_NAME]
+ predicate: AND(SEARCH(I_COLOR, Sarg[_UTF-8'azure':VARCHAR(20) CHARACTER SET "UTF-8", _UTF-8'blush':VARCHAR(20) CHARACTER SET "UTF-8", _UTF-8'gainsboro':VARCHAR(20) CHARACTER SET "UTF-8", _UTF-8'hot':VARCHAR(20) CHARACTER SET "UTF-8", _UTF-8'lemon':VARCHAR(20) CHARACTER SET "UTF-8", _UTF-8'misty':VARCHAR(20) CHARACTER SET "UTF-8"]:VARCHAR(20) CHARACTER SET "UTF-8"), >=(CAST(I_CURRENT_PRICE):DECIMAL(12, 2), 80.00), <=(CAST(I_CURRENT_PRICE): [...]
+ fieldNames: [I_ITEM_SK, I_CURRENT_PRICE, I_COLOR, I_PRODUCT_NAME]
est: (rows=1125)
Filter
- condition: >(SALE, *(2, REFUND))
+ predicate: >(SALE, *(2, REFUND))
est: (rows=14407)
ReduceHashAggregate
- rowType: RecordType(INTEGER CS_ITEM_SK, DECIMAL(32767, 2) SALE, DECIMAL(32767, 2) REFUND)
+ fieldNames: [CS_ITEM_SK, SALE, REFUND]
group: [CS_ITEM_SK]
- aggs: [SALE=SUM(_ACC0), REFUND=SUM(_ACC1)]
+ aggregation: [SUM(_ACC0), SUM(_ACC1)]
est: (rows=28813)
Exchange
distribution: single
est: (rows=28813)
MapHashAggregate
+ fieldNames: [CS_ITEM_SK, _ACC0, _ACC1, _GROUP_ID]
group: [CS_ITEM_SK]
- aggs: [SALE=SUM(CS_EXT_LIST_PRICE), REFUND=SUM($f2)]
+ aggregation: [SUM(CS_EXT_LIST_PRICE), SUM($f2)]
est: (rows=28813)
Project
- fields: [CS_ITEM_SK, CS_EXT_LIST_PRICE, $f2]
- exprs: [CS_ITEM_SK, CS_EXT_LIST_PRICE, +(+(CR_REFUNDED_CASH, CR_REVERSED_CHARGE), CR_STORE_CREDIT)]
+ fieldNames: [CS_ITEM_SK, CS_EXT_LIST_PRICE, $f2]
+ projection: [CS_ITEM_SK, CS_EXT_LIST_PRICE, +(+(CR_REFUNDED_CASH, CR_REVERSED_CHARGE), CR_STORE_CREDIT)]
est: (rows=144067)
HashJoin
- condition: AND(=(CS_ITEM_SK, CR_ITEM_SK), =(CS_ORDER_NUMBER, CR_ORDER_NUMBER))
- joinType: inner
+ predicate: AND(=(CS_ITEM_SK, CR_ITEM_SK), =(CS_ORDER_NUMBER, CR_ORDER_NUMBER))
+ type: inner
est: (rows=144067)
TableScan
table: PUBLIC.CATALOG_SALES
- fields: [CS_ITEM_SK, CS_ORDER_NUMBER, CS_EXT_LIST_PRICE]
+ fieldNames: [CS_ITEM_SK, CS_ORDER_NUMBER, CS_EXT_LIST_PRICE]
est: (rows=1441548)
TableScan
table: PUBLIC.CATALOG_RETURNS
- fields: [CR_ITEM_SK, CR_ORDER_NUMBER, CR_REFUNDED_CASH, CR_REVERSED_CHARGE, CR_STORE_CREDIT]
+ fieldNames: [CR_ITEM_SK, CR_ORDER_NUMBER, CR_REFUNDED_CASH, CR_REVERSED_CHARGE, CR_STORE_CREDIT]
est: (rows=144067)
Exchange
distribution: single
est: (rows=24325)
TableScan
table: PUBLIC.DATE_DIM
- filters: =(D_YEAR, +(1999, 1))
- fields: [D_DATE_SK, D_YEAR]
+ predicate: =(D_YEAR, +(1999, 1))
+ fieldNames: [D_DATE_SK, D_YEAR]
est: (rows=24325)
Exchange
distribution: single
est: (rows=20)
TableScan
table: PUBLIC.INCOME_BAND
- fields: [IB_INCOME_BAND_SK]
+ fieldNames: [IB_INCOME_BAND_SK]
est: (rows=20)
Exchange
distribution: single
est: (rows=20)
TableScan
table: PUBLIC.INCOME_BAND
- fields: [IB_INCOME_BAND_SK]
+ fieldNames: [IB_INCOME_BAND_SK]
est: (rows=20)
Exchange
distribution: single
est: (rows=300)
TableScan
table: PUBLIC.PROMOTION
- fields: [P_PROMO_SK]
+ fieldNames: [P_PROMO_SK]
est: (rows=300)
Exchange
distribution: single
est: (rows=12)
TableScan
table: PUBLIC.STORE
- fields: [S_STORE_SK, S_STORE_NAME, S_ZIP]
+ fieldNames: [S_STORE_SK, S_STORE_NAME, S_ZIP]
est: (rows=12)
diff --git a/modules/sql-engine/src/test/resources/tpch/plan/q1.plan b/modules/sql-engine/src/test/resources/tpch/plan/q1.plan
index 44154d7d383..cef36ac555f 100644
--- a/modules/sql-engine/src/test/resources/tpch/plan/q1.plan
+++ b/modules/sql-engine/src/test/resources/tpch/plan/q1.plan
@@ -2,32 +2,33 @@ Sort
collation: [L_RETURNFLAG ASC, L_LINESTATUS ASC]
est: (rows=1080219)
Project
- fields: [L_RETURNFLAG, L_LINESTATUS, SUM_QTY, SUM_BASE_PRICE, SUM_DISC_PRICE, SUM_CHARGE, AVG_QTY, AVG_PRICE, AVG_DISC, COUNT_ORDER]
- exprs: [f0, f1, f0_2, f0_3, f0_4, f0_5, DECIMAL_DIVIDE(f0_6, f1_7, 29, 16), DECIMAL_DIVIDE(f0_8, f1_9, 29, 16), DECIMAL_DIVIDE(f0_10, f1_11, 29, 16), CAST(f0_12):BIGINT NOT NULL]
+ fieldNames: [L_RETURNFLAG, L_LINESTATUS, SUM_QTY, SUM_BASE_PRICE, SUM_DISC_PRICE, SUM_CHARGE, AVG_QTY, AVG_PRICE, AVG_DISC, COUNT_ORDER]
+ projection: [f0, f1, f0_2, f0_3, f0_4, f0_5, DECIMAL_DIVIDE(f0_6, f1_7, 29, 16), DECIMAL_DIVIDE(f0_8, f1_9, 29, 16), DECIMAL_DIVIDE(f0_10, f1_11, 29, 16), CAST(f0_12):BIGINT NOT NULL]
est: (rows=1080219)
ReduceHashAggregate
- rowType: RecordType(VARCHAR(1) f0, VARCHAR(1) f1, DECIMAL(32767, 2) f0_2, DECIMAL(32767, 2) f0_3, DECIMAL(32767, 4) f0_4, DECIMAL(32767, 6) f0_5, DECIMAL(32767, 2) f0_6, DECIMAL(32767, 0) f1_7, DECIMAL(32767, 2) f0_8, DECIMAL(32767, 0) f1_9, DECIMAL(32767, 2) f0_10, DECIMAL(32767, 0) f1_11, BIGINT f0_12)
+ fieldNames: [f0, f1, f0_2, f0_3, f0_4, f0_5, f0_6, f1_7, f0_8, f1_9, f0_10, f1_11, f0_12]
group: [0, 1]
- aggs: [SUM_QTY=SUM(2), SUM_BASE_PRICE=SUM(3), SUM_DISC_PRICE=SUM(4), SUM_CHARGE=SUM(5), AVG_SUM6=SUM(6), AVG_SUM06=$SUM0(7), AVG_SUM8=SUM(8), AVG_SUM08=$SUM0(9), AVG_SUM10=SUM(10), AVG_SUM010=$SUM0(11), COUNT_12_MAP_SUM=$SUM0(12)]
+ aggregation: [SUM(2), SUM(3), SUM(4), SUM(5), SUM(6), $SUM0(7), SUM(8), $SUM0(9), SUM(10), $SUM0(11), $SUM0(12)]
est: (rows=1080219)
Exchange
distribution: single
est: (rows=1080219)
Project
- fields: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
- exprs: [L_RETURNFLAG, L_LINESTATUS, _ACC0, _ACC1, _ACC2, _ACC3, _ACC4, CAST(_ACC5):DECIMAL(32767, 0) NOT NULL, _ACC6, CAST(_ACC7):DECIMAL(32767, 0) NOT NULL, _ACC8, CAST(_ACC9):DECIMAL(32767, 0) NOT NULL, _ACC10, _GROUP_ID]
+ fieldNames: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
+ projection: [L_RETURNFLAG, L_LINESTATUS, _ACC0, _ACC1, _ACC2, _ACC3, _ACC4, CAST(_ACC5):DECIMAL(32767, 0) NOT NULL, _ACC6, CAST(_ACC7):DECIMAL(32767, 0) NOT NULL, _ACC8, CAST(_ACC9):DECIMAL(32767, 0) NOT NULL, _ACC10, _GROUP_ID]
est: (rows=1080219)
MapHashAggregate
+ fieldNames: [L_RETURNFLAG, L_LINESTATUS, _ACC0, _ACC1, _ACC2, _ACC3, _ACC4, _ACC5, _ACC6, _ACC7, _ACC8, _ACC9, _ACC10, _GROUP_ID]
group: [L_RETURNFLAG, L_LINESTATUS]
- aggs: [SUM_QTY=SUM(L_QUANTITY), SUM_BASE_PRICE=SUM(L_EXTENDEDPRICE), SUM_DISC_PRICE=SUM($f4), SUM_CHARGE=SUM($f5), AVG_SUM6=SUM(L_QUANTITY), AVG_COUNT6=COUNT(L_QUANTITY), AVG_SUM8=SUM(L_EXTENDEDPRICE), AVG_COUNT8=COUNT(L_EXTENDEDPRICE), AVG_SUM10=SUM(L_DISCOUNT), AVG_COUNT10=COUNT(L_DISCOUNT), COUNT_ORDER=COUNT()]
+ aggregation: [SUM(L_QUANTITY), SUM(L_EXTENDEDPRICE), SUM($f4), SUM($f5), SUM(L_QUANTITY), COUNT(L_QUANTITY), SUM(L_EXTENDEDPRICE), COUNT(L_EXTENDEDPRICE), SUM(L_DISCOUNT), COUNT(L_DISCOUNT), COUNT()]
est: (rows=1080219)
IndexScan
table: PUBLIC.LINEITEM
index: L_SD
type: SORTED
+ predicate: <=(L_SHIPDATE, -(1998-12-01, 7776000000:INTERVAL DAY))
searchBounds: [RangeBounds [lowerBound=null, upperBound=-(1998-12-01, 7776000000:INTERVAL DAY), lowerInclude=true, upperInclude=true]]
- filters: <=(L_SHIPDATE, -(1998-12-01, 7776000000:INTERVAL DAY))
- fields: [L_RETURNFLAG, L_LINESTATUS, L_QUANTITY, L_EXTENDEDPRICE, $f4, $f5, L_DISCOUNT]
- projects: [L_RETURNFLAG, L_LINESTATUS, L_QUANTITY, L_EXTENDEDPRICE, *(L_EXTENDEDPRICE, -(1, L_DISCOUNT)), *(*(L_EXTENDEDPRICE, -(1, L_DISCOUNT)), +(1, L_TAX)), L_DISCOUNT]
+ fieldNames: [L_RETURNFLAG, L_LINESTATUS, L_QUANTITY, L_EXTENDEDPRICE, $f4, $f5, L_DISCOUNT]
+ projection: [L_RETURNFLAG, L_LINESTATUS, L_QUANTITY, L_EXTENDEDPRICE, *(L_EXTENDEDPRICE, -(1, L_DISCOUNT)), *(*(L_EXTENDEDPRICE, -(1, L_DISCOUNT)), +(1, L_TAX)), L_DISCOUNT]
collation: []
est: (rows=3000608)
diff --git a/modules/sql-engine/src/test/resources/tpch/plan/q21.plan b/modules/sql-engine/src/test/resources/tpch/plan/q21.plan
index 0358daf1630..dd402239ab8 100644
--- a/modules/sql-engine/src/test/resources/tpch/plan/q21.plan
+++ b/modules/sql-engine/src/test/resources/tpch/plan/q21.plan
@@ -6,53 +6,54 @@ Limit
fetch: 100
est: (rows=100)
ColocatedSortAggregate
- group: [S_NAME]
- aggs: [NUMWAIT=COUNT()]
+ fieldNames: [S_NAME, NUMWAIT]
collation: [S_NAME ASC]
+ group: [S_NAME]
+ aggregation: [COUNT()]
est: (rows=332203730726418)
Project
- fields: [S_NAME]
- exprs: [S_NAME]
+ fieldNames: [S_NAME]
+ projection: [S_NAME]
est: (rows=1661018653632089)
Filter
- condition: IS NULL(i)
+ predicate: IS NULL(i)
est: (rows=1661018653632089)
CorrelatedNestedLoopJoin
- condition: true
- joinType: left
- variablesSet: [$cor5]
+ predicate: true
+ type: left
+ correlates: [$cor5]
est: (rows=6644074614528357)
CorrelatedNestedLoopJoin
- condition: true
- joinType: inner
- variablesSet: [$cor6]
+ predicate: true
+ type: inner
+ correlates: [$cor6]
est: (rows=66493788407)
Sort
collation: [S_NAME ASC]
est: (rows=332734)
Project
- fields: [S_NAME, L_ORDERKEY, L_SUPPKEY]
- exprs: [S_NAME, L_ORDERKEY, L_SUPPKEY]
+ fieldNames: [S_NAME, L_ORDERKEY, L_SUPPKEY]
+ projection: [S_NAME, L_ORDERKEY, L_SUPPKEY]
est: (rows=332734)
HashJoin
- condition: =(O_ORDERKEY, L_ORDERKEY)
- joinType: inner
+ predicate: =(O_ORDERKEY, L_ORDERKEY)
+ type: inner
est: (rows=332734)
HashJoin
- condition: =(S_SUPPKEY, L_SUPPKEY)
- joinType: inner
+ predicate: =(S_SUPPKEY, L_SUPPKEY)
+ type: inner
est: (rows=999202)
Exchange
distribution: single
est: (rows=3000608)
TableScan
table: PUBLIC.LINEITEM
- filters: >(L_RECEIPTDATE, L_COMMITDATE)
- fields: [L_ORDERKEY, L_SUPPKEY, L_COMMITDATE, L_RECEIPTDATE]
+ predicate: >(L_RECEIPTDATE, L_COMMITDATE)
+ fieldNames: [L_ORDERKEY, L_SUPPKEY, L_COMMITDATE, L_RECEIPTDATE]
est: (rows=3000608)
MergeJoin
- condition: =(S_NATIONKEY, N_NATIONKEY)
- joinType: inner
+ predicate: =(S_NATIONKEY, N_NATIONKEY)
+ type: inner
est: (rows=3330)
Exchange
distribution: single
@@ -61,7 +62,7 @@ Limit
table: PUBLIC.SUPPLIER
index: S_NK
type: SORTED
- fields: [S_SUPPKEY, S_NAME, S_NATIONKEY]
+ fieldNames: [S_SUPPKEY, S_NAME, S_NATIONKEY]
collation: [S_NATIONKEY ASC]
est: (rows=10000)
Exchange
@@ -72,60 +73,64 @@ Limit
est: (rows=8)
TableScan
table: PUBLIC.NATION
- filters: =(N_NAME, _UTF-8'SAUDI ARABIA')
- fields: [N_NATIONKEY, N_NAME]
+ predicate: =(N_NAME, _UTF-8'SAUDI ARABIA')
+ fieldNames: [N_NATIONKEY, N_NAME]
est: (rows=8)
Exchange
distribution: single
est: (rows=499500)
TableScan
table: PUBLIC.ORDERS
- filters: =(O_ORDERSTATUS, _UTF-8'F')
- fields: [O_ORDERKEY, O_ORDERSTATUS]
+ predicate: =(O_ORDERSTATUS, _UTF-8'F')
+ fieldNames: [O_ORDERKEY, O_ORDERSTATUS]
est: (rows=499500)
Project
- fields: []
- exprs: []
+ fieldNames: []
+ projection: []
est: (rows=199840)
ReduceHashAggregate
- rowType: RecordType(BOOLEAN i)
+ fieldNames: [i]
group: [i]
+ aggregation: []
est: (rows=199840)
Exchange
distribution: single
est: (rows=199840)
MapHashAggregate
+ fieldNames: [i, _GROUP_ID]
group: [i]
- aggs: []
+ aggregation: []
est: (rows=199840)
IndexScan
table: PUBLIC.LINEITEM
index: L_OK
type: SORTED
+ predicate: AND(=(L_ORDERKEY, $cor6.L_ORDERKEY), <>(L_SUPPKEY, $cor6.L_SUPPKEY))
searchBounds: [ExactBounds [bound=$cor6.L_ORDERKEY]]
- filters: AND(=(L_ORDERKEY, $cor6.L_ORDERKEY), <>(L_SUPPKEY, $cor6.L_SUPPKEY))
- fields: [i]
- projects: [true]
+ fieldNames: [i]
+ projection: [true]
collation: []
est: (rows=999202)
ReduceHashAggregate
- rowType: RecordType(BOOLEAN i)
+ fieldNames: [i]
group: [i]
+ aggregation: []
est: (rows=99920)
Exchange
distribution: single
est: (rows=99920)
MapHashAggregate
+ fieldNames: [i, _GROUP_ID]
group: [i]
- aggs: []
+ aggregation: []
est: (rows=99920)
IndexScan
table: PUBLIC.LINEITEM
index: L_OK
type: SORTED
+ predicate: AND(=(L_ORDERKEY, $cor5.L_ORDERKEY), <>(L_SUPPKEY, $cor5.L_SUPPKEY), >(L_RECEIPTDATE, L_COMMITDATE))
searchBounds: [ExactBounds [bound=$cor5.L_ORDERKEY]]
- filters: AND(=(L_ORDERKEY, $cor5.L_ORDERKEY), <>(L_SUPPKEY, $cor5.L_SUPPKEY), >(L_RECEIPTDATE, L_COMMITDATE))
- fields: [i]
- projects: [true]
+ fieldNames: [i]
+ projection: [true]
collation: []
est: (rows=499601)
diff --git a/modules/sql-engine/src/test/resources/tpch/plan/q5.plan b/modules/sql-engine/src/test/resources/tpch/plan/q5.plan
index 9e39e15cd8d..c6dc504bd6c 100644
--- a/modules/sql-engine/src/test/resources/tpch/plan/q5.plan
+++ b/modules/sql-engine/src/test/resources/tpch/plan/q5.plan
@@ -2,74 +2,75 @@ Sort
collation: [REVENUE DESC]
est: (rows=69944)
ColocatedHashAggregate
+ fieldNames: [N_NAME, REVENUE]
group: [N_NAME]
- aggs: [REVENUE=SUM($f1)]
+ aggregation: [SUM($f1)]
est: (rows=69944)
Project
- fields: [N_NAME, $f1]
- exprs: [N_NAME, *(L_EXTENDEDPRICE, -(1, L_DISCOUNT))]
+ fieldNames: [N_NAME, $f1]
+ projection: [N_NAME, *(L_EXTENDEDPRICE, -(1, L_DISCOUNT))]
est: (rows=349721)
HashJoin
- condition: AND(=(C_NATIONKEY, S_NATIONKEY), =(L_SUPPKEY, S_SUPPKEY))
- joinType: inner
+ predicate: AND(=(C_NATIONKEY, S_NATIONKEY), =(L_SUPPKEY, S_SUPPKEY))
+ type: inner
est: (rows=349721)
HashJoin
- condition: =(L_ORDERKEY, O_ORDERKEY)
- joinType: inner
+ predicate: =(L_ORDERKEY, O_ORDERKEY)
+ type: inner
est: (rows=1500304)
Exchange
distribution: single
est: (rows=6001215)
TableScan
table: PUBLIC.LINEITEM
- fields: [L_ORDERKEY, L_SUPPKEY, L_EXTENDEDPRICE, L_DISCOUNT]
+ fieldNames: [L_ORDERKEY, L_SUPPKEY, L_EXTENDEDPRICE, L_DISCOUNT]
est: (rows=6001215)
HashJoin
- condition: =(C_CUSTKEY, O_CUSTKEY)
- joinType: inner
+ predicate: =(C_CUSTKEY, O_CUSTKEY)
+ type: inner
est: (rows=375000)
Exchange
distribution: single
est: (rows=375000)
TableScan
table: PUBLIC.ORDERS
- filters: AND(>=(O_ORDERDATE, 1994-01-01), <(O_ORDERDATE, +(1994-01-01, 12:INTERVAL YEAR)))
- fields: [O_ORDERKEY, O_CUSTKEY, O_ORDERDATE]
+ predicate: AND(>=(O_ORDERDATE, 1994-01-01), <(O_ORDERDATE, +(1994-01-01, 12:INTERVAL YEAR)))
+ fieldNames: [O_ORDERKEY, O_CUSTKEY, O_ORDERDATE]
est: (rows=375000)
Exchange
distribution: single
est: (rows=150000)
TableScan
table: PUBLIC.CUSTOMER
- fields: [C_CUSTKEY, C_NATIONKEY]
+ fieldNames: [C_CUSTKEY, C_NATIONKEY]
est: (rows=150000)
HashJoin
- condition: =(S_NATIONKEY, N_NATIONKEY)
- joinType: inner
+ predicate: =(S_NATIONKEY, N_NATIONKEY)
+ type: inner
est: (rows=3330)
Exchange
distribution: single
est: (rows=10000)
TableScan
table: PUBLIC.SUPPLIER
- fields: [S_SUPPKEY, S_NATIONKEY]
+ fieldNames: [S_SUPPKEY, S_NATIONKEY]
est: (rows=10000)
HashJoin
- condition: =(N_REGIONKEY, R_REGIONKEY)
- joinType: inner
+ predicate: =(N_REGIONKEY, R_REGIONKEY)
+ type: inner
est: (rows=8)
Exchange
distribution: single
est: (rows=25)
TableScan
table: PUBLIC.NATION
- fields: [N_NATIONKEY, N_NAME, N_REGIONKEY]
+ fieldNames: [N_NATIONKEY, N_NAME, N_REGIONKEY]
est: (rows=25)
Exchange
distribution: single
est: (rows=2)
TableScan
table: PUBLIC.REGION
- filters: =(R_NAME, _UTF-8'ASIA')
- fields: [R_REGIONKEY, R_NAME]
+ predicate: =(R_NAME, _UTF-8'ASIA')
+ fieldNames: [R_REGIONKEY, R_NAME]
est: (rows=2)
diff --git a/modules/sql-engine/src/test/resources/tpch/plan/q7.plan b/modules/sql-engine/src/test/resources/tpch/plan/q7.plan
index 5b4e29585bd..3d2c501b480 100644
--- a/modules/sql-engine/src/test/resources/tpch/plan/q7.plan
+++ b/modules/sql-engine/src/test/resources/tpch/plan/q7.plan
@@ -2,75 +2,77 @@ Sort
collation: [SUPP_NATION ASC, CUST_NATION ASC, L_YEAR ASC]
est: (rows=165618)
ColocatedHashAggregate
+ fieldNames: [SUPP_NATION, CUST_NATION, L_YEAR, REVENUE]
group: [SUPP_NATION, CUST_NATION, L_YEAR]
- aggs: [REVENUE=SUM(VOLUME)]
+ aggregation: [SUM(VOLUME)]
est: (rows=165618)
Project
- fields: [SUPP_NATION, CUST_NATION, L_YEAR, VOLUME]
- exprs: [N_NAME, N_NAME0, EXTRACT(FLAG(YEAR), L_SHIPDATE), *(L_EXTENDEDPRICE, -(1, L_DISCOUNT))]
+ fieldNames: [SUPP_NATION, CUST_NATION, L_YEAR, VOLUME]
+ projection: [N_NAME, N_NAME0, EXTRACT(FLAG(YEAR), L_SHIPDATE), *(L_EXTENDEDPRICE, -(1, L_DISCOUNT))]
est: (rows=339381)
HashJoin
- condition: AND(=(O_ORDERKEY, L_ORDERKEY), OR(=(N_NAME, _UTF-8'FRANCE'), =(N_NAME0, _UTF-8'FRANCE')), OR(=(N_NAME0, _UTF-8'GERMANY'), =(N_NAME, _UTF-8'GERMANY')))
- joinType: inner
+ predicate: AND(=(O_ORDERKEY, L_ORDERKEY), OR(=(N_NAME, _UTF-8'FRANCE'), =(N_NAME0, _UTF-8'FRANCE')), OR(=(N_NAME0, _UTF-8'GERMANY'), =(N_NAME, _UTF-8'GERMANY')))
+ fieldNames: [L_ORDERKEY, L_SUPPKEY, L_EXTENDEDPRICE, L_DISCOUNT, L_SHIPDATE, S_SUPPKEY, S_NATIONKEY, N_NATIONKEY, N_NAME, O_ORDERKEY, O_CUSTKEY, C_CUSTKEY, C_NATIONKEY, N_NATIONKEY0, N_NAME0]
+ type: inner
est: (rows=339381)
HashJoin
- condition: =(S_SUPPKEY, L_SUPPKEY)
- joinType: inner
+ predicate: =(S_SUPPKEY, L_SUPPKEY)
+ type: inner
est: (rows=852873)
Exchange
distribution: single
est: (rows=1500304)
TableScan
table: PUBLIC.LINEITEM
- filters: SEARCH(L_SHIPDATE, Sarg[[1995-01-01..1996-12-31]])
- fields: [L_ORDERKEY, L_SUPPKEY, L_EXTENDEDPRICE, L_DISCOUNT, L_SHIPDATE]
+ predicate: SEARCH(L_SHIPDATE, Sarg[[1995-01-01..1996-12-31]])
+ fieldNames: [L_ORDERKEY, L_SUPPKEY, L_EXTENDEDPRICE, L_DISCOUNT, L_SHIPDATE]
est: (rows=1500304)
HashJoin
- condition: =(S_NATIONKEY, N_NATIONKEY)
- joinType: inner
+ predicate: =(S_NATIONKEY, N_NATIONKEY)
+ type: inner
est: (rows=5685)
Exchange
distribution: single
est: (rows=10000)
TableScan
table: PUBLIC.SUPPLIER
- fields: [S_SUPPKEY, S_NATIONKEY]
+ fieldNames: [S_SUPPKEY, S_NATIONKEY]
est: (rows=10000)
Exchange
distribution: single
est: (rows=14)
TableScan
table: PUBLIC.NATION
- filters: SEARCH(N_NAME, Sarg[_UTF-8'FRANCE':CHAR(7) CHARACTER SET "UTF-8", _UTF-8'GERMANY']:CHAR(7) CHARACTER SET "UTF-8")
- fields: [N_NATIONKEY, N_NAME]
+ predicate: SEARCH(N_NAME, Sarg[_UTF-8'FRANCE':CHAR(7) CHARACTER SET "UTF-8", _UTF-8'GERMANY']:CHAR(7) CHARACTER SET "UTF-8")
+ fieldNames: [N_NATIONKEY, N_NAME]
est: (rows=14)
HashJoin
- condition: =(C_CUSTKEY, O_CUSTKEY)
- joinType: inner
+ predicate: =(C_CUSTKEY, O_CUSTKEY)
+ type: inner
est: (rows=852700)
Exchange
distribution: single
est: (rows=1500000)
TableScan
table: PUBLIC.ORDERS
- fields: [O_ORDERKEY, O_CUSTKEY]
+ fieldNames: [O_ORDERKEY, O_CUSTKEY]
est: (rows=1500000)
HashJoin
- condition: =(C_NATIONKEY, N_NATIONKEY)
- joinType: inner
+ predicate: =(C_NATIONKEY, N_NATIONKEY)
+ type: inner
est: (rows=85270)
Exchange
distribution: single
est: (rows=150000)
TableScan
table: PUBLIC.CUSTOMER
- fields: [C_CUSTKEY, C_NATIONKEY]
+ fieldNames: [C_CUSTKEY, C_NATIONKEY]
est: (rows=150000)
Exchange
distribution: single
est: (rows=14)
TableScan
table: PUBLIC.NATION
- filters: SEARCH(N_NAME, Sarg[_UTF-8'FRANCE':CHAR(7) CHARACTER SET "UTF-8", _UTF-8'GERMANY']:CHAR(7) CHARACTER SET "UTF-8")
- fields: [N_NATIONKEY, N_NAME]
+ predicate: SEARCH(N_NAME, Sarg[_UTF-8'FRANCE':CHAR(7) CHARACTER SET "UTF-8", _UTF-8'GERMANY']:CHAR(7) CHARACTER SET "UTF-8")
+ fieldNames: [N_NATIONKEY, N_NAME]
est: (rows=14)
diff --git a/modules/sql-engine/src/test/resources/tpch/plan/q8.plan b/modules/sql-engine/src/test/resources/tpch/plan/q8.plan
index 465cbc5d37b..791b17a297d 100644
--- a/modules/sql-engine/src/test/resources/tpch/plan/q8.plan
+++ b/modules/sql-engine/src/test/resources/tpch/plan/q8.plan
@@ -2,101 +2,103 @@ Sort
collation: [O_YEAR ASC]
est: (rows=16635)
Project
- fields: [O_YEAR, MKT_SHARE]
- exprs: [O_YEAR, /($f1, $f2)]
+ fieldNames: [O_YEAR, MKT_SHARE]
+ projection: [O_YEAR, /($f1, $f2)]
est: (rows=16635)
ColocatedHashAggregate
+ fieldNames: [O_YEAR, $f1, $f2]
group: [O_YEAR]
- aggs: [SUM($f1), SUM(VOLUME)]
+ aggregation: [SUM($f1), SUM(VOLUME)]
est: (rows=16635)
Project
- fields: [O_YEAR, $f1, VOLUME]
- exprs: [EXTRACT(FLAG(YEAR), O_ORDERDATE), CASE(=(N_NAME, _UTF-8'BRAZIL'), *(L_EXTENDEDPRICE, -(1, L_DISCOUNT)), 0.0000:DECIMAL(31, 4)), *(L_EXTENDEDPRICE, -(1, L_DISCOUNT))]
+ fieldNames: [O_YEAR, $f1, VOLUME]
+ projection: [EXTRACT(FLAG(YEAR), O_ORDERDATE), CASE(=(N_NAME, _UTF-8'BRAZIL'), *(L_EXTENDEDPRICE, -(1, L_DISCOUNT)), 0.0000:DECIMAL(31, 4)), *(L_EXTENDEDPRICE, -(1, L_DISCOUNT))]
est: (rows=166367)
HashJoin
- condition: =(S_SUPPKEY, L_SUPPKEY)
- joinType: inner
+ predicate: =(S_SUPPKEY, L_SUPPKEY)
+ fieldNames: [L_ORDERKEY, L_PARTKEY, L_SUPPKEY, L_EXTENDEDPRICE, L_DISCOUNT, O_ORDERKEY, O_CUSTKEY, O_ORDERDATE, C_CUSTKEY, C_NATIONKEY, N_NATIONKEY, N_REGIONKEY, R_REGIONKEY, R_NAME, P_PARTKEY, P_TYPE, S_SUPPKEY, S_NATIONKEY, N_NATIONKEY0, N_NAME]
+ type: inner
est: (rows=166367)
HashJoin
- condition: =(P_PARTKEY, L_PARTKEY)
- joinType: inner
+ predicate: =(P_PARTKEY, L_PARTKEY)
+ type: inner
est: (rows=166367)
HashJoin
- condition: =(L_ORDERKEY, O_ORDERKEY)
- joinType: inner
+ predicate: =(L_ORDERKEY, O_ORDERKEY)
+ type: inner
est: (rows=499601)
Exchange
distribution: single
est: (rows=6001215)
TableScan
table: PUBLIC.LINEITEM
- fields: [L_ORDERKEY, L_PARTKEY, L_SUPPKEY, L_EXTENDEDPRICE, L_DISCOUNT]
+ fieldNames: [L_ORDERKEY, L_PARTKEY, L_SUPPKEY, L_EXTENDEDPRICE, L_DISCOUNT]
est: (rows=6001215)
HashJoin
- condition: =(O_CUSTKEY, C_CUSTKEY)
- joinType: inner
+ predicate: =(O_CUSTKEY, C_CUSTKEY)
+ type: inner
est: (rows=124875)
Exchange
distribution: single
est: (rows=375000)
TableScan
table: PUBLIC.ORDERS
- filters: SEARCH(O_ORDERDATE, Sarg[[1995-01-01..1996-12-31]])
- fields: [O_ORDERKEY, O_CUSTKEY, O_ORDERDATE]
+ predicate: SEARCH(O_ORDERDATE, Sarg[[1995-01-01..1996-12-31]])
+ fieldNames: [O_ORDERKEY, O_CUSTKEY, O_ORDERDATE]
est: (rows=375000)
HashJoin
- condition: =(C_NATIONKEY, N_NATIONKEY)
- joinType: inner
+ predicate: =(C_NATIONKEY, N_NATIONKEY)
+ type: inner
est: (rows=49950)
Exchange
distribution: single
est: (rows=150000)
TableScan
table: PUBLIC.CUSTOMER
- fields: [C_CUSTKEY, C_NATIONKEY]
+ fieldNames: [C_CUSTKEY, C_NATIONKEY]
est: (rows=150000)
HashJoin
- condition: =(N_REGIONKEY, R_REGIONKEY)
- joinType: inner
+ predicate: =(N_REGIONKEY, R_REGIONKEY)
+ type: inner
est: (rows=8)
Exchange
distribution: single
est: (rows=25)
TableScan
table: PUBLIC.NATION
- fields: [N_NATIONKEY, N_REGIONKEY]
+ fieldNames: [N_NATIONKEY, N_REGIONKEY]
est: (rows=25)
Exchange
distribution: single
est: (rows=2)
TableScan
table: PUBLIC.REGION
- filters: =(R_NAME, _UTF-8'AMERICA')
- fields: [R_REGIONKEY, R_NAME]
+ predicate: =(R_NAME, _UTF-8'AMERICA')
+ fieldNames: [R_REGIONKEY, R_NAME]
est: (rows=2)
Exchange
distribution: single
est: (rows=66600)
TableScan
table: PUBLIC.PART
- filters: =(P_TYPE, _UTF-8'ECONOMY ANODIZED STEEL')
- fields: [P_PARTKEY, P_TYPE]
+ predicate: =(P_TYPE, _UTF-8'ECONOMY ANODIZED STEEL')
+ fieldNames: [P_PARTKEY, P_TYPE]
est: (rows=66600)
HashJoin
- condition: =(S_NATIONKEY, N_NATIONKEY)
- joinType: inner
+ predicate: =(S_NATIONKEY, N_NATIONKEY)
+ type: inner
est: (rows=10000)
Exchange
distribution: single
est: (rows=10000)
TableScan
table: PUBLIC.SUPPLIER
- fields: [S_SUPPKEY, S_NATIONKEY]
+ fieldNames: [S_SUPPKEY, S_NATIONKEY]
est: (rows=10000)
Exchange
distribution: single
est: (rows=25)
TableScan
table: PUBLIC.NATION
- fields: [N_NATIONKEY, N_NAME]
+ fieldNames: [N_NATIONKEY, N_NAME]
est: (rows=25)
diff --git a/modules/sql-engine/src/test/resources/tpch/plan/q9.plan b/modules/sql-engine/src/test/resources/tpch/plan/q9.plan
index f7ad03fa5d1..e01182648f6 100644
--- a/modules/sql-engine/src/test/resources/tpch/plan/q9.plan
+++ b/modules/sql-engine/src/test/resources/tpch/plan/q9.plan
@@ -2,73 +2,74 @@ Sort
collation: [NATION ASC, O_YEAR DESC]
est: (rows=540109)
ColocatedHashAggregate
+ fieldNames: [NATION, O_YEAR, SUM_PROFIT]
group: [NATION, O_YEAR]
- aggs: [SUM_PROFIT=SUM(AMOUNT)]
+ aggregation: [SUM(AMOUNT)]
est: (rows=540109)
Project
- fields: [NATION, O_YEAR, AMOUNT]
- exprs: [N_NAME, EXTRACT(FLAG(YEAR), O_ORDERDATE), -(*(L_EXTENDEDPRICE, -(1, L_DISCOUNT)), *(PS_SUPPLYCOST, L_QUANTITY))]
+ fieldNames: [NATION, O_YEAR, AMOUNT]
+ projection: [N_NAME, EXTRACT(FLAG(YEAR), O_ORDERDATE), -(*(L_EXTENDEDPRICE, -(1, L_DISCOUNT)), *(PS_SUPPLYCOST, L_QUANTITY))]
est: (rows=1500304)
HashJoin
- condition: AND(=(PS_SUPPKEY, L_SUPPKEY), =(PS_PARTKEY, L_PARTKEY))
- joinType: inner
+ predicate: AND(=(PS_SUPPKEY, L_SUPPKEY), =(PS_PARTKEY, L_PARTKEY))
+ type: inner
est: (rows=1500304)
HashJoin
- condition: =(O_ORDERKEY, L_ORDERKEY)
- joinType: inner
+ predicate: =(O_ORDERKEY, L_ORDERKEY)
+ type: inner
est: (rows=1500304)
HashJoin
- condition: =(S_SUPPKEY, L_SUPPKEY)
- joinType: inner
+ predicate: =(S_SUPPKEY, L_SUPPKEY)
+ type: inner
est: (rows=1500304)
HashJoin
- condition: =(P_PARTKEY, L_PARTKEY)
- joinType: inner
+ predicate: =(P_PARTKEY, L_PARTKEY)
+ type: inner
est: (rows=1500304)
Exchange
distribution: single
est: (rows=6001215)
TableScan
table: PUBLIC.LINEITEM
- fields: [L_ORDERKEY, L_PARTKEY, L_SUPPKEY, L_QUANTITY, L_EXTENDEDPRICE, L_DISCOUNT]
+ fieldNames: [L_ORDERKEY, L_PARTKEY, L_SUPPKEY, L_QUANTITY, L_EXTENDEDPRICE, L_DISCOUNT]
est: (rows=6001215)
Exchange
distribution: single
est: (rows=50000)
TableScan
table: PUBLIC.PART
- filters: LIKE(P_NAME, _UTF-8'%green%')
- fields: [P_PARTKEY, P_NAME]
+ predicate: LIKE(P_NAME, _UTF-8'%green%')
+ fieldNames: [P_PARTKEY, P_NAME]
est: (rows=50000)
HashJoin
- condition: =(S_NATIONKEY, N_NATIONKEY)
- joinType: inner
+ predicate: =(S_NATIONKEY, N_NATIONKEY)
+ type: inner
est: (rows=10000)
Exchange
distribution: single
est: (rows=10000)
TableScan
table: PUBLIC.SUPPLIER
- fields: [S_SUPPKEY, S_NATIONKEY]
+ fieldNames: [S_SUPPKEY, S_NATIONKEY]
est: (rows=10000)
Exchange
distribution: single
est: (rows=25)
TableScan
table: PUBLIC.NATION
- fields: [N_NATIONKEY, N_NAME]
+ fieldNames: [N_NATIONKEY, N_NAME]
est: (rows=25)
Exchange
distribution: single
est: (rows=1500000)
TableScan
table: PUBLIC.ORDERS
- fields: [O_ORDERKEY, O_ORDERDATE]
+ fieldNames: [O_ORDERKEY, O_ORDERDATE]
est: (rows=1500000)
Exchange
distribution: single
est: (rows=800000)
TableScan
table: PUBLIC.PARTSUPP
- fields: [PS_PARTKEY, PS_SUPPKEY, PS_SUPPLYCOST]
+ fieldNames: [PS_PARTKEY, PS_SUPPKEY, PS_SUPPLYCOST]
est: (rows=800000)
diff --git a/modules/sql-engine/src/testFixtures/java/org/apache/ignite/internal/sql/engine/util/QueryChecker.java b/modules/sql-engine/src/testFixtures/java/org/apache/ignite/internal/sql/engine/util/QueryChecker.java
index 8ab541e5b17..671cdb490d7 100644
--- a/modules/sql-engine/src/testFixtures/java/org/apache/ignite/internal/sql/engine/util/QueryChecker.java
+++ b/modules/sql-engine/src/testFixtures/java/org/apache/ignite/internal/sql/engine/util/QueryChecker.java
@@ -44,14 +44,9 @@ import org.hamcrest.core.SubstringMatcher;
public interface QueryChecker {
Object[] NULL_AS_VARARG = {null};
- /** Creates a matcher that matches if the examined string contains the specified string anywhere. */
- static Matcher<String> containsUnion(boolean all) {
- return matchesOnce("UnionAll.*?all: " + all);
- }
-
/** Creates a matcher that matches if the examined string contains the specified string anywhere. */
static Matcher<String> containsUnion() {
- return matchesOnce("UnionAll.*?all:");
+ return matchesOnce("UnionAll");
}
/**
@@ -137,7 +132,7 @@ public interface QueryChecker {
*/
static Matcher<String> containsProject(String schema, String tblName, String... names) {
return matchesOnce("(Table|Index)Scan.*?table: " + QualifiedName.of(schema, tblName).toCanonicalForm()
- + ".*?fields: \\[" + String.join(", ", List.of(names)) + "\\]");
+ + ".*?fieldNames: \\[" + String.join(", ", List.of(names)) + "\\]");
}
/**