|
1 | 1 | #include <ydb/core/kqp/ut/common/kqp_ut_common.h>
|
2 | 2 | #include <ydb/library/yql/sql/sql.h>
|
3 | 3 | #include <ydb/library/yql/utils/log/log.h>
|
| 4 | +#include <ydb/public/sdk/cpp/client/ydb_proto/accessor.h> |
4 | 5 |
|
5 | 6 | #include <util/folder/filelist.h>
|
6 | 7 |
|
7 | 8 | #include <format>
|
8 | 9 |
|
9 | 10 | using namespace NKikimr;
|
10 | 11 | using namespace NKikimr::NKqp;
|
| 12 | +using namespace NYdb; |
11 | 13 | using namespace NYdb::NTable;
|
12 | 14 |
|
13 | 15 | namespace {
|
@@ -75,8 +77,37 @@ TDataQueryResult ExecuteDataModificationQuery(TSession& session,
|
75 | 77 | return result;
|
76 | 78 | }
|
77 | 79 |
|
78 |
| -TString GetYsonResults(TSession& session, const TString& query, const TExecDataQuerySettings& settings = {}) { |
79 |
| - return FormatResultSetYson(ExecuteDataModificationQuery(session, query, settings).GetResultSet(0)); |
| 80 | +TValue GetSingleResult(const TDataQueryResult& rawResults) { |
| 81 | + auto resultSetParser = rawResults.GetResultSetParser(0); |
| 82 | + UNIT_ASSERT(resultSetParser.TryNextRow()); |
| 83 | + return resultSetParser.GetValue(0); |
| 84 | +} |
| 85 | + |
| 86 | +TValue GetSingleResult(TSession& session, const TString& query, const TExecDataQuerySettings& settings = {}) { |
| 87 | + return GetSingleResult(ExecuteDataModificationQuery(session, query, settings)); |
| 88 | +} |
| 89 | + |
| 90 | +TInstant GetTimestamp(const TValue& value) { |
| 91 | + return TValueParser(value).GetTimestamp(); |
| 92 | +} |
| 93 | + |
| 94 | +int GetInteger(const TValue& value) { |
| 95 | + return TValueParser(value).GetInt32(); |
| 96 | +} |
| 97 | + |
| 98 | +TMaybe<bool> GetFromCacheStat(const TQueryStats& stats) { |
| 99 | + const auto& proto = TProtoAccessor::GetProto(stats); |
| 100 | + if (!proto.Hascompilation()) { |
| 101 | + return Nothing(); |
| 102 | + } |
| 103 | + return proto.Getcompilation().Getfrom_cache(); |
| 104 | +} |
| 105 | + |
| 106 | +void AssertFromCache(const TMaybe<TQueryStats>& stats, bool expectedValue) { |
| 107 | + UNIT_ASSERT(stats.Defined()); |
| 108 | + const auto isFromCache = GetFromCacheStat(*stats); |
| 109 | + UNIT_ASSERT_C(isFromCache.Defined(), stats->ToString()); |
| 110 | + UNIT_ASSERT_VALUES_EQUAL_C(*isFromCache, expectedValue, stats->ToString()); |
80 | 111 | }
|
81 | 112 |
|
82 | 113 | void CompareResults(const TDataQueryResult& first, const TDataQueryResult& second) {
|
@@ -384,6 +415,53 @@ Y_UNIT_TEST_SUITE(TSelectFromViewTest) {
|
384 | 415 | ExecuteDataDefinitionQuery(session, ReadWholeFile(pathPrefix + "drop_view.sql"));
|
385 | 416 | }
|
386 | 417 | }
|
| 418 | + |
| 419 | + Y_UNIT_TEST(QueryCacheIsUpdated) { |
| 420 | + TKikimrRunner kikimr(TKikimrSettings().SetWithSampleTables(false)); |
| 421 | + EnableViewsFeatureFlag(kikimr); |
| 422 | + auto session = kikimr.GetTableClient().CreateSession().GetValueSync().GetSession(); |
| 423 | + |
| 424 | + constexpr const char* viewName = "TheView"; |
| 425 | + |
| 426 | + const auto getCreationQuery = [&viewName](const char* innerQuery) -> TString { |
| 427 | + return std::format(R"( |
| 428 | + CREATE VIEW {} WITH (security_invoker = TRUE) AS {}; |
| 429 | + )", |
| 430 | + viewName, |
| 431 | + innerQuery |
| 432 | + ); |
| 433 | + }; |
| 434 | + constexpr const char* firstInnerQuery = "SELECT 1"; |
| 435 | + ExecuteDataDefinitionQuery(session, getCreationQuery(firstInnerQuery)); |
| 436 | + |
| 437 | + const TString selectFromViewQuery = std::format(R"( |
| 438 | + SELECT * FROM {}; |
| 439 | + )", |
| 440 | + viewName |
| 441 | + ); |
| 442 | + TExecDataQuerySettings queryExecutionSettings; |
| 443 | + queryExecutionSettings.KeepInQueryCache(true); |
| 444 | + queryExecutionSettings.CollectQueryStats(ECollectQueryStatsMode::Basic); |
| 445 | + ExecuteDataModificationQuery(session, selectFromViewQuery, queryExecutionSettings); |
| 446 | + // make sure the server side cache is working by calling the same query twice |
| 447 | + const auto cachedQueryRawResult = ExecuteDataModificationQuery(session, selectFromViewQuery, queryExecutionSettings); |
| 448 | + AssertFromCache(cachedQueryRawResult.GetStats(), true); |
| 449 | + UNIT_ASSERT_VALUES_EQUAL(GetInteger(GetSingleResult(cachedQueryRawResult)), 1); |
| 450 | + |
| 451 | + // recreate the view with a different query inside |
| 452 | + ExecuteDataDefinitionQuery(session, std::format(R"( |
| 453 | + DROP VIEW {}; |
| 454 | + )", |
| 455 | + viewName |
| 456 | + ) |
| 457 | + ); |
| 458 | + constexpr const char* secondInnerQuery = "SELECT 2"; |
| 459 | + ExecuteDataDefinitionQuery(session, getCreationQuery(secondInnerQuery)); |
| 460 | + |
| 461 | + const auto secondCallRawResult = ExecuteDataModificationQuery(session, selectFromViewQuery, queryExecutionSettings); |
| 462 | + AssertFromCache(secondCallRawResult.GetStats(), false); |
| 463 | + UNIT_ASSERT_VALUES_EQUAL(GetInteger(GetSingleResult(secondCallRawResult)), 2); |
| 464 | + } |
387 | 465 | }
|
388 | 466 |
|
389 | 467 | Y_UNIT_TEST_SUITE(TEvaluateExprInViewTest) {
|
@@ -414,9 +492,9 @@ Y_UNIT_TEST_SUITE(TEvaluateExprInViewTest) {
|
414 | 492 | TExecDataQuerySettings queryExecutionSettings;
|
415 | 493 | queryExecutionSettings.KeepInQueryCache(true);
|
416 | 494 | const auto executeTwice = [&](const TString& query) {
|
417 |
| - return TVector<TString>{ |
418 |
| - GetYsonResults(session, query, queryExecutionSettings), |
419 |
| - GetYsonResults(session, query, queryExecutionSettings) |
| 495 | + return TVector<TInstant>{ |
| 496 | + GetTimestamp(GetSingleResult(session, query, queryExecutionSettings)), |
| 497 | + GetTimestamp(GetSingleResult(session, query, queryExecutionSettings)) |
420 | 498 | };
|
421 | 499 | };
|
422 | 500 | const auto viewResults = executeTwice(selectFromViewQuery);
|
@@ -455,9 +533,9 @@ Y_UNIT_TEST_SUITE(TEvaluateExprInViewTest) {
|
455 | 533 | TExecDataQuerySettings queryExecutionSettings;
|
456 | 534 | queryExecutionSettings.KeepInQueryCache(true);
|
457 | 535 | const auto executeTwice = [&](const TString& query) {
|
458 |
| - return TVector<TString>{ |
459 |
| - GetYsonResults(session, query, queryExecutionSettings), |
460 |
| - GetYsonResults(session, query, queryExecutionSettings) |
| 536 | + return TVector<TInstant>{ |
| 537 | + GetTimestamp(GetSingleResult(session, query, queryExecutionSettings)), |
| 538 | + GetTimestamp(GetSingleResult(session, query, queryExecutionSettings)) |
461 | 539 | };
|
462 | 540 | };
|
463 | 541 | const auto viewResults = executeTwice(selectFromViewQuery);
|
|
0 commit comments