Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rel group query #2023

Merged
merged 1 commit into from
Sep 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions dataset/rel-group/copy.cypher
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
COPY personA FROM "dataset/rel-group/node.csv" (HeaDER=true, deLim=',');
COPY personB FROM "dataset/rel-group/node.csv" (HeaDER=true, deLim=',');
COPY personC FROM "dataset/rel-group/node.csv" (HeaDER=true, deLim=',');
COPY knows_personA_personB FROM "dataset/rel-group/edge.csv";
COPY knows_personA_personC FROM "dataset/rel-group/edge.csv";
COPY knows_personB_personC FROM "dataset/rel-group/edge.csv";
COPY likes_personA_personB FROM "dataset/rel-group/edge.csv";
COPY likes_personB_personA FROM "dataset/rel-group/edge.csv";
14 changes: 14 additions & 0 deletions dataset/rel-group/edge.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
0,2,2021-06-30
0,3,2021-06-30
0,5,2021-06-30
2,0,2021-06-30
2,3,1950-05-14
2,5,1950-05-14
3,0,2021-06-30
3,2,1950-05-14
3,5,2000-01-01
5,0,2021-06-30
5,2,1950-05-14
5,3,2000-01-01
7,8,1905-12-12
7,9,1905-12-12
9 changes: 9 additions & 0 deletions dataset/rel-group/node.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
id,fname
0,Alice
2,Bob
3,Carol
5,Dan
7,Elizabeth
8,Farooq
9,Greg
10,Hubert Blaine Wolfeschlegelsteinhausenbergerdorff
5 changes: 5 additions & 0 deletions dataset/rel-group/schema.cypher
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
create node table personA (ID INt64, fName StRING, PRIMARY KEY (ID));
create node table personB (ID INt64, fName StRING, PRIMARY KEY (ID));
create node table personC (ID INt64, fName StRING, PRIMARY KEY (ID));
create rel table group knows (FROM personA TO personB, FROM personA To personC, FROM personB TO personC, date DATE);
create rel table group likes (FROM personA TO personB, FROM personB To personA, date DATE);
22 changes: 11 additions & 11 deletions src/binder/bind/bind_copy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ expression_vector Binder::bindColumnExpressions(
return columnExpressions;
}

bool Binder::bindContainsSerial(TableSchema* tableSchema, CopyDescription::FileType fileType) {
static bool bindContainsSerial(TableSchema* tableSchema, CopyDescription::FileType fileType) {
bool containsSerial = false;
for (auto& property : tableSchema->properties) {
if (property->getDataType()->getLogicalTypeID() == LogicalTypeID::SERIAL) {
Expand All @@ -104,7 +104,7 @@ std::unique_ptr<BoundStatement> Binder::bindCopyFromClause(const Statement& stat
auto catalogContent = catalog.getReadOnlyVersion();
auto tableName = copyStatement.getTableName();
// Bind to table schema.
validateTableExist(catalog, tableName);
validateNodeRelTableExist(tableName);
auto tableID = catalogContent->getTableID(tableName);
auto tableSchema = catalogContent->getTableSchema(tableID);
// Bind csv reader configuration
Expand All @@ -127,17 +127,17 @@ std::unique_ptr<BoundStatement> Binder::bindCopyFromClause(const Statement& stat
actualFileType, boundFilePaths, std::move(csvReaderConfig));
auto nodeOffsetExpression =
createVariable(std::string(Property::OFFSET_NAME), LogicalType{LogicalTypeID::INT64});
auto boundOffsetExpression = tableSchema->tableType == TableType::REL ?
createVariable(std::string(Property::REL_BOUND_OFFSET_NAME),
LogicalType{LogicalTypeID::ARROW_COLUMN}) :
nullptr;
auto nbrOffsetExpression = tableSchema->tableType == TableType::REL ?
createVariable(std::string(Property::REL_NBR_OFFSET_NAME),
LogicalType{LogicalTypeID::ARROW_COLUMN}) :
nullptr;
std::shared_ptr<Expression> boundOffset = nullptr;
std::shared_ptr<Expression> nbrOffset = nullptr;
if (tableSchema->tableType == TableType::REL) {
boundOffset = createVariable(
std::string(Property::REL_BOUND_OFFSET_NAME), LogicalType{LogicalTypeID::ARROW_COLUMN});
nbrOffset = createVariable(
std::string(Property::REL_NBR_OFFSET_NAME), LogicalType{LogicalTypeID::ARROW_COLUMN});
}
auto boundCopyFromInfo = std::make_unique<BoundCopyFromInfo>(std::move(copyDescription),
tableSchema, std::move(columnExpressions), std::move(nodeOffsetExpression),
std::move(boundOffsetExpression), std::move(nbrOffsetExpression), containsSerial);
std::move(boundOffset), std::move(nbrOffset), containsSerial);
return std::make_unique<BoundCopyFrom>(std::move(boundCopyFromInfo));
}

Expand Down
10 changes: 5 additions & 5 deletions src/binder/bind/bind_ddl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ std::unique_ptr<BoundStatement> Binder::bindCreateTable(const parser::Statement&
std::unique_ptr<BoundStatement> Binder::bindDropTable(const Statement& statement) {
auto& dropTable = (DropTable&)statement;
auto tableName = dropTable.getTableName();
validateTableExist(catalog, tableName);
validateNodeRelTableExist(tableName);
auto catalogContent = catalog.getReadOnlyVersion();
auto tableID = catalogContent->getTableID(tableName);
if (catalogContent->containNodeTable(tableName)) {
Expand All @@ -247,7 +247,7 @@ std::unique_ptr<BoundStatement> Binder::bindRenameTable(const Statement& stateme
auto renameTable = (RenameTable&)statement;
auto tableName = renameTable.getTableName();
auto catalogContent = catalog.getReadOnlyVersion();
validateTableExist(catalog, tableName);
validateNodeRelTableExist(tableName);
if (catalogContent->containTable(renameTable.getNewName())) {
throw BinderException("Table: " + renameTable.getNewName() + " already exists.");
}
Expand All @@ -258,7 +258,7 @@ std::unique_ptr<BoundStatement> Binder::bindRenameTable(const Statement& stateme
std::unique_ptr<BoundStatement> Binder::bindAddProperty(const Statement& statement) {
auto& addProperty = (AddProperty&)statement;
auto tableName = addProperty.getTableName();
validateTableExist(catalog, tableName);
validateNodeRelTableExist(tableName);
auto catalogContent = catalog.getReadOnlyVersion();
auto tableID = catalogContent->getTableID(tableName);
auto dataType = bindDataType(addProperty.getDataType());
Expand All @@ -277,7 +277,7 @@ std::unique_ptr<BoundStatement> Binder::bindAddProperty(const Statement& stateme
std::unique_ptr<BoundStatement> Binder::bindDropProperty(const Statement& statement) {
auto& dropProperty = (DropProperty&)statement;
auto tableName = dropProperty.getTableName();
validateTableExist(catalog, tableName);
validateNodeRelTableExist(tableName);
auto catalogContent = catalog.getReadOnlyVersion();
auto tableID = catalogContent->getTableID(tableName);
auto tableSchema = catalogContent->getTableSchema(tableID);
Expand All @@ -292,7 +292,7 @@ std::unique_ptr<BoundStatement> Binder::bindDropProperty(const Statement& statem
std::unique_ptr<BoundStatement> Binder::bindRenameProperty(const Statement& statement) {
auto& renameProperty = (RenameProperty&)statement;
auto tableName = renameProperty.getTableName();
validateTableExist(catalog, tableName);
validateNodeRelTableExist(tableName);
auto catalogContent = catalog.getReadOnlyVersion();
auto tableID = catalogContent->getTableID(tableName);
auto tableSchema = catalogContent->getTableSchema(tableID);
Expand Down
24 changes: 21 additions & 3 deletions src/binder/bind/bind_graph_pattern.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "binder/expression/path_expression.h"
#include "binder/expression/property_expression.h"
#include "catalog/node_table_schema.h"
#include "catalog/rel_table_group_schema.h"
#include "catalog/rel_table_schema.h"

using namespace kuzu::common;
Expand Down Expand Up @@ -457,17 +458,34 @@
}

std::vector<table_id_t> Binder::bindRelTableIDs(const std::vector<std::string>& tableNames) {
if (catalog.getReadOnlyVersion()->getRelTableIDs().empty()) {
auto catalogContent = catalog.getReadOnlyVersion();
if (catalogContent->getRelTableIDs().empty()) {
throw BinderException("No rel table exists in database.");
}
// Rewrite empty rel pattern "-[]-" as all rel tables
std::unordered_set<table_id_t> tableIDs;
if (tableNames.empty()) {
for (auto tableID : catalog.getReadOnlyVersion()->getRelTableIDs()) {
for (auto tableID : catalogContent->getRelTableIDs()) {
tableIDs.insert(tableID);
}
}
for (auto& tableName : tableNames) {
tableIDs.insert(bindRelTableID(tableName));
validateTableExist(tableName);
auto tableID = catalogContent->getTableID(tableName);
auto tableSchema = catalogContent->getTableSchema(tableID);
switch (tableSchema->getTableType()) {
case TableType::REL: {
tableIDs.insert(tableID);
} break;
case TableType::REL_GROUP: {
auto relGroupSchema = reinterpret_cast<RelTableGroupSchema*>(tableSchema);
for (auto& relTableID : relGroupSchema->getRelTableIDs()) {
tableIDs.insert(relTableID);
}
} break;
default:
throw BinderException("Rel table " + tableName + " does not exist.");

Check warning on line 487 in src/binder/bind/bind_graph_pattern.cpp

View check run for this annotation

Codecov / codecov/patch

src/binder/bind/bind_graph_pattern.cpp#L486-L487

Added lines #L486 - L487 were not covered by tests
}
}
auto result = std::vector<table_id_t>{tableIDs.begin(), tableIDs.end()};
std::sort(result.begin(), result.end());
Expand Down
26 changes: 13 additions & 13 deletions src/binder/binder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,18 +67,12 @@ std::shared_ptr<Expression> Binder::bindWhereExpression(const ParsedExpression&
return whereExpression;
}

table_id_t Binder::bindRelTableID(const std::string& tableName) const {
if (!catalog.getReadOnlyVersion()->containRelTable(tableName)) {
throw BinderException("Rel table " + tableName + " does not exist.");
}
return catalog.getReadOnlyVersion()->getTableID(tableName);
}

table_id_t Binder::bindNodeTableID(const std::string& tableName) const {
if (!catalog.getReadOnlyVersion()->containNodeTable(tableName)) {
auto catalogContent = catalog.getReadOnlyVersion();
if (!catalogContent->containNodeTable(tableName)) {
throw BinderException("Node table " + tableName + " does not exist.");
}
return catalog.getReadOnlyVersion()->getTableID(tableName);
return catalogContent->getTableID(tableName);
}

std::shared_ptr<Expression> Binder::createVariable(
Expand Down Expand Up @@ -164,10 +158,16 @@ void Binder::validateReadNotFollowUpdate(const NormalizedSingleQuery& singleQuer
}
}

void Binder::validateTableExist(const Catalog& _catalog, std::string& tableName) {
if (!_catalog.getReadOnlyVersion()->containNodeTable(tableName) &&
!_catalog.getReadOnlyVersion()->containRelTable(tableName)) {
throw BinderException("Node/Rel " + tableName + " does not exist.");
void Binder::validateTableExist(const std::string& tableName) {
if (!catalog.getReadOnlyVersion()->containTable(tableName)) {
throw BinderException("Table " + tableName + " does not exist.");
}
}

void Binder::validateNodeRelTableExist(const std::string& tableName) {
if (!catalog.getReadOnlyVersion()->containNodeTable(tableName) &&
!catalog.getReadOnlyVersion()->containRelTable(tableName)) {
throw BinderException("Table " + tableName + " does not exist.");
}
}

Expand Down
26 changes: 9 additions & 17 deletions src/catalog/catalog_content.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,22 +109,6 @@ table_id_t CatalogContent::addRdfGraphSchema(const BoundCreateTableInfo& info) {
return rdfGraphID;
}

bool CatalogContent::containNodeTable(const std::string& tableName) const {
if (!tableNameToIDMap.contains(tableName)) {
return false;
}
auto tableID = getTableID(tableName);
return tableSchemas.at(tableID)->tableType == TableType::NODE;
}

bool CatalogContent::containRelTable(const std::string& tableName) const {
if (!tableNameToIDMap.contains(tableName)) {
return false;
}
auto tableID = getTableID(tableName);
return tableSchemas.at(tableID)->tableType == TableType::REL;
}

Property* CatalogContent::getNodeProperty(
table_id_t tableID, const std::string& propertyName) const {
for (auto& property : tableSchemas.at(tableID)->properties) {
Expand Down Expand Up @@ -268,7 +252,15 @@ void CatalogContent::registerBuiltInFunctions() {
builtInTableFunctions = std::make_unique<function::BuiltInTableFunctions>();
}

std::vector<TableSchema*> CatalogContent::getTableSchemas(common::TableType tableType) const {
bool CatalogContent::containTable(const std::string& tableName, TableType tableType) const {
if (!tableNameToIDMap.contains(tableName)) {
return false;
}
auto tableID = getTableID(tableName);
return tableSchemas.at(tableID)->tableType == tableType;
}

std::vector<TableSchema*> CatalogContent::getTableSchemas(TableType tableType) const {
std::vector<TableSchema*> result;
for (auto& [id, schema] : tableSchemas) {
if (schema->getTableType() == tableType) {
Expand Down
7 changes: 3 additions & 4 deletions src/include/binder/binder.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ class Binder {
std::shared_ptr<Expression> bindWhereExpression(
const parser::ParsedExpression& parsedExpression);

common::table_id_t bindRelTableID(const std::string& tableName) const;
common::table_id_t bindNodeTableID(const std::string& tableName) const;

std::shared_ptr<Expression> createVariable(
Expand Down Expand Up @@ -105,8 +104,6 @@ class Binder {
catalog::TableSchema* tableSchema, const std::string& propertyName);

/*** bind copy from/to ***/
static bool bindContainsSerial(
catalog::TableSchema* tableSchema, common::CopyDescription::FileType fileType);
expression_vector bindColumnExpressions(
catalog::TableSchema* tableSchema, common::CopyDescription::FileType fileType);
std::unique_ptr<BoundStatement> bindCopyFromClause(const parser::Statement& statement);
Expand Down Expand Up @@ -243,7 +240,9 @@ class Binder {
// multiple statement.
static void validateReadNotFollowUpdate(const NormalizedSingleQuery& singleQuery);

static void validateTableExist(const catalog::Catalog& _catalog, std::string& tableName);
void validateTableExist(const std::string& tableName);
// TODO(Xiyang): remove this validation once we refactor DDL.
void validateNodeRelTableExist(const std::string& tableName);

static bool validateStringParsingOptionName(std::string& parsingOptionName);

Expand Down
14 changes: 10 additions & 4 deletions src/include/catalog/catalog_content.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ class CatalogContent {
inline bool containTable(const std::string& name) const {
return tableNameToIDMap.contains(name);
}
inline bool containNodeTable(const std::string& tableName) const {
return containTable(tableName, common::TableType::NODE);
}
inline bool containRelTable(const std::string& tableName) const {
return containTable(tableName, common::TableType::REL);
}
inline bool containRelGroup(const std::string& tableName) const {
return containTable(tableName, common::TableType::REL_GROUP);
}
inline std::string getTableName(common::table_id_t tableID) const {
assert(tableSchemas.contains(tableID));
return getTableSchema(tableID)->tableName;
Expand All @@ -53,10 +62,6 @@ class CatalogContent {
common::table_id_t addRelTableGroupSchema(const binder::BoundCreateTableInfo& info);
common::table_id_t addRdfGraphSchema(const binder::BoundCreateTableInfo& info);

bool containNodeTable(const std::string& tableName) const;

bool containRelTable(const std::string& tableName) const;

/**
* Node and Rel property functions.
*/
Expand Down Expand Up @@ -113,6 +118,7 @@ class CatalogContent {

void registerBuiltInFunctions();

bool containTable(const std::string& tableName, common::TableType tableType) const;
std::vector<TableSchema*> getTableSchemas(common::TableType tableType) const;
std::vector<common::table_id_t> getTableIDs(common::TableType tableType) const;

Expand Down
4 changes: 2 additions & 2 deletions test/test_files/ddl/ddl.test
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
---- ok
-STATEMENT MATCH ()-[e:studyAt]->() RETURN count(*)
---- error
Binder exception: Rel table studyAt does not exist.
Binder exception: Table studyAt does not exist.
-STATEMENT DROP TABLE workAt
---- ok
-STATEMENT MATCH ()-[e:workAt]->() RETURN count(*)
---- error
Binder exception: Rel table workAt does not exist.
Binder exception: Table workAt does not exist.
-STATEMENT DROP TABLE organisation
---- ok
-STATEMENT MATCH (n:organisation) RETURN count(*)
Expand Down
10 changes: 5 additions & 5 deletions test/test_files/exceptions/binder/binder_error.test
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ Binder exception: Unrecognized parsing csv option: PK.
-LOG CopyCSVInvalidSchemaName
-STATEMENT COPY university FROM "person_0_0.csv" (pk=",")
---- error
Binder exception: Node/Rel university does not exist.
Binder exception: Table university does not exist.

-LOG CopyCSVInvalidEscapeChar
-STATEMENT COPY person FROM "person_0_0.csv" (ESCAPE="..")
Expand Down Expand Up @@ -305,7 +305,7 @@ Binder exception: PropertyName: _id is an internal reserved propertyName.
-LOG DropNotExistsTable
-STATEMENT DROP TABLE person1;
---- error
Binder exception: Node/Rel person1 does not exist.
Binder exception: Table person1 does not exist.

-LOG InvalidLimitNumberType
-STATEMENT MATCH (a:person) RETURN a.age LIMIT "abc"
Expand Down Expand Up @@ -360,7 +360,7 @@ DISTINCT (SERIAL) -> SERIAL
-LOG DropColumnFromNonExistedTable
-STATEMENT alter table person1 drop k
---- error
Binder exception: Node/Rel person1 does not exist.
Binder exception: Table person1 does not exist.

-LOG DropNonExistedColumn
-STATEMENT alter table person drop random
Expand All @@ -385,7 +385,7 @@ Binder exception: Expression 3.2 has data type STRING but expect INT64. Implicit
-LOG RenameNonExistedTable
-STATEMENT alter table person1 rename to person2
---- error
Binder exception: Node/Rel person1 does not exist.
Binder exception: Table person1 does not exist.

-LOG RenameTableDuplicateName
-STATEMENT alter table person rename to organisation
Expand All @@ -395,7 +395,7 @@ Binder exception: Table: organisation already exists.
-LOG RenamePropertyOfNonExistedTable
-STATEMENT alter table person1 rename col1 to col2
---- error
Binder exception: Node/Rel person1 does not exist.
Binder exception: Table person1 does not exist.

-LOG RenamePropertyDuplicateName
-STATEMENT alter table person rename fName to gender
Expand Down
Loading