This is an automated email from the ASF dual-hosted git repository.

amashenkov pushed a commit to branch ignite-22161
in repository https://gitbox.apache.org/repos/asf/ignite-3.git

commit bfaf586b4ae8c8c803ea68e24d88378b4a2f3289
Author: amashenkov <[email protected]>
AuthorDate: Fri May 3 17:05:34 2024 +0300

    wip.
---
 .../catalog/commands/CreateTableCommand.java       | 21 +++++--
 .../internal/sql/engine/ItCreateTableDdlTest.java  | 25 ++++++++
 .../internal/sql/engine/sql/SqlDdlParserTest.java  | 69 +++++++++++++++++++++-
 3 files changed, 110 insertions(+), 5 deletions(-)

diff --git 
a/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/commands/CreateTableCommand.java
 
b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/commands/CreateTableCommand.java
index 565cdce0bf..0a2ef4a8d4 100644
--- 
a/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/commands/CreateTableCommand.java
+++ 
b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/commands/CreateTableCommand.java
@@ -35,6 +35,7 @@ import java.util.Set;
 import org.apache.ignite.internal.catalog.Catalog;
 import org.apache.ignite.internal.catalog.CatalogCommand;
 import org.apache.ignite.internal.catalog.CatalogValidationException;
+import org.apache.ignite.internal.catalog.commands.DefaultValue.FunctionCall;
 import org.apache.ignite.internal.catalog.commands.DefaultValue.Type;
 import org.apache.ignite.internal.catalog.descriptors.CatalogColumnCollation;
 import 
org.apache.ignite.internal.catalog.descriptors.CatalogHashIndexDescriptor;
@@ -176,10 +177,22 @@ public class CreateTableCommand extends 
AbstractTableCommand {
         primaryKey.validate(columns);
 
         for (ColumnParams column : columns) {
-            boolean partOfPk = primaryKey.columns().contains(column.name());
-            if (!partOfPk && column.defaultValueDefinition().type == 
Type.FUNCTION_CALL) {
-                throw new CatalogValidationException(
-                        format("Functional defaults are not supported for 
non-primary key columns [col={}].", column.name()));
+            DefaultValue defaultValue = column.defaultValueDefinition();
+
+            if (defaultValue.type == Type.FUNCTION_CALL) {
+                boolean partOfPk = 
primaryKey.columns().contains(column.name());
+                if (!partOfPk) {
+                    throw new CatalogValidationException(
+                            format("Functional defaults are not supported for 
non-primary key columns [col={}].", column.name()));
+                }
+
+                // TODO: fix function validation.
+                String functionName = ((FunctionCall) 
defaultValue).functionName();
+                if (!"gen_random_uuid".equalsIgnoreCase(functionName)) {
+                    throw new CatalogValidationException(
+                            format("Functional default contains unsupported 
function: [col={}, functionName={}]",
+                                    column.name(), functionName));
+                }
             }
         }
 
diff --git 
a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItCreateTableDdlTest.java
 
b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItCreateTableDdlTest.java
index 27869fc632..57a0336ebf 100644
--- 
a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItCreateTableDdlTest.java
+++ 
b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItCreateTableDdlTest.java
@@ -141,6 +141,15 @@ public class ItCreateTableDdlTest extends 
BaseSqlIntegrationTest {
         assertThat(result, hasSize(2)); // both rows are inserted without 
conflict
     }
 
+    @Test
+    public void pkWithInvalidFunctionalDefault() {
+        assertThrowsSqlException(
+                STMT_VALIDATION_ERR,
+                "Functional default contains unsupported function: [col=ID, 
functionName=INVALID_FUNC]",
+                () -> sql("create table t (id varchar default invalid_func 
primary key, val int)")
+                );
+    }
+
     @Test
     public void undefinedColumnsInPrimaryKey() {
         assertThrowsSqlException(
@@ -332,6 +341,22 @@ public class ItCreateTableDdlTest extends 
BaseSqlIntegrationTest {
         assertEquals("Id0", colocationColumns.get(0).name());
     }
 
+    @Test
+    public void literalAsColumDefault() {
+        sql("CREATE TABLE T0("
+                + "id BIGINT DEFAULT 1, "
+                + "valdate DATE DEFAULT DATE '2001-12-21',"
+                + "valtime TIME DEFAULT TIME '11:22:33.444',"
+                + "valts TIMESTAMP DEFAULT TIMESTAMP '2001-12-21 
11:22:33.444',"
+                + "valstr VARCHAR DEFAULT 'string',"
+                + "valbin VARBINARY DEFAULT x'ff'"
+                + ")");
+
+        List<Column> columns = 
unwrapTableViewInternal(table("T0")).schemaView().lastKnownSchema().columns();
+
+        assertEquals(6, columns.size());
+    }
+
     @Test
     public void doNotAllowFunctionsInNonPkColumns() {
         assertThrowsSqlException(
diff --git 
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/sql/SqlDdlParserTest.java
 
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/sql/SqlDdlParserTest.java
index 7cbab7832e..5d476acecc 100644
--- 
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/sql/SqlDdlParserTest.java
+++ 
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/sql/SqlDdlParserTest.java
@@ -34,10 +34,14 @@ import java.util.Set;
 import java.util.stream.Collectors;
 import org.apache.calcite.schema.ColumnStrategy;
 import org.apache.calcite.sql.SqlBasicCall;
+import org.apache.calcite.sql.SqlBinaryStringLiteral;
+import org.apache.calcite.sql.SqlCharStringLiteral;
 import org.apache.calcite.sql.SqlIdentifier;
 import org.apache.calcite.sql.SqlKind;
 import org.apache.calcite.sql.SqlLiteral;
 import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.SqlNumericLiteral;
+import org.apache.calcite.sql.SqlUnknownLiteral;
 import org.apache.calcite.sql.ddl.SqlColumnDeclaration;
 import org.apache.ignite.lang.ErrorGroups.Sql;
 import org.hamcrest.CustomMatcher;
@@ -109,6 +113,69 @@ public class SqlDdlParserTest extends 
AbstractDdlParserTest {
         );
     }
 
+    /**
+     * Parsing of CREATE TABLE with a literal as a default expression.
+     */
+    @Test
+    public void createTableWithDefaultLiteral() {
+        String query = "CREATE TABLE my_table("
+                + "id BIGINT DEFAULT 1, "
+                + "valdate DATE DEFAULT DATE '2001-12-21',"
+                + "valdate2 DATE DEFAULT '2001-12-21',"
+                + "valtime TIME DEFAULT TIME '11:22:33.444',"
+                + "valtime2 TIME DEFAULT '11:22:33.444',"
+                + "valts TIMESTAMP DEFAULT TIMESTAMP '2001-12-21 
11:22:33.444',"
+                + "valts2 TIMESTAMP DEFAULT '2001-12-21 11:22:33.444',"
+                + "valbin VARBINARY DEFAULT x'ff',"
+                + "valstr VARCHAR DEFAULT 'string'"
+                + ")";
+
+        SqlNode node = parse(query);
+
+        assertThat(node, instanceOf(IgniteSqlCreateTable.class));
+
+        IgniteSqlCreateTable createTable = (IgniteSqlCreateTable) node;
+
+        assertThat(createTable.name().names, is(List.of("MY_TABLE")));
+        assertThat(createTable.columnList(), 
hasColumnWithLiteralAsDefault("ID", SqlNumericLiteral.class, "1"));
+        assertThat(createTable.columnList(), 
hasColumnWithLiteralAsDefault("VALSTR", SqlCharStringLiteral.class, "string"));
+        assertThat(createTable.columnList(), 
hasColumnWithLiteralAsDefault("VALBIN", SqlBinaryStringLiteral.class, 
"11111111"));
+        assertThat(createTable.columnList(), 
hasColumnWithLiteralAsDefault("VALDATE2", SqlCharStringLiteral.class, 
"2001-12-21"));
+        assertThat(createTable.columnList(), 
hasColumnWithLiteralAsDefault("VALTIME2", SqlCharStringLiteral.class, 
"11:22:33.444"));
+        assertThat(createTable.columnList(), 
hasColumnWithLiteralAsDefault("VALTS2", SqlCharStringLiteral.class, "2001-12-21 
11:22:33.444"));
+        // TODO: should we fix literal type somehow?
+        assertThat(createTable.columnList(), 
hasColumnWithLiteralAsDefault("VALDATE", SqlUnknownLiteral.class, 
"2001-12-21"));
+        assertThat(createTable.columnList(), 
hasColumnWithLiteralAsDefault("VALTIME", SqlUnknownLiteral.class, 
"11:22:33.444"));
+        assertThat(createTable.columnList(), 
hasColumnWithLiteralAsDefault("VALTS", SqlUnknownLiteral.class, "2001-12-21 
11:22:33.444"));
+
+
+        expectUnparsed(node, "CREATE TABLE \"MY_TABLE\" "
+                + "(\"ID\" BIGINT DEFAULT (1), "
+                + "\"VALDATE\" DATE DEFAULT (DATE '2001-12-21'), "
+                + "\"VALDATE2\" DATE DEFAULT ('2001-12-21'), "
+                + "\"VALTIME\" TIME DEFAULT (TIME '11:22:33.444'), "
+                + "\"VALTIME2\" TIME DEFAULT ('11:22:33.444'), "
+                + "\"VALTS\" TIMESTAMP DEFAULT (TIMESTAMP '2001-12-21 
11:22:33.444'), "
+                + "\"VALTS2\" TIMESTAMP DEFAULT ('2001-12-21 11:22:33.444'), "
+                + "\"VALBIN\" VARBINARY DEFAULT (X'FF'), "
+                + "\"VALSTR\" VARCHAR DEFAULT ('string'))"
+        );
+    }
+
+    private Matcher<Iterable<? super SqlColumnDeclaration>> 
hasColumnWithLiteralAsDefault(
+            String columnName,
+            Class<? extends SqlLiteral> literalType,
+            String literalValue
+    ) {
+        return hasItem(ofTypeMatching(
+                "Column with literal as default: columnName=" + columnName,
+                SqlColumnDeclaration.class,
+                col -> columnName.equals(col.name.getSimple())
+                        && literalType.isInstance(col.expression)
+                        && literalValue.equals(((SqlLiteral) 
col.expression).toValue())
+        ));
+    }
+
     /**
      * Parsing of CREATE TABLE statement with quoted identifiers.
      */
@@ -634,7 +701,7 @@ public class SqlDdlParserTest extends AbstractDdlParserTest 
{
                         && ((SqlBasicCall) 
bc.getOperandList().get(0)).getOperandList().get(0) instanceof SqlIdentifier
                         && ((SqlIdentifier) ((SqlBasicCall) 
bc.getOperandList().get(0)).getOperandList().get(0)).isSimple()
                         && ((SqlIdentifier) ((SqlBasicCall) 
bc.getOperandList().get(0)).getOperandList().get(0))
-                                .getSimple().equals("COL3"))));
+                        .getSimple().equals("COL3"))));
 
         expectUnparsed(node, "CREATE INDEX \"MY_INDEX\" ON \"MY_TABLE\" ("
                 + "\"COL1\" NULLS FIRST, \"COL2\" NULLS LAST, \"COL3\" DESC 
NULLS FIRST)"

Reply via email to