Skip to content

Commit a5879e5

Browse files
authored
Revert "Support returning list in delete statements (#1684)" (#1705)
This reverts commit 7f54b71.
1 parent 9f3b6ae commit a5879e5

9 files changed

+33
-130
lines changed

ydb/core/kqp/expr_nodes/kqp_expr_nodes.json

+2-8
Original file line numberDiff line numberDiff line change
@@ -509,18 +509,12 @@
509509
{
510510
"Name": "TKqlDeleteRows",
511511
"Base": "TKqlDeleteRowsBase",
512-
"Match": {"Type": "Callable", "Name": "KqlDeleteRows"},
513-
"Children": [
514-
{"Index": 2, "Name": "ReturningColumns", "Type": "TCoAtomList"}
515-
]
512+
"Match": {"Type": "Callable", "Name": "KqlDeleteRows"}
516513
},
517514
{
518515
"Name": "TKqlDeleteRowsIndex",
519516
"Base": "TKqlDeleteRowsBase",
520-
"Match": {"Type": "Callable", "Name": "KqlDeleteRowsIndex"},
521-
"Children": [
522-
{"Index": 2, "Name": "ReturningColumns", "Type": "TCoAtomList"}
523-
]
517+
"Match": {"Type": "Callable", "Name": "KqlDeleteRowsIndex"}
524518
},
525519
{
526520
"Name": "TKqpDeleteRows",

ydb/core/kqp/host/kqp_type_ann.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -830,7 +830,7 @@ TStatus AnnotateUpdateRows(const TExprNode::TPtr& node, TExprContext& ctx, const
830830
TStatus AnnotateDeleteRows(const TExprNode::TPtr& node, TExprContext& ctx, const TString& cluster,
831831
const TKikimrTablesData& tablesData)
832832
{
833-
if (!EnsureMaxArgsCount(*node, 3, ctx) && !EnsureMinArgsCount(*node, 2, ctx)) {
833+
if (!EnsureArgsCount(*node, 2, ctx)) {
834834
return TStatus::Error;
835835
}
836836

ydb/core/kqp/opt/kqp_opt_kql.cpp

-6
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,6 @@ TExprBase BuildDeleteTable(const TKiWriteTable& write, const TKikimrTableDescrip
429429
return Build<TKqlDeleteRows>(ctx, write.Pos())
430430
.Table(BuildTableMeta(tableData, write.Pos(), ctx))
431431
.Input(keysToDelete)
432-
.ReturningColumns(write.ReturningColumns())
433432
.Done();
434433
}
435434

@@ -439,7 +438,6 @@ TExprBase BuildDeleteTableWithIndex(const TKiWriteTable& write, const TKikimrTab
439438
return Build<TKqlDeleteRowsIndex>(ctx, write.Pos())
440439
.Table(BuildTableMeta(tableData, write.Pos(), ctx))
441440
.Input(keysToDelete)
442-
.ReturningColumns(write.ReturningColumns())
443441
.Done();
444442
}
445443

@@ -466,7 +464,6 @@ TExprBase BuildDeleteTable(const TKiDeleteTable& del, const TKikimrTableDescript
466464
return Build<TKqlDeleteRows>(ctx, del.Pos())
467465
.Table(BuildTableMeta(tableData, del.Pos(), ctx))
468466
.Input(keysToDelete)
469-
.ReturningColumns<TCoAtomList>().Build()
470467
.Done();
471468
}
472469

@@ -486,7 +483,6 @@ TExprBase BuildDeleteTableWithIndex(const TKiDeleteTable& del, const TKikimrTabl
486483
auto tableDelete = Build<TKqlDeleteRows>(ctx, del.Pos())
487484
.Table(BuildTableMeta(tableData, del.Pos(), ctx))
488485
.Input(ProjectColumns(rowsToDelete, pk, ctx))
489-
.ReturningColumns<TCoAtomList>().Build()
490486
.Done();
491487

492488
TVector<TExprBase> effects;
@@ -510,7 +506,6 @@ TExprBase BuildDeleteTableWithIndex(const TKiDeleteTable& del, const TKikimrTabl
510506
auto indexDelete = Build<TKqlDeleteRows>(ctx, del.Pos())
511507
.Table(indexMeta)
512508
.Input(ProjectColumns(rowsToDelete, indexTableColumns, ctx))
513-
.ReturningColumns<TCoAtomList>().Build()
514509
.Done();
515510

516511
effects.push_back(indexDelete);
@@ -704,7 +699,6 @@ TExprBase BuildUpdateTableWithIndex(const TKiUpdateTable& update, const TKikimrT
704699
auto indexDelete = Build<TKqlDeleteRows>(ctx, update.Pos())
705700
.Table(indexMeta)
706701
.Input(ProjectColumns(rowsToUpdate, indexTableColumns, ctx))
707-
.ReturningColumns<TCoAtomList>().Build()
708702
.Done();
709703

710704
effects.push_back(indexDelete);

ydb/core/kqp/opt/logical/kqp_opt_log_effects.cpp

-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@ TExprBase KqpDeleteOverLookup(const TExprBase& node, TExprContext& ctx, const TK
9797
return Build<TKqlDeleteRows>(ctx, deleteRows.Pos())
9898
.Table(deleteRows.Table())
9999
.Input(deleteInput.Cast())
100-
.ReturningColumns(deleteRows.ReturningColumns())
101100
.Done();
102101
}
103102

ydb/core/kqp/opt/physical/effects/kqp_opt_phy_delete_index.cpp

-2
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@ TExprBase KqpBuildDeleteIndexStages(TExprBase node, TExprContext& ctx, const TKq
8181
auto tableDelete = Build<TKqlDeleteRows>(ctx, del.Pos())
8282
.Table(del.Table())
8383
.Input(lookupKeys)
84-
.ReturningColumns(del.ReturningColumns())
8584
.Done();
8685

8786
TVector<TExprBase> effects;
@@ -103,7 +102,6 @@ TExprBase KqpBuildDeleteIndexStages(TExprBase node, TExprContext& ctx, const TKq
103102
auto indexDelete = Build<TKqlDeleteRows>(ctx, del.Pos())
104103
.Table(tableNode)
105104
.Input(deleteIndexKeys)
106-
.ReturningColumns<TCoAtomList>().Build()
107105
.Done();
108106

109107
effects.emplace_back(std::move(indexDelete));

ydb/core/kqp/opt/physical/effects/kqp_opt_phy_effects_rules.h

-3
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,6 @@ NYql::NNodes::TExprBase KqpBuildReturning(NYql::NNodes::TExprBase node, NYql::TE
1212
NYql::NNodes::TExprBase KqpRewriteReturningUpsert(NYql::NNodes::TExprBase node, NYql::TExprContext& ctx,
1313
const TKqpOptimizeContext& kqpCtx);
1414

15-
NYql::NNodes::TExprBase KqpRewriteReturningDelete(NYql::NNodes::TExprBase node, NYql::TExprContext& ctx,
16-
const TKqpOptimizeContext& kqpCtx);
17-
1815
NYql::NNodes::TExprBase KqpRewriteGenerateIfInsert(NYql::NNodes::TExprBase node, NYql::TExprContext& ctx,
1916
const TKqpOptimizeContext& kqpCtx);
2017

ydb/core/kqp/opt/physical/effects/kqp_opt_phy_returning.cpp

+26-88
Original file line numberDiff line numberDiff line change
@@ -15,33 +15,6 @@ TCoAtomList MakeColumnsList(Container rows, TExprContext& ctx, TPositionHandle p
1515
return Build<TCoAtomList>(ctx, pos).Add(columnsVector).Done();
1616
}
1717

18-
template<typename Container>
19-
TExprBase SelectFields(TExprBase node, Container fields, TExprContext& ctx, TPositionHandle pos) {
20-
TVector<TExprBase> items;
21-
for (auto&& field : fields) {
22-
TString name;
23-
24-
if constexpr (std::is_same_v<NYql::NNodes::TCoAtom&&, decltype(field)>) {
25-
name = field.Value();
26-
} else {
27-
name = field;
28-
}
29-
30-
auto tuple = Build<TCoNameValueTuple>(ctx, pos)
31-
.Name().Build(field)
32-
.template Value<TCoMember>()
33-
.Struct(node)
34-
.Name().Build(name)
35-
.Build()
36-
.Done();
37-
38-
items.emplace_back(tuple);
39-
}
40-
return Build<TCoAsStruct>(ctx, pos)
41-
.Add(items)
42-
.Done();
43-
}
44-
4518
TExprBase KqpBuildReturning(TExprBase node, TExprContext& ctx, const TKqpOptimizeContext& kqpCtx) {
4619
auto maybeReturning = node.Maybe<TKqlReturningList>();
4720
if (!maybeReturning) {
@@ -51,60 +24,46 @@ TExprBase KqpBuildReturning(TExprBase node, TExprContext& ctx, const TKqpOptimiz
5124
auto returning = maybeReturning.Cast();
5225
const auto& tableDesc = kqpCtx.Tables->ExistingTable(kqpCtx.Cluster, returning.Table().Path());
5326

54-
auto buildReturningRows = [&](TExprBase rows, TCoAtomList columns, TCoAtomList returningColumns) -> TExprBase {
55-
auto pos = rows.Pos();
27+
auto buildFromUpsert = [&](TMaybeNode<TKqlUpsertRows> upsert) -> TExprBase {
28+
auto rows = upsert.Cast().Input();
29+
auto pos = upsert.Input().Cast().Pos();
5630

5731
TSet<TString> inputColumns;
5832
TSet<TString> columnsToReadSet;
59-
for (auto&& column : columns) {
33+
34+
for (auto&& column : upsert.Columns().Cast()) {
6035
inputColumns.insert(TString(column.Value()));
6136
}
62-
for (auto&& column : returningColumns) {
37+
for (auto&& column : upsert.ReturningColumns().Cast()) {
6338
if (!inputColumns.contains(column) && !tableDesc.GetKeyColumnIndex(TString(column))) {
6439
columnsToReadSet.insert(TString(column));
6540
}
6641
}
67-
TMaybeNode<TExprBase> input = rows;
6842

69-
if (!columnsToReadSet.empty()) {
70-
auto payloadSelectorArg = TCoArgument(ctx.NewArgument(pos, "payload_selector_row"));
71-
TVector<TExprBase> payloadTuples;
72-
for (const auto& column : columns) {
73-
payloadTuples.emplace_back(
74-
Build<TCoNameValueTuple>(ctx, pos)
75-
.Name(column)
76-
.Value<TCoMember>()
77-
.Struct(payloadSelectorArg)
78-
.Name(column)
79-
.Build()
80-
.Done());
81-
}
43+
TMaybeNode<TExprBase> input = upsert.Input();
8244

83-
auto payloadSelector = Build<TCoLambda>(ctx, pos)
84-
.Args({payloadSelectorArg})
85-
.Body<TCoAsStruct>()
86-
.Add(payloadTuples)
87-
.Build()
88-
.Done();
45+
if (!columnsToReadSet.empty()) {
46+
TString upsertInputName = "upsertInput";
47+
TString tableInputName = "table";
8948

49+
auto payloadSelector = MakeRowsPayloadSelector(upsert.Columns().Cast(), tableDesc, pos, ctx);
9050
auto condenseResult = CondenseInputToDictByPk(input.Cast(), tableDesc, payloadSelector, ctx);
9151
if (!condenseResult) {
9252
return node;
9353
}
9454

9555
auto inputDictAndKeys = PrecomputeDictAndKeys(*condenseResult, pos, ctx);
56+
57+
TSet<TString> columnsToLookup = columnsToReadSet;
9658
for (auto&& column : tableDesc.Metadata->KeyColumnNames) {
9759
columnsToReadSet.insert(column);
9860
}
99-
TSet<TString> columnsToLookup = columnsToReadSet;
61+
10062
for (auto&& column : tableDesc.Metadata->KeyColumnNames) {
10163
columnsToReadSet.erase(column);
10264
}
10365
TCoAtomList additionalColumnsToRead = MakeColumnsList(columnsToReadSet, ctx, pos);
10466

105-
TCoArgument existingRow = Build<TCoArgument>(ctx, node.Pos())
106-
.Name("existing_row")
107-
.Done();
10867
auto prepareUpdateStage = Build<TDqStage>(ctx, pos)
10968
.Inputs()
11069
.Add(inputDictAndKeys.KeysPrecompute)
@@ -121,21 +80,27 @@ TExprBase KqpBuildReturning(TExprBase node, TExprContext& ctx, const TKqpOptimiz
12180
.Columns(MakeColumnsList(columnsToLookup, ctx, pos))
12281
.Build()
12382
.Lambda()
124-
.Args({existingRow})
83+
.Args({"existingRow"})
12584
.Body<TCoJust>()
12685
.Input<TCoFlattenMembers>()
12786
.Add()
12887
.Name().Build("")
12988
.Value<TCoUnwrap>() // Key should always exist in the dict
13089
.Optional<TCoLookup>()
13190
.Collection("dict")
132-
.Lookup(SelectFields(existingRow, tableDesc.Metadata->KeyColumnNames, ctx, pos))
91+
.Lookup<TCoExtractMembers>()
92+
.Input("existingRow")
93+
.Members(MakeColumnsList(tableDesc.Metadata->KeyColumnNames, ctx, pos))
94+
.Build()
13395
.Build()
13496
.Build()
13597
.Build()
13698
.Add()
13799
.Name().Build("")
138-
.Value(SelectFields(existingRow, additionalColumnsToRead, ctx, pos))
100+
.Value<TCoExtractMembers>()
101+
.Input("existingRow")
102+
.Members(additionalColumnsToRead)
103+
.Build()
139104
.Build()
140105
.Build()
141106
.Build()
@@ -163,27 +128,20 @@ TExprBase KqpBuildReturning(TExprBase node, TExprContext& ctx, const TKqpOptimiz
163128
for (auto item : maybeList.Cast()) {
164129
if (auto upsert = item.Maybe<TKqlUpsertRows>()) {
165130
if (upsert.Cast().Table().Raw() == returning.Table().Raw()) {
166-
return buildReturningRows(upsert.Input().Cast(), upsert.Columns().Cast(), returning.Columns());
167-
}
168-
}
169-
if (auto del = item.Maybe<TKqlDeleteRows>()) {
170-
if (del.Cast().Table().Raw() == returning.Table().Raw()) {
171-
return buildReturningRows(del.Input().Cast(), MakeColumnsList(tableDesc.Metadata->KeyColumnNames, ctx, node.Pos()), returning.Columns());
131+
return buildFromUpsert(upsert);
172132
}
173133
}
174134
}
175135
}
176136

177137
if (auto upsert = returning.Update().Maybe<TKqlUpsertRows>()) {
178-
return buildReturningRows(upsert.Input().Cast(), upsert.Columns().Cast(), returning.Columns());
179-
}
180-
if (auto del = returning.Update().Maybe<TKqlDeleteRows>()) {
181-
return buildReturningRows(del.Input().Cast(), MakeColumnsList(tableDesc.Metadata->KeyColumnNames, ctx, node.Pos()), returning.Columns());
138+
return buildFromUpsert(upsert);
182139
}
183140

184141
return node;
185142
}
186143

144+
187145
TExprBase KqpRewriteReturningUpsert(TExprBase node, TExprContext& ctx, const TKqpOptimizeContext&) {
188146
auto upsert = node.Cast<TKqlUpsertRows>();
189147
if (upsert.ReturningColumns().Empty()) {
@@ -206,24 +164,4 @@ TExprBase KqpRewriteReturningUpsert(TExprBase node, TExprContext& ctx, const TKq
206164
.Done();
207165
}
208166

209-
TExprBase KqpRewriteReturningDelete(TExprBase node, TExprContext& ctx, const TKqpOptimizeContext&) {
210-
auto del = node.Cast<TKqlDeleteRows>();
211-
if (del.ReturningColumns().Empty()) {
212-
return node;
213-
}
214-
215-
if (!del.Input().Maybe<TDqPrecompute>() && !del.Input().Maybe<TDqPhyPrecompute>()) {
216-
return node;
217-
}
218-
219-
return
220-
Build<TKqlDeleteRows>(ctx, del.Pos())
221-
.Input<TDqPrecompute>()
222-
.Input(del.Input())
223-
.Build()
224-
.Table(del.Table())
225-
.ReturningColumns<TCoAtomList>().Build()
226-
.Done();
227-
}
228-
229167
} // namespace NKikimr::NKqp::NOpt

ydb/core/kqp/opt/physical/kqp_opt_phy.cpp

+3-9
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,10 @@ class TKqpPhysicalOptTransformer : public TOptimizeTransformerBase {
123123

124124
AddHandler(2, &TDqStage::Match, HNDL(RewriteKqpReadTable));
125125
AddHandler(2, &TDqStage::Match, HNDL(RewriteKqpLookupTable));
126-
AddHandler(2, &TKqlUpsertRows::Match, HNDL(RewriteReturningUpsert));
127-
AddHandler(2, &TKqlDeleteRows::Match, HNDL(RewriteReturningDelete));
128126

129-
AddHandler(3, &TKqlReturningList::Match, HNDL(BuildReturning));
127+
AddHandler(3, &TKqlUpsertRows::Match, HNDL(RewriteReturningUpsert));
128+
129+
AddHandler(4, &TKqlReturningList::Match, HNDL(BuildReturning));
130130
#undef HNDL
131131

132132
SetGlobal(1u);
@@ -145,12 +145,6 @@ class TKqpPhysicalOptTransformer : public TOptimizeTransformerBase {
145145
return output;
146146
}
147147

148-
TMaybeNode<TExprBase> RewriteReturningDelete(TExprBase node, TExprContext& ctx) {
149-
TExprBase output = KqpRewriteReturningDelete(node, ctx, KqpCtx);
150-
DumpAppliedRule("RewriteReturningDelete", node.Ptr(), output.Ptr(), ctx);
151-
return output;
152-
}
153-
154148
TMaybeNode<TExprBase> RewriteGenerateIfInsert(TExprBase node, TExprContext& ctx) {
155149
TExprBase output = KqpRewriteGenerateIfInsert(node, ctx, KqpCtx);
156150
DumpAppliedRule("RewriteGenerateIfInsert", node.Ptr(), output.Ptr(), ctx);

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

+1-12
Original file line numberDiff line numberDiff line change
@@ -1534,24 +1534,13 @@ Y_UNIT_TEST_SUITE(KqpPg) {
15341534
{
15351535
const auto query = Q_(R"(
15361536
--!syntax_pg
1537-
DELETE FROM ReturningTableExtraValue WHERE key = 2 RETURNING key, value, value2;
1537+
UPDATE ReturningTableExtraValue SET value2 = 3 where key = 2 RETURNING *;
15381538
)");
15391539

15401540
auto result = session.ExecuteDataQuery(query, TTxControl::BeginTx().CommitTx()).GetValueSync();
15411541
UNIT_ASSERT(result.IsSuccess());
15421542
CompareYson(R"([["2";"4";"3"]])", FormatResultSetYson(result.GetResultSet(0)));
15431543
}
1544-
1545-
{
1546-
const auto query = Q_(R"(
1547-
--!syntax_pg
1548-
DELETE FROM ReturningTable WHERE key <= 3 RETURNING key, value;
1549-
)");
1550-
1551-
auto result = session.ExecuteDataQuery(query, TTxControl::BeginTx().CommitTx()).GetValueSync();
1552-
UNIT_ASSERT(result.IsSuccess());
1553-
CompareYson(R"([["2";"2"];["3";"2"];["1";"3"]])", FormatResultSetYson(result.GetResultSet(0)));
1554-
}
15551544
}
15561545

15571546
Y_UNIT_TEST(DropTablePg) {

0 commit comments

Comments
 (0)