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

Catalog rework #1877

Merged
merged 1 commit into from
Aug 1, 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
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.11)

project(Kuzu VERSION 0.0.6.2 LANGUAGES CXX)
project(Kuzu VERSION 0.0.6.3 LANGUAGES CXX)

find_package(Threads REQUIRED)

Expand Down
37 changes: 18 additions & 19 deletions src/binder/bind/bind_ddl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ std::unique_ptr<BoundStatement> Binder::bindCreateNodeTableClause(
auto primaryKeyIdx = bindPrimaryKey(
createNodeTableClause.getPKColName(), createNodeTableClause.getPropertyNameDataTypes());
for (auto i = 0u; i < boundProperties.size(); ++i) {
if (boundProperties[i].dataType.getLogicalTypeID() == LogicalTypeID::SERIAL &&
if (boundProperties[i]->getDataType()->getLogicalTypeID() == LogicalTypeID::SERIAL &&
primaryKeyIdx != i) {
throw BinderException("Serial property in node table must be the primary key.");
}
Expand All @@ -50,7 +50,7 @@ std::unique_ptr<BoundStatement> Binder::bindCreateRelTableClause(
}
auto boundProperties = bindProperties(createRelClause.getPropertyNameDataTypes());
for (auto& boundProperty : boundProperties) {
if (boundProperty.dataType.getLogicalTypeID() == LogicalTypeID::SERIAL) {
if (boundProperty->getDataType()->getLogicalTypeID() == LogicalTypeID::SERIAL) {
throw BinderException("Serial property is not supported in rel table.");
}
}
Expand Down Expand Up @@ -94,27 +94,25 @@ std::unique_ptr<BoundStatement> Binder::bindAddPropertyClause(const parser::Stat
if (catalogContent->getTableSchema(tableID)->containProperty(addProperty.getPropertyName())) {
throw BinderException("Property: " + addProperty.getPropertyName() + " already exists.");
}
if (dataType.getLogicalTypeID() == LogicalTypeID::SERIAL) {
if (dataType->getLogicalTypeID() == LogicalTypeID::SERIAL) {
throw BinderException("Serial property in node table must be the primary key.");
}
auto defaultVal = ExpressionBinder::implicitCastIfNecessary(
expressionBinder.bindExpression(*addProperty.getDefaultValue()), dataType);
expressionBinder.bindExpression(*addProperty.getDefaultValue()), *dataType);
return make_unique<BoundAddProperty>(
tableID, addProperty.getPropertyName(), dataType, defaultVal, tableName);
tableID, addProperty.getPropertyName(), std::move(dataType), defaultVal, tableName);
}

std::unique_ptr<BoundStatement> Binder::bindDropPropertyClause(const parser::Statement& statement) {
auto& dropProperty = (DropProperty&)statement;
auto tableName = dropProperty.getTableName();
validateTableExist(catalog, tableName);
auto catalogContent = catalog.getReadOnlyVersion();
auto isNodeTable = catalogContent->containNodeTable(tableName);
auto tableID = catalogContent->getTableID(tableName);
auto propertyID =
bindPropertyName(catalogContent->getTableSchema(tableID), dropProperty.getPropertyName());
if (isNodeTable &&
((NodeTableSchema*)catalogContent->getTableSchema(tableID))->primaryKeyPropertyID ==
propertyID) {
auto tableSchema = catalogContent->getTableSchema(tableID);
auto propertyID = bindPropertyName(tableSchema, dropProperty.getPropertyName());
if (tableSchema->getTableType() == catalog::TableType::NODE &&
reinterpret_cast<NodeTableSchema*>(tableSchema)->getPrimaryKeyPropertyID() == propertyID) {
throw BinderException("Cannot drop primary key of a node table.");
}
return make_unique<BoundDropProperty>(tableID, propertyID, tableName);
Expand All @@ -137,10 +135,11 @@ std::unique_ptr<BoundStatement> Binder::bindRenamePropertyClause(
tableID, tableName, propertyID, renameProperty.getNewName());
}

std::vector<Property> Binder::bindProperties(
std::vector<std::unique_ptr<Property>> Binder::bindProperties(
std::vector<std::pair<std::string, std::string>> propertyNameDataTypes) {
std::vector<Property> boundPropertyNameDataTypes;
std::vector<std::unique_ptr<Property>> boundPropertyNameDataTypes;
std::unordered_set<std::string> boundPropertyNames;
boundPropertyNameDataTypes.reserve(propertyNameDataTypes.size());
for (auto& propertyNameDataType : propertyNameDataTypes) {
if (boundPropertyNames.contains(propertyNameDataType.first)) {
throw BinderException(StringUtils::string_format(
Expand All @@ -151,8 +150,8 @@ std::vector<Property> Binder::bindProperties(
StringUtils::string_format("PropertyName: {} is an internal reserved propertyName.",
propertyNameDataType.first));
}
auto dataType = bindDataType(propertyNameDataType.second);
boundPropertyNameDataTypes.emplace_back(propertyNameDataType.first, dataType);
boundPropertyNameDataTypes.push_back(std::make_unique<Property>(
propertyNameDataType.first, bindDataType(propertyNameDataType.second)));
boundPropertyNames.emplace(propertyNameDataType.first);
}
return boundPropertyNameDataTypes;
Expand Down Expand Up @@ -187,15 +186,15 @@ uint32_t Binder::bindPrimaryKey(const std::string& pkColName,

property_id_t Binder::bindPropertyName(TableSchema* tableSchema, const std::string& propertyName) {
for (auto& property : tableSchema->properties) {
if (property.name == propertyName) {
return property.propertyID;
if (property->getName() == propertyName) {
return property->getPropertyID();
}
}
throw BinderException(
tableSchema->tableName + " table doesn't have property: " + propertyName + ".");
}

LogicalType Binder::bindDataType(const std::string& dataType) {
std::unique_ptr<common::LogicalType> Binder::bindDataType(const std::string& dataType) {
auto boundType = LogicalTypeUtils::dataTypeFromString(dataType);
if (boundType.getLogicalTypeID() == common::LogicalTypeID::FIXED_LIST) {
auto validNumericTypes = common::LogicalTypeUtils::getNumericalLogicalTypeIDs();
Expand All @@ -222,7 +221,7 @@ LogicalType Binder::bindDataType(const std::string& dataType) {
storage::StorageUtils::getDataTypeSize(boundType)));
}
}
return boundType;
return std::make_unique<common::LogicalType>(boundType);
}

} // namespace binder
Expand Down
48 changes: 25 additions & 23 deletions src/binder/bind/bind_graph_pattern.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,53 +123,55 @@ static std::vector<table_id_t> pruneRelTableIDs(const Catalog& catalog_,
std::vector<table_id_t> result;
for (auto& relTableID : relTableIDs) {
auto relTableSchema = catalog_.getReadOnlyVersion()->getRelTableSchema(relTableID);
if (!srcNodeTableIDs.contains(relTableSchema->srcTableID) ||
!dstNodeTableIDs.contains(relTableSchema->dstTableID)) {
if (!srcNodeTableIDs.contains(relTableSchema->getSrcTableID()) ||
!dstNodeTableIDs.contains(relTableSchema->getDstTableID())) {
continue;
}
result.push_back(relTableID);
}
return result;
}

static std::vector<std::pair<std::string, std::vector<Property>>> getPropertyNameAndSchemasPairs(
static std::vector<std::pair<std::string, std::vector<Property*>>> getPropertyNameAndSchemasPairs(
const std::vector<std::string>& propertyNames,
std::unordered_map<std::string, std::vector<Property>> propertyNamesToSchemas) {
std::vector<std::pair<std::string, std::vector<Property>>> propertyNameAndSchemasPairs;
std::unordered_map<std::string, std::vector<Property*>> propertyNamesToSchemas) {
std::vector<std::pair<std::string, std::vector<Property*>>> propertyNameAndSchemasPairs;
for (auto& propertyName : propertyNames) {
auto propertySchemas = propertyNamesToSchemas.at(propertyName);
propertyNameAndSchemasPairs.emplace_back(propertyName, std::move(propertySchemas));
}
return propertyNameAndSchemasPairs;
}

static std::vector<std::pair<std::string, std::vector<Property>>>
static std::vector<std::pair<std::string, std::vector<Property*>>>
getRelPropertyNameAndPropertiesPairs(const std::vector<RelTableSchema*>& relTableSchemas) {
std::vector<std::string> propertyNames; // preserve order as specified in catalog.
std::unordered_map<std::string, std::vector<Property>> propertyNamesToSchemas;
std::unordered_map<std::string, std::vector<Property*>> propertyNamesToSchemas;
for (auto& relTableSchema : relTableSchemas) {
for (auto& property : relTableSchema->properties) {
if (!propertyNamesToSchemas.contains(property.name)) {
propertyNames.push_back(property.name);
propertyNamesToSchemas.insert({property.name, std::vector<Property>{}});
auto propertyName = property->getName();
if (!propertyNamesToSchemas.contains(propertyName)) {
propertyNames.push_back(propertyName);
propertyNamesToSchemas.emplace(propertyName, std::vector<Property*>{});
}
propertyNamesToSchemas.at(property.name).push_back(property);
propertyNamesToSchemas.at(propertyName).push_back(property.get());
}
}
return getPropertyNameAndSchemasPairs(propertyNames, propertyNamesToSchemas);
}

static std::vector<std::pair<std::string, std::vector<Property>>>
static std::vector<std::pair<std::string, std::vector<Property*>>>
getNodePropertyNameAndPropertiesPairs(const std::vector<NodeTableSchema*>& nodeTableSchemas) {
std::vector<std::string> propertyNames; // preserve order as specified in catalog.
std::unordered_map<std::string, std::vector<Property>> propertyNamesToSchemas;
std::unordered_map<std::string, std::vector<Property*>> propertyNamesToSchemas;
for (auto& nodeTableSchema : nodeTableSchemas) {
for (auto& property : nodeTableSchema->properties) {
if (!propertyNamesToSchemas.contains(property.name)) {
propertyNames.push_back(property.name);
propertyNamesToSchemas.insert({property.name, std::vector<Property>{}});
auto propertyName = property->getName();
if (!propertyNamesToSchemas.contains(propertyName)) {
propertyNames.push_back(propertyName);
propertyNamesToSchemas.emplace(propertyName, std::vector<Property*>{});
}
propertyNamesToSchemas.at(property.name).push_back(property);
propertyNamesToSchemas.at(propertyName).push_back(property.get());
}
}
return getPropertyNameAndSchemasPairs(propertyNames, propertyNamesToSchemas);
Expand Down Expand Up @@ -278,8 +280,8 @@ std::shared_ptr<RelExpression> Binder::createRecursiveQueryRel(const parser::Rel
std::unordered_set<common::table_id_t> recursiveNodeTableIDs;
for (auto relTableID : tableIDs) {
auto relTableSchema = catalog.getReadOnlyVersion()->getRelTableSchema(relTableID);
recursiveNodeTableIDs.insert(relTableSchema->srcTableID);
recursiveNodeTableIDs.insert(relTableSchema->dstTableID);
recursiveNodeTableIDs.insert(relTableSchema->getSrcTableID());
recursiveNodeTableIDs.insert(relTableSchema->getDstTableID());
}
auto recursiveRelPatternInfo = relPattern.getRecursiveInfo();
auto tmpNode = createQueryNode(
Expand Down Expand Up @@ -423,8 +425,8 @@ void Binder::bindQueryNodeProperties(NodeExpression& node) {
getNodePropertyNameAndPropertiesPairs(tableSchemas)) {
bool isPrimaryKey = false;
if (!node.isMultiLabeled()) {
isPrimaryKey =
tableSchemas[0]->getPrimaryKey().propertyID == propertySchemas[0].propertyID;
isPrimaryKey = tableSchemas[0]->getPrimaryKey()->getPropertyID() ==
propertySchemas[0]->getPropertyID();
}
auto propertyExpression =
expressionBinder.createPropertyExpression(node, propertySchemas, isPrimaryKey);
Expand All @@ -434,7 +436,7 @@ void Binder::bindQueryNodeProperties(NodeExpression& node) {

std::vector<common::table_id_t> Binder::bindNodeTableIDs(
const std::vector<std::string>& tableNames) {
if (!catalog.getReadOnlyVersion()->hasNodeTable()) {
if (catalog.getReadOnlyVersion()->getNodeTableIDs().empty()) {
throw common::BinderException("No node table exists in database.");
}
std::unordered_set<table_id_t> tableIDs;
Expand All @@ -454,7 +456,7 @@ std::vector<common::table_id_t> Binder::bindNodeTableIDs(

std::vector<common::table_id_t> Binder::bindRelTableIDs(
const std::vector<std::string>& tableNames) {
if (!catalog.getReadOnlyVersion()->hasRelTable()) {
if (catalog.getReadOnlyVersion()->getRelTableIDs().empty()) {
throw common::BinderException("No rel table exists in database.");
}
std::unordered_set<table_id_t> tableIDs;
Expand Down
35 changes: 18 additions & 17 deletions src/binder/bind/bind_updating_clause.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,12 +120,12 @@
auto primaryKey = nodeTableSchema->getPrimaryKey();
std::shared_ptr<Expression> primaryKeyExpression;
std::vector<expression_pair> setItems;
for (auto& property : catalog.getReadOnlyVersion()->getNodeProperties(nodeTableID)) {
if (collection.hasKeyVal(node, property.name)) {
setItems.emplace_back(collection.getKeyVal(node, property.name));
for (auto& property : catalog.getReadOnlyVersion()->getProperties(nodeTableID)) {
if (collection.hasKeyVal(node, property->getName())) {
setItems.emplace_back(collection.getKeyVal(node, property->getName()));
} else {
auto propertyExpression =
expressionBinder.bindNodePropertyExpression(*node, property.name);
expressionBinder.bindNodePropertyExpression(*node, property->getName());
auto nullExpression = expressionBinder.createNullLiteralExpression();
nullExpression = ExpressionBinder::implicitCastIfNecessary(
nullExpression, propertyExpression->dataType);
Expand All @@ -134,14 +134,14 @@
}
for (auto& [key, val] : collection.getKeyVals(node)) {
auto propertyExpression = static_pointer_cast<PropertyExpression>(key);
if (propertyExpression->getPropertyID(nodeTableID) == primaryKey.propertyID) {
if (propertyExpression->getPropertyID(nodeTableID) == primaryKey->getPropertyID()) {
primaryKeyExpression = val;
}
}
if (nodeTableSchema->getPrimaryKey().dataType.getLogicalTypeID() != LogicalTypeID::SERIAL &&
if (primaryKey->getDataType()->getLogicalTypeID() != LogicalTypeID::SERIAL &&
primaryKeyExpression == nullptr) {
throw BinderException("Create node " + node->toString() + " expects primary key " +
primaryKey.name + " as input.");
primaryKey->getName() + " as input.");
}
auto extraInfo = std::make_unique<ExtraCreateNodeInfo>(std::move(primaryKeyExpression));
return std::make_unique<BoundCreateInfo>(
Expand All @@ -160,12 +160,12 @@
// CreateRel requires all properties in schema as input. So we rewrite set property to
// null if user does not specify a property in the query.
std::vector<expression_pair> setItems;
for (auto& property : catalogContent->getRelProperties(relTableID)) {
if (collection.hasKeyVal(rel, property.name)) {
setItems.push_back(collection.getKeyVal(rel, property.name));
for (auto& property : catalogContent->getProperties(relTableID)) {
if (collection.hasKeyVal(rel, property->getName())) {
setItems.push_back(collection.getKeyVal(rel, property->getName()));
} else {
auto propertyExpression =
expressionBinder.bindRelPropertyExpression(*rel, property.name);
expressionBinder.bindRelPropertyExpression(*rel, property->getName());
auto nullExpression = expressionBinder.createNullLiteralExpression();
nullExpression = ExpressionBinder::implicitCastIfNecessary(
nullExpression, propertyExpression->dataType);
Expand Down Expand Up @@ -262,20 +262,21 @@
auto anchorPrimaryKey = tableSchemas[0]->getPrimaryKey();
for (auto i = 1; i < tableSchemas.size(); ++i) {
auto primaryKey = tableSchemas[i]->getPrimaryKey();
if (primaryKey.name != anchorPrimaryKey.name) {
if (primaryKey->getName() != anchorPrimaryKey->getName()) {
throw common::BinderException(common::StringUtils::string_format(
"Cannot delete node {} with different primary key name. Expect {} but get {}.",
node->toString(), anchorPrimaryKey.name, primaryKey.name));
node->toString(), anchorPrimaryKey->getName(), primaryKey->getName()));

Check warning on line 268 in src/binder/bind/bind_updating_clause.cpp

View check run for this annotation

Codecov / codecov/patch

src/binder/bind/bind_updating_clause.cpp#L268

Added line #L268 was not covered by tests
}
if (primaryKey.dataType != anchorPrimaryKey.dataType) {
if (*primaryKey->getDataType() != *anchorPrimaryKey->getDataType()) {
throw common::BinderException(common::StringUtils::string_format(
"Cannot delete node {} with different primary key data type. Expect {} but get {}.",
node->toString(), LogicalTypeUtils::dataTypeToString(anchorPrimaryKey.dataType),
LogicalTypeUtils::dataTypeToString(primaryKey.dataType)));
node->toString(),
LogicalTypeUtils::dataTypeToString(*anchorPrimaryKey->getDataType()),
LogicalTypeUtils::dataTypeToString(*primaryKey->getDataType())));

Check warning on line 275 in src/binder/bind/bind_updating_clause.cpp

View check run for this annotation

Codecov / codecov/patch

src/binder/bind/bind_updating_clause.cpp#L273-L275

Added lines #L273 - L275 were not covered by tests
}
}
auto primaryKeyExpression =
expressionBinder.bindNodePropertyExpression(*node, anchorPrimaryKey.name);
expressionBinder.bindNodePropertyExpression(*node, anchorPrimaryKey->getName());
auto extraInfo = std::make_unique<ExtraDeleteNodeInfo>(primaryKeyExpression);
return std::make_unique<BoundDeleteInfo>(UpdateTableType::NODE, node, std::move(extraInfo));
}
Expand Down
Loading
Loading