Skip to content

Commit 984207e

Browse files
committed
init
1 parent 546c8cb commit 984207e

File tree

9 files changed

+156
-55
lines changed

9 files changed

+156
-55
lines changed

ydb/library/yql/core/type_ann/type_ann_core.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12321,6 +12321,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
1232112321
Functions["OrderedSqlProject"] = &SqlProjectWrapper;
1232212322
Functions["SqlProjectItem"] = &SqlProjectItemWrapper;
1232312323
Functions["SqlProjectStarItem"] = &SqlProjectItemWrapper;
12324+
Functions["PgSelf"] = &PgSelfWrapper;
1232412325
Functions["PgStar"] = &PgStarWrapper;
1232512326
Functions["PgQualifiedStar"] = &PgQualifiedStarWrapper;
1232612327
Functions["PgColumnRef"] = &PgColumnRefWrapper;

ydb/library/yql/core/type_ann/type_ann_pg.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,16 @@ IGraphTransformer::TStatus InferPgCommonType(TPositionHandle pos, const TExprNod
191191
return IGraphTransformer::TStatus::Ok;
192192
}
193193

194+
IGraphTransformer::TStatus PgSelfWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
195+
Y_UNUSED(output);
196+
if (!EnsureArgsCount(*input, 0, ctx.Expr)) {
197+
return IGraphTransformer::TStatus::Error;
198+
}
199+
200+
input->SetTypeAnn(ctx.Expr.MakeType<TUnitExprType>());
201+
return IGraphTransformer::TStatus::Ok;
202+
}
203+
194204
IGraphTransformer::TStatus PgStarWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
195205
Y_UNUSED(output);
196206
if (!EnsureArgsCount(*input, 0, ctx.Expr)) {

ydb/library/yql/core/type_ann/type_ann_pg.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ bool IsPlainMemberOverArg(const TExprNode& expr, TStringBuf& memberName);
1919
const TTypeAnnotationNode* ToPgImpl(TPositionHandle pos, const TTypeAnnotationNode* type, TExprContext& ctx);
2020
const TTypeAnnotationNode* FromPgImpl(TPositionHandle pos, const TTypeAnnotationNode* type, TExprContext& ctx);
2121

22+
IGraphTransformer::TStatus PgSelfWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
2223
IGraphTransformer::TStatus PgStarWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
2324
IGraphTransformer::TStatus PgCallWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx);
2425
IGraphTransformer::TStatus PgBoolOpWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);

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

Lines changed: 75 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ class TConverter : public IPGParseEvents {
282282
ui32 ReadIndex = 0;
283283
TViews Views;
284284
TVector<TViews> CTE;
285+
const TView* CurrentRecursiveView = nullptr;
285286
TVector<NYql::TPosition> Positions = {NYql::TPosition()};
286287
THashMap<TString, TString> ParamNameToPgTypeName;
287288
THashMap<TString, Ydb::TypedValue> AutoParamValues;
@@ -450,7 +451,7 @@ class TConverter : public IPGParseEvents {
450451
}
451452
switch (NodeTag(node)) {
452453
case T_SelectStmt:
453-
return ParseSelectStmt(CAST_NODE(SelectStmt, node), false) != nullptr;
454+
return ParseSelectStmt(CAST_NODE(SelectStmt, node), {.Inner = false}) != nullptr;
454455
case T_InsertStmt:
455456
return ParseInsertStmt(CAST_NODE(InsertStmt, node)) != nullptr;
456457
case T_UpdateStmt:
@@ -759,15 +760,20 @@ class TConverter : public IPGParseEvents {
759760
using TTraverseSelectStack = TStack<std::pair<const SelectStmt*, bool>>;
760761
using TTraverseNodeStack = TStack<std::pair<const Node*, bool>>;
761762

763+
struct TSelectStmtSettings {
764+
bool Inner = true;
765+
mutable TVector<TAstNode*> TargetColumns;
766+
bool AllowEmptyResSet = false;
767+
bool EmitPgStar = false;
768+
bool FillTargetColumns = false;
769+
bool UnknownsAllowed = false;
770+
const TView* Recursive = nullptr;
771+
};
772+
762773
[[nodiscard]]
763774
TAstNode* ParseSelectStmt(
764775
const SelectStmt* value,
765-
bool inner,
766-
TVector <TAstNode*> targetColumns = {},
767-
bool allowEmptyResSet = false,
768-
bool emitPgStar = false,
769-
bool fillTargetColumns = false,
770-
bool unknownsAllowed = false
776+
const TSelectStmtSettings& selectSettings
771777
) {
772778
if (Settings.Mode == NSQLTranslation::ESqlMode::LIMITED_VIEW) {
773779
if (HasSelectInLimitedView) {
@@ -778,11 +784,14 @@ class TConverter : public IPGParseEvents {
778784
HasSelectInLimitedView = true;
779785
}
780786

781-
bool isValuesClauseOfInsertStmt = fillTargetColumns;
787+
bool isValuesClauseOfInsertStmt = selectSettings.FillTargetColumns;
782788

783789
State.CTE.emplace_back();
790+
auto prevRecursiveView = State.CurrentRecursiveView;
791+
State.CurrentRecursiveView = selectSettings.Recursive;
784792
Y_DEFER {
785793
State.CTE.pop_back();
794+
State.CurrentRecursiveView = prevRecursiveView;
786795
};
787796

788797
if (value->withClause) {
@@ -904,11 +913,11 @@ class TConverter : public IPGParseEvents {
904913
auto node = ListNodeNth(x->fromClause, i);
905914
if (NodeTag(node) != T_JoinExpr) {
906915
auto p = ParseFromClause(node);
907-
if (!p.Source) {
916+
if (!p) {
908917
return nullptr;
909918
}
910919

911-
AddFrom(p, fromList);
920+
AddFrom(*p, fromList);
912921
joinOps.push_back(QL());
913922
} else {
914923
TTraverseNodeStack traverseNodeStack;
@@ -920,10 +929,10 @@ class TConverter : public IPGParseEvents {
920929
if (NodeTag(top.first) != T_JoinExpr) {
921930
// leaf
922931
auto p = ParseFromClause(top.first);
923-
if (!p.Source) {
932+
if (!p) {
924933
return nullptr;
925934
}
926-
AddFrom(p, fromList);
935+
AddFrom(*p, fromList);
927936
traverseNodeStack.pop();
928937
} else {
929938
auto join = CAST_NODE(JoinExpr, top.first);
@@ -1105,7 +1114,7 @@ class TConverter : public IPGParseEvents {
11051114
return nullptr;
11061115
}
11071116

1108-
if (!allowEmptyResSet && (ListLength(x->valuesLists) == 0) && (ListLength(x->targetList) == 0)) {
1117+
if (!selectSettings.AllowEmptyResSet && (ListLength(x->valuesLists) == 0) && (ListLength(x->targetList) == 0)) {
11091118
AddError("SelectStmt: both values_list and target_list are not allowed to be empty");
11101119
return nullptr;
11111120
}
@@ -1133,11 +1142,11 @@ class TConverter : public IPGParseEvents {
11331142

11341143
TVector<TAstNode*> res;
11351144
ui32 i = 0;
1136-
if (emitPgStar && id + 1 == setItems.size()) {
1145+
if (selectSettings.EmitPgStar && id + 1 == setItems.size()) {
11371146
res.emplace_back(CreatePgStarResultItem());
11381147
i++;
11391148
}
1140-
bool maybeSelectWithJustSetConfig = !inner && !sort && windowItems.empty() && !having && !groupBy && !whereFilter && !x->distinctClause && ListLength(x->targetList) == 1;
1149+
bool maybeSelectWithJustSetConfig = !selectSettings.Inner && !sort && windowItems.empty() && !having && !groupBy && !whereFilter && !x->distinctClause && ListLength(x->targetList) == 1;
11411150
if (maybeSelectWithJustSetConfig) {
11421151
auto node = ListNodeNth(x->targetList, 0);
11431152
if (NodeTag(node) != T_ResTarget) {
@@ -1193,13 +1202,13 @@ class TConverter : public IPGParseEvents {
11931202
}
11941203

11951204
TVector<TAstNode*> setItemOptions;
1196-
if (emitPgStar) {
1205+
if (selectSettings.EmitPgStar) {
11971206
setItemOptions.push_back(QL(QA("emit_pg_star")));
11981207
}
1199-
if (!targetColumns.empty()) {
1200-
setItemOptions.push_back(QL(QA("target_columns"), QVL(targetColumns.data(), targetColumns.size())));
1208+
if (!selectSettings.TargetColumns.empty()) {
1209+
setItemOptions.push_back(QL(QA("target_columns"), QVL(selectSettings.TargetColumns.data(), selectSettings.TargetColumns.size())));
12011210
}
1202-
if (fillTargetColumns) {
1211+
if (selectSettings.FillTargetColumns) {
12031212
setItemOptions.push_back(QL(QA("fill_target_columns")));
12041213
}
12051214
if (ListLength(x->targetList) > 0) {
@@ -1247,7 +1256,7 @@ class TConverter : public IPGParseEvents {
12471256
setItemOptions.push_back(QL(QA("sort"), sort));
12481257
}
12491258

1250-
if (unknownsAllowed || hasCombiningQueries) {
1259+
if (selectSettings.UnknownsAllowed || hasCombiningQueries) {
12511260
setItemOptions.push_back(QL(QA("unknowns_allowed")));
12521261
}
12531262

@@ -1312,7 +1321,7 @@ class TConverter : public IPGParseEvents {
13121321

13131322
auto output = L(A("PgSelect"), QVL(selectOptions.data(), selectOptions.size()));
13141323

1315-
if (inner) {
1324+
if (selectSettings.Inner) {
13161325
return output;
13171326
}
13181327

@@ -1345,19 +1354,14 @@ class TConverter : public IPGParseEvents {
13451354
[[nodiscard]]
13461355
bool ParseWithClause(const WithClause* value) {
13471356
AT_LOCATION(value);
1348-
if (value->recursive) {
1349-
AddError("WithClause: recursion is not supported");
1350-
return false;
1351-
}
1352-
13531357
for (int i = 0; i < ListLength(value->ctes); ++i) {
13541358
auto object = ListNodeNth(value->ctes, i);
13551359
if (NodeTag(object) != T_CommonTableExpr) {
13561360
NodeNotImplemented(value, object);
13571361
return false;
13581362
}
13591363

1360-
if (!ParseCTE(CAST_NODE(CommonTableExpr, object))) {
1364+
if (!ParseCTE(CAST_NODE(CommonTableExpr, object), value->recursive)) {
13611365
return false;
13621366
}
13631367
}
@@ -1366,7 +1370,7 @@ class TConverter : public IPGParseEvents {
13661370
}
13671371

13681372
[[nodiscard]]
1369-
bool ParseCTE(const CommonTableExpr* value) {
1373+
bool ParseCTE(const CommonTableExpr* value, bool recursive) {
13701374
AT_LOCATION(value);
13711375
TView view;
13721376
view.Name = value->ctename;
@@ -1386,7 +1390,11 @@ class TConverter : public IPGParseEvents {
13861390
return false;
13871391
}
13881392

1389-
view.Source = ParseSelectStmt(CAST_NODE(SelectStmt, value->ctequery), true);
1393+
view.Source = ParseSelectStmt(CAST_NODE(SelectStmt, value->ctequery), {
1394+
.Inner = true,
1395+
.Recursive = recursive ? &view : nullptr
1396+
});
1397+
13901398
if (!view.Source) {
13911399
return false;
13921400
}
@@ -1531,12 +1539,14 @@ class TConverter : public IPGParseEvents {
15311539
const auto select = (value->selectStmt)
15321540
? ParseSelectStmt(
15331541
CAST_NODE(SelectStmt, value->selectStmt),
1534-
true,
1535-
targetColumns,
1536-
/*allowEmptyResSet=*/false,
1537-
/*emitPgStar=*/false,
1538-
/*fillTargetColumns=*/true,
1539-
/*unknownsAllowed=*/true)
1542+
{
1543+
.Inner = true,
1544+
.TargetColumns = targetColumns,
1545+
.AllowEmptyResSet = false,
1546+
.EmitPgStar = false,
1547+
.FillTargetColumns = true,
1548+
.UnknownsAllowed = true
1549+
})
15401550
: L(A("Void"));
15411551
if (!select) {
15421552
return nullptr;
@@ -1572,12 +1582,13 @@ class TConverter : public IPGParseEvents {
15721582
};
15731583
const auto select = ParseSelectStmt(
15741584
&selectStmt,
1575-
/* inner */ true,
1576-
/* targetColumns */{},
1577-
/* allowEmptyResSet */ true,
1578-
/*emitPgStar=*/true,
1579-
/*fillTargetColumns=*/false,
1580-
/*unknownsAllowed=*/true
1585+
{
1586+
.Inner = true,
1587+
.AllowEmptyResSet = true,
1588+
.EmitPgStar = true,
1589+
.FillTargetColumns = false,
1590+
.UnknownsAllowed = true
1591+
}
15811592
);
15821593
if (!select) {
15831594
return nullptr;
@@ -1675,7 +1686,7 @@ class TConverter : public IPGParseEvents {
16751686
}
16761687

16771688

1678-
view.Source = ParseSelectStmt(CAST_NODE(SelectStmt, value->query), true);
1689+
view.Source = ParseSelectStmt(CAST_NODE(SelectStmt, value->query), { .Inner = true });
16791690
if (!view.Source) {
16801691
return nullptr;
16811692
}
@@ -2478,10 +2489,10 @@ class TConverter : public IPGParseEvents {
24782489

24792490
TVector<TAstNode*> fromList;
24802491
auto p = ParseRangeVar(value->relation);
2481-
if (!p.Source) {
2492+
if (!p) {
24822493
return nullptr;
24832494
}
2484-
AddFrom(p, fromList);
2495+
AddFrom(*p, fromList);
24852496

24862497
TAstNode* whereFilter = nullptr;
24872498
if (value->whereClause) {
@@ -2878,7 +2889,7 @@ class TConverter : public IPGParseEvents {
28782889
return State.Statements.back();
28792890
}
28802891

2881-
TFromDesc ParseFromClause(const Node* node) {
2892+
TMaybe<TFromDesc> ParseFromClause(const Node* node) {
28822893
switch (NodeTag(node)) {
28832894
case T_RangeVar:
28842895
return ParseRangeVar(CAST_NODE(RangeVar, node));
@@ -2907,7 +2918,12 @@ class TConverter : public IPGParseEvents {
29072918
fromList.push_back(QL(L(A("Right!"), A(label)), aliasNode, colNamesTuple));
29082919
++State.ReadIndex;
29092920
} else {
2910-
fromList.push_back(QL(p.Source, aliasNode, colNamesTuple));
2921+
auto source = p.Source;
2922+
if (!source) {
2923+
source = L(A("PgSelf"));
2924+
}
2925+
2926+
fromList.push_back(QL(source, aliasNode, colNamesTuple));
29112927
}
29122928
}
29132929

@@ -3031,7 +3047,7 @@ class TConverter : public IPGParseEvents {
30313047
/* isSink */ true, isScheme);
30323048
}
30333049

3034-
TFromDesc ParseRangeVar(const RangeVar* value) {
3050+
TMaybe<TFromDesc> ParseRangeVar(const RangeVar* value) {
30353051
AT_LOCATION(value);
30363052

30373053
const TView* view = nullptr;
@@ -3043,6 +3059,10 @@ class TConverter : public IPGParseEvents {
30433059
break;
30443060
}
30453061
}
3062+
if (!view && State.CurrentRecursiveView && State.CurrentRecursiveView->Name == value->relname) {
3063+
view = State.CurrentRecursiveView;
3064+
}
3065+
30463066
if (!view) {
30473067
auto viewIt = State.Views.find(value->relname);
30483068
if (viewIt != State.Views.end()) {
@@ -3062,7 +3082,7 @@ class TConverter : public IPGParseEvents {
30623082
}
30633083

30643084
if (view) {
3065-
return { view->Source, alias, colnames.empty() ? view->ColNames : colnames, false };
3085+
return TFromDesc{view->Source, alias, colnames.empty() ? view->ColNames : colnames, false };
30663086
}
30673087

30683088
TString schemaname = value->schemaname;
@@ -3088,7 +3108,7 @@ class TConverter : public IPGParseEvents {
30883108
if (!s) {
30893109
return {};
30903110
}
3091-
return { s, alias, colnames, true };
3111+
return TFromDesc{ s, alias, colnames, true };
30923112
}
30933113
}
30943114

@@ -3108,7 +3128,7 @@ class TConverter : public IPGParseEvents {
31083128
L(A("Void")),
31093129
QL()
31103130
);
3111-
return {
3131+
return TFromDesc {
31123132
readExpr,
31133133
alias,
31143134
colnames,
@@ -3168,7 +3188,7 @@ class TConverter : public IPGParseEvents {
31683188
);
31693189
}
31703190

3171-
TFromDesc ParseRangeFunction(const RangeFunction* value) {
3191+
TMaybe<TFromDesc> ParseRangeFunction(const RangeFunction* value) {
31723192
if (value->lateral) {
31733193
AddError("RangeFunction: unsupported lateral");
31743194
return {};
@@ -3229,10 +3249,10 @@ class TConverter : public IPGParseEvents {
32293249
return {};
32303250
}
32313251

3232-
return { func, alias, colnames, false };
3252+
return TFromDesc{ func, alias, colnames, false };
32333253
}
32343254

3235-
TFromDesc ParseRangeSubselect(const RangeSubselect* value) {
3255+
TMaybe<TFromDesc> ParseRangeSubselect(const RangeSubselect* value) {
32363256
if (value->lateral) {
32373257
AddError("RangeSubselect: unsupported lateral");
32383258
return {};
@@ -3259,7 +3279,7 @@ class TConverter : public IPGParseEvents {
32593279
return {};
32603280
}
32613281

3262-
return { ParseSelectStmt(CAST_NODE(SelectStmt, value->subquery), true), alias, colnames, false };
3282+
return TFromDesc{ ParseSelectStmt(CAST_NODE(SelectStmt, value->subquery), { .Inner = true }), alias, colnames, false };
32633283
}
32643284

32653285
TAstNode* ParseNullTestExpr(const NullTest* value, const TExprSettings& settings) {
@@ -3811,7 +3831,7 @@ class TConverter : public IPGParseEvents {
38113831
rowTest = L(A("Void"));
38123832
}
38133833

3814-
auto select = ParseSelectStmt(CAST_NODE(SelectStmt, value->subselect), true);
3834+
auto select = ParseSelectStmt(CAST_NODE(SelectStmt, value->subselect), {.Inner = true});
38153835
if (!select) {
38163836
return nullptr;
38173837
}

0 commit comments

Comments
 (0)