This is an automated email from the ASF dual-hosted git repository.
ppa 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 6afc371a05 IGNITE-22164 Sql. Fixed conversion from SqlMerge AST to
relational expression when columns defined in different order.
6afc371a05 is described below
commit 6afc371a05beb8b94ed2171c346142c74e5bcec1
Author: Pavel Pereslegin <[email protected]>
AuthorDate: Thu May 23 15:27:57 2024 +0300
IGNITE-22164 Sql. Fixed conversion from SqlMerge AST to relational
expression when columns defined in different order.
---
.../ignite/internal/sql/engine/ItDmlTest.java | 29 ++++++++++++++++++++++
.../engine/prepare/IgniteSqlToRelConvertor.java | 25 ++++++++++++++-----
2 files changed, 48 insertions(+), 6 deletions(-)
diff --git
a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItDmlTest.java
b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItDmlTest.java
index 29d1ed609c..57a7faa4dc 100644
---
a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItDmlTest.java
+++
b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItDmlTest.java
@@ -251,6 +251,35 @@ public class ItDmlTest extends BaseSqlIntegrationTest {
.returns(444, 444, 2, 200, null)
.check();
+ // ---- all fields covered on NOT MATCHED but columns in different
order
+ clearAndPopulateMergeTable2();
+
+ sql = "MERGE INTO test2 dst USING test1 src ON dst.a = src.a "
+ + "WHEN MATCHED THEN UPDATE SET b = src.b, a = src.a "
+ + "WHEN NOT MATCHED THEN INSERT (k1, k2, c, a, b) VALUES
(src.k1, src.k2, src.c, src.a, src.b)";
+
+ sql(sql);
+
+ assertQuery("SELECT * FROM test2 ORDER BY k1")
+ .returns(222, 222, 1, 300, "1")
+ .returns(333, 333, 0, 100, "")
+ .returns(444, 444, 2, 200, null)
+ .check();
+
+ // ---- all fields covered on NOT MATCHED but columns in different
order and with filter
+ clearAndPopulateMergeTable2();
+
+ sql = "MERGE INTO test2 dst USING (SELECT * FROM test1 WHERE a = 0)
src ON dst.a = src.a "
+ + "WHEN MATCHED THEN UPDATE SET b = src.b, a = src.a "
+ + "WHEN NOT MATCHED THEN INSERT (k1, k2, c, a, b) VALUES
(src.k1, src.k2, src.c, src.a, src.b)";
+
+ sql(sql);
+
+ assertQuery("SELECT * FROM test2 ORDER BY k1")
+ .returns(333, 333, 0, 100, "")
+ .returns(444, 444, 2, 200, null)
+ .check();
+
// --- only WHEN MATCHED section.
clearAndPopulateMergeTable2();
diff --git
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/IgniteSqlToRelConvertor.java
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/IgniteSqlToRelConvertor.java
index 74c6f49bc1..2350f6504a 100644
---
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/IgniteSqlToRelConvertor.java
+++
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/IgniteSqlToRelConvertor.java
@@ -265,14 +265,27 @@ public class IgniteSqlToRelConvertor extends
SqlToRelConverter {
// provided, in which case, the expression is the default value for
// the column; or if the expressions directly map to the source
// table
- level1InsertExprs =
- ((LogicalProject) insertRel.getInput(0)).getProjects();
- if (insertRel.getInput(0).getInput(0) instanceof LogicalProject) {
- level2InsertExprs =
- ((LogicalProject) insertRel.getInput(0).getInput(0))
- .getProjects();
+ RelNode input = insertRel.getInput(0);
+
+ if (input instanceof LogicalProject) {
+ level1InsertExprs = ((LogicalProject) input).getProjects();
+ } else {
+ // TODO https://issues.apache.org/jira/browse/IGNITE-22293
+ // convertInsert() may return LogicalTableModify without
projection in the input.
+ // As a workaround for this case, we additionally build
required column expressions.
+ RelDataType rowType = input.getRowType();
+ level1InsertExprs = new ArrayList<>(rowType.getFieldCount());
+ int pos = 0;
+ for (RelDataTypeField type : rowType.getFieldList()) {
+
level1InsertExprs.add(rexBuilder.makeInputRef(type.getType(), pos++));
+ }
}
+
numLevel1Exprs = level1InsertExprs.size();
+
+ if (!input.getInputs().isEmpty() && input.getInput(0) instanceof
LogicalProject) {
+ level2InsertExprs = ((LogicalProject)
input.getInput(0)).getProjects();
+ }
}
LogicalJoin join = (LogicalJoin) mergeSourceRel.getInput(0);