diff --git a/duckpgq/src/duckpgq_extension.cpp b/duckpgq/src/duckpgq_extension.cpp index cd5b3dfb..4cd10314 100644 --- a/duckpgq/src/duckpgq_extension.cpp +++ b/duckpgq/src/duckpgq_extension.cpp @@ -16,6 +16,8 @@ #include "duckdb/parser/parsed_data/create_table_function_info.hpp" #include "duckdb/parser/query_node/select_node.hpp" #include "duckdb/parser/statement/copy_statement.hpp" +#include "duckdb/parser/statement/prepare_statement.hpp" + #include "duckdb/parser/parsed_data/create_table_info.hpp" #include "duckdb/parser/statement/extension_statement.hpp" @@ -99,7 +101,7 @@ BoundStatement duckpgq_bind(ClientContext &context, Binder &binder, throw BinderException("Registered state not found"); } - auto duckpgq_state = (DuckPGQState *)lookup->second.get(); + auto duckpgq_state = dynamic_cast(lookup->second.get()); auto duckpgq_binder = Binder::CreateBinder(context); auto duckpgq_parse_data = dynamic_cast(duckpgq_state->parse_data.get()); @@ -111,11 +113,11 @@ BoundStatement duckpgq_bind(ClientContext &context, Binder &binder, ParserExtensionPlanResult duckpgq_handle_statement(SQLStatement *statement, DuckPGQState &duckpgq_state) { if (statement->type == StatementType::SELECT_STATEMENT) { - auto select_statement = dynamic_cast(statement); - auto select_node = dynamic_cast(select_statement->node.get()); - auto from_table_function = + const auto select_statement = dynamic_cast(statement); + const auto select_node = dynamic_cast(select_statement->node.get()); + const auto from_table_function = dynamic_cast(select_node->from_table.get()); - auto function = + const auto function = dynamic_cast(from_table_function->function.get()); if (function->function_name == "duckpgq_match") { duckpgq_state.transform_expression = @@ -125,8 +127,8 @@ ParserExtensionPlanResult duckpgq_handle_statement(SQLStatement *statement, Duck throw Exception("use duckpgq_bind instead"); } if (statement->type == StatementType::CREATE_STATEMENT) { - auto &create_statement = statement->Cast(); - auto create_property_graph = dynamic_cast(create_statement.info.get()); + const auto &create_statement = statement->Cast(); + const auto create_property_graph = dynamic_cast(create_statement.info.get()); if (create_property_graph) { ParserExtensionPlanResult result; result.function = CreatePropertyGraphFunction(); @@ -167,6 +169,10 @@ ParserExtensionPlanResult duckpgq_handle_statement(SQLStatement *statement, Duck auto &insert_statement = statement->Cast(); duckpgq_handle_statement(insert_statement.select_statement.get(), duckpgq_state); } + if (statement->type == StatementType::PREPARE_STATEMENT) { + auto &prepare_statement = statement->Cast(); + duckpgq_handle_statement(prepare_statement.statement.get(), duckpgq_state); + } // Preferably throw NotImplementedExpection here, but only BinderExceptions are caught properly on MacOS right now throw BinderException("%s has not been implemented yet for DuckPGQ queries", StatementTypeToString(statement->type)); diff --git a/test/sql/prepared_statement_duckpgq.test b/test/sql/prepared_statement_duckpgq.test new file mode 100644 index 00000000..00ecc616 --- /dev/null +++ b/test/sql/prepared_statement_duckpgq.test @@ -0,0 +1,64 @@ +# name: test/sql/sqlpgq/copy_to_duckpgq.test +# group: [duckpgq] + +require duckpgq + +statement ok +import database 'duckdb-pgq/data/SNB0.003' + +statement ok +-CREATE PROPERTY GRAPH snb +VERTEX TABLES ( + Person LABEL Person, + Forum LABEL Forum, + Organisation LABEL Organisation IN typemask(company, university), + Place LABEL Place, + Tag LABEL Tag, + TagClass LABEL TagClass, + Country LABEL Country, + City LABEL City, + Message LABEL Message + ) +EDGE TABLES ( + Person_knows_person SOURCE KEY (Person1Id) REFERENCES Person (id) + DESTINATION KEY (Person2Id) REFERENCES Person (id) + LABEL Knows, + Forum_hasMember_Person SOURCE KEY (ForumId) REFERENCES Forum (id) + DESTINATION KEY (PersonId) REFERENCES Person (id) + LABEL hasMember, + Forum_hasTag_Tag SOURCE KEY (ForumId) REFERENCES Forum (id) + DESTINATION KEY (TagId) REFERENCES Tag (id) + LABEL Forum_hasTag, + Person_hasInterest_Tag SOURCE KEY (PersonId) REFERENCES Person (id) + DESTINATION KEY (TagId) REFERENCES Tag (id) + LABEL hasInterest, + person_workAt_Organisation SOURCE KEY (PersonId) REFERENCES Person (id) + DESTINATION KEY (OrganisationId) REFERENCES Organisation (id) + LABEL workAt_Organisation, + Person_likes_Message SOURCE KEY (PersonId) REFERENCES Person (id) + DESTINATION KEY (id) REFERENCES Message (id) + LABEL likes_Message, + Message_hasTag_Tag SOURCE KEY (id) REFERENCES Message (id) + DESTINATION KEY (TagId) REFERENCES Tag (id) + LABEL message_hasTag, + Message_hasAuthor_Person SOURCE KEY (messageId) REFERENCES Message (id) + DESTINATION KEY (PersonId) REFERENCES Person (id) + LABEL hasAuthor, + Message_replyOf_Message SOURCE KEY (messageId) REFERENCES Message (id) + DESTINATION KEY (ParentMessageId) REFERENCES Message (id) + LABEL replyOf + ); + + + +statement ok +-PREPARE is5 AS + FROM GRAPH_TABLE (snb + MATCH (m:message where m.id = $1)-[au:hasAuthor]->(p:person) + COLUMNS (p.id, p.firstName, p.lastName) + ) tmp; + +query III +EXECUTE is5(824633720985) +---- +14 Hossein Forouhar