Skip to content

Commit 837cdec

Browse files
authored
Merge 1790ae6 into bead065
2 parents bead065 + 1790ae6 commit 837cdec

File tree

9 files changed

+352
-44
lines changed

9 files changed

+352
-44
lines changed

ydb/core/kqp/common/kqp_resolve.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ struct TTableConstInfo : public TAtomicRefCount<TTableConstInfo> {
5858
Columns.emplace(phyColumn.GetId().GetName(), std::move(column));
5959
if (!phyColumn.GetDefaultFromSequence().empty()) {
6060
TString seq = phyColumn.GetDefaultFromSequence();
61-
if (!seq.StartsWith(Path)) {
61+
if (!seq.StartsWith("/")) {
6262
seq = Path + "/" + seq;
6363
}
6464

ydb/core/kqp/provider/yql_kikimr_exec.cpp

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1319,14 +1319,28 @@ class TKiSinkCallableExecutionTransformer : public TAsyncCallbackTransformer<TKi
13191319
auto columnName = columnTuple.Item(0).Cast<TCoAtom>();
13201320
alter_columns->set_name(TString(columnName));
13211321

1322-
auto families = columnTuple.Item(1).Cast<TCoAtomList>();
1323-
if (families.Size() > 1) {
1324-
ctx.AddError(TIssue(ctx.GetPosition(families.Pos()),
1325-
"Unsupported number of families"));
1326-
return SyncError();
1327-
}
1328-
for (auto family : families) {
1329-
alter_columns->set_family(TString(family.Value()));
1322+
auto alterColumnList = columnTuple.Item(1).Cast<TExprList>();
1323+
if (TString(alterColumnList.Item(0).Cast<TCoAtom>()) = "setDefault") {
1324+
auto setDefault = alterColumnList.Item(1).Cast<TCoAtomList>();
1325+
auto func = TString(setDefault.Item(0).Cast<TCoAtom>());
1326+
auto arg = TString(setDefault.Item(1).Cast<TCoAtom>());
1327+
if (func != "nextval") {
1328+
ctx.AddError(TIssue(ctx.GetPosition(alterColumnList.Pos()),
1329+
TStringBuilder() << "Unsupported function to set default: " << func));
1330+
return SyncError();
1331+
}
1332+
auto fromSequence = alter_columns->mutable_from_sequence();
1333+
fromSequence->set_name(arg);
1334+
} else {
1335+
auto families = columnTuple.Item(1).Cast<TCoAtomList>();
1336+
if (families.Size() > 1) {
1337+
ctx.AddError(TIssue(ctx.GetPosition(families.Pos()),
1338+
"Unsupported number of families"));
1339+
return SyncError();
1340+
}
1341+
for (auto family : families) {
1342+
alter_columns->set_family(TString(family.Value()));
1343+
}
13301344
}
13311345
}
13321346
} else if (name == "addColumnFamilies" || name == "alterColumnFamilies") {

ydb/core/kqp/provider/yql_kikimr_type_ann.cpp

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1361,13 +1361,29 @@ virtual TStatus HandleCreateTable(TKiCreateTable create, TExprContext& ctx) over
13611361
<< " Column: \"" << name << "\" does not exist"));
13621362
return TStatus::Error;
13631363
}
1364-
auto families = columnTuple.Item(1);
1365-
if (families.Cast<TCoAtomList>().Size() > 1) {
1366-
ctx.AddError(TIssue(ctx.GetPosition(nameNode.Pos()), TStringBuilder()
1367-
<< "AlterTable : " << NCommon::FullTableName(table->Metadata->Cluster, table->Metadata->Name)
1368-
<< " Column: \"" << name
1369-
<< "\". Several column families for a single column are not yet supported"));
1370-
return TStatus::Error;
1364+
if (TString(columnTuple.Item(1).Cast<TExprList>().Item(0).Cast<TCoAtom>()) == "setDefault") {
1365+
auto setDefault = columnTuple.Item(1).Cast<TExprList>().Item(1).Cast<TCoAtomList>();
1366+
auto func = TString(setDefault.Item(0).Cast<TCoAtom>());
1367+
auto arg = TString(setDefault.Item(1).Cast<TCoAtom>());
1368+
if (func != "nextval") {
1369+
ctx.AddError(TIssue(ctx.GetPosition(nameNode.Pos()),
1370+
TStringBuilder() << "Unsupported function to set default: " << func));
1371+
return TStatus::Error;
1372+
}
1373+
if (setDefault.Size() > 2) {
1374+
ctx.AddError(TIssue(ctx.GetPosition(nameNode.Pos()),
1375+
TStringBuilder() << "Function nextval has exactly one argument"));
1376+
return TStatus::Error;
1377+
}
1378+
} else {
1379+
auto families = columnTuple.Item(1);
1380+
if (families.Cast<TCoAtomList>().Size() > 1) {
1381+
ctx.AddError(TIssue(ctx.GetPosition(nameNode.Pos()), TStringBuilder()
1382+
<< "AlterTable : " << NCommon::FullTableName(table->Metadata->Cluster, table->Metadata->Name)
1383+
<< " Column: \"" << name
1384+
<< "\". Several column families for a single column are not yet supported"));
1385+
return TStatus::Error;
1386+
}
13711387
}
13721388
}
13731389
} else if (name == "addIndex") {

ydb/core/kqp/ut/pg/kqp_pg_ut.cpp

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2548,6 +2548,180 @@ Y_UNIT_TEST_SUITE(KqpPg) {
25482548
}
25492549
}
25502550

2551+
Y_UNIT_TEST(AlterColumnSetDefaultFromSequence) {
2552+
NKikimrConfig::TAppConfig appConfig;
2553+
appConfig.MutableTableServiceConfig()->SetEnablePreparedDdl(true);;
2554+
auto setting = NKikimrKqp::TKqpSetting();
2555+
auto serverSettings = TKikimrSettings()
2556+
.SetAppConfig(appConfig)
2557+
.SetKqpSettings({setting});
2558+
TKikimrRunner kikimr(
2559+
serverSettings.SetWithSampleTables(false));
2560+
auto clientConfig = NGRpcProxy::TGRpcClientConfig(kikimr.GetEndpoint());
2561+
auto client = kikimr.GetQueryClient();
2562+
2563+
auto session = client.GetSession().GetValueSync().GetSession();
2564+
2565+
auto tableClient = kikimr.GetTableClient();
2566+
auto tableClientSession = tableClient.CreateSession().GetValueSync().GetSession();
2567+
2568+
{
2569+
auto result = session.ExecuteQuery(R"(
2570+
--!syntax_pg
2571+
CREATE TABLE Pg (
2572+
key int4 PRIMARY KEY,
2573+
value int8
2574+
);
2575+
)", NYdb::NQuery::TTxControl::NoTx()).ExtractValueSync();
2576+
UNIT_ASSERT_C(result.IsSuccess(), result.GetIssues().ToString());
2577+
}
2578+
2579+
{
2580+
const auto query = Q_(R"(
2581+
--!syntax_pg
2582+
INSERT INTO Pg (key, value) values (1, 1);
2583+
)");
2584+
2585+
auto result = tableClientSession.ExecuteDataQuery(query, TTxControl::BeginTx().CommitTx()).ExtractValueSync();
2586+
UNIT_ASSERT_C(result.IsSuccess(), result.GetIssues().ToString());
2587+
}
2588+
2589+
{
2590+
const auto query = Q_(R"(
2591+
--!syntax_pg
2592+
SELECT * FROM Pg;
2593+
)");
2594+
2595+
auto result = tableClientSession.ExecuteDataQuery(query, TTxControl::BeginTx().CommitTx()).ExtractValueSync();
2596+
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString());
2597+
2598+
UNIT_ASSERT_C(!result.GetResultSets().empty(), "results are empty");
2599+
CompareYson(R"(
2600+
[["1";"1"]]
2601+
)", FormatResultSetYson(result.GetResultSet(0)));
2602+
}
2603+
2604+
{
2605+
auto result = session.ExecuteQuery(R"(
2606+
--!syntax_pg
2607+
ALTER TABLE Pg ALTER COLUMN value SET DEFAULT nextval('seq');
2608+
)", NYdb::NQuery::TTxControl::NoTx()).ExtractValueSync();
2609+
UNIT_ASSERT(!result.IsSuccess());
2610+
}
2611+
2612+
{
2613+
const auto queryCreate = R"(
2614+
--!syntax_pg
2615+
CREATE SEQUENCE IF NOT EXISTS seq1
2616+
START WITH 10
2617+
INCREMENT BY 2
2618+
MINVALUE 1
2619+
CACHE 3
2620+
CYCLE;
2621+
)";
2622+
2623+
auto resultCreate = session.ExecuteQuery(queryCreate, NYdb::NQuery::TTxControl::NoTx()).ExtractValueSync();
2624+
UNIT_ASSERT_C(resultCreate.IsSuccess(), resultCreate.GetIssues().ToString());
2625+
}
2626+
2627+
{
2628+
auto result = session.ExecuteQuery(R"(
2629+
--!syntax_pg
2630+
ALTER TABLE Pg ALTER COLUMN value SET DEFAULT nextval('seq1');
2631+
)", NYdb::NQuery::TTxControl::NoTx()).ExtractValueSync();
2632+
UNIT_ASSERT_C(result.IsSuccess(), result.GetIssues().ToString());
2633+
}
2634+
2635+
{
2636+
auto runtime = kikimr.GetTestServer().GetRuntime();
2637+
TActorId sender = runtime->AllocateEdgeActor();
2638+
auto describeResult = DescribeTable(&kikimr.GetTestServer(), sender, "/Root/Pg");
2639+
UNIT_ASSERT_VALUES_EQUAL(describeResult.GetStatus(), NKikimrScheme::StatusSuccess);
2640+
const auto& tableDescription = describeResult.GetPathDescription().GetTable();
2641+
2642+
for (const auto& column: tableDescription.GetColumns()) {
2643+
if (column.GetName() == "value") {
2644+
UNIT_ASSERT(column.HasDefaultFromSequence());
2645+
UNIT_ASSERT(column.GetDefaultFromSequence() == "/Root/seq1");
2646+
break;
2647+
}
2648+
}
2649+
}
2650+
2651+
{
2652+
const auto query = Q_(R"(
2653+
--!syntax_pg
2654+
INSERT INTO Pg (key) values (2), (3);
2655+
)");
2656+
2657+
auto result = tableClientSession.ExecuteDataQuery(query, TTxControl::BeginTx().CommitTx()).ExtractValueSync();
2658+
UNIT_ASSERT_C(result.IsSuccess(), result.GetIssues().ToString());
2659+
}
2660+
2661+
{
2662+
const auto query = Q_(R"(
2663+
--!syntax_pg
2664+
SELECT * FROM Pg;
2665+
)");
2666+
2667+
auto result = tableClientSession.ExecuteDataQuery(query, TTxControl::BeginTx().CommitTx()).ExtractValueSync();
2668+
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString());
2669+
2670+
UNIT_ASSERT_C(!result.GetResultSets().empty(), "results are empty");
2671+
CompareYson(R"(
2672+
[["1";"1"];["2";"10"];["3";"12"]]
2673+
)", FormatResultSetYson(result.GetResultSet(0)));
2674+
}
2675+
2676+
{
2677+
const auto queryCreate = R"(
2678+
--!syntax_pg
2679+
CREATE SEQUENCE IF NOT EXISTS seq2
2680+
START WITH 5
2681+
INCREMENT BY 3
2682+
MINVALUE 1
2683+
CACHE 3
2684+
CYCLE;
2685+
)";
2686+
2687+
auto resultCreate = session.ExecuteQuery(queryCreate, NYdb::NQuery::TTxControl::NoTx()).ExtractValueSync();
2688+
UNIT_ASSERT_C(resultCreate.IsSuccess(), resultCreate.GetIssues().ToString());
2689+
}
2690+
2691+
{
2692+
auto result = session.ExecuteQuery(R"(
2693+
--!syntax_pg
2694+
ALTER TABLE Pg ALTER COLUMN value SET DEFAULT nextval('seq2');
2695+
)", NYdb::NQuery::TTxControl::NoTx()).ExtractValueSync();
2696+
UNIT_ASSERT_C(result.IsSuccess(), result.GetIssues().ToString());
2697+
}
2698+
2699+
{
2700+
const auto query = Q_(R"(
2701+
--!syntax_pg
2702+
INSERT INTO Pg (key) values (4), (5);
2703+
)");
2704+
2705+
auto result = tableClientSession.ExecuteDataQuery(query, TTxControl::BeginTx().CommitTx()).ExtractValueSync();
2706+
UNIT_ASSERT_C(result.IsSuccess(), result.GetIssues().ToString());
2707+
}
2708+
2709+
{
2710+
const auto query = Q_(R"(
2711+
--!syntax_pg
2712+
SELECT * FROM Pg;
2713+
)");
2714+
2715+
auto result = tableClientSession.ExecuteDataQuery(query, TTxControl::BeginTx().CommitTx()).ExtractValueSync();
2716+
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString());
2717+
2718+
UNIT_ASSERT_C(!result.GetResultSets().empty(), "results are empty");
2719+
CompareYson(R"(
2720+
[["1";"1"];["2";"10"];["3";"12"];["4";"5"];["5";"8"]]
2721+
)", FormatResultSetYson(result.GetResultSet(0)));
2722+
}
2723+
}
2724+
25512725
Y_UNIT_TEST(TempTablesSessionsIsolation) {
25522726
NKikimrConfig::TAppConfig appConfig;
25532727
appConfig.MutableTableServiceConfig()->SetEnablePreparedDdl(true);

ydb/core/tx/schemeshard/schemeshard__operation_alter_table.cpp

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -535,36 +535,31 @@ class TAlterTable: public TSubOperation {
535535

536536
THashSet<TString> localSequences;
537537

538-
std::optional<TString> defaultFromSequence;
539538
for (const auto& column: alter.GetColumns()) {
540539
if (column.HasDefaultFromSequence()) {
541-
defaultFromSequence = column.GetDefaultFromSequence();
542-
}
543-
}
544-
545-
if (defaultFromSequence.has_value()) {
546-
Y_ABORT_UNLESS(alter.GetColumns().size() == 1);
547-
548-
const auto sequencePath = TPath::Resolve(*defaultFromSequence, context.SS);
549-
{
550-
const auto checks = sequencePath.Check();
551-
checks
552-
.NotEmpty()
553-
.NotUnderDomainUpgrade()
554-
.IsAtLocalSchemeShard()
555-
.IsResolved()
556-
.NotDeleted()
557-
.IsSequence()
558-
.NotUnderDeleting()
559-
.NotUnderOperation();
560-
561-
if (!checks) {
562-
result->SetError(checks.GetStatus(), checks.GetError());
563-
return result;
540+
TString defaultFromSequence = column.GetDefaultFromSequence();
541+
542+
const auto sequencePath = TPath::Resolve(defaultFromSequence, context.SS);
543+
{
544+
const auto checks = sequencePath.Check();
545+
checks
546+
.NotEmpty()
547+
.NotUnderDomainUpgrade()
548+
.IsAtLocalSchemeShard()
549+
.IsResolved()
550+
.NotDeleted()
551+
.IsSequence()
552+
.NotUnderDeleting()
553+
.NotUnderOperation();
554+
555+
if (!checks) {
556+
result->SetError(checks.GetStatus(), checks.GetError());
557+
return result;
558+
}
564559
}
565-
}
566560

567-
localSequences.insert(sequencePath.PathString());
561+
localSequences.insert(sequencePath.PathString());
562+
}
568563
}
569564

570565
TString errStr;

ydb/core/tx/schemeshard/schemeshard_info_types.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -290,9 +290,13 @@ TTableInfo::TAlterDataPtr TTableInfo::CreateAlterData(
290290
const TTableInfo::TColumn& sourceColumn = source->Columns[colId];
291291

292292
if (col.HasDefaultFromSequence()) {
293-
if (sourceColumn.PType.GetTypeId() != NScheme::NTypeIds::Int64) {
293+
if (sourceColumn.PType.GetTypeId() != NScheme::NTypeIds::Int64
294+
&& NPg::PgTypeIdFromTypeDesc(sourceColumn.PType.GetTypeDesc()) != INT8OID) {
295+
TString sequenceType = sourceColumn.PType.GetTypeId() == NScheme::NTypeIds::Pg
296+
? NPg::PgTypeNameFromTypeDesc(NPg::TypeDescFromPgTypeId(INT8OID))
297+
: NScheme::TypeName(NScheme::NTypeIds::Int64);
294298
errStr = Sprintf(
295-
"Sequence value type '%s' must be equal to the column type '%s'", "Int64",
299+
"Sequence value type '%s' must be equal to the column type '%s'", sequenceType.c_str(),
296300
NScheme::TypeName(sourceColumn.PType, sourceColumn.PTypeMod).c_str());
297301
return nullptr;
298302
}

ydb/core/ydb_convert/table_description.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,17 @@ bool BuildAlterTableModifyScheme(const Ydb::Table::AlterTableRequest* req, NKiki
298298
if (!alter.family().empty()) {
299299
column->SetFamilyName(alter.family());
300300
}
301+
switch (alter.default_value_case()) {
302+
case Ydb::Table::ColumnMeta::kFromSequence: {
303+
auto fromSequence = column->MutableDefaultFromSequence();
304+
TString sequenceName = alter.from_sequence().name();
305+
if (!IsStartWithSlash(sequenceName)) {
306+
*fromSequence = JoinPath({workingDir, sequenceName});
307+
}
308+
break;
309+
}
310+
default: break;
311+
}
301312
}
302313

303314
bool hadPartitionConfig = desc->HasPartitionConfig();

0 commit comments

Comments
 (0)