@@ -226,4 +226,191 @@ Y_UNIT_TEST_SUITE(GenericProviderLookupActor) {
226
226
}
227
227
}
228
228
229
+ Y_UNIT_TEST (LookupWithErrors) {
230
+ auto alloc = std::make_shared<NKikimr::NMiniKQL::TScopedAlloc>(__LOCATION__, NKikimr::TAlignedPagePoolCounters (), true , false );
231
+ NKikimr::NMiniKQL::TMemoryUsageInfo memUsage (" TestMemUsage" );
232
+ NKikimr::NMiniKQL::THolderFactory holderFactory (alloc->Ref (), memUsage);
233
+ NKikimr::NMiniKQL::TTypeEnvironment typeEnv (*alloc);
234
+ NKikimr::NMiniKQL::TTypeBuilder typeBuilder (typeEnv);
235
+
236
+ auto loggerConfig = NYql::NProto::TLoggingConfig ();
237
+ loggerConfig.set_allcomponentslevel (::NYql::NProto::TLoggingConfig_ELevel::TLoggingConfig_ELevel_TRACE);
238
+ NYql::NLog::InitLogger (loggerConfig, false );
239
+
240
+ TTestActorRuntimeBase runtime (1 , 1 , true );
241
+ runtime.Initialize ();
242
+ auto edge = runtime.AllocateEdgeActor ();
243
+
244
+ NYql::TGenericDataSourceInstance dsi;
245
+ dsi.Setkind (NYql::EGenericDataSourceKind::YDB);
246
+ dsi.mutable_endpoint ()->Sethost (" some_host" );
247
+ dsi.mutable_endpoint ()->Setport (2135 );
248
+ dsi.Setdatabase (" some_db" );
249
+ dsi.Setuse_tls (true );
250
+ dsi.set_protocol (::NYql::EGenericProtocol::NATIVE);
251
+ auto token = dsi.mutable_credentials ()->mutable_token ();
252
+ token->Settype (" IAM" );
253
+ token->Setvalue (" TEST_TOKEN" );
254
+
255
+ auto connectorMock = std::make_shared<NYql::NConnector::NTest::TConnectorClientMock>();
256
+
257
+ // clang-format off
258
+ // step 1: ListSplits
259
+ {
260
+ ::testing::InSequence seq;
261
+ for (grpc::StatusCode readStatus : { grpc::StatusCode::UNAVAILABLE, grpc::StatusCode::DEADLINE_EXCEEDED, grpc::StatusCode::OK }) {
262
+ for (grpc::StatusCode listStatus : { grpc::StatusCode::UNAVAILABLE, grpc::StatusCode::DEADLINE_EXCEEDED, grpc::StatusCode::OK }) {
263
+ auto listBuilder = connectorMock->ExpectListSplits ();
264
+ listBuilder
265
+ .Select ()
266
+ .DataSourceInstance (dsi)
267
+ .What ()
268
+ .Column (" id" , Ydb::Type::UINT64)
269
+ .NullableColumn (" optional_id" , Ydb::Type::UINT64)
270
+ .NullableColumn (" string_value" , Ydb::Type::STRING)
271
+ .Done ()
272
+ .Table (" lookup_test" )
273
+ .Where ()
274
+ .Filter ()
275
+ .Disjunction ()
276
+ .Operand ()
277
+ .Conjunction ()
278
+ .Operand ().Equal ().Column (" id" ).Value <ui64>(2 ).Done ().Done ()
279
+ .Operand ().Equal ().Column (" optional_id" ).OptionalValue <ui64>(102 ).Done ().Done ()
280
+ .Done ()
281
+ .Done ()
282
+ .Operand ()
283
+ .Conjunction ()
284
+ .Operand ().Equal ().Column (" id" ).Value <ui64>(1 ).Done ().Done ()
285
+ .Operand ().Equal ().Column (" optional_id" ).OptionalValue <ui64>(101 ).Done ().Done ()
286
+ .Done ()
287
+ .Done ()
288
+ .Operand ()
289
+ .Conjunction ()
290
+ .Operand ().Equal ().Column (" id" ).Value <ui64>(0 ).Done ().Done ()
291
+ .Operand ().Equal ().Column (" optional_id" ).OptionalValue <ui64>(100 ).Done ().Done ()
292
+ .Done ()
293
+ .Done ()
294
+ .Done ()
295
+ .Done ()
296
+ .Done ()
297
+ .Done ()
298
+ .MaxSplitCount (1 )
299
+ ;
300
+ Cerr << " Simulate " << (int )listStatus << Endl;
301
+ if (listStatus != grpc::StatusCode::OK) {
302
+ listBuilder
303
+ .Status (NYdbGrpc::TGrpcStatus (listStatus, " Mocked Error" ))
304
+ ;
305
+ continue ;
306
+ }
307
+ listBuilder
308
+ .Result ()
309
+ .AddResponse (NewSuccess ())
310
+ .Description (" Actual split info is not important" )
311
+ ;
312
+ }
313
+
314
+ auto readBuilder = connectorMock->ExpectReadSplits ();
315
+ readBuilder
316
+ .DataSourceInstance (dsi)
317
+ .Filtering (NYql::NConnector::NApi::TReadSplitsRequest::FILTERING_MANDATORY)
318
+ .Split ()
319
+ .Description (" Actual split info is not important" )
320
+ .Done ()
321
+ ;
322
+ Cerr << " Simulate " << (int )readStatus << Endl;
323
+ if (readStatus != grpc::StatusCode::OK) {
324
+ readBuilder
325
+ .Status (NYdbGrpc::TGrpcStatus (readStatus, " Mocked Error" ))
326
+ ;
327
+ continue ;
328
+ }
329
+ readBuilder
330
+ .Result ()
331
+ .AddResponse (
332
+ MakeRecordBatch (
333
+ MakeArray<arrow::UInt64Builder, uint64_t >(" id" , {0 , 1 , 2 }, arrow::uint64 ()),
334
+ MakeArray<arrow::UInt64Builder, uint64_t >(" optional_id" , {100 , 101 , 103 }, arrow::uint64 ()), // the last value is intentially wrong
335
+ MakeArray<arrow::StringBuilder, std::string>(" string_value" , {" a" , " b" , " c" }, arrow::utf8 ())
336
+ ),
337
+ NewSuccess ()
338
+ )
339
+ ;
340
+ }
341
+ }
342
+ // clang-format on
343
+
344
+ NYql::Generic::TLookupSource lookupSourceSettings;
345
+ *lookupSourceSettings.mutable_data_source_instance () = dsi;
346
+ lookupSourceSettings.Settable (" lookup_test" );
347
+ lookupSourceSettings.SetServiceAccountId (" testsaid" );
348
+ lookupSourceSettings.SetServiceAccountIdSignature (" fake_signature" );
349
+
350
+ google::protobuf::Any packedLookupSource;
351
+ Y_ABORT_UNLESS (packedLookupSource.PackFrom (lookupSourceSettings));
352
+
353
+ NKikimr::NMiniKQL::TStructTypeBuilder keyTypeBuilder{typeEnv};
354
+ keyTypeBuilder.Add (" id" , typeBuilder.NewDataType (NYql::NUdf::EDataSlot::Uint64, false ));
355
+ keyTypeBuilder.Add (" optional_id" , typeBuilder.NewDataType (NYql::NUdf::EDataSlot::Uint64, true ));
356
+ NKikimr::NMiniKQL::TStructTypeBuilder outputypeBuilder{typeEnv};
357
+ outputypeBuilder.Add (" string_value" , typeBuilder.NewDataType (NYql::NUdf::EDataSlot::String, true ));
358
+
359
+ auto guard = Guard (*alloc.get ());
360
+ auto keyTypeHelper = std::make_shared<NYql::NDq::IDqAsyncLookupSource::TKeyTypeHelper>(keyTypeBuilder.Build ());
361
+
362
+ auto [lookupSource, actor] = NYql::NDq::CreateGenericLookupActor (
363
+ connectorMock,
364
+ std::make_shared<NYql::NTestCreds::TSecuredServiceAccountCredentialsFactory>(),
365
+ edge,
366
+ nullptr ,
367
+ alloc,
368
+ keyTypeHelper,
369
+ std::move (lookupSourceSettings),
370
+ keyTypeBuilder.Build (),
371
+ outputypeBuilder.Build (),
372
+ typeEnv,
373
+ holderFactory,
374
+ 1'000'000 );
375
+ auto lookupActor = runtime.Register (actor);
376
+
377
+ auto request = std::make_shared<NYql::NDq::IDqAsyncLookupSource::TUnboxedValueMap>(3 , keyTypeHelper->GetValueHash (), keyTypeHelper->GetValueEqual ());
378
+ for (size_t i = 0 ; i != 3 ; ++i) {
379
+ NYql::NUdf::TUnboxedValue* keyItems;
380
+ auto key = holderFactory.CreateDirectArrayHolder (2 , keyItems);
381
+ keyItems[0 ] = NYql::NUdf::TUnboxedValuePod (ui64 (i));
382
+ keyItems[1 ] = NYql::NUdf::TUnboxedValuePod (ui64 (100 + i));
383
+ request->emplace (std::move (key), NYql::NUdf::TUnboxedValue{});
384
+ }
385
+
386
+ guard.Release (); // let actors use alloc
387
+
388
+ auto callLookupActor = new TCallLookupActor (alloc, lookupActor, request);
389
+ runtime.Register (callLookupActor);
390
+
391
+ auto ev = runtime.GrabEdgeEventRethrow <NYql::NDq::IDqAsyncLookupSource::TEvLookupResult>(edge);
392
+ auto guard2 = Guard (*alloc.get ());
393
+ auto lookupResult = ev->Get ()->Result .lock ();
394
+ UNIT_ASSERT (lookupResult);
395
+
396
+ UNIT_ASSERT_EQUAL (3 , lookupResult->size ());
397
+ {
398
+ const auto * v = lookupResult->FindPtr (CreateStructValue (holderFactory, {0 , 100 }));
399
+ UNIT_ASSERT (v);
400
+ NYql::NUdf::TUnboxedValue val = v->GetElement (0 );
401
+ UNIT_ASSERT (val.AsStringRef () == TStringBuf (" a" ));
402
+ }
403
+ {
404
+ const auto * v = lookupResult->FindPtr (CreateStructValue (holderFactory, {1 , 101 }));
405
+ UNIT_ASSERT (v);
406
+ NYql::NUdf::TUnboxedValue val = v->GetElement (0 );
407
+ UNIT_ASSERT (val.AsStringRef () == TStringBuf (" b" ));
408
+ }
409
+ {
410
+ const auto * v = lookupResult->FindPtr (CreateStructValue (holderFactory, {2 , 102 }));
411
+ UNIT_ASSERT (v);
412
+ UNIT_ASSERT (!*v);
413
+ }
414
+ }
415
+
229
416
} // Y_UNIT_TEST_SUITE(GenericProviderLookupActor)
0 commit comments