diff options
author | udovichenko-r <[email protected]> | 2022-06-01 08:12:46 +0300 |
---|---|---|
committer | udovichenko-r <[email protected]> | 2022-06-01 08:12:46 +0300 |
commit | b9ca6add54055c55757fe7afcfcb408d8530e8f9 (patch) | |
tree | 171d556173e977b5a00faf3eff0a51f129f20285 | |
parent | 4ae9d1eb320226b37bc2de7b05b22092e3666771 (diff) |
[yql] Support Pg values in evaluation
YQL-12393
ref:135b1b52d9e65c1a95493bb469352d14e23453b3
-rw-r--r-- | ydb/library/yql/parser/pg_wrapper/comp_factory.cpp | 95 | ||||
-rw-r--r-- | ydb/library/yql/providers/common/codec/yql_codec.cpp | 23 | ||||
-rw-r--r-- | ydb/library/yql/providers/common/codec/yql_pg_codec.h | 3 | ||||
-rw-r--r-- | ydb/library/yql/sql/pg_dummy/pg_sql_dummy.cpp | 13 |
4 files changed, 125 insertions, 9 deletions
diff --git a/ydb/library/yql/parser/pg_wrapper/comp_factory.cpp b/ydb/library/yql/parser/pg_wrapper/comp_factory.cpp index f210675a203..001ab87e6ee 100644 --- a/ydb/library/yql/parser/pg_wrapper/comp_factory.cpp +++ b/ydb/library/yql/parser/pg_wrapper/comp_factory.cpp @@ -1595,15 +1595,13 @@ void WriteYsonValueInTableFormatPg(TOutputBuf& buf, TPgType* type, const NUdf::T } } -void WriteYsonValuePg(TYsonResultWriter& writer, const NUdf::TUnboxedValuePod& value, NKikimr::NMiniKQL::TPgType* type, - const TVector<ui32>* structPositions) { +TString PgValueToString(const NUdf::TUnboxedValuePod& value, ui32 pgTypeId) { if (!value) { - writer.OnNull(); - return; + return "null"; } TString ret; - switch (type->GetTypeId()) { + switch (pgTypeId) { case BOOLOID: ret = DatumGetBool(ScalarDatumFromPod(value)) ? "true" : "false"; break; @@ -1636,7 +1634,7 @@ void WriteYsonValuePg(TYsonResultWriter& writer, const NUdf::TUnboxedValuePod& v } default: TPAllocScope call; - const auto& typeInfo = NPg::LookupType(type->GetTypeId()); + const auto& typeInfo = NPg::LookupType(pgTypeId); auto outFuncId = typeInfo.OutFuncId; if (typeInfo.TypeId == typeInfo.ArrayTypeId) { outFuncId = NPg::LookupProc("array_out", { 0 }).ProcId; @@ -1667,10 +1665,20 @@ void WriteYsonValuePg(TYsonResultWriter& writer, const NUdf::TUnboxedValuePod& v ret = str; } - writer.OnStringScalar(ret); + return ret; } -NUdf::TUnboxedValue ReadYsonValuePg(TPgType* type, char cmd, TInputBuf& buf) { +void WriteYsonValuePg(TYsonResultWriter& writer, const NUdf::TUnboxedValuePod& value, NKikimr::NMiniKQL::TPgType* type, + const TVector<ui32>* structPositions) { + if (!value) { + writer.OnNull(); + return; + } + + writer.OnStringScalar(PgValueToString(value, type->GetTypeId())); +} + +NUdf::TUnboxedValue ReadYsonValueInTableFormatPg(TPgType* type, char cmd, TInputBuf& buf) { using namespace NYson::NDetail; if (cmd == EntitySymbol) { return NUdf::TUnboxedValuePod(); @@ -1762,6 +1770,77 @@ NUdf::TUnboxedValue ReadYsonValuePg(TPgType* type, char cmd, TInputBuf& buf) { } } +NUdf::TUnboxedValue ReadYsonValuePg(TPgType* type, char cmd, TInputBuf& buf) { + using namespace NYson::NDetail; + if (cmd == EntitySymbol) { + return NUdf::TUnboxedValuePod(); + } + + CHECK_EXPECTED(cmd, StringMarker); + auto s = buf.ReadYtString(); + switch (type->GetTypeId()) { + case BOOLOID: { + return ScalarDatumToPod(BoolGetDatum(FromString<bool>(s))); + } + case INT2OID: { + return ScalarDatumToPod(Int16GetDatum(FromString<i16>(s))); + } + case INT4OID: { + return ScalarDatumToPod(Int32GetDatum(FromString<i32>(s))); + } + case INT8OID: { + return ScalarDatumToPod(Int64GetDatum(FromString<i64>(s))); + } + case FLOAT4OID: { + return ScalarDatumToPod(Float4GetDatum(FromString<float>(s))); + } + case FLOAT8OID: { + return ScalarDatumToPod(Float8GetDatum(FromString<double>(s))); + } + case BYTEAOID: + case VARCHAROID: + case TEXTOID: { + auto ret = MakeVar(s); + return PointerDatumToPod((Datum)ret); + } + case CSTRINGOID: { + auto ret = MakeCString(s); + return PointerDatumToPod((Datum)ret); + } + default: + TString str{s}; + + TPAllocScope call; + const auto& typeInfo = NPg::LookupType(type->GetTypeId()); + auto typeIOParam = MakeTypeIOParam(typeInfo); + auto inFuncId = typeInfo.InFuncId; + if (typeInfo.TypeId == typeInfo.ArrayTypeId) { + inFuncId = NPg::LookupProc("array_in", { 0,0,0 }).ProcId; + } + + FmgrInfo finfo; + Zero(finfo); + Y_ENSURE(inFuncId); + fmgr_info(inFuncId, &finfo); + Y_ENSURE(!finfo.fn_retset); + Y_ENSURE(finfo.fn_addr); + Y_ENSURE(finfo.fn_nargs >= 1 && finfo.fn_nargs <= 3); + LOCAL_FCINFO(callInfo, 3); + Zero(*callInfo); + callInfo->flinfo = &finfo; + callInfo->nargs = 3; + callInfo->fncollation = DEFAULT_COLLATION_OID; + callInfo->isnull = false; + callInfo->args[0] = { (Datum)str.c_str(), false }; + callInfo->args[1] = { ObjectIdGetDatum(typeIOParam), false }; + callInfo->args[2] = { Int32GetDatum(-1), false }; + + auto x = finfo.fn_addr(callInfo); + Y_ENSURE(!callInfo->isnull); + return typeInfo.PassByValue ? ScalarDatumToPod(x) : PointerDatumToPod(x); + } +} + NKikimr::NUdf::TUnboxedValue ReadSkiffPg(NKikimr::NMiniKQL::TPgType* type, NCommon::TInputBuf& buf) { auto marker = buf.Read(); if (!marker) { diff --git a/ydb/library/yql/providers/common/codec/yql_codec.cpp b/ydb/library/yql/providers/common/codec/yql_codec.cpp index 8f06281f45d..01e3e863881 100644 --- a/ydb/library/yql/providers/common/codec/yql_codec.cpp +++ b/ydb/library/yql/providers/common/codec/yql_codec.cpp @@ -1243,7 +1243,7 @@ NUdf::TUnboxedValue ReadYsonValue(TType* type, case TType::EKind::Pg: { auto pgType = static_cast<TPgType*>(type); - return ReadYsonValuePg(pgType, cmd, buf); + return isTableFormat ? ReadYsonValueInTableFormatPg(pgType, cmd, buf) : ReadYsonValuePg(pgType, cmd, buf); } default: @@ -2419,6 +2419,27 @@ TExprNode::TPtr ValueToExprLiteral(const TTypeAnnotationNode* type, const NKikim }); } + case ETypeAnnotationKind::Pg: { + auto pgType = type->Cast<TPgExprType>(); + if (!value) { + return ctx.NewCallable(pos, "PgCast", { + ctx.NewCallable(pos, "Utf8", { + ctx.NewAtom(pos, "null") + }), + ctx.NewCallable(pos, "PgType", { + ctx.NewAtom(pos, pgType->GetName()) + }) + }); + } else { + return ctx.NewCallable(pos, "PgConst", { + ctx.NewAtom(pos, PgValueToString(value, pgType->GetId())), + ctx.NewCallable(pos, "PgType", { + ctx.NewAtom(pos, pgType->GetName()) + }) + }); + } + } + default: break; } diff --git a/ydb/library/yql/providers/common/codec/yql_pg_codec.h b/ydb/library/yql/providers/common/codec/yql_pg_codec.h index b20adab166e..36a09bec4fb 100644 --- a/ydb/library/yql/providers/common/codec/yql_pg_codec.h +++ b/ydb/library/yql/providers/common/codec/yql_pg_codec.h @@ -12,11 +12,14 @@ namespace NYql { namespace NCommon { +TString PgValueToString(const NUdf::TUnboxedValuePod& value, ui32 pgTypeId); + void WriteYsonValuePg(TYsonResultWriter& writer, const NUdf::TUnboxedValuePod& value, NKikimr::NMiniKQL::TPgType* type, const TVector<ui32>* structPositions); void WriteYsonValueInTableFormatPg(TOutputBuf& buf, NKikimr::NMiniKQL::TPgType* type, const NKikimr::NUdf::TUnboxedValuePod& value); +NUdf::TUnboxedValue ReadYsonValueInTableFormatPg(NKikimr::NMiniKQL::TPgType* type, char cmd, TInputBuf& buf); NUdf::TUnboxedValue ReadYsonValuePg(NKikimr::NMiniKQL::TPgType* type, char cmd, TInputBuf& buf); extern "C" void ReadSkiffPgValue(NKikimr::NMiniKQL::TPgType* type, NKikimr::NUdf::TUnboxedValue& value, NCommon::TInputBuf& buf); diff --git a/ydb/library/yql/sql/pg_dummy/pg_sql_dummy.cpp b/ydb/library/yql/sql/pg_dummy/pg_sql_dummy.cpp index 1688176083e..3f97980d3e3 100644 --- a/ydb/library/yql/sql/pg_dummy/pg_sql_dummy.cpp +++ b/ydb/library/yql/sql/pg_dummy/pg_sql_dummy.cpp @@ -20,6 +20,12 @@ NYql::TAstParseResult PGToYql(const TString& query, const NSQLTranslation::TTran namespace NYql { namespace NCommon { +TString PgValueToString(const NUdf::TUnboxedValuePod& value, ui32 pgTypeId) { + Y_UNUSED(value); + Y_UNUSED(pgTypeId); + throw yexception() << "PG types are not supported"; +} + void WriteYsonValuePg(TYsonResultWriter& writer, const NUdf::TUnboxedValuePod& value, NKikimr::NMiniKQL::TPgType* type, const TVector<ui32>* structPositions) { Y_UNUSED(writer); @@ -36,6 +42,13 @@ void WriteYsonValueInTableFormatPg(TOutputBuf& buf, NKikimr::NMiniKQL::TPgType* throw yexception() << "PG types are not supported"; } +NUdf::TUnboxedValue ReadYsonValueInTableFormatPg(NKikimr::NMiniKQL::TPgType* type, char cmd, TInputBuf& buf) { + Y_UNUSED(type); + Y_UNUSED(cmd); + Y_UNUSED(buf); + throw yexception() << "PG types are not supported"; +} + NUdf::TUnboxedValue ReadYsonValuePg(NKikimr::NMiniKQL::TPgType* type, char cmd, TInputBuf& buf) { Y_UNUSED(type); Y_UNUSED(cmd); |