Skip to content

Commit 89dfce5

Browse files
author
flown4qqqq
authored
Alter table drop not null (#6342)
1 parent 9b28941 commit 89dfce5

File tree

13 files changed

+343
-25
lines changed

13 files changed

+343
-25
lines changed

ydb/core/kqp/provider/yql_kikimr_exec.cpp

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1328,7 +1328,7 @@ class TKiSinkCallableExecutionTransformer : public TAsyncCallbackTransformer<TKi
13281328
bool hasNotNull = false;
13291329
if (columnTuple.Size() > 2) {
13301330
auto columnConstraints = columnTuple.Item(2).Cast<TCoNameValueTuple>();
1331-
for(const auto& constraint: columnConstraints.Value().Cast<TCoNameValueTupleList>()) {
1331+
for (const auto& constraint: columnConstraints.Value().Cast<TCoNameValueTupleList>()) {
13321332
if (constraint.Name().Value() == "serial") {
13331333
ctx.AddError(TIssue(ctx.GetPosition(constraint.Pos()),
13341334
"Column addition with serial data type is unsupported"));
@@ -1431,6 +1431,36 @@ class TKiSinkCallableExecutionTransformer : public TAsyncCallbackTransformer<TKi
14311431
for (auto family : families) {
14321432
alter_columns->set_family(TString(family.Value()));
14331433
}
1434+
} else if (alterColumnAction == "changeColumnConstraints") {
1435+
auto constraintsList = alterColumnList.Item(1).Cast<TExprList>();
1436+
1437+
if (constraintsList.Size() != 1) {
1438+
ctx.AddError(TIssue(ctx.GetPosition(constraintsList.Pos()), TStringBuilder()
1439+
<< "\". Several column constrains for a single column are not yet supported"));
1440+
return SyncError();
1441+
}
1442+
1443+
auto constraint = constraintsList.Item(0).Cast<TCoAtomList>();
1444+
1445+
if (constraint.Size() != 1) {
1446+
ctx.AddError(TIssue(ctx.GetPosition(constraint.Pos()), TStringBuilder()
1447+
<< "changeColumnConstraints can get exactly one token \\in {\"drop_not_null\", \"set_not_null\"}"));
1448+
return SyncError();
1449+
}
1450+
1451+
auto value = constraint.Item(0).Cast<TCoAtom>();
1452+
1453+
if (value == "drop_not_null") {
1454+
alter_columns->set_not_null(false);
1455+
} else if (value == "set_not_null") {
1456+
ctx.AddError(TIssue(ctx.GetPosition(constraintsList.Pos()), TStringBuilder()
1457+
<< "SET NOT NULL is currently not supported."));
1458+
return SyncError();
1459+
} else {
1460+
ctx.AddError(TIssue(ctx.GetPosition(constraintsList.Pos()), TStringBuilder()
1461+
<< "Unknown operation in changeColumnConstraints"));
1462+
return SyncError();
1463+
}
14341464
} else {
14351465
ctx.AddError(TIssue(ctx.GetPosition(alterColumnList.Pos()),
14361466
TStringBuilder() << "Unsupported action to alter column"));
@@ -1841,7 +1871,6 @@ class TKiSinkCallableExecutionTransformer : public TAsyncCallbackTransformer<TKi
18411871
auto resultNode = ctx.NewWorld(input->Pos());
18421872
return resultNode;
18431873
});
1844-
18451874
}
18461875

18471876
if (auto maybeCreate = TMaybeNode<TKiCreateTopic>(input)) {

ydb/core/kqp/provider/yql_kikimr_type_ann.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1403,6 +1403,26 @@ virtual TStatus HandleCreateTable(TKiCreateTable create, TExprContext& ctx) over
14031403
<< "\". Several column families for a single column are not yet supported"));
14041404
return TStatus::Error;
14051405
}
1406+
} else if (alterColumnAction == "changeColumnConstraints") {
1407+
auto constraintsList = alterColumnList.Item(1).Cast<TExprList>();
1408+
1409+
if (constraintsList.Size() != 1) {
1410+
ctx.AddError(TIssue(ctx.GetPosition(nameNode.Pos()), TStringBuilder()
1411+
<< "AlterTable : " << NCommon::FullTableName(table->Metadata->Cluster, table->Metadata->Name)
1412+
<< " Column: \"" << name
1413+
<< "\". Several column constrains for a single column are not yet supported"));
1414+
return TStatus::Error;
1415+
}
1416+
1417+
auto constraint = constraintsList.Item(0).Cast<TCoAtomList>();
1418+
1419+
if (constraint.Size() != 1) {
1420+
ctx.AddError(TIssue(ctx.GetPosition(nameNode.Pos()), TStringBuilder()
1421+
<< "AlterTable : " << NCommon::FullTableName(table->Metadata->Cluster, table->Metadata->Name)
1422+
<< " Column: \"" << name
1423+
<< "changeColumnConstraints can get exactly one token \\in {\"set_not_null\", \"drop_not_null\"}"));
1424+
return TStatus::Error;
1425+
}
14061426
} else {
14071427
ctx.AddError(TIssue(ctx.GetPosition(nameNode.Pos()),
14081428
TStringBuilder() << "Unsupported action to alter column"));

ydb/core/kqp/ut/service/kqp_qs_queries_ut.cpp

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3644,6 +3644,184 @@ Y_UNIT_TEST_SUITE(KqpQueryService) {
36443644
UNIT_ASSERT_C(replaceValues.IsSuccess(), replaceValues.GetIssues().ToString());
36453645
}
36463646
}
3647+
3648+
Y_UNIT_TEST(AlterTable_DropNotNull_Valid) {
3649+
NKikimrConfig::TAppConfig appConfig;
3650+
auto settings = TKikimrSettings()
3651+
.SetAppConfig(appConfig)
3652+
.SetWithSampleTables(false);
3653+
3654+
TKikimrRunner kikimr(settings);
3655+
Tests::NCommon::TLoggerInit(kikimr).Initialize();
3656+
3657+
auto client = kikimr.GetQueryClient();
3658+
3659+
{
3660+
auto createTable = client.ExecuteQuery(R"sql(
3661+
CREATE TABLE `/Root/test/alterDropNotNull` (
3662+
id Int32 NOT NULL,
3663+
val Int32 NOT NULL,
3664+
PRIMARY KEY (id)
3665+
);
3666+
)sql", NYdb::NQuery::TTxControl::NoTx()).ExtractValueSync();
3667+
UNIT_ASSERT_C(createTable.IsSuccess(), createTable.GetIssues().ToString());
3668+
}
3669+
3670+
{
3671+
auto initValues = client.ExecuteQuery(R"sql(
3672+
REPLACE INTO `/Root/test/alterDropNotNull` (id, val)
3673+
VALUES
3674+
( 1, 1 ),
3675+
( 2, 10 ),
3676+
( 3, 100 ),
3677+
( 4, 1000 ),
3678+
( 5, 10000 ),
3679+
( 6, 100000 ),
3680+
( 7, 1000000 );
3681+
)sql", NYdb::NQuery::TTxControl::BeginTx().CommitTx()).ExtractValueSync();
3682+
UNIT_ASSERT_C(initValues.IsSuccess(), initValues.GetIssues().ToString());
3683+
}
3684+
3685+
{
3686+
auto initNullValues = client.ExecuteQuery(R"sql(
3687+
REPLACE INTO `/Root/test/alterDropNotNull` (id, val)
3688+
VALUES
3689+
( 1, NULL ),
3690+
( 2, NULL );
3691+
)sql", NYdb::NQuery::TTxControl::BeginTx().CommitTx()).ExtractValueSync();
3692+
UNIT_ASSERT_C(!initNullValues.IsSuccess(), initNullValues.GetIssues().ToString());
3693+
UNIT_ASSERT_STRING_CONTAINS(initNullValues.GetIssues().ToString(), "Failed to convert type: Struct<'id':Int32,'val':Null> to Struct<'id':Int32,'val':Int32>");
3694+
}
3695+
3696+
{
3697+
auto setNull = client.ExecuteQuery(R"sql(
3698+
ALTER TABLE `/Root/test/alterDropNotNull`
3699+
ALTER COLUMN val DROP NOT NULL;
3700+
)sql", NYdb::NQuery::TTxControl::NoTx()).ExtractValueSync();
3701+
UNIT_ASSERT_C(setNull.IsSuccess(), setNull.GetIssues().ToString());
3702+
}
3703+
3704+
{
3705+
auto initNullValues = client.ExecuteQuery(R"sql(
3706+
REPLACE INTO `/Root/test/alterDropNotNull` (id, val)
3707+
VALUES
3708+
( 1, NULL ),
3709+
( 2, NULL );
3710+
)sql", NYdb::NQuery::TTxControl::BeginTx().CommitTx()).ExtractValueSync();
3711+
UNIT_ASSERT_C(initNullValues.IsSuccess(), initNullValues.GetIssues().ToString());
3712+
}
3713+
3714+
{
3715+
auto getValues = client.StreamExecuteQuery(R"sql(
3716+
SELECT *
3717+
FROM `/Root/test/alterDropNotNull`;
3718+
)sql", NYdb::NQuery::TTxControl::BeginTx().CommitTx()).ExtractValueSync();
3719+
3720+
UNIT_ASSERT_VALUES_EQUAL_C(getValues.GetStatus(), EStatus::SUCCESS, getValues.GetIssues().ToString());
3721+
CompareYson(
3722+
StreamResultToYson(getValues),
3723+
R"([[1;#];[2;#];[3;[100]];[4;[1000]];[5;[10000]];[6;[100000]];[7;[1000000]]])"
3724+
);
3725+
}
3726+
}
3727+
3728+
Y_UNIT_TEST(AlterTable_DropNotNull_WithSetFamily_Valid) {
3729+
NKikimrConfig::TAppConfig appConfig;
3730+
auto settings = TKikimrSettings()
3731+
.SetAppConfig(appConfig)
3732+
.SetWithSampleTables(false);
3733+
3734+
TKikimrRunner kikimr(settings);
3735+
Tests::NCommon::TLoggerInit(kikimr).Initialize();
3736+
3737+
auto client = kikimr.GetQueryClient();
3738+
3739+
{
3740+
auto createTable = client.ExecuteQuery(R"sql(
3741+
CREATE TABLE `/Root/test/alterDropNotNullWithSetFamily` (
3742+
id Int32 NOT NULL,
3743+
val1 Int32 FAMILY Family1 NOT NULL,
3744+
val2 Int32,
3745+
PRIMARY KEY (id),
3746+
3747+
FAMILY default (
3748+
DATA = "test",
3749+
COMPRESSION = "lz4"
3750+
),
3751+
FAMILY Family1 (
3752+
DATA = "test",
3753+
COMPRESSION = "off"
3754+
)
3755+
);
3756+
)sql", NYdb::NQuery::TTxControl::NoTx()).ExtractValueSync();
3757+
UNIT_ASSERT_C(createTable.IsSuccess(), createTable.GetIssues().ToString());
3758+
}
3759+
3760+
{
3761+
auto initValues = client.ExecuteQuery(R"sql(
3762+
REPLACE INTO `/Root/test/alterDropNotNullWithSetFamily` (id, val1, val2)
3763+
VALUES
3764+
( 1, 1, 1 ),
3765+
( 2, 10, 10 ),
3766+
( 3, 100, 100 ),
3767+
( 4, 1000, 1000 ),
3768+
( 5, 10000, 10000 ),
3769+
( 6, 100000, 100000 ),
3770+
( 7, 1000000, 1000000 );
3771+
)sql", NYdb::NQuery::TTxControl::BeginTx().CommitTx()).ExtractValueSync();
3772+
UNIT_ASSERT_C(initValues.IsSuccess(), initValues.GetIssues().ToString());
3773+
}
3774+
3775+
{
3776+
auto initNullValues = client.ExecuteQuery(R"sql(
3777+
REPLACE INTO `/Root/test/alterDropNotNullWithSetFamily` (id, val1, val2)
3778+
VALUES
3779+
( 1, NULL, 1 ),
3780+
( 2, NULL, 2 );
3781+
)sql", NYdb::NQuery::TTxControl::BeginTx().CommitTx()).ExtractValueSync();
3782+
UNIT_ASSERT_C(!initNullValues.IsSuccess(), initNullValues.GetIssues().ToString());
3783+
UNIT_ASSERT_STRING_CONTAINS(initNullValues.GetIssues().ToString(), "Failed to convert type: Struct<'id':Int32,'val1':Null,'val2':Int32> to Struct<'id':Int32,'val1':Int32,'val2':Int32?>");
3784+
}
3785+
3786+
{
3787+
auto setNull = client.ExecuteQuery(R"sql(
3788+
ALTER TABLE `/Root/test/alterDropNotNullWithSetFamily`
3789+
ALTER COLUMN val1 DROP NOT NULL;
3790+
)sql", NYdb::NQuery::TTxControl::NoTx()).ExtractValueSync();
3791+
UNIT_ASSERT_C(setNull.IsSuccess(), setNull.GetIssues().ToString());
3792+
}
3793+
3794+
{
3795+
auto setNull = client.ExecuteQuery(R"sql(
3796+
ALTER TABLE `/Root/test/alterDropNotNullWithSetFamily`
3797+
ALTER COLUMN val1 SET FAMILY Family1;
3798+
)sql", NYdb::NQuery::TTxControl::NoTx()).ExtractValueSync();
3799+
UNIT_ASSERT_C(setNull.IsSuccess(), setNull.GetIssues().ToString());
3800+
}
3801+
3802+
{
3803+
auto initNullValues = client.ExecuteQuery(R"sql(
3804+
REPLACE INTO `/Root/test/alterDropNotNullWithSetFamily` (id, val1, val2)
3805+
VALUES
3806+
( 1, NULL, 1 ),
3807+
( 2, NULL, 2 );
3808+
)sql", NYdb::NQuery::TTxControl::BeginTx().CommitTx()).ExtractValueSync();
3809+
UNIT_ASSERT_C(initNullValues.IsSuccess(), initNullValues.GetIssues().ToString());
3810+
}
3811+
3812+
{
3813+
auto getValues = client.StreamExecuteQuery(R"sql(
3814+
SELECT *
3815+
FROM `/Root/test/alterDropNotNullWithSetFamily`;
3816+
)sql", NYdb::NQuery::TTxControl::BeginTx().CommitTx()).ExtractValueSync();
3817+
3818+
UNIT_ASSERT_VALUES_EQUAL_C(getValues.GetStatus(), EStatus::SUCCESS, getValues.GetIssues().ToString());
3819+
CompareYson(
3820+
StreamResultToYson(getValues),
3821+
R"([[1;#;[1]];[2;#;[2]];[3;[100];[100]];[4;[1000];[1000]];[5;[10000];[10000]];[6;[100000];[100000]];[7;[1000000];[1000000]]])"
3822+
);
3823+
}
3824+
}
36473825
}
36483826

36493827
} // namespace NKqp

ydb/core/tx/schemeshard/schemeshard_info_types.cpp

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,9 @@ TTableInfo::TAlterDataPtr TTableInfo::CreateAlterData(
334334
return nullptr;
335335
}
336336

337-
if (!columnFamily && !col.HasDefaultFromSequence() && !col.HasEmptyDefault()) {
337+
bool isDropNotNull = col.HasNotNull(); // if has, then always false
338+
339+
if (!isDropNotNull && !columnFamily && !col.HasDefaultFromSequence() && !col.HasEmptyDefault()) {
338340
errStr = Sprintf("Nothing to alter for column '%s'", colName.data());
339341
return nullptr;
340342
}
@@ -408,6 +410,11 @@ TTableInfo::TAlterDataPtr TTableInfo::CreateAlterData(
408410

409411
TTableInfo::TColumn& column = alterData->Columns[colId];
410412
column = sourceColumn;
413+
414+
if (isDropNotNull) {
415+
column.NotNull = false;
416+
}
417+
411418
if (columnFamily) {
412419
column.Family = columnFamily->GetId();
413420
}
@@ -1447,18 +1454,20 @@ void TTableInfo::FinishAlter() {
14471454
AlterVersion = AlterData->AlterVersion;
14481455
NextColumnId = AlterData->NextColumnId;
14491456
for (const auto& col : AlterData->Columns) {
1457+
const auto& cinfo = col.second;
14501458
TColumn * oldCol = Columns.FindPtr(col.first);
14511459
if (oldCol) {
1452-
//oldCol->CreateVersion = col.second.CreateVersion;
1453-
oldCol->DeleteVersion = col.second.DeleteVersion;
1454-
oldCol->Family = col.second.Family;
1455-
oldCol->DefaultKind = col.second.DefaultKind;
1456-
oldCol->DefaultValue = col.second.DefaultValue;
1460+
//oldCol->CreateVersion = cinfo.CreateVersion;
1461+
oldCol->DeleteVersion = cinfo.DeleteVersion;
1462+
oldCol->Family = cinfo.Family;
1463+
oldCol->DefaultKind = cinfo.DefaultKind;
1464+
oldCol->DefaultValue = cinfo.DefaultValue;
1465+
oldCol->NotNull = cinfo.NotNull;
14571466
} else {
1458-
Columns[col.first] = col.second;
1459-
if (col.second.KeyOrder != (ui32)-1) {
1460-
KeyColumnIds.resize(Max<ui32>(KeyColumnIds.size(), col.second.KeyOrder + 1));
1461-
KeyColumnIds[col.second.KeyOrder] = col.first;
1467+
Columns[col.first] = cinfo;
1468+
if (cinfo.KeyOrder != (ui32)-1) {
1469+
KeyColumnIds.resize(Max<ui32>(KeyColumnIds.size(), cinfo.KeyOrder + 1));
1470+
KeyColumnIds[cinfo.KeyOrder] = col.first;
14621471
}
14631472
}
14641473
}

ydb/core/ydb_convert/table_description.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,11 @@ bool BuildAlterTableModifyScheme(const Ydb::Table::AlterTableRequest* req, NKiki
296296
for (const auto &alter : req->alter_columns()) {
297297
auto column = desc->AddColumns();
298298
column->SetName(alter.name());
299+
300+
if (alter.Hasnot_null()) {
301+
column->SetNotNull(alter.Getnot_null());
302+
}
303+
299304
if (!alter.family().empty()) {
300305
column->SetFamilyName(alter.family());
301306
}

ydb/library/yql/sql/v1/SQLv1.g.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,7 @@ alter_table_action:
669669
| alter_table_drop_changefeed
670670
| alter_table_rename_index_to
671671
| alter_table_alter_index
672+
| alter_table_alter_column_drop_not_null
672673
;
673674

674675
alter_external_table_stmt: ALTER EXTERNAL TABLE simple_table_ref alter_external_table_action (COMMA alter_external_table_action)*;
@@ -690,6 +691,7 @@ alter_table_store_action:
690691
alter_table_add_column: ADD COLUMN? column_schema;
691692
alter_table_drop_column: DROP COLUMN? an_id;
692693
alter_table_alter_column: ALTER COLUMN an_id SET family_relation;
694+
alter_table_alter_column_drop_not_null: ALTER COLUMN an_id DROP NOT NULL;
693695
alter_table_add_column_family: ADD family_entry;
694696
alter_table_alter_column_family: ALTER FAMILY an_id SET an_id family_setting_value;
695697
alter_table_set_table_setting_uncompat: SET an_id table_setting_value;

ydb/library/yql/sql/v1/format/sql_format_ut.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,8 @@ Y_UNIT_TEST_SUITE(CheckSqlFormatter) {
438438
"ALTER TABLE user\n\tDROP COLUMN user;\n"},
439439
{"alter table user alter column user set family user",
440440
"ALTER TABLE user\n\tALTER COLUMN user SET FAMILY user;\n"},
441+
{"alter table t alter column c drop not null",
442+
"ALTER TABLE t\n\tALTER COLUMN c DROP NOT NULL;\n"},
441443
{"alter table user add family user(user='foo')",
442444
"ALTER TABLE user\n\tADD FAMILY user (user = 'foo');\n"},
443445
{"alter table user alter family user set user 'foo'",

ydb/library/yql/sql/v1/node.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,15 @@ TColumnConstraints::TColumnConstraints(TNodePtr defaultExpr, bool nullable)
4545

4646

4747
TColumnSchema::TColumnSchema(TPosition pos, const TString& name, const TNodePtr& type, bool nullable,
48-
TVector<TIdentifier> families, bool serial, TNodePtr defaultExpr)
48+
TVector<TIdentifier> families, bool serial, TNodePtr defaultExpr, ETypeOfChange typeOfChange)
4949
: Pos(pos)
5050
, Name(name)
5151
, Type(type)
5252
, Nullable(nullable)
5353
, Families(families)
5454
, Serial(serial)
5555
, DefaultExpr(defaultExpr)
56+
, TypeOfChange(typeOfChange)
5657
{
5758
}
5859

ydb/library/yql/sql/v1/node.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -688,16 +688,24 @@ namespace NSQLTranslationV1 {
688688
};
689689

690690
struct TColumnSchema {
691+
enum class ETypeOfChange {
692+
Nothing,
693+
DropNotNullConstraint,
694+
SetNotNullConstraint, // todo flown4qqqq
695+
SetFamily
696+
};
697+
691698
TPosition Pos;
692699
TString Name;
693700
TNodePtr Type;
694701
bool Nullable;
695702
TVector<TIdentifier> Families;
696703
bool Serial;
697704
TNodePtr DefaultExpr;
705+
const ETypeOfChange TypeOfChange;
698706

699707
TColumnSchema(TPosition pos, const TString& name, const TNodePtr& type, bool nullable,
700-
TVector<TIdentifier> families, bool serial, TNodePtr defaultExpr);
708+
TVector<TIdentifier> families, bool serial, TNodePtr defaultExpr, ETypeOfChange typeOfChange = ETypeOfChange::Nothing);
701709
};
702710

703711
struct TColumns: public TSimpleRefCount<TColumns> {

0 commit comments

Comments
 (0)