Skip to content

Commit

Permalink
Enable COUNT in view queries (ydb-platform#6820)
Browse files Browse the repository at this point in the history
  • Loading branch information
jepett0 authored Aug 6, 2024
1 parent 18b7d76 commit d7a9935
Show file tree
Hide file tree
Showing 23 changed files with 223 additions and 24 deletions.
2 changes: 1 addition & 1 deletion ydb/core/kqp/host/kqp_host.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1776,7 +1776,7 @@ class TKqpHost : public IKqpHost {

auto queryExecutor = MakeIntrusive<TKqpQueryExecutor>(Gateway, Cluster, SessionCtx, KqpRunner);
auto kikimrDataSource = CreateKikimrDataSource(*FuncRegistry, *TypesCtx, gatewayProxy, SessionCtx,
ExternalSourceFactory, IsInternalCall);
ExternalSourceFactory, IsInternalCall, GUCSettings);
auto kikimrDataSink = CreateKikimrDataSink(*FuncRegistry, *TypesCtx, gatewayProxy, SessionCtx, ExternalSourceFactory, queryExecutor);

FillSettings.AllResultsBytesLimit = Nothing();
Expand Down
2 changes: 2 additions & 0 deletions ydb/core/kqp/host/kqp_translate.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#include "kqp_translate.h"

#include <ydb/core/kqp/provider/yql_kikimr_results.h>
#include <ydb/library/yql/sql/sql.h>
#include <ydb/public/api/protos/ydb_query.pb.h>


namespace NKikimr {
Expand Down
5 changes: 3 additions & 2 deletions ydb/core/kqp/host/kqp_translate.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#pragma once

#include <ydb/core/kqp/provider/yql_kikimr_results.h>
#include <ydb/core/kqp/common/kqp.h>
#include <ydb/core/kqp/common/simple/query_ast.h>
#include <ydb/core/kqp/provider/yql_kikimr_provider.h>
#include <ydb/core/protos/table_service_config.pb.h>
#include <ydb/library/yql/core/pg_settings/guc_settings.h>

namespace NKikimr {
Expand Down
25 changes: 10 additions & 15 deletions ydb/core/kqp/provider/rewrite_io_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,31 +15,25 @@ using namespace NNodes;

constexpr const char* QueryGraphNodeSignature = "SavedQueryGraph";

NSQLTranslation::TTranslationSettings CreateViewTranslationSettings(const TString& cluster) {
NSQLTranslation::TTranslationSettings settings;

settings.DefaultCluster = cluster;
settings.ClusterMapping[cluster] = TString(NYql::KikimrProviderName);
settings.Mode = NSQLTranslation::ESqlMode::LIMITED_VIEW;

return settings;
}

TExprNode::TPtr CompileViewQuery(
const TString& query,
TExprContext& ctx,
const TString& cluster
NKikimr::NKqp::TKqpTranslationSettingsBuilder& settingsBuilder,
IModuleResolver::TPtr moduleResolver
) {
auto translationSettings = settingsBuilder.Build(ctx);
translationSettings.Mode = NSQLTranslation::ESqlMode::LIMITED_VIEW;

TAstParseResult queryAst;
queryAst = NSQLTranslation::SqlToYql(query, CreateViewTranslationSettings(cluster));
queryAst = NSQLTranslation::SqlToYql(query, translationSettings);

ctx.IssueManager.AddIssues(queryAst.Issues);
if (!queryAst.IsOk()) {
return nullptr;
}

TExprNode::TPtr queryGraph;
if (!CompileExpr(*queryAst.Root, queryGraph, ctx, nullptr, nullptr)) {
if (!CompileExpr(*queryAst.Root, queryGraph, ctx, moduleResolver.get(), nullptr)) {
return nullptr;
}

Expand Down Expand Up @@ -123,7 +117,8 @@ TExprNode::TPtr RewriteReadFromView(
const TExprNode::TPtr& node,
TExprContext& ctx,
const TString& query,
const TString& cluster
NKikimr::NKqp::TKqpTranslationSettingsBuilder& settingsBuilder,
IModuleResolver::TPtr moduleResolver
) {
YQL_PROFILE_FUNC(DEBUG);

Expand All @@ -132,7 +127,7 @@ TExprNode::TPtr RewriteReadFromView(

TExprNode::TPtr queryGraph = FindSavedQueryGraph(readNode.Ptr());
if (!queryGraph) {
queryGraph = CompileViewQuery(query, ctx, cluster);
queryGraph = CompileViewQuery(query, ctx, settingsBuilder, moduleResolver);
if (!queryGraph) {
ctx.AddError(TIssue(ctx.GetPosition(readNode.Pos()),
"The query stored in the view cannot be compiled."));
Expand Down
4 changes: 3 additions & 1 deletion ydb/core/kqp/provider/rewrite_io_utils.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include <ydb/core/kqp/host/kqp_translate.h>
#include <ydb/library/yql/ast/yql_expr.h>

namespace NYql {
Expand All @@ -10,7 +11,8 @@ TExprNode::TPtr RewriteReadFromView(
const TExprNode::TPtr& node,
TExprContext& ctx,
const TString& query,
const TString& cluster
NKikimr::NKqp::TKqpTranslationSettingsBuilder& settingsBuilder,
IModuleResolver::TPtr moduleResolver
);

}
22 changes: 18 additions & 4 deletions ydb/core/kqp/provider/yql_kikimr_datasource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "yql_kikimr_provider_impl.h"

#include <ydb/core/kqp/common/simple/services.h>
#include <ydb/core/kqp/host/kqp_translate.h>
#include <ydb/library/yql/providers/common/provider/yql_data_provider_impl.h>
#include <ydb/library/yql/providers/common/config/yql_configuration_transformer.h>

Expand Down Expand Up @@ -472,12 +473,14 @@ class TKikimrDataSource : public TDataProviderBase {
TIntrusivePtr<IKikimrGateway> gateway,
TIntrusivePtr<TKikimrSessionContext> sessionCtx,
const NExternalSource::IExternalSourceFactory::TPtr& externalSourceFactory,
bool isInternalCall)
bool isInternalCall,
TGUCSettings::TPtr gucSettings)
: FunctionRegistry(functionRegistry)
, Types(types)
, Gateway(gateway)
, SessionCtx(sessionCtx)
, ExternalSourceFactory(externalSourceFactory)
, GUCSettings(gucSettings)
, ConfigurationTransformer(new TKikimrConfigurationTransformer(sessionCtx, types))
, IntentDeterminationTransformer(new TKiSourceIntentDeterminationTransformer(sessionCtx))
, LoadTableMetadataTransformer(CreateKiSourceLoadTableMetadataTransformer(gateway, sessionCtx, types, externalSourceFactory, isInternalCall))
Expand Down Expand Up @@ -760,6 +763,7 @@ class TKikimrDataSource : public TDataProviderBase {
}

ctx.Step
.Repeat(TExprStep::ExpandApplyForLambdas)
.Repeat(TExprStep::ExprEval)
.Repeat(TExprStep::DiscoveryIO)
.Repeat(TExprStep::Epochs)
Expand All @@ -768,7 +772,15 @@ class TKikimrDataSource : public TDataProviderBase {
.Repeat(TExprStep::RewriteIO);

const auto& query = tableDesc.Metadata->ViewPersistedData.QueryText;
return RewriteReadFromView(node, ctx, query, cluster);
NKqp::TKqpTranslationSettingsBuilder settingsBuilder(
SessionCtx->Query().Type,
SessionCtx->Config()._KqpYqlSyntaxVersion.Get().GetRef(),
cluster,
query,
SessionCtx->Config().BindingsMode,
GUCSettings
);
return RewriteReadFromView(node, ctx, query, settingsBuilder, Types.Modules);
}
}

Expand Down Expand Up @@ -881,6 +893,7 @@ class TKikimrDataSource : public TDataProviderBase {
TIntrusivePtr<IKikimrGateway> Gateway;
TIntrusivePtr<TKikimrSessionContext> SessionCtx;
NExternalSource::IExternalSourceFactory::TPtr ExternalSourceFactory;
TGUCSettings::TPtr GUCSettings;

TAutoPtr<IGraphTransformer> ConfigurationTransformer;
TAutoPtr<IGraphTransformer> IntentDeterminationTransformer;
Expand Down Expand Up @@ -920,9 +933,10 @@ TIntrusivePtr<IDataProvider> CreateKikimrDataSource(
TIntrusivePtr<IKikimrGateway> gateway,
TIntrusivePtr<TKikimrSessionContext> sessionCtx,
const NExternalSource::IExternalSourceFactory::TPtr& externalSourceFactory,
bool isInternalCall)
bool isInternalCall,
TGUCSettings::TPtr gucSettings)
{
return new TKikimrDataSource(functionRegistry, types, gateway, sessionCtx, externalSourceFactory, isInternalCall);
return new TKikimrDataSource(functionRegistry, types, gateway, sessionCtx, externalSourceFactory, isInternalCall, gucSettings);
}

TAutoPtr<IGraphTransformer> CreateKiSourceLoadTableMetadataTransformer(TIntrusivePtr<IKikimrGateway> gateway,
Expand Down
3 changes: 2 additions & 1 deletion ydb/core/kqp/provider/yql_kikimr_provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,8 @@ TIntrusivePtr<IDataProvider> CreateKikimrDataSource(
TIntrusivePtr<IKikimrGateway> gateway,
TIntrusivePtr<TKikimrSessionContext> sessionCtx,
const NKikimr::NExternalSource::IExternalSourceFactory::TPtr& sourceFactory,
bool isInternalCall);
bool isInternalCall,
TGUCSettings::TPtr gucSettings);

TIntrusivePtr<IDataProvider> CreateKikimrDataSink(
const NKikimr::NMiniKQL::IFunctionRegistry& functionRegistry,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
CREATE VIEW `/Root/aggregates_and_window` WITH (security_invoker = TRUE) AS
SELECT
series.title AS series,
series_stats.seasons_with_episode_count_greater_than_average AS seasons_with_episode_count_greater_than_average
FROM (
SELECT
series_id,
SUM(
CASE
WHEN episode_count > average_episodes_in_season
THEN 1
ELSE 0
END
) AS seasons_with_episode_count_greater_than_average
FROM (
SELECT
series_id,
season_id,
episode_count,
AVG(episode_count) OVER average_episodes_in_season_window AS average_episodes_in_season
FROM (
SELECT
series_id,
season_id,
COUNT(*) AS episode_count
FROM `/Root/episodes`
GROUP BY
series_id,
season_id
)
WINDOW
average_episodes_in_season_window AS (
PARTITION BY
series_id
)
)
GROUP BY
series_id
)
AS series_stats
JOIN `/Root/series`
AS series
USING (series_id);
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DROP VIEW `/Root/aggregates_and_window`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
SELECT
*
FROM (
SELECT
series.title AS series,
series_stats.seasons_with_episode_count_greater_than_average AS seasons_with_episode_count_greater_than_average
FROM (
SELECT
series_id,
SUM(
CASE
WHEN episode_count > average_episodes_in_season
THEN 1
ELSE 0
END
) AS seasons_with_episode_count_greater_than_average
FROM (
SELECT
series_id,
season_id,
episode_count,
AVG(episode_count) OVER average_episodes_in_season_window AS average_episodes_in_season
FROM (
SELECT
series_id,
season_id,
COUNT(*) AS episode_count
FROM `/Root/episodes`
GROUP BY
series_id,
season_id
)
WINDOW
average_episodes_in_season_window AS (
PARTITION BY
series_id
)
)
GROUP BY
series_id
)
AS series_stats
JOIN `/Root/series`
AS series
USING (series_id)
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
SELECT
*
FROM `/Root/aggregates_and_window`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
CREATE VIEW `/Root/count_episodes` WITH (security_invoker = TRUE) AS
SELECT
series_id,
season_id,
COUNT(*)
FROM `/Root/episodes`
GROUP BY
series_id,
season_id;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DROP VIEW `/Root/count_episodes`;
12 changes: 12 additions & 0 deletions ydb/core/kqp/ut/view/input/cases/count_episodes/etalon_query.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
SELECT
*
FROM (
SELECT
series_id,
season_id,
COUNT(*)
FROM `/Root/episodes`
GROUP BY
series_id,
season_id
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
SELECT
*
FROM `/Root/count_episodes`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
CREATE VIEW `/Root/count_episodes_with_titles` WITH (security_invoker = TRUE) AS
SELECT
series.title AS series,
seasons.title AS season,
episodes.episode_count AS episode_count
FROM (
SELECT
series_id,
season_id,
COUNT(*) AS episode_count
FROM `/Root/episodes`
GROUP BY
series_id,
season_id
)
AS episodes
JOIN `/Root/series`
AS series
ON episodes.series_id == series.series_id
JOIN `/Root/seasons`
AS seasons
ON episodes.series_id == seasons.series_id AND episodes.season_id == seasons.season_id;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DROP VIEW `/Root/count_episodes_with_titles`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
SELECT
*
FROM (
SELECT
series.title AS series,
seasons.title AS season,
episodes.episode_count AS episode_count
FROM (
SELECT
series_id,
season_id,
COUNT(*) AS episode_count
FROM `/Root/episodes`
GROUP BY
series_id,
season_id
)
AS episodes
JOIN `/Root/series`
AS series
ON episodes.series_id == series.series_id
JOIN `/Root/seasons`
AS seasons
ON episodes.series_id == seasons.series_id AND episodes.season_id == seasons.season_id
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
SELECT
*
FROM `/Root/count_episodes_with_titles`;
4 changes: 4 additions & 0 deletions ydb/core/kqp/ut/view/input/cases/count_rows/create_view.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
CREATE VIEW `/Root/count_rows` WITH (security_invoker = TRUE) AS
SELECT
COUNT(*)
FROM `/Root/episodes`;
1 change: 1 addition & 0 deletions ydb/core/kqp/ut/view/input/cases/count_rows/drop_view.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DROP VIEW `/Root/count_rows`;
7 changes: 7 additions & 0 deletions ydb/core/kqp/ut/view/input/cases/count_rows/etalon_query.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
SELECT
*
FROM (
SELECT
COUNT(*)
FROM `/Root/episodes`
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
SELECT
*
FROM `/Root/count_rows`;

0 comments on commit d7a9935

Please sign in to comment.