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 23cd9abffe IGNITE-18801 Sql. Add an SQL function that generates a
random UUID (#1734)
23cd9abffe is described below
commit 23cd9abffe847eec67996219333cd807d4bf038b
Author: Pavel Pereslegin <[email protected]>
AuthorDate: Wed Mar 8 15:33:32 2023 +0300
IGNITE-18801 Sql. Add an SQL function that generates a random UUID (#1734)
---
.../internal/sql/engine/ItSqlOperatorsTest.java | 1 +
.../ignite/internal/sql/engine/ItUuidTest.java | 41 +++++++++++++++-------
.../internal/sql/engine/exec/exp/RexImpTable.java | 3 ++
.../sql/engine/exec/exp/RexToLixTranslator.java | 6 +++-
.../internal/sql/engine/rex/IgniteRexBuilder.java | 2 +-
.../sql/engine/sql/fun/IgniteSqlOperatorTable.java | 25 +++++++++++++
.../internal/sql/engine/util/IgniteMethod.java | 6 +++-
7 files changed, 69 insertions(+), 15 deletions(-)
diff --git
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItSqlOperatorsTest.java
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItSqlOperatorsTest.java
index 8de2b82978..6f7e464e9c 100644
---
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItSqlOperatorsTest.java
+++
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItSqlOperatorsTest.java
@@ -181,6 +181,7 @@ public class ItSqlOperatorsTest extends
ClusterPerClassIntegrationTest {
assertExpression("ABS(-1)").returns(Math.abs(-1)).check();
assertExpression("RAND()").check();
assertExpression("RAND_INTEGER(10)").check();
+ assertExpression("RAND_UUID()").check();
assertExpression("ACOS(1)").returns(Math.acos(1)).check();
assertExpression("ASIN(1)").returns(Math.asin(1)).check();
assertExpression("ATAN(1)").returns(Math.atan(1)).check();
diff --git
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItUuidTest.java
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItUuidTest.java
index 824826eecd..4bd6965f99 100644
---
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItUuidTest.java
+++
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItUuidTest.java
@@ -30,6 +30,7 @@ import org.apache.ignite.lang.IgniteException;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
@@ -54,7 +55,7 @@ public class ItUuidTest extends
ClusterPerClassIntegrationTest {
@BeforeAll
public void createTables() {
- sql("CREATE TABLE t(id INTEGER PRIMARY KEY, uuid_key UUID)");
+ sql("CREATE TABLE t(id INTEGER PRIMARY KEY, uuid_key UUID, uuid_key2
UUID)");
}
@BeforeEach
@@ -93,14 +94,14 @@ public class ItUuidTest extends
ClusterPerClassIntegrationTest {
@Test
public void testUuidInUpdates() {
- sql("INSERT INTO t VALUES (1, ?)", UUID_1);
+ sql("INSERT INTO t (id, uuid_key) VALUES (1, ?)", UUID_1);
// Update column UUID with an UUID value
assertQuery("UPDATE t SET uuid_key = ? WHERE
id=1").withParams(UUID_2).returns(1L).check();
assertQuery("SELECT uuid_key FROM t WHERE
id=1").columnTypes(UUID.class).returns(UUID_2).check();
// Insert column UUID with a string value are possible to allow CASTs
from STRING to UUID.
- sql("INSERT INTO t VALUES (3, ?)", UUID_1.toString());
+ sql("INSERT INTO t (id, uuid_key) VALUES (3, ?)", UUID_1.toString());
// Update column UUID with a string value are possible to allow CASTs
from STRING to UUID.
assertQuery("UPDATE t SET uuid_key = ? WHERE
id=1").withParams(UUID_1.toString()).returns(1L).check();
@@ -110,16 +111,16 @@ public class ItUuidTest extends
ClusterPerClassIntegrationTest {
@Test
public void testUuidInQueries() {
// cast from string
- sql(format("INSERT INTO t VALUES (1, CAST('{}' as UUID))", UUID_1));
+ sql(format("INSERT INTO t (id, uuid_key) VALUES (1, CAST('{}' as
UUID))", UUID_1));
assertQuery("SELECT uuid_key FROM t WHERE
id=1").columnTypes(UUID.class).returns(UUID_1).check();
// parameter in a query
- sql("INSERT INTO t VALUES (2, ?)", UUID_2);
+ sql("INSERT INTO t (id, uuid_key) VALUES (2, ?)", UUID_2);
assertQuery("SELECT uuid_key FROM t WHERE
id=2").columnTypes(UUID.class).returns(UUID_2).check();
// null value
- sql("INSERT INTO t VALUES (3, NULL)");
+ sql("INSERT INTO t (id, uuid_key) VALUES (3, NULL)");
assertQuery("SELECT uuid_key FROM t WHERE
id=3").columnTypes(UUID.class).returns(null).check();
// uuid in predicate
@@ -144,8 +145,8 @@ public class ItUuidTest extends
ClusterPerClassIntegrationTest {
@Test
public void testBasicAggregates() {
- sql(format("INSERT INTO t VALUES (1, CAST('{}' as UUID))", UUID_1));
- sql(format("INSERT INTO t VALUES (2, CAST('{}' as UUID))", UUID_2));
+ sql(format("INSERT INTO t (id, uuid_key) VALUES (1, CAST('{}' as
UUID))", UUID_1));
+ sql(format("INSERT INTO t (id, uuid_key) VALUES (2, CAST('{}' as
UUID))", UUID_2));
assertQuery("SELECT COUNT(uuid_key) FROM t").returns(2L).check();
assertQuery("SELECT ANY_VALUE(uuid_key) FROM t").check();
@@ -158,9 +159,7 @@ public class ItUuidTest extends
ClusterPerClassIntegrationTest {
public void testUuidCaseExpression() {
UUID other = UUID.randomUUID();
- sql("INSERT INTO t VALUES (1, ?)", UUID_1);
- sql("INSERT INTO t VALUES (2, ?)", UUID_2);
- sql("INSERT INTO t VALUES (3, NULL)");
+ sql("INSERT INTO t (id, uuid_key) VALUES (1, ?), (2, ?), (3, NULL)",
UUID_1, UUID_2);
// CASE WHEN <condition> THEN .. WHEN <condition2> THEN ... END
assertQuery("SELECT id, CASE WHEN uuid_key = ? THEN uuid_key ELSE ?
END FROM t ORDER BY id ASC ")
@@ -239,7 +238,7 @@ public class ItUuidTest extends
ClusterPerClassIntegrationTest {
@Test
public void testTypeCoercionInDml() {
- sql("INSERT INTO t VALUES (1, ?)", UUID_1.toString());
+ sql("INSERT INTO t (id, uuid_key) VALUES (1, ?)", UUID_1.toString());
sql("UPDATE t SET uuid_key=? WHERE id=1", UUID_2.toString());
@@ -265,4 +264,22 @@ public class ItUuidTest extends
ClusterPerClassIntegrationTest {
assertQuery("SELECT ? < ?").withParams(uuid1,
uuid2).returns(false).check();
assertQuery("SELECT ? <= ?").withParams(uuid1,
uuid2).returns(false).check();
}
+
+ @Test
+ public void testRandomUuid() {
+ assertQuery("INSERT INTO t SELECT x, RAND_UUID(), RAND_UUID() FROM
TABLE(SYSTEM_RANGE(0, 99))").returns(100L).check();
+ assertQuery("SELECT uuid_key FROM t").columnTypes(UUID.class).check();
+ assertQuery("SELECT COUNT(DISTINCT uuid_key) FROM
t").returns(100L).check();
+ assertQuery("SELECT COUNT(DISTINCT uuid_key2) FROM
t").returns(100L).check();
+ assertQuery("SELECT COUNT(*) FROM t WHERE uuid_key =
uuid_key2").returns(0L).check();
+ assertQuery("SELECT COUNT(*) FROM t WHERE uuid_key =
RAND_UUID()").returns(0L).check();
+ assertQuery("SELECT COUNT(*) FROM t WHERE uuid_key !=
uuid_key2").returns(100L).check();
+ }
+
+ @Test
+ @Disabled("https://issues.apache.org/jira/browse/IGNITE-18931")
+ public void testRandomUuidComparison() {
+ assertQuery("SELECT RAND_UUID() = RAND_UUID()").returns(false).check();
+ assertQuery("SELECT RAND_UUID() != RAND_UUID()").returns(true).check();
+ }
}
diff --git
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/RexImpTable.java
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/RexImpTable.java
index b0f761be47..f845837246 100644
---
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/RexImpTable.java
+++
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/RexImpTable.java
@@ -173,6 +173,7 @@ import static
org.apache.calcite.sql.fun.SqlStdOperatorTable.UPPER;
import static
org.apache.ignite.internal.sql.engine.sql.fun.IgniteSqlOperatorTable.GREATEST2;
import static
org.apache.ignite.internal.sql.engine.sql.fun.IgniteSqlOperatorTable.LEAST2;
import static
org.apache.ignite.internal.sql.engine.sql.fun.IgniteSqlOperatorTable.NULL_BOUND;
+import static
org.apache.ignite.internal.sql.engine.sql.fun.IgniteSqlOperatorTable.RAND_UUID;
import static
org.apache.ignite.internal.sql.engine.sql.fun.IgniteSqlOperatorTable.SYSTEM_RANGE;
import static
org.apache.ignite.internal.sql.engine.sql.fun.IgniteSqlOperatorTable.TYPEOF;
@@ -510,6 +511,8 @@ public class RexImpTable {
// Operator IS_NOT_DISTINCT_FROM is removed by RexSimplify, but still
possible in join conditions, so
// implementation required.
defineMethod(IS_NOT_DISTINCT_FROM,
IgniteMethod.IS_NOT_DISTINCT_FROM.method(), NullPolicy.NONE);
+
+ defineMethod(RAND_UUID, IgniteMethod.RAND_UUID.method(),
NullPolicy.NONE);
}
private void defineMethod(SqlOperator operator, String functionName,
NullPolicy nullPolicy) {
diff --git
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/RexToLixTranslator.java
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/RexToLixTranslator.java
index 7615dbfbe6..2a4699488a 100644
---
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/RexToLixTranslator.java
+++
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/RexToLixTranslator.java
@@ -1102,7 +1102,11 @@ public class RexToLixTranslator implements
RexVisitor<RexToLixTranslator.Result>
}
callOperandResultMap.put(call, operandResults);
final Result result = implementor.implement(this, call,
operandResults);
- rexResultMap.put(call, result);
+
+ if (call.op.isDeterministic()) {
+ rexResultMap.put(call, result);
+ }
+
return result;
}
diff --git
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rex/IgniteRexBuilder.java
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rex/IgniteRexBuilder.java
index 2df4af8542..4aa81d599d 100644
---
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rex/IgniteRexBuilder.java
+++
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rex/IgniteRexBuilder.java
@@ -47,7 +47,7 @@ public class IgniteRexBuilder extends RexBuilder {
//
// throw new AssertionError("unknown type " + value.getClass());
//
- if (type instanceof IgniteCustomType) {
+ if (value != null && type instanceof IgniteCustomType) {
// IgniteCustomType: Not comparable types are not supported.
assert value instanceof Comparable : "Not comparable
IgniteCustomType:" + type + ". value: " + value;
return makeLiteral((Comparable<?>) value, type,
type.getSqlTypeName());
diff --git
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/fun/IgniteSqlOperatorTable.java
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/fun/IgniteSqlOperatorTable.java
index d626348b2e..4b895b15d9 100644
---
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/fun/IgniteSqlOperatorTable.java
+++
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/fun/IgniteSqlOperatorTable.java
@@ -28,6 +28,7 @@ import org.apache.calcite.sql.type.ReturnTypes;
import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.calcite.sql.type.SqlTypeTransforms;
import org.apache.calcite.sql.util.ReflectiveSqlOperatorTable;
+import org.apache.ignite.internal.sql.engine.type.UuidType;
/**
* Operator table that contains only Ignite-specific functions and operators.
@@ -107,6 +108,29 @@ public class IgniteSqlOperatorTable extends
ReflectiveSqlOperatorTable {
OperandTypes.STRING_INTEGER_OPTIONAL_INTEGER,
SqlFunctionCategory.STRING);
+ /**
+ * The {@code RAND_UUID()} function, which yields a random UUID.
+ */
+ public static final SqlFunction RAND_UUID =
+ new SqlFunction(
+ "RAND_UUID",
+ SqlKind.OTHER_FUNCTION,
+ ReturnTypes.explicit(new UuidType(false)),
+ null,
+ OperandTypes.NILADIC,
+ SqlFunctionCategory.SYSTEM
+ ) {
+ @Override
+ public boolean isDynamicFunction() {
+ return true;
+ }
+
+ @Override
+ public boolean isDeterministic() {
+ return false;
+ }
+ };
+
/** Singleton instance. */
public static final IgniteSqlOperatorTable INSTANCE = new
IgniteSqlOperatorTable();
@@ -374,5 +398,6 @@ public class IgniteSqlOperatorTable extends
ReflectiveSqlOperatorTable {
register(LEAST2);
register(GREATEST2);
register(NULL_BOUND);
+ register(RAND_UUID);
}
}
diff --git
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/IgniteMethod.java
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/IgniteMethod.java
index 043449d3ee..34d4c8a4f7 100644
---
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/IgniteMethod.java
+++
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/IgniteMethod.java
@@ -20,6 +20,7 @@ package org.apache.ignite.internal.sql.engine.util;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Objects;
+import java.util.UUID;
import org.apache.calcite.DataContext;
import org.apache.calcite.avatica.util.ByteString;
import org.apache.calcite.linq4j.tree.Types;
@@ -94,7 +95,10 @@ public enum IgniteMethod {
GREATEST2(IgniteSqlFunctions.class, "greatest2", Object.class,
Object.class),
/** See {@link Objects#equals(Object, Object)}. */
- IS_NOT_DISTINCT_FROM(Objects.class, "equals", Object.class, Object.class);
+ IS_NOT_DISTINCT_FROM(Objects.class, "equals", Object.class, Object.class),
+
+ /** See {@link UUID#randomUUID()}. */
+ RAND_UUID(UUID.class, "randomUUID");
private final Method method;