Skip to content

Commit

Permalink
Merge 37bd9db into 33ba54d
Browse files Browse the repository at this point in the history
  • Loading branch information
gridnevvvit authored Feb 8, 2024
2 parents 33ba54d + 37bd9db commit 3ed7ded
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 16 deletions.
45 changes: 42 additions & 3 deletions ydb/core/kqp/provider/yql_kikimr_datasink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -787,7 +787,7 @@ class TKikimrDataSink : public TDataProviderBase
auto replaceIfExists = (settings.Mode.Cast().Value() == "create_or_replace");
auto existringOk = (settings.Mode.Cast().Value() == "create_if_not_exists");

return Build<TKiCreateTable>(ctx, node->Pos())
auto createTable = Build<TKiCreateTable>(ctx, node->Pos())
.World(node->Child(0))
.DataSink(node->Child(1))
.Table().Build(key.GetTablePath())
Expand All @@ -807,8 +807,47 @@ class TKikimrDataSink : public TDataProviderBase
.ExistingOk<TCoAtom>()
.Value(existringOk)
.Build()
.Done()
.Ptr();
.Done();

bool exprEvalNeeded = false;

for(auto item: createTable.Cast<TKiCreateTable>().Columns()) {
auto columnTuple = item.Cast<TExprList>();
if (columnTuple.Size() > 2) {
const auto& columnConstraints = columnTuple.Item(2).Cast<TCoNameValueTuple>();
for(const auto& constraint: columnConstraints.Value().Cast<TCoNameValueTupleList>()) {
if (constraint.Name().Value() != "default")
continue;

YQL_ENSURE(constraint.Value().IsValid());
bool shouldEvaluate = (
constraint.Value().Cast().Ptr()->IsCallable() &&
(constraint.Value().Cast().Ptr()->Content() == "PgCast") &&
(constraint.Value().Cast().Ptr()->ChildrenSize() >= 1) &&
(constraint.Value().Cast().Ptr()->Child(0)->IsCallable()) &&
(constraint.Value().Cast().Ptr()->Child(0)->Content() == "PgConst")
);

if (shouldEvaluate) {
auto evaluatedExpr = ctx.Builder(constraint.Value().Cast().Ptr()->Pos())
.Callable("EvaluateExpr")
.Add(0, constraint.Value().Cast().Ptr())
.Seal()
.Build();

constraint.Ptr()->ChildRef(TCoNameValueTuple::idx_Value) = evaluatedExpr;
exprEvalNeeded = true;
}
}
}
}

if (exprEvalNeeded) {
ctx.Step.Repeat(TExprStep::ExprEval);
}

return createTable.Ptr();

} else if (mode == "alter") {
for (auto setting : settings.Other) {
if (setting.Name().Value() == "intent") {
Expand Down
38 changes: 25 additions & 13 deletions ydb/core/kqp/provider/yql_kikimr_type_ann.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -808,7 +808,13 @@ virtual TStatus HandleCreateTable(TKiCreateTable create, TExprContext& ctx) over

columnMeta.SetDefaultFromLiteral();

if (auto pgConst = constraint.Value().Maybe<TCoPgConst>()) {
YQL_ENSURE(constraint.Value().IsValid());
const auto& constrValue = constraint.Value().Cast();
bool isPgNull = constrValue.Ptr()->IsCallable() &&
constrValue.Ptr()->Content() == "PgCast" && constrValue.Ptr()->ChildrenSize() >= 1 &&
constrValue.Ptr()->Child(0)->IsCallable() && constrValue.Ptr()->Child(0)->Content() == "Null";

if (constrValue.Maybe<TCoPgConst>() || isPgNull) {
auto actualPgType = actualType->Cast<TPgExprType>();
YQL_ENSURE(actualPgType);

Expand All @@ -819,25 +825,31 @@ virtual TStatus HandleCreateTable(TKiCreateTable create, TExprContext& ctx) over
return TStatus::Error;
}

TString content = TString(pgConst.Cast().Value().Value());
auto parseResult = NKikimr::NPg::PgNativeBinaryFromNativeText(content, typeDesc);
if (parseResult.Error) {
ctx.AddError(TIssue(ctx.GetPosition(constraint.Pos()),
TStringBuilder() << "Failed to parse default expr for typename " << actualPgType->GetName()
<< ", error reason: " << *parseResult.Error));
return TStatus::Error;
if (isPgNull) {
columnMeta.DefaultFromLiteral.mutable_value()->set_null_flag_value(NProtoBuf::NULL_VALUE);
} else {
YQL_ENSURE(constrValue.Maybe<TCoPgConst>());
auto pgConst = constrValue.Cast<TCoPgConst>();
TString content = TString(pgConst.Value().Value());
auto parseResult = NKikimr::NPg::PgNativeBinaryFromNativeText(content, typeDesc);
if (parseResult.Error) {
ctx.AddError(TIssue(ctx.GetPosition(constraint.Pos()),
TStringBuilder() << "Failed to parse default expr for typename " << actualPgType->GetName()
<< ", error reason: " << *parseResult.Error));
return TStatus::Error;
}

columnMeta.DefaultFromLiteral.mutable_value()->set_bytes_value(parseResult.Str);
}

columnMeta.DefaultFromLiteral.mutable_value()->set_bytes_value(parseResult.Str);
auto* pg = columnMeta.DefaultFromLiteral.mutable_type()->mutable_pg_type();

pg->set_type_name(NKikimr::NPg::PgTypeNameFromTypeDesc(typeDesc));
pg->set_oid(NKikimr::NPg::PgTypeIdFromTypeDesc(typeDesc));
} else if (auto literal = constraint.Value().Maybe<TCoDataCtor>()) {
FillLiteralProto(constraint.Value().Cast<TCoDataCtor>(), columnMeta.DefaultFromLiteral);
} else if (auto literal = constrValue.Maybe<TCoDataCtor>()) {
FillLiteralProto(literal.Cast(), columnMeta.DefaultFromLiteral);
} else {
ctx.AddError(TIssue(ctx.GetPosition(constraint.Pos()),
TStringBuilder() << "Unsupported type of default value " << constraint.Value().Cast().Ptr()->Content()));
TStringBuilder() << "Unsupported type of default value"));
return TStatus::Error;
}

Expand Down
43 changes: 43 additions & 0 deletions ydb/core/kqp/ut/pg/kqp_pg_ut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3401,6 +3401,49 @@ Y_UNIT_TEST_SUITE(KqpPg) {
}
}

Y_UNIT_TEST(InsertValuesFromTableWithDefaultAndCast) {
NKikimrConfig::TAppConfig appConfig;
appConfig.MutableTableServiceConfig()->SetEnablePreparedDdl(true);
auto setting = NKikimrKqp::TKqpSetting();
auto serverSettings = TKikimrSettings()
.SetAppConfig(appConfig)
.SetKqpSettings({setting});
TKikimrRunner kikimr(serverSettings.SetWithSampleTables(false));
auto db = kikimr.GetQueryClient();
auto settings = NYdb::NQuery::TExecuteQuerySettings().Syntax(NYdb::NQuery::ESyntax::Pg);
{
auto result = db.ExecuteQuery(R"(
CREATE TABLE t (
a INT,
b int DEFAULT 5::int4,
c int DEFAULT '7'::int4,
d varchar(20) DEFAULT 'foo'::varchar(2),
e int DEFAULT NULL,
f bit varying(5) DEFAULT '1001',
PRIMARY KEY(a)
);
)", NYdb::NQuery::TTxControl::NoTx(), settings).ExtractValueSync();
UNIT_ASSERT_C(result.IsSuccess(), result.GetIssues().ToString());
}
{
auto result = db.ExecuteQuery(R"(
INSERT INTO t VALUES(1);
)", NYdb::NQuery::TTxControl::BeginTx().CommitTx(), settings).ExtractValueSync();
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString());
}
{
auto result = db.ExecuteQuery(R"(
SELECT * FROM t;
)", NYdb::NQuery::TTxControl::BeginTx().CommitTx(), settings).ExtractValueSync();
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString());

UNIT_ASSERT_C(!result.GetResultSets().empty(), "results are empty");
CompareYson(R"(
[["1";"5";"7";"fo";#;"1001"]]
)", FormatResultSetYson(result.GetResultSet(0)));
}
}

Y_UNIT_TEST(InsertValuesFromTableWithDefaultBool) {
NKikimrConfig::TAppConfig appConfig;
appConfig.MutableTableServiceConfig()->SetEnablePreparedDdl(true);
Expand Down

0 comments on commit 3ed7ded

Please sign in to comment.