diff --git a/presto-native-execution/presto_cpp/main/PrestoServer.cpp b/presto-native-execution/presto_cpp/main/PrestoServer.cpp index 15cb145aa9596..11811b5923bad 100644 --- a/presto-native-execution/presto_cpp/main/PrestoServer.cpp +++ b/presto-native-execution/presto_cpp/main/PrestoServer.cpp @@ -63,6 +63,7 @@ #include "velox/dwio/parquet/RegisterParquetWriter.h" #include "velox/dwio/text/RegisterTextWriter.h" #include "velox/exec/OutputBufferManager.h" +#include "velox/exec/TraceUtil.h" #include "velox/functions/prestosql/aggregates/RegisterAggregateFunctions.h" #include "velox/functions/prestosql/registration/RegistrationFunctions.h" #include "velox/functions/prestosql/window/WindowFunctionsRegistration.h" @@ -437,6 +438,7 @@ void PrestoServer::run() { registerRemoteFunctions(); registerVectorSerdes(); registerPrestoPlanNodeSerDe(); + registerTraceNodeFactories(); registerDynamicFunctions(); facebook::velox::exec::ExchangeSource::registerFactory( @@ -1805,4 +1807,29 @@ void PrestoServer::reportNodeStats(proxygen::ResponseHandler* downstream) { http::sendOkResponse(downstream, json(nodeStats)); } + +void PrestoServer::registerTraceNodeFactories() { + // Register trace node factory for PartitionAndSerialize operator + velox::exec::trace::registerTraceNodeFactory( + "PartitionAndSerialize", + [](const velox::core::PlanNode* traceNode, + const velox::core::PlanNodeId& nodeId) -> velox::core::PlanNodePtr { + if (const auto* partitionAndSerializeNode = + dynamic_cast( + traceNode)) { + return std::make_shared( + nodeId, + partitionAndSerializeNode->keys(), + partitionAndSerializeNode->numPartitions(), + partitionAndSerializeNode->serializedRowType(), + std::make_shared( + partitionAndSerializeNode->sources().front()->outputType()), + partitionAndSerializeNode->isReplicateNullsAndAny(), + partitionAndSerializeNode->partitionFunctionFactory(), + partitionAndSerializeNode->sortingOrders(), + partitionAndSerializeNode->sortingKeys()); + } + return nullptr; + }); +} } // namespace facebook::presto diff --git a/presto-native-execution/presto_cpp/main/PrestoServer.h b/presto-native-execution/presto_cpp/main/PrestoServer.h index 391c5306f9987..3cfc02ac6c881 100644 --- a/presto-native-execution/presto_cpp/main/PrestoServer.h +++ b/presto-native-execution/presto_cpp/main/PrestoServer.h @@ -165,6 +165,8 @@ class PrestoServer { virtual void registerMemoryArbitrators(); + virtual void registerTraceNodeFactories(); + /// Invoked after creating global (singleton) config objects (SystemConfig and /// NodeConfig) and before loading their properties from the file. /// In the implementation any extra config properties can be registered. diff --git a/presto-native-execution/presto_cpp/main/operators/tests/ShuffleTest.cpp b/presto-native-execution/presto_cpp/main/operators/tests/ShuffleTest.cpp index 2781daa30effe..a90fd6a0ee4cd 100644 --- a/presto-native-execution/presto_cpp/main/operators/tests/ShuffleTest.cpp +++ b/presto-native-execution/presto_cpp/main/operators/tests/ShuffleTest.cpp @@ -838,6 +838,98 @@ class ShuffleTest : public exec::test::OperatorTestBase { fileSystem->remove(file); } } + + void runPartitionAndSerializeSerdeTest( + const RowVectorPtr& data, + size_t numPartitions, + const std::optional>& serdeLayout = + std::nullopt) { + TestShuffleWriter::reset(); + + auto shuffleInfo = testShuffleInfo(numPartitions, 1 << 20); + TestShuffleWriter::createWriter(shuffleInfo, pool()); + + auto plan = exec::test::PlanBuilder() + .values({data}, true) + .addNode(addPartitionAndSerializeNode( + numPartitions, + false, + serdeLayout.value_or(std::vector{}))) + .localPartition(std::vector{}) + .addNode(addShuffleWriteNode( + numPartitions, + std::string(TestShuffleFactory::kShuffleName), + shuffleInfo)) + .planNode(); + + exec::CursorParameters params; + params.planNode = plan; + params.maxDrivers = 1; + + auto [taskCursor, results] = exec::test::readCursor(params); + ASSERT_EQ(results.size(), 0); + + auto shuffleWriter = TestShuffleWriter::getInstance(); + ASSERT_NE(shuffleWriter, nullptr); + + auto readyPartitions = shuffleWriter->readyPartitions(); + ASSERT_NE(readyPartitions, nullptr); + + size_t totalRows = 0; + for (size_t partitionIdx = 0; partitionIdx < numPartitions; + ++partitionIdx) { + for (const auto& batch : (*readyPartitions)[partitionIdx]) { + totalRows += batch->rows.size(); + } + } + ASSERT_EQ(totalRows, data->size()); + + auto expectedType = serdeLayout.has_value() + ? createSerdeLayoutType(asRowType(data->type()), serdeLayout.value()) + : asRowType(data->type()); + + std::vector deserializedData; + for (size_t partitionIdx = 0; partitionIdx < numPartitions; + ++partitionIdx) { + for (const auto& batch : (*readyPartitions)[partitionIdx]) { + auto deserialized = std::dynamic_pointer_cast( + row::CompactRow::deserialize(batch->rows, expectedType, pool())); + if (deserialized != nullptr && deserialized->size() > 0) { + deserializedData.push_back(deserialized); + } + } + } + + auto expected = serdeLayout.has_value() + ? reorderColumns(data, serdeLayout.value()) + : data; + velox::exec::test::assertEqualResults({expected}, deserializedData); + } + + private: + RowTypePtr createSerdeLayoutType( + const RowTypePtr& originalType, + const std::vector& layout) { + std::vector names; + std::vector types; + for (const auto& name : layout) { + auto idx = originalType->getChildIdx(name); + names.push_back(name); + types.push_back(originalType->childAt(idx)); + } + return ROW(std::move(names), std::move(types)); + } + + RowVectorPtr reorderColumns( + const RowVectorPtr& data, + const std::vector& newLayout) { + auto rowType = asRowType(data->type()); + std::vector columns; + for (const auto& name : newLayout) { + columns.push_back(data->childAt(rowType->getChildIdx(name))); + } + return makeRowVector(columns); + } }; TEST_F(ShuffleTest, operators) { @@ -1583,6 +1675,23 @@ TEST_F(ShuffleTest, shuffleReadRuntimeStats) { ASSERT_EQ(velox::RuntimeCounter::Unit::kNone, numBatchesStat.unit); } } + +TEST_F(ShuffleTest, partitionAndSerializeEndToEnd) { + auto data = makeRowVector({ + makeFlatVector({1, 2, 3, 4, 5, 6}), + makeFlatVector({10, 20, 30, 40, 50, 60}), + }); + runPartitionAndSerializeSerdeTest(data, 4); + + data = makeRowVector({ + makeFlatVector({1, 2, 3, 4}), + makeFlatVector({10, 20, 30, 40}), + makeFlatVector({"a", "b", "c", "d"}), + }); + + runPartitionAndSerializeSerdeTest(data, 2, {{"c2", "c0"}}); +} + } // namespace facebook::presto::operators::test int main(int argc, char** argv) { diff --git a/presto-native-execution/presto_cpp/main/tool/trace/PartitionAndSerializeReplayer.cpp b/presto-native-execution/presto_cpp/main/tool/trace/PartitionAndSerializeReplayer.cpp new file mode 100644 index 0000000000000..ae0d9c985f8de --- /dev/null +++ b/presto-native-execution/presto_cpp/main/tool/trace/PartitionAndSerializeReplayer.cpp @@ -0,0 +1,76 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + */ +#include "presto_cpp/main/tool/trace/PartitionAndSerializeReplayer.h" + +#include "presto_cpp/main/operators/PartitionAndSerialize.h" +#include "velox/tool/trace/TraceReplayTaskRunner.h" + +using namespace facebook::velox; +using namespace facebook::velox::exec; +using namespace facebook::velox::exec::test; +using namespace facebook::presto; + +namespace facebook::velox::tool::trace { + +PartitionAndSerializeReplayer::PartitionAndSerializeReplayer( + const std::string& traceDir, + const std::string& queryId, + const std::string& taskId, + const std::string& nodeId, + const std::string& nodeName, + const std::string& driverIds, + uint64_t queryCapacity, + folly::Executor* executor) + : OperatorReplayerBase( + traceDir, + queryId, + taskId, + nodeId, + nodeName, + driverIds, + queryCapacity, + executor) {} + +RowVectorPtr PartitionAndSerializeReplayer::run(bool copyResults) { + TraceReplayTaskRunner traceTaskRunner(createPlan(), createQueryCtx()); + auto [task, result] = + traceTaskRunner.maxDrivers(driverIds_.size()).run(copyResults); + printStats(task); + return result; +} + +core::PlanNodePtr PartitionAndSerializeReplayer::createPlanNode( + const core::PlanNode* node, + const core::PlanNodeId& nodeId, + const core::PlanNodePtr& source) const { + const auto partitionAndSerializeNode = + dynamic_cast(node); + VELOX_CHECK_NOT_NULL(partitionAndSerializeNode); + + return std::make_shared( + nodeId, + partitionAndSerializeNode->keys(), + partitionAndSerializeNode->numPartitions(), + partitionAndSerializeNode->serializedRowType(), + source, + partitionAndSerializeNode->isReplicateNullsAndAny(), + partitionAndSerializeNode->partitionFunctionFactory(), + partitionAndSerializeNode->sortingOrders(), + partitionAndSerializeNode->sortingKeys()); +} + +} // namespace facebook::velox::tool::trace diff --git a/presto-native-execution/presto_cpp/main/tool/trace/PartitionAndSerializeReplayer.h b/presto-native-execution/presto_cpp/main/tool/trace/PartitionAndSerializeReplayer.h new file mode 100644 index 0000000000000..f1cfd1c1d5a75 --- /dev/null +++ b/presto-native-execution/presto_cpp/main/tool/trace/PartitionAndSerializeReplayer.h @@ -0,0 +1,46 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + */ +#pragma once + +#include "velox/core/PlanNode.h" +#include "velox/tool/trace/OperatorReplayerBase.h" + +namespace facebook::velox::tool::trace { + +/// The replayer to replay the traced 'PartitionAndSerialize' operators. +class PartitionAndSerializeReplayer final : public OperatorReplayerBase { + public: + PartitionAndSerializeReplayer( + const std::string& traceDir, + const std::string& queryId, + const std::string& taskId, + const std::string& nodeId, + const std::string& nodeName, + const std::string& driverIds, + uint64_t queryCapacity, + folly::Executor* executor); + + RowVectorPtr run(bool copyResults = true) override; + + private: + core::PlanNodePtr createPlanNode( + const core::PlanNode* node, + const core::PlanNodeId& nodeId, + const core::PlanNodePtr& source) const override; +}; + +} // namespace facebook::velox::tool::trace diff --git a/presto-native-execution/presto_cpp/main/tool/trace/TraceReplayerMain.cpp b/presto-native-execution/presto_cpp/main/tool/trace/TraceReplayerMain.cpp new file mode 100644 index 0000000000000..6d3a2486d86b8 --- /dev/null +++ b/presto-native-execution/presto_cpp/main/tool/trace/TraceReplayerMain.cpp @@ -0,0 +1,76 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "velox/tool/trace/TraceReplayRunner.h" + +#include +#include "presto_cpp/main/operators/PartitionAndSerialize.h" +#include "presto_cpp/main/tool/trace/PartitionAndSerializeReplayer.h" +#include "presto_cpp/main/types/PrestoToVeloxQueryPlan.h" + +using namespace facebook::velox; +using namespace facebook::presto; + +namespace { +/// Custom trace replay runner for Presto operators. +/// This runner extends the base Velox TraceReplayRunner to support: +/// - Presto-specific operators (e.g., PartitionAndSerialize) +/// - Presto plan node serialization/deserialization +class PrestoTraceReplayRunner + : public facebook::velox::tool::trace::TraceReplayRunner { + public: + void init() override { + // Register Presto plan node SerDe for reading traced plan nodes + registerPrestoPlanNodeSerDe(); + + // Register custom Presto operators to execute during replay + exec::Operator::registerOperator( + std::make_unique()); + + // Call base init to complete initialization + TraceReplayRunner::init(); + } + + private: + std::unique_ptr createReplayer() + const override { + const auto nodeName = taskTraceMetadataReader_->nodeName(FLAGS_node_id); + const auto queryCapacityBytes = (1ULL * FLAGS_query_memory_capacity_mb) + << 20; + + if (nodeName == "PartitionAndSerialize") { + return std::make_unique( + FLAGS_root_dir, + FLAGS_query_id, + FLAGS_task_id, + FLAGS_node_id, + nodeName, + FLAGS_driver_ids, + queryCapacityBytes, + cpuExecutor_.get()); + } + + // Fall back to base class for standard Velox operators + return TraceReplayRunner::createReplayer(); + } +}; +} // namespace + +int main(int argc, char** argv) { + folly::Init init(&argc, &argv); + PrestoTraceReplayRunner runner; + runner.init(); + runner.run(); + return 0; +} diff --git a/presto-native-execution/presto_cpp/main/tool/trace/cMakeLists.txt b/presto-native-execution/presto_cpp/main/tool/trace/cMakeLists.txt new file mode 100644 index 0000000000000..2397137e178df --- /dev/null +++ b/presto-native-execution/presto_cpp/main/tool/trace/cMakeLists.txt @@ -0,0 +1,28 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +add_library( + presto_tool_trace_replayers + PartitionAndSerializeReplayer.cpp +) + +target_link_libraries( + presto_tool_trace_replayers + presto_operators + velox_core + velox_exec + velox_tool_trace +) + +if(PRESTO_ENABLE_TESTING) + add_subdirectory(tests) +endif() diff --git a/presto-native-execution/presto_cpp/main/tool/trace/tests/PartitionAndSerializeReplayerTest.cpp b/presto-native-execution/presto_cpp/main/tool/trace/tests/PartitionAndSerializeReplayerTest.cpp new file mode 100644 index 0000000000000..ec2fef74eb6f1 --- /dev/null +++ b/presto-native-execution/presto_cpp/main/tool/trace/tests/PartitionAndSerializeReplayerTest.cpp @@ -0,0 +1,220 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + */ +#include +#include +#include + +#include "presto_cpp/main/operators/PartitionAndSerialize.h" +#include "presto_cpp/main/operators/tests/PlanBuilder.h" +#include "presto_cpp/main/tool/trace/PartitionAndSerializeReplayer.h" +#include "velox/exec/PartitionFunction.h" +#include "velox/exec/TraceUtil.h" +#include "velox/exec/tests/utils/AssertQueryBuilder.h" +#include "velox/exec/tests/utils/HiveConnectorTestBase.h" +#include "velox/exec/tests/utils/PlanBuilder.h" +#include "velox/exec/tests/utils/TempDirectoryPath.h" + +using namespace facebook::velox; +using namespace facebook::velox::exec; +using namespace facebook::velox::exec::test; +using namespace facebook::velox::tool::trace; +using namespace facebook::presto; +using namespace facebook::presto::operators; + +namespace { + +// Mock operator that passes data through for tracing +class MockPartitionAndSerializeOperator : public Operator { + public: + MockPartitionAndSerializeOperator( + int32_t operatorId, + DriverCtx* driverCtx, + const std::shared_ptr& node) + : Operator( + driverCtx, + node->outputType(), + operatorId, + node->id(), + "MockPartitionAndSerialize") {} + + void addInput(RowVectorPtr input) override { + input_ = std::move(input); + } + + RowVectorPtr getOutput() override { + if (!input_) { + return nullptr; + } + auto output = std::move(input_); + return output; + } + + bool needsInput() const override { + return !input_; + } + + void noMoreInput() override { + Operator::noMoreInput(); + } + + BlockingReason isBlocked(ContinueFuture* future) override { + return BlockingReason::kNotBlocked; + } + + bool isFinished() override { + return noMoreInput_ && !input_; + } + + private: + RowVectorPtr input_; +}; + +class MockPartitionAndSerializeTranslator + : public Operator::PlanNodeTranslator { + public: + std::unique_ptr toOperator( + DriverCtx* ctx, + int32_t id, + const core::PlanNodePtr& node) override { + if (auto partitionNode = + std::dynamic_pointer_cast(node)) { + return std::make_unique( + id, ctx, partitionNode); + } + return nullptr; + } +}; + +} // namespace + +class PartitionAndSerializeReplayerTest : public HiveConnectorTestBase { + protected: + static void SetUpTestCase() { + exec::test::HiveConnectorTestBase::SetUpTestCase(); + memory::MemoryManager::testingSetInstance(memory::MemoryManager::Options{}); + filesystems::registerLocalFileSystem(); + facebook::velox::exec::trace::registerDummySourceSerDe(); + if (!isRegisteredVectorSerde()) { + serializer::presto::PrestoVectorSerde::registerVectorSerde(); + } + Type::registerSerDe(); + common::Filter::registerSerDe(); + core::PlanNode::registerSerDe(); + core::ITypedExpr::registerSerDe(); + exec::registerPartitionFunctionSerDe(); + DeserializationWithContextRegistryForSharedPtr().Register( + "PartitionAndSerializeNode", PartitionAndSerializeNode::create); + exec::trace::registerTraceNodeFactory( + "MockPartitionAndSerialize", + [](const core::PlanNode* traceNode, + const core::PlanNodeId& nodeId) -> core::PlanNodePtr { + if (const auto* partitionNode = + dynamic_cast(traceNode)) { + return std::make_shared( + nodeId, + partitionNode->keys(), + partitionNode->numPartitions(), + partitionNode->serializedRowType(), + std::make_shared( + partitionNode->sources().front()->outputType()), + partitionNode->isReplicateNullsAndAny(), + partitionNode->partitionFunctionFactory(), + partitionNode->sortingOrders(), + partitionNode->sortingKeys()); + } + return nullptr; + }); + } + + void SetUp() override { + HiveConnectorTestBase::SetUp(); + executor_ = std::make_unique( + std::thread::hardware_concurrency()); + } + + void TearDown() override { + HiveConnectorTestBase::TearDown(); + } + + std::unique_ptr executor_; +}; + +TEST_F(PartitionAndSerializeReplayerTest, basicReplay) { + auto traceDirPath = exec::test::TempDirectoryPath::create(); + const std::string traceRoot = traceDirPath->getPath(); + + // Register mock operator for trace phase + auto mockTranslator = std::make_unique(); + exec::Operator::registerOperator(std::move(mockTranslator)); + + const auto inputData = makeRowVector({ + makeFlatVector({0, 1, 2, 3, 4}), + makeFlatVector( + {"data-a", "data-b", "data-c", "data-d", "data-e"}), + }); + + // Create partition and serialize plan with mock operator + const uint32_t numPartitions = 5; + std::string partitionNodeId; + auto plan = PlanBuilder() + .values({inputData}) + .addNode(addPartitionAndSerializeNode(numPartitions, false)) + .capturePlanNodeId(partitionNodeId) + .planNode(); + + // Run the trace phase with mock operator + std::shared_ptr task; + AssertQueryBuilder(duckDbQueryRunner_) + .plan(plan) + .config(core::QueryConfig::kQueryTraceEnabled, true) + .config(core::QueryConfig::kQueryTraceDir, traceRoot) + .config(core::QueryConfig::kQueryTraceMaxBytes, 100UL << 30) + .config(core::QueryConfig::kQueryTraceTaskRegExp, ".*") + .config(core::QueryConfig::kQueryTraceNodeId, partitionNodeId) + .copyResults(pool(), task); + + // Clear and register real operators for replay phase + exec::Operator::unregisterAllOperators(); + exec::Operator::registerOperator( + std::make_unique()); + + // Test the replayer with the traced data + const std::string driverIds = "0"; + const uint64_t queryCapacity = 1024 * 1024; + + PartitionAndSerializeReplayer replayer( + traceRoot, + task->queryCtx()->queryId(), + task->taskId(), + partitionNodeId, + "PartitionAndSerialize", + driverIds, + queryCapacity, + executor_.get()); + + auto result = replayer.run(); + EXPECT_TRUE(result != nullptr); + + // Verify the output has the expected structure + // Output should have 3 columns: partition (INTEGER), key (VARBINARY), data + // (VARBINARY) + EXPECT_EQ(result->childrenSize(), 3); + EXPECT_EQ(result->childAt(0)->typeKind(), TypeKind::INTEGER); + EXPECT_EQ(result->childAt(1)->typeKind(), TypeKind::VARBINARY); + EXPECT_EQ(result->childAt(2)->typeKind(), TypeKind::VARBINARY); + EXPECT_EQ(result->size(), inputData->size()); +} diff --git a/presto-native-execution/presto_cpp/main/types/PrestoToVeloxQueryPlan.cpp b/presto-native-execution/presto_cpp/main/types/PrestoToVeloxQueryPlan.cpp index 0285c16ea48c7..ac5b8e89e9e33 100644 --- a/presto-native-execution/presto_cpp/main/types/PrestoToVeloxQueryPlan.cpp +++ b/presto-native-execution/presto_cpp/main/types/PrestoToVeloxQueryPlan.cpp @@ -35,6 +35,7 @@ #include "presto_cpp/main/operators/ShuffleRead.h" #include "presto_cpp/main/operators/ShuffleWrite.h" #include "presto_cpp/main/types/TypeParser.h" +#include "velox/exec/TraceUtil.h" using namespace facebook::velox; using namespace facebook::velox::exec; diff --git a/presto-native-execution/presto_cpp/main/types/PrestoToVeloxQueryPlan.h b/presto-native-execution/presto_cpp/main/types/PrestoToVeloxQueryPlan.h index c21e6f0ea35d8..0bd111e09cbb8 100644 --- a/presto-native-execution/presto_cpp/main/types/PrestoToVeloxQueryPlan.h +++ b/presto-native-execution/presto_cpp/main/types/PrestoToVeloxQueryPlan.h @@ -292,6 +292,8 @@ class VeloxBatchQueryPlanConverter : public VeloxQueryPlanConverterBase { void registerPrestoPlanNodeSerDe(); +void registerPrestoTraceNodeFactories(); + void parseSqlFunctionHandle( const std::shared_ptr& sqlFunction, std::vector& rawInputTypes,