Skip to content

Commit

Permalink
Allow multiple graph tables inside single query
Browse files Browse the repository at this point in the history
  • Loading branch information
Dtenwolde committed Jun 7, 2024
1 parent 3079f0f commit 150ff7d
Show file tree
Hide file tree
Showing 5 changed files with 191 additions and 59 deletions.
14 changes: 5 additions & 9 deletions src/duckpgq_extension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ ParserExtensionParseResult duckpgq_parse(ParserExtensionInfo *info,
: query);
if (parser.statements.size() != 1) {
throw Exception(ExceptionType::PARSER,
"More than 1 statement detected, please only give one.");
"More than one statement detected, please only give one.");
}
return ParserExtensionParseResult(make_uniq_base<ParserExtensionParseData, DuckPGQParseData>(
std::move(parser.statements[0])));
Expand Down Expand Up @@ -119,15 +119,11 @@ void duckpgq_find_match_function(TableRef *table_ref,
// Handle TableFunctionRef case
auto function =
dynamic_cast<FunctionExpression *>(table_function_ref->function.get());
if (function->function_name == "duckpgq_match") {
if (duckpgq_state.transform_expression != nullptr) {
throw Exception(ExceptionType::INVALID,
"Multiple graph tables in a single query are not supported yet");
}
duckpgq_state.transform_expression =
std::move(std::move(function->children[0]));
function->children.pop_back();
if (function->function_name != "duckpgq_match") {
return;
}
duckpgq_state.transform_expression.push_back(std::move(function->children[0]));
function->children.pop_back();
} else if (auto join_ref = dynamic_cast<JoinRef *>(table_ref)) {
// Handle JoinRef case
duckpgq_find_match_function(join_ref->left.get(), duckpgq_state);
Expand Down
12 changes: 9 additions & 3 deletions src/functions/tablefunctions/match.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -943,11 +943,9 @@ PGQMatchFunction::MatchBindReplace(ClientContext &context,
dynamic_cast<DuckPGQState *>(duckpgq_state_entry->second.get());

auto ref = dynamic_cast<MatchExpression *>(
duckpgq_state->transform_expression.get());
duckpgq_state->transform_expression[0].get());
auto pg_table = duckpgq_state->GetPropertyGraph(ref->pg_name);

auto data = make_uniq<MatchBindData>();

vector<unique_ptr<ParsedExpression>> conditions;

auto select_node = make_uniq<SelectNode>();
Expand Down Expand Up @@ -1040,8 +1038,16 @@ PGQMatchFunction::MatchBindReplace(ClientContext &context,

auto subquery = make_uniq<SelectStatement>();
subquery->node = std::move(select_node);
if (ref->alias == "unnamed_graphtable") {
if (duckpgq_state->unnamed_graphtable_index > 1) {
ref->alias = "unnamed_graphtable" +
std::to_string(duckpgq_state->unnamed_graphtable_index);
}
duckpgq_state->unnamed_graphtable_index++;
}

auto result = make_uniq<SubqueryRef>(std::move(subquery), ref->alias);
duckpgq_state->transform_expression.erase(duckpgq_state->transform_expression.begin());
return std::move(result);
}
} // namespace duckdb
8 changes: 6 additions & 2 deletions src/include/duckpgq_extension.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ class DuckPGQState : public ClientContextState {

void QueryEnd() override {
parse_data.reset();
transform_expression = nullptr;
transform_expression.clear();
unnamed_graphtable_index = 1; // Reset the index
for (const auto &csr_id : csr_to_delete) {
csr_list.erase(csr_id);
}
Expand All @@ -105,7 +106,10 @@ class DuckPGQState : public ClientContextState {
public:
unique_ptr<ParserExtensionParseData> parse_data;

unique_ptr<ParsedExpression> transform_expression;
vector<unique_ptr<ParsedExpression>> transform_expression;

int32_t unnamed_graphtable_index = 1; // Used to generate unique names for
// unnamed graph tables

//! Property graphs that are registered
std::unordered_map<string, unique_ptr<CreateInfo>> registered_property_graphs;
Expand Down
171 changes: 171 additions & 0 deletions test/sql/multiple_graph_table.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
# name: test/sql/multiple_graph_table.test
# group: [duckpgq]

require duckpgq

statement ok
CREATE TABLE Student(id BIGINT, name VARCHAR);INSERT INTO Student VALUES (0, 'Daniel'), (1, 'Tavneet'), (2, 'Gabor'), (3, 'Peter'), (4, 'David');

statement ok
CREATE TABLE know(src BIGINT, dst BIGINT, createDate BIGINT);INSERT INTO know VALUES (0,1, 10), (0,2, 11), (0,3, 12), (3,0, 13), (1,2, 14), (1,3, 15), (2,3, 16), (4,3, 17);

statement ok
CREATE TABLE School(name VARCHAR, Id BIGINT, Kind VARCHAR);INSERT INTO School VALUES ('VU', 0, 'University'), ('UVA', 1, 'University');

statement ok
CREATE TABLE StudyAt(personId BIGINT, schoolId BIGINT);INSERT INTO StudyAt VALUES (0, 0), (1, 0), (2, 1), (3, 1), (4, 1);

statement ok
-CREATE PROPERTY GRAPH pg
VERTEX TABLES (
Student,
School
)
EDGE TABLES (
know SOURCE KEY ( src ) REFERENCES Student ( id )
DESTINATION KEY ( dst ) REFERENCES Student ( id ),
studyAt SOURCE KEY ( personId ) REFERENCES Student ( id )
DESTINATION KEY ( SchoolId ) REFERENCES School ( id )
);

query II
-select a.id, b.id FROM GRAPH_TABLE(pg MATCH (a:student)) a, GRAPH_TABLE(pg MATCH (b:student)) b;
----
0 0
0 1
0 2
0 3
0 4
1 0
1 1
1 2
1 3
1 4
2 0
2 1
2 2
2 3
2 4
3 0
3 1
3 2
3 3
3 4
4 0
4 1
4 2
4 3
4 4

query II
-select unnamed_graphtable.id, unnamed_graphtable2.id FROM GRAPH_TABLE(pg MATCH (a:student)), GRAPH_TABLE(pg MATCH (b:student));
----
0 0
0 1
0 2
0 3
0 4
1 0
1 1
1 2
1 3
1 4
2 0
2 1
2 2
2 3
2 4
3 0
3 1
3 2
3 3
3 4
4 0
4 1
4 2
4 3
4 4


query IIII
-select a.id, a.name, unnamed_graphtable.id, unnamed_graphtable.name FROM GRAPH_TABLE(pg MATCH (a:student)) a, GRAPH_TABLE(pg MATCH (b:student)-[r:know]->(c:student));
----
0 Daniel 1 Tavneet
0 Daniel 2 Gabor
0 Daniel 3 Peter
0 Daniel 0 Daniel
0 Daniel 2 Gabor
0 Daniel 3 Peter
0 Daniel 3 Peter
0 Daniel 3 Peter
1 Tavneet 1 Tavneet
1 Tavneet 2 Gabor
1 Tavneet 3 Peter
1 Tavneet 0 Daniel
1 Tavneet 2 Gabor
1 Tavneet 3 Peter
1 Tavneet 3 Peter
1 Tavneet 3 Peter
2 Gabor 1 Tavneet
2 Gabor 2 Gabor
2 Gabor 3 Peter
2 Gabor 0 Daniel
2 Gabor 2 Gabor
2 Gabor 3 Peter
2 Gabor 3 Peter
2 Gabor 3 Peter
3 Peter 1 Tavneet
3 Peter 2 Gabor
3 Peter 3 Peter
3 Peter 0 Daniel
3 Peter 2 Gabor
3 Peter 3 Peter
3 Peter 3 Peter
3 Peter 3 Peter
4 David 1 Tavneet
4 David 2 Gabor
4 David 3 Peter
4 David 0 Daniel
4 David 2 Gabor
4 David 3 Peter
4 David 3 Peter
4 David 3 Peter


query II
-select unnamed_subquery.id, unnamed_graphtable.id
FROM GRAPH_TABLE(pg MATCH (a:student)), (select 1 as id);
----
1 0
1 1
1 2
1 3
1 4

statement ok
CREATE TABLE cities (
name VARCHAR,
lat DECIMAL,
lon DECIMAL
);

statement ok
CREATE TABLE cities_are_adjacent (
city1name VARCHAR,
city2name VARCHAR
);

statement ok
-CREATE PROPERTY GRAPH citymap
VERTEX TABLES (
cities PROPERTIES (name,lat,lon) LABEL city
)
EDGE TABLES (
cities_are_adjacent SOURCE KEY ( city1name ) REFERENCES cities ( name )
DESTINATION KEY ( city2name ) REFERENCES cities ( name )
LABEL adjacent
);

statement ok
-select * from GRAPH_TABLE (citymap MATCH (s:city)-[r:adjacent]->(t:city)) g1, GRAPH_TABLE (citymap MATCH (s:city)-[r:adjacent]->(t:city)) g2;

45 changes: 0 additions & 45 deletions test/sql/multiple_graph_table_error.test

This file was deleted.

0 comments on commit 150ff7d

Please sign in to comment.