Skip to content

Commit ced7e50

Browse files
authored
Merge e2733d4 into 34ddb63
2 parents 34ddb63 + e2733d4 commit ced7e50

File tree

2 files changed

+104
-4
lines changed

2 files changed

+104
-4
lines changed

ydb/library/yql/sql/pg/pg_sql.cpp

+84-1
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,8 @@ class TConverter : public IPGParseEvents {
495495
return ParseTransactionStmt(CAST_NODE(TransactionStmt, node));
496496
case T_IndexStmt:
497497
return ParseIndexStmt(CAST_NODE(IndexStmt, node)) != nullptr;
498+
case T_CreateSeqStmt:
499+
return ParseCreateSeqStmt(CAST_NODE(CreateSeqStmt, node)) != nullptr;
498500
default:
499501
NodeNotImplemented(value, node);
500502
return false;
@@ -2650,6 +2652,87 @@ class TConverter : public IPGParseEvents {
26502652
return State.Statements.back();
26512653
}
26522654

2655+
[[nodiscard]]
2656+
TAstNode* ParseCreateSeqStmt(const CreateSeqStmt* value) {
2657+
2658+
std::vector<TAstNode*> options;
2659+
2660+
TString mode = (value->if_not_exists) ? "create_if_not_exists" : "create";
2661+
options.push_back(QL(QA("mode"), QA(mode)));
2662+
2663+
auto [sink, key] = ParseQualifiedPgObjectName(
2664+
value->sequence->catalogname,
2665+
value->sequence->schemaname,
2666+
value->sequence->relname,
2667+
"pgSequence"
2668+
);
2669+
2670+
if (!sink || !key) {
2671+
return nullptr;
2672+
}
2673+
2674+
const auto relPersistence = static_cast<NPg::ERelPersistence>(value->sequence->relpersistence);
2675+
switch (relPersistence) {
2676+
case NPg::ERelPersistence::Temp:
2677+
options.push_back(QL(QA("temporary")));
2678+
break;
2679+
case NPg::ERelPersistence::Unlogged:
2680+
AddError("UNLOGGED sequence not supported");
2681+
return nullptr;
2682+
break;
2683+
case NPg::ERelPersistence::Permanent:
2684+
break;
2685+
}
2686+
2687+
for (int i = 0; i < ListLength(value->options); ++i) {
2688+
auto rawNode = ListNodeNth(value->options, i);
2689+
2690+
switch (NodeTag(rawNode)) {
2691+
case T_DefElem: {
2692+
const auto* defElem = CAST_NODE(DefElem, rawNode);
2693+
TStringBuf nameElem = defElem->defname;
2694+
if (defElem->arg) {
2695+
switch (NodeTag(defElem->arg))
2696+
{
2697+
case T_Integer:
2698+
options.emplace_back(QL(QA(nameElem), QA(ToString(intVal(defElem->arg)))));
2699+
break;
2700+
case T_Float:
2701+
options.emplace_back(QL(QA(nameElem), QA(strVal(defElem->arg))));
2702+
break;
2703+
case T_TypeName: {
2704+
const auto* typeName = reinterpret_cast<PG_TypeName*>(defElem->arg);
2705+
options.emplace_back(QL(QA(nameElem),
2706+
QA(StrVal(ListNodeNth(typeName->names, ListLength(typeName->names) - 1)))));
2707+
break;
2708+
}
2709+
default:
2710+
NodeNotImplemented(defElem->arg);
2711+
return nullptr;
2712+
}
2713+
}
2714+
break;
2715+
}
2716+
default:
2717+
NodeNotImplemented(rawNode);
2718+
return nullptr;
2719+
}
2720+
}
2721+
2722+
if (value->for_identity) {
2723+
options.push_back(QL(QA("for_identity")));
2724+
}
2725+
2726+
options.push_back(QL(QA("owner_id"), QA(ToString(value->ownerId))));
2727+
2728+
State.Statements.push_back(
2729+
L(A("let"), A("world"),
2730+
L(A("Write!"), A("world"), sink, key, L(A("Void")),
2731+
QVL(options.data(), options.size()))));
2732+
2733+
return State.Statements.back();
2734+
}
2735+
26532736
TFromDesc ParseFromClause(const Node* node) {
26542737
switch (NodeTag(node)) {
26552738
case T_RangeVar:
@@ -4780,7 +4863,7 @@ TVector<NYql::TAstParseResult> PGToYqlStatements(const TString& query, const NSQ
47804863
TConverter converter(results, settings, query, stmtParseInfo, true);
47814864
NYql::PGParse(query, converter);
47824865
for (auto& res : results) {
4783-
res.ActualSyntaxType = NYql::ESyntaxType::Pg;
4866+
res.ActualSyntaxType = NYql::ESyntaxType::Pg;
47844867
}
47854868
return results;
47864869
}

ydb/library/yql/sql/pg/pg_sql_ut.cpp

+20-3
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ Y_UNIT_TEST_SUITE(PgSqlParsingOnly) {
166166
)";
167167
const auto expectedAst = NYql::ParseAst(program);
168168
UNIT_ASSERT_STRINGS_EQUAL(res.Root->ToString(), expectedAst.Root->ToString());
169-
}
169+
}
170170

171171
Y_UNIT_TEST(CreateTableStmt_PKAndNotNull) {
172172
auto res = PgSqlToYql("CREATE TABLE t (a int PRIMARY KEY NOT NULL, b text)");
@@ -265,6 +265,23 @@ Y_UNIT_TEST_SUITE(PgSqlParsingOnly) {
265265
UNIT_ASSERT_STRINGS_EQUAL(res.Root->ToString(), expectedAst.Root->ToString());
266266
}
267267

268+
Y_UNIT_TEST(CreateSeqStmt) {
269+
auto res = PgSqlToYql(
270+
"CREATE TEMP SEQUENCE IF NOT EXISTS seq AS integer START WITH 10 INCREMENT BY 2 NO MINVALUE NO MAXVALUE CACHE 3;");
271+
UNIT_ASSERT_C(res.Root, res.Issues.ToString());
272+
273+
TString program = R"(
274+
(
275+
(let world (Configure! world (DataSource 'config) 'OrderedColumns))
276+
(let world (Write! world (DataSink '"kikimr" '"") (Key '('pgObject (String 'seq) (String 'pgSequence))) (Void) '('('mode 'create_if_not_exists) '('temporary) '('as 'int4) '('start '10) '('increment '2) '('cache '3) '('owner_id '0))))
277+
(let world (CommitAll! world))
278+
(return world)
279+
)
280+
)";
281+
const auto expectedAst = NYql::ParseAst(program);
282+
UNIT_ASSERT_STRINGS_EQUAL(res.Root->ToString(), expectedAst.Root->ToString());
283+
}
284+
268285
Y_UNIT_TEST(VariableShowStmt) {
269286
auto res = PgSqlToYql("Show server_version_num");
270287
UNIT_ASSERT(res.Root);
@@ -482,7 +499,7 @@ SELECT COUNT(*) FROM public.t;");
482499
settings);
483500
UNIT_ASSERT_C(res.IsOk(), res.Issues.ToString());
484501
UNIT_ASSERT(res.Root);
485-
502+
486503
res = SqlToYqlWithMode(
487504
R"(select oid,
488505
typinput::int4 as typinput,
@@ -514,7 +531,7 @@ from pg_catalog.pg_type)",
514531
settings);
515532
UNIT_ASSERT(res.IsOk());
516533
UNIT_ASSERT(res.Root);
517-
534+
518535
res = SqlToYqlWithMode(
519536
R"(select set_config('search_path', 'public', false);)",
520537
NSQLTranslation::ESqlMode::QUERY,

0 commit comments

Comments
 (0)