You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by zs...@apache.org on 2022/03/17 07:18:06 UTC
[ignite-3] branch main updated: IGNITE-16656 Adoption of a bunch of calcite related tickets from Ignite-2 - Fixes #707.
This is an automated email from the ASF dual-hosted git repository.
zstan 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 79a4b40 IGNITE-16656 Adoption of a bunch of calcite related tickets from Ignite-2 - Fixes #707.
79a4b40 is described below
commit 79a4b403e32f47c8ccd2d6c32c3d995ffc80f88a
Author: zstan <st...@gmail.com>
AuthorDate: Thu Mar 17 10:10:46 2022 +0300
IGNITE-16656 Adoption of a bunch of calcite related tickets from Ignite-2 - Fixes #707.
IGNITE-14681 Extend return type of sum() aggregate function
IGNITE-16414 Sorted index spool produces wrong collation
IGNITE-14963 Date interval arythmetic returns invalid results
Signed-off-by: zstan <st...@gmail.com>
---
.../internal/sql/engine/ItAggregatesTest.java | 4 +-
.../internal/sql/engine/ItDataTypesTest.java | 59 ++++++
.../ignite/internal/sql/engine/ItIntervalTest.java | 50 ++---
.../internal/sql/engine/ItSortAggregateTest.java | 6 +-
.../internal/sql/engine/exec/ExecutionContext.java | 3 -
.../sql/engine/exec/exp/agg/Accumulators.java | 215 +++------------------
.../engine/rel/agg/IgniteSortAggregateBase.java | 24 ++-
.../FilterSpoolMergeToSortedIndexSpoolRule.java | 61 +++++-
.../engine/rule/SortAggregateConverterRule.java | 7 +-
.../internal/sql/engine/trait/TraitUtils.java | 22 ++-
.../sql/engine/type/IgniteTypeFactory.java | 14 +-
.../internal/sql/engine/type/IgniteTypeSystem.java | 64 ++++++
.../ignite/internal/sql/engine/util/RexUtils.java | 19 +-
.../ignite/internal/sql/engine/util/TypeUtils.java | 31 +--
.../sql/engine/exec/rel/BaseAggregateTest.java | 96 +++++++++
.../sql/engine/planner/AbstractPlannerTest.java | 32 +++
.../planner/AggregateDistinctPlannerTest.java | 4 +-
.../sql/engine/planner/AggregatePlannerTest.java | 86 ++++++++-
.../CorrelatedNestedLoopJoinPlannerTest.java | 8 +-
.../engine/planner/HashAggregatePlannerTest.java | 4 +-
.../engine/planner/HashIndexSpoolPlannerTest.java | 8 +-
.../sql/engine/planner/LimitOffsetPlannerTest.java | 20 +-
.../engine/planner/SortAggregatePlannerTest.java | 7 +-
.../planner/SortedIndexSpoolPlannerTest.java | 8 +-
24 files changed, 538 insertions(+), 314 deletions(-)
diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItAggregatesTest.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItAggregatesTest.java
index ea370e2..e383d01 100644
--- a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItAggregatesTest.java
+++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItAggregatesTest.java
@@ -78,8 +78,8 @@ public class ItAggregatesTest extends AbstractBasicIntegrationTest {
.check();
assertQuery("select salary, count(1), sum(1) from person group by salary order by salary")
- .returns(10d, 3L, 3)
- .returns(15d, 2L, 2)
+ .returns(10d, 3L, 3L)
+ .returns(15d, 2L, 2L)
.check();
assertQuery("select salary, name, count(1), sum(salary) from person group by salary, name order by salary")
diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItDataTypesTest.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItDataTypesTest.java
index d9f8bfe..d79ea91 100644
--- a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItDataTypesTest.java
+++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItDataTypesTest.java
@@ -20,6 +20,8 @@ package org.apache.ignite.internal.sql.engine;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
@@ -156,4 +158,61 @@ public class ItDataTypesTest extends AbstractBasicIntegrationTest {
sql("DROP TABLE if exists tbl");
}
}
+
+ /**
+ * Test right date/time interpretation.
+ */
+ @Test
+ public void testDateTime() {
+ assertQuery("select date '1992-01-19'").returns(sqlDate("1992-01-19")).check();
+ assertQuery("select date '1992-01-18' + interval (1) days").returns(sqlDate("1992-01-19")).check();
+ assertQuery("select date '1992-01-18' + interval (24) hours").returns(sqlDate("1992-01-19")).check();
+ assertQuery("SELECT timestamp '1992-01-18 02:30:00' + interval (25) hours")
+ .returns(sqlDateTime("1992-01-19T03:30:00")).check();
+ assertQuery("SELECT timestamp '1992-01-18 02:30:00' + interval (23) hours")
+ .returns(sqlDateTime("1992-01-19T01:30:00.000")).check();
+ assertQuery("SELECT timestamp '1992-01-18 02:30:00' + interval (24) hours")
+ .returns(sqlDateTime("1992-01-19T02:30:00.000")).check();
+
+ assertQuery("select date '1992-03-29'").returns(sqlDate("1992-03-29")).check();
+ assertQuery("select date '1992-03-28' + interval (1) days").returns(sqlDate("1992-03-29")).check();
+ assertQuery("select date '1992-03-28' + interval (24) hours").returns(sqlDate("1992-03-29")).check();
+ assertQuery("SELECT timestamp '1992-03-28 02:30:00' + interval (25) hours")
+ .returns(sqlDateTime("1992-03-29T03:30:00.000")).check();
+ assertQuery("SELECT timestamp '1992-03-28 02:30:00' + interval (23) hours")
+ .returns(sqlDateTime("1992-03-29T01:30:00.000")).check();
+ assertQuery("SELECT timestamp '1992-03-28 02:30:00' + interval (24) hours")
+ .returns(sqlDateTime("1992-03-29T02:30:00.000")).check();
+
+ assertQuery("select date '1992-09-27'").returns(sqlDate("1992-09-27")).check();
+ assertQuery("select date '1992-09-26' + interval (1) days").returns(sqlDate("1992-09-27")).check();
+ assertQuery("select date '1992-09-26' + interval (24) hours").returns(sqlDate("1992-09-27")).check();
+ assertQuery("SELECT timestamp '1992-09-26 02:30:00' + interval (25) hours")
+ .returns(sqlDateTime("1992-09-27T03:30:00.000")).check();
+ assertQuery("SELECT timestamp '1992-09-26 02:30:00' + interval (23) hours")
+ .returns(sqlDateTime("1992-09-27T01:30:00.000")).check();
+ assertQuery("SELECT timestamp '1992-09-26 02:30:00' + interval (24) hours")
+ .returns(sqlDateTime("1992-09-27T02:30:00.000")).check();
+
+ assertQuery("select date '2021-11-07'").returns(sqlDate("2021-11-07")).check();
+ assertQuery("select date '2021-11-06' + interval (1) days").returns(sqlDate("2021-11-07")).check();
+ assertQuery("select date '2021-11-06' + interval (24) hours").returns(sqlDate("2021-11-07")).check();
+ assertQuery("SELECT timestamp '2021-11-06 01:30:00' + interval (25) hours")
+ .returns(sqlDateTime("2021-11-07T02:30:00.000")).check();
+ // Check string representation here, since after timestamp calculation we have '2021-11-07T01:30:00.000-0800'
+ // but Timestamp.valueOf method converts '2021-11-07 01:30:00' in 'America/Los_Angeles' time zone to
+ // '2021-11-07T01:30:00.000-0700' (we pass through '2021-11-07 01:30:00' twice after DST ended).
+ assertQuery("SELECT (timestamp '2021-11-06 02:30:00' + interval (23) hours)::varchar")
+ .returns("2021-11-07 01:30:00").check();
+ assertQuery("SELECT (timestamp '2021-11-06 01:30:00' + interval (24) hours)::varchar")
+ .returns("2021-11-07 01:30:00").check();
+ }
+
+ private LocalDate sqlDate(String str) {
+ return LocalDate.parse(str);
+ }
+
+ private LocalDateTime sqlDateTime(String str) {
+ return LocalDateTime.parse(str);
+ }
}
diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItIntervalTest.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItIntervalTest.java
index 47211c9..ea7bf3c 100644
--- a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItIntervalTest.java
+++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItIntervalTest.java
@@ -22,10 +22,10 @@ import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import java.sql.Date;
-import java.sql.Time;
-import java.sql.Timestamp;
import java.time.Duration;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
import java.time.Period;
import org.apache.ignite.lang.IgniteInternalException;
import org.junit.jupiter.api.Disabled;
@@ -220,45 +220,45 @@ public class ItIntervalTest extends AbstractBasicIntegrationTest {
@Test
public void testIntervalArithmetic() {
// Date +/- interval.
- assertEquals(Date.valueOf("2021-01-02"), eval("DATE '2021-01-01' + INTERVAL 1 DAY"));
- assertEquals(Date.valueOf("2020-12-31"), eval("DATE '2021-01-01' - INTERVAL 1 DAY"));
- assertEquals(Date.valueOf("2020-12-31"), eval("DATE '2021-01-01' + INTERVAL -1 DAY"));
- assertEquals(Date.valueOf("2021-02-01"), eval("DATE '2021-01-01' + INTERVAL 1 MONTH"));
- assertEquals(Date.valueOf("2022-01-01"), eval("DATE '2021-01-01' + INTERVAL 1 YEAR"));
- assertEquals(Date.valueOf("2022-02-01"), eval("DATE '2021-01-01' + INTERVAL '1-1' YEAR TO MONTH"));
+ assertEquals(LocalDate.parse("2021-01-02"), eval("DATE '2021-01-01' + INTERVAL 1 DAY"));
+ assertEquals(LocalDate.parse("2020-12-31"), eval("DATE '2021-01-01' - INTERVAL 1 DAY"));
+ assertEquals(LocalDate.parse("2020-12-31"), eval("DATE '2021-01-01' + INTERVAL -1 DAY"));
+ assertEquals(LocalDate.parse("2021-02-01"), eval("DATE '2021-01-01' + INTERVAL 1 MONTH"));
+ assertEquals(LocalDate.parse("2022-01-01"), eval("DATE '2021-01-01' + INTERVAL 1 YEAR"));
+ assertEquals(LocalDate.parse("2022-02-01"), eval("DATE '2021-01-01' + INTERVAL '1-1' YEAR TO MONTH"));
// Timestamp +/- interval.
- assertEquals(Timestamp.valueOf("2021-01-01 00:00:01"),
+ assertEquals(LocalDateTime.parse("2021-01-01T00:00:01"),
eval("TIMESTAMP '2021-01-01 00:00:00' + INTERVAL 1 SECOND"));
- assertEquals(Timestamp.valueOf("2021-01-01 00:00:01.123"),
+ assertEquals(LocalDateTime.parse("2021-01-01T00:00:01.123"),
eval("TIMESTAMP '2021-01-01 00:00:00.123' + INTERVAL 1 SECOND"));
- assertEquals(Timestamp.valueOf("2021-01-01 00:00:01.123"),
+ assertEquals(LocalDateTime.parse("2021-01-01T00:00:01.123"),
eval("TIMESTAMP '2021-01-01 00:00:00' + INTERVAL '1.123' SECOND"));
- assertEquals(Timestamp.valueOf("2021-01-01 00:00:01.246"),
+ assertEquals(LocalDateTime.parse("2021-01-01T00:00:01.246"),
eval("TIMESTAMP '2021-01-01 00:00:00.123' + INTERVAL '1.123' SECOND"));
- assertEquals(Timestamp.valueOf("2020-12-31 23:59:59"),
+ assertEquals(LocalDateTime.parse("2020-12-31T23:59:59"),
eval("TIMESTAMP '2021-01-01 00:00:00' - INTERVAL 1 SECOND"));
- assertEquals(Timestamp.valueOf("2020-12-31 23:59:59"),
+ assertEquals(LocalDateTime.parse("2020-12-31T23:59:59"),
eval("TIMESTAMP '2021-01-01 00:00:00' + INTERVAL -1 SECOND"));
- assertEquals(Timestamp.valueOf("2021-01-01 00:01:00"),
+ assertEquals(LocalDateTime.parse("2021-01-01T00:01:00"),
eval("TIMESTAMP '2021-01-01 00:00:00' + INTERVAL 1 MINUTE"));
- assertEquals(Timestamp.valueOf("2021-01-01 01:00:00"),
+ assertEquals(LocalDateTime.parse("2021-01-01T01:00:00"),
eval("TIMESTAMP '2021-01-01 00:00:00' + INTERVAL 1 HOUR"));
- assertEquals(Timestamp.valueOf("2021-01-02 00:00:00"),
+ assertEquals(LocalDateTime.parse("2021-01-02T00:00:00"),
eval("TIMESTAMP '2021-01-01 00:00:00' + INTERVAL 1 DAY"));
- assertEquals(Timestamp.valueOf("2021-02-01 00:00:00"),
+ assertEquals(LocalDateTime.parse("2021-02-01T00:00:00"),
eval("TIMESTAMP '2021-01-01 00:00:00' + INTERVAL 1 MONTH"));
- assertEquals(Timestamp.valueOf("2022-01-01 00:00:00"),
+ assertEquals(LocalDateTime.parse("2022-01-01T00:00:00"),
eval("TIMESTAMP '2021-01-01 00:00:00' + INTERVAL 1 YEAR"));
- assertEquals(Timestamp.valueOf("2021-01-02 01:01:01.123"),
+ assertEquals(LocalDateTime.parse("2021-01-02T01:01:01.123"),
eval("TIMESTAMP '2021-01-01 00:00:00' + INTERVAL '1 1:1:1.123' DAY TO SECOND"));
- assertEquals(Timestamp.valueOf("2022-02-01 01:01:01.123"),
+ assertEquals(LocalDateTime.parse("2022-02-01T01:01:01.123"),
eval("TIMESTAMP '2021-01-01 01:01:01.123' + INTERVAL '1-1' YEAR TO MONTH"));
// Time +/- interval.
- assertEquals(Time.valueOf("00:00:01"), eval("TIME '00:00:00' + INTERVAL 1 SECOND"));
- assertEquals(Time.valueOf("00:01:00"), eval("TIME '00:00:00' + INTERVAL 1 MINUTE"));
- assertEquals(Time.valueOf("01:00:00"), eval("TIME '00:00:00' + INTERVAL 1 HOUR"));
+ assertEquals(LocalTime.parse("00:00:01"), eval("TIME '00:00:00' + INTERVAL 1 SECOND"));
+ assertEquals(LocalTime.parse("00:01:00"), eval("TIME '00:00:00' + INTERVAL 1 MINUTE"));
+ assertEquals(LocalTime.parse("01:00:00"), eval("TIME '00:00:00' + INTERVAL 1 HOUR"));
// Date - date as interval.
assertEquals(Duration.ofDays(1), eval("(DATE '2021-01-02' - DATE '2021-01-01') DAYS"));
diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItSortAggregateTest.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItSortAggregateTest.java
index 4ac7024..db305c5 100644
--- a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItSortAggregateTest.java
+++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItSortAggregateTest.java
@@ -119,10 +119,10 @@ public class ItSortAggregateTest extends AbstractBasicIntegrationTest {
assertEquals(ROWS / 10, res.size());
res.forEach(r -> {
- Integer s0 = (Integer) r.get(0);
- Integer s1 = (Integer) r.get(1);
+ long s0 = (Long) r.get(0);
+ long s1 = (Long) r.get(1);
- assertEquals(s0 * 2, (int) s1);
+ assertEquals(s0 * 2, s1);
});
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/ExecutionContext.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/ExecutionContext.java
index 2acf658..0cb7b48 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/ExecutionContext.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/ExecutionContext.java
@@ -237,9 +237,6 @@ public class ExecutionContext<RowT> extends AbstractQueryContext implements Data
if (Variable.CANCEL_FLAG.camelName.equals(name)) {
return cancelFlag;
}
- if (Variable.TIME_ZONE.camelName.equals(name)) {
- return TIME_ZONE; // TODO DistributedSqlConfiguration#timeZone
- }
if (Variable.CURRENT_TIMESTAMP.camelName.equals(name)) {
return startTs;
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/agg/Accumulators.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/agg/Accumulators.java
index 1a925c3..ad9a159 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/agg/Accumulators.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/agg/Accumulators.java
@@ -98,31 +98,37 @@ public class Accumulators {
private static Supplier<Accumulator> sumFactory(AggregateCall call) {
switch (call.type.getSqlTypeName()) {
+ case BIGINT:
+ case DECIMAL:
+ return () -> new Sum(new DecimalSumEmptyIsZero());
+
case DOUBLE:
case REAL:
case FLOAT:
- return DoubleSum.FACTORY;
- case DECIMAL:
- return DecimalSum.FACTORY;
+ return () -> new Sum(new DoubleSumEmptyIsZero());
+
+ case TINYINT:
+ case SMALLINT:
case INTEGER:
- return IntSum.FACTORY;
- case BIGINT:
default:
- return LongSum.FACTORY;
+ return () -> new Sum(new LongSumEmptyIsZero());
}
}
private static Supplier<Accumulator> sumEmptyIsZeroFactory(AggregateCall call) {
switch (call.type.getSqlTypeName()) {
+ case BIGINT:
+ case DECIMAL:
+ return DecimalSumEmptyIsZero.FACTORY;
+
case DOUBLE:
case REAL:
case FLOAT:
return DoubleSumEmptyIsZero.FACTORY;
- case DECIMAL:
- return DecimalSumEmptyIsZero.FACTORY;
+
+ case TINYINT:
+ case SMALLINT:
case INTEGER:
- return IntSumEmptyIsZero.FACTORY;
- case BIGINT:
default:
return LongSumEmptyIsZero.FACTORY;
}
@@ -392,207 +398,50 @@ public class Accumulators {
}
}
- private static class DoubleSum implements Accumulator {
- public static final Supplier<Accumulator> FACTORY = DoubleSum::new;
-
- private double sum;
+ private static class Sum implements Accumulator {
+ private Accumulator acc;
private boolean empty = true;
- /** {@inheritDoc} */
- @Override
- public void add(Object... args) {
- Double in = (Double) args[0];
-
- if (in == null) {
- return;
- }
-
- empty = false;
- sum += in;
- }
-
- /** {@inheritDoc} */
- @Override
- public void apply(Accumulator other) {
- DoubleSum other0 = (DoubleSum) other;
-
- if (other0.empty) {
- return;
- }
-
- empty = false;
- sum += other0.sum;
- }
-
- /** {@inheritDoc} */
- @Override
- public Object end() {
- return empty ? null : sum;
- }
-
- /** {@inheritDoc} */
- @Override
- public List<RelDataType> argumentTypes(IgniteTypeFactory typeFactory) {
- return List.of(typeFactory.createTypeWithNullability(typeFactory.createSqlType(DOUBLE), true));
- }
-
- /** {@inheritDoc} */
- @Override
- public RelDataType returnType(IgniteTypeFactory typeFactory) {
- return typeFactory.createTypeWithNullability(typeFactory.createSqlType(DOUBLE), true);
- }
- }
-
- private static class IntSum implements Accumulator {
- public static final Supplier<Accumulator> FACTORY = IntSum::new;
-
- private int sum;
-
- private boolean empty = true;
-
- /** {@inheritDoc} */
- @Override
- public void add(Object... args) {
- Integer in = (Integer) args[0];
-
- if (in == null) {
- return;
- }
-
- empty = false;
- sum += in;
- }
-
- /** {@inheritDoc} */
- @Override
- public void apply(Accumulator other) {
- IntSum other0 = (IntSum) other;
-
- if (other0.empty) {
- return;
- }
-
- empty = false;
- sum += other0.sum;
- }
-
- /** {@inheritDoc} */
- @Override
- public Object end() {
- return empty ? null : sum;
- }
-
- /** {@inheritDoc} */
- @Override
- public List<RelDataType> argumentTypes(IgniteTypeFactory typeFactory) {
- return List.of(typeFactory.createTypeWithNullability(typeFactory.createSqlType(INTEGER), true));
- }
-
- /** {@inheritDoc} */
- @Override
- public RelDataType returnType(IgniteTypeFactory typeFactory) {
- return typeFactory.createTypeWithNullability(typeFactory.createSqlType(INTEGER), true);
+ public Sum(Accumulator acc) {
+ this.acc = acc;
}
- }
-
- private static class LongSum implements Accumulator {
- public static final Supplier<Accumulator> FACTORY = LongSum::new;
-
- private long sum;
-
- private boolean empty = true;
/** {@inheritDoc} */
- @Override
- public void add(Object... args) {
- Long in = (Long) args[0];
-
- if (in == null) {
+ @Override public void add(Object... args) {
+ if (args[0] == null) {
return;
}
empty = false;
- sum += in;
+ acc.add(args[0]);
}
/** {@inheritDoc} */
- @Override
- public void apply(Accumulator other) {
- LongSum other0 = (LongSum) other;
+ @Override public void apply(Accumulator other) {
+ Sum other0 = (Sum) other;
if (other0.empty) {
return;
}
empty = false;
- sum += other0.sum;
+ acc.apply(other0.acc);
}
/** {@inheritDoc} */
- @Override
- public Object end() {
- return empty ? null : sum;
+ @Override public Object end() {
+ return empty ? null : acc.end();
}
/** {@inheritDoc} */
- @Override
- public List<RelDataType> argumentTypes(IgniteTypeFactory typeFactory) {
- return List.of(typeFactory.createTypeWithNullability(typeFactory.createSqlType(BIGINT), true));
- }
-
- /** {@inheritDoc} */
- @Override
- public RelDataType returnType(IgniteTypeFactory typeFactory) {
- return typeFactory.createTypeWithNullability(typeFactory.createSqlType(BIGINT), true);
- }
- }
-
- private static class DecimalSum implements Accumulator {
- public static final Supplier<Accumulator> FACTORY = DecimalSum::new;
-
- private BigDecimal sum;
-
- /** {@inheritDoc} */
- @Override
- public void add(Object... args) {
- BigDecimal in = (BigDecimal) args[0];
-
- if (in == null) {
- return;
- }
-
- sum = sum == null ? in : sum.add(in);
- }
-
- /** {@inheritDoc} */
- @Override
- public void apply(Accumulator other) {
- DecimalSum other0 = (DecimalSum) other;
-
- if (other0.sum == null) {
- return;
- }
-
- sum = sum == null ? other0.sum : sum.add(other0.sum);
- }
-
- /** {@inheritDoc} */
- @Override
- public Object end() {
- return sum;
- }
-
- /** {@inheritDoc} */
- @Override
- public List<RelDataType> argumentTypes(IgniteTypeFactory typeFactory) {
- return List.of(typeFactory.createTypeWithNullability(typeFactory.createSqlType(DECIMAL), true));
+ @Override public List<RelDataType> argumentTypes(IgniteTypeFactory typeFactory) {
+ return acc.argumentTypes(typeFactory);
}
/** {@inheritDoc} */
- @Override
- public RelDataType returnType(IgniteTypeFactory typeFactory) {
- return typeFactory.createTypeWithNullability(typeFactory.createSqlType(DECIMAL), true);
+ @Override public RelDataType returnType(IgniteTypeFactory typeFactory) {
+ return acc.returnType(typeFactory);
}
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/agg/IgniteSortAggregateBase.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/agg/IgniteSortAggregateBase.java
index 772cf61..19b227d 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/agg/IgniteSortAggregateBase.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rel/agg/IgniteSortAggregateBase.java
@@ -19,8 +19,8 @@ package org.apache.ignite.internal.sql.engine.rel.agg;
import static org.apache.ignite.internal.sql.engine.util.Commons.maxPrefix;
-import com.google.common.collect.ImmutableList;
import it.unimi.dsi.fastutil.ints.IntList;
+import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.calcite.plan.RelTraitSet;
@@ -28,7 +28,6 @@ import org.apache.calcite.rel.RelCollation;
import org.apache.calcite.rel.RelCollations;
import org.apache.calcite.rel.RelFieldCollation;
import org.apache.calcite.util.ImmutableBitSet;
-import org.apache.calcite.util.ImmutableIntList;
import org.apache.calcite.util.Pair;
import org.apache.ignite.internal.sql.engine.trait.TraitUtils;
import org.apache.ignite.internal.sql.engine.trait.TraitsAwareIgniteRel;
@@ -50,7 +49,22 @@ interface IgniteSortAggregateBase extends TraitsAwareIgniteRel {
default Pair<RelTraitSet, List<RelTraitSet>> passThroughCollation(
RelTraitSet nodeTraits, List<RelTraitSet> inputTraits
) {
- RelCollation collation = RelCollations.of(ImmutableIntList.copyOf(getGroupSet().asList()));
+ RelCollation required = TraitUtils.collation(nodeTraits);
+ ImmutableBitSet requiredKeys = ImmutableBitSet.of(required.getKeys());
+ RelCollation collation;
+
+ if (getGroupSet().contains(requiredKeys)) {
+ List<RelFieldCollation> newCollationFields = new ArrayList<>(getGroupSet().cardinality());
+ newCollationFields.addAll(required.getFieldCollations());
+
+ ImmutableBitSet keysLeft = getGroupSet().except(requiredKeys);
+
+ keysLeft.forEach(fieldIdx -> newCollationFields.add(TraitUtils.createFieldCollation(fieldIdx)));
+
+ collation = RelCollations.of(newCollationFields);
+ } else {
+ collation = TraitUtils.createCollation(getGroupSet().toList());
+ }
return Pair.of(nodeTraits.replace(collation),
List.of(inputTraits.get(0).replace(collation)));
@@ -66,13 +80,13 @@ interface IgniteSortAggregateBase extends TraitsAwareIgniteRel {
IntList newCollationColls = maxPrefix(inputCollation.getKeys(), getGroupSet().asSet());
if (newCollationColls.size() < getGroupSet().cardinality()) {
- return ImmutableList.of();
+ return List.of();
}
List<RelFieldCollation> suitableCollations = inputCollation.getFieldCollations()
.stream().filter(k -> newCollationColls.contains(k.getFieldIndex())).collect(Collectors.toList());
- return ImmutableList.of(Pair.of(
+ return List.of(Pair.of(
nodeTraits.replace(RelCollations.of(suitableCollations)),
inputTraits
));
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rule/FilterSpoolMergeToSortedIndexSpoolRule.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rule/FilterSpoolMergeToSortedIndexSpoolRule.java
index 6339e23..668e984 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rule/FilterSpoolMergeToSortedIndexSpoolRule.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rule/FilterSpoolMergeToSortedIndexSpoolRule.java
@@ -19,15 +19,23 @@ package org.apache.ignite.internal.sql.engine.rule;
import static org.apache.ignite.internal.util.CollectionUtils.nullOrEmpty;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
import org.apache.calcite.plan.RelOptCluster;
import org.apache.calcite.plan.RelOptRule;
import org.apache.calcite.plan.RelOptRuleCall;
import org.apache.calcite.plan.RelRule;
import org.apache.calcite.plan.RelTraitSet;
import org.apache.calcite.rel.RelCollation;
+import org.apache.calcite.rel.RelCollations;
+import org.apache.calcite.rel.RelFieldCollation;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.core.Filter;
import org.apache.calcite.rel.core.Spool;
+import org.apache.calcite.rex.RexNode;
import org.apache.ignite.internal.sql.engine.rel.IgniteFilter;
import org.apache.ignite.internal.sql.engine.rel.IgniteSortedIndexSpool;
import org.apache.ignite.internal.sql.engine.rel.IgniteTableSpool;
@@ -66,9 +74,11 @@ public class FilterSpoolMergeToSortedIndexSpoolRule extends RelRule<FilterSpoolM
RelNode input = spool.getInput();
+ RelCollation inCollation = TraitUtils.collation(input);
+
IndexConditions idxCond = RexUtils.buildSortedIndexConditions(
cluster,
- TraitUtils.collation(input),
+ inCollation,
filter.getCondition(),
spool.getRowType(),
null
@@ -78,13 +88,54 @@ public class FilterSpoolMergeToSortedIndexSpoolRule extends RelRule<FilterSpoolM
return;
}
- RelCollation collation = TraitUtils.createCollation(idxCond.keys());
+ RelCollation traitCollation;
+ RelCollation searchCollation;
+
+ if (inCollation == null || inCollation.isDefault()) {
+ // Create collation by index condition.
+ List<RexNode> lowerBound = idxCond.lowerBound();
+ List<RexNode> upperBound = idxCond.upperBound();
+
+ assert lowerBound == null || upperBound == null || lowerBound.size() == upperBound.size();
+
+ int cardinality = lowerBound != null ? lowerBound.size() : upperBound.size();
+
+ List<Integer> equalsFields = new ArrayList<>(cardinality);
+ List<Integer> otherFields = new ArrayList<>(cardinality);
+
+ // First, add all equality filters to collation, then add other fields.
+ for (int i = 0; i < cardinality; i++) {
+ RexNode lowerNode = lowerBound != null ? lowerBound.get(i) : null;
+ RexNode upperNode = upperBound != null ? upperBound.get(i) : null;
+
+ if (RexUtils.isNotNull(lowerNode) || RexUtils.isNotNull(upperNode)) {
+ (Objects.equals(lowerNode, upperNode) ? equalsFields : otherFields).add(i);
+ }
+ }
+
+ equalsFields.addAll(otherFields);
+
+ searchCollation = traitCollation = TraitUtils.createCollation(equalsFields);
+ } else {
+ // Create search collation as a prefix of input collation.
+ traitCollation = inCollation;
+
+ Set<Integer> searchKeys = idxCond.keys();
+
+ List<RelFieldCollation> collationFields = inCollation.getFieldCollations().subList(0, searchKeys.size());
+
+ assert searchKeys.containsAll(collationFields.stream().map(RelFieldCollation::getFieldIndex)
+ .collect(Collectors.toSet())) : "Search condition should be a prefix of collation [searchKeys="
+ + searchKeys + ", collation=" + inCollation + ']';
+
+ searchCollation = RelCollations.of(collationFields);
+ }
RelNode res = new IgniteSortedIndexSpool(
cluster,
- trait.replace(collation),
- convert(input, input.getTraitSet().replace(collation)),
- collation,
+ trait.replace(traitCollation),
+ convert(input, input.getTraitSet().replace(traitCollation)),
+ searchCollation,
filter.getCondition(),
idxCond
);
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rule/SortAggregateConverterRule.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rule/SortAggregateConverterRule.java
index 31dbe73..33e6bd8 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rule/SortAggregateConverterRule.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rule/SortAggregateConverterRule.java
@@ -25,16 +25,15 @@ import org.apache.calcite.plan.RelOptRule;
import org.apache.calcite.plan.RelTraitSet;
import org.apache.calcite.rel.PhysicalNode;
import org.apache.calcite.rel.RelCollation;
-import org.apache.calcite.rel.RelCollations;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.logical.LogicalAggregate;
import org.apache.calcite.rel.metadata.RelMetadataQuery;
-import org.apache.calcite.util.ImmutableIntList;
import org.apache.ignite.internal.sql.engine.rel.IgniteConvention;
import org.apache.ignite.internal.sql.engine.rel.agg.IgniteMapSortAggregate;
import org.apache.ignite.internal.sql.engine.rel.agg.IgniteReduceSortAggregate;
import org.apache.ignite.internal.sql.engine.rel.agg.IgniteSingleSortAggregate;
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.util.HintUtils;
/**
@@ -71,7 +70,7 @@ public class SortAggregateConverterRule {
RelOptCluster cluster = agg.getCluster();
RelNode input = agg.getInput();
- RelCollation collation = RelCollations.of(ImmutableIntList.copyOf(agg.getGroupSet().asList()));
+ RelCollation collation = TraitUtils.createCollation(agg.getGroupSet().asList());
RelTraitSet inTrait = cluster.traitSetOf(IgniteConvention.INSTANCE)
.replace(collation)
@@ -113,7 +112,7 @@ public class SortAggregateConverterRule {
RelOptCluster cluster = agg.getCluster();
RelNode input = agg.getInput();
- RelCollation collation = RelCollations.of(ImmutableIntList.copyOf(agg.getGroupSet().asList()));
+ RelCollation collation = TraitUtils.createCollation(agg.getGroupSet().asList());
RelTraitSet inTrait = cluster.traitSetOf(IgniteConvention.INSTANCE).replace(collation);
RelTraitSet outTrait = cluster.traitSetOf(IgniteConvention.INSTANCE).replace(collation);
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/trait/TraitUtils.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/trait/TraitUtils.java
index a3d8026..a51fc24 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/trait/TraitUtils.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/trait/TraitUtils.java
@@ -28,9 +28,9 @@ import static org.apache.ignite.internal.util.CollectionUtils.first;
import static org.apache.ignite.internal.util.CollectionUtils.nullOrEmpty;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
-import it.unimi.dsi.fastutil.ints.IntSet;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
@@ -471,13 +471,29 @@ public class TraitUtils {
* @param keys The keys to create collation from.
* @return New collation.
*/
- public static RelCollation createCollation(IntSet keys) {
+ public static RelCollation createCollation(Collection<Integer> keys) {
return RelCollations.of(
- keys.intStream().mapToObj(RelFieldCollation::new).collect(Collectors.toList())
+ keys.stream().map(TraitUtils::createFieldCollation).collect(Collectors.toList())
);
}
/**
+ * Creates field collation with default direction and nulls ordering.
+ */
+ public static RelFieldCollation createFieldCollation(int fieldIdx) {
+ return createFieldCollation(fieldIdx, true);
+ }
+
+ /**
+ * Creates field collation with default nulls ordering.
+ */
+ public static RelFieldCollation createFieldCollation(int fieldIdx, boolean asc) {
+ return asc
+ ? new RelFieldCollation(fieldIdx, RelFieldCollation.Direction.ASCENDING, RelFieldCollation.NullDirection.FIRST)
+ : new RelFieldCollation(fieldIdx, RelFieldCollation.Direction.DESCENDING, RelFieldCollation.NullDirection.LAST);
+ }
+
+ /**
* Creates mapping from provided projects that maps a source column idx to idx in a row after applying projections.
*
* @param inputFieldCount Size of a source row.
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/type/IgniteTypeFactory.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/type/IgniteTypeFactory.java
index a6df9bc..d9c0da3 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/type/IgniteTypeFactory.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/type/IgniteTypeFactory.java
@@ -25,8 +25,8 @@ import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
-import java.sql.Timestamp;
import java.time.Duration;
+import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Period;
@@ -204,15 +204,14 @@ public class IgniteTypeFactory extends JavaTypeFactoryImpl {
case CHAR:
return String.class;
case DATE:
- return java.sql.Date.class;
+ return LocalDate.class;
case TIME:
- return java.sql.Time.class;
- case TIMESTAMP:
- return Timestamp.class;
- case TIME_WITH_LOCAL_TIME_ZONE:
return LocalTime.class;
+ case TIMESTAMP:
case TIMESTAMP_WITH_LOCAL_TIME_ZONE:
return LocalDateTime.class;
+ case TIME_WITH_LOCAL_TIME_ZONE:
+ return LocalTime.class;
case INTEGER:
return type.isNullable() ? Integer.class : int.class;
case INTERVAL_YEAR:
@@ -310,7 +309,8 @@ public class IgniteTypeFactory extends JavaTypeFactoryImpl {
/** {@inheritDoc} */
@Override public RelDataType createType(Type type) {
- if (type == Duration.class || type == Period.class) {
+ if (type == Duration.class || type == Period.class || type == LocalDate.class || type == LocalDateTime.class
+ || type == LocalTime.class) {
return createJavaType((Class<?>) type);
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/type/IgniteTypeSystem.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/type/IgniteTypeSystem.java
index 9a7d619..f65f74a 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/type/IgniteTypeSystem.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/type/IgniteTypeSystem.java
@@ -18,8 +18,13 @@
package org.apache.ignite.internal.sql.engine.type;
import java.io.Serializable;
+import java.math.BigDecimal;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.rel.type.RelDataTypeSystem;
import org.apache.calcite.rel.type.RelDataTypeSystemImpl;
+import org.apache.calcite.sql.type.BasicSqlType;
+import org.apache.calcite.sql.type.SqlTypeName;
/**
* Ignite type system.
@@ -38,4 +43,63 @@ public class IgniteTypeSystem extends RelDataTypeSystemImpl implements Serializa
public int getMaxNumericPrecision() {
return Short.MAX_VALUE;
}
+
+ /** {@inheritDoc} */
+ @Override
+ public RelDataType deriveSumType(RelDataTypeFactory typeFactory, RelDataType argumentType) {
+ RelDataType sumType;
+ if (argumentType instanceof BasicSqlType) {
+ switch (argumentType.getSqlTypeName()) {
+ case INTEGER:
+ case TINYINT:
+ case SMALLINT:
+ sumType = typeFactory.createSqlType(SqlTypeName.BIGINT);
+
+ break;
+
+ case BIGINT:
+ case DECIMAL:
+ sumType = typeFactory.createSqlType(SqlTypeName.DECIMAL);
+
+ break;
+
+ case REAL:
+ case FLOAT:
+ case DOUBLE:
+ sumType = typeFactory.createSqlType(SqlTypeName.DOUBLE);
+
+ break;
+
+ default:
+ return super.deriveSumType(typeFactory, argumentType);
+ }
+ } else {
+ switch (argumentType.getSqlTypeName()) {
+ case INTEGER:
+ case TINYINT:
+ case SMALLINT:
+ sumType = typeFactory.createJavaType(Long.class);
+
+ break;
+
+ case BIGINT:
+ case DECIMAL:
+ sumType = typeFactory.createJavaType(BigDecimal.class);
+
+ break;
+
+ case REAL:
+ case FLOAT:
+ case DOUBLE:
+ sumType = typeFactory.createJavaType(Double.class);
+
+ break;
+
+ default:
+ return super.deriveSumType(typeFactory, argumentType);
+ }
+ }
+
+ return typeFactory.createTypeWithNullability(sumType, argumentType.isNullable());
+ }
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/RexUtils.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/RexUtils.java
index 50e5a54..8fb3d3d 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/RexUtils.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/RexUtils.java
@@ -41,7 +41,6 @@ import org.apache.calcite.plan.RelOptCluster;
import org.apache.calcite.plan.RelOptPredicateList;
import org.apache.calcite.plan.RelOptUtil;
import org.apache.calcite.rel.RelCollation;
-import org.apache.calcite.rel.RelCollations;
import org.apache.calcite.rel.RelFieldCollation;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.core.CorrelationId;
@@ -69,11 +68,11 @@ import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.calcite.util.ControlFlowException;
import org.apache.calcite.util.ImmutableBitSet;
-import org.apache.calcite.util.ImmutableIntList;
import org.apache.calcite.util.Litmus;
import org.apache.calcite.util.Util;
import org.apache.calcite.util.mapping.MappingType;
import org.apache.calcite.util.mapping.Mappings;
+import org.apache.ignite.internal.sql.engine.trait.TraitUtils;
import org.apache.ignite.internal.util.IgniteUtils;
import org.jetbrains.annotations.Nullable;
@@ -214,7 +213,16 @@ public class RexUtils {
// Force collation for all fields of the condition.
if (collation == null || collation.isDefault()) {
- collation = RelCollations.of(ImmutableIntList.of(fieldsToPredicates.keySet().toIntArray()));
+ List<Integer> equalsFields = new ArrayList<>(fieldsToPredicates.size());
+ List<Integer> otherFields = new ArrayList<>(fieldsToPredicates.size());
+
+ // It's more effective to put equality conditions in the collation first.
+ fieldsToPredicates.forEach((idx, conds) ->
+ (conds.stream().allMatch(call -> call.getOperator().getKind() == EQUALS) ? equalsFields : otherFields).add(idx));
+
+ equalsFields.addAll(otherFields);
+
+ collation = TraitUtils.createCollation(equalsFields);
}
for (int i = 0; i < collation.getFieldCollations().size(); i++) {
@@ -278,11 +286,6 @@ public class RexUtils {
break; // No bounds, so break the loop.
}
- if (i > 0 && bestLower != bestUpper) {
- // Go behind the first index field only in the case of multiple "=" conditions on index fields.
- break; // TODO https://issues.apache.org/jira/browse/IGNITE-13568
- }
-
if (bestLower != null && bestUpper != null) { // "x>5 AND x<10"
upper.add(bestUpper);
lower.add(bestLower);
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/TypeUtils.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/TypeUtils.java
index 10b2217..8062e76 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/TypeUtils.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/TypeUtils.java
@@ -25,17 +25,21 @@ import static org.apache.ignite.internal.util.CollectionUtils.nullOrEmpty;
import java.lang.reflect.Type;
import java.sql.Timestamp;
import java.time.Duration;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
import java.time.Period;
+import java.time.ZoneOffset;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
-import java.util.TimeZone;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.apache.calcite.DataContext;
+import org.apache.calcite.avatica.util.ByteString;
import org.apache.calcite.avatica.util.DateTimeUtils;
import org.apache.calcite.plan.RelOptSchema;
import org.apache.calcite.plan.RelOptTable;
@@ -64,10 +68,10 @@ import org.jetbrains.annotations.Nullable;
*/
public class TypeUtils {
private static final Set<Type> CONVERTABLE_TYPES = Set.of(
- java.util.Date.class,
- java.sql.Date.class,
- java.sql.Time.class,
- java.sql.Timestamp.class,
+ LocalDate.class,
+ LocalDateTime.class,
+ LocalTime.class,
+ Timestamp.class,
Duration.class,
Period.class
);
@@ -337,19 +341,18 @@ public class TypeUtils {
public static Object fromInternal(ExecutionContext<?> ectx, Object val, Type storageType) {
if (val == null) {
return null;
- } else if (storageType == java.sql.Date.class && val instanceof Integer) {
- final long t = (Integer) val * DateTimeUtils.MILLIS_PER_DAY;
- return new java.sql.Date(t - DataContext.Variable.TIME_ZONE.<TimeZone>get(ectx).getOffset(t));
- } else if (storageType == java.sql.Time.class && val instanceof Integer) {
- return new java.sql.Time((Integer) val - DataContext.Variable.TIME_ZONE.<TimeZone>get(ectx).getOffset((Integer) val));
- } else if (storageType == Timestamp.class && val instanceof Long) {
- return new Timestamp((Long) val - DataContext.Variable.TIME_ZONE.<TimeZone>get(ectx).getOffset((Long) val));
- } else if (storageType == java.util.Date.class && val instanceof Long) {
- return new java.util.Date((Long) val - DataContext.Variable.TIME_ZONE.<TimeZone>get(ectx).getOffset((Long) val));
+ } else if (storageType == LocalDate.class && val instanceof Integer) {
+ return LocalDate.ofEpochDay((Integer) val);
+ } else if (storageType == LocalTime.class && val instanceof Integer) {
+ return LocalTime.ofSecondOfDay((Integer) val / 1000);
+ } else if (storageType == LocalDateTime.class && (val instanceof Long)) {
+ return LocalDateTime.ofEpochSecond((Long) val / 1000, (int) ((Long) val % 1000) * 1000 * 1000, ZoneOffset.UTC);
} else if (storageType == Duration.class && val instanceof Long) {
return Duration.ofMillis((Long) val);
} else if (storageType == Period.class && val instanceof Integer) {
return Period.of((Integer) val / 12, (Integer) val % 12, 0);
+ } else if (storageType == byte[].class && val instanceof ByteString) {
+ return ((ByteString) val).getBytes();
} else {
return val;
}
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/BaseAggregateTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/BaseAggregateTest.java
index 91f339d..b771437 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/BaseAggregateTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/BaseAggregateTest.java
@@ -26,6 +26,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet;
+import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.function.Supplier;
@@ -511,6 +512,101 @@ public abstract class BaseAggregateTest extends AbstractExecutionTest {
}
}
+ @ParameterizedTest
+ @EnumSource
+ public void sumIntegerOverflow(TestAggregateType testAgg) {
+ ExecutionContext<Object[]> ctx = executionContext();
+ IgniteTypeFactory tf = ctx.getTypeFactory();
+ RelDataType rowType = TypeUtils.createRowType(tf, int.class, int.class);
+ ScanNode<Object[]> scan = new ScanNode<>(ctx, rowType, Arrays.asList(
+ row(0, Integer.MAX_VALUE / 2),
+ row(0, Integer.MAX_VALUE / 2 + 11)
+ ));
+
+ AggregateCall call = AggregateCall.create(
+ SqlStdOperatorTable.SUM,
+ false,
+ false,
+ false,
+ ImmutableIntList.of(1),
+ -1,
+ null,
+ RelCollations.EMPTY,
+ tf.createJavaType(Long.class),
+ null);
+
+ List<ImmutableBitSet> grpSets = List.of(ImmutableBitSet.of(0));
+
+ RelDataType aggRowType = TypeUtils.createRowType(tf, int.class);
+
+ SingleNode<Object[]> aggChain = createAggregateNodesChain(
+ testAgg,
+ ctx,
+ grpSets,
+ call,
+ rowType,
+ aggRowType,
+ rowFactory(),
+ scan
+ );
+
+ RootNode<Object[]> root = new RootNode<>(ctx, aggRowType);
+ root.register(aggChain);
+
+ assertTrue(root.hasNext());
+
+ assertArrayEquals(row(0, (long) Integer.MAX_VALUE / 2 + (long) Integer.MAX_VALUE / 2 + 11L), root.next());
+
+ assertFalse(root.hasNext());
+ }
+
+ @ParameterizedTest
+ @EnumSource
+ public void sumLongOverflow(TestAggregateType testAgg) {
+ ExecutionContext<Object[]> ctx = executionContext();
+ IgniteTypeFactory tf = ctx.getTypeFactory();
+ RelDataType rowType = TypeUtils.createRowType(tf, int.class, long.class);
+ ScanNode<Object[]> scan = new ScanNode<>(ctx, rowType, Arrays.asList(
+ row(0, Long.MAX_VALUE / 2),
+ row(0, Long.MAX_VALUE / 2 + 11)
+ ));
+
+ AggregateCall call = AggregateCall.create(
+ SqlStdOperatorTable.SUM,
+ false,
+ false,
+ false,
+ ImmutableIntList.of(1),
+ -1,
+ RelCollations.EMPTY,
+ tf.createJavaType(BigDecimal.class),
+ null);
+
+ List<ImmutableBitSet> grpSets = List.of(ImmutableBitSet.of(0));
+
+ RelDataType aggRowType = TypeUtils.createRowType(tf, int.class);
+
+ SingleNode<Object[]> aggChain = createAggregateNodesChain(
+ testAgg,
+ ctx,
+ grpSets,
+ call,
+ rowType,
+ aggRowType,
+ rowFactory(),
+ scan
+ );
+
+ RootNode<Object[]> root = new RootNode<>(ctx, aggRowType);
+ root.register(aggChain);
+
+ assertTrue(root.hasNext());
+
+ assertArrayEquals(row(0, new BigDecimal(Long.MAX_VALUE).add(new BigDecimal(10))), root.next());
+
+ assertFalse(root.hasNext());
+ }
+
protected SingleNode<Object[]> createAggregateNodesChain(
TestAggregateType testAgg,
ExecutionContext<Object[]> ctx,
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/AbstractPlannerTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/AbstractPlannerTest.java
index 08da3d0..72228a5 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/AbstractPlannerTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/AbstractPlannerTest.java
@@ -84,6 +84,7 @@ import org.apache.ignite.internal.sql.engine.prepare.MappingQueryContext;
import org.apache.ignite.internal.sql.engine.prepare.PlannerHelper;
import org.apache.ignite.internal.sql.engine.prepare.PlanningContext;
import org.apache.ignite.internal.sql.engine.prepare.Splitter;
+import org.apache.ignite.internal.sql.engine.rel.IgniteIndexScan;
import org.apache.ignite.internal.sql.engine.rel.IgniteRel;
import org.apache.ignite.internal.sql.engine.rel.IgniteTableScan;
import org.apache.ignite.internal.sql.engine.rel.logical.IgniteLogicalIndexScan;
@@ -97,6 +98,7 @@ import org.apache.ignite.internal.sql.engine.schema.ModifyRow;
import org.apache.ignite.internal.sql.engine.schema.SqlSchemaManager;
import org.apache.ignite.internal.sql.engine.schema.TableDescriptor;
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.type.IgniteTypeFactory;
import org.apache.ignite.internal.sql.engine.type.IgniteTypeSystem;
import org.apache.ignite.internal.sql.engine.util.BaseQueryContext;
@@ -549,6 +551,30 @@ public abstract class AbstractPlannerTest extends IgniteAbstractTest {
}
}
+ /**
+ * Predicate builder for "Index scan with given name" condition.
+ */
+ protected <T extends RelNode> Predicate<IgniteIndexScan> isIndexScan(String tableName, String idxName) {
+ return isInstanceOf(IgniteIndexScan.class).and(
+ n -> {
+ String scanTableName = Util.last(n.getTable().getQualifiedName());
+
+ if (!tableName.equalsIgnoreCase(scanTableName)) {
+ lastErrorMsg = "Unexpected table name [exp=" + tableName + ", act=" + scanTableName + ']';
+
+ return false;
+ }
+
+ if (!idxName.equals(n.indexName())) {
+ lastErrorMsg = "Unexpected index name [exp=" + idxName + ", act=" + n.indexName() + ']';
+
+ return false;
+ }
+
+ return true;
+ });
+ }
+
protected void clearTraits(RelNode rel) {
IgniteTestUtils.setFieldValue(rel, AbstractRelNode.class, "traitSet", RelTraitSet.createEmpty());
rel.getInputs().forEach(this::clearTraits);
@@ -745,6 +771,12 @@ public abstract class AbstractPlannerTest extends IgniteAbstractTest {
return this;
}
+ public TestTable addIndex(String name, int... keys) {
+ addIndex(TraitUtils.createCollation(Arrays.stream(keys).boxed().collect(Collectors.toList())), name);
+
+ return this;
+ }
+
/** {@inheritDoc} */
@Override
public IgniteIndex getIndex(String idxName) {
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/AggregateDistinctPlannerTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/AggregateDistinctPlannerTest.java
index 255d553..b209438 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/AggregateDistinctPlannerTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/AggregateDistinctPlannerTest.java
@@ -22,9 +22,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.apache.calcite.plan.RelOptUtil;
-import org.apache.calcite.rel.RelCollations;
import org.apache.calcite.sql.SqlExplainLevel;
-import org.apache.calcite.util.ImmutableIntList;
import org.apache.ignite.internal.sql.engine.rel.IgniteAggregate;
import org.apache.ignite.internal.sql.engine.rel.IgniteIndexScan;
import org.apache.ignite.internal.sql.engine.rel.IgniteRel;
@@ -55,7 +53,7 @@ public class AggregateDistinctPlannerTest extends AbstractAggregatePlannerTest {
@ParameterizedTest
@EnumSource
public void mapReduceDistinctWithIndex(AggregateAlgorithm algo) throws Exception {
- TestTable tbl = createAffinityTable().addIndex(RelCollations.of(ImmutableIntList.of(1, 2)), "val0_val1");
+ TestTable tbl = createAffinityTable().addIndex("val0_val1", 1, 2);
IgniteSchema publicSchema = new IgniteSchema("PUBLIC");
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/AggregatePlannerTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/AggregatePlannerTest.java
index 6767d58..617bd77 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/AggregatePlannerTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/AggregatePlannerTest.java
@@ -25,14 +25,17 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
+import java.math.BigDecimal;
+import java.util.stream.Stream;
import org.apache.calcite.plan.RelOptUtil;
-import org.apache.calcite.rel.RelCollations;
+import org.apache.calcite.rel.SingleRel;
import org.apache.calcite.rel.core.Aggregate;
import org.apache.calcite.rel.core.AggregateCall;
import org.apache.calcite.rel.core.Join;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.sql.SqlExplainLevel;
import org.apache.calcite.sql.fun.SqlAvgAggFunction;
-import org.apache.calcite.util.ImmutableIntList;
import org.apache.ignite.internal.sql.engine.rel.IgniteAggregate;
import org.apache.ignite.internal.sql.engine.rel.IgniteIndexScan;
import org.apache.ignite.internal.sql.engine.rel.IgniteRel;
@@ -47,11 +50,14 @@ import org.apache.ignite.internal.sql.engine.rel.agg.IgniteSingleAggregateBase;
import org.apache.ignite.internal.sql.engine.rel.agg.IgniteSingleHashAggregate;
import org.apache.ignite.internal.sql.engine.rel.agg.IgniteSingleSortAggregate;
import org.apache.ignite.internal.sql.engine.schema.IgniteSchema;
+import org.apache.ignite.internal.sql.engine.trait.IgniteDistribution;
import org.apache.ignite.internal.sql.engine.trait.IgniteDistributions;
import org.apache.ignite.internal.sql.engine.trait.TraitUtils;
import org.hamcrest.core.IsInstanceOf;
import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.EnumSource;
+import org.junit.jupiter.params.provider.MethodSource;
/**
* AggregatePlannerTest.
@@ -67,7 +73,7 @@ public class AggregatePlannerTest extends AbstractAggregatePlannerTest {
@ParameterizedTest
@EnumSource
public void singleWithoutIndex(AggregateAlgorithm algo) throws Exception {
- TestTable tbl = createBroadcastTable().addIndex(RelCollations.of(ImmutableIntList.of(1, 2)), "val0_val1");
+ TestTable tbl = createBroadcastTable().addIndex("val0_val1", 1, 2);
IgniteSchema publicSchema = new IgniteSchema("PUBLIC");
@@ -104,7 +110,7 @@ public class AggregatePlannerTest extends AbstractAggregatePlannerTest {
@ParameterizedTest
@EnumSource
public void singleWithIndex(AggregateAlgorithm algo) throws Exception {
- TestTable tbl = createBroadcastTable().addIndex(RelCollations.of(ImmutableIntList.of(3, 4)), "grp0_grp1");
+ TestTable tbl = createBroadcastTable().addIndex("grp0_grp1", 3, 4);
IgniteSchema publicSchema = new IgniteSchema("PUBLIC");
@@ -184,7 +190,7 @@ public class AggregatePlannerTest extends AbstractAggregatePlannerTest {
@ParameterizedTest
@EnumSource
public void distribution(AggregateAlgorithm algo) throws Exception {
- TestTable tbl = createAffinityTable().addIndex(RelCollations.of(ImmutableIntList.of(3)), "grp0");
+ TestTable tbl = createAffinityTable().addIndex("grp0", 3);
IgniteSchema publicSchema = new IgniteSchema("PUBLIC");
@@ -225,8 +231,8 @@ public class AggregatePlannerTest extends AbstractAggregatePlannerTest {
@EnumSource
public void expandDistinctAggregates(AggregateAlgorithm algo) throws Exception {
TestTable tbl = createAffinityTable()
- .addIndex(RelCollations.of(ImmutableIntList.of(3, 1, 0)), "idx_val0")
- .addIndex(RelCollations.of(ImmutableIntList.of(3, 2, 0)), "idx_val1");
+ .addIndex("idx_val0", 3, 1, 0)
+ .addIndex("idx_val1", 3, 2, 0);
IgniteSchema publicSchema = new IgniteSchema("PUBLIC");
@@ -268,7 +274,7 @@ public class AggregatePlannerTest extends AbstractAggregatePlannerTest {
"Invalid plan\n" + RelOptUtil.toString(phys, SqlExplainLevel.ALL_ATTRIBUTES)
);
- // Check the second aggrgation step contains accumulators.
+ // Check the second aggregation step contains accumulators.
assertTrue(
findNodes(phys, byClass(algo.single)).stream()
.noneMatch(n -> ((Aggregate) n).getAggCallList().isEmpty()),
@@ -276,6 +282,70 @@ public class AggregatePlannerTest extends AbstractAggregatePlannerTest {
);
}
+ @ParameterizedTest
+ @MethodSource("provideAlgoAndDistribution")
+ public void singleSumTypes(AggregateAlgorithm algo, IgniteDistribution distr) throws Exception {
+ IgniteSchema schema = createSchema(
+ createTable(
+ "TEST", distr,
+ "ID", Integer.class,
+ "GRP", Integer.class,
+ "VAL_TINYINT", Byte.class,
+ "VAL_SMALLINT", Short.class,
+ "VAL_INT", Integer.class,
+ "VAL_BIGINT", Long.class,
+ "VAL_DECIMAL", BigDecimal.class,
+ "VAL_FLOAT", Float.class,
+ "VAL_DOUBLE", Double.class
+ )
+ );
+
+ String sql = "SELECT "
+ + "SUM(VAL_TINYINT), "
+ + "SUM(VAL_SMALLINT), "
+ + "SUM(VAL_INT), "
+ + "SUM(VAL_BIGINT), "
+ + "SUM(VAL_DECIMAL), "
+ + "SUM(VAL_FLOAT), "
+ + "SUM(VAL_DOUBLE) "
+ + "FROM test GROUP BY grp";
+
+ IgniteRel phys = physicalPlan(
+ sql,
+ schema,
+ algo.rulesToDisable
+ );
+
+ checkSplitAndSerialization(phys, schema);
+
+ Class<? extends SingleRel> cls = distr == IgniteDistributions.broadcast() ? algo.single : algo.reduce;
+
+ SingleRel agg = findFirstNode(phys, byClass(cls));
+
+ assertNotNull(agg, "Invalid plan\n" + RelOptUtil.toString(phys));
+
+ RelDataType rowTypes = agg.getRowType();
+
+ RelDataTypeFactory tf = phys.getCluster().getTypeFactory();
+
+ assertEquals(tf.createJavaType(Long.class), rowTypes.getFieldList().get(1).getType());
+ assertEquals(tf.createJavaType(Long.class), rowTypes.getFieldList().get(2).getType());
+ assertEquals(tf.createJavaType(Long.class), rowTypes.getFieldList().get(3).getType());
+ assertEquals(tf.createJavaType(BigDecimal.class), rowTypes.getFieldList().get(4).getType());
+ assertEquals(tf.createJavaType(BigDecimal.class), rowTypes.getFieldList().get(5).getType());
+ assertEquals(tf.createJavaType(Double.class), rowTypes.getFieldList().get(6).getType());
+ assertEquals(tf.createJavaType(Double.class), rowTypes.getFieldList().get(7).getType());
+ }
+
+ private static Stream<Arguments> provideAlgoAndDistribution() {
+ return Stream.of(
+ Arguments.of(AggregateAlgorithm.SORT, IgniteDistributions.broadcast()),
+ Arguments.of(AggregateAlgorithm.SORT, IgniteDistributions.random()),
+ Arguments.of(AggregateAlgorithm.HASH, IgniteDistributions.broadcast()),
+ Arguments.of(AggregateAlgorithm.HASH, IgniteDistributions.random())
+ );
+ }
+
enum AggregateAlgorithm {
SORT(
IgniteSingleSortAggregate.class,
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/CorrelatedNestedLoopJoinPlannerTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/CorrelatedNestedLoopJoinPlannerTest.java
index bf27768..4c966e6 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/CorrelatedNestedLoopJoinPlannerTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/CorrelatedNestedLoopJoinPlannerTest.java
@@ -23,12 +23,10 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.List;
import org.apache.calcite.plan.RelOptUtil;
-import org.apache.calcite.rel.RelCollations;
import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.rex.RexFieldAccess;
import org.apache.calcite.rex.RexLiteral;
import org.apache.calcite.rex.RexNode;
-import org.apache.calcite.util.ImmutableIntList;
import org.apache.ignite.internal.sql.engine.rel.IgniteIndexScan;
import org.apache.ignite.internal.sql.engine.rel.IgniteRel;
import org.apache.ignite.internal.sql.engine.schema.IgniteSchema;
@@ -81,7 +79,7 @@ public class CorrelatedNestedLoopJoinPlannerTest extends AbstractPlannerTest {
return IgniteDistributions.broadcast();
}
}
- .addIndex(RelCollations.of(ImmutableIntList.of(1, 0)), "t1_jid_idx")
+ .addIndex("t1_jid_idx", 1, 0)
);
String sql = "select * "
@@ -142,7 +140,7 @@ public class CorrelatedNestedLoopJoinPlannerTest extends AbstractPlannerTest {
return IgniteDistributions.broadcast();
}
}
- .addIndex(RelCollations.of(ImmutableIntList.of(1, 0)), "t0_jid_idx")
+ .addIndex("t0_jid_idx", 1, 0)
);
publicSchema.addTable(
@@ -159,7 +157,7 @@ public class CorrelatedNestedLoopJoinPlannerTest extends AbstractPlannerTest {
return IgniteDistributions.broadcast();
}
}
- .addIndex(RelCollations.of(ImmutableIntList.of(1, 0)), "t1_jid_idx")
+ .addIndex("t1_jid_idx", 1, 0)
);
String sql = "select * "
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/HashAggregatePlannerTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/HashAggregatePlannerTest.java
index 5a3779c..c2c5b51 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/HashAggregatePlannerTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/HashAggregatePlannerTest.java
@@ -22,11 +22,9 @@ import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import org.apache.calcite.plan.RelOptUtil;
-import org.apache.calcite.rel.RelCollations;
import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.sql.fun.SqlAvgAggFunction;
import org.apache.calcite.sql.fun.SqlCountAggFunction;
-import org.apache.calcite.util.ImmutableIntList;
import org.apache.ignite.internal.sql.engine.rel.IgniteRel;
import org.apache.ignite.internal.sql.engine.rel.agg.IgniteMapHashAggregate;
import org.apache.ignite.internal.sql.engine.rel.agg.IgniteReduceHashAggregate;
@@ -102,7 +100,7 @@ public class HashAggregatePlannerTest extends AbstractAggregatePlannerTest {
*/
@Test
public void noGroupByAggregate() throws Exception {
- TestTable tbl = createAffinityTable().addIndex(RelCollations.of(ImmutableIntList.of(1, 2)), "val0_val1");
+ TestTable tbl = createAffinityTable().addIndex("val0_val1", 1, 2);
IgniteSchema publicSchema = new IgniteSchema("PUBLIC");
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/HashIndexSpoolPlannerTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/HashIndexSpoolPlannerTest.java
index 526fef1..68227c7 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/HashIndexSpoolPlannerTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/HashIndexSpoolPlannerTest.java
@@ -23,12 +23,10 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.List;
import org.apache.calcite.plan.RelOptUtil;
-import org.apache.calcite.rel.RelCollations;
import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.rex.RexFieldAccess;
import org.apache.calcite.rex.RexLiteral;
import org.apache.calcite.rex.RexNode;
-import org.apache.calcite.util.ImmutableIntList;
import org.apache.ignite.internal.sql.engine.rel.IgniteHashIndexSpool;
import org.apache.ignite.internal.sql.engine.rel.IgniteRel;
import org.apache.ignite.internal.sql.engine.schema.IgniteSchema;
@@ -66,7 +64,7 @@ public class HashIndexSpoolPlannerTest extends AbstractPlannerTest {
return IgniteDistributions.affinity(0, "T0", "hash");
}
}
- .addIndex(RelCollations.of(ImmutableIntList.of(1, 0)), "t0_jid_idx")
+ .addIndex("t0_jid_idx", 1, 0)
);
publicSchema.addTable(
@@ -83,7 +81,7 @@ public class HashIndexSpoolPlannerTest extends AbstractPlannerTest {
return IgniteDistributions.affinity(0, "T1", "hash");
}
}
- .addIndex(RelCollations.of(ImmutableIntList.of(1, 0)), "t1_jid_idx")
+ .addIndex("t1_jid_idx", 1, 0)
);
String sql = "select * "
@@ -147,7 +145,7 @@ public class HashIndexSpoolPlannerTest extends AbstractPlannerTest {
return IgniteDistributions.affinity(0, "T1", "hash");
}
}
- .addIndex(RelCollations.of(ImmutableIntList.of(1, 0)), "t1_jid0_idx")
+ .addIndex("t1_jid0_idx", 1, 0)
);
String sql = "select * "
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/LimitOffsetPlannerTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/LimitOffsetPlannerTest.java
index 8113511..68b9b92 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/LimitOffsetPlannerTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/LimitOffsetPlannerTest.java
@@ -17,11 +17,6 @@
package org.apache.ignite.internal.sql.engine.planner;
-import static java.util.stream.Collectors.toList;
-
-import java.util.Arrays;
-import org.apache.calcite.rel.RelCollations;
-import org.apache.calcite.rel.RelFieldCollation;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.util.ImmutableIntList;
@@ -182,20 +177,7 @@ public class LimitOffsetPlannerTest extends AbstractPlannerTest {
};
if (!ArrayUtils.nullOrEmpty(indexedColumns)) {
- table.addIndex(
- RelCollations.of(
- Arrays.stream(indexedColumns)
- .mapToObj(
- idx -> new RelFieldCollation(
- idx,
- RelFieldCollation.Direction.ASCENDING,
- RelFieldCollation.NullDirection.FIRST
- )
- )
- .collect(toList())
- ),
- "test_idx"
- );
+ table.addIndex("test_idx", indexedColumns);
}
return createSchema(table);
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/SortAggregatePlannerTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/SortAggregatePlannerTest.java
index ebafa11..cc8f28b 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/SortAggregatePlannerTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/SortAggregatePlannerTest.java
@@ -29,7 +29,6 @@ import org.apache.calcite.plan.RelOptUtil;
import org.apache.calcite.rel.RelCollations;
import org.apache.calcite.rel.RelFieldCollation;
import org.apache.calcite.rel.type.RelDataTypeFactory;
-import org.apache.calcite.util.ImmutableIntList;
import org.apache.ignite.internal.sql.engine.rel.IgniteCorrelatedNestedLoopJoin;
import org.apache.ignite.internal.sql.engine.rel.IgniteLimit;
import org.apache.ignite.internal.sql.engine.rel.IgniteRel;
@@ -55,7 +54,7 @@ public class SortAggregatePlannerTest extends AbstractAggregatePlannerTest {
*/
@Test
public void notApplicableForSortAggregate() {
- TestTable tbl = createAffinityTable().addIndex(RelCollations.of(ImmutableIntList.of(1, 2)), "val0_val1");
+ TestTable tbl = createAffinityTable().addIndex("val0_val1", 1, 2);
IgniteSchema publicSchema = new IgniteSchema("PUBLIC");
@@ -129,7 +128,7 @@ public class SortAggregatePlannerTest extends AbstractAggregatePlannerTest {
return IgniteDistributions.broadcast();
}
}
- .addIndex(RelCollations.of(ImmutableIntList.of(3, 4)), "grp0_1");
+ .addIndex("grp0_1", 3, 4);
IgniteSchema publicSchema = new IgniteSchema("PUBLIC");
@@ -177,7 +176,7 @@ public class SortAggregatePlannerTest extends AbstractAggregatePlannerTest {
return IgniteDistributions.affinity(0, "test", "hash");
}
}
- .addIndex(RelCollations.of(ImmutableIntList.of(3, 4)), "grp0_1");
+ .addIndex("grp0_1", 3, 4);
IgniteSchema publicSchema = new IgniteSchema("PUBLIC");
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/SortedIndexSpoolPlannerTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/SortedIndexSpoolPlannerTest.java
index bbb9e9d..a4d9cd3 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/SortedIndexSpoolPlannerTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/SortedIndexSpoolPlannerTest.java
@@ -23,12 +23,10 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.List;
import org.apache.calcite.plan.RelOptUtil;
-import org.apache.calcite.rel.RelCollations;
import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.rex.RexFieldAccess;
import org.apache.calcite.rex.RexLiteral;
import org.apache.calcite.rex.RexNode;
-import org.apache.calcite.util.ImmutableIntList;
import org.apache.ignite.internal.sql.engine.rel.IgniteRel;
import org.apache.ignite.internal.sql.engine.rel.IgniteSortedIndexSpool;
import org.apache.ignite.internal.sql.engine.schema.IgniteSchema;
@@ -66,7 +64,7 @@ public class SortedIndexSpoolPlannerTest extends AbstractPlannerTest {
return IgniteDistributions.affinity(0, "T0", "hash");
}
}
- .addIndex(RelCollations.of(ImmutableIntList.of(1, 0)), "t0_jid_idx")
+ .addIndex("t0_jid_idx", 1, 0)
);
publicSchema.addTable(
@@ -83,7 +81,7 @@ public class SortedIndexSpoolPlannerTest extends AbstractPlannerTest {
return IgniteDistributions.affinity(0, "T1", "hash");
}
}
- .addIndex(RelCollations.of(ImmutableIntList.of(1, 0)), "t1_jid_idx")
+ .addIndex("t1_jid_idx", 1, 0)
);
String sql = "select * "
@@ -158,7 +156,7 @@ public class SortedIndexSpoolPlannerTest extends AbstractPlannerTest {
return IgniteDistributions.affinity(0, "T1", "hash");
}
}
- .addIndex(RelCollations.of(ImmutableIntList.of(1, 0)), "t1_jid0_idx")
+ .addIndex("t1_jid0_idx", 1, 0)
);
String sql = "select * "