aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniil Demin <deminds@ydb.tech>2025-04-02 15:27:14 +0300
committerGitHub <noreply@github.com>2025-04-02 12:27:14 +0000
commit4d6d0626d1787dfccba27b09e16d200805d0394d (patch)
tree3006472142fa7832550e5facea4957e45235af92
parentced625185b35de68237df07a9012aa069a6fb220 (diff)
downloadydb-4d6d0626d1787dfccba27b09e16d200805d0394d.tar.gz
refactoring before SHOW CREATE VIEW (#16629)
-rw-r--r--ydb/core/kqp/provider/yql_kikimr_opt_build.cpp68
-rw-r--r--ydb/core/kqp/ut/service/kqp_qs_queries_ut.cpp6
-rw-r--r--ydb/core/sys_view/show_create/create_table_formatter.cpp141
-rw-r--r--ydb/core/sys_view/show_create/create_table_formatter.h58
-rw-r--r--ydb/core/sys_view/show_create/formatters_common.cpp19
-rw-r--r--ydb/core/sys_view/show_create/formatters_common.h60
-rw-r--r--ydb/core/sys_view/show_create/show_create.cpp82
-rw-r--r--ydb/core/sys_view/show_create/ya.make3
8 files changed, 247 insertions, 190 deletions
diff --git a/ydb/core/kqp/provider/yql_kikimr_opt_build.cpp b/ydb/core/kqp/provider/yql_kikimr_opt_build.cpp
index af58f5ec04..2ee8144948 100644
--- a/ydb/core/kqp/provider/yql_kikimr_opt_build.cpp
+++ b/ydb/core/kqp/provider/yql_kikimr_opt_build.cpp
@@ -876,6 +876,13 @@ TVector<TKiDataQueryBlock> MakeKiDataQueryBlocks(TExprBase node, const TKiExplor
return queryBlocks;
}
+TString GetShowCreateType(const TExprNode& settings) {
+ if (HasSetting(settings, "showCreateTable")) {
+ return "showCreateTable";
+ }
+ return "";
+}
+
} // namespace
TExprNode::TPtr KiBuildQuery(TExprBase node, TExprContext& ctx, TStringBuf database, TIntrusivePtr<TKikimrTablesData> tablesData,
@@ -953,23 +960,23 @@ TExprNode::TPtr KiBuildQuery(TExprBase node, TExprContext& ctx, TStringBuf datab
return res;
}
- TNodeOnNodeOwnedMap showCreateTableReadReplaces;
- VisitExpr(node.Ptr(), [&showCreateTableReadReplaces](const TExprNode::TPtr& input) -> bool {
+ TNodeOnNodeOwnedMap showCreateReadReplacements;
+ VisitExpr(node.Ptr(), [&showCreateReadReplacements](const TExprNode::TPtr& input) -> bool {
TExprBase currentNode(input);
if (auto maybeReadTable = currentNode.Maybe<TKiReadTable>()) {
auto readTable = maybeReadTable.Cast();
for (auto setting : readTable.Settings()) {
auto name = setting.Name().Value();
if (name == "showCreateTable") {
- showCreateTableReadReplaces[input.Get()] = nullptr;
+ showCreateReadReplacements[input.Get()] = nullptr;
}
}
}
return true;
});
- if (!showCreateTableReadReplaces.empty()) {
- for (auto& [input, _] : showCreateTableReadReplaces) {
+ if (!showCreateReadReplacements.empty()) {
+ for (auto& [input, _] : showCreateReadReplacements) {
TKiReadTable content(input);
TExprNode::TPtr path = ctx.NewCallable(
@@ -983,6 +990,9 @@ TExprNode::TPtr KiBuildQuery(TExprBase node, TExprContext& ctx, TStringBuf datab
TKikimrKey key(ctx);
YQL_ENSURE(key.Extract(content.TableKey().Ref()));
+ auto type = GetShowCreateType(content.Settings().Ref());
+ YQL_ENSURE(!type.empty());
+
auto sysViewRewrittenValue = Build<TCoNameValueTuple>(ctx, node.Pos())
.Name()
.Build("sysViewRewritten")
@@ -991,12 +1001,12 @@ TExprNode::TPtr KiBuildQuery(TExprBase node, TExprContext& ctx, TStringBuf datab
.Build()
.Done();
- auto showCreateTableValue = Build<TCoNameValueTuple>(ctx, node.Pos())
+ auto showCreateTypeValue = Build<TCoNameValueTuple>(ctx, node.Pos())
.Name()
- .Build("showCreateTable")
+ .Build(type)
.Done();
- auto showCreateTableRead = Build<TCoRead>(ctx, node.Pos())
+ auto showCreateRead = Build<TCoRead>(ctx, node.Pos())
.World<TCoWorld>().Build()
.DataSource<TCoDataSource>()
.Category(ctx.NewAtom(node.Pos(), KikimrProviderName))
@@ -1009,61 +1019,65 @@ TExprNode::TPtr KiBuildQuery(TExprBase node, TExprContext& ctx, TStringBuf datab
.Add(ctx.NewCallable(node.Pos(), "Void", {}))
.Add(ctx.NewList(node.Pos(), {}))
.Add(sysViewRewrittenValue)
- .Add(showCreateTableValue)
+ .Add(showCreateTypeValue)
.Build()
.Done().Ptr();
- showCreateTableReadReplaces[input] = showCreateTableRead;
+ showCreateReadReplacements[input] = showCreateRead;
}
- auto res = ctx.ReplaceNodes(std::move(node.Ptr()), showCreateTableReadReplaces);
+ auto res = ctx.ReplaceNodes(std::move(node.Ptr()), showCreateReadReplacements);
TExprBase resNode(res);
- TNodeOnNodeOwnedMap showCreateTableRightReplaces;
- VisitExpr(resNode.Ptr(), [&showCreateTableRightReplaces](const TExprNode::TPtr& input) -> bool {
+ TNodeOnNodeOwnedMap showCreateRightReplacements;
+ VisitExpr(resNode.Ptr(), [&showCreateRightReplacements](const TExprNode::TPtr& input) -> bool {
TExprBase currentNode(input);
if (auto rightMaybe = currentNode.Maybe<TCoRight>()) {
auto right = rightMaybe.Cast();
if (auto maybeRead = right.Input().Maybe<TCoRead>()) {
auto read = maybeRead.Cast();
bool isSysViewRewritten = false;
- bool isShowCreateTable = false;
+ bool isShowCreate = false;
for (auto arg : read.FreeArgs()) {
if (auto tuple = arg.Maybe<TCoNameValueTuple>()) {
auto name = tuple.Cast().Name().Value();
if (name == "sysViewRewritten") {
isSysViewRewritten = true;
} else if (name == "showCreateTable") {
- isShowCreateTable = true;
+ isShowCreate = true;
}
}
}
- if (isShowCreateTable && isSysViewRewritten) {
- showCreateTableRightReplaces[input.Get()] = nullptr;
+ if (isShowCreate && isSysViewRewritten) {
+ showCreateRightReplacements[input.Get()] = nullptr;
}
}
}
return true;
});
- for (auto& [input, _] : showCreateTableRightReplaces) {
+ for (auto& [input, _] : showCreateRightReplacements) {
TCoRight right(input);
TCoRead read(right.Input().Ptr());
- TString tablePath;
+ TString path;
+ TString pathType;
for (auto arg : read.FreeArgs()) {
if (auto tuple = arg.Maybe<TCoNameValueTuple>()) {
auto name = tuple.Cast().Name().Value();
if (name == "sysViewRewritten") {
- tablePath = tuple.Cast().Value().Cast().Cast<TCoAtom>().StringValue();
+ path = tuple.Cast().Value().Cast().Cast<TCoAtom>().StringValue();
+ }
+ if (name == "showCreateTable") {
+ pathType = "Table";
}
}
}
- YQL_ENSURE(!tablePath.empty(), "Unexpected empty table path for SHOW CREATE TABLE");
+ YQL_ENSURE(!path.empty(), "Unexpected empty path for SHOW CREATE " << pathType.to_upper());
- auto tempTablePath = tablesData->GetTempTablePath(tablePath);
+ auto tempTablePath = tablesData->GetTempTablePath(path);
if (tempTablePath) {
- tablePath = tempTablePath.value();
+ path = tempTablePath.value();
}
auto showCreateArg = Build<TCoArgument>(ctx, resNode.Pos())
@@ -1082,7 +1096,7 @@ TExprNode::TPtr KiBuildQuery(TExprBase node, TExprContext& ctx, TStringBuf datab
auto pathCondition = Build<TCoCmpEqual>(ctx, resNode.Pos())
.Left(columnPath)
.Right<TCoString>()
- .Literal().Build(tablePath)
+ .Literal().Build(path)
.Build()
.Done();
@@ -1095,7 +1109,7 @@ TExprNode::TPtr KiBuildQuery(TExprBase node, TExprContext& ctx, TStringBuf datab
auto pathTypeCondition = Build<TCoCmpEqual>(ctx, resNode.Pos())
.Left(columnPathType)
.Right<TCoString>()
- .Literal().Build("Table")
+ .Literal().Build(pathType)
.Build()
.Done();
@@ -1121,7 +1135,7 @@ TExprNode::TPtr KiBuildQuery(TExprBase node, TExprContext& ctx, TStringBuf datab
.Lambda(lambda)
.Done().Ptr();
- showCreateTableRightReplaces[input] = filterData;
+ showCreateRightReplacements[input] = filterData;
}
ctx.Step
@@ -1133,7 +1147,7 @@ TExprNode::TPtr KiBuildQuery(TExprBase node, TExprContext& ctx, TStringBuf datab
.Repeat(TExprStep::LoadTablesMetadata)
.Repeat(TExprStep::RewriteIO);
- return ctx.ReplaceNodes(std::move(resNode.Ptr()), showCreateTableRightReplaces);
+ return ctx.ReplaceNodes(std::move(resNode.Ptr()), showCreateRightReplacements);
}
TKiExploreTxResults txExplore;
diff --git a/ydb/core/kqp/ut/service/kqp_qs_queries_ut.cpp b/ydb/core/kqp/ut/service/kqp_qs_queries_ut.cpp
index 96d1d6aea1..a40d4f331f 100644
--- a/ydb/core/kqp/ut/service/kqp_qs_queries_ut.cpp
+++ b/ydb/core/kqp/ut/service/kqp_qs_queries_ut.cpp
@@ -2908,15 +2908,15 @@ Y_UNIT_TEST_SUITE(KqpQueryService) {
CREATE VIEW test_view WITH security_invoker = TRUE AS
SELECT * FROM KeyValue;
)", TTxControl::NoTx()).ExtractValueSync();
- UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString());
+ UNIT_ASSERT_C(result.IsSuccess(), result.GetIssues().ToString());
}
{
auto result = session.ExecuteQuery(R"(
SHOW CREATE TABLE test_view;
)", TTxControl::NoTx()).ExtractValueSync();
- UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::ABORTED, result.GetIssues().ToString());
- UNIT_ASSERT_STRING_CONTAINS(result.GetIssues().ToString(), "Invalid path type");
+ UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::BAD_REQUEST, result.GetIssues().ToString());
+ UNIT_ASSERT_STRING_CONTAINS(result.GetIssues().ToString(), "Expected path type: Table");
}
}
diff --git a/ydb/core/sys_view/show_create/create_table_formatter.cpp b/ydb/core/sys_view/show_create/create_table_formatter.cpp
index ab9b40f509..9c53079ec8 100644
--- a/ydb/core/sys_view/show_create/create_table_formatter.cpp
+++ b/ydb/core/sys_view/show_create/create_table_formatter.cpp
@@ -7,7 +7,6 @@
#include <ydb/public/lib/ydb_cli/dump/util/query_utils.h>
-#include <yql/essentials/ast/yql_ast_escaping.h>
#include <yql/essentials/minikql/mkql_type_ops.h>
#include <util/generic/yexception.h>
@@ -19,18 +18,6 @@ using namespace NKikimrSchemeOp;
using namespace Ydb::Table;
using namespace NYdb;
-void TCreateTableFormatter::EscapeName(const TString& str) {
- NYql::EscapeArbitraryAtom(str, '`', &Stream);
-}
-
-void TCreateTableFormatter::EscapeString(const TString& str) {
- NYql::EscapeArbitraryAtom(str, '\'', &Stream);
-}
-
-void TCreateTableFormatter::EscapeBinary(const TString& str) {
- NYql::EscapeBinaryAtom(str, '\'', &Stream);
-}
-
void TCreateTableFormatter::FormatValue(NYdb::TValueParser& parser, bool isPartition, TString del) {
TGuard<NMiniKQL::TScopedAlloc> guard(Alloc);
switch (parser.GetKind()) {
@@ -72,7 +59,7 @@ void TCreateTableFormatter::FormatValue(NYdb::TValueParser& parser, bool isParti
auto precision = decimal.DecimalType_.Precision;
auto scale = decimal.DecimalType_.Scale;
Stream << "CAST(";
- EscapeString(decimal.ToString());
+ EscapeString(decimal.ToString(), Stream);
Stream << " AS Decimal(" << ui32(precision) << "," << ui32(scale) << ")";
Stream << ")";
return;
@@ -152,24 +139,24 @@ void TCreateTableFormatter::FormatPrimitive(NYdb::TValueParser& parser) {
break;
}
case NYdb::EPrimitiveType::Utf8: {
- EscapeString(TString(parser.GetUtf8()));
+ EscapeString(TString(parser.GetUtf8()), Stream);
break;
}
case NYdb::EPrimitiveType::Date: {
Stream << "DATE(";
- EscapeString(parser.GetDate().FormatGmTime("%Y-%m-%d"));
+ EscapeString(parser.GetDate().FormatGmTime("%Y-%m-%d"), Stream);
Stream << ")";
break;
}
case NYdb::EPrimitiveType::Datetime: {
Stream << "DATETIME(";
- EscapeString(parser.GetDatetime().ToStringUpToSeconds());
+ EscapeString(parser.GetDatetime().ToStringUpToSeconds(), Stream);
Stream << ")";
break;
}
case NYdb::EPrimitiveType::Timestamp: {
Stream << "TIMESTAMP(";
- EscapeString(parser.GetTimestamp().ToString());
+ EscapeString(parser.GetTimestamp().ToString(), Stream);
Stream << ")";
break;
}
@@ -177,7 +164,7 @@ void TCreateTableFormatter::FormatPrimitive(NYdb::TValueParser& parser) {
Stream << "INTERVAL(";
const NUdf::TUnboxedValue str = NMiniKQL::ValueToString(NUdf::EDataSlot::Interval, NUdf::TUnboxedValuePod(static_cast<i64>(parser.GetInterval())));
Y_ENSURE(str.HasValue());
- EscapeString(TString(str.AsStringRef()));
+ EscapeString(TString(str.AsStringRef()), Stream);
Stream << ")";
break;
}
@@ -185,7 +172,7 @@ void TCreateTableFormatter::FormatPrimitive(NYdb::TValueParser& parser) {
Stream << "DATE32(";
const NUdf::TUnboxedValue str = NMiniKQL::ValueToString(NUdf::EDataSlot::Date32, NUdf::TUnboxedValuePod(parser.GetDate32()));
Y_ENSURE(str.HasValue());
- EscapeString(TString(str.AsStringRef()));
+ EscapeString(TString(str.AsStringRef()), Stream);
Stream << ")";
break;
}
@@ -193,7 +180,7 @@ void TCreateTableFormatter::FormatPrimitive(NYdb::TValueParser& parser) {
Stream << "DATETIME64(";
const NUdf::TUnboxedValue str = NMiniKQL::ValueToString(NUdf::EDataSlot::Datetime64, NUdf::TUnboxedValuePod(static_cast<i64>(parser.GetDatetime64())));
Y_ENSURE(str.HasValue());
- EscapeString(TString(str.AsStringRef()));
+ EscapeString(TString(str.AsStringRef()), Stream);
Stream << ")";
break;
}
@@ -201,7 +188,7 @@ void TCreateTableFormatter::FormatPrimitive(NYdb::TValueParser& parser) {
Stream << "TIMESTAMP64(";
const NUdf::TUnboxedValue str = NMiniKQL::ValueToString(NUdf::EDataSlot::Timestamp64, NUdf::TUnboxedValuePod(static_cast<i64>(parser.GetTimestamp64())));
Y_ENSURE(str.HasValue());
- EscapeString(TString(str.AsStringRef()));
+ EscapeString(TString(str.AsStringRef()), Stream);
Stream << ")";
break;
}
@@ -209,28 +196,28 @@ void TCreateTableFormatter::FormatPrimitive(NYdb::TValueParser& parser) {
Stream << "INTERVAL64(";
const NUdf::TUnboxedValue str = NMiniKQL::ValueToString(NUdf::EDataSlot::Interval64, NUdf::TUnboxedValuePod(static_cast<i64>(parser.GetInterval64())));
Y_ENSURE(str.HasValue());
- EscapeString(TString(str.AsStringRef()));
+ EscapeString(TString(str.AsStringRef()), Stream);
Stream << ")";
break;
}
case NYdb::EPrimitiveType::String:
- EscapeString(TString(parser.GetString()));
+ EscapeString(TString(parser.GetString()), Stream);
break;
case NYdb::EPrimitiveType::Yson:
- EscapeString(TString(parser.GetYson()));
+ EscapeString(TString(parser.GetYson()), Stream);
break;
case NYdb::EPrimitiveType::Json:
- EscapeString(TString(parser.GetJson()));
+ EscapeString(TString(parser.GetJson()), Stream);
break;
case NYdb::EPrimitiveType::DyNumber: {
Stream << "DyNumber(";
- EscapeString(TString(parser.GetDyNumber()));
+ EscapeString(TString(parser.GetDyNumber()), Stream);
Stream << ")";
break;
}
case NYdb::EPrimitiveType::Uuid: {
Stream << "UUID(";
- EscapeString(TString(parser.GetUuid().ToString()));
+ EscapeString(TString(parser.GetUuid().ToString()), Stream);
Stream << ")";
break;
}
@@ -258,7 +245,7 @@ private:
TStringStream& Stream;
};
-TCreateTableFormatter::TResult TCreateTableFormatter::Format(const TString& tablePath,
+TFormatResult TCreateTableFormatter::Format(const TString& tablePath,
const TTableDescription& tableDesc, bool temporary) {
Stream.Clear();
@@ -270,14 +257,14 @@ TCreateTableFormatter::TResult TCreateTableFormatter::Format(const TString& tabl
} else {
Stream << "CREATE TABLE ";
}
- EscapeName(tablePath);
+ EscapeName(tablePath, Stream);
Stream << " (\n";
NKikimrMiniKQL::TType mkqlKeyType;
try {
FillColumnDescription(createRequest, mkqlKeyType, tableDesc);
} catch (const yexception& e) {
- return TResult(Ydb::StatusIds::UNSUPPORTED, e.what());
+ return TFormatResult(Ydb::StatusIds::UNSUPPORTED, e.what());
}
Y_ENSURE(!tableDesc.GetColumns().empty());
@@ -298,16 +285,16 @@ TCreateTableFormatter::TResult TCreateTableFormatter::Format(const TString& tabl
Format(*it->second);
}
} catch (const TFormatFail& ex) {
- return TResult(ex.Status, ex.Error);
+ return TFormatResult(ex.Status, ex.Error);
} catch (const yexception& e) {
- return TResult(Ydb::StatusIds::UNSUPPORTED, e.what());
+ return TFormatResult(Ydb::StatusIds::UNSUPPORTED, e.what());
}
try {
FillTableBoundary(createRequest, tableDesc, mkqlKeyType);
FillIndexDescription(createRequest, tableDesc);
} catch (const yexception& e) {
- return TResult(Ydb::StatusIds::UNSUPPORTED, e.what());;
+ return TFormatResult(Ydb::StatusIds::UNSUPPORTED, e.what());;
}
if (!createRequest.indexes().empty()) {
@@ -319,9 +306,9 @@ TCreateTableFormatter::TResult TCreateTableFormatter::Format(const TString& tabl
Format(createRequest.indexes(i));
}
} catch (const TFormatFail& ex) {
- return TResult(ex.Status, ex.Error);
+ return TFormatResult(ex.Status, ex.Error);
} catch (const yexception& e) {
- return TResult(Ydb::StatusIds::UNSUPPORTED, e.what());
+ return TFormatResult(Ydb::StatusIds::UNSUPPORTED, e.what());
}
}
Stream << ",\n";
@@ -340,9 +327,9 @@ TCreateTableFormatter::TResult TCreateTableFormatter::Format(const TString& tabl
isFamilyPrinted = Format(partitionConfig.GetColumnFamilies(i));
}
} catch (const TFormatFail& ex) {
- return TResult(ex.Status, ex.Error);
+ return TFormatResult(ex.Status, ex.Error);
} catch (const yexception& e) {
- return TResult(Ydb::StatusIds::UNSUPPORTED, e.what());
+ return TFormatResult(Ydb::StatusIds::UNSUPPORTED, e.what());
}
}
}
@@ -352,10 +339,10 @@ TCreateTableFormatter::TResult TCreateTableFormatter::Format(const TString& tabl
Stream << ",\n";
}
Stream << "\tPRIMARY KEY (";
- EscapeName(columns[tableDesc.GetKeyColumnIds(0)]->GetName());
+ EscapeName(columns[tableDesc.GetKeyColumnIds(0)]->GetName(), Stream);
for (int i = 1; i < tableDesc.GetKeyColumnIds().size(); i++) {
Stream << ", ";
- EscapeName(columns[tableDesc.GetKeyColumnIds(i)]->GetName());
+ EscapeName(columns[tableDesc.GetKeyColumnIds(i)]->GetName(), Stream);
}
Stream << ")\n";
Stream << ")";
@@ -374,9 +361,9 @@ TCreateTableFormatter::TResult TCreateTableFormatter::Format(const TString& tabl
try {
printed |= Format(createRequest.partition_at_keys(), del, !printed);
} catch (const TFormatFail& ex) {
- return TResult(ex.Status, ex.Error);
+ return TFormatResult(ex.Status, ex.Error);
} catch (const yexception& e) {
- return TResult(Ydb::StatusIds::UNSUPPORTED, e.what());
+ return TFormatResult(Ydb::StatusIds::UNSUPPORTED, e.what());
}
}
@@ -408,9 +395,9 @@ TCreateTableFormatter::TResult TCreateTableFormatter::Format(const TString& tabl
try {
printed |= Format(createRequest.ttl_settings(), del, !printed);
} catch (const TFormatFail& ex) {
- return TResult(ex.Status, ex.Error);
+ return TFormatResult(ex.Status, ex.Error);
} catch (const yexception& e) {
- return TResult(Ydb::StatusIds::UNSUPPORTED, e.what());
+ return TFormatResult(Ydb::StatusIds::UNSUPPORTED, e.what());
}
}
@@ -422,17 +409,17 @@ TCreateTableFormatter::TResult TCreateTableFormatter::Format(const TString& tabl
TString formattedStatement;
NYql::TIssues issues;
if (!NYdb::NDump::Format(statement, formattedStatement, issues)) {
- return TResult(Ydb::StatusIds::INTERNAL_ERROR, issues.ToString());
+ return TFormatResult(Ydb::StatusIds::INTERNAL_ERROR, issues.ToString());
}
- auto result = TResult(std::move(formattedStatement));
+ auto result = TFormatResult(std::move(formattedStatement));
return result;
}
void TCreateTableFormatter::Format(const NKikimrSchemeOp::TColumnDescription& columnDesc) {
Stream << "\t";
- EscapeName(columnDesc.GetName());
+ EscapeName(columnDesc.GetName(), Stream);
Stream << " ";
auto type = columnDesc.GetType();
@@ -460,7 +447,7 @@ void TCreateTableFormatter::Format(const NKikimrSchemeOp::TColumnDescription& co
if (columnDesc.HasFamilyName()) {
Stream << " FAMILY ";
- EscapeName(columnDesc.GetFamilyName());
+ EscapeName(columnDesc.GetFamilyName(), Stream);
}
if (columnDesc.GetNotNull()) {
Stream << " NOT NULL";
@@ -473,7 +460,7 @@ void TCreateTableFormatter::Format(const NKikimrSchemeOp::TColumnDescription& co
void TCreateTableFormatter::Format(const TableIndex& index) {
Stream << "\tINDEX ";
- EscapeName(index.name());
+ EscapeName(index.name(), Stream);
std::optional<KMeansTreeSettings> kMeansTreeSettings;
switch (index.type_case()) {
case TableIndex::kGlobalIndex: {
@@ -499,20 +486,20 @@ void TCreateTableFormatter::Format(const TableIndex& index) {
Y_ENSURE(!index.index_columns().empty());
Stream << "(";
- EscapeName(index.index_columns(0));
+ EscapeName(index.index_columns(0), Stream);
for (int i = 1; i < index.index_columns().size(); i++) {
Stream << ", ";
- EscapeName(index.index_columns(i));
+ EscapeName(index.index_columns(i), Stream);
}
Stream << ")";
if (!index.data_columns().empty()) {
Stream << " COVER ";
Stream << "(";
- EscapeName(index.data_columns(0));
+ EscapeName(index.data_columns(0), Stream);
for (int i = 1; i < index.data_columns().size(); i++) {
Stream << ", ";
- EscapeName(index.data_columns(i));
+ EscapeName(index.data_columns(i), Stream);
}
Stream << ")";
}
@@ -635,7 +622,7 @@ bool TCreateTableFormatter::Format(const TFamilyDescription& familyDesc) {
Y_ENSURE(familyName);
Stream << "\tFAMILY ";
- EscapeName(familyName);
+ EscapeName(familyName, Stream);
Stream << " (";
TString del = "";
@@ -754,11 +741,11 @@ void TCreateTableFormatter::Format(ui64 expireAfterSeconds, std::optional<TStrin
Stream << "INTERVAL(";
const NUdf::TUnboxedValue str = NMiniKQL::ValueToString(NUdf::EDataSlot::Interval, NUdf::TUnboxedValuePod(expireAfterSeconds * 1000000));
Y_ENSURE(str.HasValue());
- EscapeString(TString(str.AsStringRef()));
+ EscapeString(TString(str.AsStringRef()), Stream);
Stream << ") ";
if (storage) {
Stream << "TO EXTERNAL DATA SOURCE ";
- EscapeName(*storage);
+ EscapeName(*storage, Stream);
} else {
Stream << "DELETE";
}
@@ -885,7 +872,7 @@ bool TCreateTableFormatter::Format(const Ydb::Table::TtlSettings& ttlSettings, T
return true;
}
-TCreateTableFormatter::TResult TCreateTableFormatter::Format(const TString& tablePath, const TColumnTableDescription& tableDesc, bool temporary) {
+TFormatResult TCreateTableFormatter::Format(const TString& tablePath, const TColumnTableDescription& tableDesc, bool temporary) {
Stream.Clear();
TStringStreamWrapper wrapper(Stream);
@@ -896,7 +883,7 @@ TCreateTableFormatter::TResult TCreateTableFormatter::Format(const TString& tabl
} else {
Stream << "CREATE TABLE ";
}
- EscapeName(tablePath);
+ EscapeName(tablePath, Stream);
Stream << " (\n";
const auto& schema = tableDesc.GetSchema();
@@ -915,14 +902,14 @@ TCreateTableFormatter::TResult TCreateTableFormatter::Format(const TString& tabl
Format(*it->second);
}
} catch (const TFormatFail& ex) {
- return TResult(ex.Status, ex.Error);
+ return TFormatResult(ex.Status, ex.Error);
} catch (const yexception& e) {
- return TResult(Ydb::StatusIds::UNSUPPORTED, e.what());
+ return TFormatResult(Ydb::StatusIds::UNSUPPORTED, e.what());
}
Stream << ",\n";
if (!schema.GetIndexes().empty()) {
- return TResult(Ydb::StatusIds::UNSUPPORTED, "Indexes are not supported yet for column tables.");
+ return TFormatResult(Ydb::StatusIds::UNSUPPORTED, "Indexes are not supported yet for column tables.");
}
bool isFamilyPrinted = false;
@@ -936,9 +923,9 @@ TCreateTableFormatter::TResult TCreateTableFormatter::Format(const TString& tabl
isFamilyPrinted = Format(schema.GetColumnFamilies(i));
}
} catch (const TFormatFail& ex) {
- return TResult(ex.Status, ex.Error);
+ return TFormatResult(ex.Status, ex.Error);
} catch (const yexception& e) {
- return TResult(Ydb::StatusIds::UNSUPPORTED, e.what());
+ return TFormatResult(Ydb::StatusIds::UNSUPPORTED, e.what());
}
}
@@ -947,10 +934,10 @@ TCreateTableFormatter::TResult TCreateTableFormatter::Format(const TString& tabl
Stream << ",\n";
}
Stream << "\tPRIMARY KEY (";
- EscapeName(schema.GetKeyColumnNames(0));
+ EscapeName(schema.GetKeyColumnNames(0), Stream);
for (int i = 1; i < schema.GetKeyColumnNames().size(); i++) {
Stream << ", ";
- EscapeName(schema.GetKeyColumnNames(i));
+ EscapeName(schema.GetKeyColumnNames(i), Stream);
}
Stream << ")\n";
Stream << ") ";
@@ -958,16 +945,16 @@ TCreateTableFormatter::TResult TCreateTableFormatter::Format(const TString& tabl
if (schema.HasOptions()) {
const auto& options = schema.GetOptions();
if (options.GetSchemeNeedActualization()) {
- return TResult(Ydb::StatusIds::UNSUPPORTED, "Unsupported setting: SCHEME_NEED_ACTUALIZATION");
+ return TFormatResult(Ydb::StatusIds::UNSUPPORTED, "Unsupported setting: SCHEME_NEED_ACTUALIZATION");
}
if (options.HasScanReaderPolicyName() && !options.GetScanReaderPolicyName().empty()) {
- return TResult(Ydb::StatusIds::UNSUPPORTED, "Unsupported setting: SCAN_READER_POLICY_NAME");
+ return TFormatResult(Ydb::StatusIds::UNSUPPORTED, "Unsupported setting: SCAN_READER_POLICY_NAME");
}
if (options.HasCompactionPlannerConstructor()) {
- return TResult(Ydb::StatusIds::UNSUPPORTED, "Unsupported setting: COMPACTION_PLANNER");
+ return TFormatResult(Ydb::StatusIds::UNSUPPORTED, "Unsupported setting: COMPACTION_PLANNER");
}
if (options.HasMetadataManagerConstructor()) {
- return TResult(Ydb::StatusIds::UNSUPPORTED, "Unsupported setting: METADATA_MEMORY_MANAGER");
+ return TFormatResult(Ydb::StatusIds::UNSUPPORTED, "Unsupported setting: METADATA_MEMORY_MANAGER");
}
}
@@ -993,22 +980,22 @@ TCreateTableFormatter::TResult TCreateTableFormatter::Format(const TString& tabl
TString formattedStatement;
NYql::TIssues issues;
if (!NYdb::NDump::Format(statement, formattedStatement, issues)) {
- return TResult(Ydb::StatusIds::INTERNAL_ERROR, issues.ToString());
+ return TFormatResult(Ydb::StatusIds::INTERNAL_ERROR, issues.ToString());
}
- auto result = TResult(std::move(formattedStatement));
+ auto result = TFormatResult(std::move(formattedStatement));
return result;
}
void TCreateTableFormatter::Format(const TOlapColumnDescription& olapColumnDesc) {
Stream << "\t";
- EscapeName(olapColumnDesc.GetName());
+ EscapeName(olapColumnDesc.GetName(), Stream);
Stream << " " << olapColumnDesc.GetType();
if (olapColumnDesc.HasColumnFamilyName()) {
Stream << " FAMILY ";
- EscapeName(olapColumnDesc.GetColumnFamilyName());
+ EscapeName(olapColumnDesc.GetColumnFamilyName(), Stream);
}
if (olapColumnDesc.GetNotNull()) {
Stream << " NOT NULL";
@@ -1104,10 +1091,10 @@ void TCreateTableFormatter::Format(const NKikimrColumnShardColumnDefaults::TColu
Stream << "TIMESTAMP(";
const NUdf::TUnboxedValue str = NMiniKQL::ValueToString(NUdf::EDataSlot::Timestamp, NUdf::TUnboxedValuePod(value));
Y_ENSURE(str.HasValue());
- EscapeString(TString(str.AsStringRef()));
+ EscapeString(TString(str.AsStringRef()), Stream);
Stream << ")";
} else if (scalar.HasString()) {
- EscapeString(TString(scalar.GetString()));
+ EscapeString(TString(scalar.GetString()), Stream);
} else {
ythrow TFormatFail(Ydb::StatusIds::UNSUPPORTED, "Unsupported type for default value");
}
@@ -1119,10 +1106,10 @@ void TCreateTableFormatter::Format(const NKikimrSchemeOp::TColumnTableSharding&
const auto& hashSharding = sharding.GetHashSharding();
Y_ENSURE(!hashSharding.GetColumns().empty());
Stream << "PARTITION BY HASH(";
- EscapeName(hashSharding.GetColumns(0));
+ EscapeName(hashSharding.GetColumns(0), Stream);
for (int i = 1; i < hashSharding.GetColumns().size(); i++) {
Stream << ", ";
- EscapeName(hashSharding.GetColumns(i));
+ EscapeName(hashSharding.GetColumns(i), Stream);
}
Stream << ")\n";
break;
diff --git a/ydb/core/sys_view/show_create/create_table_formatter.h b/ydb/core/sys_view/show_create/create_table_formatter.h
index 249ef6e0fd..bd82bc5a15 100644
--- a/ydb/core/sys_view/show_create/create_table_formatter.h
+++ b/ydb/core/sys_view/show_create/create_table_formatter.h
@@ -1,5 +1,7 @@
#pragma once
+#include "formatters_common.h"
+
#include <ydb/public/sdk/cpp/include/ydb-cpp-sdk/client/value/value.h>
#include <ydb/core/protos/flat_scheme_op.pb.h>
@@ -10,60 +12,13 @@
#include <yql/essentials/minikql/mkql_alloc.h>
-#include <util/generic/hash.h>
#include <util/stream/str.h>
-#include <util/string/builder.h>
namespace NKikimr {
namespace NSysView {
class TCreateTableFormatter {
public:
- class TFormatFail : public yexception {
- public:
- Ydb::StatusIds::StatusCode Status;
- TString Error;
-
- TFormatFail(Ydb::StatusIds::StatusCode status, TString error = {})
- : Status(status)
- , Error(std::move(error))
- {}
- };
-
- class TResult {
- public:
- TResult(TString out)
- : Out(std::move(out))
- , Status(Ydb::StatusIds::SUCCESS)
- {}
-
- TResult(Ydb::StatusIds::StatusCode status, TString error)
- : Status(status)
- , Error(std::move(error))
- {}
-
- bool IsSuccess() const {
- return Status == Ydb::StatusIds::SUCCESS;
- }
-
- Ydb::StatusIds::StatusCode GetStatus() const {
- return Status;
- }
-
- const TString& GetError() const {
- return Error;
- }
-
- TString ExtractOut() {
- return std::move(Out);
- }
- private:
- TString Out;
-
- Ydb::StatusIds::StatusCode Status;
- TString Error;
- };
-
TCreateTableFormatter()
: Alloc(__LOCATION__)
{
@@ -75,11 +30,10 @@ public:
Alloc.Acquire();
}
- TResult Format(const TString& tablePath, const NKikimrSchemeOp::TTableDescription& tableDesc, bool temporary);
- TResult Format(const TString& tablePath, const NKikimrSchemeOp::TColumnTableDescription& tableDesc, bool temporary);
+ TFormatResult Format(const TString& tablePath, const NKikimrSchemeOp::TTableDescription& tableDesc, bool temporary);
+ TFormatResult Format(const TString& tablePath, const NKikimrSchemeOp::TColumnTableDescription& tableDesc, bool temporary);
private:
-
void Format(const NKikimrSchemeOp::TColumnDescription& columnDesc);
bool Format(const NKikimrSchemeOp::TFamilyDescription& familyDesc);
bool Format(const NKikimrSchemeOp::TPartitioningPolicy& policy, ui32 shardsToCreate, TString& del, bool needWith);
@@ -101,10 +55,6 @@ private:
void FormatValue(NYdb::TValueParser& parser, bool isPartition = false, TString del = "");
void FormatPrimitive(NYdb::TValueParser& parser);
- void EscapeName(const TString& str);
- void EscapeString(const TString& str);
- void EscapeBinary(const TString& str);
-private:
TStringStream Stream;
NMiniKQL::TScopedAlloc Alloc;
};
diff --git a/ydb/core/sys_view/show_create/formatters_common.cpp b/ydb/core/sys_view/show_create/formatters_common.cpp
new file mode 100644
index 0000000000..04d0808397
--- /dev/null
+++ b/ydb/core/sys_view/show_create/formatters_common.cpp
@@ -0,0 +1,19 @@
+#include "formatters_common.h"
+
+#include <yql/essentials/ast/yql_ast_escaping.h>
+
+namespace NKikimr::NSysView {
+
+void EscapeName(const TString& str, TStringStream& stream) {
+ NYql::EscapeArbitraryAtom(str, '`', &stream);
+}
+
+void EscapeString(const TString& str, TStringStream& stream) {
+ NYql::EscapeArbitraryAtom(str, '\'', &stream);
+}
+
+void EscapeBinary(const TString& str, TStringStream& stream) {
+ NYql::EscapeBinaryAtom(str, '\'', &stream);
+}
+
+}
diff --git a/ydb/core/sys_view/show_create/formatters_common.h b/ydb/core/sys_view/show_create/formatters_common.h
new file mode 100644
index 0000000000..64c133da8e
--- /dev/null
+++ b/ydb/core/sys_view/show_create/formatters_common.h
@@ -0,0 +1,60 @@
+#pragma once
+
+#include <ydb/public/api/protos/ydb_status_codes.pb.h>
+
+#include <util/generic/yexception.h>
+#include <util/stream/str.h>
+
+namespace NKikimr::NSysView {
+
+void EscapeName(const TString& str, TStringStream& stream);
+void EscapeString(const TString& str, TStringStream& stream);
+void EscapeBinary(const TString& str, TStringStream& stream);
+
+class TFormatFail : public yexception {
+public:
+ Ydb::StatusIds::StatusCode Status;
+ TString Error;
+
+ TFormatFail(Ydb::StatusIds::StatusCode status, TString error = {})
+ : Status(status)
+ , Error(std::move(error))
+ {}
+};
+
+class TFormatResult {
+public:
+ TFormatResult(TString out)
+ : Out(std::move(out))
+ , Status(Ydb::StatusIds::SUCCESS)
+ {}
+
+ TFormatResult(Ydb::StatusIds::StatusCode status, TString error)
+ : Status(status)
+ , Error(std::move(error))
+ {}
+
+ bool IsSuccess() const {
+ return Status == Ydb::StatusIds::SUCCESS;
+ }
+
+ Ydb::StatusIds::StatusCode GetStatus() const {
+ return Status;
+ }
+
+ const TString& GetError() const {
+ return Error;
+ }
+
+ TString ExtractOut() {
+ return std::move(Out);
+ }
+
+private:
+ TString Out;
+
+ Ydb::StatusIds::StatusCode Status;
+ TString Error;
+};
+
+}
diff --git a/ydb/core/sys_view/show_create/show_create.cpp b/ydb/core/sys_view/show_create/show_create.cpp
index 2c9f4d3df5..51800cbebb 100644
--- a/ydb/core/sys_view/show_create/show_create.cpp
+++ b/ydb/core/sys_view/show_create/show_create.cpp
@@ -20,6 +20,31 @@ namespace {
using namespace NActors;
+TString ToString(NKikimrSchemeOp::EPathType pathType) {
+ switch (pathType) {
+ case NKikimrSchemeOp::EPathTypeTable:
+ case NKikimrSchemeOp::EPathTypeColumnTable:
+ return "Table";
+ default:
+ return "Unknown";
+ }
+}
+
+bool RewriteTemporaryTablePath(const TString& database, TString& tablePath, TString& error) {
+ auto pathVecTmp = SplitPath(tablePath);
+ auto sz = pathVecTmp.size();
+ Y_ENSURE(sz > 3 && pathVecTmp[0] == ".tmp" && pathVecTmp[1] == "sessions");
+
+ auto pathTmp = JoinPath(TVector<TString>(pathVecTmp.begin() + 3, pathVecTmp.end()));
+ std::pair<TString, TString> pathPairTmp;
+ if (!TrySplitPathByDb(pathTmp, database, pathPairTmp, error)) {
+ return false;
+ }
+
+ tablePath = pathPairTmp.second;
+ return true;
+}
+
class TShowCreate : public TScanActorBase<TShowCreate> {
public:
using TBase = TScanActorBase<TShowCreate>;
@@ -136,14 +161,14 @@ private:
switch (status) {
case NKikimrScheme::StatusSuccess: {
const auto& pathDescription = record.GetPathDescription();
- if (pathDescription.GetSelf().GetPathType() != NKikimrSchemeOp::EPathTypeTable
- && pathDescription.GetSelf().GetPathType() != NKikimrSchemeOp::EPathTypeColumnTable) {
- ReplyErrorAndDie(Ydb::StatusIds::SCHEME_ERROR, "Invalid path type");
- return;
+ if (auto pathType = ToString(pathDescription.GetSelf().GetPathType()); pathType != PathType) {
+ return ReplyErrorAndDie(Ydb::StatusIds::BAD_REQUEST, TStringBuilder()
+ << "Expected path type: " << PathType
+ << ", actual path type: " << pathType
+ );
}
std::pair<TString, TString> pathPair;
-
{
TString error;
if (!TrySplitPathByDb(Path, Database, pathPair, error)) {
@@ -152,29 +177,20 @@ private:
}
}
- auto [_, tablePath] = pathPair;
- bool temporary = false;
-
- if (NKqp::IsSessionsDirPath(Database, tablePath)) {
- auto pathVecTmp = SplitPath(tablePath);
- auto sz = pathVecTmp.size();
- Y_ENSURE(sz > 3 && pathVecTmp[0] == ".tmp" && pathVecTmp[1] == "sessions");
-
- auto pathTmp = JoinPath(TVector<TString>(pathVecTmp.begin() + 3, pathVecTmp.end()));
- std::pair<TString, TString> pathPairTmp;
- TString error;
- if (!TrySplitPathByDb(pathTmp, Database, pathPairTmp, error)) {
- ReplyErrorAndDie(Ydb::StatusIds::SCHEME_ERROR, error);
- return;
- }
-
- tablePath = pathPairTmp.second;
- temporary = true;
- }
-
switch (pathDescription.GetSelf().GetPathType()) {
case NKikimrSchemeOp::EPathTypeTable: {
const auto& tableDesc = pathDescription.GetTable();
+ auto tablePath = pathPair.second;
+
+ bool temporary = false;
+ if (NKqp::IsSessionsDirPath(Database, pathPair.second)) {
+ TString error;
+ if (!RewriteTemporaryTablePath(Database, tablePath, error)) {
+ return ReplyErrorAndDie(Ydb::StatusIds::SCHEME_ERROR, error);
+ }
+ temporary = true;
+ }
+
TCreateTableFormatter formatter;
auto formatterResult = formatter.Format(tablePath, tableDesc, temporary);
if (formatterResult.IsSuccess()) {
@@ -188,6 +204,17 @@ private:
}
case NKikimrSchemeOp::EPathTypeColumnTable: {
const auto& columnTableDesc = pathDescription.GetColumnTableDescription();
+ auto tablePath = pathPair.second;
+
+ bool temporary = false;
+ if (NKqp::IsSessionsDirPath(Database, pathPair.second)) {
+ TString error;
+ if (!RewriteTemporaryTablePath(Database, tablePath, error)) {
+ return ReplyErrorAndDie(Ydb::StatusIds::SCHEME_ERROR, error);
+ }
+ temporary = true;
+ }
+
TCreateTableFormatter formatter;
auto formatterResult = formatter.Format(tablePath, columnTableDesc, temporary);
if (formatterResult.IsSuccess()) {
@@ -200,8 +227,9 @@ private:
break;
}
default: {
- ReplyErrorAndDie(Ydb::StatusIds::SCHEME_ERROR, "Invalid path type");
- return;
+ return ReplyErrorAndDie(Ydb::StatusIds::BAD_REQUEST, TStringBuilder()
+ << "Unsupported path type: " << pathDescription.GetSelf().GetPathType()
+ );
}
}
break;
diff --git a/ydb/core/sys_view/show_create/ya.make b/ydb/core/sys_view/show_create/ya.make
index 16fad0e331..7a3bb3fae3 100644
--- a/ydb/core/sys_view/show_create/ya.make
+++ b/ydb/core/sys_view/show_create/ya.make
@@ -2,9 +2,8 @@ LIBRARY()
SRCS(
create_table_formatter.cpp
- create_table_formatter.h
+ formatters_common.cpp
show_create.cpp
- show_create.h
)
PEERDIR(