Skip to content

Commit f0d28ca

Browse files
authored
Add unit tests for EvaluateExpr in VIEWs (#1488)
Make sure that the behaviour is the same for the plain SELECT CurrentUtcTimestamp() and for the same statement, but executed via a view.
1 parent 0ef3bfb commit f0d28ca

File tree

1 file changed

+90
-3
lines changed

1 file changed

+90
-3
lines changed

ydb/core/kqp/ut/view/view_ut.cpp

+90-3
Original file line numberDiff line numberDiff line change
@@ -60,17 +60,25 @@ void ExecuteDataDefinitionQuery(TSession& session, const TString& script) {
6060
<< script << "\nThe issues:\n" << result.GetIssues().ToString());
6161
}
6262

63-
TDataQueryResult ExecuteDataModificationQuery(TSession& session, const TString& script) {
63+
TDataQueryResult ExecuteDataModificationQuery(TSession& session,
64+
const TString& script,
65+
const TExecDataQuerySettings& settings = {}
66+
) {
6467
const auto result = session.ExecuteDataQuery(
6568
script,
66-
TTxControl::BeginTx(TTxSettings::SerializableRW()).CommitTx()
69+
TTxControl::BeginTx(TTxSettings::SerializableRW()).CommitTx(),
70+
settings
6771
).ExtractValueSync();
6872
UNIT_ASSERT_C(result.IsSuccess(), "Failed to execute the following DML script:\n"
6973
<< script << "\nThe issues:\n" << result.GetIssues().ToString());
7074

7175
return result;
7276
}
7377

78+
TString GetYsonResults(TSession& session, const TString& query, const TExecDataQuerySettings& settings = {}) {
79+
return FormatResultSetYson(ExecuteDataModificationQuery(session, query, settings).GetResultSet(0));
80+
}
81+
7482
void CompareResults(const TDataQueryResult& first, const TDataQueryResult& second) {
7583
const auto& firstResults = first.GetResultSets();
7684
const auto& secondResults = second.GetResultSets();
@@ -89,7 +97,7 @@ void InitializeTablesAndSecondaryViews(TSession& session) {
8997

9098
}
9199

92-
Y_UNIT_TEST_SUITE(TKQPViewTest) {
100+
Y_UNIT_TEST_SUITE(TCreateAndDropViewTest) {
93101

94102
Y_UNIT_TEST(CheckCreatedView) {
95103
TKikimrRunner kikimr(TKikimrSettings().SetWithSampleTables(false));
@@ -377,3 +385,82 @@ Y_UNIT_TEST_SUITE(TSelectFromViewTest) {
377385
}
378386
}
379387
}
388+
389+
Y_UNIT_TEST_SUITE(TEvaluateExprInViewTest) {
390+
391+
Y_UNIT_TEST(EvaluateExpr) {
392+
TKikimrRunner kikimr;
393+
EnableViewsFeatureFlag(kikimr);
394+
auto session = kikimr.GetTableClient().CreateSession().GetValueSync().GetSession();
395+
396+
constexpr const char* viewName = "TheView";
397+
constexpr const char* timeQuery = R"(
398+
SELECT EvaluateExpr(CurrentUtcTimestamp())
399+
)";
400+
401+
const TString creationQuery = std::format(R"(
402+
CREATE VIEW {} WITH (security_invoker = TRUE) AS {};
403+
)",
404+
viewName,
405+
timeQuery
406+
);
407+
ExecuteDataDefinitionQuery(session, creationQuery);
408+
409+
const TString selectFromViewQuery = std::format(R"(
410+
SELECT * FROM {};
411+
)",
412+
viewName
413+
);
414+
TExecDataQuerySettings queryExecutionSettings;
415+
queryExecutionSettings.KeepInQueryCache(true);
416+
const auto executeTwice = [&](const TString& query) {
417+
return TVector<TString>{
418+
GetYsonResults(session, query, queryExecutionSettings),
419+
GetYsonResults(session, query, queryExecutionSettings)
420+
};
421+
};
422+
const auto viewResults = executeTwice(selectFromViewQuery);
423+
const auto etalonResults = executeTwice(timeQuery);
424+
UNIT_ASSERT_EQUAL_C(viewResults[0] < viewResults[1], etalonResults[0] < etalonResults[1],
425+
TStringBuilder()
426+
<< "\nQuery cache works differently for EvaluateExpr written (1) in a view versus (2) in a plain SELECT statement.\n"
427+
<< "(1) SELECT from view results: (first call) " << viewResults[0] << ", (second call) " << viewResults[1]
428+
<< "(2) SELECT EvaluateExpr(...) results: (first call) " << etalonResults[0] << ", (second call) " << etalonResults[1] << "\n"
429+
);
430+
}
431+
432+
Y_UNIT_TEST(NakedCallToCurrentTimeFunction) {
433+
TKikimrRunner kikimr;
434+
EnableViewsFeatureFlag(kikimr);
435+
auto session = kikimr.GetTableClient().CreateSession().GetValueSync().GetSession();
436+
437+
constexpr const char* viewName = "TheView";
438+
constexpr const char* timeQuery = R"(
439+
SELECT CurrentUtcTimestamp()
440+
)";
441+
442+
const TString creationQuery = std::format(R"(
443+
CREATE VIEW {} WITH (security_invoker = TRUE) AS {};
444+
)",
445+
viewName,
446+
timeQuery
447+
);
448+
ExecuteDataDefinitionQuery(session, creationQuery);
449+
450+
const TString selectFromViewQuery = std::format(R"(
451+
SELECT * FROM {};
452+
)",
453+
viewName
454+
);
455+
TExecDataQuerySettings queryExecutionSettings;
456+
queryExecutionSettings.KeepInQueryCache(true);
457+
const auto executeTwice = [&](const TString& query) {
458+
return TVector<TString>{
459+
GetYsonResults(session, query, queryExecutionSettings),
460+
GetYsonResults(session, query, queryExecutionSettings)
461+
};
462+
};
463+
const auto viewResults = executeTwice(selectFromViewQuery);
464+
UNIT_ASSERT_LT(viewResults[0], viewResults[1]);
465+
}
466+
}

0 commit comments

Comments
 (0)