From db3e1d293bdef7d009dd326f515e86383692d7bd Mon Sep 17 00:00:00 2001 From: Arun Sharma Date: Thu, 15 Oct 2026 10:02:40 -0700 Subject: [PATCH 1/4] fix(algo): name projected-graph parameter in GDS signatures All GDS table functions take a projected-graph name yet registered a bare ANY parameter, so arity mismatches reported the unhelpful 'Expected: (ANY)'. Register STRING with parameterNames {"graph_name"} (plus LIST "sources" for the PPR extra arg) so failures read 'Expected: (graph_name STRING)'. Pairs with LadybugDB/ladybug#1265, which adds parameterNames support and a CALL PROJECT_GRAPH(...) hint to the core function-match error. --- algo/src/function/gds_node2vec.cpp | 3 ++- algo/src/function/k_core_decomposition.cpp | 3 ++- algo/src/function/louvain.cpp | 3 ++- algo/src/function/page_rank.cpp | 3 ++- algo/src/function/spanning_forest.cpp | 3 ++- algo/src/function/strongly_connected_components.cpp | 3 ++- .../function/strongly_connected_components_kosaraju.cpp | 3 ++- algo/src/function/weakly_connected_components.cpp | 3 ++- algo/src/include/function/gds_algo_template.h | 7 +++++-- 9 files changed, 21 insertions(+), 10 deletions(-) diff --git a/algo/src/function/gds_node2vec.cpp b/algo/src/function/gds_node2vec.cpp index c3a65b0e..3c7fe416 100644 --- a/algo/src/function/gds_node2vec.cpp +++ b/algo/src/function/gds_node2vec.cpp @@ -142,7 +142,8 @@ static std::unique_ptr bindFunc(main::ClientContext* context, function_set GDSNode2VecFunction::getFunctionSet() { function_set result; auto func = std::make_unique(GDSNode2VecFunction::name, - std::vector{LogicalTypeID::ANY}); + std::vector{LogicalTypeID::STRING}); + func->parameterNames = {"graph_name"}; func->bindFunc = bindFunc; func->tableFunc = tableFunc; func->initSharedStateFunc = GDSFunction::initSharedState; diff --git a/algo/src/function/k_core_decomposition.cpp b/algo/src/function/k_core_decomposition.cpp index 63724bc5..74dd8193 100644 --- a/algo/src/function/k_core_decomposition.cpp +++ b/algo/src/function/k_core_decomposition.cpp @@ -240,7 +240,8 @@ static std::unique_ptr bindFunc(main::ClientContext* context, function_set KCoreDecompositionFunction::getFunctionSet() { function_set result; auto func = std::make_unique(KCoreDecompositionFunction::name, - std::vector{LogicalTypeID::ANY}); + std::vector{LogicalTypeID::STRING}); + func->parameterNames = {"graph_name"}; func->bindFunc = bindFunc; func->tableFunc = tableFunc; func->initSharedStateFunc = GDSFunction::initSharedState; diff --git a/algo/src/function/louvain.cpp b/algo/src/function/louvain.cpp index 7ba00c5d..8b62a7b2 100644 --- a/algo/src/function/louvain.cpp +++ b/algo/src/function/louvain.cpp @@ -689,7 +689,8 @@ static std::unique_ptr bindFunc(main::ClientContext* context, function_set LouvainFunction::getFunctionSet() { function_set result; - auto func = std::make_unique(name, std::vector{LogicalTypeID::ANY}); + auto func = std::make_unique(name, std::vector{LogicalTypeID::STRING}); + func->parameterNames = {"graph_name"}; func->bindFunc = bindFunc; func->tableFunc = tableFunc; func->initSharedStateFunc = GDSFunction::initSharedState; diff --git a/algo/src/function/page_rank.cpp b/algo/src/function/page_rank.cpp index 377e969b..abf2789e 100644 --- a/algo/src/function/page_rank.cpp +++ b/algo/src/function/page_rank.cpp @@ -339,7 +339,8 @@ static std::unique_ptr bindFunc(main::ClientContext* context, function_set PageRankFunction::getFunctionSet() { function_set result; auto func = std::make_unique(PageRankFunction::name, - std::vector{LogicalTypeID::ANY}); + std::vector{LogicalTypeID::STRING}); + func->parameterNames = {"graph_name"}; func->bindFunc = bindFunc; func->tableFunc = tableFunc; func->initSharedStateFunc = GDSFunction::initSharedState; diff --git a/algo/src/function/spanning_forest.cpp b/algo/src/function/spanning_forest.cpp index 894611b9..4e9af68c 100644 --- a/algo/src/function/spanning_forest.cpp +++ b/algo/src/function/spanning_forest.cpp @@ -454,7 +454,8 @@ static void getLogicalPlan(Planner* planner, const BoundReadingClause& readingCl function_set SpanningForest::getFunctionSet() { function_set result; - auto func = std::make_unique(name, std::vector{LogicalTypeID::ANY}); + auto func = std::make_unique(name, std::vector{LogicalTypeID::STRING}); + func->parameterNames = {"graph_name"}; func->bindFunc = bindFunc; func->tableFunc = tableFunc; func->initSharedStateFunc = GDSFunction::initSharedState; diff --git a/algo/src/function/strongly_connected_components.cpp b/algo/src/function/strongly_connected_components.cpp index 4d56b00a..5c07f57f 100644 --- a/algo/src/function/strongly_connected_components.cpp +++ b/algo/src/function/strongly_connected_components.cpp @@ -302,7 +302,8 @@ static std::unique_ptr bindFunc(main::ClientContext* context, function_set SCCFunction::getFunctionSet() { function_set result; auto func = std::make_unique(SCCFunction::name, - std::vector{LogicalTypeID::ANY}); + std::vector{LogicalTypeID::STRING}); + func->parameterNames = {"graph_name"}; func->bindFunc = bindFunc; func->tableFunc = tableFunc; func->initSharedStateFunc = GDSFunction::initSharedState; diff --git a/algo/src/function/strongly_connected_components_kosaraju.cpp b/algo/src/function/strongly_connected_components_kosaraju.cpp index 6f9ee0bc..fbaa3488 100644 --- a/algo/src/function/strongly_connected_components_kosaraju.cpp +++ b/algo/src/function/strongly_connected_components_kosaraju.cpp @@ -264,7 +264,8 @@ static std::unique_ptr bindFunc(main::ClientContext* context, function_set SCCKosarajuFunction::getFunctionSet() { function_set result; - auto func = std::make_unique(name, std::vector{LogicalTypeID::ANY}); + auto func = std::make_unique(name, std::vector{LogicalTypeID::STRING}); + func->parameterNames = {"graph_name"}; func->bindFunc = bindFunc; func->tableFunc = tableFunc; func->initSharedStateFunc = GDSFunction::initSharedState; diff --git a/algo/src/function/weakly_connected_components.cpp b/algo/src/function/weakly_connected_components.cpp index 61601993..147430a0 100644 --- a/algo/src/function/weakly_connected_components.cpp +++ b/algo/src/function/weakly_connected_components.cpp @@ -106,7 +106,8 @@ static std::unique_ptr bindFunc(main::ClientContext* context, function_set WeaklyConnectedComponentsFunction::getFunctionSet() { function_set result; - auto func = std::make_unique(name, std::vector{LogicalTypeID::ANY}); + auto func = std::make_unique(name, std::vector{LogicalTypeID::STRING}); + func->parameterNames = {"graph_name"}; func->bindFunc = bindFunc; func->tableFunc = tableFunc; func->initSharedStateFunc = GDSFunction::initSharedState; diff --git a/algo/src/include/function/gds_algo_template.h b/algo/src/include/function/gds_algo_template.h index d848cf18..6071efe1 100644 --- a/algo/src/include/function/gds_algo_template.h +++ b/algo/src/include/function/gds_algo_template.h @@ -198,11 +198,14 @@ struct GDSPerNodeScalarAlgo { static function::function_set getFunctionSet() { function::function_set result; - std::vector inputTypes{common::LogicalTypeID::ANY}; + std::vector inputTypes{common::LogicalTypeID::STRING}; + std::vector paramNames{"graph_name"}; for (auto i = 0u; i < DESC::Extra::NUM_ARGS; ++i) { - inputTypes.push_back(common::LogicalTypeID::ANY); + inputTypes.push_back(common::LogicalTypeID::LIST); + paramNames.emplace_back("sources"); } auto func = std::make_unique(std::string{DESC::name}, inputTypes); + func->parameterNames = std::move(paramNames); func->bindFunc = bindFunc; func->tableFunc = tableFunc; func->initSharedStateFunc = function::GDSFunction::initSharedState; From e387f31e9cd90dde793040f9636fb1ea92b16163 Mon Sep 17 00:00:00 2001 From: Arun Sharma Date: Thu, 15 Oct 2026 10:13:10 -0700 Subject: [PATCH 2/4] fix(algo): declare PPR sources as typed LIST(INT64) Renders as (graph_name STRING,sources INT64[]) in signatures and function-match errors. --- algo/src/include/function/gds_algo_template.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/algo/src/include/function/gds_algo_template.h b/algo/src/include/function/gds_algo_template.h index 6071efe1..1904e794 100644 --- a/algo/src/include/function/gds_algo_template.h +++ b/algo/src/include/function/gds_algo_template.h @@ -200,12 +200,16 @@ struct GDSPerNodeScalarAlgo { function::function_set result; std::vector inputTypes{common::LogicalTypeID::STRING}; std::vector paramNames{"graph_name"}; + std::vector paramTypes{common::LogicalType::STRING()}; for (auto i = 0u; i < DESC::Extra::NUM_ARGS; ++i) { + // Extra args are lists of node rowids (see SourceListArg::bind). inputTypes.push_back(common::LogicalTypeID::LIST); paramNames.emplace_back("sources"); + paramTypes.push_back(common::LogicalType::LIST(common::LogicalType::INT64())); } auto func = std::make_unique(std::string{DESC::name}, inputTypes); func->parameterNames = std::move(paramNames); + func->parameterTypes = std::move(paramTypes); func->bindFunc = bindFunc; func->tableFunc = tableFunc; func->initSharedStateFunc = function::GDSFunction::initSharedState; From b4cd2573ea2925f17dc875b1a8d69219a3c55af3 Mon Sep 17 00:00:00 2001 From: Arun Sharma Date: Thu, 15 Oct 2026 23:17:01 -0700 Subject: [PATCH 3/4] Fix LogicalType vector init: use moves not initializer-list copy --- algo/src/include/function/gds_algo_template.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/algo/src/include/function/gds_algo_template.h b/algo/src/include/function/gds_algo_template.h index 1904e794..f04500b5 100644 --- a/algo/src/include/function/gds_algo_template.h +++ b/algo/src/include/function/gds_algo_template.h @@ -200,7 +200,11 @@ struct GDSPerNodeScalarAlgo { function::function_set result; std::vector inputTypes{common::LogicalTypeID::STRING}; std::vector paramNames{"graph_name"}; - std::vector paramTypes{common::LogicalType::STRING()}; + // LogicalType is explicitly-copyable only (private copy ctor): build via moves, + // not an initializer list (which would copy). + std::vector paramTypes; + paramTypes.reserve(1 + DESC::Extra::NUM_ARGS); + paramTypes.push_back(common::LogicalType::STRING()); for (auto i = 0u; i < DESC::Extra::NUM_ARGS; ++i) { // Extra args are lists of node rowids (see SourceListArg::bind). inputTypes.push_back(common::LogicalTypeID::LIST); From e7b51f05c9ffb55b4037d18ca16ebcb6ea74fd13 Mon Sep 17 00:00:00 2001 From: Arun Sharma Date: Fri, 16 Oct 2026 08:53:37 -0700 Subject: [PATCH 4/4] fix(algo): infer nested input types for GDS extra args CALLs with a LIST-typed extra (GDS_PPR sources) fail to bind: the binder builds input LogicalTypes from the declared LogicalTypeIDs and a bare LIST ID carries no child info. Set inferInputTypes when the descriptor takes extra args so the nested type comes from the CALL-site argument instead. --- algo/src/include/function/gds_algo_template.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/algo/src/include/function/gds_algo_template.h b/algo/src/include/function/gds_algo_template.h index f04500b5..897f6328 100644 --- a/algo/src/include/function/gds_algo_template.h +++ b/algo/src/include/function/gds_algo_template.h @@ -212,6 +212,17 @@ struct GDSPerNodeScalarAlgo { paramTypes.push_back(common::LogicalType::LIST(common::LogicalType::INT64())); } auto func = std::make_unique(std::string{DESC::name}, inputTypes); + if constexpr (DESC::Extra::NUM_ARGS > 0) { + // Extra args are nested types (SOURCE_LIST's LIST(INT64)). The binder builds + // input LogicalTypes from the declared LogicalTypeIDs, and a bare LIST ID has + // no child info — infer the nested type from the CALL-site argument instead. + func->inferInputTypes = [](const binder::expression_vector& params) { + std::vector types; + types.push_back(common::LogicalType::STRING()); + types.push_back(params[1]->getDataType().copy()); + return types; + }; + } func->parameterNames = std::move(paramNames); func->parameterTypes = std::move(paramTypes); func->bindFunc = bindFunc;