11
11
12
12
#include < ydb/core/kqp/common/kqp_ru_calc.h>
13
13
#include < ydb/core/kqp/common/kqp_lwtrace_probes.h>
14
+ #include < ydb/core/kqp/runtime/kqp_transport.h>
14
15
15
16
#include < ydb/core/actorlib_impl/long_timer.h>
16
17
#include < ydb/core/base/appdata.h>
34
35
35
36
#include < ydb/library/yql/dq/actors/compute/dq_compute_actor.h>
36
37
#include < ydb/library/yql/dq/runtime/dq_transport.h>
38
+ #include < ydb/library/yql/dq/common/dq_serialized_batch.h>
37
39
#include < ydb/library/yql/providers/common/http_gateway/yql_http_gateway.h>
38
40
#include < ydb/library/yql/providers/common/structured_token/yql_token_builder.h>
39
41
#include < ydb/library/yql/public/issue/yql_issue.h>
45
47
#include < ydb/library/actors/core/hfunc.h>
46
48
#include < ydb/library/actors/core/log.h>
47
49
50
+
48
51
#include < util/generic/size_literals.h>
49
52
50
53
@@ -119,7 +122,7 @@ class TKqpExecuterBase : public TActorBootstrapped<TDerived> {
119
122
const NKikimrConfig::TTableServiceConfig::EChannelTransportVersion chanTransportVersion,
120
123
const NKikimrConfig::TTableServiceConfig::TAggregationConfig& aggregation,
121
124
TDuration maximalSecretsSnapshotWaitTime, const TIntrusivePtr<TUserRequestContext>& userRequestContext,
122
- ui64 spanVerbosity = 0 , TString spanName = " KqpExecuterBase" )
125
+ ui64 spanVerbosity = 0 , TString spanName = " KqpExecuterBase" , bool streamResult = false )
123
126
: Request(std::move(request))
124
127
, Database(database)
125
128
, UserToken(userToken)
@@ -130,6 +133,7 @@ class TKqpExecuterBase : public TActorBootstrapped<TDerived> {
130
133
, MaximalSecretsSnapshotWaitTime(maximalSecretsSnapshotWaitTime)
131
134
, AggregationSettings(aggregation)
132
135
, HasOlapTable(false )
136
+ , StreamResult(streamResult)
133
137
{
134
138
TasksGraph.GetMeta ().Snapshot = IKqpGateway::TKqpSnapshot (Request.Snapshot .Step , Request.Snapshot .TxId );
135
139
TasksGraph.GetMeta ().Arena = MakeIntrusive<NActors::TProtoArenaHolder>();
@@ -234,6 +238,128 @@ class TKqpExecuterBase : public TActorBootstrapped<TDerived> {
234
238
return true ;
235
239
}
236
240
241
+ struct TEvComputeChannelDataOOB {
242
+ NYql::NDqProto::TEvComputeChannelData Proto;
243
+ TRope Payload;
244
+
245
+ size_t Size () const {
246
+ return Proto.GetChannelData ().GetData ().GetRaw ().size () + Payload.size ();
247
+ }
248
+
249
+ ui32 RowCount () const {
250
+ return Proto.GetChannelData ().GetData ().GetRows ();
251
+ }
252
+ };
253
+
254
+ void HandleChannelData (NYql::NDq::TEvDqCompute::TEvChannelData::TPtr& ev) {
255
+ auto & record = ev->Get ()->Record ;
256
+ auto & channelData = record.GetChannelData ();
257
+ auto & channel = TasksGraph.GetChannel (channelData.GetChannelId ());
258
+ auto & task = TasksGraph.GetTask (channel.SrcTask );
259
+ const TActorId channelComputeActorId = ev->Sender ;
260
+ auto [it, _] = ResultChannelToComputeActor.emplace (channel.DstInputIndex , std::make_pair (ev->Sender , channel.Id ));
261
+
262
+ YQL_ENSURE (it->second .first == channelComputeActorId);
263
+
264
+ auto & txResult = ResponseEv->TxResults [channel.DstInputIndex ];
265
+ if (StreamResult && txResult.IsStream && txResult.QueryResultIndex .Defined ()) {
266
+
267
+ TEvComputeChannelDataOOB computeData;
268
+ computeData.Proto = std::move (ev->Get ()->Record );
269
+ if (computeData.Proto .GetChannelData ().GetData ().HasPayloadId ()) {
270
+ computeData.Payload = ev->Get ()->GetPayload (computeData.Proto .GetChannelData ().GetData ().GetPayloadId ());
271
+ }
272
+
273
+ const bool trailingResults = (
274
+ computeData.Proto .GetChannelData ().GetFinished () &&
275
+ (ResponseEv->TxResults .size () == 1 ) &&
276
+ Request.IsTrailingResultsAllowed ());
277
+
278
+ TVector<NYql::NDq::TDqSerializedBatch> batches (1 );
279
+ auto & batch = batches.front ();
280
+
281
+ batch.Proto = std::move (*computeData.Proto .MutableChannelData ()->MutableData ());
282
+ batch.Payload = std::move (computeData.Payload );
283
+
284
+ TKqpProtoBuilder protoBuilder{*AppData ()->FunctionRegistry };
285
+ auto resultSet = protoBuilder.BuildYdbResultSet (std::move (batches), txResult.MkqlItemType , txResult.ColumnOrder );
286
+
287
+ if (!trailingResults) {
288
+ auto streamEv = MakeHolder<TEvKqpExecuter::TEvStreamData>();
289
+ streamEv->Record .SetSeqNo (computeData.Proto .GetSeqNo ());
290
+ streamEv->Record .SetQueryResultIndex (*txResult.QueryResultIndex );
291
+ streamEv->Record .MutableResultSet ()->Swap (&resultSet);
292
+
293
+ LOG_E (" Send TEvStreamData to " << Target << " , seqNo: " << streamEv->Record .GetSeqNo ()
294
+ << " , nRows: " << streamEv->Record .GetResultSet ().rows ().size ());
295
+
296
+ this ->Send (Target, streamEv.Release ());
297
+
298
+ } else {
299
+ auto ackEv = MakeHolder<NYql::NDq::TEvDqCompute::TEvChannelDataAck>();
300
+ ackEv->Record .SetSeqNo (computeData.Proto .GetSeqNo ());
301
+ ackEv->Record .SetChannelId (channel.Id );
302
+ ackEv->Record .SetFreeSpace (50_MB);
303
+ this ->Send (channelComputeActorId, ackEv.Release (), /* TODO: undelivery */ 0 , /* cookie */ channel.Id );
304
+ txResult.TrailingResult .Swap (&resultSet);
305
+ LOG_E (" staging TEvStreamData to " << Target << " , seqNo: " << computeData.Proto .GetSeqNo ()
306
+ << " , nRows: " << txResult.TrailingResult .rows ().size ());
307
+ }
308
+
309
+ return ;
310
+ }
311
+
312
+ NYql::NDq::TDqSerializedBatch batch;
313
+ batch.Proto = std::move (*record.MutableChannelData ()->MutableData ());
314
+ if (batch.Proto .HasPayloadId ()) {
315
+ batch.Payload = ev->Get ()->GetPayload (batch.Proto .GetPayloadId ());
316
+ }
317
+
318
+ YQL_ENSURE (channel.DstTask == 0 );
319
+
320
+ if (Stats) {
321
+ Stats->ResultBytes += batch.Size ();
322
+ Stats->ResultRows += batch.RowCount ();
323
+ }
324
+
325
+ LOG_T (" Got result, channelId: " << channel.Id << " , shardId: " << task.Meta .ShardId
326
+ << " , inputIndex: " << channel.DstInputIndex << " , from: " << ev->Sender
327
+ << " , finished: " << channelData.GetFinished ());
328
+
329
+ ResponseEv->TakeResult (channel.DstInputIndex , std::move (batch));
330
+ LOG_T (" Send ack to channelId: " << channel.Id << " , seqNo: " << record.GetSeqNo () << " , to: " << ev->Sender );
331
+
332
+ auto ackEv = MakeHolder<NYql::NDq::TEvDqCompute::TEvChannelDataAck>();
333
+ ackEv->Record .SetSeqNo (record.GetSeqNo ());
334
+ ackEv->Record .SetChannelId (channel.Id );
335
+ ackEv->Record .SetFreeSpace (50_MB);
336
+ this ->Send (channelComputeActorId, ackEv.Release (), /* TODO: undelivery */ 0 , /* cookie */ channel.Id );
337
+ }
338
+
339
+ void HandleStreamAck (TEvKqpExecuter::TEvStreamDataAck::TPtr& ev) {
340
+ ui64 queryResultIndex = ev->Get ()->Record .GetQueryResultIndex ();
341
+ auto it = ResultChannelToComputeActor.find (queryResultIndex);
342
+ YQL_ENSURE (it != ResultChannelToComputeActor.end ());
343
+ const auto [channelComputeActorId, channelId] = it->second ;
344
+
345
+ ui64 seqNo = ev->Get ()->Record .GetSeqNo ();
346
+ i64 freeSpace = ev->Get ()->Record .GetFreeSpace ();
347
+
348
+ LOG_ERROR_S (*NActors::TlsActivationContext, NKikimrServices::KQP_EXECUTER, " TxId: " << TxId
349
+ << " , send ack to channelId: " << channelId
350
+ << " , seqNo: " << seqNo
351
+ << " , enough: " << ev->Get ()->Record .GetEnough ()
352
+ << " , freeSpace: " << freeSpace
353
+ << " , to: " << channelComputeActorId);
354
+
355
+ auto ackEv = MakeHolder<NYql::NDq::TEvDqCompute::TEvChannelDataAck>();
356
+ ackEv->Record .SetSeqNo (seqNo);
357
+ ackEv->Record .SetChannelId (channelId);
358
+ ackEv->Record .SetFreeSpace (freeSpace);
359
+ ackEv->Record .SetFinish (ev->Get ()->Record .GetEnough ());
360
+ this ->Send (channelComputeActorId, ackEv.Release (), /* TODO: undelivery */ 0 , /* cookie */ channelId);
361
+ }
362
+
237
363
void HandleComputeStats (NYql::NDq::TEvDqCompute::TEvState::TPtr& ev) {
238
364
TActorId computeActor = ev->Sender ;
239
365
auto & state = ev->Get ()->Record ;
@@ -1594,16 +1720,6 @@ class TKqpExecuterBase : public TActorBootstrapped<TDerived> {
1594
1720
return true ;
1595
1721
}
1596
1722
1597
- void InitializeChannelProxies () {
1598
- for (const auto & channel: TasksGraph.GetChannels ()) {
1599
- if (channel.DstTask ) {
1600
- continue ;
1601
- }
1602
-
1603
- CreateChannelProxy (channel);
1604
- }
1605
- }
1606
-
1607
1723
const IKqpGateway::TKqpSnapshot& GetSnapshot () const {
1608
1724
return TasksGraph.GetMeta ().Snapshot ;
1609
1725
}
@@ -1753,8 +1869,11 @@ class TKqpExecuterBase : public TActorBootstrapped<TDerived> {
1753
1869
const NKikimrConfig::TTableServiceConfig::TAggregationConfig AggregationSettings;
1754
1870
TVector<NKikimrKqp::TKqpNodeResources> ResourcesSnapshot;
1755
1871
bool HasOlapTable = false ;
1872
+ bool StreamResult = false ;
1756
1873
bool HasDatashardSourceScan = false ;
1757
1874
bool UnknownAffectedShardCount = false ;
1875
+
1876
+ THashMap<ui64, std::pair<TActorId, ui64>> ResultChannelToComputeActor;
1758
1877
THashMap<NYql::NDq::TStageId, THashMap<ui64, TShardInfo>> SourceScanStageIdToParititions;
1759
1878
1760
1879
private:
0 commit comments