From 20aef2e63f764c7e13e75bad33eed4cba371ced1 Mon Sep 17 00:00:00 2001 From: Vitalii Gridnev Date: Wed, 24 Apr 2024 19:59:44 +0300 Subject: [PATCH] implicit cast for default values --- ydb/core/kqp/provider/yql_kikimr_type_ann.cpp | 31 ++++++++++++++++--- ydb/core/kqp/ut/pg/kqp_pg_ut.cpp | 1 + 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/ydb/core/kqp/provider/yql_kikimr_type_ann.cpp b/ydb/core/kqp/provider/yql_kikimr_type_ann.cpp index 06388123bcb7..ffb188b5f742 100644 --- a/ydb/core/kqp/provider/yql_kikimr_type_ann.cpp +++ b/ydb/core/kqp/provider/yql_kikimr_type_ann.cpp @@ -294,7 +294,7 @@ namespace { return true; } - bool ParseConstraintNode(TExprContext& ctx, TKikimrColumnMetadata& columnMeta, const TExprList& columnTuple, TCoNameValueTuple constraint, TKikimrConfiguration& config, bool isAlter = false) { + bool ParseConstraintNode(TExprContext& ctx, TKikimrColumnMetadata& columnMeta, const TExprList& columnTuple, TCoNameValueTuple constraint, TKikimrConfiguration& config, bool& needEval, bool isAlter = false) { auto nameNode = columnTuple.Item(0).Cast(); auto typeNode = columnTuple.Item(1); @@ -341,9 +341,23 @@ namespace { } if (!skipAnnotationValidation && !IsSameAnnotation(*defaultType, *actualType)) { - ctx.AddError(TIssue(ctx.GetPosition(constraint.Pos()), TStringBuilder() << "Default expr " << columnName - << " type mismatch, expected: " << (*actualType) << ", actual: " << *(defaultType))); + auto constrPtr = constraint.Value().Cast().Ptr(); + auto status = TryConvertTo(constrPtr, *type, ctx); + if (status == IGraphTransformer::TStatus::Error) { + ctx.AddError(TIssue(ctx.GetPosition(constraint.Pos()), TStringBuilder() << "Default expr " << columnName + << " type mismatch, expected: " << (*actualType) << ", actual: " << *(defaultType))); return false; + } else if (status == IGraphTransformer::TStatus::Repeat) { + auto evaluatedExpr = ctx.Builder(constrPtr->Pos()) + .Callable("EvaluateExpr") + .Add(0, constrPtr) + .Seal() + .Build(); + + constraint.Ptr()->ChildRef(TCoNameValueTuple::idx_Value) = evaluatedExpr; + needEval = true; + return true; + } } if (columnMeta.IsDefaultKindDefined()) { @@ -863,9 +877,15 @@ virtual TStatus HandleCreateTable(TKiCreateTable create, TExprContext& ctx) over if (columnTuple.Size() > 2) { const auto& columnConstraints = columnTuple.Item(2).Cast(); for(const auto& constraint: columnConstraints.Value().Cast()) { - if (!ParseConstraintNode(ctx, columnMeta, columnTuple, constraint, SessionCtx->Config())) { + bool needEval = false; + if (!ParseConstraintNode(ctx, columnMeta, columnTuple, constraint, SessionCtx->Config(), needEval)) { return TStatus::Error; } + + if (needEval) { + ctx.Step.Repeat(TExprStep::ExprEval); + return TStatus(TStatus::Repeat, true); + } } } @@ -1278,7 +1298,8 @@ virtual TStatus HandleCreateTable(TKiCreateTable create, TExprContext& ctx) over if (columnTuple.Size() > 2) { const auto& columnConstraints = columnTuple.Item(2).Cast(); for(const auto& constraint: columnConstraints.Value().Cast()) { - if (!ParseConstraintNode(ctx, columnMeta, columnTuple, constraint, SessionCtx->Config(), true)) { + bool needEval = false; + if (!ParseConstraintNode(ctx, columnMeta, columnTuple, constraint, SessionCtx->Config(), needEval, true)) { return TStatus::Error; } } diff --git a/ydb/core/kqp/ut/pg/kqp_pg_ut.cpp b/ydb/core/kqp/ut/pg/kqp_pg_ut.cpp index f3c2c3678cfb..e935e675cb70 100644 --- a/ydb/core/kqp/ut/pg/kqp_pg_ut.cpp +++ b/ydb/core/kqp/ut/pg/kqp_pg_ut.cpp @@ -3743,6 +3743,7 @@ Y_UNIT_TEST_SUITE(KqpPg) { d varchar(20) DEFAULT 'foo'::varchar(2), e int DEFAULT NULL, f bit varying(5) DEFAULT '1001', + g bigint DEFAULT 0 NOT NULL, PRIMARY KEY(a) ); )", NYdb::NQuery::TTxControl::NoTx(), settings).ExtractValueSync();