From f6e0d968f423f1c82824c21783a2b508e2ab6baa Mon Sep 17 00:00:00 2001 From: Vitaly Stoyan Date: Thu, 10 Oct 2024 12:41:30 +0300 Subject: [PATCH] Fixed crash in pg_show_all_settings (#10261) --- .../yql/parser/pg_catalog/safe_procs.h | 1 + .../yql/parser/pg_wrapper/comp_factory.cpp | 72 ++++++++++++++----- .../src/backend/utils/misc/guc_funcs.c | 3 +- .../part12/canondata/result.json | 4 +- 4 files changed, 59 insertions(+), 21 deletions(-) diff --git a/ydb/library/yql/parser/pg_catalog/safe_procs.h b/ydb/library/yql/parser/pg_catalog/safe_procs.h index 265759d480be..be13dd59c032 100644 --- a/ydb/library/yql/parser/pg_catalog/safe_procs.h +++ b/ydb/library/yql/parser/pg_catalog/safe_procs.h @@ -24,6 +24,7 @@ "jsonb_path_query_first_tz", "jsonb_typeof", +"pg_show_all_settings",//pgadmin "pg_is_in_recovery",//pgadmin "pg_is_wal_replay_paused",//pgadmin "has_database_privilege",//pgadmin diff --git a/ydb/library/yql/parser/pg_wrapper/comp_factory.cpp b/ydb/library/yql/parser/pg_wrapper/comp_factory.cpp index e586dbb7390d..f19c8619d95a 100644 --- a/ydb/library/yql/parser/pg_wrapper/comp_factory.cpp +++ b/ydb/library/yql/parser/pg_wrapper/comp_factory.cpp @@ -1249,6 +1249,15 @@ class TPgResolvedCallBase : public TMutableComputationNode { } FInfo.fn_expr = ArgsExprBuilder.Build(ProcDesc); + + if (StructType) { + StructTypeDesc.reserve(StructType->GetMembersCount()); + for (ui32 i = 0; i < StructType->GetMembersCount(); ++i) { + auto itemType = StructType->GetMemberType(i); + auto type = AS_TYPE(TPgType, itemType)->GetTypeId(); + StructTypeDesc.emplace_back(NPg::LookupType(type)); + } + } } private: @@ -1268,6 +1277,7 @@ class TPgResolvedCallBase : public TMutableComputationNode { const TVector ArgTypes; const TStructType* StructType; TVector ArgDesc; + TVector StructTypeDesc; TPgArgsExprBuilder ArgsExprBuilder; }; @@ -1370,7 +1380,7 @@ class TPgResolvedMultiCall : public TPgResolvedCallBase { public: TIterator(TMemoryUsageInfo* memInfo, const std::string_view& name, const TUnboxedValueVector& args, const TVector& argDesc, const NPg::TTypeDesc& retTypeDesc, const NPg::TProcDesc& procDesc, - const FmgrInfo* fInfo, const TStructType* structType, const THolderFactory& holderFactory) + const FmgrInfo* fInfo, const TStructType* structType, const TVector& structTypeDesc, const THolderFactory& holderFactory) : TComputationValue(memInfo) , Name(name) , Args(args) @@ -1379,6 +1389,7 @@ class TPgResolvedMultiCall : public TPgResolvedCallBase { , ProcDesc(procDesc) , CallInfo(argDesc.size(), fInfo) , StructType(structType) + , StructTypeDesc(structTypeDesc) , HolderFactory(holderFactory) { auto& callInfo = CallInfo.Ref(); @@ -1457,20 +1468,38 @@ class TPgResolvedMultiCall : public TPgResolvedCallBase { tuplestore_select_read_pointer(RSInfo.Ref().setResult, readPtr); return CopyTuple(value); } else { - YQL_ENSURE(!StructType); if (RSInfo.Ref().isDone == ExprEndResult) { FinishAndFree(); return false; } - if (callInfo.isnull) { - value = NUdf::TUnboxedValuePod(); + if (StructType) { + YQL_ENSURE(!callInfo.isnull); + auto tuple = DatumGetHeapTupleHeader(ret); + YQL_ENSURE(HeapTupleHeaderGetNatts(tuple) == StructType->GetMembersCount()); + HeapTupleData tmptup; + tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple); + ItemPointerSetInvalid(&(tmptup.t_self)); + tmptup.t_tableOid = InvalidOid; + tmptup.t_data = tuple; + + NUdf::TUnboxedValue* itemsPtr; + value = HolderFactory.CreateDirectArrayHolder(StructType->GetMembersCount(), itemsPtr); + for (ui32 i = 0; i < StructType->GetMembersCount(); ++i) { + bool isNull; + auto datum = heap_getattr(&tmptup,i + 1,RSInfo.Ref().expectedDesc,&isNull); + itemsPtr[StructIndicies[i]] = CloneTupleItem(i, isNull, datum); + } } else { - if (RetTypeDesc.PassByValue) { - value = ScalarDatumToPod(ret); + if (callInfo.isnull) { + value = NUdf::TUnboxedValuePod(); } else { - auto cloned = datumCopy(ret, false, RetTypeDesc.TypeLen); - value = PointerDatumToPod(cloned); + if (RetTypeDesc.PassByValue) { + value = ScalarDatumToPod(ret); + } else { + auto cloned = datumCopy(ret, false, RetTypeDesc.TypeLen); + value = PointerDatumToPod(cloned); + } } } @@ -1513,26 +1542,30 @@ class TPgResolvedMultiCall : public TPgResolvedCallBase { return true; } - NUdf::TUnboxedValuePod CloneTupleItem(ui32 index) { - if (TupleSlot->tts_isnull[index]) { + NUdf::TUnboxedValuePod CloneTupleItem(ui32 index, bool isNull, Datum datum) { + if (isNull) { return NUdf::TUnboxedValuePod(); } else { - auto datum = TupleSlot->tts_values[index]; - if (RetTypeDesc.PassByValue) { + const auto& desc = StructType ? StructTypeDesc[StructIndicies[index]] : RetTypeDesc; + if (desc.PassByValue) { return ScalarDatumToPod(datum); - } else if (RetTypeDesc.TypeLen == -1) { + } else if (desc.TypeLen == -1) { const text* orig = (const text*)datum; return PointerDatumToPod((Datum)MakeVar(GetVarBuf(orig))); - } else if(RetTypeDesc.TypeLen == -2) { + } else if(desc.TypeLen == -2) { const char* orig = (const char*)datum; return PointerDatumToPod((Datum)MakeCString(orig)); } else { const char* orig = (const char*)datum; - return PointerDatumToPod((Datum)MakeFixedString(orig, RetTypeDesc.TypeLen)); + return PointerDatumToPod((Datum)MakeFixedString(orig, desc.TypeLen)); } } } + NUdf::TUnboxedValuePod CloneTupleItem(ui32 index) { + return CloneTupleItem(index, TupleSlot->tts_isnull[index], TupleSlot->tts_values[index]); + } + void FinishAndFree() { if (TupleSlot) { ExecDropSingleTupleTableSlot(TupleSlot); @@ -1552,6 +1585,7 @@ class TPgResolvedMultiCall : public TPgResolvedCallBase { TExprContextHolder ExprContextHolder; TFunctionCallInfo CallInfo; const TStructType* StructType; + const TVector& StructTypeDesc; const THolderFactory& HolderFactory; TReturnSetInfo RSInfo; bool IsFinished = false; @@ -1562,7 +1596,7 @@ class TPgResolvedMultiCall : public TPgResolvedCallBase { TListValue(TMemoryUsageInfo* memInfo, TComputationContext& compCtx, const std::string_view& name, TUnboxedValueVector&& args, const TVector& argDesc, const NPg::TTypeDesc& retTypeDesc, const NPg::TProcDesc& procDesc, const FmgrInfo* fInfo, - const TStructType* structType, const THolderFactory& holderFactory) + const TStructType* structType, const TVector& structTypeDesc, const THolderFactory& holderFactory) : TCustomListValue(memInfo) , CompCtx(compCtx) , Name(name) @@ -1572,13 +1606,14 @@ class TPgResolvedMultiCall : public TPgResolvedCallBase { , ProcDesc(procDesc) , FInfo(fInfo) , StructType(structType) + , StructTypeDesc(structTypeDesc) , HolderFactory(holderFactory) { } private: NUdf::TUnboxedValue GetListIterator() const final { - return CompCtx.HolderFactory.Create(Name, Args, ArgDesc, RetTypeDesc, ProcDesc, FInfo, StructType, CompCtx.HolderFactory); + return CompCtx.HolderFactory.Create(Name, Args, ArgDesc, RetTypeDesc, ProcDesc, FInfo, StructType, StructTypeDesc, CompCtx.HolderFactory); } TComputationContext& CompCtx; @@ -1589,6 +1624,7 @@ class TPgResolvedMultiCall : public TPgResolvedCallBase { const NPg::TProcDesc& ProcDesc; const FmgrInfo* FInfo; const TStructType* StructType; + const TVector& StructTypeDesc; const THolderFactory& HolderFactory; }; @@ -1607,7 +1643,7 @@ class TPgResolvedMultiCall : public TPgResolvedCallBase { args.push_back(value); } - return compCtx.HolderFactory.Create(compCtx, Name, std::move(args), ArgDesc, RetTypeDesc, ProcDesc, &FInfo, StructType, compCtx.HolderFactory); + return compCtx.HolderFactory.Create(compCtx, Name, std::move(args), ArgDesc, RetTypeDesc, ProcDesc, &FInfo, StructType, StructTypeDesc, compCtx.HolderFactory); } }; diff --git a/ydb/library/yql/parser/pg_wrapper/postgresql/src/backend/utils/misc/guc_funcs.c b/ydb/library/yql/parser/pg_wrapper/postgresql/src/backend/utils/misc/guc_funcs.c index 0903ba43a96e..da67f37aacd2 100644 --- a/ydb/library/yql/parser/pg_wrapper/postgresql/src/backend/utils/misc/guc_funcs.c +++ b/ydb/library/yql/parser/pg_wrapper/postgresql/src/backend/utils/misc/guc_funcs.c @@ -916,7 +916,8 @@ show_all_settings(PG_FUNCTION_ARGS) funcctx->attinmeta = attinmeta; /* collect the variables, in sorted order */ - guc_vars = get_guc_variables(&num_vars); + guc_vars = NULL; + num_vars = 0; /* use user_fctx to remember the array location */ funcctx->user_fctx = guc_vars; diff --git a/ydb/library/yql/tests/sql/yt_native_file/part12/canondata/result.json b/ydb/library/yql/tests/sql/yt_native_file/part12/canondata/result.json index a8727deac261..c121ee495ea7 100644 --- a/ydb/library/yql/tests/sql/yt_native_file/part12/canondata/result.json +++ b/ydb/library/yql/tests/sql/yt_native_file/part12/canondata/result.json @@ -2961,9 +2961,9 @@ ], "test.test[pg_catalog-pg_description_pg_syntax-default.txt-Results]": [ { - "checksum": "c67fbc7d8d6fb7fe3eff3f34c32a5b7a", + "checksum": "ab8e21760da4bf353ac12f633213227b", "size": 2768, - "uri": "https://{canondata_backend}/1809005/6d5702cdf5f37d18a9deb9127ecce08cfe554c8a/resource.tar.gz#test.test_pg_catalog-pg_description_pg_syntax-default.txt-Results_/results.txt" + "uri": "https://{canondata_backend}/1689644/24cc2a34d7ebf1958abe0cd6c74c6af03994cd3e/resource.tar.gz#test.test_pg_catalog-pg_description_pg_syntax-default.txt-Results_/results.txt" } ], "test.test[pg_catalog-pg_timezone_abbrevs-default.txt-Debug]": [