Skip to content

Capture TablePathPrefix (and other parts of the parser context) in CREATE VIEW #8991

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions ydb/core/kqp/gateway/behaviour/view/manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <ydb/core/base/path.h>
#include <ydb/core/kqp/gateway/actors/scheme.h>
#include <ydb/core/kqp/gateway/utils/scheme_helpers.h>
#include <ydb/core/kqp/provider/yql_kikimr_provider.h>
#include <ydb/core/tx/tx_proxy/proxy.h>

namespace NKikimr::NKqp {
Expand All @@ -11,13 +12,14 @@ namespace {

using TYqlConclusionStatus = TViewManager::TYqlConclusionStatus;
using TInternalModificationContext = TViewManager::TInternalModificationContext;
using TExternalModificationContext = TViewManager::TExternalModificationContext;

TString GetByKeyOrDefault(const NYql::TCreateObjectSettings& container, const TString& key) {
const auto value = container.GetFeaturesExtractor().Extract(key);
return value ? *value : TString{};
}

TYqlConclusionStatus CheckFeatureFlag(TInternalModificationContext& context) {
TYqlConclusionStatus CheckFeatureFlag(const TInternalModificationContext& context) {
auto* const actorSystem = context.GetExternalData().GetActorSystem();
if (!actorSystem) {
ythrow yexception() << "This place needs an actor system. Please contact internal support";
Expand Down Expand Up @@ -48,15 +50,16 @@ std::pair<TString, TString> SplitPathByObjectId(const TString& objectId) {

void FillCreateViewProposal(NKikimrSchemeOp::TModifyScheme& modifyScheme,
const NYql::TCreateObjectSettings& settings,
const TString& database) {
const TExternalModificationContext& context) {

const auto pathPair = SplitPathByDb(settings.GetObjectId(), database);
const auto pathPair = SplitPathByDb(settings.GetObjectId(), context.GetDatabase());
modifyScheme.SetWorkingDir(pathPair.first);
modifyScheme.SetOperationType(NKikimrSchemeOp::ESchemeOpCreateView);

auto& viewDesc = *modifyScheme.MutableCreateView();
viewDesc.SetName(pathPair.second);
viewDesc.SetQueryText(GetByKeyOrDefault(settings, "query_text"));
NSQLTranslation::Serialize(context.GetTranslationSettings(), *viewDesc.MutableCapturedContext());

if (!settings.GetFeaturesExtractor().IsFinished()) {
ythrow TBadArgumentException() << "Unknown property: " << settings.GetFeaturesExtractor().GetRemainedParamsString();
Expand Down Expand Up @@ -92,20 +95,20 @@ NThreading::TFuture<TYqlConclusionStatus> SendSchemeRequest(TEvTxUserProxy::TEvP
}

NThreading::TFuture<TYqlConclusionStatus> CreateView(const NYql::TCreateObjectSettings& settings,
TInternalModificationContext& context) {
const TInternalModificationContext& context) {
auto proposal = MakeHolder<TEvTxUserProxy::TEvProposeTransaction>();
proposal->Record.SetDatabaseName(context.GetExternalData().GetDatabase());
if (context.GetExternalData().GetUserToken()) {
proposal->Record.SetUserToken(context.GetExternalData().GetUserToken()->GetSerializedToken());
}
auto& schemeTx = *proposal->Record.MutableTransaction()->MutableModifyScheme();
FillCreateViewProposal(schemeTx, settings, context.GetExternalData().GetDatabase());
FillCreateViewProposal(schemeTx, settings, context.GetExternalData());

return SendSchemeRequest(proposal.Release(), context.GetExternalData().GetActorSystem(), true);
}

NThreading::TFuture<TYqlConclusionStatus> DropView(const NYql::TDropObjectSettings& settings,
TInternalModificationContext& context) {
const TInternalModificationContext& context) {
auto proposal = MakeHolder<TEvTxUserProxy::TEvProposeTransaction>();
proposal->Record.SetDatabaseName(context.GetExternalData().GetDatabase());
if (context.GetExternalData().GetUserToken()) {
Expand All @@ -119,8 +122,8 @@ NThreading::TFuture<TYqlConclusionStatus> DropView(const NYql::TDropObjectSettin

void PrepareCreateView(NKqpProto::TKqpSchemeOperation& schemeOperation,
const NYql::TObjectSettingsImpl& settings,
TInternalModificationContext& context) {
FillCreateViewProposal(*schemeOperation.MutableCreateView(), settings, context.GetExternalData().GetDatabase());
const TInternalModificationContext& context) {
FillCreateViewProposal(*schemeOperation.MutableCreateView(), settings, context.GetExternalData());
}

void PrepareDropView(NKqpProto::TKqpSchemeOperation& schemeOperation,
Expand Down
1 change: 1 addition & 0 deletions ydb/core/kqp/gateway/behaviour/view/ya.make
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ SRCS(
PEERDIR(
ydb/core/base
ydb/core/kqp/gateway/actors
ydb/core/kqp/provider
ydb/core/tx/tx_proxy
ydb/services/metadata/abstract
ydb/services/metadata/manager
Expand Down
2 changes: 1 addition & 1 deletion ydb/core/kqp/gateway/kqp_metadata_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ TTableMetadataResult GetViewMetadataResult(
metadata->SchemaVersion = description.GetVersion();
metadata->Kind = NYql::EKikimrTableKind::View;
metadata->Attributes = schemeEntry.Attributes;
metadata->ViewPersistedData = {description.GetQueryText()};
metadata->ViewPersistedData = {description.GetQueryText(), description.GetCapturedContext()};

return builtResult;
}
Expand Down
5 changes: 3 additions & 2 deletions ydb/core/kqp/host/kqp_gateway_proxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1259,6 +1259,7 @@ class TKqpGatewayProxy : public IKikimrGateway {
if (SessionCtx->GetUserToken()) {
context.SetUserToken(*SessionCtx->GetUserToken());
}
context.SetTranslationSettings(SessionCtx->Query().TranslationSettings);

auto& phyTx = phyTxRemover.Capture(SessionCtx->Query().PreparingQuery->MutablePhysicalQuery());
phyTx.SetType(NKqpProto::TKqpPhyTx::TYPE_SCHEME);
Expand Down Expand Up @@ -2179,7 +2180,7 @@ class TKqpGatewayProxy : public IKikimrGateway {
if (cluster != SessionCtx->GetCluster()) {
return MakeFuture(ResultFromError<TGenericResult>("Invalid cluster: " + cluster));
}

NKqpProto::TKqpAnalyzeOperation analyzeTx;
analyzeTx.SetTablePath(settings.TablePath);
for (const auto& column: settings.Columns) {
Expand All @@ -2192,7 +2193,7 @@ class TKqpGatewayProxy : public IKikimrGateway {
phyTx.SetType(NKqpProto::TKqpPhyTx::TYPE_SCHEME);

phyTx.MutableSchemeOperation()->MutableAnalyzeTable()->Swap(&analyzeTx);

TGenericResult result;
result.SetSuccess();
return MakeFuture(result);
Expand Down
14 changes: 13 additions & 1 deletion ydb/core/kqp/host/kqp_host.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1230,7 +1230,19 @@ class TKqpHost : public IKqpHost {
.SetQueryParameters(query.ParameterTypes)
.SetApplicationName(ApplicationName)
.SetIsEnablePgSyntax(SessionCtx->Config().FeatureFlags.GetEnablePgSyntax());
auto astRes = ParseQuery(query.Text, isSql, sqlVersion, TypesCtx->DeprecatedSQL, ctx, settingsBuilder, result.KeepInCache, result.CommandTagName);
NSQLTranslation::TTranslationSettings effectiveSettings;
auto astRes = ParseQuery(
query.Text,
isSql,
sqlVersion,
TypesCtx->DeprecatedSQL,
ctx,
settingsBuilder,
result.KeepInCache,
result.CommandTagName,
&effectiveSettings
);
SessionCtx->Query().TranslationSettings = std::move(effectiveSettings);
if (astRes.ActualSyntaxType == NYql::ESyntaxType::Pg) {
SessionCtx->Config().IndexAutoChooserMode = NKikimrConfig::TTableServiceConfig_EIndexAutoChooseMode::TTableServiceConfig_EIndexAutoChooseMode_MAX_USED_PREFIX;
}
Expand Down
7 changes: 4 additions & 3 deletions ydb/core/kqp/host/kqp_translate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ NYql::EKikimrQueryType ConvertType(NKikimrKqp::EQueryType type) {
YQL_ENSURE(false, "Unexpected query type: " << type);
}
}

NSQLTranslation::TTranslationSettings TKqpTranslationSettingsBuilder::Build(NYql::TExprContext& ctx) {
NSQLTranslation::TTranslationSettings settings;
settings.PgParser = UsePgParser && *UsePgParser;
Expand Down Expand Up @@ -154,13 +154,14 @@ NSQLTranslation::TTranslationSettings TKqpTranslationSettingsBuilder::Build(NYql
}

NYql::TAstParseResult ParseQuery(const TString& queryText, bool isSql, TMaybe<ui16>& sqlVersion, bool& deprecatedSQL,
NYql::TExprContext& ctx, TKqpTranslationSettingsBuilder& settingsBuilder, bool& keepInCache, TMaybe<TString>& commandTagName) {
NYql::TExprContext& ctx, TKqpTranslationSettingsBuilder& settingsBuilder, bool& keepInCache, TMaybe<TString>& commandTagName,
NSQLTranslation::TTranslationSettings* effectiveSettings) {
NYql::TAstParseResult astRes;
settingsBuilder.SetSqlVersion(sqlVersion);
if (isSql) {
auto settings = settingsBuilder.Build(ctx);
NYql::TStmtParseInfo stmtParseInfo;
auto ast = NSQLTranslation::SqlToYql(queryText, settings, nullptr, &stmtParseInfo);
auto ast = NSQLTranslation::SqlToYql(queryText, settings, nullptr, &stmtParseInfo, effectiveSettings);
deprecatedSQL = (ast.ActualSyntaxType == NYql::ESyntaxType::YQLv0);
sqlVersion = ast.ActualSyntaxType == NYql::ESyntaxType::YQLv1 ? 1 : 0;
keepInCache = stmtParseInfo.KeepInCache;
Expand Down
3 changes: 2 additions & 1 deletion ydb/core/kqp/host/kqp_translate.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ NSQLTranslation::EBindingsMode RemapBindingsMode(NKikimrConfig::TTableServiceCon
NYql::EKikimrQueryType ConvertType(NKikimrKqp::EQueryType type);

NYql::TAstParseResult ParseQuery(const TString& queryText, bool isSql, TMaybe<ui16>& sqlVersion, bool& deprecatedSQL,
NYql::TExprContext& ctx, TKqpTranslationSettingsBuilder& settingsBuilder, bool& keepInCache, TMaybe<TString>& commandTagName);
NYql::TExprContext& ctx, TKqpTranslationSettingsBuilder& settingsBuilder, bool& keepInCache, TMaybe<TString>& commandTagName,
NSQLTranslation::TTranslationSettings* effectiveSettings = nullptr);

TVector<TQueryAst> ParseStatements(const TString& queryText, const TMaybe<Ydb::Query::Syntax>& syntax, bool isSql, TKqpTranslationSettingsBuilder& settingsBuilder, bool perStatementExecution);

Expand Down
16 changes: 9 additions & 7 deletions ydb/core/kqp/provider/rewrite_io_utils.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "rewrite_io_utils.h"

#include <ydb/core/kqp/provider/yql_kikimr_expr_nodes.h>
#include <ydb/core/kqp/provider/yql_kikimr_provider.h>
#include <ydb/library/yql/core/expr_nodes/yql_expr_nodes.h>
#include <ydb/library/yql/core/yql_expr_optimize.h>
#include <ydb/library/yql/providers/common/provider/yql_provider.h>
Expand All @@ -16,16 +17,17 @@ using namespace NNodes;
constexpr const char* QueryGraphNodeSignature = "SavedQueryGraph";

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

TAstParseResult queryAst;
queryAst = NSQLTranslation::SqlToYql(query, translationSettings);
queryAst = NSQLTranslation::SqlToYql(viewData.QueryText, translationSettings);

ctx.IssueManager.AddIssues(queryAst.Issues);
if (!queryAst.IsOk()) {
Expand Down Expand Up @@ -116,9 +118,9 @@ TExprNode::TPtr FindTopLevelRead(const TExprNode::TPtr& queryGraph) {
TExprNode::TPtr RewriteReadFromView(
const TExprNode::TPtr& node,
TExprContext& ctx,
const TString& query,
NKikimr::NKqp::TKqpTranslationSettingsBuilder& settingsBuilder,
IModuleResolver::TPtr moduleResolver
IModuleResolver::TPtr moduleResolver,
const TViewPersistedData& viewData
) {
YQL_PROFILE_FUNC(DEBUG);

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

TExprNode::TPtr queryGraph = FindSavedQueryGraph(readNode.Ptr());
if (!queryGraph) {
queryGraph = CompileViewQuery(query, ctx, settingsBuilder, moduleResolver);
queryGraph = CompileViewQuery(ctx, settingsBuilder, moduleResolver, viewData);
if (!queryGraph) {
ctx.AddError(TIssue(ctx.GetPosition(readNode.Pos()),
"The query stored in the view cannot be compiled."));
Expand All @@ -151,4 +153,4 @@ TExprNode::TPtr RewriteReadFromView(
return Build<TCoLeft>(ctx, node->Pos()).Input(topLevelRead).Done().Ptr();
}

}
}
7 changes: 4 additions & 3 deletions ydb/core/kqp/provider/rewrite_io_utils.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

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

namespace NYql {
Expand All @@ -10,9 +11,9 @@ TExprNode::TPtr FindTopLevelRead(const TExprNode::TPtr& queryGraph);
TExprNode::TPtr RewriteReadFromView(
const TExprNode::TPtr& node,
TExprContext& ctx,
const TString& query,
NKikimr::NKqp::TKqpTranslationSettingsBuilder& settingsBuilder,
IModuleResolver::TPtr moduleResolver
IModuleResolver::TPtr moduleResolver,
const TViewPersistedData& viewData
);

}
}
8 changes: 4 additions & 4 deletions ydb/core/kqp/provider/yql_kikimr_datasink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,9 @@ class TKiSinkIntentDeterminationTransformer: public TKiSinkVisitorTransformer {
}

TStatus HandleDropObject(TKiDropObject node, TExprContext& ctx) override {
ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), TStringBuilder()
<< "DropObject is not yet implemented for intent determination transformer"));
return TStatus::Error;
Y_UNUSED(node);
Y_UNUSED(ctx);
return TStatus::Ok;
Copy link
Collaborator Author

@jepett0 jepett0 Sep 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is needed for the intent determination transformer to be able to handle the following query:

DROP VIEW some_view;
CREATE VIEW some_other_view ...;

The same (i.e. nothing) is done in HandleCreateObject 12 lines above.

}

TStatus HandleCreateGroup(TKiCreateGroup node, TExprContext& ctx) override {
Expand Down Expand Up @@ -893,7 +893,7 @@ class TKikimrDataSink : public TDataProviderBase

if (tableDesc.Metadata->Kind == EKikimrTableKind::Datashard && mode == "analyze") {
ctx.AddError(TIssue(ctx.GetPosition(node->Pos()), TStringBuilder() << static_cast<TStringBuf>(mode) << " is not supported for oltp tables."));
return true;
return true;
}

return false;
Expand Down
7 changes: 4 additions & 3 deletions ydb/core/kqp/provider/yql_kikimr_datasource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -771,16 +771,17 @@ class TKikimrDataSource : public TDataProviderBase {
.Repeat(TExprStep::LoadTablesMetadata)
.Repeat(TExprStep::RewriteIO);

const auto& query = tableDesc.Metadata->ViewPersistedData.QueryText;
const auto& viewData = tableDesc.Metadata->ViewPersistedData;

NKqp::TKqpTranslationSettingsBuilder settingsBuilder(
SessionCtx->Query().Type,
SessionCtx->Config()._KqpYqlSyntaxVersion.Get().GetRef(),
cluster,
query,
viewData.QueryText,
SessionCtx->Config().BindingsMode,
GUCSettings
);
return RewriteReadFromView(node, ctx, query, settingsBuilder, Types.Modules);
return RewriteReadFromView(node, ctx, settingsBuilder, Types.Modules, viewData);
}
}

Expand Down
2 changes: 2 additions & 0 deletions ydb/core/kqp/provider/yql_kikimr_gateway.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <ydb/core/protos/flat_scheme_op.pb.h>
#include <ydb/core/protos/kqp.pb.h>
#include <ydb/core/protos/kqp_stats.pb.h>
#include <ydb/core/protos/yql_translation_settings.pb.h>
#include <ydb/core/scheme/scheme_types_proto.h>

#include <library/cpp/json/json_reader.h>
Expand Down Expand Up @@ -446,6 +447,7 @@ enum EMetaSerializationType : ui64 {

struct TViewPersistedData {
TString QueryText;
NYql::NProto::TTranslationSettings CapturedContext;
};

struct TKikimrTableMetadata : public TThrRefBase {
Expand Down
35 changes: 34 additions & 1 deletion ydb/core/kqp/provider/yql_kikimr_provider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -838,7 +838,7 @@ Ydb::Table::VectorIndexSettings_Distance VectorIndexSettingsParseDistance(std::s
return Ydb::Table::VectorIndexSettings::DISTANCE_MANHATTAN;
else if (distance == "euclidean")
return Ydb::Table::VectorIndexSettings::DISTANCE_EUCLIDEAN;
else
else
YQL_ENSURE(false, "Wrong index setting distance: " << distance);
};

Expand Down Expand Up @@ -998,3 +998,36 @@ TCoNameValueTupleList TKiExecDataQuerySettings::BuildNode(TExprContext& ctx, TPo
}

} // namespace NYql

namespace NSQLTranslation {

void Serialize(const TTranslationSettings& settings, NYql::NProto::TTranslationSettings& serializedSettings) {
serializedSettings.SetPathPrefix(settings.PathPrefix);
serializedSettings.SetSyntaxVersion(settings.SyntaxVersion);
serializedSettings.SetAnsiLexer(settings.AnsiLexer);
serializedSettings.SetPgParser(settings.PgParser);

auto* pragmas = serializedSettings.MutablePragmas();
pragmas->Clear();
pragmas->Add(settings.Flags.begin(), settings.Flags.end());
}

void Deserialize(const NYql::NProto::TTranslationSettings& serializedSettings, TTranslationSettings& settings) {
#define DeserializeSetting(settingName) \
if (serializedSettings.Has##settingName()) { \
settings.settingName = serializedSettings.Get##settingName(); \
}

DeserializeSetting(PathPrefix);
DeserializeSetting(SyntaxVersion);
DeserializeSetting(AnsiLexer);
DeserializeSetting(PgParser);

#undef DeserializeSetting

// overwrite existing pragmas
settings.Flags.clear();
settings.Flags.insert(serializedSettings.GetPragmas().begin(), serializedSettings.GetPragmas().end());
}

}
10 changes: 10 additions & 0 deletions ydb/core/kqp/provider/yql_kikimr_provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ struct TKikimrQueryContext : TThrRefBase {
// we do not want add extra life time for query context here
std::shared_ptr<NKikimr::NGRpcService::IRequestCtxMtSafe> RpcCtx;

NSQLTranslation::TTranslationSettings TranslationSettings;

void Reset() {
PrepareOnly = false;
SuppressDdlChecks = false;
Expand All @@ -143,6 +145,7 @@ struct TKikimrQueryContext : TThrRefBase {

RlPath.Clear();
RpcCtx.reset();
TranslationSettings = NSQLTranslation::TTranslationSettings();
}
};

Expand Down Expand Up @@ -568,3 +571,10 @@ TIntrusivePtr<IDataProvider> CreateKikimrDataSink(
TIntrusivePtr<IKikimrQueryExecutor> queryExecutor);

} // namespace NYql

namespace NSQLTranslation {

void Serialize(const TTranslationSettings& settings, NYql::NProto::TTranslationSettings& serializedSettings);
void Deserialize(const NYql::NProto::TTranslationSettings& serializedSettings, TTranslationSettings& settings);

}
Loading
Loading