Browse Source

[YQL-14487] Support SQL PgConst() callable

ref:4d5beb06c17c6f2e89c2c299698325491b35658d
aneporada 3 years ago
parent
commit
bc921e787b

+ 20 - 3
ydb/library/yql/core/type_ann/type_ann_core.cpp

@@ -9509,15 +9509,32 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
             return IGraphTransformer::TStatus::Error;
         }
 
-        if (!EnsureAtom(*input->Child(0), ctx.Expr)) {
-            return IGraphTransformer::TStatus::Error;
+        ui32 typeId;
+        if (input->Child(0)->IsAtom()) {
+            auto type = input->Child(0)->Content();
+            if (!NPg::HasType(type)) {
+                ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(0)->Pos()),
+                    TStringBuilder() << "Unknown type: '" << type << "'"));
+                return IGraphTransformer::TStatus::Error;
+            }
+            typeId = NPg::LookupType(TString(input->Child(0)->Content())).TypeId;
+        } else {
+            if (!EnsureType(input->Head(), ctx.Expr)) {
+                return IGraphTransformer::TStatus::Error;
+            }
+            auto typeAnn = input->Head().GetTypeAnn()->Cast<TTypeExprType>()->GetType();
+            if (typeAnn->GetKind() != ETypeAnnotationKind::Pg) {
+                ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(0)->Pos()),
+                    TStringBuilder() << "Expecting Pg type, got: " << *typeAnn));
+                return IGraphTransformer::TStatus::Error;
+            }
+            typeId = typeAnn->Cast<TPgExprType>()->GetId();
         }
 
         if (!EnsureAtom(*input->Child(1), ctx.Expr)) {
             return IGraphTransformer::TStatus::Error;
         }
 
-        auto typeId = NPg::LookupType(TString(input->Child(0)->Content())).TypeId;
         input->SetTypeAnn(ctx.Expr.MakeType<TPgExprType>(typeId));
         return IGraphTransformer::TStatus::Ok;
     }

+ 28 - 0
ydb/library/yql/sql/v1/builtin.cpp

@@ -588,6 +588,33 @@ public:
     }
 };
 
+class TYqlPgConst : public TCallNode {
+public:
+    TYqlPgConst(TPosition pos, const TVector<TNodePtr>& args)
+        : TCallNode(pos, "PgConst", 2, 2, args)
+    {
+    }
+
+    bool DoInit(TContext& ctx, ISource* src) override {
+        if (!ValidateArguments(ctx)) {
+            return false;
+        }
+
+        if (!Args[1]->Init(ctx, src)) {
+            return false;
+        }
+        auto value = MakeAtomFromExpression(ctx, Args[1]).Build();
+        Args[1] = value;
+
+        return TCallNode::DoInit(ctx, src);
+    }
+
+    TNodePtr DoClone() const final {
+        return new TYqlPgConst(Pos, Args);
+    }
+};
+
+
 template <const char* Name>
 class TYqlSubqueryFor : public TCallNode {
 public:
@@ -2608,6 +2635,7 @@ struct TBuiltinFuncData {
             {"nothing", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("Nothing", 1, 1) },
             {"formattype", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("FormatType", 1, 1) },
             {"pgtype", BuildSimpleBuiltinFactoryCallback<TYqlPgType>() },
+            {"pgconst", BuildSimpleBuiltinFactoryCallback<TYqlPgConst>() },
             {"typeof", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("TypeOf", 1, 1) },
             {"instanceof", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("InstanceOf", 1, 1) },
             {"datatype", BuildSimpleBuiltinFactoryCallback<TYqlDataType>() },

+ 2 - 0
ydb/library/yql/sql/v1/context.cpp

@@ -430,6 +430,8 @@ TMaybe<EColumnRefState> GetFunctionArgColumnStatus(TContext& ctx, const TString&
         { {"formattype", 0},          EColumnRefState::Deny },
         { {"instanceof", 0},          EColumnRefState::Deny },
         { {"pgtype", 0},              EColumnRefState::AsPgType },
+        { {"pgconst", 0},             EColumnRefState::AsPgType },
+        { {"pgconst", 1},             EColumnRefState::Deny },
 
         { {"unpickle", 0},            EColumnRefState::Deny },
         { {"typehandle", 0},          EColumnRefState::Deny },