Skip to content
Open
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
27 changes: 27 additions & 0 deletions src/catalog/catalog_entry/duck_table_entry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,29 @@ DuckTableEntry::DuckTableEntry(Catalog &catalog, SchemaCatalogEntry &schema, Bou
return;
}

if (info.base->type == CatalogType::TABLE_ENTRY) {
vector<string> unsupported_keywords;
auto &base = info.Base();
if (!base.partition_keys.empty()) {
unsupported_keywords.push_back("PARTITIONED BY");
}
if (!base.order_keys.empty()) {
unsupported_keywords.push_back("SORTED BY");
}
if (!base.location.empty()) {
unsupported_keywords.push_back("LOCATION");
}
if (!base.tbl_properties.empty()) {
unsupported_keywords.push_back("TBLPROPERTIES");
}
if (!unsupported_keywords.empty()) {
auto error_message = StringUtil::Join(unsupported_keywords, ", ") +
(unsupported_keywords.size() > 1 ? " are" : " is") +
" not supported for DuckDB tables";
throw CatalogException(error_message);
}
}

// create the physical storage
vector<ColumnDefinition> column_defs;
for (auto &col_def : columns.Physical()) {
Expand Down Expand Up @@ -242,6 +265,10 @@ unique_ptr<CatalogEntry> DuckTableEntry::AlterEntry(ClientContext &context, Alte
throw NotImplementedException("SET PARTITIONED BY is not supported for DuckDB tables");
case AlterTableType::SET_SORTED_BY:
throw NotImplementedException("SET SORTED BY is not supported for DuckDB tables");
case AlterTableType::SET_LOCATION:
throw NotImplementedException("SET LOCATION is not supported for DuckDB tables");
case AlterTableType::SET_TBLPROPERTIES:
throw NotImplementedException("SET TBLPROPERTIES is not supported for DuckDB tables");
default:
throw InternalException("Unrecognized alter table type!");
}
Expand Down
44 changes: 43 additions & 1 deletion src/include/duckdb/parser/parsed_data/alter_table_info.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,9 @@ enum class AlterTableType : uint8_t {
SET_SORTED_BY = 13,
ADD_FIELD = 14,
REMOVE_FIELD = 15,
RENAME_FIELD = 16
RENAME_FIELD = 16,
SET_LOCATION = 17,
SET_TBLPROPERTIES = 18
};

struct AlterTableInfo : public AlterInfo {
Expand Down Expand Up @@ -493,4 +495,44 @@ struct SetSortedByInfo : public AlterTableInfo {
SetSortedByInfo();
};

//===--------------------------------------------------------------------===//
// SetLocationInfo
//===--------------------------------------------------------------------===//
struct SetLocationInfo : public AlterTableInfo {
SetLocationInfo(AlterEntryData data, string location);
~SetLocationInfo() override;

string location;

public:
unique_ptr<AlterInfo> Copy() const override;
string ToString() const override;

void Serialize(Serializer &serializer) const override;
static unique_ptr<AlterTableInfo> Deserialize(Deserializer &deserializer);

private:
SetLocationInfo();
};

//===--------------------------------------------------------------------===//
// SetTblPropertiesInfo
//===--------------------------------------------------------------------===//
struct SetTblPropertiesInfo : public AlterTableInfo {
SetTblPropertiesInfo(AlterEntryData data, case_insensitive_map_t<string> tbl_properties);
~SetTblPropertiesInfo() override;

case_insensitive_map_t<string> tbl_properties;

public:
unique_ptr<AlterInfo> Copy() const override;
string ToString() const override;

void Serialize(Serializer &serializer) const override;
static unique_ptr<AlterTableInfo> Deserialize(Deserializer &deserializer);

private:
SetTblPropertiesInfo();
};

} // namespace duckdb
8 changes: 8 additions & 0 deletions src/include/duckdb/parser/parsed_data/create_table_info.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ struct CreateTableInfo : public CreateInfo {
vector<unique_ptr<Constraint>> constraints;
//! CREATE TABLE as QUERY
unique_ptr<SelectStatement> query;
//! Table Partition definitions
vector<unique_ptr<ParsedExpression>> partition_keys;
//! Table Sort definitions
vector<unique_ptr<ParsedExpression>> order_keys;
//! Table location (if any)
string location;
//! TBLPROPERTIES (if any)
case_insensitive_map_t<Value> tbl_properties;

public:
DUCKDB_API unique_ptr<CreateInfo> Copy() const override;
Expand Down
1 change: 1 addition & 0 deletions src/include/duckdb/parser/transformer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ class Transformer {
unique_ptr<CopyStatement> TransformCopy(duckdb_libpgquery::PGCopyStmt &stmt);
void TransformCopyOptions(CopyInfo &info, optional_ptr<duckdb_libpgquery::PGList> options);
void TransformCreateSecretOptions(CreateSecretInfo &info, optional_ptr<duckdb_libpgquery::PGList> options);
void TransformOptions(case_insensitive_map_t<Value> &info, optional_ptr<duckdb_libpgquery::PGList> options);
//! Transform a Postgres duckdb_libpgquery::T_PGTransactionStmt node into a TransactionStatement
unique_ptr<TransactionStatement> TransformTransaction(duckdb_libpgquery::PGTransactionStmt &stmt);
//! Transform a Postgres T_DeleteStatement node into a DeleteStatement
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ struct BoundCreateTableInfo {
unique_ptr<LogicalOperator> query;
//! Indexes created by this table
vector<IndexStorageInfo> indexes;
//! partition info
vector<unique_ptr<ParsedExpression>> partition_keys;
//! sort info
vector<unique_ptr<ParsedExpression>> order_keys;
//! location info
string location;
//! tbl_properties info
case_insensitive_map_t<Value> tbl_properties;

CreateTableInfo &Base() {
D_ASSERT(base);
Expand Down
22 changes: 22 additions & 0 deletions src/include/duckdb/storage/serialization/create_info.json
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,28 @@
"id": 203,
"name": "query",
"type": "SelectStatement*"
},
{
"id": 204,
"name": "partition_keys",
"type": "vector<ParsedExpression*>"
},
{
"id": 205,
"name": "order_keys",
"type": "vector<ParsedExpression*>"
},
{
"id": 206,
"name": "location",
"type": "string",
"default": "\"\""
},
{
"id": 207,
"name": "tbl_properties",
"type": "case_insensitive_map_t<Value>",
"default": "case_insensitive_map_t<Value>()"
}
]
},
Expand Down
57 changes: 57 additions & 0 deletions src/parser/parsed_data/alter_table_info.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -671,4 +671,61 @@ string SetSortedByInfo::ToString() const {
return result;
}

//===--------------------------------------------------------------------===//
// SetLocationInfo
//===--------------------------------------------------------------------===//
SetLocationInfo::SetLocationInfo() : AlterTableInfo(AlterTableType::SET_LOCATION) {
}

SetLocationInfo::SetLocationInfo(AlterEntryData data, string location_p)
: AlterTableInfo(AlterTableType::SET_LOCATION, std::move(data)), location(std::move(location_p)) {
}

SetLocationInfo::~SetLocationInfo() {
}

unique_ptr<AlterInfo> SetLocationInfo::Copy() const {
return make_uniq<SetLocationInfo>(GetAlterEntryData(), location);
}

string SetLocationInfo::ToString() const {
string result = "ALTER TABLE ";
result += QualifierToString(catalog, schema, name);
result += " SET LOCATION " + KeywordHelper::WriteQuoted(location, '\'');
return result;
}

//===--------------------------------------------------------------------===//
// SetTblPropertiesInfo
//===--------------------------------------------------------------------===//
SetTblPropertiesInfo::SetTblPropertiesInfo() : AlterTableInfo(AlterTableType::SET_TBLPROPERTIES) {
}

SetTblPropertiesInfo::SetTblPropertiesInfo(AlterEntryData data, case_insensitive_map_t<string> tbl_properties_p)
: AlterTableInfo(AlterTableType::SET_TBLPROPERTIES, std::move(data)), tbl_properties(std::move(tbl_properties_p)) {
}

SetTblPropertiesInfo::~SetTblPropertiesInfo() {
}

unique_ptr<AlterInfo> SetTblPropertiesInfo::Copy() const {
return make_uniq<SetTblPropertiesInfo>(GetAlterEntryData(), tbl_properties);
}

string SetTblPropertiesInfo::ToString() const {
string result = "ALTER TABLE ";
result += QualifierToString(catalog, schema, name);
result += " SET TBLPROPERTIES (";
idx_t i = 0;
for (auto &entry : tbl_properties) {
if (i > 0) {
result += ", ";
}
result += KeywordHelper::WriteQuoted(entry.first, '\'') + "=" + KeywordHelper::WriteQuoted(entry.second, '\'');
i++;
}
result += ")";
return result;
}

} // namespace duckdb
39 changes: 38 additions & 1 deletion src/parser/parsed_data/create_table_info.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ unique_ptr<CreateInfo> CreateTableInfo::Copy() const {
for (auto &constraint : constraints) {
result->constraints.push_back(constraint->Copy());
}
for (auto &partition : partition_keys) {
result->partition_keys.push_back(partition->Copy());
}
for (auto &order : order_keys) {
result->order_keys.push_back(order->Copy());
}
result->location = location;
result->tbl_properties = tbl_properties;
if (query) {
result->query = unique_ptr_cast<SQLStatement, SelectStatement>(query->Copy());
}
Expand All @@ -37,8 +45,37 @@ string CreateTableInfo::ToString() const {
ret += TableCatalogEntry::ColumnNamesToSQL(columns);
ret += " AS " + query->ToString();
} else {
ret += TableCatalogEntry::ColumnsToSQL(columns, constraints) + ";";
ret += TableCatalogEntry::ColumnsToSQL(columns, constraints);
if (!partition_keys.empty()) {
ret += " PARTITIONED BY (";
for (auto &partition : partition_keys) {
ret += partition->ToString() + ",";
}
ret.pop_back();
ret += ")";
}
if (!order_keys.empty()) {
ret += " SORTED BY (";
for (auto &order : order_keys) {
ret += order->ToString() + ",";
}
ret.pop_back();
ret += ")";
}
if (!location.empty()) {
ret += " LOCATION '" + location + "'";
}
if (!tbl_properties.empty()) {
ret += " TBLPROPERTIES (";
for (auto &entry : tbl_properties) {
ret += "'" + entry.first + "'='" + entry.second.ToString() + "',";
}
ret.pop_back();
ret += ")";
}
ret += ";";
}

return ret;
}

Expand Down
3 changes: 3 additions & 0 deletions src/parser/transform/expression/transform_expression.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "duckdb/common/exception.hpp"
#include "duckdb/parser/expression/default_expression.hpp"
#include "duckdb/parser/expression/constant_expression.hpp"
#include "duckdb/parser/transformer.hpp"

namespace duckdb {
Expand Down Expand Up @@ -77,6 +78,8 @@ unique_ptr<ParsedExpression> Transformer::TransformExpression(duckdb_libpgquery:
return TransformBooleanTest(PGCast<duckdb_libpgquery::PGBooleanTest>(node));
case duckdb_libpgquery::T_PGMultiAssignRef:
return TransformMultiAssignRef(PGCast<duckdb_libpgquery::PGMultiAssignRef>(node));
case duckdb_libpgquery::T_PGString:
return TransformValue(PGCast<duckdb_libpgquery::PGValue>(node));
default:
throw NotImplementedException("Expression type %s (%d)", NodetypeToString(node.type), (int)node.type);
}
Expand Down
16 changes: 16 additions & 0 deletions src/parser/transform/statement/transform_alter_table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,22 @@ unique_ptr<SQLStatement> Transformer::TransformAlter(duckdb_libpgquery::PGAlterT
result->info = make_uniq<SetSortedByInfo>(std::move(data), std::move(orders));
break;
}
case duckdb_libpgquery::PG_AT_SetLocation: {
result->info = make_uniq<SetLocationInfo>(std::move(data), command->location);
break;
}
case duckdb_libpgquery::PG_AT_SetTblProperties: {
case_insensitive_map_t<string> tbl_properties;
if (command->tbl_properties) {
for (auto cell = command->tbl_properties->head; cell != nullptr; cell = cell->next) {
auto def_elem = PGPointerCast<duckdb_libpgquery::PGDefElem>(cell->data.ptr_value);
auto val = PGPointerCast<duckdb_libpgquery::PGValue>(def_elem->arg);
tbl_properties[def_elem->defname] = val->val.str;
}
}
result->info = make_uniq<SetTblPropertiesInfo>(std::move(data), std::move(tbl_properties));
break;
}
default:
throw NotImplementedException("No support for that ALTER TABLE option yet!");
}
Expand Down
19 changes: 19 additions & 0 deletions src/parser/transform/statement/transform_create_table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,25 @@ unique_ptr<CreateStatement> Transformer::TransformCreateTable(duckdb_libpgquery:
}
}

vector<unique_ptr<ParsedExpression>> partition_keys;
if (stmt.partition_list) {
TransformExpressionList(*stmt.partition_list, partition_keys);
}
info->partition_keys = std::move(partition_keys);

vector<unique_ptr<ParsedExpression>> order_keys;
if (stmt.sort_list) {
TransformExpressionList(*stmt.sort_list, order_keys);
}
info->order_keys = std::move(order_keys);

if (stmt.location) {
info->location = stmt.location;
}
if (stmt.tbl_properties) {
TransformOptions(info->tbl_properties, stmt.tbl_properties);
}

if (!column_count) {
throw ParserException("Table must have at least one column!");
}
Expand Down
26 changes: 26 additions & 0 deletions src/parser/transformer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -244,4 +244,30 @@ void Transformer::SetQueryLocation(TableRef &ref, int query_location) {
ref.query_location = optional_idx(static_cast<idx_t>(query_location));
}

void Transformer::TransformOptions(case_insensitive_map_t<Value> &options,
optional_ptr<duckdb_libpgquery::PGList> pg_options) {
if (!pg_options) {
return;
}

duckdb_libpgquery::PGListCell *cell;
for_each_cell(cell, pg_options->head) {
auto def_elem = PGPointerCast<duckdb_libpgquery::PGDefElem>(cell->data.ptr_value);
auto lower_name = StringUtil::Lower(def_elem->defname);
if (options.find(lower_name) != options.end()) {
throw ParserException("Duplicate option \"%s\"", lower_name);
}
if (!def_elem->arg) {
options[lower_name] = Value::BOOLEAN(true);
continue;
}
auto expr = TransformExpression(def_elem->arg);
if (expr->type != ExpressionType::VALUE_CONSTANT) {
throw ParserException("Option \"%s\" must be a constant", lower_name);
}
auto &constant = expr->Cast<ConstantExpression>();
options[lower_name] = constant.value;
}
}

} // namespace duckdb
8 changes: 8 additions & 0 deletions src/storage/serialization/serialize_create_info.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,10 @@ void CreateTableInfo::Serialize(Serializer &serializer) const {
serializer.WriteProperty<ColumnList>(201, "columns", columns);
serializer.WritePropertyWithDefault<vector<unique_ptr<Constraint>>>(202, "constraints", constraints);
serializer.WritePropertyWithDefault<unique_ptr<SelectStatement>>(203, "query", query);
serializer.WritePropertyWithDefault<vector<unique_ptr<ParsedExpression>>>(204, "partition_keys", partition_keys);
serializer.WritePropertyWithDefault<vector<unique_ptr<ParsedExpression>>>(205, "order_keys", order_keys);
serializer.WritePropertyWithDefault<string>(206, "location", location, "");
serializer.WritePropertyWithDefault<case_insensitive_map_t<Value>>(207, "tbl_properties", tbl_properties);
}

unique_ptr<CreateInfo> CreateTableInfo::Deserialize(Deserializer &deserializer) {
Expand All @@ -176,6 +180,10 @@ unique_ptr<CreateInfo> CreateTableInfo::Deserialize(Deserializer &deserializer)
deserializer.ReadProperty<ColumnList>(201, "columns", result->columns);
deserializer.ReadPropertyWithDefault<vector<unique_ptr<Constraint>>>(202, "constraints", result->constraints);
deserializer.ReadPropertyWithDefault<unique_ptr<SelectStatement>>(203, "query", result->query);
deserializer.ReadPropertyWithDefault<vector<unique_ptr<ParsedExpression>>>(204, "partition_keys", result->partition_keys);
deserializer.ReadPropertyWithDefault<vector<unique_ptr<ParsedExpression>>>(205, "order_keys", result->order_keys);
deserializer.ReadPropertyWithDefault<string>(206, "location", result->location);
deserializer.ReadPropertyWithDefault<case_insensitive_map_t<Value>>(207, "tbl_properties", result->tbl_properties);
return std::move(result);
}

Expand Down
Loading
Loading