This is an automated email from the ASF dual-hosted git repository.
ppa pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git
The following commit(s) were added to refs/heads/main by this push:
new b0e37f0b316 IGNITE-27730 Sql. Add validation that a not null column
must have a default value (#7640)
b0e37f0b316 is described below
commit b0e37f0b316858e388c3131cb2d3f9335d204da6
Author: Pavel Pereslegin <[email protected]>
AuthorDate: Wed Feb 25 10:04:27 2026 +0300
IGNITE-27730 Sql. Add validation that a not null column must have a default
value (#7640)
---
.../commands/AlterTableAddColumnCommand.java | 11 ++++-
.../ignite/internal/catalog/CatalogTableTest.java | 10 ++--
.../AlterTableAddColumnCommandValidationTest.java | 47 ++++++++++++++++---
.../schemacompat/SchemaCompatibilityValidator.java | 11 ++++-
.../SchemaCompatibilityValidatorTest.java | 12 ++++-
.../ItThinClientSchemaSynchronizationTest.java | 16 +++----
.../sql/engine/ItAlterTableAlterColumnTest.java | 53 ++++++++++++++++++++++
.../internal/sql/engine/ItAlterTableDdlTest.java | 22 +++++++++
.../ignite/internal/sql/engine/ItDmlTest.java | 4 +-
.../sql/engine/exec/SqlOutdatedPlanTest.java | 2 +-
.../ignite/internal/table/TableTestUtils.java | 2 +-
11 files changed, 161 insertions(+), 29 deletions(-)
diff --git
a/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/commands/AlterTableAddColumnCommand.java
b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/commands/AlterTableAddColumnCommand.java
index 195ee1b9512..db1cf6cc33b 100644
---
a/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/commands/AlterTableAddColumnCommand.java
+++
b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/commands/AlterTableAddColumnCommand.java
@@ -33,6 +33,8 @@ 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.UpdateContext;
+import org.apache.ignite.internal.catalog.commands.DefaultValue.ConstantValue;
+import org.apache.ignite.internal.catalog.commands.DefaultValue.Type;
import org.apache.ignite.internal.catalog.descriptors.CatalogSchemaDescriptor;
import
org.apache.ignite.internal.catalog.descriptors.CatalogTableColumnDescriptor;
import org.apache.ignite.internal.catalog.descriptors.CatalogTableDescriptor;
@@ -123,8 +125,15 @@ public class AlterTableAddColumnCommand extends
AbstractTableCommand {
throw new CatalogValidationException("Column with name '{}'
specified more than once.", column.name());
}
+ DefaultValue defaultValue = column.defaultValueDefinition();
+
ensureTypeCanBeStored(column.name(), column.type());
- ensureNonFunctionalDefault(column.name(),
column.defaultValueDefinition());
+ ensureNonFunctionalDefault(column.name(), defaultValue);
+
+ if (!column.nullable() && (defaultValue == null
+ || (defaultValue.type() == Type.CONSTANT &&
((ConstantValue) defaultValue).value() == null))) {
+ throw new CatalogValidationException("Non-nullable column '{}'
must have the default value.", column.name());
+ }
}
}
diff --git
a/modules/catalog/src/test/java/org/apache/ignite/internal/catalog/CatalogTableTest.java
b/modules/catalog/src/test/java/org/apache/ignite/internal/catalog/CatalogTableTest.java
index 6a0b7428595..8d9f6d1d876 100644
---
a/modules/catalog/src/test/java/org/apache/ignite/internal/catalog/CatalogTableTest.java
+++
b/modules/catalog/src/test/java/org/apache/ignite/internal/catalog/CatalogTableTest.java
@@ -515,7 +515,7 @@ public class CatalogTableTest extends
BaseCatalogManagerTest {
@Test
public void testAddColumnWithNotExistingTable() {
- assertThat(manager.execute(addColumnParams(TABLE_NAME,
columnParams("key", INT32))),
+ assertThat(manager.execute(addColumnParams(TABLE_NAME,
columnParams("key", INT32, true))),
willThrowFast(CatalogValidationException.class, "Table with
name 'PUBLIC.test_table' not found."));
}
@@ -523,7 +523,7 @@ public class CatalogTableTest extends
BaseCatalogManagerTest {
public void testAddColumnWithExistingName() {
tryApplyAndExpectApplied(simpleTable(TABLE_NAME));
- assertThat(manager.execute(addColumnParams(TABLE_NAME,
columnParams("ID", INT32))),
+ assertThat(manager.execute(addColumnParams(TABLE_NAME,
columnParams("ID", INT32, true))),
willThrowFast(CatalogValidationException.class, "Column with
name 'ID' already exists."));
}
@@ -693,7 +693,7 @@ public class CatalogTableTest extends
BaseCatalogManagerTest {
public void addColumnIncrementsTableVersion() {
createSomeTable(TABLE_NAME);
- tryApplyAndExpectApplied(addColumnParams(TABLE_NAME,
columnParams("val2", INT32)));
+ tryApplyAndExpectApplied(addColumnParams(TABLE_NAME,
columnParams("val2", INT32, true)));
CatalogTableDescriptor table = actualTable(TABLE_NAME);
@@ -751,7 +751,7 @@ public class CatalogTableTest extends
BaseCatalogManagerTest {
manager.listen(CatalogEvent.TABLE_ALTER, eventListener);
// Try to add column without table.
- assertThat(manager.execute(addColumnParams(TABLE_NAME,
columnParams(NEW_COLUMN_NAME, INT32))),
+ assertThat(manager.execute(addColumnParams(TABLE_NAME,
columnParams(NEW_COLUMN_NAME, INT32, true))),
willThrow(CatalogValidationException.class, "Table with name
'PUBLIC.test_table' not found."));
verifyNoInteractions(eventListener);
@@ -759,7 +759,7 @@ public class CatalogTableTest extends
BaseCatalogManagerTest {
tryApplyAndExpectApplied(simpleTable(TABLE_NAME));
// Add column.
- tryApplyAndExpectApplied(addColumnParams(TABLE_NAME,
columnParams(NEW_COLUMN_NAME, INT32)));
+ tryApplyAndExpectApplied(addColumnParams(TABLE_NAME,
columnParams(NEW_COLUMN_NAME, INT32, true)));
verify(eventListener).notify(any(AddColumnEventParameters.class));
// Drop column.
diff --git
a/modules/catalog/src/test/java/org/apache/ignite/internal/catalog/commands/AlterTableAddColumnCommandValidationTest.java
b/modules/catalog/src/test/java/org/apache/ignite/internal/catalog/commands/AlterTableAddColumnCommandValidationTest.java
index e3df89d26f0..4fe6091e2a4 100644
---
a/modules/catalog/src/test/java/org/apache/ignite/internal/catalog/commands/AlterTableAddColumnCommandValidationTest.java
+++
b/modules/catalog/src/test/java/org/apache/ignite/internal/catalog/commands/AlterTableAddColumnCommandValidationTest.java
@@ -17,6 +17,7 @@
package org.apache.ignite.internal.catalog.commands;
+import static org.apache.ignite.internal.catalog.CatalogTestUtils.columnParams;
import static
org.apache.ignite.internal.testframework.IgniteTestUtils.assertThrowsWithCause;
import static org.apache.ignite.sql.ColumnType.INT32;
import static org.apache.ignite.sql.ColumnType.STRING;
@@ -34,7 +35,7 @@ import org.junit.jupiter.params.provider.MethodSource;
/**
* Tests to verify validation of {@link AlterTableAddColumnCommand}.
*/
-@SuppressWarnings({"DataFlowIssue", "ThrowableNotThrown"})
+@SuppressWarnings("ThrowableNotThrown")
public class AlterTableAddColumnCommandValidationTest extends
AbstractCommandValidationTest {
@ParameterizedTest(name = "[{index}] ''{argumentsWithNames}''")
@MethodSource("nullAndBlankStrings")
@@ -91,6 +92,7 @@ public class AlterTableAddColumnCommandValidationTest extends
AbstractCommandVal
ColumnParams column = ColumnParams.builder()
.name("C")
.type(INT32)
+ .nullable(true)
.build();
builder = fillProperties(builder).columns(List.of(column, column));
@@ -110,6 +112,7 @@ public class AlterTableAddColumnCommandValidationTest
extends AbstractCommandVal
ColumnParams.builder()
.name("NEW_C")
.type(INT32)
+ .nullable(true)
.build()
));
}
@@ -152,18 +155,18 @@ public class AlterTableAddColumnCommandValidationTest
extends AbstractCommandVal
void exceptionIsThrownIfColumnWithGivenNameAlreadyExists() {
String tableName = "TEST";
String columnName = "TEST";
- ColumnParams columnParams =
ColumnParams.builder().name(columnName).type(INT32).build();
+
Catalog catalog = catalogWithTable(builder -> builder
.schemaName(SCHEMA_NAME)
.tableName(tableName)
- .columns(List.of(columnParams))
+ .columns(List.of(columnParams(columnName, INT32)))
.primaryKey(primaryKey(columnName))
);
AlterTableAddColumnCommandBuilder builder =
AlterTableAddColumnCommand.builder()
.schemaName(SCHEMA_NAME)
.tableName(tableName)
- .columns(List.of(columnParams));
+ .columns(List.of(columnParams(columnName, INT32, true)));
assertThrowsWithCause(
() -> builder.build().get(new UpdateContext(catalog)),
@@ -176,18 +179,18 @@ public class AlterTableAddColumnCommandValidationTest
extends AbstractCommandVal
void
exceptionNotThrownIfColumnWithGivenNameAlreadyExistsWithIfColumnNotExists() {
String tableName = "TEST";
String columnName = "TEST";
- ColumnParams columnParams =
ColumnParams.builder().name(columnName).type(INT32).build();
+
Catalog catalog = catalogWithTable(builder -> builder
.schemaName(SCHEMA_NAME)
.tableName(tableName)
- .columns(List.of(columnParams))
+ .columns(List.of(columnParams(columnName, INT32)))
.primaryKey(primaryKey(columnName))
);
AlterTableAddColumnCommandBuilder builder =
AlterTableAddColumnCommand.builder()
.schemaName(SCHEMA_NAME)
.tableName(tableName)
- .columns(List.of(columnParams))
+ .columns(List.of(columnParams(columnName, INT32, true)))
.ifColumnNotExists(true);
assertDoesNotThrow(() -> builder.build().get(new
UpdateContext(catalog)));
@@ -219,6 +222,36 @@ public class AlterTableAddColumnCommandValidationTest
extends AbstractCommandVal
);
}
+ @Test
+ void cannotAddNonNullableColumnWithoutDefault() {
+ String tableName = "TEST";
+ String columnName = "TEST";
+ Catalog catalog = catalogWithTable(builder -> builder
+ .schemaName(SCHEMA_NAME)
+ .tableName(tableName)
+ .columns(List.of(columnParams("ID", INT32, false)))
+ .primaryKey(primaryKey("ID"))
+ );
+
+ ColumnParams columnParams = ColumnParams.builder()
+ .name(columnName)
+ .type(STRING)
+ .length(10)
+ .nullable(false)
+ .build();
+
+ AlterTableAddColumnCommandBuilder builder =
AlterTableAddColumnCommand.builder()
+ .schemaName(SCHEMA_NAME)
+ .tableName(tableName)
+ .columns(List.of(columnParams));
+
+ assertThrowsWithCause(
+ () -> builder.build().get(new UpdateContext(catalog)),
+ CatalogValidationException.class,
+ "Non-nullable column 'TEST' must have the default value"
+ );
+ }
+
@ParameterizedTest
@MethodSource("reservedSchemaNames")
void exceptionIsThrownIfSchemaIsReserved(String schema) {
diff --git
a/modules/partition-replicator/src/main/java/org/apache/ignite/internal/partition/replicator/schemacompat/SchemaCompatibilityValidator.java
b/modules/partition-replicator/src/main/java/org/apache/ignite/internal/partition/replicator/schemacompat/SchemaCompatibilityValidator.java
index 4dedbcb3541..c83e440674b 100644
---
a/modules/partition-replicator/src/main/java/org/apache/ignite/internal/partition/replicator/schemacompat/SchemaCompatibilityValidator.java
+++
b/modules/partition-replicator/src/main/java/org/apache/ignite/internal/partition/replicator/schemacompat/SchemaCompatibilityValidator.java
@@ -24,6 +24,9 @@ import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.apache.ignite.internal.catalog.CatalogService;
+import org.apache.ignite.internal.catalog.commands.DefaultValue;
+import org.apache.ignite.internal.catalog.commands.DefaultValue.ConstantValue;
+import org.apache.ignite.internal.catalog.commands.DefaultValue.Type;
import
org.apache.ignite.internal.catalog.descriptors.CatalogTableColumnDescriptor;
import org.apache.ignite.internal.catalog.descriptors.CatalogTableDescriptor;
import org.apache.ignite.internal.hlc.HybridTimestamp;
@@ -355,8 +358,12 @@ public class SchemaCompatibilityValidator {
}
for (CatalogTableColumnDescriptor column : diff.addedColumns()) {
- if (!column.nullable() && column.defaultValue() == null) {
- return new ValidationResult(ValidatorVerdict.INCOMPATIBLE,
"Not null column added without default value");
+ if (!column.nullable()) {
+ DefaultValue defaultValue = column.defaultValue();
+
+ if (defaultValue == null || (defaultValue.type() ==
Type.CONSTANT && ((ConstantValue) defaultValue).value() == null)) {
+ return new
ValidationResult(ValidatorVerdict.INCOMPATIBLE, "Not null column added without
default value");
+ }
}
}
diff --git
a/modules/partition-replicator/src/test/java/org/apache/ignite/internal/partition/replicator/schemacompat/SchemaCompatibilityValidatorTest.java
b/modules/partition-replicator/src/test/java/org/apache/ignite/internal/partition/replicator/schemacompat/SchemaCompatibilityValidatorTest.java
index 3048a74be0c..92397dcdc33 100644
---
a/modules/partition-replicator/src/test/java/org/apache/ignite/internal/partition/replicator/schemacompat/SchemaCompatibilityValidatorTest.java
+++
b/modules/partition-replicator/src/test/java/org/apache/ignite/internal/partition/replicator/schemacompat/SchemaCompatibilityValidatorTest.java
@@ -406,7 +406,7 @@ class SchemaCompatibilityValidatorTest extends
BaseIgniteAbstractTest {
return new CatalogTableColumnDescriptor(columnName, INT32, true,
DEFAULT_PRECISION, DEFAULT_SCALE, DEFAULT_LENGTH, null);
}
- private static CatalogTableColumnDescriptor intColumnWithDefault(String
columnName, int defaultValue) {
+ private static CatalogTableColumnDescriptor intColumnWithDefault(String
columnName, @Nullable Integer defaultValue) {
return new CatalogTableColumnDescriptor(
columnName,
INT32,
@@ -556,6 +556,16 @@ class SchemaCompatibilityValidatorTest extends
BaseIgniteAbstractTest {
),
"Not null column added without default value"
),
+ NON_NULL_WITH_DEFAULT_NULL(
+ List.of(
+ tableSchema(1, List.of(
+ )),
+ tableSchema(2, List.of(
+
intColumnWithDefault("NON_NULL_WITHOUT_DEFAULT_COL", null)
+ ))
+ ),
+ "Not null column added without default value"
+ ),
TYPE_CHANGED(
List.of(
tableSchema(1, List.of(
diff --git
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/client/ItThinClientSchemaSynchronizationTest.java
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/client/ItThinClientSchemaSynchronizationTest.java
index cf6f5ec4a92..c403d646144 100644
---
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/client/ItThinClientSchemaSynchronizationTest.java
+++
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/client/ItThinClientSchemaSynchronizationTest.java
@@ -19,7 +19,6 @@ package org.apache.ignite.internal.runner.app.client;
import static
org.apache.ignite.internal.testframework.IgniteTestUtils.assertThrowsWithCause;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.apache.ignite.client.IgniteClient;
@@ -89,7 +88,7 @@ public class ItThinClientSchemaSynchronizationTest extends
ItAbstractThinClientT
}
@Test
- void testClientUsesLatestSchemaOnReadWithNotNullColumn() {
+ void testClientUsesLatestSchemaOnReadWithNotNullColumnWithDefault() {
IgniteClient client = client();
IgniteSql sql = client.sql();
@@ -103,9 +102,8 @@ public class ItThinClientSchemaSynchronizationTest extends
ItAbstractThinClientT
recordView.insert(null, rec);
// Modify table and get old row.
- // It still has null value in the old column, even though it is not
allowed by the new schema.
- sql.execute("ALTER TABLE " + tableName + " ADD COLUMN NAME VARCHAR NOT
NULL");
- assertNull(recordView.get(null, rec).stringValue(1));
+ sql.execute("ALTER TABLE " + tableName + " ADD COLUMN NAME VARCHAR NOT
NULL DEFAULT '1'");
+ assertEquals("1", recordView.get(null, rec).stringValue(1));
}
@Test
@@ -151,7 +149,7 @@ public class ItThinClientSchemaSynchronizationTest extends
ItAbstractThinClientT
// Modify table, insert again - client will use old schema, throw
ClientSchemaMismatchException,
// reload schema, retry with new schema and succeed.
- sql.execute("ALTER TABLE " + tableName + " ADD COLUMN NAME VARCHAR NOT
NULL");
+ sql.execute("ALTER TABLE " + tableName + " ADD COLUMN NAME VARCHAR NOT
NULL DEFAULT '1'");
action.run();
assertEquals("name", recordView.get(null, rec).stringValue(1));
@@ -181,7 +179,7 @@ public class ItThinClientSchemaSynchronizationTest extends
ItAbstractThinClientT
// Modify table, insert again - client will use old schema, throw
ClientSchemaMismatchException,
// reload schema, retry with new schema and succeed.
- sql.execute("ALTER TABLE " + tableName + " ADD COLUMN NAME VARCHAR NOT
NULL");
+ sql.execute("ALTER TABLE " + tableName + " ADD COLUMN NAME VARCHAR NOT
NULL DEFAULT '1'");
action.run();
assertEquals("name", kvView.get(null, key).stringValue(0));
@@ -210,7 +208,7 @@ public class ItThinClientSchemaSynchronizationTest extends
ItAbstractThinClientT
// Modify table, insert again - client will use old schema, throw
ClientSchemaMismatchException,
// reload schema, retry with new schema and succeed.
- sql.execute("ALTER TABLE " + tableName + " ADD COLUMN NAME VARCHAR NOT
NULL");
+ sql.execute("ALTER TABLE " + tableName + " ADD COLUMN NAME VARCHAR NOT
NULL DEFAULT '1'");
action.run();
assertEquals("name", recordView.get(null, rec).name);
@@ -242,7 +240,7 @@ public class ItThinClientSchemaSynchronizationTest extends
ItAbstractThinClientT
// Modify table, insert again - client will use old schema, throw
ClientSchemaMismatchException,
// reload schema, retry with new schema and succeed.
- sql.execute("ALTER TABLE " + tableName + " ADD COLUMN NAME VARCHAR NOT
NULL");
+ sql.execute("ALTER TABLE " + tableName + " ADD COLUMN NAME VARCHAR NOT
NULL DEFAULT '1'");
action.run();
assertEquals("name", kvView.get(null, key).name);
diff --git
a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItAlterTableAlterColumnTest.java
b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItAlterTableAlterColumnTest.java
index 56b9ce01048..4232e6a0722 100644
---
a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItAlterTableAlterColumnTest.java
+++
b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItAlterTableAlterColumnTest.java
@@ -275,6 +275,59 @@ public class ItAlterTableAlterColumnTest extends
BaseSqlIntegrationTest {
}
}
+ @Test
+ public void dropDefaultNonNullableColumn() {
+ sql("CREATE TABLE t (id INT PRIMARY KEY)");
+ sql("INSERT INTO t VALUES (0)");
+ sql("ALTER TABLE t ADD COLUMN C1 VARCHAR NOT NULL DEFAULT 'a'");
+ sql("ALTER TABLE t ADD COLUMN C2 VARCHAR NOT NULL DEFAULT 'b'");
+
+ sql("ALTER TABLE t ALTER COLUMN C1 DROP DEFAULT");
+ sql("ALTER TABLE t ALTER COLUMN C2 SET DEFAULT NULL");
+
+ assertThrowsSqlException(Sql.CONSTRAINT_VIOLATION_ERR, "Column 'C1'
does not allow NULL",
+ () -> sql("INSERT INTO t (id, c2) VALUES (1, 'c')"));
+ assertThrowsSqlException(Sql.CONSTRAINT_VIOLATION_ERR, "Column 'C2'
does not allow NULL",
+ () -> sql("INSERT INTO t (id, c1) VALUES (1, 'c')"));
+
+ sql("INSERT INTO t (id, c1, c2) VALUES (1, 'a1', 'b1')");
+
+ sql("ALTER TABLE t ALTER COLUMN C1 SET DEFAULT 'a2'");
+ sql("ALTER TABLE t ALTER COLUMN C2 SET DEFAULT 'b2'");
+
+ sql("INSERT INTO t (id) VALUES (2)");
+
+ assertQuery("SELECT id, c1, c2 FROM t ORDER BY id")
+ .returns(0, "a", "b")
+ .returns(1, "a1", "b1")
+ .returns(2, "a2", "b2")
+ .check();
+ }
+
+ @Test
+ public void dropDefaultNullableColumn() {
+ sql("CREATE TABLE t (id INT PRIMARY KEY)");
+ sql("INSERT INTO t VALUES (0)");
+ sql("ALTER TABLE t ADD COLUMN C1 VARCHAR DEFAULT 'a'");
+ sql("ALTER TABLE t ADD COLUMN C2 VARCHAR DEFAULT 'b'");
+
+ sql("ALTER TABLE t ALTER COLUMN C1 DROP DEFAULT");
+ sql("ALTER TABLE t ALTER COLUMN C2 SET DEFAULT NULL");
+
+ sql("INSERT INTO t (id) VALUES (1)");
+
+ sql("ALTER TABLE t ALTER COLUMN C1 SET DEFAULT 'a2'");
+ sql("ALTER TABLE t ALTER COLUMN C2 SET DEFAULT 'b2'");
+
+ sql("INSERT INTO t (id) VALUES (2)");
+
+ assertQuery("SELECT id, c1, c2 FROM t ORDER BY id")
+ .returns(0, "a", "b")
+ .returns(1, null, null)
+ .returns(2, "a2", "b2")
+ .check();
+ }
+
@Test
public void setDataTypeSetDefault() {
sql("CREATE TABLE t (id int PRIMARY KEY, val int)");
diff --git
a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItAlterTableDdlTest.java
b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItAlterTableDdlTest.java
index 2fdd9310cea..c3481999f64 100644
---
a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItAlterTableDdlTest.java
+++
b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItAlterTableDdlTest.java
@@ -240,6 +240,28 @@ public class ItAlterTableDdlTest extends
BaseSqlIntegrationTest {
);
}
+ @Test
+ public void cannotAddNonNullableColumnWithoutDefault() {
+ sql("CREATE TABLE t (id VARCHAR PRIMARY KEY)");
+
+ assertThrowsSqlException(
+ STMT_VALIDATION_ERR,
+ "Non-nullable column 'VAL' must have the default value",
+ () -> sql("ALTER TABLE t ADD COLUMN val VARCHAR NOT NULL")
+ );
+
+ // Should not throw an exception since default value is provided.
+ sql("ALTER TABLE t ADD COLUMN val VARCHAR NOT NULL DEFAULT 'a'");
+
+ assertThrowsSqlException(
+ STMT_VALIDATION_ERR,
+ "Non-nullable column 'VAL2' must have the default value",
+ () -> sql("ALTER TABLE t ADD COLUMN val2 VARCHAR NOT NULL
DEFAULT NULL")
+ );
+
+ sql("ALTER TABLE t ADD COLUMN val2 VARCHAR DEFAULT NULL");
+ }
+
@Test
public void uuidDefault() {
UUID defaultUuid = UUID.randomUUID();
diff --git
a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItDmlTest.java
b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItDmlTest.java
index 6b7ea900f03..1e39144ac78 100644
---
a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItDmlTest.java
+++
b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItDmlTest.java
@@ -797,8 +797,6 @@ public class ItDmlTest extends BaseSqlIntegrationTest {
try {
sql(format("CREATE TABLE test (id INT PRIMARY KEY, val {}
DEFAULT {})", arg.sqlType, arg.sqlVal));
sql("INSERT INTO test (id) VALUES (1)");
- assertQuery("SELECT val FROM test WHERE id =
1").returns(arg.expectedVal).check();
-
sql("ALTER TABLE test ALTER COLUMN val DROP DEFAULT");
if (arg.sqlType.endsWith("NOT NULL")) {
@@ -808,6 +806,8 @@ public class ItDmlTest extends BaseSqlIntegrationTest {
sql("INSERT INTO test (id) VALUES (2)");
assertQuery("SELECT val FROM test WHERE id =
2").returns(null).check();
}
+
+ assertQuery("SELECT val FROM test WHERE id =
1").returns(arg.expectedVal).check();
} finally {
sql("DROP TABLE IF EXISTS test");
}
diff --git
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/SqlOutdatedPlanTest.java
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/SqlOutdatedPlanTest.java
index a4f18e5d128..f06e0dccf07 100644
---
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/SqlOutdatedPlanTest.java
+++
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/SqlOutdatedPlanTest.java
@@ -180,7 +180,7 @@ public class SqlOutdatedPlanTest extends
BaseIgniteAbstractTest {
return AlterTableAddColumnCommand.builder()
.schemaName(DEFAULT_SCHEMA_NAME)
.tableName("T1")
- .columns(List.of(columnParams(columnName, INT32)))
+ .columns(List.of(columnParams(columnName, INT32, true)))
.build();
}
diff --git
a/modules/table/src/testFixtures/java/org/apache/ignite/internal/table/TableTestUtils.java
b/modules/table/src/testFixtures/java/org/apache/ignite/internal/table/TableTestUtils.java
index eef93d46a1b..f4acf416e40 100644
---
a/modules/table/src/testFixtures/java/org/apache/ignite/internal/table/TableTestUtils.java
+++
b/modules/table/src/testFixtures/java/org/apache/ignite/internal/table/TableTestUtils.java
@@ -442,7 +442,7 @@ public class TableTestUtils {
CatalogCommand command = AlterTableAddColumnCommand.builder()
.schemaName(schemaName)
.tableName(tableName)
-
.columns(List.of(ColumnParams.builder().name(columnName).type(columnType).build()))
+
.columns(List.of(ColumnParams.builder().name(columnName).type(columnType).nullable(true).build()))
.build();
assertThat(catalogManager.execute(command),
willCompleteSuccessfully());