@@ -177,7 +177,7 @@ TExprBase MakeNonexistingRowsFilter(const TDqPhyPrecompute& inputRows, const TDq
177
177
TExprBase MakeUpsertIndexRows (TKqpPhyUpsertIndexMode mode, const TDqPhyPrecompute& inputRows,
178
178
const TDqPhyPrecompute& lookupDict, const THashSet<TStringBuf>& inputColumns,
179
179
const THashSet<TStringBuf>& indexColumns, const TKikimrTableDescription& table, TPositionHandle pos,
180
- TExprContext& ctx)
180
+ TExprContext& ctx, bool opt )
181
181
{
182
182
// Check if we can update index table from just input data
183
183
bool allColumnFromInput = true ; // - indicate all data from input
@@ -250,14 +250,18 @@ TExprBase MakeUpsertIndexRows(TKqpPhyUpsertIndexMode mode, const TDqPhyPrecomput
250
250
.Build ()
251
251
.Done ()
252
252
);
253
+ TExprNode::TPtr member = payload.Ptr ();
254
+ if (opt) {
255
+ member = Build<TCoNth>(ctx, pos)
256
+ .Tuple (member)
257
+ .Index ().Build (0 )
258
+ .Done ().Ptr ();
259
+ }
253
260
presentKeyRow.emplace_back (
254
261
Build<TCoNameValueTuple>(ctx, pos)
255
262
.Name (columnAtom)
256
263
.Value <TCoMember>()
257
- .Struct <TCoNth>()
258
- .Tuple (payload)
259
- .Index ().Build (0 )
260
- .Build ()
264
+ .Struct (member)
261
265
.Name (columnAtom)
262
266
.Build ()
263
267
.Done ()
@@ -269,19 +273,29 @@ TExprBase MakeUpsertIndexRows(TKqpPhyUpsertIndexMode mode, const TDqPhyPrecomput
269
273
.Add (presentKeyRow)
270
274
.Done ();
271
275
276
+ TExprNode::TPtr b;
277
+
278
+ if (opt) {
279
+ b = Build<TCoFlatOptionalIf>(ctx, pos)
280
+ .Predicate <TCoNth>()
281
+ .Tuple (payload)
282
+ .Index ().Build (1 )
283
+ .Build ()
284
+ .Value <TCoJust>()
285
+ .Input (presentKeyRowStruct)
286
+ .Build ()
287
+ .Done ().Ptr ();
288
+ } else {
289
+ b = Build<TCoJust>(ctx, pos)
290
+ .Input (presentKeyRowStruct)
291
+ .Done ().Ptr ();
292
+ }
293
+
272
294
TExprBase flatmapBody = Build<TCoIfPresent>(ctx, pos)
273
295
.Optional (lookup)
274
296
.PresentHandler <TCoLambda>()
275
297
.Args (payload)
276
- .Body <TCoFlatOptionalIf>()
277
- .Predicate <TCoNth>()
278
- .Tuple (payload)
279
- .Index ().Build (1 )
280
- .Build ()
281
- .Value <TCoJust>()
282
- .Input (presentKeyRowStruct)
283
- .Build ()
284
- .Build ()
298
+ .Body (b)
285
299
.Build ()
286
300
.MissingValue <TCoJust>()
287
301
.Input <TCoAsStruct>()
@@ -531,12 +545,18 @@ TMaybeNode<TExprList> KqpPhyUpsertIndexEffectsImpl(TKqpPhyUpsertIndexMode mode,
531
545
auto indexTableColumnsWithoutData = indexTableColumns;
532
546
533
547
bool indexDataColumnsUpdated = false ;
548
+ bool optUpsert = true ;
534
549
for (const auto & column : indexDesc->DataColumns ) {
535
550
// TODO: Conder not fetching/updating data columns without input value.
536
551
YQL_ENSURE (indexTableColumns.emplace (column).second );
537
552
538
553
if (inputColumnsSet.contains (column)) {
539
554
indexDataColumnsUpdated = true ;
555
+ // 'skip index update' optimization checks given value equal to saved one
556
+ // so the type must be equatable to perform it
557
+ auto t = table.GetColumnType (column);
558
+ YQL_ENSURE (t);
559
+ optUpsert &= t->IsEquatable ();
540
560
}
541
561
}
542
562
@@ -695,7 +715,9 @@ TMaybeNode<TExprList> KqpPhyUpsertIndexEffectsImpl(TKqpPhyUpsertIndexMode mode,
695
715
696
716
if (indexKeyColumnsUpdated) {
697
717
// Have to delete old index value from index table in case when index key columns were updated
698
- auto deleteIndexKeys = MakeRowsFromTupleDict (lookupDictRecomputed, pk, indexTableColumnsWithoutData, pos, ctx);
718
+ auto deleteIndexKeys = optUpsert
719
+ ? MakeRowsFromTupleDict (lookupDictRecomputed, pk, indexTableColumnsWithoutData, pos, ctx)
720
+ : MakeRowsFromDict (lookupDict.Cast (), pk, indexTableColumnsWithoutData, pos, ctx);
699
721
700
722
auto indexDelete = Build<TKqlDeleteRows>(ctx, pos)
701
723
.Table (tableNode)
@@ -711,8 +733,11 @@ TMaybeNode<TExprList> KqpPhyUpsertIndexEffectsImpl(TKqpPhyUpsertIndexMode mode,
711
733
needIndexTableUpdate = needIndexTableUpdate || indexKeyColumnsUpdated || indexDataColumnsUpdated;
712
734
713
735
if (needIndexTableUpdate) {
714
- auto upsertIndexRows = MakeUpsertIndexRows (mode, inputRowsAndKeys.RowsPrecompute , lookupDictRecomputed,
715
- inputColumnsSet, indexTableColumns, table, pos, ctx);
736
+ auto upsertIndexRows = optUpsert
737
+ ? MakeUpsertIndexRows (mode, inputRowsAndKeys.RowsPrecompute , lookupDictRecomputed,
738
+ inputColumnsSet, indexTableColumns, table, pos, ctx, true )
739
+ : MakeUpsertIndexRows (mode, inputRowsAndKeys.RowsPrecompute , lookupDict.Cast (),
740
+ inputColumnsSet, indexTableColumns, table, pos, ctx, false );
716
741
717
742
auto indexUpsert = Build<TKqlUpsertRows>(ctx, pos)
718
743
.Table (tableNode)
0 commit comments