From 0d835285a741b72e5fa28f5278b1ec187e6e1760 Mon Sep 17 00:00:00 2001 From: Shangjie Chen Date: Mon, 2 Apr 2018 02:01:16 +0000 Subject: [PATCH 01/58] add alter table catalog --- src/catalog/catalog.cpp | 268 +++++++++++++++++++++++++++------ src/include/catalog/catalog.h | 25 +++ src/include/storage/database.h | 3 + src/storage/database.cpp | 20 +++ 4 files changed, 274 insertions(+), 42 deletions(-) diff --git a/src/catalog/catalog.cpp b/src/catalog/catalog.cpp index 3ed19e68dc1..3e877afcaee 100644 --- a/src/catalog/catalog.cpp +++ b/src/catalog/catalog.cpp @@ -26,11 +26,16 @@ #include "catalog/table_metrics_catalog.h" #include "catalog/trigger_catalog.h" #include "concurrency/transaction_manager_factory.h" +#include "executor/executor_context.h" +#include "executor/insert_executor.h" +#include "executor/seq_scan_executor.h" #include "function/date_functions.h" #include "function/decimal_functions.h" #include "function/old_engine_string_functions.h" #include "function/timestamp_functions.h" #include "index/index_factory.h" +#include "planner/seq_scan_plan.h" +#include "planner/insert_plan.h" #include "settings/settings_manager.h" #include "storage/storage_manager.h" #include "storage/table_factory.h" @@ -148,12 +153,12 @@ void Catalog::Bootstrap() { DatabaseMetricsCatalog::GetInstance(txn); TableMetricsCatalog::GetInstance(txn); IndexMetricsCatalog::GetInstance(txn); - QueryMetricsCatalog::GetInstance(txn); + QueryMetricsCatalog::GetInstance(txn); SettingsCatalog::GetInstance(txn); TriggerCatalog::GetInstance(txn); LanguageCatalog::GetInstance(txn); ProcCatalog::GetInstance(txn); - + if (settings::SettingsManager::GetBool(settings::SettingId::brain)) { QueryHistoryCatalog::GetInstance(txn); } @@ -614,18 +619,18 @@ ResultType Catalog::DropIndex(oid_t index_oid, ResultType Catalog::DropIndex(const std::string &index_name, concurrency::TransactionContext *txn) { - if(txn == nullptr) { - throw CatalogException("Do not have transaction to drop index " + - index_name); - } - auto index_object = catalog::IndexCatalog::GetInstance()->GetIndexObject( - index_name, txn); - if(index_object == nullptr) { - throw CatalogException("Index name " + index_name + " cannot be found"); - } - ResultType result = DropIndex(index_object->GetIndexOid(), txn); + if (txn == nullptr) { + throw CatalogException("Do not have transaction to drop index " + + index_name); + } + auto index_object = + catalog::IndexCatalog::GetInstance()->GetIndexObject(index_name, txn); + if (index_object == nullptr) { + throw CatalogException("Index name " + index_name + " cannot be found"); + } + ResultType result = DropIndex(index_object->GetIndexOid(), txn); - return result; + return result; } //===--------------------------------------------------------------------===// @@ -787,6 +792,189 @@ std::shared_ptr Catalog::GetTableObject( return table_object; } +//===--------------------------------------------------------------------===// +// ALTER TABLE +//===--------------------------------------------------------------------===// +/* Helper function for alter table, called internally + */ +ResultType Catalog::AlterTable(oid_t database_oid, oid_t table_oid, + std::unique_ptr new_schema, + concurrency::TransactionContext *txn) { + if (txn == nullptr) + throw CatalogException("Alter table requires transaction"); + try { + auto storage_manager = storage::StorageManager::GetInstance(); + auto database = storage_manager->GetDatabaseWithOid(database_oid); + try { + auto old_table = database->GetTableWithOid(table_oid); + auto old_schema = old_table->GetSchema(); + // TODO: Try and grab table read lock + + // Step 1: build empty table with new schema + bool own_schema = true; + bool adapt_table = false; + auto new_table = storage::TableFactory::GetDataTable( + database_oid, table_oid, + catalog::Schema::CopySchema(new_schema.get()), old_table->GetName(), + DEFAULT_TUPLES_PER_TILEGROUP, own_schema, adapt_table); + + // Step 2: Copy indexes + auto old_index_oids = + IndexCatalog::GetInstance()->GetIndexObjects(table_oid, txn); + for (auto index_oid_pair : old_index_oids) { + oid_t index_oid = index_oid_pair.first; + // delete record in pg_index + IndexCatalog::GetInstance()->DeleteIndex(index_oid, txn); + // Check if all indexed columns still exists + auto old_index = old_table->GetIndexWithOid(index_oid); + bool index_exist = true; + std::vector new_key_attrs; + + for (oid_t column_id : old_index->GetMetadata()->GetKeyAttrs()) { + bool is_found = false; + std::string column_name = old_schema->GetColumn(column_id).GetName(); + oid_t i = 0; + for (auto new_column : new_schema->GetColumns()) { + if (column_name == new_column.GetName()) { + is_found = true; + new_key_attrs.push_back(i); + break; + } + i++; + } + if (!is_found) { + index_exist = false; + break; + } + } + if (!index_exist) continue; + + // construct index on new table + auto index_metadata = new index::IndexMetadata( + old_index->GetName(), index_oid, table_oid, database_oid, + old_index->GetMetadata()->GetIndexType(), + old_index->GetMetadata()->GetIndexConstraintType(), + new_schema.get(), + // catalog::Schema::CopySchema(old_index->GetKeySchema()), + catalog::Schema::CopySchema(new_schema.get(), new_key_attrs), + new_key_attrs, old_index->GetMetadata()->HasUniqueKeys()); + + std::shared_ptr new_index( + index::IndexFactory::GetIndex(index_metadata)); + new_table->AddIndex(new_index); + + // reinsert record into pg_index + IndexCatalog::GetInstance()->InsertIndex( + index_oid, old_index->GetName(), table_oid, + old_index->GetMetadata()->GetIndexType(), + old_index->GetMetadata()->GetIndexConstraintType(), + old_index->GetMetadata()->HasUniqueKeys(), new_key_attrs, + pool_.get(), txn); + } + + std::unique_ptr context( + new executor::ExecutorContext(txn, {})); + // Step 3: build column mapping between old table and new table + // we're using column name as unique identifier + std::vector old_column_ids; + std::unordered_map column_map; + for (oid_t old_column_id = 0; + old_column_id < old_schema->GetColumnCount(); old_column_id++) { + old_column_ids.push_back(old_column_id); + for (oid_t new_column_id = 0; + new_column_id < new_schema->GetColumnCount(); new_column_id++) { + if (old_schema->GetColumn(old_column_id).GetName() == + new_schema->GetColumn(new_column_id).GetName()) { + column_map[new_column_id] = old_column_id; + } + } + } + // Step 4: Get tuples from old table with sequential scan + // TODO: Try to reuse Sequential scan function and insert function in + // abstract catalog + planner::SeqScanPlan seq_scan_node(old_table, nullptr, old_column_ids); + executor::SeqScanExecutor seq_scan_executor(&seq_scan_node, + context.get()); + seq_scan_executor.Init(); + while (seq_scan_executor.Execute()) { + std::unique_ptr result_tile( + seq_scan_executor.GetOutput()); + for (size_t i = 0; i < result_tile->GetTupleCount(); i++) { + // Transform tuple into new schema + std::unique_ptr tuple( + new storage::Tuple(new_schema.get(), true)); + + for (oid_t new_column_id = 0; + new_column_id < new_schema->GetColumnCount(); new_column_id++) { + auto it = column_map.find(new_column_id); + type::Value val; + if (it == column_map.end()) { + // new column, set value to null + val = type::ValueFactory::GetNullValueByType( + new_schema->GetColumn(new_column_id).GetType()); + } else { + // otherwise, copy value in old table + val = result_tile->GetValue(i, it->second); + } + tuple->SetValue(new_column_id, val, pool_.get()); + } + // insert new tuple into new table + planner::InsertPlan node(new_table, std::move(tuple)); + executor::InsertExecutor executor(&node, context.get()); + executor.Init(); + executor.Execute(); + } + } + // Step 5: delete all the column(attribute) records in pg_attribute + // and reinsert them using new schema(column offset needs to change + // accordingly) + catalog::ColumnCatalog::GetInstance()->DeleteColumns(table_oid, txn); + oid_t column_offset = 0; + for (auto new_column : new_schema->GetColumns()) { + catalog::ColumnCatalog::GetInstance()->InsertColumn( + table_oid, new_column.GetName(), column_offset, + new_column.GetOffset(), new_column.GetType(), + new_column.IsInlined(), new_column.GetConstraints(), pool_.get(), + txn); + column_offset++; + } + + // Final step of physical change should be moved to commit time + database->ReplaceTableWithOid(table_oid, new_table); + + // TODO: Record table drop + // txn->RecordDrop(database, old_table); + + // TODO: Release table lock, should be moved to commit time too + } catch (CatalogException &e) { + return ResultType::FAILURE; + } + } catch (CatalogException &e) { + return ResultType::FAILURE; + } + return ResultType::SUCCESS; +} + +ResultType AddColumn(UNUSED_ATTRIBUTE const std::string &database_name, + UNUSED_ATTRIBUTE const std::string &table_name, + UNUSED_ATTRIBUTE const std::vector &columns, + UNUSED_ATTRIBUTE concurrency::TransactionContext *txn); + +ResultType DropColumn(UNUSED_ATTRIBUTE const std::string &database_name, + UNUSED_ATTRIBUTE const std::string &table_name, + UNUSED_ATTRIBUTE const std::vector &columns, + UNUSED_ATTRIBUTE concurrency::TransactionContext *txn); + +ResultType ChangeColumnName( + UNUSED_ATTRIBUTE const std::string &database_name, + UNUSED_ATTRIBUTE const std::string &table_name, + UNUSED_ATTRIBUTE const std::vector &old_columns, + UNUSED_ATTRIBUTE const std::vector &names, + UNUSED_ATTRIBUTE concurrency::TransactionContext *txn) { + LOG_TRACE("Change Column Name"); + return ResultType::SUCCESS; +} + //===--------------------------------------------------------------------===// // DEPRECATED //===--------------------------------------------------------------------===// @@ -1064,11 +1252,11 @@ void Catalog::InitializeFunctions() { /** * decimal functions */ - AddBuiltinFunction( - "abs", {type::TypeId::DECIMAL}, type::TypeId::DECIMAL, internal_lang, - "Abs", function::BuiltInFuncType{OperatorId::Abs, - function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction("abs", {type::TypeId::DECIMAL}, type::TypeId::DECIMAL, + internal_lang, "Abs", + function::BuiltInFuncType{ + OperatorId::Abs, function::DecimalFunctions::_Abs}, + txn); AddBuiltinFunction( "sqrt", {type::TypeId::TINYINT}, type::TypeId::DECIMAL, internal_lang, "Sqrt", function::BuiltInFuncType{OperatorId::Sqrt, @@ -1105,33 +1293,29 @@ void Catalog::InitializeFunctions() { /** * integer functions */ - AddBuiltinFunction( - "abs", {type::TypeId::TINYINT}, type::TypeId::TINYINT, - internal_lang, "Abs", - function::BuiltInFuncType{OperatorId::Abs, - function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction("abs", {type::TypeId::TINYINT}, type::TypeId::TINYINT, + internal_lang, "Abs", + function::BuiltInFuncType{ + OperatorId::Abs, function::DecimalFunctions::_Abs}, + txn); - AddBuiltinFunction( - "abs", {type::TypeId::SMALLINT}, type::TypeId::SMALLINT, - internal_lang, "Abs", - function::BuiltInFuncType{OperatorId::Abs, - function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction("abs", {type::TypeId::SMALLINT}, + type::TypeId::SMALLINT, internal_lang, "Abs", + function::BuiltInFuncType{ + OperatorId::Abs, function::DecimalFunctions::_Abs}, + txn); - AddBuiltinFunction( - "abs", {type::TypeId::INTEGER}, type::TypeId::INTEGER, - internal_lang, "Abs", - function::BuiltInFuncType{OperatorId::Abs, - function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction("abs", {type::TypeId::INTEGER}, type::TypeId::INTEGER, + internal_lang, "Abs", + function::BuiltInFuncType{ + OperatorId::Abs, function::DecimalFunctions::_Abs}, + txn); - AddBuiltinFunction( - "abs", {type::TypeId::BIGINT}, type::TypeId::BIGINT, - internal_lang, "Abs", - function::BuiltInFuncType{OperatorId::Abs, - function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction("abs", {type::TypeId::BIGINT}, type::TypeId::BIGINT, + internal_lang, "Abs", + function::BuiltInFuncType{ + OperatorId::Abs, function::DecimalFunctions::_Abs}, + txn); AddBuiltinFunction( "floor", {type::TypeId::INTEGER}, type::TypeId::DECIMAL, diff --git a/src/include/catalog/catalog.h b/src/include/catalog/catalog.h index f060e26c5bc..b32cea93f33 100644 --- a/src/include/catalog/catalog.h +++ b/src/include/catalog/catalog.h @@ -15,6 +15,7 @@ #include #include "catalog/catalog_defaults.h" +#include "catalog/column_catalog.h" #include "function/functions.h" namespace peloton { @@ -176,6 +177,30 @@ class Catalog { std::shared_ptr GetTableObject( oid_t database_oid, oid_t table_oid, concurrency::TransactionContext *txn); + + //===--------------------------------------------------------------------===// + // ALTER TABLE + //===--------------------------------------------------------------------===// + ResultType AlterTable(oid_t database_oid, oid_t table_oid, + std::unique_ptr new_schema, + concurrency::TransactionContext *txn); + + ResultType AddColumn(const std::string &database_name, + const std::string &table_name, + const std::vector &columns, + concurrency::TransactionContext *txn); + + ResultType DropColumn(const std::string &database_name, + const std::string &table_name, + const std::vector &columns, + concurrency::TransactionContext *txn); + + ResultType ChangeColumnName(const std::string &database_name, + const std::string &table_name, + const std::vector &old_columns, + const std::vector &names, + concurrency::TransactionContext *txn); + //===--------------------------------------------------------------------===// // DEPRECATED FUNCTIONS //===--------------------------------------------------------------------===// diff --git a/src/include/storage/database.h b/src/include/storage/database.h index d8eca8a4373..82412d8582b 100644 --- a/src/include/storage/database.h +++ b/src/include/storage/database.h @@ -72,6 +72,9 @@ class Database : public Printable { std::string GetDBName(); void setDBName(const std::string &database_name); + storage::DataTable *ReplaceTableWithOid(const oid_t table_oid, + storage::DataTable *new_table); + protected: //===--------------------------------------------------------------------===// // MEMBERS diff --git a/src/storage/database.cpp b/src/storage/database.cpp index 705ad42916e..a7ea96dab93 100644 --- a/src/storage/database.cpp +++ b/src/storage/database.cpp @@ -184,5 +184,25 @@ void Database::setDBName(const std::string &database_name) { Database::database_name = database_name; } +storage::DataTable *Database::ReplaceTableWithOid( + const oid_t table_oid, storage::DataTable *new_table) { + { + std::lock_guard lock(database_mutex); + + oid_t table_offset = 0; + for (auto table : tables) { + if (table->GetOid() == table_oid) { + break; + } + table_offset++; + } + PL_ASSERT(table_offset < tables.size()); + + auto old_table = tables.at(table_offset); + tables[table_offset] = new_table; + return old_table; + } +} + } // namespace storage } // namespace peloton From f015e94c4e41629b54aa7dc6e93e4db7902083de Mon Sep 17 00:00:00 2001 From: Shangjie Chen Date: Thu, 5 Apr 2018 16:29:00 +0000 Subject: [PATCH 02/58] add change column catalog --- src/catalog/catalog.cpp | 63 +++++++++++++++++++++++++---- src/catalog/table_catalog.cpp | 12 +++++- src/include/catalog/schema.h | 6 ++- src/include/catalog/table_catalog.h | 14 ++++--- src/include/storage/tile.h | 4 ++ 5 files changed, 85 insertions(+), 14 deletions(-) diff --git a/src/catalog/catalog.cpp b/src/catalog/catalog.cpp index 3e877afcaee..c4c33011d4c 100644 --- a/src/catalog/catalog.cpp +++ b/src/catalog/catalog.cpp @@ -39,6 +39,7 @@ #include "settings/settings_manager.h" #include "storage/storage_manager.h" #include "storage/table_factory.h" +#include "storage/tile.h" #include "type/ephemeral_pool.h" namespace peloton { @@ -965,13 +966,61 @@ ResultType DropColumn(UNUSED_ATTRIBUTE const std::string &database_name, UNUSED_ATTRIBUTE const std::vector &columns, UNUSED_ATTRIBUTE concurrency::TransactionContext *txn); -ResultType ChangeColumnName( - UNUSED_ATTRIBUTE const std::string &database_name, - UNUSED_ATTRIBUTE const std::string &table_name, - UNUSED_ATTRIBUTE const std::vector &old_columns, - UNUSED_ATTRIBUTE const std::vector &names, - UNUSED_ATTRIBUTE concurrency::TransactionContext *txn) { - LOG_TRACE("Change Column Name"); +ResultType ChangeColumnName(const std::string &database_name, + const std::string &table_name, + const std::vector &old_names, + const std::vector &names, + concurrency::TransactionContext *txn) { + if (txn == nullptr) { + throw CatalogException("Change Column requires transaction."); + } + + if (old_names.size() == 0 || names.size() == 0) { + throw CatalogException("No names are given."); + } + + LOG_TRACE("Change Column Name %s to %s", old_names[0], names[0]); + + try { + // Get table from the name + auto table = Catalog::GetInstance()->GetTableWithName(database_name, + table_name, txn); + auto schema = table->GetSchema(); + + // Currently we only support change the first column name! + + // Check the validity of old name and the new name + oid_t columnId = schema->GetColumnID(names[0]); + if (columnId != INVALID_OID) { + throw CatalogException("New column already exists in the table."); + } + columnId = schema->GetColumnID(old_names[0]); + if (columnId == INVALID_OID) { + throw CatalogException("Old column already exists in the table."); + } + + // Change column name in the global schema + schema->ChangeColumnName(columnId, names[0]); + + // Get all the tiles from the Data Table + for (oid_t i = 0; i < table->GetTileGroupCount(); i++) { + auto tile_group = table->GetTileGroupById(i); + for (oid_t j = 0; j < tile_group->GetTileCount(); j++) { + // Change schema in the tiles + auto tile = tile_group->GetTile(j); + tile->ChangeColumnName(columnId, names[0]); + } + } + + // Change cached column names in the table catalog + auto table_catalog = + Catalog::GetInstance()->GetTableObject(database_name, table_name, txn); + std::vector columns(1, columnId); + table_catalog->ChangeColumnName(columns, names); + + } catch (CastException &e) { + return ResultType::FAILURE; + } return ResultType::SUCCESS; } diff --git a/src/catalog/table_catalog.cpp b/src/catalog/table_catalog.cpp index 49fbaed6db5..39db1bff587 100644 --- a/src/catalog/table_catalog.cpp +++ b/src/catalog/table_catalog.cpp @@ -303,6 +303,15 @@ std::shared_ptr TableCatalogObject::GetColumnObject( return nullptr; } +void TableCatalogObject::ChangeColumnName( + const std::vector &columns, + UNUSED_ATTRIBUTE const std::vector &names) { + // TODO: Change column_names + // TODO: Change column_objects + TableCatalogObject::EvictColumnObject(columns[0]); + return; +} + TableCatalog *TableCatalog::GetInstance(storage::Database *pg_catalog, type::AbstractPool *pool, concurrency::TransactionContext *txn) { @@ -394,7 +403,8 @@ bool TableCatalog::InsertTable(oid_t table_oid, const std::string &table_name, * @param txn TransactionContext * @return Whether deletion is Successful */ -bool TableCatalog::DeleteTable(oid_t table_oid, concurrency::TransactionContext *txn) { +bool TableCatalog::DeleteTable(oid_t table_oid, + concurrency::TransactionContext *txn) { oid_t index_offset = IndexId::PRIMARY_KEY; // Index of table_oid std::vector values; values.push_back(type::ValueFactory::GetIntegerValue(table_oid).Copy()); diff --git a/src/include/catalog/schema.h b/src/include/catalog/schema.h index 8a2feec5dcd..2be14d0eefb 100644 --- a/src/include/catalog/schema.h +++ b/src/include/catalog/schema.h @@ -144,6 +144,10 @@ class Schema : public Printable { return index; } + inline void ChangeColumnName(const oid_t column_id, std::string new_name) { + columns[column_id].column_name = new_name; + } + inline oid_t GetUninlinedColumn(const oid_t column_id) const { return uninlined_columns[column_id]; } @@ -191,7 +195,7 @@ class Schema : public Printable { } // Get the default value for the column - inline type::Value* GetDefaultValue(const oid_t column_id) const { + inline type::Value *GetDefaultValue(const oid_t column_id) const { for (auto constraint : columns[column_id].GetConstraints()) { if (constraint.GetType() == ConstraintType::DEFAULT) { return constraint.getDefaultValue(); diff --git a/src/include/catalog/table_catalog.h b/src/include/catalog/table_catalog.h index 3ef4668d5ca..5e44beeca2e 100644 --- a/src/include/catalog/table_catalog.h +++ b/src/include/catalog/table_catalog.h @@ -45,8 +45,8 @@ class TableCatalogObject { friend class ColumnCatalog; public: - TableCatalogObject(executor::LogicalTile *tile, concurrency::TransactionContext *txn, - int tupleId = 0); + TableCatalogObject(executor::LogicalTile *tile, + concurrency::TransactionContext *txn, int tupleId = 0); public: // Get indexes @@ -71,6 +71,9 @@ class TableCatalogObject { std::shared_ptr GetColumnObject( const std::string &column_name, bool cached_only = false); + void ChangeColumnName(const std::vector &columns, + const std::vector &names); + inline oid_t GetTableOid() { return table_oid; } inline const std::string &GetTableName() { return table_name; } inline oid_t GetDatabaseOid() { return database_oid; } @@ -119,9 +122,10 @@ class TableCatalog : public AbstractCatalog { ~TableCatalog(); // Global Singleton, only the first call requires passing parameters. - static TableCatalog *GetInstance(storage::Database *pg_catalog = nullptr, - type::AbstractPool *pool = nullptr, - concurrency::TransactionContext *txn = nullptr); + static TableCatalog *GetInstance( + storage::Database *pg_catalog = nullptr, + type::AbstractPool *pool = nullptr, + concurrency::TransactionContext *txn = nullptr); inline oid_t GetNextOid() { return oid_++ | TABLE_OID_MASK; } diff --git a/src/include/storage/tile.h b/src/include/storage/tile.h index edb210f868c..958f8769fef 100644 --- a/src/include/storage/tile.h +++ b/src/include/storage/tile.h @@ -139,6 +139,10 @@ class Tile : public Printable { return schema.GetColumn(column_index).GetName(); } + void ChangeColumnName(const oid_t column_index, const std::string name) { + schema.ChangeColumnName(column_index, name); + } + inline oid_t GetColumnCount() const { return column_count; }; inline TileGroupHeader *GetHeader() const { return tile_group_header; } From 583ec6a3a4ae84bc4cf2eaed4399e882226111da Mon Sep 17 00:00:00 2001 From: dingshilun <524768593@qq.com> Date: Thu, 5 Apr 2018 19:17:20 +0000 Subject: [PATCH 03/58] Revert "Merge pull request #1 from DeanChensj/catlog" This reverts commit 6704d0e6ed401377c5c810da3176789f942a360a, reversing changes made to 39fa518996e8923a3577a6be6fc17a2698af9f3c. --- src/catalog/catalog.cpp | 317 ++++------------------------ src/catalog/table_catalog.cpp | 12 +- src/include/catalog/catalog.h | 25 --- src/include/catalog/schema.h | 6 +- src/include/catalog/table_catalog.h | 14 +- src/include/storage/database.h | 3 - src/include/storage/tile.h | 4 - src/storage/database.cpp | 20 -- 8 files changed, 49 insertions(+), 352 deletions(-) diff --git a/src/catalog/catalog.cpp b/src/catalog/catalog.cpp index c4c33011d4c..3ed19e68dc1 100644 --- a/src/catalog/catalog.cpp +++ b/src/catalog/catalog.cpp @@ -26,20 +26,14 @@ #include "catalog/table_metrics_catalog.h" #include "catalog/trigger_catalog.h" #include "concurrency/transaction_manager_factory.h" -#include "executor/executor_context.h" -#include "executor/insert_executor.h" -#include "executor/seq_scan_executor.h" #include "function/date_functions.h" #include "function/decimal_functions.h" #include "function/old_engine_string_functions.h" #include "function/timestamp_functions.h" #include "index/index_factory.h" -#include "planner/seq_scan_plan.h" -#include "planner/insert_plan.h" #include "settings/settings_manager.h" #include "storage/storage_manager.h" #include "storage/table_factory.h" -#include "storage/tile.h" #include "type/ephemeral_pool.h" namespace peloton { @@ -154,12 +148,12 @@ void Catalog::Bootstrap() { DatabaseMetricsCatalog::GetInstance(txn); TableMetricsCatalog::GetInstance(txn); IndexMetricsCatalog::GetInstance(txn); - QueryMetricsCatalog::GetInstance(txn); + QueryMetricsCatalog::GetInstance(txn); SettingsCatalog::GetInstance(txn); TriggerCatalog::GetInstance(txn); LanguageCatalog::GetInstance(txn); ProcCatalog::GetInstance(txn); - + if (settings::SettingsManager::GetBool(settings::SettingId::brain)) { QueryHistoryCatalog::GetInstance(txn); } @@ -620,18 +614,18 @@ ResultType Catalog::DropIndex(oid_t index_oid, ResultType Catalog::DropIndex(const std::string &index_name, concurrency::TransactionContext *txn) { - if (txn == nullptr) { - throw CatalogException("Do not have transaction to drop index " + - index_name); - } - auto index_object = - catalog::IndexCatalog::GetInstance()->GetIndexObject(index_name, txn); - if (index_object == nullptr) { - throw CatalogException("Index name " + index_name + " cannot be found"); - } - ResultType result = DropIndex(index_object->GetIndexOid(), txn); + if(txn == nullptr) { + throw CatalogException("Do not have transaction to drop index " + + index_name); + } + auto index_object = catalog::IndexCatalog::GetInstance()->GetIndexObject( + index_name, txn); + if(index_object == nullptr) { + throw CatalogException("Index name " + index_name + " cannot be found"); + } + ResultType result = DropIndex(index_object->GetIndexOid(), txn); - return result; + return result; } //===--------------------------------------------------------------------===// @@ -793,237 +787,6 @@ std::shared_ptr Catalog::GetTableObject( return table_object; } -//===--------------------------------------------------------------------===// -// ALTER TABLE -//===--------------------------------------------------------------------===// -/* Helper function for alter table, called internally - */ -ResultType Catalog::AlterTable(oid_t database_oid, oid_t table_oid, - std::unique_ptr new_schema, - concurrency::TransactionContext *txn) { - if (txn == nullptr) - throw CatalogException("Alter table requires transaction"); - try { - auto storage_manager = storage::StorageManager::GetInstance(); - auto database = storage_manager->GetDatabaseWithOid(database_oid); - try { - auto old_table = database->GetTableWithOid(table_oid); - auto old_schema = old_table->GetSchema(); - // TODO: Try and grab table read lock - - // Step 1: build empty table with new schema - bool own_schema = true; - bool adapt_table = false; - auto new_table = storage::TableFactory::GetDataTable( - database_oid, table_oid, - catalog::Schema::CopySchema(new_schema.get()), old_table->GetName(), - DEFAULT_TUPLES_PER_TILEGROUP, own_schema, adapt_table); - - // Step 2: Copy indexes - auto old_index_oids = - IndexCatalog::GetInstance()->GetIndexObjects(table_oid, txn); - for (auto index_oid_pair : old_index_oids) { - oid_t index_oid = index_oid_pair.first; - // delete record in pg_index - IndexCatalog::GetInstance()->DeleteIndex(index_oid, txn); - // Check if all indexed columns still exists - auto old_index = old_table->GetIndexWithOid(index_oid); - bool index_exist = true; - std::vector new_key_attrs; - - for (oid_t column_id : old_index->GetMetadata()->GetKeyAttrs()) { - bool is_found = false; - std::string column_name = old_schema->GetColumn(column_id).GetName(); - oid_t i = 0; - for (auto new_column : new_schema->GetColumns()) { - if (column_name == new_column.GetName()) { - is_found = true; - new_key_attrs.push_back(i); - break; - } - i++; - } - if (!is_found) { - index_exist = false; - break; - } - } - if (!index_exist) continue; - - // construct index on new table - auto index_metadata = new index::IndexMetadata( - old_index->GetName(), index_oid, table_oid, database_oid, - old_index->GetMetadata()->GetIndexType(), - old_index->GetMetadata()->GetIndexConstraintType(), - new_schema.get(), - // catalog::Schema::CopySchema(old_index->GetKeySchema()), - catalog::Schema::CopySchema(new_schema.get(), new_key_attrs), - new_key_attrs, old_index->GetMetadata()->HasUniqueKeys()); - - std::shared_ptr new_index( - index::IndexFactory::GetIndex(index_metadata)); - new_table->AddIndex(new_index); - - // reinsert record into pg_index - IndexCatalog::GetInstance()->InsertIndex( - index_oid, old_index->GetName(), table_oid, - old_index->GetMetadata()->GetIndexType(), - old_index->GetMetadata()->GetIndexConstraintType(), - old_index->GetMetadata()->HasUniqueKeys(), new_key_attrs, - pool_.get(), txn); - } - - std::unique_ptr context( - new executor::ExecutorContext(txn, {})); - // Step 3: build column mapping between old table and new table - // we're using column name as unique identifier - std::vector old_column_ids; - std::unordered_map column_map; - for (oid_t old_column_id = 0; - old_column_id < old_schema->GetColumnCount(); old_column_id++) { - old_column_ids.push_back(old_column_id); - for (oid_t new_column_id = 0; - new_column_id < new_schema->GetColumnCount(); new_column_id++) { - if (old_schema->GetColumn(old_column_id).GetName() == - new_schema->GetColumn(new_column_id).GetName()) { - column_map[new_column_id] = old_column_id; - } - } - } - // Step 4: Get tuples from old table with sequential scan - // TODO: Try to reuse Sequential scan function and insert function in - // abstract catalog - planner::SeqScanPlan seq_scan_node(old_table, nullptr, old_column_ids); - executor::SeqScanExecutor seq_scan_executor(&seq_scan_node, - context.get()); - seq_scan_executor.Init(); - while (seq_scan_executor.Execute()) { - std::unique_ptr result_tile( - seq_scan_executor.GetOutput()); - for (size_t i = 0; i < result_tile->GetTupleCount(); i++) { - // Transform tuple into new schema - std::unique_ptr tuple( - new storage::Tuple(new_schema.get(), true)); - - for (oid_t new_column_id = 0; - new_column_id < new_schema->GetColumnCount(); new_column_id++) { - auto it = column_map.find(new_column_id); - type::Value val; - if (it == column_map.end()) { - // new column, set value to null - val = type::ValueFactory::GetNullValueByType( - new_schema->GetColumn(new_column_id).GetType()); - } else { - // otherwise, copy value in old table - val = result_tile->GetValue(i, it->second); - } - tuple->SetValue(new_column_id, val, pool_.get()); - } - // insert new tuple into new table - planner::InsertPlan node(new_table, std::move(tuple)); - executor::InsertExecutor executor(&node, context.get()); - executor.Init(); - executor.Execute(); - } - } - // Step 5: delete all the column(attribute) records in pg_attribute - // and reinsert them using new schema(column offset needs to change - // accordingly) - catalog::ColumnCatalog::GetInstance()->DeleteColumns(table_oid, txn); - oid_t column_offset = 0; - for (auto new_column : new_schema->GetColumns()) { - catalog::ColumnCatalog::GetInstance()->InsertColumn( - table_oid, new_column.GetName(), column_offset, - new_column.GetOffset(), new_column.GetType(), - new_column.IsInlined(), new_column.GetConstraints(), pool_.get(), - txn); - column_offset++; - } - - // Final step of physical change should be moved to commit time - database->ReplaceTableWithOid(table_oid, new_table); - - // TODO: Record table drop - // txn->RecordDrop(database, old_table); - - // TODO: Release table lock, should be moved to commit time too - } catch (CatalogException &e) { - return ResultType::FAILURE; - } - } catch (CatalogException &e) { - return ResultType::FAILURE; - } - return ResultType::SUCCESS; -} - -ResultType AddColumn(UNUSED_ATTRIBUTE const std::string &database_name, - UNUSED_ATTRIBUTE const std::string &table_name, - UNUSED_ATTRIBUTE const std::vector &columns, - UNUSED_ATTRIBUTE concurrency::TransactionContext *txn); - -ResultType DropColumn(UNUSED_ATTRIBUTE const std::string &database_name, - UNUSED_ATTRIBUTE const std::string &table_name, - UNUSED_ATTRIBUTE const std::vector &columns, - UNUSED_ATTRIBUTE concurrency::TransactionContext *txn); - -ResultType ChangeColumnName(const std::string &database_name, - const std::string &table_name, - const std::vector &old_names, - const std::vector &names, - concurrency::TransactionContext *txn) { - if (txn == nullptr) { - throw CatalogException("Change Column requires transaction."); - } - - if (old_names.size() == 0 || names.size() == 0) { - throw CatalogException("No names are given."); - } - - LOG_TRACE("Change Column Name %s to %s", old_names[0], names[0]); - - try { - // Get table from the name - auto table = Catalog::GetInstance()->GetTableWithName(database_name, - table_name, txn); - auto schema = table->GetSchema(); - - // Currently we only support change the first column name! - - // Check the validity of old name and the new name - oid_t columnId = schema->GetColumnID(names[0]); - if (columnId != INVALID_OID) { - throw CatalogException("New column already exists in the table."); - } - columnId = schema->GetColumnID(old_names[0]); - if (columnId == INVALID_OID) { - throw CatalogException("Old column already exists in the table."); - } - - // Change column name in the global schema - schema->ChangeColumnName(columnId, names[0]); - - // Get all the tiles from the Data Table - for (oid_t i = 0; i < table->GetTileGroupCount(); i++) { - auto tile_group = table->GetTileGroupById(i); - for (oid_t j = 0; j < tile_group->GetTileCount(); j++) { - // Change schema in the tiles - auto tile = tile_group->GetTile(j); - tile->ChangeColumnName(columnId, names[0]); - } - } - - // Change cached column names in the table catalog - auto table_catalog = - Catalog::GetInstance()->GetTableObject(database_name, table_name, txn); - std::vector columns(1, columnId); - table_catalog->ChangeColumnName(columns, names); - - } catch (CastException &e) { - return ResultType::FAILURE; - } - return ResultType::SUCCESS; -} - //===--------------------------------------------------------------------===// // DEPRECATED //===--------------------------------------------------------------------===// @@ -1301,11 +1064,11 @@ void Catalog::InitializeFunctions() { /** * decimal functions */ - AddBuiltinFunction("abs", {type::TypeId::DECIMAL}, type::TypeId::DECIMAL, - internal_lang, "Abs", - function::BuiltInFuncType{ - OperatorId::Abs, function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction( + "abs", {type::TypeId::DECIMAL}, type::TypeId::DECIMAL, internal_lang, + "Abs", function::BuiltInFuncType{OperatorId::Abs, + function::DecimalFunctions::_Abs}, + txn); AddBuiltinFunction( "sqrt", {type::TypeId::TINYINT}, type::TypeId::DECIMAL, internal_lang, "Sqrt", function::BuiltInFuncType{OperatorId::Sqrt, @@ -1342,29 +1105,33 @@ void Catalog::InitializeFunctions() { /** * integer functions */ - AddBuiltinFunction("abs", {type::TypeId::TINYINT}, type::TypeId::TINYINT, - internal_lang, "Abs", - function::BuiltInFuncType{ - OperatorId::Abs, function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction( + "abs", {type::TypeId::TINYINT}, type::TypeId::TINYINT, + internal_lang, "Abs", + function::BuiltInFuncType{OperatorId::Abs, + function::DecimalFunctions::_Abs}, + txn); - AddBuiltinFunction("abs", {type::TypeId::SMALLINT}, - type::TypeId::SMALLINT, internal_lang, "Abs", - function::BuiltInFuncType{ - OperatorId::Abs, function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction( + "abs", {type::TypeId::SMALLINT}, type::TypeId::SMALLINT, + internal_lang, "Abs", + function::BuiltInFuncType{OperatorId::Abs, + function::DecimalFunctions::_Abs}, + txn); - AddBuiltinFunction("abs", {type::TypeId::INTEGER}, type::TypeId::INTEGER, - internal_lang, "Abs", - function::BuiltInFuncType{ - OperatorId::Abs, function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction( + "abs", {type::TypeId::INTEGER}, type::TypeId::INTEGER, + internal_lang, "Abs", + function::BuiltInFuncType{OperatorId::Abs, + function::DecimalFunctions::_Abs}, + txn); - AddBuiltinFunction("abs", {type::TypeId::BIGINT}, type::TypeId::BIGINT, - internal_lang, "Abs", - function::BuiltInFuncType{ - OperatorId::Abs, function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction( + "abs", {type::TypeId::BIGINT}, type::TypeId::BIGINT, + internal_lang, "Abs", + function::BuiltInFuncType{OperatorId::Abs, + function::DecimalFunctions::_Abs}, + txn); AddBuiltinFunction( "floor", {type::TypeId::INTEGER}, type::TypeId::DECIMAL, diff --git a/src/catalog/table_catalog.cpp b/src/catalog/table_catalog.cpp index 39db1bff587..49fbaed6db5 100644 --- a/src/catalog/table_catalog.cpp +++ b/src/catalog/table_catalog.cpp @@ -303,15 +303,6 @@ std::shared_ptr TableCatalogObject::GetColumnObject( return nullptr; } -void TableCatalogObject::ChangeColumnName( - const std::vector &columns, - UNUSED_ATTRIBUTE const std::vector &names) { - // TODO: Change column_names - // TODO: Change column_objects - TableCatalogObject::EvictColumnObject(columns[0]); - return; -} - TableCatalog *TableCatalog::GetInstance(storage::Database *pg_catalog, type::AbstractPool *pool, concurrency::TransactionContext *txn) { @@ -403,8 +394,7 @@ bool TableCatalog::InsertTable(oid_t table_oid, const std::string &table_name, * @param txn TransactionContext * @return Whether deletion is Successful */ -bool TableCatalog::DeleteTable(oid_t table_oid, - concurrency::TransactionContext *txn) { +bool TableCatalog::DeleteTable(oid_t table_oid, concurrency::TransactionContext *txn) { oid_t index_offset = IndexId::PRIMARY_KEY; // Index of table_oid std::vector values; values.push_back(type::ValueFactory::GetIntegerValue(table_oid).Copy()); diff --git a/src/include/catalog/catalog.h b/src/include/catalog/catalog.h index b32cea93f33..f060e26c5bc 100644 --- a/src/include/catalog/catalog.h +++ b/src/include/catalog/catalog.h @@ -15,7 +15,6 @@ #include #include "catalog/catalog_defaults.h" -#include "catalog/column_catalog.h" #include "function/functions.h" namespace peloton { @@ -177,30 +176,6 @@ class Catalog { std::shared_ptr GetTableObject( oid_t database_oid, oid_t table_oid, concurrency::TransactionContext *txn); - - //===--------------------------------------------------------------------===// - // ALTER TABLE - //===--------------------------------------------------------------------===// - ResultType AlterTable(oid_t database_oid, oid_t table_oid, - std::unique_ptr new_schema, - concurrency::TransactionContext *txn); - - ResultType AddColumn(const std::string &database_name, - const std::string &table_name, - const std::vector &columns, - concurrency::TransactionContext *txn); - - ResultType DropColumn(const std::string &database_name, - const std::string &table_name, - const std::vector &columns, - concurrency::TransactionContext *txn); - - ResultType ChangeColumnName(const std::string &database_name, - const std::string &table_name, - const std::vector &old_columns, - const std::vector &names, - concurrency::TransactionContext *txn); - //===--------------------------------------------------------------------===// // DEPRECATED FUNCTIONS //===--------------------------------------------------------------------===// diff --git a/src/include/catalog/schema.h b/src/include/catalog/schema.h index 2be14d0eefb..8a2feec5dcd 100644 --- a/src/include/catalog/schema.h +++ b/src/include/catalog/schema.h @@ -144,10 +144,6 @@ class Schema : public Printable { return index; } - inline void ChangeColumnName(const oid_t column_id, std::string new_name) { - columns[column_id].column_name = new_name; - } - inline oid_t GetUninlinedColumn(const oid_t column_id) const { return uninlined_columns[column_id]; } @@ -195,7 +191,7 @@ class Schema : public Printable { } // Get the default value for the column - inline type::Value *GetDefaultValue(const oid_t column_id) const { + inline type::Value* GetDefaultValue(const oid_t column_id) const { for (auto constraint : columns[column_id].GetConstraints()) { if (constraint.GetType() == ConstraintType::DEFAULT) { return constraint.getDefaultValue(); diff --git a/src/include/catalog/table_catalog.h b/src/include/catalog/table_catalog.h index 5e44beeca2e..3ef4668d5ca 100644 --- a/src/include/catalog/table_catalog.h +++ b/src/include/catalog/table_catalog.h @@ -45,8 +45,8 @@ class TableCatalogObject { friend class ColumnCatalog; public: - TableCatalogObject(executor::LogicalTile *tile, - concurrency::TransactionContext *txn, int tupleId = 0); + TableCatalogObject(executor::LogicalTile *tile, concurrency::TransactionContext *txn, + int tupleId = 0); public: // Get indexes @@ -71,9 +71,6 @@ class TableCatalogObject { std::shared_ptr GetColumnObject( const std::string &column_name, bool cached_only = false); - void ChangeColumnName(const std::vector &columns, - const std::vector &names); - inline oid_t GetTableOid() { return table_oid; } inline const std::string &GetTableName() { return table_name; } inline oid_t GetDatabaseOid() { return database_oid; } @@ -122,10 +119,9 @@ class TableCatalog : public AbstractCatalog { ~TableCatalog(); // Global Singleton, only the first call requires passing parameters. - static TableCatalog *GetInstance( - storage::Database *pg_catalog = nullptr, - type::AbstractPool *pool = nullptr, - concurrency::TransactionContext *txn = nullptr); + static TableCatalog *GetInstance(storage::Database *pg_catalog = nullptr, + type::AbstractPool *pool = nullptr, + concurrency::TransactionContext *txn = nullptr); inline oid_t GetNextOid() { return oid_++ | TABLE_OID_MASK; } diff --git a/src/include/storage/database.h b/src/include/storage/database.h index 82412d8582b..d8eca8a4373 100644 --- a/src/include/storage/database.h +++ b/src/include/storage/database.h @@ -72,9 +72,6 @@ class Database : public Printable { std::string GetDBName(); void setDBName(const std::string &database_name); - storage::DataTable *ReplaceTableWithOid(const oid_t table_oid, - storage::DataTable *new_table); - protected: //===--------------------------------------------------------------------===// // MEMBERS diff --git a/src/include/storage/tile.h b/src/include/storage/tile.h index 958f8769fef..edb210f868c 100644 --- a/src/include/storage/tile.h +++ b/src/include/storage/tile.h @@ -139,10 +139,6 @@ class Tile : public Printable { return schema.GetColumn(column_index).GetName(); } - void ChangeColumnName(const oid_t column_index, const std::string name) { - schema.ChangeColumnName(column_index, name); - } - inline oid_t GetColumnCount() const { return column_count; }; inline TileGroupHeader *GetHeader() const { return tile_group_header; } diff --git a/src/storage/database.cpp b/src/storage/database.cpp index a7ea96dab93..705ad42916e 100644 --- a/src/storage/database.cpp +++ b/src/storage/database.cpp @@ -184,25 +184,5 @@ void Database::setDBName(const std::string &database_name) { Database::database_name = database_name; } -storage::DataTable *Database::ReplaceTableWithOid( - const oid_t table_oid, storage::DataTable *new_table) { - { - std::lock_guard lock(database_mutex); - - oid_t table_offset = 0; - for (auto table : tables) { - if (table->GetOid() == table_oid) { - break; - } - table_offset++; - } - PL_ASSERT(table_offset < tables.size()); - - auto old_table = tables.at(table_offset); - tables[table_offset] = new_table; - return old_table; - } -} - } // namespace storage } // namespace peloton From 469474bb857b3bfdd5861baf364ee98c1ed53134 Mon Sep 17 00:00:00 2001 From: dingshilun Date: Thu, 5 Apr 2018 16:52:21 -0400 Subject: [PATCH 04/58] This commit added parser support of alter table - added alter and rename plan and statements - modified optimizor to bind db name and make plans - modified parsenodes - added node to string support and vice versa - added nodetransform of alter table --- src/binder/bind_node_visitor.cpp | 6 + src/common/internal_types.cpp | 38 +-- src/include/binder/bind_node_visitor.h | 2 + src/include/common/internal_types.h | 7 +- src/include/common/logger.h | 12 +- src/include/common/sql_node_visitor.h | 6 +- src/include/optimizer/query_node_visitor.h | 2 + .../optimizer/query_to_operator_transformer.h | 2 + src/include/parser/alter_statement.h | 61 +++++ src/include/parser/parsenodes.h | 253 +++++++++++++----- src/include/parser/postgresparser.h | 28 +- .../parser/rename_function_statement.h | 41 +++ src/include/parser/statements.h | 2 + src/include/planner/alter_plan.h | 24 ++ src/include/planner/rename_plan.h | 82 ++++++ src/optimizer/optimizer.cpp | 15 ++ .../query_to_operator_transformer.cpp | 4 + src/parser/postgresparser.cpp | 114 ++++++-- 18 files changed, 583 insertions(+), 116 deletions(-) create mode 100644 src/include/parser/alter_statement.h create mode 100644 src/include/parser/rename_function_statement.h create mode 100644 src/include/planner/alter_plan.h create mode 100644 src/include/planner/rename_plan.h diff --git a/src/binder/bind_node_visitor.cpp b/src/binder/bind_node_visitor.cpp index 3c4b23e0f04..8f3373ddca5 100644 --- a/src/binder/bind_node_visitor.cpp +++ b/src/binder/bind_node_visitor.cpp @@ -187,6 +187,12 @@ void BindNodeVisitor::Visit(parser::DropStatement *node) { void BindNodeVisitor::Visit(parser::PrepareStatement *) {} void BindNodeVisitor::Visit(parser::ExecuteStatement *) {} void BindNodeVisitor::Visit(parser::TransactionStatement *) {} +void BindNodeVisitor::Visit(parser::AlterTableStatement *node) { + node->TryBindDatabaseName(default_database_name_); +} +void BindNodeVisitor::Visit(parser::RenameFuncStatement *node) { + node->TryBindDatabaseName(default_database_name_); +} void BindNodeVisitor::Visit(parser::AnalyzeStatement *node) { node->TryBindDatabaseName(default_database_name_); } diff --git a/src/common/internal_types.cpp b/src/common/internal_types.cpp index 125d719b5d7..ca4fa9e6c41 100644 --- a/src/common/internal_types.cpp +++ b/src/common/internal_types.cpp @@ -575,7 +575,7 @@ std::string QueryTypeToString(QueryType query_type) { return "EXECUTE"; case QueryType::QUERY_SELECT: return "SELECT"; - case QueryType::QUERY_EXPLAIN: + case QueryType::QUERY_EXPLAIN: return "EXPLAIN"; case QueryType::QUERY_OTHER: default: @@ -623,20 +623,18 @@ QueryType StatementTypeToQueryType(StatementType stmt_type, const parser::SQLStatement *sql_stmt) { LOG_TRACE("%s", StatementTypeToString(stmt_type).c_str()); static std::unordered_map> - type_map{ - {StatementType::EXECUTE, QueryType::QUERY_EXECUTE}, - {StatementType::PREPARE, QueryType::QUERY_PREPARE}, - {StatementType::INSERT, QueryType::QUERY_INSERT}, - {StatementType::UPDATE, QueryType::QUERY_UPDATE}, - {StatementType::DELETE, QueryType::QUERY_DELETE}, - {StatementType::COPY, QueryType::QUERY_COPY}, - {StatementType::ANALYZE, QueryType::QUERY_ANALYZE}, - {StatementType::ALTER, QueryType::QUERY_ALTER}, - {StatementType::DROP, QueryType::QUERY_DROP}, - {StatementType::SELECT, QueryType::QUERY_SELECT}, - {StatementType::VARIABLE_SET, QueryType::QUERY_SET}, - {StatementType::EXPLAIN, QueryType::QUERY_EXPLAIN} - }; + type_map{{StatementType::EXECUTE, QueryType::QUERY_EXECUTE}, + {StatementType::PREPARE, QueryType::QUERY_PREPARE}, + {StatementType::INSERT, QueryType::QUERY_INSERT}, + {StatementType::UPDATE, QueryType::QUERY_UPDATE}, + {StatementType::DELETE, QueryType::QUERY_DELETE}, + {StatementType::COPY, QueryType::QUERY_COPY}, + {StatementType::ANALYZE, QueryType::QUERY_ANALYZE}, + {StatementType::ALTER, QueryType::QUERY_ALTER}, + {StatementType::DROP, QueryType::QUERY_DROP}, + {StatementType::SELECT, QueryType::QUERY_SELECT}, + {StatementType::VARIABLE_SET, QueryType::QUERY_SET}, + {StatementType::EXPLAIN, QueryType::QUERY_EXPLAIN}}; QueryType query_type = QueryType::QUERY_OTHER; std::unordered_map>::iterator it = @@ -1383,6 +1381,12 @@ std::string PlanNodeTypeToString(PlanNodeType type) { case PlanNodeType::ANALYZE: { return ("ANALYZE"); } + case PlanNodeType::RENAME: { + return ("RENAME"); + } + case PlanNodeType::ALTER: { + return ("ALTER"); + } default: { throw ConversionException( StringUtil::Format("No string conversion for PlanNodeType value '%d'", @@ -1454,6 +1458,10 @@ PlanNodeType StringToPlanNodeType(const std::string &str) { return PlanNodeType::MOCK; } else if (upper_str == "ANALYZE") { return PlanNodeType::ANALYZE; + } else if (upper_str == "RENAME") { + return PlanNodeType::RENAME; + } else if (upper_str == "ALTER") { + return PlanNodeType::ALTER; } else { throw ConversionException(StringUtil::Format( "No PlanNodeType conversion from string '%s'", upper_str.c_str())); diff --git a/src/include/binder/bind_node_visitor.h b/src/include/binder/bind_node_visitor.h index 9ca09c68693..ab84e5548ac 100644 --- a/src/include/binder/bind_node_visitor.h +++ b/src/include/binder/bind_node_visitor.h @@ -67,6 +67,8 @@ class BindNodeVisitor : public SqlNodeVisitor { void Visit(parser::UpdateStatement *) override; void Visit(parser::CopyStatement *) override; void Visit(parser::AnalyzeStatement *) override; + void Visit(parser::AlterTableStatement *) override; + void Visit(parser::RenameFuncStatement *) override; void Visit(expression::CaseExpression *expr) override; void Visit(expression::SubqueryExpression *expr) override; diff --git a/src/include/common/internal_types.h b/src/include/common/internal_types.h index ab701cea5ea..2ca30eec3d5 100644 --- a/src/include/common/internal_types.h +++ b/src/include/common/internal_types.h @@ -81,7 +81,7 @@ extern int TEST_TUPLES_PER_TILEGROUP; enum class CmpBool { CmpFalse = 0, CmpTrue = 1, - NULL_ = 2 // Note the underscore suffix + NULL_ = 2 // Note the underscore suffix }; //===--------------------------------------------------------------------===// @@ -574,6 +574,8 @@ enum class PlanNodeType { CREATE = 34, POPULATE_INDEX = 35, ANALYZE = 36, + RENAME = 37, + ALTER = 38, // Communication Nodes SEND = 40, @@ -1240,7 +1242,8 @@ enum class DDLType { CREATE, DROP, }; -typedef tbb::concurrent_vector> CreateDropSet; +typedef tbb::concurrent_vector> + CreateDropSet; typedef std::vector> GCObjectSet; //===--------------------------------------------------------------------===// diff --git a/src/include/common/logger.h b/src/include/common/logger.h index 0e912ca21c2..bd57c1f20fd 100644 --- a/src/include/common/logger.h +++ b/src/include/common/logger.h @@ -26,8 +26,8 @@ // Fix for PRId64 (See https://stackoverflow.com/a/18719205) #if defined(__cplusplus) && !defined(__STDC_FORMAT_MACROS) -#define __STDC_FORMAT_MACROS 1 // Not sure where to put this -#endif +#define __STDC_FORMAT_MACROS 1 // Not sure where to put this +#endif #include namespace peloton { @@ -46,7 +46,7 @@ namespace peloton { #define LOG_LOG_TIME_FORMAT "%Y-%m-%d %H:%M:%S" #define LOG_OUTPUT_STREAM stdout - +#define LOG_LEVEL LOG_LEVEL_TRACE // Compile Option #ifndef LOG_LEVEL // TODO : any way to use pragma message in GCC? @@ -178,10 +178,8 @@ inline void outputLogHeader_(const char *file, int line, const char *func, type = "UNKWN"; } // PAVLO: DO NOT CHANGE THIS - ::fprintf(LOG_OUTPUT_STREAM, "%s [%s:%d:%s] %s - ", - time_str, - file, line, func, - type); + ::fprintf(LOG_OUTPUT_STREAM, "%s [%s:%d:%s] %s - ", time_str, file, line, + func, type); } } // namespace peloton diff --git a/src/include/common/sql_node_visitor.h b/src/include/common/sql_node_visitor.h index 96071410adb..53346eb933c 100644 --- a/src/include/common/sql_node_visitor.h +++ b/src/include/common/sql_node_visitor.h @@ -21,6 +21,8 @@ class CreateFunctionStatement; class InsertStatement; class DeleteStatement; class DropStatement; +class RenameFuncStatement; +class AlterTableStatement; class ExplainStatement; class PrepareStatement; class ExecuteStatement; @@ -80,7 +82,9 @@ class SqlNodeVisitor { virtual void Visit(parser::TransactionStatement *) {} virtual void Visit(parser::UpdateStatement *) {} virtual void Visit(parser::CopyStatement *) {} - virtual void Visit(parser::AnalyzeStatement *){}; + virtual void Visit(parser::AnalyzeStatement *) {} + virtual void Visit(parser::AlterTableStatement *) {} + virtual void Visit(parser::RenameFuncStatement *) {} virtual void Visit(parser::ExplainStatement *){}; virtual void Visit(expression::ComparisonExpression *expr); diff --git a/src/include/optimizer/query_node_visitor.h b/src/include/optimizer/query_node_visitor.h index 49dc04ff54f..7f611c63e30 100644 --- a/src/include/optimizer/query_node_visitor.h +++ b/src/include/optimizer/query_node_visitor.h @@ -29,6 +29,8 @@ class CopyStatement; class AnalyzeStatement; class VariableSetStatement; class JoinDefinition; +class RenameFuncStatement; +class AlterTableStatement; struct TableRef; class GroupByDescription; diff --git a/src/include/optimizer/query_to_operator_transformer.h b/src/include/optimizer/query_to_operator_transformer.h index 2ba6bc8e117..7fcd4e59bfb 100644 --- a/src/include/optimizer/query_to_operator_transformer.h +++ b/src/include/optimizer/query_to_operator_transformer.h @@ -63,6 +63,8 @@ class QueryToOperatorTransformer : public SqlNodeVisitor { void Visit(parser::UpdateStatement *op) override; void Visit(parser::CopyStatement *op) override; void Visit(parser::AnalyzeStatement *op) override; + void Visit(parser::RenameFuncStatement *op) override; + void Visit(parser::AlterTableStatement *op) override; void Visit(expression::ComparisonExpression *expr) override; void Visit(expression::OperatorExpression *expr) override; diff --git a/src/include/parser/alter_statement.h b/src/include/parser/alter_statement.h new file mode 100644 index 00000000000..f89a6f116a8 --- /dev/null +++ b/src/include/parser/alter_statement.h @@ -0,0 +1,61 @@ +//===----------------------------------------------------------------------===// +// +// Peloton +// +// alter_function_statement.h +// +// Identification: src/include/parser/alter_function_statement.h +// +// Copyright (c) 2015-17, Carnegie Mellon University Database Group +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include "parser/sql_statement.h" +#include "common/sql_node_visitor.h" + +namespace peloton { +namespace parser { +/** + * @struct AlterTableStatement + * @brief Represents "ALTER TABLE add column COLUMN_NAME COLUMN_TYPE" + */ +class AlterTableStatement : public TableRefStatement { + public: + enum class AlterTableType { INVALID = 0, ADD = 1, DROP = 2 }; + AlterTableStatement(AlterTableType type) + : TableRefStatement(StatementType::ALTER), + type(type), + names(new std::vector) {} + + virtual ~AlterTableStatement() { + // if (columns != nullptr) { + // for (auto col : *columns) delete col; + // delete columns; + // } + if (names != nullptr) { + for (auto name : *names) delete name; + delete names; + } + } + + virtual void Accept(SqlNodeVisitor *v) override { v->Visit(this); } + + const std::string GetInfo(UNUSED_ATTRIBUTE int num_indent) const override { + return std::string{}; + } + + const std::string GetInfo() const override { return std::string{}; } + + AlterTableType type; + + // Dropped columns + std::vector *names; + + // Added columns + // std::vector* columns; +}; + +} // End parser namespace +} // End peloton namespace diff --git a/src/include/parser/parsenodes.h b/src/include/parser/parsenodes.h index bf818ff6b86..7f8523a053a 100644 --- a/src/include/parser/parsenodes.h +++ b/src/include/parser/parsenodes.h @@ -73,7 +73,8 @@ typedef struct Expr { NodeTag type; } Expr; * of the lefthand expression (if any), and operName is the String name of * the combining operator. Also, subselect is a raw parsetree. During parse * analysis, the parser transforms testexpr into a complete boolean expression - * that compares the lefthand value(s) to PARAM_SUBLINK nodes representing the + * that compares the lefthand value(s) to PARAM_SUBLINK nodes representing +*the * output columns of the subselect. And subselect is transformed to a Query. * This is the representation seen in saved rules and in the rewriter. * @@ -89,8 +90,7 @@ typedef struct Expr { NodeTag type; } Expr; * The CTE_SUBLINK case never occurs in actual SubLink nodes, but it is used * in SubPlans generated for WITH subqueries. */ -typedef enum SubLinkType -{ +typedef enum SubLinkType { EXISTS_SUBLINK, ALL_SUBLINK, ANY_SUBLINK, @@ -98,19 +98,17 @@ typedef enum SubLinkType EXPR_SUBLINK, MULTIEXPR_SUBLINK, ARRAY_SUBLINK, - CTE_SUBLINK /* for SubPlans only */ + CTE_SUBLINK /* for SubPlans only */ } SubLinkType; - -typedef struct SubLink -{ - Expr xpr; - SubLinkType subLinkType; /* see above */ - int subLinkId; /* ID (1..n); 0 if not MULTIEXPR */ - Node *testexpr; /* outer-query test for ALL/ANY/ROWCOMPARE */ - List *operName; /* originally specified operator name */ - Node *subselect; /* subselect as Query* or raw parsetree */ - int location; /* token location, or -1 if unknown */ +typedef struct SubLink { + Expr xpr; + SubLinkType subLinkType; /* see above */ + int subLinkId; /* ID (1..n); 0 if not MULTIEXPR */ + Node *testexpr; /* outer-query test for ALL/ANY/ROWCOMPARE */ + List *operName; /* originally specified operator name */ + Node *subselect; /* subselect as Query* or raw parsetree */ + int location; /* token location, or -1 if unknown */ } SubLink; typedef struct BoolExpr { @@ -663,8 +661,8 @@ typedef struct DropStmt { typedef struct DropDatabaseStmt { NodeTag type; - char *dbname; /* name of database to drop */ - bool missing_ok; /* skip error if object is missing? */ + char *dbname; /* name of database to drop */ + bool missing_ok; /* skip error if object is missing? */ } DropDatabaseStmt; typedef struct TruncateStmt { @@ -674,6 +672,141 @@ typedef struct TruncateStmt { DropBehavior behavior; /* RESTRICT or CASCADE behavior */ } TruncateStmt; +/* ---------------------- + * Alter Table + * ---------------------- + */ +typedef struct AlterTableStmt { + NodeTag type; + RangeVar *relation; /* table to work on */ + List *cmds; /* list of subcommands */ + ObjectType relkind; /* type of object */ + bool missing_ok; /* skip error if table missing */ +} AlterTableStmt; + +typedef enum AlterTableType { + AT_AddColumn, /* add column */ + AT_AddColumnRecurse, /* internal to commands/tablecmds.c */ + AT_AddColumnToView, /* implicitly via CREATE OR REPLACE VIEW */ + AT_ColumnDefault, /* alter column default */ + AT_DropNotNull, /* alter column drop not null */ + AT_SetNotNull, /* alter column set not null */ + AT_SetStatistics, /* alter column set statistics */ + AT_SetOptions, /* alter column set ( options ) */ + AT_ResetOptions, /* alter column reset ( options ) */ + AT_SetStorage, /* alter column set storage */ + AT_DropColumn, /* drop column */ + AT_DropColumnRecurse, /* internal to commands/tablecmds.c */ + AT_AddIndex, /* add index */ + AT_ReAddIndex, /* internal to commands/tablecmds.c */ + AT_AddConstraint, /* add constraint */ + AT_AddConstraintRecurse, /* internal to commands/tablecmds.c */ + AT_ReAddConstraint, /* internal to commands/tablecmds.c */ + AT_AlterConstraint, /* alter constraint */ + AT_ValidateConstraint, /* validate constraint */ + AT_ValidateConstraintRecurse, /* internal to commands/tablecmds.c */ + AT_ProcessedConstraint, /* pre-processed add constraint (local in + * parser/parse_utilcmd.c) */ + AT_AddIndexConstraint, /* add constraint using existing index */ + AT_DropConstraint, /* drop constraint */ + AT_DropConstraintRecurse, /* internal to commands/tablecmds.c */ + AT_ReAddComment, /* internal to commands/tablecmds.c */ + AT_AlterColumnType, /* alter column type */ + AT_AlterColumnGenericOptions, /* alter column OPTIONS (...) */ + AT_ChangeOwner, /* change owner */ + AT_ClusterOn, /* CLUSTER ON */ + AT_DropCluster, /* SET WITHOUT CLUSTER */ + AT_SetLogged, /* SET LOGGED */ + AT_SetUnLogged, /* SET UNLOGGED */ + AT_AddOids, /* SET WITH OIDS */ + AT_AddOidsRecurse, /* internal to commands/tablecmds.c */ + AT_DropOids, /* SET WITHOUT OIDS */ + AT_SetTableSpace, /* SET TABLESPACE */ + AT_SetRelOptions, /* SET (...) -- AM specific parameters */ + AT_ResetRelOptions, /* RESET (...) -- AM specific parameters */ + AT_ReplaceRelOptions, /* replace reloption list in its entirety */ + AT_EnableTrig, /* ENABLE TRIGGER name */ + AT_EnableAlwaysTrig, /* ENABLE ALWAYS TRIGGER name */ + AT_EnableReplicaTrig, /* ENABLE REPLICA TRIGGER name */ + AT_DisableTrig, /* DISABLE TRIGGER name */ + AT_EnableTrigAll, /* ENABLE TRIGGER ALL */ + AT_DisableTrigAll, /* DISABLE TRIGGER ALL */ + AT_EnableTrigUser, /* ENABLE TRIGGER USER */ + AT_DisableTrigUser, /* DISABLE TRIGGER USER */ + AT_EnableRule, /* ENABLE RULE name */ + AT_EnableAlwaysRule, /* ENABLE ALWAYS RULE name */ + AT_EnableReplicaRule, /* ENABLE REPLICA RULE name */ + AT_DisableRule, /* DISABLE RULE name */ + AT_AddInherit, /* INHERIT parent */ + AT_DropInherit, /* NO INHERIT parent */ + AT_AddOf, /* OF */ + AT_DropOf, /* NOT OF */ + AT_ReplicaIdentity, /* REPLICA IDENTITY */ + AT_EnableRowSecurity, /* ENABLE ROW SECURITY */ + AT_DisableRowSecurity, /* DISABLE ROW SECURITY */ + AT_ForceRowSecurity, /* FORCE ROW SECURITY */ + AT_NoForceRowSecurity, /* NO FORCE ROW SECURITY */ + AT_GenericOptions /* OPTIONS (...) */ +} AlterTableType; + +typedef struct AlterTableCmd /* one subcommand of an ALTER TABLE */ + { + NodeTag type; + AlterTableType subtype; /* Type of table alteration to apply */ + char *name; /* column, constraint, or trigger to act on, + * or tablespace */ + Node *newowner; /* RoleSpec */ + Node *def; /* definition of new column, index, + * constraint, or parent table */ + DropBehavior behavior; /* RESTRICT or CASCADE for DROP cases */ + bool missing_ok; /* skip error if missing? */ +} AlterTableCmd; + +/* ---------------------- + * Alter Object Rename Statement + * ---------------------- + */ +typedef struct RenameStmt { + NodeTag type; + ObjectType renameType; /* OBJECT_TABLE, OBJECT_COLUMN, etc */ + ObjectType relationType; /* if column name, associated relation type */ + RangeVar *relation; /* in case it's a table */ + List *object; /* in case it's some other object */ + List *objarg; /* argument types, if applicable */ + char *subname; /* name of contained object (column, rule, + * trigger, etc) */ + char *newname; /* the new name */ + DropBehavior behavior; /* RESTRICT or CASCADE behavior */ + bool missing_ok; /* skip error if missing? */ +} RenameStmt; + +/* ---------------------- + * ALTER object SET SCHEMA Statement + * ---------------------- + */ +typedef struct AlterObjectSchemaStmt { + NodeTag type; + ObjectType objectType; /* OBJECT_TABLE, OBJECT_TYPE, etc */ + RangeVar *relation; /* in case it's a table */ + List *object; /* in case it's some other object */ + List *objarg; /* argument types, if applicable */ + char *newschema; /* the new schema */ + bool missing_ok; /* skip error if missing? */ +} AlterObjectSchemaStmt; + +/* ---------------------- + * Alter Object Owner Statement + * ---------------------- + */ +typedef struct AlterOwnerStmt { + NodeTag type; + ObjectType objectType; /* OBJECT_TABLE, OBJECT_TYPE, etc */ + RangeVar *relation; /* in case it's a table */ + List *object; /* in case it's some other object */ + List *objarg; /* argument types, if applicable */ + Node *newowner; /* the new owner */ +} AlterOwnerStmt; + typedef struct ExecuteStmt { NodeTag type; char *name; /* The name of the plan to execute */ @@ -721,47 +854,42 @@ typedef struct CreateDatabaseStmt { List *options; /* List of DefElem nodes */ } CreateDatabaseStmt; -typedef struct CreateSchemaStmt -{ - NodeTag type; - char *schemaname; /* the name of the schema to create */ - Node *authrole; /* the owner of the created schema */ - List *schemaElts; /* schema components (list of parsenodes) */ - bool if_not_exists; /* just do nothing if schema already exists? */ +typedef struct CreateSchemaStmt { + NodeTag type; + char *schemaname; /* the name of the schema to create */ + Node *authrole; /* the owner of the created schema */ + List *schemaElts; /* schema components (list of parsenodes) */ + bool if_not_exists; /* just do nothing if schema already exists? */ } CreateSchemaStmt; -typedef enum RoleSpecType -{ - ROLESPEC_CSTRING, /* role name is stored as a C string */ - ROLESPEC_CURRENT_USER, /* role spec is CURRENT_USER */ - ROLESPEC_SESSION_USER, /* role spec is SESSION_USER */ - ROLESPEC_PUBLIC /* role name is "public" */ +typedef enum RoleSpecType { + ROLESPEC_CSTRING, /* role name is stored as a C string */ + ROLESPEC_CURRENT_USER, /* role spec is CURRENT_USER */ + ROLESPEC_SESSION_USER, /* role spec is SESSION_USER */ + ROLESPEC_PUBLIC /* role name is "public" */ } RoleSpecType; -typedef struct RoleSpec -{ - NodeTag type; - RoleSpecType roletype; /* Type of this rolespec */ - char *rolename; /* filled only for ROLESPEC_CSTRING */ - int location; /* token location, or -1 if unknown */ +typedef struct RoleSpec { + NodeTag type; + RoleSpecType roletype; /* Type of this rolespec */ + char *rolename; /* filled only for ROLESPEC_CSTRING */ + int location; /* token location, or -1 if unknown */ } RoleSpec; -typedef enum ViewCheckOption -{ +typedef enum ViewCheckOption { NO_CHECK_OPTION, LOCAL_CHECK_OPTION, CASCADED_CHECK_OPTION } ViewCheckOption; -typedef struct ViewStmt -{ - NodeTag type; - RangeVar *view; /* the view to be created */ - List *aliases; /* target column names */ - Node *query; /* the SELECT query */ - bool replace; /* replace an existing view? */ - List *options; /* options from WITH clause */ - ViewCheckOption withCheckOption; /* WITH CHECK OPTION */ +typedef struct ViewStmt { + NodeTag type; + RangeVar *view; /* the view to be created */ + List *aliases; /* target column names */ + Node *query; /* the SELECT query */ + bool replace; /* replace an existing view? */ + List *options; /* options from WITH clause */ + ViewCheckOption withCheckOption; /* WITH CHECK OPTION */ } ViewStmt; typedef struct ParamRef { @@ -787,29 +915,26 @@ typedef struct VacuumStmt { List *va_cols; /* list of column names, or NIL for all */ } VacuumStmt; -typedef enum -{ - VAR_SET_VALUE, /* SET var = value */ - VAR_SET_DEFAULT, /* SET var TO DEFAULT */ - VAR_SET_CURRENT, /* SET var FROM CURRENT */ - VAR_SET_MULTI, /* special case for SET TRANSACTION ... */ - VAR_RESET, /* RESET var */ - VAR_RESET_ALL /* RESET ALL */ +typedef enum { + VAR_SET_VALUE, /* SET var = value */ + VAR_SET_DEFAULT, /* SET var TO DEFAULT */ + VAR_SET_CURRENT, /* SET var FROM CURRENT */ + VAR_SET_MULTI, /* special case for SET TRANSACTION ... */ + VAR_RESET, /* RESET var */ + VAR_RESET_ALL /* RESET ALL */ } VariableSetKind; -typedef struct VariableSetStmt -{ - NodeTag type; +typedef struct VariableSetStmt { + NodeTag type; VariableSetKind kind; - char *name; /* variable to be set */ - List *args; /* List of A_Const nodes */ - bool is_local; /* SET LOCAL? */ + char *name; /* variable to be set */ + List *args; /* List of A_Const nodes */ + bool is_local; /* SET LOCAL? */ } VariableSetStmt; -typedef struct VariableShowStmt -{ - NodeTag type; - char *name; +typedef struct VariableShowStmt { + NodeTag type; + char *name; } VariableShowStmt; /// ********** For UDFs *********** /// diff --git a/src/include/parser/postgresparser.h b/src/include/parser/postgresparser.h index decd43d9ee7..9a23517dbeb 100644 --- a/src/include/parser/postgresparser.h +++ b/src/include/parser/postgresparser.h @@ -118,8 +118,8 @@ class PostgresParser { static parser::TableRef *FromTransform(SelectStmt *root); // transform helper for select targets - static std::vector> - *TargetTransform(List *root); + static std::vector> * + TargetTransform(List *root); // transform helper for all expr nodes static expression::AbstractExpression *ExprTransform(Node *root); @@ -167,7 +167,8 @@ class PostgresParser { static parser::OrderDescription *OrderByTransform(List *order); // transform helper for table column definitions - static void ColumnDefTransform(ColumnDef* root, parser::CreateStatement* stmt); + static void ColumnDefTransform(ColumnDef *root, + parser::CreateStatement *stmt); // transform helper for create statements static parser::SQLStatement *CreateTransform(CreateStmt *root); @@ -195,7 +196,8 @@ class PostgresParser { * @param Postgres CreateDatabaseStmt parsenode * @return a peloton CreateStatement node */ - static parser::SQLStatement *CreateDatabaseTransform(CreateDatabaseStmt *root); + static parser::SQLStatement *CreateDatabaseTransform( + CreateDatabaseStmt *root); // transform helper for create schema statements static parser::SQLStatement *CreateSchemaTransform(CreateSchemaStmt *root); @@ -208,8 +210,8 @@ class PostgresParser { // transform helper for ListsTransform (insert multiple rows) static std::vector< - std::vector>> - *ValueListsTransform(List *root); + std::vector>> * + ValueListsTransform(List *root); // transform helper for insert statements static parser::SQLStatement *InsertTransform(InsertStmt *root); @@ -233,8 +235,8 @@ class PostgresParser { static parser::UpdateStatement *UpdateTransform(UpdateStmt *update_stmt); // transform helper for update statement - static std::vector> - *UpdateTargetTransform(List *root); + static std::vector> * + UpdateTargetTransform(List *root); // transform helper for drop statement static parser::DropStatement *DropTransform(DropStmt *root); @@ -282,13 +284,19 @@ class PostgresParser { static parser::CopyStatement *CopyTransform(CopyStmt *root); // transform helper for analyze statement - static parser::AnalyzeStatement *VacuumTransform(VacuumStmt* root); + static parser::AnalyzeStatement *VacuumTransform(VacuumStmt *root); - static parser::VariableSetStatement *VariableSetTransform(VariableSetStmt* root); + static parser::VariableSetStatement *VariableSetTransform( + VariableSetStmt *root); // transform helper for subquery expressions static expression::AbstractExpression *SubqueryExprTransform(SubLink *node); + // transform helper for alter table statement + static parser::AlterTableStatement *AlterTransform(AlterTableStmt *root); + + // transform helper for alter rename statement + static parser::RenameFuncStatement *RenameTransform(RenameStmt *root); }; } // namespace parser diff --git a/src/include/parser/rename_function_statement.h b/src/include/parser/rename_function_statement.h new file mode 100644 index 00000000000..7883322a136 --- /dev/null +++ b/src/include/parser/rename_function_statement.h @@ -0,0 +1,41 @@ +// +// Created by Nevermore on 01/04/2018. +// + +#pragma once + +#include "parser/sql_statement.h" +#include "common/sql_node_visitor.h" + +namespace peloton { +namespace parser { +class RenameFuncStatement : public TableRefStatement { + public: + enum class ObjectType { INVALID = 0, COLUMN = 1 }; + RenameFuncStatement(ObjectType type) + : TableRefStatement(StatementType::RENAME), + type(type), + oldName(nullptr), + newName(nullptr) {} + + virtual ~RenameFuncStatement() { + if (oldName) delete oldName; + if (newName) delete newName; + } + + virtual void Accept(SqlNodeVisitor *v) override { v->Visit(this); } + + const std::string GetInfo(UNUSED_ATTRIBUTE int num_indent) const override { + return std::string{""}; + } + + const std::string GetInfo() const override { return std::string{""}; } + + ObjectType type; + + // the name that needs to be changed + char *oldName; + char *newName; +}; +} +} \ No newline at end of file diff --git a/src/include/parser/statements.h b/src/include/parser/statements.h index 628b708a4c0..e668794a8f5 100644 --- a/src/include/parser/statements.h +++ b/src/include/parser/statements.h @@ -15,6 +15,7 @@ // This is just for convenience #include "analyze_statement.h" +#include "alter_statement.h" #include "copy_statement.h" #include "create_function_statement.h" #include "create_statement.h" @@ -24,6 +25,7 @@ #include "explain_statement.h" #include "insert_statement.h" #include "prepare_statement.h" +#include "rename_function_statement.h" #include "select_statement.h" #include "sql_statement.h" #include "transaction_statement.h" diff --git a/src/include/planner/alter_plan.h b/src/include/planner/alter_plan.h new file mode 100644 index 00000000000..5fd2ce6cb16 --- /dev/null +++ b/src/include/planner/alter_plan.h @@ -0,0 +1,24 @@ +// +// Created by Nevermore on 03/04/2018. +// + +#pragma once +#include "planner/abstract_plan.h" +#include "parser/alter_statement.h" +namespace peloton { + +namespace planner { +class AlterPlan : public AbstractPlan { + public: + AlterPlan() = delete; + explicit AlterPlan(UNUSED_ATTRIBUTE parser::AlterTableStatement *parse_tree) { + LOG_TRACE("%s", parse_tree->GetInfo().c_str()); + } + virtual ~AlterPlan() {} + + virtual PlanNodeType GetPlanNodeType() { return PlanNodeType::ALTER; } + + virtual std::unique_ptr Copy() { return nullptr; } +}; +} +} diff --git a/src/include/planner/rename_plan.h b/src/include/planner/rename_plan.h new file mode 100644 index 00000000000..e48b713ac13 --- /dev/null +++ b/src/include/planner/rename_plan.h @@ -0,0 +1,82 @@ +// +// Created by Nevermore on 03/04/2018. +// + +#pragma once + +#include "planner/abstract_plan.h" +#include "parser/rename_function_statement.h" + +namespace peloton { +namespace planner { +class RenamePlan : public AbstractPlan { + public: + explicit RenamePlan() = delete; + + explicit RenamePlan(parser::RenameFuncStatement *tree) + : AbstractPlan(), + obj_type(tree->type), + table_name_(tree->table_info_->table_name), + db_name_(tree->GetDatabaseName()) { + old_names_.emplace_back(std::string{tree->oldName}); + new_names_.emplace_back(std::string{tree->newName}); + LOG_TRACE("Build rename plan table: %s, db: %s, oldname: %s, new name: %s", + const_cast(table_name_.c_str()), + const_cast(db_name_.c_str()), + const_cast(old_names_[0].c_str()), + const_cast(new_names_[0].c_str())); + } + + RenamePlan(parser::RenameFuncStatement::ObjectType obj_t, std::string tb_name, + std::string db_name, std::vector old_names, + std::vector new_names) + : AbstractPlan(), + old_names_(old_names), + new_names_(new_names), + obj_type(obj_t), + table_name_(tb_name), + db_name_(db_name) {} + + virtual ~RenamePlan() {} + + virtual PlanNodeType GetPlanNodeType() const { return PlanNodeType::RENAME; } + + const std::string GetInfo() const override { + return StringUtil::Format( + "Rename Object %d, old name %s, new name %s, table %s, db %s\n", + this->obj_type, const_cast(this->old_names_[0].c_str()), + const_cast(this->new_names_[0].c_str()), + const_cast(this->table_name_.c_str()), + const_cast(this->db_name_.c_str())); + } + + std::unique_ptr Copy() const { + return std::unique_ptr( + new RenamePlan(this->obj_type, this->table_name_, this->db_name_, + this->old_names_, this->new_names_)); + } + + std::string GetOldName() { return this->old_names_[0]; } + + std::string GetNewName() { return this->new_names_[0]; } + + std::string GetDatabaseName() { return this->db_name_; } + + std::string GetTableName() { return this->table_name_; } + + parser::RenameFuncStatement::ObjectType GetObjectType() { + return this->obj_type; + } + + private: + // those names are corresponding with their indexes + std::vector old_names_; + std::vector new_names_; + + parser::RenameFuncStatement::ObjectType obj_type; + + std::string table_name_; + std::string db_name_; +}; +} +} diff --git a/src/optimizer/optimizer.cpp b/src/optimizer/optimizer.cpp index 0a84013ca7c..bb17abbd634 100644 --- a/src/optimizer/optimizer.cpp +++ b/src/optimizer/optimizer.cpp @@ -41,6 +41,8 @@ #include "planner/populate_index_plan.h" #include "planner/projection_plan.h" #include "planner/seq_scan_plan.h" +#include "planner/alter_plan.h" +#include "planner/rename_plan.h" #include "storage/data_table.h" @@ -145,6 +147,19 @@ unique_ptr Optimizer::HandleDDLStatement( is_ddl_stmt = true; auto stmt_type = tree->GetType(); switch (stmt_type) { + case StatementType::ALTER: { + // TODO (shilun) adding support of Alter + LOG_TRACE("TO BE Implemented..."); + break; + } + case StatementType::RENAME: { + LOG_TRACE("Adding Rename Plan"); + unique_ptr rename_plan( + new planner::RenamePlan((parser::RenameFuncStatement *)tree)); + ddl_plan = move(rename_plan); + LOG_TRACE("plan build complete"); + break; + } case StatementType::DROP: { LOG_TRACE("Adding Drop plan..."); unique_ptr drop_plan( diff --git a/src/optimizer/query_to_operator_transformer.cpp b/src/optimizer/query_to_operator_transformer.cpp index a0c1243472b..5c0725d00a8 100644 --- a/src/optimizer/query_to_operator_transformer.cpp +++ b/src/optimizer/query_to_operator_transformer.cpp @@ -336,6 +336,10 @@ void QueryToOperatorTransformer::Visit( UNUSED_ATTRIBUTE parser::ExecuteStatement *op) {} void QueryToOperatorTransformer::Visit( UNUSED_ATTRIBUTE parser::TransactionStatement *op) {} +void QueryToOperatorTransformer::Visit( + UNUSED_ATTRIBUTE parser::RenameFuncStatement *op) {} +void QueryToOperatorTransformer::Visit( + UNUSED_ATTRIBUTE parser::AlterTableStatement *op) {} void QueryToOperatorTransformer::Visit(parser::UpdateStatement *op) { auto target_table = catalog::Catalog::GetInstance() diff --git a/src/parser/postgresparser.cpp b/src/parser/postgresparser.cpp index 32e7a374e38..2a336fe049f 100644 --- a/src/parser/postgresparser.cpp +++ b/src/parser/postgresparser.cpp @@ -490,9 +490,8 @@ expression::AbstractExpression *PostgresParser::TypeCastTransform( } TypeName *type_name = root->typeName; - char *name = - (reinterpret_cast(type_name->names->tail->data.ptr_value) - ->val.str); + char *name = (reinterpret_cast( + type_name->names->tail->data.ptr_value)->val.str); type::VarlenType temp(StringToTypeId("INVALID")); result = new expression::ConstantValueExpression( temp.CastAs(source_value, ColumnDefinition::StrToValueType(name))); @@ -558,8 +557,8 @@ expression::AbstractExpression *PostgresParser::FuncCallTransform( // This function takes in the whereClause part of a Postgres SelectStmt // parsenode and transfers it into the select_list of a Peloton SelectStatement. // It checks the type of each target and call the corresponding helpers. -std::vector> - *PostgresParser::TargetTransform(List *root) { +std::vector> * +PostgresParser::TargetTransform(List *root) { // Statement like 'SELECT;' cannot detect by postgres parser and would lead to // null list if (root == nullptr) { @@ -865,9 +864,8 @@ expression::AbstractExpression *PostgresParser::WhenTransform(Node *root) { void PostgresParser::ColumnDefTransform(ColumnDef *root, parser::CreateStatement *stmt) { TypeName *type_name = root->typeName; - char *name = - (reinterpret_cast(type_name->names->tail->data.ptr_value) - ->val.str); + char *name = (reinterpret_cast( + type_name->names->tail->data.ptr_value)->val.str); parser::ColumnDefinition *result = nullptr; parser::ColumnDefinition::DataType data_type = @@ -1055,9 +1053,8 @@ parser::FuncParameter *PostgresParser::FunctionParameterTransform( FunctionParameter *root) { parser::FuncParameter::DataType data_type; TypeName *type_name = root->argType; - char *name = - (reinterpret_cast(type_name->names->tail->data.ptr_value) - ->val.str); + char *name = (reinterpret_cast( + type_name->names->tail->data.ptr_value)->val.str); parser::FuncParameter *result = nullptr; // Transform parameter type @@ -1515,8 +1512,8 @@ std::vector *PostgresParser::ColumnNameTransform(List *root) { // parsenode and transfers it into Peloton AbstractExpression. // This is a vector pointer of vector pointers because one InsertStmt can insert // multiple tuples. -std::vector>> - *PostgresParser::ValueListsTransform(List *root) { +std::vector>> * +PostgresParser::ValueListsTransform(List *root) { auto result = new std::vector< std::vector>>(); @@ -1627,8 +1624,8 @@ parser::SQLStatement *PostgresParser::InsertTransform(InsertStmt *root) { result = new parser::InsertStatement(InsertType::VALUES); PELOTON_ASSERT(select_stmt->valuesLists != NULL); - std::vector>> - *insert_values = nullptr; + std::vector>> * + insert_values = nullptr; try { insert_values = ValueListsTransform(select_stmt->valuesLists); } catch (Exception e) { @@ -1732,6 +1729,82 @@ parser::TransactionStatement *PostgresParser::TransactionTransform( } } +parser::AlterTableStatement *PostgresParser::AlterTransform( + AlterTableStmt *root) { + // TODO (shilun) adding alter type check + parser::AlterTableStatement *result = new AlterTableStatement( + parser::AlterTableStatement::AlterTableType::INVALID); + + // Get database and table name + RangeVar *relation = root->relation; + result->table_info_ = + std::unique_ptr(new parser::TableInfo()); + if (relation->relname) { + result->table_info_->table_name = strdup(relation->relname); + } + if (relation->catalogname) { + result->table_info_->database_name = strdup(relation->catalogname); + } + + for (auto cell = root->cmds->head; cell != NULL; cell = cell->next) { + auto cmd = reinterpret_cast(cell->data.ptr_value); + switch (cmd->subtype) { + /*case AT_AddColumn: { + auto column = + ColumnDefTransform(reinterpret_cast(cmd->def)); + result->columns->push_back(column); + break; + } + case AT_DropColumn: + result->names->push_back(strdup(cmd->name)); + break; + case AT_AlterColumnGenericOptions:*/ + default: { + throw NotImplementedException(StringUtil::Format( + "Alter Table type %d not supported yet...\n", cmd->subtype)); + } + } + } + return result; +} + +/** + * RenameTransorm - right now we only support + * ALTER TABLE [ ONLY ] name [ * ] + RENAME [ COLUMN ] column TO new_column + * @param root + * @return + */ +parser::RenameFuncStatement *PostgresParser::RenameTransform(RenameStmt *root) { + if (root->renameType != ObjectType::OBJECT_COLUMN) { + throw NotImplementedException(StringUtil::Format( + "Rename type %d not supported yes...\n", root->relationType)); + } + parser::RenameFuncStatement *result = new parser::RenameFuncStatement( + parser::RenameFuncStatement::ObjectType::COLUMN); + RangeVar *relation = root->relation; + result->table_info_ = + std::unique_ptr(new parser::TableInfo()); + if (relation->relname) { + result->table_info_->table_name = strdup(relation->relname); + LOG_TRACE("root->relname: %s", relation->relname); + } + if (relation->catalogname) { + result->table_info_->database_name = strdup(relation->catalogname); + LOG_TRACE("root->catalogname: %s", relation->catalogname); + } + if (root->subname) { + result->oldName = strdup(root->subname); + LOG_TRACE("root->subname: %s", root->subname); + } + if (root->newname) { + result->newName = strdup(root->newname); + LOG_TRACE("root->newname: %s", root->newname); + } + LOG_TRACE("finished transform"); + return result; +} + // This function transfers a single Postgres statement into // a Peloton SQLStatement object. It checks the type of // Postgres parsenode of the input and call the corresponding @@ -1739,6 +1812,13 @@ parser::TransactionStatement *PostgresParser::TransactionTransform( parser::SQLStatement *PostgresParser::NodeTransform(Node *stmt) { parser::SQLStatement *result = nullptr; switch (stmt->type) { + case T_AlterTableStmt: + // TODO (Shilun): adding T_ALTER_TABLE_STMT + result = AlterTransform(reinterpret_cast(stmt)); + break; + case T_RenameStmt: + result = RenameTransform(reinterpret_cast(stmt)); + break; case T_SelectStmt: result = SelectTransform(reinterpret_cast(stmt)); break; @@ -1843,8 +1923,8 @@ parser::SQLStatementList *PostgresParser::ListTransform(List *root) { return result; } -std::vector> - *PostgresParser::UpdateTargetTransform(List *root) { +std::vector> * +PostgresParser::UpdateTargetTransform(List *root) { auto result = new std::vector>(); for (auto cell = root->head; cell != NULL; cell = cell->next) { auto update_clause = new UpdateClause(); From 7b2ae56c0781c7181e8a51fc094a57f70f503188 Mon Sep 17 00:00:00 2001 From: Shaoxiong Zhang Date: Sat, 7 Apr 2018 10:18:04 -0400 Subject: [PATCH 05/58] add rename column executor --- src/common/internal_types.cpp | 33 +++++++++++++ src/executor/alter_executor.cpp | 70 +++++++++++++++++++++++++++ src/executor/plan_executor.cpp | 6 ++- src/include/common/internal_types.h | 12 +++++ src/include/executor/alter_executor.h | 42 ++++++++++++++++ src/include/executor/executors.h | 1 + src/include/planner/rename_plan.h | 8 +-- 7 files changed, 166 insertions(+), 6 deletions(-) create mode 100644 src/executor/alter_executor.cpp create mode 100644 src/include/executor/alter_executor.h diff --git a/src/common/internal_types.cpp b/src/common/internal_types.cpp index ca4fa9e6c41..412d585307d 100644 --- a/src/common/internal_types.cpp +++ b/src/common/internal_types.cpp @@ -417,6 +417,39 @@ std::ostream &operator<<(std::ostream &os, const DropType &type) { return os; } +std::string AlterTypeToString(AlterType type) { + switch (type) { + case AlterType::INVALID: { + return "INVALID"; + } + case AlterType::RENAME: { + return "RENAME"; + } + default: { + throw ConversionException( + StringUtil::Format("No string conversion for AlterType value '%d'", + static_cast(type))); + } + } +} + +AlterType StringToAlterType(const std::string &str) { + std::string upper_str = StringUtil::Upper(str); + if (upper_str == "INVALID") { + return AlterType::INVALID; + } else if (upper_str == "RENAME") { + return AlterType::RENAME; + } else { + throw ConversionException(StringUtil::Format( + "No AlterType conversion from string '%s'", upper_str.c_str())); + } + return AlterType::INVALID; +} +std::ostream &operator<<(std::ostream &os, const AlterType &type) { + os << AlterTypeToString(type); + return os; +} + //===--------------------------------------------------------------------===// // Statement - String Utilities //===--------------------------------------------------------------------===// diff --git a/src/executor/alter_executor.cpp b/src/executor/alter_executor.cpp new file mode 100644 index 00000000000..ca85339719a --- /dev/null +++ b/src/executor/alter_executor.cpp @@ -0,0 +1,70 @@ +#include "executor/alter_executor.h" + +#include "catalog/catalog.h" +#include "common/logger.h" +#include "executor/executor_context.h" + +namespace peloton { +namespace executor { + +// Constructor for alter table executor +AlterExecutor::AlterExecutor(const planner::AbstractPlan *node, + ExecutorContext *executor_context) + : AbstractExecutor(node, executor_context) { + context_ = executor_context; +} + +// Initialize executor +// Nothing to initialize for now +bool AlterExecutor::DInit() { + LOG_TRACE("Initializing Alter Executer..."); + + LOG_TRACE("Alter Executor initialized!"); + return true; +} + +bool AlterExecutor::DExecute() { + LOG_TRACE("Executing Drop..."); + bool result = false; + const planner::RenamePlan &node = GetPlanNode(); + auto current_txn = context_->GetTransaction(); + PlanNodeType plan_node_type = node.GetPlanNodeType(); + if (plan_node_type == PlanNodeType::RENAME) { + result = RenameColumn(node, current_txn); + } else if (plan_node_type == PlanNodeType::ALTER) { + LOG_TRACE("Will perform alter table operations"); + } else { + throw NotImplementedException( + StringUtil::Format("Plan node type not supported, %s", + PlanNodeTypeToString(plan_node_type).c_str())); + } + + return result; +} + +bool AlterExecutor::RenameColumn( + const peloton::planner::RenamePlan &node, + peloton::concurrency::TransactionContext *txn) { + auto database_name = node.GetDatabaseName(); + auto table_name = node.GetTableName(); + auto new_column_name = node.GetNewName(); + auto old_column_name = node.GetOldName(); + + std::vector old_names = {old_column_name}; + std::vector names = {new_column_name}; + ResultType result = catalog::Catalog::GetInstance()->ChangeColumnName( + database_name, table_name, old_names, names, txn); + txn->SetResult(result); + + if (txn->GetResult() == ResultType::SUCCESS) { + LOG_TRACE("Rename column succeeded!"); + + // Add on succeed logic if necessary + } else { + LOG_TRACE("Result is: %s", ResultTypeToString(txn->GetResult()).c_str()); + } + return false; +} + +} // executor +} // peloton diff --git a/src/executor/plan_executor.cpp b/src/executor/plan_executor.cpp index 104aff1351c..855de14d498 100644 --- a/src/executor/plan_executor.cpp +++ b/src/executor/plan_executor.cpp @@ -64,7 +64,7 @@ static void CompileAndExecutePlan( } auto on_query_result = - [&on_complete, &consumer, plan](executor::ExecutionResult result) { + [&on_complete, &consumer, plan](executor::ExecutionResult result) { std::vector values; for (const auto &tuple : consumer.GetOutputTuples()) { for (uint32_t i = 0; i < tuple.tuple_.size(); i++) { @@ -336,7 +336,9 @@ executor::AbstractExecutor *BuildExecutorTree( child_executor = new executor::PopulateIndexExecutor(plan, executor_context); break; - + case PlanNodeType::RENAME: + child_executor = new executor::AlterExecutor(plan, executor_context); + break; default: LOG_ERROR("Unsupported plan node type : %s", PlanNodeTypeToString(plan_node_type).c_str()); diff --git a/src/include/common/internal_types.h b/src/include/common/internal_types.h index 2ca30eec3d5..5b198050e8e 100644 --- a/src/include/common/internal_types.h +++ b/src/include/common/internal_types.h @@ -639,6 +639,18 @@ std::string DropTypeToString(DropType type); DropType StringToDropType(const std::string &str); std::ostream &operator<<(std::ostream &os, const DropType &type); +//===--------------------------------------------------------------------===// +// Alter Types +//===--------------------------------------------------------------------===// + +enum class AlterType { + INVALID = INVALID_TYPE_ID, // invalid alter type + RENAME = 1, // rename table, column, database... +}; +std::string AlterTypeToString(AlterType type); +AlterType StringToAlterType(const std::string &str); +std::ostream &operator<<(std::ostream &os, const AlterType &type); + template class EnumHash { public: diff --git a/src/include/executor/alter_executor.h b/src/include/executor/alter_executor.h new file mode 100644 index 00000000000..2fd2f5d546d --- /dev/null +++ b/src/include/executor/alter_executor.h @@ -0,0 +1,42 @@ +#pragma once + +#include "concurrency/transaction_context.h" +#include "executor/abstract_executor.h" +#include "planner/alter_plan.h" +#include "planner/rename_plan.h" + +namespace peloton { + +namespace planner { +class AbstractPlan; +} + +namespace executor { + +class AlterExecutor : public AbstractExecutor { + public: + AlterExecutor(const AlterExecutor &) = delete; + AlterExecutor &operator=(const AlterExecutor &) = delete; + AlterExecutor(AlterExecutor &&) = delete; + AlterExecutor &operator=(AlterExecutor &&) = delete; + + AlterExecutor(const planner::AbstractPlan *node, + ExecutorContext *executor_context); + + ~AlterExecutor() {} + + protected: + bool DInit(); + + bool DExecute(); + + bool RenameColumn(const planner::RenamePlan &node, + concurrency::TransactionContext *txn); + + private: + ExecutorContext *context_; +}; + +} // executor + +} // namespace peloton \ No newline at end of file diff --git a/src/include/executor/executors.h b/src/include/executor/executors.h index 16614120444..8dd5e51bc46 100644 --- a/src/include/executor/executors.h +++ b/src/include/executor/executors.h @@ -38,3 +38,4 @@ #include "executor/projection_executor.h" #include "executor/seq_scan_executor.h" #include "executor/update_executor.h" +#include "executor/alter_executor.h" diff --git a/src/include/planner/rename_plan.h b/src/include/planner/rename_plan.h index e48b713ac13..51c45c0b704 100644 --- a/src/include/planner/rename_plan.h +++ b/src/include/planner/rename_plan.h @@ -56,13 +56,13 @@ class RenamePlan : public AbstractPlan { this->old_names_, this->new_names_)); } - std::string GetOldName() { return this->old_names_[0]; } + std::string GetOldName() const { return this->old_names_[0]; } - std::string GetNewName() { return this->new_names_[0]; } + std::string GetNewName() const { return this->new_names_[0]; } - std::string GetDatabaseName() { return this->db_name_; } + std::string GetDatabaseName() const { return this->db_name_; } - std::string GetTableName() { return this->table_name_; } + std::string GetTableName() const { return this->table_name_; } parser::RenameFuncStatement::ObjectType GetObjectType() { return this->obj_type; From f255f783c6bbb5186ec989d5c4a889514277da17 Mon Sep 17 00:00:00 2001 From: Shangjie Chen Date: Fri, 6 Apr 2018 01:14:53 +0000 Subject: [PATCH 06/58] Catalog for change column name --- src/catalog/catalog.cpp | 181 ++++++++++++++++++++++++++-------- src/include/catalog/catalog.h | 24 +++++ src/include/catalog/schema.h | 7 +- src/include/storage/tile.h | 5 + 4 files changed, 174 insertions(+), 43 deletions(-) diff --git a/src/catalog/catalog.cpp b/src/catalog/catalog.cpp index 3ed19e68dc1..c5d3d5df297 100644 --- a/src/catalog/catalog.cpp +++ b/src/catalog/catalog.cpp @@ -26,6 +26,7 @@ #include "catalog/table_metrics_catalog.h" #include "catalog/trigger_catalog.h" #include "concurrency/transaction_manager_factory.h" +#include "executor/executor_context.h" #include "function/date_functions.h" #include "function/decimal_functions.h" #include "function/old_engine_string_functions.h" @@ -34,6 +35,7 @@ #include "settings/settings_manager.h" #include "storage/storage_manager.h" #include "storage/table_factory.h" +#include "storage/tile.h" #include "type/ephemeral_pool.h" namespace peloton { @@ -148,12 +150,12 @@ void Catalog::Bootstrap() { DatabaseMetricsCatalog::GetInstance(txn); TableMetricsCatalog::GetInstance(txn); IndexMetricsCatalog::GetInstance(txn); - QueryMetricsCatalog::GetInstance(txn); + QueryMetricsCatalog::GetInstance(txn); SettingsCatalog::GetInstance(txn); TriggerCatalog::GetInstance(txn); LanguageCatalog::GetInstance(txn); ProcCatalog::GetInstance(txn); - + if (settings::SettingsManager::GetBool(settings::SettingId::brain)) { QueryHistoryCatalog::GetInstance(txn); } @@ -614,18 +616,18 @@ ResultType Catalog::DropIndex(oid_t index_oid, ResultType Catalog::DropIndex(const std::string &index_name, concurrency::TransactionContext *txn) { - if(txn == nullptr) { - throw CatalogException("Do not have transaction to drop index " + - index_name); - } - auto index_object = catalog::IndexCatalog::GetInstance()->GetIndexObject( - index_name, txn); - if(index_object == nullptr) { - throw CatalogException("Index name " + index_name + " cannot be found"); - } - ResultType result = DropIndex(index_object->GetIndexOid(), txn); + if (txn == nullptr) { + throw CatalogException("Do not have transaction to drop index " + + index_name); + } + auto index_object = + catalog::IndexCatalog::GetInstance()->GetIndexObject(index_name, txn); + if (index_object == nullptr) { + throw CatalogException("Index name " + index_name + " cannot be found"); + } + ResultType result = DropIndex(index_object->GetIndexOid(), txn); - return result; + return result; } //===--------------------------------------------------------------------===// @@ -787,6 +789,105 @@ std::shared_ptr Catalog::GetTableObject( return table_object; } +//===--------------------------------------------------------------------===// +// ALTER TABLE +//===--------------------------------------------------------------------===// +/* Helper function for alter table, called internally + */ +ResultType Catalog::AlterTable( + UNUSED_ATTRIBUTE oid_t database_oid, UNUSED_ATTRIBUTE oid_t table_oid, + UNUSED_ATTRIBUTE std::unique_ptr new_schema, + UNUSED_ATTRIBUTE concurrency::TransactionContext *txn) { + LOG_TRACE("AlterTable in Catalog"); + + // TODO: perform AlterTable Operation + return ResultType::SUCCESS; +} + +ResultType Catalog::AddColumn( + UNUSED_ATTRIBUTE const std::string &database_name, + UNUSED_ATTRIBUTE const std::string &table_name, + UNUSED_ATTRIBUTE const std::vector &columns, + UNUSED_ATTRIBUTE concurrency::TransactionContext *txn) { + return ResultType::SUCCESS; +} + +ResultType Catalog::DropColumn( + UNUSED_ATTRIBUTE const std::string &database_name, + UNUSED_ATTRIBUTE const std::string &table_name, + UNUSED_ATTRIBUTE const std::vector &columns, + UNUSED_ATTRIBUTE concurrency::TransactionContext *txn) { + return ResultType::SUCCESS; +} + +ResultType Catalog::ChangeColumnName(const std::string &database_name, + const std::string &table_name, + const std::vector &old_names, + const std::vector &names, + concurrency::TransactionContext *txn) { + if (txn == nullptr) { + throw CatalogException("Change Column requires transaction."); + } + + if (old_names.size() == 0 || names.size() == 0) { + throw CatalogException("No names are given."); + } + + LOG_TRACE("Change Column Name %s to %s", old_names[0].c_str(), + names[0].c_str()); + + try { + // Get table from the name + auto table = Catalog::GetInstance()->GetTableWithName(database_name, + table_name, txn); + auto schema = table->GetSchema(); + + // Currently we only support change the first column name! + + // Check the validity of old name and the new name + oid_t columnId = schema->GetColumnID(names[0]); + if (columnId != INVALID_OID) { + throw CatalogException("New column already exists in the table."); + } + columnId = schema->GetColumnID(old_names[0]); + if (columnId == INVALID_OID) { + throw CatalogException("Old column does not exist in the table."); + } + + // Change column name in the global schema + schema->ChangeColumnName(columnId, names[0]); + + // TODO: verify do we really need doing so + // Modify all the tiles within the Data Table + /* + for (oid_t i = 0; i < table->GetTileGroupCount(); i++) { + auto tile_group = table->GetTileGroup(i); + for (oid_t j = 0; j < tile_group->GetNextTupleSlot(); j++) { + // Change schema in the tiles + auto tile = tile_group->GetTile(j); + tile->ChangeColumnName(columnId, names[0]); + } + } + */ + + // Change cached ColumnCatalog + oid_t table_oid = Catalog::GetInstance() + ->GetTableObject(database_name, table_name, txn) + ->GetTableOid(); + catalog::ColumnCatalog::GetInstance()->DeleteColumn(table_oid, old_names[0], + txn); + auto new_column = schema->GetColumn(columnId); + catalog::ColumnCatalog::GetInstance()->InsertColumn( + table_oid, new_column.GetName(), columnId, new_column.GetOffset(), + new_column.GetType(), new_column.IsInlined(), + new_column.GetConstraints(), pool_.get(), txn); + + } catch (CastException &e) { + return ResultType::FAILURE; + } + return ResultType::SUCCESS; +} + //===--------------------------------------------------------------------===// // DEPRECATED //===--------------------------------------------------------------------===// @@ -1064,11 +1165,11 @@ void Catalog::InitializeFunctions() { /** * decimal functions */ - AddBuiltinFunction( - "abs", {type::TypeId::DECIMAL}, type::TypeId::DECIMAL, internal_lang, - "Abs", function::BuiltInFuncType{OperatorId::Abs, - function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction("abs", {type::TypeId::DECIMAL}, type::TypeId::DECIMAL, + internal_lang, "Abs", + function::BuiltInFuncType{ + OperatorId::Abs, function::DecimalFunctions::_Abs}, + txn); AddBuiltinFunction( "sqrt", {type::TypeId::TINYINT}, type::TypeId::DECIMAL, internal_lang, "Sqrt", function::BuiltInFuncType{OperatorId::Sqrt, @@ -1105,33 +1206,29 @@ void Catalog::InitializeFunctions() { /** * integer functions */ - AddBuiltinFunction( - "abs", {type::TypeId::TINYINT}, type::TypeId::TINYINT, - internal_lang, "Abs", - function::BuiltInFuncType{OperatorId::Abs, - function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction("abs", {type::TypeId::TINYINT}, type::TypeId::TINYINT, + internal_lang, "Abs", + function::BuiltInFuncType{ + OperatorId::Abs, function::DecimalFunctions::_Abs}, + txn); - AddBuiltinFunction( - "abs", {type::TypeId::SMALLINT}, type::TypeId::SMALLINT, - internal_lang, "Abs", - function::BuiltInFuncType{OperatorId::Abs, - function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction("abs", {type::TypeId::SMALLINT}, + type::TypeId::SMALLINT, internal_lang, "Abs", + function::BuiltInFuncType{ + OperatorId::Abs, function::DecimalFunctions::_Abs}, + txn); - AddBuiltinFunction( - "abs", {type::TypeId::INTEGER}, type::TypeId::INTEGER, - internal_lang, "Abs", - function::BuiltInFuncType{OperatorId::Abs, - function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction("abs", {type::TypeId::INTEGER}, type::TypeId::INTEGER, + internal_lang, "Abs", + function::BuiltInFuncType{ + OperatorId::Abs, function::DecimalFunctions::_Abs}, + txn); - AddBuiltinFunction( - "abs", {type::TypeId::BIGINT}, type::TypeId::BIGINT, - internal_lang, "Abs", - function::BuiltInFuncType{OperatorId::Abs, - function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction("abs", {type::TypeId::BIGINT}, type::TypeId::BIGINT, + internal_lang, "Abs", + function::BuiltInFuncType{ + OperatorId::Abs, function::DecimalFunctions::_Abs}, + txn); AddBuiltinFunction( "floor", {type::TypeId::INTEGER}, type::TypeId::DECIMAL, diff --git a/src/include/catalog/catalog.h b/src/include/catalog/catalog.h index f060e26c5bc..4092ed90631 100644 --- a/src/include/catalog/catalog.h +++ b/src/include/catalog/catalog.h @@ -176,6 +176,30 @@ class Catalog { std::shared_ptr GetTableObject( oid_t database_oid, oid_t table_oid, concurrency::TransactionContext *txn); + + //===--------------------------------------------------------------------===// + // ALTER TABLE + //===--------------------------------------------------------------------===// + ResultType AlterTable(oid_t database_oid, oid_t table_oid, + std::unique_ptr new_schema, + concurrency::TransactionContext *txn); + + ResultType AddColumn(const std::string &database_name, + const std::string &table_name, + const std::vector &columns, + concurrency::TransactionContext *txn); + + ResultType DropColumn(const std::string &database_name, + const std::string &table_name, + const std::vector &columns, + concurrency::TransactionContext *txn); + + ResultType ChangeColumnName(const std::string &database_name, + const std::string &table_name, + const std::vector &old_columns, + const std::vector &names, + concurrency::TransactionContext *txn); + //===--------------------------------------------------------------------===// // DEPRECATED FUNCTIONS //===--------------------------------------------------------------------===// diff --git a/src/include/catalog/schema.h b/src/include/catalog/schema.h index 8a2feec5dcd..d722a21812c 100644 --- a/src/include/catalog/schema.h +++ b/src/include/catalog/schema.h @@ -144,6 +144,11 @@ class Schema : public Printable { return index; } + inline void ChangeColumnName(const oid_t column_id, + const std::string &new_name) { + columns[column_id].column_name = new_name; + } + inline oid_t GetUninlinedColumn(const oid_t column_id) const { return uninlined_columns[column_id]; } @@ -191,7 +196,7 @@ class Schema : public Printable { } // Get the default value for the column - inline type::Value* GetDefaultValue(const oid_t column_id) const { + inline type::Value *GetDefaultValue(const oid_t column_id) const { for (auto constraint : columns[column_id].GetConstraints()) { if (constraint.GetType() == ConstraintType::DEFAULT) { return constraint.getDefaultValue(); diff --git a/src/include/storage/tile.h b/src/include/storage/tile.h index edb210f868c..adff52f7739 100644 --- a/src/include/storage/tile.h +++ b/src/include/storage/tile.h @@ -139,6 +139,11 @@ class Tile : public Printable { return schema.GetColumn(column_index).GetName(); } + inline void ChangeColumnName(const oid_t column_index, + const std::string &name) { + schema.ChangeColumnName(column_index, name); + } + inline oid_t GetColumnCount() const { return column_count; }; inline TileGroupHeader *GetHeader() const { return tile_group_header; } From fd0cb0bacf3e1345d0622ad88ad3c66be1a2288c Mon Sep 17 00:00:00 2001 From: Shaoxiong Zhang Date: Sun, 8 Apr 2018 01:11:22 -0400 Subject: [PATCH 07/58] resolve comments, add header, TODO, remove context in subclass --- src/common/internal_types.cpp | 1 + src/executor/alter_executor.cpp | 18 ++++++++++++++---- src/include/executor/alter_executor.h | 15 ++++++++++++--- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/common/internal_types.cpp b/src/common/internal_types.cpp index 412d585307d..383a5f95d5f 100644 --- a/src/common/internal_types.cpp +++ b/src/common/internal_types.cpp @@ -418,6 +418,7 @@ std::ostream &operator<<(std::ostream &os, const DropType &type) { } std::string AlterTypeToString(AlterType type) { + // TODO: add other AlterType switch (type) { case AlterType::INVALID: { return "INVALID"; diff --git a/src/executor/alter_executor.cpp b/src/executor/alter_executor.cpp index ca85339719a..49845a14b63 100644 --- a/src/executor/alter_executor.cpp +++ b/src/executor/alter_executor.cpp @@ -1,3 +1,15 @@ +//===----------------------------------------------------------------------===// +// +// Peloton +// +// alter_executor.cpp +// +// Identification: src/executor/alter_executor.cpp +// +// Copyright (c) 2015-2018, Carnegie Mellon University Database Group +// +//===----------------------------------------------------------------------===// + #include "executor/alter_executor.h" #include "catalog/catalog.h" @@ -10,9 +22,7 @@ namespace executor { // Constructor for alter table executor AlterExecutor::AlterExecutor(const planner::AbstractPlan *node, ExecutorContext *executor_context) - : AbstractExecutor(node, executor_context) { - context_ = executor_context; -} + : AbstractExecutor(node, executor_context) {} // Initialize executor // Nothing to initialize for now @@ -27,7 +37,7 @@ bool AlterExecutor::DExecute() { LOG_TRACE("Executing Drop..."); bool result = false; const planner::RenamePlan &node = GetPlanNode(); - auto current_txn = context_->GetTransaction(); + auto current_txn = executor_context_->GetTransaction(); PlanNodeType plan_node_type = node.GetPlanNodeType(); if (plan_node_type == PlanNodeType::RENAME) { result = RenameColumn(node, current_txn); diff --git a/src/include/executor/alter_executor.h b/src/include/executor/alter_executor.h index 2fd2f5d546d..46a58b71cac 100644 --- a/src/include/executor/alter_executor.h +++ b/src/include/executor/alter_executor.h @@ -1,3 +1,15 @@ +//===----------------------------------------------------------------------===// +// +// Peloton +// +// alter_executor.h +// +// Identification: src/include/executor/alter_executor.h +// +// Copyright (c) 2015-2018, Carnegie Mellon University Database Group +// +//===----------------------------------------------------------------------===// + #pragma once #include "concurrency/transaction_context.h" @@ -32,9 +44,6 @@ class AlterExecutor : public AbstractExecutor { bool RenameColumn(const planner::RenamePlan &node, concurrency::TransactionContext *txn); - - private: - ExecutorContext *context_; }; } // executor From a3a7cfa081aee2572273fa40cd790259c487c650 Mon Sep 17 00:00:00 2001 From: Shaoxiong Zhang Date: Sun, 8 Apr 2018 01:24:33 -0400 Subject: [PATCH 08/58] fix --- src/include/executor/alter_executor.h | 2 +- src/include/executor/executors.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/include/executor/alter_executor.h b/src/include/executor/alter_executor.h index 46a58b71cac..d2e271f0f16 100644 --- a/src/include/executor/alter_executor.h +++ b/src/include/executor/alter_executor.h @@ -48,4 +48,4 @@ class AlterExecutor : public AbstractExecutor { } // executor -} // namespace peloton \ No newline at end of file +} // namespace peloton diff --git a/src/include/executor/executors.h b/src/include/executor/executors.h index 8dd5e51bc46..38a0fb606fa 100644 --- a/src/include/executor/executors.h +++ b/src/include/executor/executors.h @@ -16,6 +16,7 @@ #include "executor/aggregate_executor.h" #include "executor/aggregator.h" +#include "executor/alter_executor.h" #include "executor/analyze_executor.h" #include "executor/append_executor.h" #include "executor/copy_executor.h" @@ -38,4 +39,3 @@ #include "executor/projection_executor.h" #include "executor/seq_scan_executor.h" #include "executor/update_executor.h" -#include "executor/alter_executor.h" From 9e07a95a2e696353154914574b65e622b4309fd4 Mon Sep 17 00:00:00 2001 From: Shangjie Chen Date: Mon, 2 Apr 2018 02:01:16 +0000 Subject: [PATCH 09/58] add alter table catalog --- src/catalog/catalog.cpp | 4 ++++ src/include/catalog/catalog.h | 1 + src/include/storage/database.h | 3 +++ src/storage/database.cpp | 20 ++++++++++++++++++++ 4 files changed, 28 insertions(+) diff --git a/src/catalog/catalog.cpp b/src/catalog/catalog.cpp index c5d3d5df297..ffbc2e1f522 100644 --- a/src/catalog/catalog.cpp +++ b/src/catalog/catalog.cpp @@ -27,11 +27,15 @@ #include "catalog/trigger_catalog.h" #include "concurrency/transaction_manager_factory.h" #include "executor/executor_context.h" +#include "executor/insert_executor.h" +#include "executor/seq_scan_executor.h" #include "function/date_functions.h" #include "function/decimal_functions.h" #include "function/old_engine_string_functions.h" #include "function/timestamp_functions.h" #include "index/index_factory.h" +#include "planner/seq_scan_plan.h" +#include "planner/insert_plan.h" #include "settings/settings_manager.h" #include "storage/storage_manager.h" #include "storage/table_factory.h" diff --git a/src/include/catalog/catalog.h b/src/include/catalog/catalog.h index 4092ed90631..3fac448c8fc 100644 --- a/src/include/catalog/catalog.h +++ b/src/include/catalog/catalog.h @@ -15,6 +15,7 @@ #include #include "catalog/catalog_defaults.h" +#include "catalog/column_catalog.h" #include "function/functions.h" namespace peloton { diff --git a/src/include/storage/database.h b/src/include/storage/database.h index d8eca8a4373..82412d8582b 100644 --- a/src/include/storage/database.h +++ b/src/include/storage/database.h @@ -72,6 +72,9 @@ class Database : public Printable { std::string GetDBName(); void setDBName(const std::string &database_name); + storage::DataTable *ReplaceTableWithOid(const oid_t table_oid, + storage::DataTable *new_table); + protected: //===--------------------------------------------------------------------===// // MEMBERS diff --git a/src/storage/database.cpp b/src/storage/database.cpp index 705ad42916e..a7ea96dab93 100644 --- a/src/storage/database.cpp +++ b/src/storage/database.cpp @@ -184,5 +184,25 @@ void Database::setDBName(const std::string &database_name) { Database::database_name = database_name; } +storage::DataTable *Database::ReplaceTableWithOid( + const oid_t table_oid, storage::DataTable *new_table) { + { + std::lock_guard lock(database_mutex); + + oid_t table_offset = 0; + for (auto table : tables) { + if (table->GetOid() == table_oid) { + break; + } + table_offset++; + } + PL_ASSERT(table_offset < tables.size()); + + auto old_table = tables.at(table_offset); + tables[table_offset] = new_table; + return old_table; + } +} + } // namespace storage } // namespace peloton From e695ac27c5b29cf08424f3639f8d481d0cc25dfb Mon Sep 17 00:00:00 2001 From: Shangjie Chen Date: Thu, 5 Apr 2018 16:29:00 +0000 Subject: [PATCH 10/58] add change column catalog --- src/catalog/catalog.cpp | 2 -- src/catalog/table_catalog.cpp | 12 +++++++++++- src/include/catalog/table_catalog.h | 14 +++++++++----- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/catalog/catalog.cpp b/src/catalog/catalog.cpp index ffbc2e1f522..bf8b463b458 100644 --- a/src/catalog/catalog.cpp +++ b/src/catalog/catalog.cpp @@ -27,8 +27,6 @@ #include "catalog/trigger_catalog.h" #include "concurrency/transaction_manager_factory.h" #include "executor/executor_context.h" -#include "executor/insert_executor.h" -#include "executor/seq_scan_executor.h" #include "function/date_functions.h" #include "function/decimal_functions.h" #include "function/old_engine_string_functions.h" diff --git a/src/catalog/table_catalog.cpp b/src/catalog/table_catalog.cpp index 49fbaed6db5..39db1bff587 100644 --- a/src/catalog/table_catalog.cpp +++ b/src/catalog/table_catalog.cpp @@ -303,6 +303,15 @@ std::shared_ptr TableCatalogObject::GetColumnObject( return nullptr; } +void TableCatalogObject::ChangeColumnName( + const std::vector &columns, + UNUSED_ATTRIBUTE const std::vector &names) { + // TODO: Change column_names + // TODO: Change column_objects + TableCatalogObject::EvictColumnObject(columns[0]); + return; +} + TableCatalog *TableCatalog::GetInstance(storage::Database *pg_catalog, type::AbstractPool *pool, concurrency::TransactionContext *txn) { @@ -394,7 +403,8 @@ bool TableCatalog::InsertTable(oid_t table_oid, const std::string &table_name, * @param txn TransactionContext * @return Whether deletion is Successful */ -bool TableCatalog::DeleteTable(oid_t table_oid, concurrency::TransactionContext *txn) { +bool TableCatalog::DeleteTable(oid_t table_oid, + concurrency::TransactionContext *txn) { oid_t index_offset = IndexId::PRIMARY_KEY; // Index of table_oid std::vector values; values.push_back(type::ValueFactory::GetIntegerValue(table_oid).Copy()); diff --git a/src/include/catalog/table_catalog.h b/src/include/catalog/table_catalog.h index 3ef4668d5ca..5e44beeca2e 100644 --- a/src/include/catalog/table_catalog.h +++ b/src/include/catalog/table_catalog.h @@ -45,8 +45,8 @@ class TableCatalogObject { friend class ColumnCatalog; public: - TableCatalogObject(executor::LogicalTile *tile, concurrency::TransactionContext *txn, - int tupleId = 0); + TableCatalogObject(executor::LogicalTile *tile, + concurrency::TransactionContext *txn, int tupleId = 0); public: // Get indexes @@ -71,6 +71,9 @@ class TableCatalogObject { std::shared_ptr GetColumnObject( const std::string &column_name, bool cached_only = false); + void ChangeColumnName(const std::vector &columns, + const std::vector &names); + inline oid_t GetTableOid() { return table_oid; } inline const std::string &GetTableName() { return table_name; } inline oid_t GetDatabaseOid() { return database_oid; } @@ -119,9 +122,10 @@ class TableCatalog : public AbstractCatalog { ~TableCatalog(); // Global Singleton, only the first call requires passing parameters. - static TableCatalog *GetInstance(storage::Database *pg_catalog = nullptr, - type::AbstractPool *pool = nullptr, - concurrency::TransactionContext *txn = nullptr); + static TableCatalog *GetInstance( + storage::Database *pg_catalog = nullptr, + type::AbstractPool *pool = nullptr, + concurrency::TransactionContext *txn = nullptr); inline oid_t GetNextOid() { return oid_++ | TABLE_OID_MASK; } From d843ae34e7becc212dc0159ad94d1cae385b65b6 Mon Sep 17 00:00:00 2001 From: dingshilun <524768593@qq.com> Date: Thu, 5 Apr 2018 19:17:20 +0000 Subject: [PATCH 11/58] Revert "Merge pull request #1 from DeanChensj/catlog" This reverts commit 6704d0e6ed401377c5c810da3176789f942a360a, reversing changes made to 39fa518996e8923a3577a6be6fc17a2698af9f3c. --- src/catalog/catalog.cpp | 83 +++++++++++++++-------------- src/catalog/table_catalog.cpp | 12 +---- src/include/catalog/catalog.h | 1 - src/include/catalog/schema.h | 2 +- src/include/catalog/table_catalog.h | 14 ++--- src/include/storage/database.h | 3 -- src/storage/database.cpp | 20 ------- 7 files changed, 49 insertions(+), 86 deletions(-) diff --git a/src/catalog/catalog.cpp b/src/catalog/catalog.cpp index bf8b463b458..2cb221fd669 100644 --- a/src/catalog/catalog.cpp +++ b/src/catalog/catalog.cpp @@ -32,12 +32,9 @@ #include "function/old_engine_string_functions.h" #include "function/timestamp_functions.h" #include "index/index_factory.h" -#include "planner/seq_scan_plan.h" -#include "planner/insert_plan.h" #include "settings/settings_manager.h" #include "storage/storage_manager.h" #include "storage/table_factory.h" -#include "storage/tile.h" #include "type/ephemeral_pool.h" namespace peloton { @@ -152,12 +149,12 @@ void Catalog::Bootstrap() { DatabaseMetricsCatalog::GetInstance(txn); TableMetricsCatalog::GetInstance(txn); IndexMetricsCatalog::GetInstance(txn); - QueryMetricsCatalog::GetInstance(txn); + QueryMetricsCatalog::GetInstance(txn); SettingsCatalog::GetInstance(txn); TriggerCatalog::GetInstance(txn); LanguageCatalog::GetInstance(txn); ProcCatalog::GetInstance(txn); - + if (settings::SettingsManager::GetBool(settings::SettingId::brain)) { QueryHistoryCatalog::GetInstance(txn); } @@ -618,18 +615,18 @@ ResultType Catalog::DropIndex(oid_t index_oid, ResultType Catalog::DropIndex(const std::string &index_name, concurrency::TransactionContext *txn) { - if (txn == nullptr) { - throw CatalogException("Do not have transaction to drop index " + - index_name); - } - auto index_object = - catalog::IndexCatalog::GetInstance()->GetIndexObject(index_name, txn); - if (index_object == nullptr) { - throw CatalogException("Index name " + index_name + " cannot be found"); - } - ResultType result = DropIndex(index_object->GetIndexOid(), txn); + if(txn == nullptr) { + throw CatalogException("Do not have transaction to drop index " + + index_name); + } + auto index_object = catalog::IndexCatalog::GetInstance()->GetIndexObject( + index_name, txn); + if(index_object == nullptr) { + throw CatalogException("Index name " + index_name + " cannot be found"); + } + ResultType result = DropIndex(index_object->GetIndexOid(), txn); - return result; + return result; } //===--------------------------------------------------------------------===// @@ -1167,11 +1164,11 @@ void Catalog::InitializeFunctions() { /** * decimal functions */ - AddBuiltinFunction("abs", {type::TypeId::DECIMAL}, type::TypeId::DECIMAL, - internal_lang, "Abs", - function::BuiltInFuncType{ - OperatorId::Abs, function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction( + "abs", {type::TypeId::DECIMAL}, type::TypeId::DECIMAL, internal_lang, + "Abs", function::BuiltInFuncType{OperatorId::Abs, + function::DecimalFunctions::_Abs}, + txn); AddBuiltinFunction( "sqrt", {type::TypeId::TINYINT}, type::TypeId::DECIMAL, internal_lang, "Sqrt", function::BuiltInFuncType{OperatorId::Sqrt, @@ -1208,29 +1205,33 @@ void Catalog::InitializeFunctions() { /** * integer functions */ - AddBuiltinFunction("abs", {type::TypeId::TINYINT}, type::TypeId::TINYINT, - internal_lang, "Abs", - function::BuiltInFuncType{ - OperatorId::Abs, function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction( + "abs", {type::TypeId::TINYINT}, type::TypeId::TINYINT, + internal_lang, "Abs", + function::BuiltInFuncType{OperatorId::Abs, + function::DecimalFunctions::_Abs}, + txn); - AddBuiltinFunction("abs", {type::TypeId::SMALLINT}, - type::TypeId::SMALLINT, internal_lang, "Abs", - function::BuiltInFuncType{ - OperatorId::Abs, function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction( + "abs", {type::TypeId::SMALLINT}, type::TypeId::SMALLINT, + internal_lang, "Abs", + function::BuiltInFuncType{OperatorId::Abs, + function::DecimalFunctions::_Abs}, + txn); - AddBuiltinFunction("abs", {type::TypeId::INTEGER}, type::TypeId::INTEGER, - internal_lang, "Abs", - function::BuiltInFuncType{ - OperatorId::Abs, function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction( + "abs", {type::TypeId::INTEGER}, type::TypeId::INTEGER, + internal_lang, "Abs", + function::BuiltInFuncType{OperatorId::Abs, + function::DecimalFunctions::_Abs}, + txn); - AddBuiltinFunction("abs", {type::TypeId::BIGINT}, type::TypeId::BIGINT, - internal_lang, "Abs", - function::BuiltInFuncType{ - OperatorId::Abs, function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction( + "abs", {type::TypeId::BIGINT}, type::TypeId::BIGINT, + internal_lang, "Abs", + function::BuiltInFuncType{OperatorId::Abs, + function::DecimalFunctions::_Abs}, + txn); AddBuiltinFunction( "floor", {type::TypeId::INTEGER}, type::TypeId::DECIMAL, diff --git a/src/catalog/table_catalog.cpp b/src/catalog/table_catalog.cpp index 39db1bff587..49fbaed6db5 100644 --- a/src/catalog/table_catalog.cpp +++ b/src/catalog/table_catalog.cpp @@ -303,15 +303,6 @@ std::shared_ptr TableCatalogObject::GetColumnObject( return nullptr; } -void TableCatalogObject::ChangeColumnName( - const std::vector &columns, - UNUSED_ATTRIBUTE const std::vector &names) { - // TODO: Change column_names - // TODO: Change column_objects - TableCatalogObject::EvictColumnObject(columns[0]); - return; -} - TableCatalog *TableCatalog::GetInstance(storage::Database *pg_catalog, type::AbstractPool *pool, concurrency::TransactionContext *txn) { @@ -403,8 +394,7 @@ bool TableCatalog::InsertTable(oid_t table_oid, const std::string &table_name, * @param txn TransactionContext * @return Whether deletion is Successful */ -bool TableCatalog::DeleteTable(oid_t table_oid, - concurrency::TransactionContext *txn) { +bool TableCatalog::DeleteTable(oid_t table_oid, concurrency::TransactionContext *txn) { oid_t index_offset = IndexId::PRIMARY_KEY; // Index of table_oid std::vector values; values.push_back(type::ValueFactory::GetIntegerValue(table_oid).Copy()); diff --git a/src/include/catalog/catalog.h b/src/include/catalog/catalog.h index 3fac448c8fc..4092ed90631 100644 --- a/src/include/catalog/catalog.h +++ b/src/include/catalog/catalog.h @@ -15,7 +15,6 @@ #include #include "catalog/catalog_defaults.h" -#include "catalog/column_catalog.h" #include "function/functions.h" namespace peloton { diff --git a/src/include/catalog/schema.h b/src/include/catalog/schema.h index d722a21812c..d3d7d33fe27 100644 --- a/src/include/catalog/schema.h +++ b/src/include/catalog/schema.h @@ -196,7 +196,7 @@ class Schema : public Printable { } // Get the default value for the column - inline type::Value *GetDefaultValue(const oid_t column_id) const { + inline type::Value* GetDefaultValue(const oid_t column_id) const { for (auto constraint : columns[column_id].GetConstraints()) { if (constraint.GetType() == ConstraintType::DEFAULT) { return constraint.getDefaultValue(); diff --git a/src/include/catalog/table_catalog.h b/src/include/catalog/table_catalog.h index 5e44beeca2e..3ef4668d5ca 100644 --- a/src/include/catalog/table_catalog.h +++ b/src/include/catalog/table_catalog.h @@ -45,8 +45,8 @@ class TableCatalogObject { friend class ColumnCatalog; public: - TableCatalogObject(executor::LogicalTile *tile, - concurrency::TransactionContext *txn, int tupleId = 0); + TableCatalogObject(executor::LogicalTile *tile, concurrency::TransactionContext *txn, + int tupleId = 0); public: // Get indexes @@ -71,9 +71,6 @@ class TableCatalogObject { std::shared_ptr GetColumnObject( const std::string &column_name, bool cached_only = false); - void ChangeColumnName(const std::vector &columns, - const std::vector &names); - inline oid_t GetTableOid() { return table_oid; } inline const std::string &GetTableName() { return table_name; } inline oid_t GetDatabaseOid() { return database_oid; } @@ -122,10 +119,9 @@ class TableCatalog : public AbstractCatalog { ~TableCatalog(); // Global Singleton, only the first call requires passing parameters. - static TableCatalog *GetInstance( - storage::Database *pg_catalog = nullptr, - type::AbstractPool *pool = nullptr, - concurrency::TransactionContext *txn = nullptr); + static TableCatalog *GetInstance(storage::Database *pg_catalog = nullptr, + type::AbstractPool *pool = nullptr, + concurrency::TransactionContext *txn = nullptr); inline oid_t GetNextOid() { return oid_++ | TABLE_OID_MASK; } diff --git a/src/include/storage/database.h b/src/include/storage/database.h index 82412d8582b..d8eca8a4373 100644 --- a/src/include/storage/database.h +++ b/src/include/storage/database.h @@ -72,9 +72,6 @@ class Database : public Printable { std::string GetDBName(); void setDBName(const std::string &database_name); - storage::DataTable *ReplaceTableWithOid(const oid_t table_oid, - storage::DataTable *new_table); - protected: //===--------------------------------------------------------------------===// // MEMBERS diff --git a/src/storage/database.cpp b/src/storage/database.cpp index a7ea96dab93..705ad42916e 100644 --- a/src/storage/database.cpp +++ b/src/storage/database.cpp @@ -184,25 +184,5 @@ void Database::setDBName(const std::string &database_name) { Database::database_name = database_name; } -storage::DataTable *Database::ReplaceTableWithOid( - const oid_t table_oid, storage::DataTable *new_table) { - { - std::lock_guard lock(database_mutex); - - oid_t table_offset = 0; - for (auto table : tables) { - if (table->GetOid() == table_oid) { - break; - } - table_offset++; - } - PL_ASSERT(table_offset < tables.size()); - - auto old_table = tables.at(table_offset); - tables[table_offset] = new_table; - return old_table; - } -} - } // namespace storage } // namespace peloton From 59e59829b37e7bfe222250f92c51fc7c8d0a868b Mon Sep 17 00:00:00 2001 From: dingshilun Date: Thu, 5 Apr 2018 16:52:21 -0400 Subject: [PATCH 12/58] This commit added parser support of alter table - added alter and rename plan and statements - modified optimizor to bind db name and make plans - modified parsenodes - added node to string support and vice versa - added nodetransform of alter table --- src/include/planner/rename_plan.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/planner/rename_plan.h b/src/include/planner/rename_plan.h index 51c45c0b704..76d0c5aac63 100644 --- a/src/include/planner/rename_plan.h +++ b/src/include/planner/rename_plan.h @@ -55,7 +55,7 @@ class RenamePlan : public AbstractPlan { new RenamePlan(this->obj_type, this->table_name_, this->db_name_, this->old_names_, this->new_names_)); } - + std::string GetOldName() const { return this->old_names_[0]; } std::string GetNewName() const { return this->new_names_[0]; } From dd42a3b911a85f73227a54f1200fdf8ae1c99f3d Mon Sep 17 00:00:00 2001 From: Shaoxiong Zhang Date: Sat, 7 Apr 2018 10:18:04 -0400 Subject: [PATCH 13/58] add rename column executor --- src/executor/alter_executor.cpp | 3 +++ src/include/executor/executors.h | 1 + 2 files changed, 4 insertions(+) diff --git a/src/executor/alter_executor.cpp b/src/executor/alter_executor.cpp index 49845a14b63..d9c408ceffe 100644 --- a/src/executor/alter_executor.cpp +++ b/src/executor/alter_executor.cpp @@ -1,3 +1,4 @@ +<<<<<<< HEAD //===----------------------------------------------------------------------===// // // Peloton @@ -10,6 +11,8 @@ // //===----------------------------------------------------------------------===// +======= +>>>>>>> add rename column executor #include "executor/alter_executor.h" #include "catalog/catalog.h" diff --git a/src/include/executor/executors.h b/src/include/executor/executors.h index 38a0fb606fa..cbc8184b470 100644 --- a/src/include/executor/executors.h +++ b/src/include/executor/executors.h @@ -39,3 +39,4 @@ #include "executor/projection_executor.h" #include "executor/seq_scan_executor.h" #include "executor/update_executor.h" +#include "executor/alter_executor.h" From a8451359aef9d35374b16e694dd291a4b0e14fca Mon Sep 17 00:00:00 2001 From: Shangjie Chen Date: Fri, 6 Apr 2018 01:14:53 +0000 Subject: [PATCH 14/58] Catalog for change column name --- src/catalog/catalog.cpp | 81 +++++++++++++++++------------------- src/include/catalog/schema.h | 2 +- 2 files changed, 40 insertions(+), 43 deletions(-) diff --git a/src/catalog/catalog.cpp b/src/catalog/catalog.cpp index 2cb221fd669..c5d3d5df297 100644 --- a/src/catalog/catalog.cpp +++ b/src/catalog/catalog.cpp @@ -35,6 +35,7 @@ #include "settings/settings_manager.h" #include "storage/storage_manager.h" #include "storage/table_factory.h" +#include "storage/tile.h" #include "type/ephemeral_pool.h" namespace peloton { @@ -149,12 +150,12 @@ void Catalog::Bootstrap() { DatabaseMetricsCatalog::GetInstance(txn); TableMetricsCatalog::GetInstance(txn); IndexMetricsCatalog::GetInstance(txn); - QueryMetricsCatalog::GetInstance(txn); + QueryMetricsCatalog::GetInstance(txn); SettingsCatalog::GetInstance(txn); TriggerCatalog::GetInstance(txn); LanguageCatalog::GetInstance(txn); ProcCatalog::GetInstance(txn); - + if (settings::SettingsManager::GetBool(settings::SettingId::brain)) { QueryHistoryCatalog::GetInstance(txn); } @@ -615,18 +616,18 @@ ResultType Catalog::DropIndex(oid_t index_oid, ResultType Catalog::DropIndex(const std::string &index_name, concurrency::TransactionContext *txn) { - if(txn == nullptr) { - throw CatalogException("Do not have transaction to drop index " + - index_name); - } - auto index_object = catalog::IndexCatalog::GetInstance()->GetIndexObject( - index_name, txn); - if(index_object == nullptr) { - throw CatalogException("Index name " + index_name + " cannot be found"); - } - ResultType result = DropIndex(index_object->GetIndexOid(), txn); + if (txn == nullptr) { + throw CatalogException("Do not have transaction to drop index " + + index_name); + } + auto index_object = + catalog::IndexCatalog::GetInstance()->GetIndexObject(index_name, txn); + if (index_object == nullptr) { + throw CatalogException("Index name " + index_name + " cannot be found"); + } + ResultType result = DropIndex(index_object->GetIndexOid(), txn); - return result; + return result; } //===--------------------------------------------------------------------===// @@ -1164,11 +1165,11 @@ void Catalog::InitializeFunctions() { /** * decimal functions */ - AddBuiltinFunction( - "abs", {type::TypeId::DECIMAL}, type::TypeId::DECIMAL, internal_lang, - "Abs", function::BuiltInFuncType{OperatorId::Abs, - function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction("abs", {type::TypeId::DECIMAL}, type::TypeId::DECIMAL, + internal_lang, "Abs", + function::BuiltInFuncType{ + OperatorId::Abs, function::DecimalFunctions::_Abs}, + txn); AddBuiltinFunction( "sqrt", {type::TypeId::TINYINT}, type::TypeId::DECIMAL, internal_lang, "Sqrt", function::BuiltInFuncType{OperatorId::Sqrt, @@ -1205,33 +1206,29 @@ void Catalog::InitializeFunctions() { /** * integer functions */ - AddBuiltinFunction( - "abs", {type::TypeId::TINYINT}, type::TypeId::TINYINT, - internal_lang, "Abs", - function::BuiltInFuncType{OperatorId::Abs, - function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction("abs", {type::TypeId::TINYINT}, type::TypeId::TINYINT, + internal_lang, "Abs", + function::BuiltInFuncType{ + OperatorId::Abs, function::DecimalFunctions::_Abs}, + txn); - AddBuiltinFunction( - "abs", {type::TypeId::SMALLINT}, type::TypeId::SMALLINT, - internal_lang, "Abs", - function::BuiltInFuncType{OperatorId::Abs, - function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction("abs", {type::TypeId::SMALLINT}, + type::TypeId::SMALLINT, internal_lang, "Abs", + function::BuiltInFuncType{ + OperatorId::Abs, function::DecimalFunctions::_Abs}, + txn); - AddBuiltinFunction( - "abs", {type::TypeId::INTEGER}, type::TypeId::INTEGER, - internal_lang, "Abs", - function::BuiltInFuncType{OperatorId::Abs, - function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction("abs", {type::TypeId::INTEGER}, type::TypeId::INTEGER, + internal_lang, "Abs", + function::BuiltInFuncType{ + OperatorId::Abs, function::DecimalFunctions::_Abs}, + txn); - AddBuiltinFunction( - "abs", {type::TypeId::BIGINT}, type::TypeId::BIGINT, - internal_lang, "Abs", - function::BuiltInFuncType{OperatorId::Abs, - function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction("abs", {type::TypeId::BIGINT}, type::TypeId::BIGINT, + internal_lang, "Abs", + function::BuiltInFuncType{ + OperatorId::Abs, function::DecimalFunctions::_Abs}, + txn); AddBuiltinFunction( "floor", {type::TypeId::INTEGER}, type::TypeId::DECIMAL, diff --git a/src/include/catalog/schema.h b/src/include/catalog/schema.h index d3d7d33fe27..d722a21812c 100644 --- a/src/include/catalog/schema.h +++ b/src/include/catalog/schema.h @@ -196,7 +196,7 @@ class Schema : public Printable { } // Get the default value for the column - inline type::Value* GetDefaultValue(const oid_t column_id) const { + inline type::Value *GetDefaultValue(const oid_t column_id) const { for (auto constraint : columns[column_id].GetConstraints()) { if (constraint.GetType() == ConstraintType::DEFAULT) { return constraint.getDefaultValue(); From 57e9a6e93352d403c44dde6ba57db931642a8920 Mon Sep 17 00:00:00 2001 From: Shaoxiong Zhang Date: Sun, 8 Apr 2018 01:11:22 -0400 Subject: [PATCH 15/58] resolve comments, add header, TODO, remove context in subclass --- src/executor/alter_executor.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/executor/alter_executor.cpp b/src/executor/alter_executor.cpp index d9c408ceffe..49845a14b63 100644 --- a/src/executor/alter_executor.cpp +++ b/src/executor/alter_executor.cpp @@ -1,4 +1,3 @@ -<<<<<<< HEAD //===----------------------------------------------------------------------===// // // Peloton @@ -11,8 +10,6 @@ // //===----------------------------------------------------------------------===// -======= ->>>>>>> add rename column executor #include "executor/alter_executor.h" #include "catalog/catalog.h" From 357504841bcbf00aa8951dd25bed8934b5b1fe81 Mon Sep 17 00:00:00 2001 From: Shaoxiong Zhang Date: Sun, 8 Apr 2018 01:24:33 -0400 Subject: [PATCH 16/58] fix --- src/include/executor/executors.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/include/executor/executors.h b/src/include/executor/executors.h index cbc8184b470..38a0fb606fa 100644 --- a/src/include/executor/executors.h +++ b/src/include/executor/executors.h @@ -39,4 +39,3 @@ #include "executor/projection_executor.h" #include "executor/seq_scan_executor.h" #include "executor/update_executor.h" -#include "executor/alter_executor.h" From 6b5da72dfbd4961560baa61fe246fe725f8442c5 Mon Sep 17 00:00:00 2001 From: Shangjie Chen Date: Sun, 8 Apr 2018 19:58:46 +0000 Subject: [PATCH 17/58] AlterTable init test --- script/testing/junit/AlterTableTest.java | 105 +++++++++++++++++++++++ src/catalog/catalog.cpp | 2 +- 2 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 script/testing/junit/AlterTableTest.java diff --git a/script/testing/junit/AlterTableTest.java b/script/testing/junit/AlterTableTest.java new file mode 100644 index 00000000000..630a93db882 --- /dev/null +++ b/script/testing/junit/AlterTableTest.java @@ -0,0 +1,105 @@ +//===----------------------------------------------------------------------===// +// +// Peloton +// +// AlterTableTest.java +// +// Identification: script/testing/junit/AlterTableTest.java +// +// Copyright (c) 2015-2018, Carnegie Mellon University Database Group +// +//===----------------------------------------------------------------------===// + +import java.sql.*; +import org.junit.*; +import org.junit.rules.ExpectedException; +import org.postgresql.util.PSQLException; + +public class AlterTableTest extends PLTestBase { + private Connection conn; + private String s_sql = "SELECT * FROM foo;"; + + private static final String SQL_DROP_TABLE = + "DROP TABLE IF EXISTS foo;"; + + private static final String SQL_CREATE_TABLE = + "CREATE TABLE foo (" + + "id integer, " + + "year integer);"; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + /** + * Initialize the database and table for testing + */ + private void InitDatabase() throws SQLException { + Statement stmt = conn.createStatement(); + stmt.execute(SQL_DROP_TABLE); + stmt.execute(SQL_CREATE_TABLE); + } + + @Before + public void Setup() throws SQLException { + conn = makeDefaultConnection(); + conn.setAutoCommit(true); + InitDatabase(); + } + + @After + public void Teardown() throws SQLException { + Statement stmt = conn.createStatement(); + stmt.execute(SQL_DROP_TABLE); + } + + /** + * Insert 1 tuple, rename the column, and see if the change is visible. + */ + @Test + public void test_RenameColumn_1() throws SQLException { + String sql_1 = "INSERT INTO foo VALUES (5, 400);"; + conn.createStatement().execute(sql_1); + + ResultSet rs_1 = conn.createStatement().executeQuery(s_sql); + rs_1.next(); + checkRow(rs_1, + new String [] {"id", "year"}, + new int [] {5, 400}); + assertNoMoreRows(rs_1); + + String sql_2 = "ALTER TABLE foo RENAME year to month;"; + conn.createStatement().execute(sql_2); + ResultSet rs_2 = conn.createStatement().executeQuery(s_sql); + + rs_2.next(); + checkRow(rs_2, + new String [] {"id", "month"}, + new int [] {5, 400}); + assertNoMoreRows(rs_2); + } + + /** + * Rename a column that does not exist, should throw exception + */ + @Test + public void test_RenameColumn_2() throws SQLException { + String sql = "ALTER TABLE foo RENAME a to b;"; + + // Old column does not exist + thrown.expect(PSQLException.class); + conn.createStatement().execute(sql); + } + + /** + * Rename a column to a name that already exists, should throw exception + */ + @Test + public void test_RenameColumn_3() throws SQLException { + String sql = "ALTER TABLE foo RENAME year to id;"; + + // New column already exists + thrown.expect(PSQLException.class); + conn.createStatement().execute(sql); + } + +} diff --git a/src/catalog/catalog.cpp b/src/catalog/catalog.cpp index c5d3d5df297..afb64e1b019 100644 --- a/src/catalog/catalog.cpp +++ b/src/catalog/catalog.cpp @@ -882,7 +882,7 @@ ResultType Catalog::ChangeColumnName(const std::string &database_name, new_column.GetType(), new_column.IsInlined(), new_column.GetConstraints(), pool_.get(), txn); - } catch (CastException &e) { + } catch (CatalogException &e) { return ResultType::FAILURE; } return ResultType::SUCCESS; From b08fa9e6a6bf0426a0f79c66ec7f2693dadd31ae Mon Sep 17 00:00:00 2001 From: dingshilun Date: Tue, 10 Apr 2018 18:41:38 -0400 Subject: [PATCH 18/58] added headers, comments and TODO --- src/include/parser/alter_statement.h | 5 +---- src/include/parser/rename_function_statement.h | 14 +++++++++++++- src/include/planner/alter_plan.h | 13 ++++++++++++- src/include/planner/rename_plan.h | 15 ++++++++++++++- 4 files changed, 40 insertions(+), 7 deletions(-) diff --git a/src/include/parser/alter_statement.h b/src/include/parser/alter_statement.h index f89a6f116a8..a733f988e4f 100644 --- a/src/include/parser/alter_statement.h +++ b/src/include/parser/alter_statement.h @@ -20,6 +20,7 @@ namespace parser { /** * @struct AlterTableStatement * @brief Represents "ALTER TABLE add column COLUMN_NAME COLUMN_TYPE" + * TODO: add implementation of AlterTableStatement */ class AlterTableStatement : public TableRefStatement { public: @@ -30,10 +31,6 @@ class AlterTableStatement : public TableRefStatement { names(new std::vector) {} virtual ~AlterTableStatement() { - // if (columns != nullptr) { - // for (auto col : *columns) delete col; - // delete columns; - // } if (names != nullptr) { for (auto name : *names) delete name; delete names; diff --git a/src/include/parser/rename_function_statement.h b/src/include/parser/rename_function_statement.h index 7883322a136..1a07a1ef4a6 100644 --- a/src/include/parser/rename_function_statement.h +++ b/src/include/parser/rename_function_statement.h @@ -1,6 +1,14 @@ +//===----------------------------------------------------------------------===// // -// Created by Nevermore on 01/04/2018. +// Peloton // +// rename_function_statement.h +// +// Identification: src/include/parser/rename_function_statement.h +// +// Copyright (c) 2015-17, Carnegie Mellon University Database Group +// +//===----------------------------------------------------------------------===// #pragma once @@ -9,6 +17,10 @@ namespace peloton { namespace parser { +/** @brief Rename statement + * The statement that used for transform from postgress statement + * to Peloton statement + */ class RenameFuncStatement : public TableRefStatement { public: enum class ObjectType { INVALID = 0, COLUMN = 1 }; diff --git a/src/include/planner/alter_plan.h b/src/include/planner/alter_plan.h index 5fd2ce6cb16..a65fb622c01 100644 --- a/src/include/planner/alter_plan.h +++ b/src/include/planner/alter_plan.h @@ -1,6 +1,14 @@ +//===----------------------------------------------------------------------===// // -// Created by Nevermore on 03/04/2018. +// Peloton // +// alter_plan.h +// +// Identification: src/include/parser/alter_plan.h +// +// Copyright (c) 2015-17, Carnegie Mellon University Database Group +// +//===----------------------------------------------------------------------===// #pragma once #include "planner/abstract_plan.h" @@ -8,6 +16,9 @@ namespace peloton { namespace planner { +/** @brief The plan used for altering + * TODO: adding support for add/drop column + */ class AlterPlan : public AbstractPlan { public: AlterPlan() = delete; diff --git a/src/include/planner/rename_plan.h b/src/include/planner/rename_plan.h index 76d0c5aac63..3d0f0429730 100644 --- a/src/include/planner/rename_plan.h +++ b/src/include/planner/rename_plan.h @@ -1,12 +1,25 @@ +//===----------------------------------------------------------------------===// // -// Created by Nevermore on 03/04/2018. +// Peloton // +// rename_plan.h +// +// Identification: src/include/parser/rename_plan.h +// +// Copyright (c) 2015-17, Carnegie Mellon University Database Group +// +//===----------------------------------------------------------------------===// #pragma once #include "planner/abstract_plan.h" #include "parser/rename_function_statement.h" +/** @brief: The Plan used for rename + * The plan contains the necessary information for + * renaming, including old names, new names and + * which object and database + */ namespace peloton { namespace planner { class RenamePlan : public AbstractPlan { From 0e46c9079ea4843e8e5bf873cb5bfb2a74698c1b Mon Sep 17 00:00:00 2001 From: Shangjie Chen Date: Wed, 11 Apr 2018 00:25:23 +0000 Subject: [PATCH 19/58] remove comments --- src/catalog/catalog.cpp | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/catalog/catalog.cpp b/src/catalog/catalog.cpp index afb64e1b019..4db482a3801 100644 --- a/src/catalog/catalog.cpp +++ b/src/catalog/catalog.cpp @@ -857,19 +857,6 @@ ResultType Catalog::ChangeColumnName(const std::string &database_name, // Change column name in the global schema schema->ChangeColumnName(columnId, names[0]); - // TODO: verify do we really need doing so - // Modify all the tiles within the Data Table - /* - for (oid_t i = 0; i < table->GetTileGroupCount(); i++) { - auto tile_group = table->GetTileGroup(i); - for (oid_t j = 0; j < tile_group->GetNextTupleSlot(); j++) { - // Change schema in the tiles - auto tile = tile_group->GetTile(j); - tile->ChangeColumnName(columnId, names[0]); - } - } - */ - // Change cached ColumnCatalog oid_t table_oid = Catalog::GetInstance() ->GetTableObject(database_name, table_name, txn) From d07920e2060d2e1b28e54e615f6b1fdb08b34015 Mon Sep 17 00:00:00 2001 From: Shangjie Chen Date: Mon, 2 Apr 2018 02:01:16 +0000 Subject: [PATCH 20/58] add alter table catalog --- src/catalog/catalog.cpp | 7 +++++++ src/include/catalog/catalog.h | 1 + src/include/storage/database.h | 3 +++ src/storage/database.cpp | 20 ++++++++++++++++++++ 4 files changed, 31 insertions(+) diff --git a/src/catalog/catalog.cpp b/src/catalog/catalog.cpp index 4db482a3801..b26b54934c8 100644 --- a/src/catalog/catalog.cpp +++ b/src/catalog/catalog.cpp @@ -27,11 +27,18 @@ #include "catalog/trigger_catalog.h" #include "concurrency/transaction_manager_factory.h" #include "executor/executor_context.h" +<<<<<<< HEAD +======= +#include "executor/insert_executor.h" +#include "executor/seq_scan_executor.h" +>>>>>>> add alter table catalog #include "function/date_functions.h" #include "function/decimal_functions.h" #include "function/old_engine_string_functions.h" #include "function/timestamp_functions.h" #include "index/index_factory.h" +#include "planner/seq_scan_plan.h" +#include "planner/insert_plan.h" #include "settings/settings_manager.h" #include "storage/storage_manager.h" #include "storage/table_factory.h" diff --git a/src/include/catalog/catalog.h b/src/include/catalog/catalog.h index 4092ed90631..3fac448c8fc 100644 --- a/src/include/catalog/catalog.h +++ b/src/include/catalog/catalog.h @@ -15,6 +15,7 @@ #include #include "catalog/catalog_defaults.h" +#include "catalog/column_catalog.h" #include "function/functions.h" namespace peloton { diff --git a/src/include/storage/database.h b/src/include/storage/database.h index d8eca8a4373..82412d8582b 100644 --- a/src/include/storage/database.h +++ b/src/include/storage/database.h @@ -72,6 +72,9 @@ class Database : public Printable { std::string GetDBName(); void setDBName(const std::string &database_name); + storage::DataTable *ReplaceTableWithOid(const oid_t table_oid, + storage::DataTable *new_table); + protected: //===--------------------------------------------------------------------===// // MEMBERS diff --git a/src/storage/database.cpp b/src/storage/database.cpp index 705ad42916e..a7ea96dab93 100644 --- a/src/storage/database.cpp +++ b/src/storage/database.cpp @@ -184,5 +184,25 @@ void Database::setDBName(const std::string &database_name) { Database::database_name = database_name; } +storage::DataTable *Database::ReplaceTableWithOid( + const oid_t table_oid, storage::DataTable *new_table) { + { + std::lock_guard lock(database_mutex); + + oid_t table_offset = 0; + for (auto table : tables) { + if (table->GetOid() == table_oid) { + break; + } + table_offset++; + } + PL_ASSERT(table_offset < tables.size()); + + auto old_table = tables.at(table_offset); + tables[table_offset] = new_table; + return old_table; + } +} + } // namespace storage } // namespace peloton From 88a397c09a846dda03852a6928be9e006f00ba8c Mon Sep 17 00:00:00 2001 From: Shangjie Chen Date: Thu, 5 Apr 2018 16:29:00 +0000 Subject: [PATCH 21/58] add change column catalog --- src/catalog/catalog.cpp | 5 ----- src/catalog/table_catalog.cpp | 12 +++++++++++- src/include/catalog/table_catalog.h | 14 +++++++++----- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/catalog/catalog.cpp b/src/catalog/catalog.cpp index b26b54934c8..9db89a94c98 100644 --- a/src/catalog/catalog.cpp +++ b/src/catalog/catalog.cpp @@ -27,11 +27,6 @@ #include "catalog/trigger_catalog.h" #include "concurrency/transaction_manager_factory.h" #include "executor/executor_context.h" -<<<<<<< HEAD -======= -#include "executor/insert_executor.h" -#include "executor/seq_scan_executor.h" ->>>>>>> add alter table catalog #include "function/date_functions.h" #include "function/decimal_functions.h" #include "function/old_engine_string_functions.h" diff --git a/src/catalog/table_catalog.cpp b/src/catalog/table_catalog.cpp index 49fbaed6db5..39db1bff587 100644 --- a/src/catalog/table_catalog.cpp +++ b/src/catalog/table_catalog.cpp @@ -303,6 +303,15 @@ std::shared_ptr TableCatalogObject::GetColumnObject( return nullptr; } +void TableCatalogObject::ChangeColumnName( + const std::vector &columns, + UNUSED_ATTRIBUTE const std::vector &names) { + // TODO: Change column_names + // TODO: Change column_objects + TableCatalogObject::EvictColumnObject(columns[0]); + return; +} + TableCatalog *TableCatalog::GetInstance(storage::Database *pg_catalog, type::AbstractPool *pool, concurrency::TransactionContext *txn) { @@ -394,7 +403,8 @@ bool TableCatalog::InsertTable(oid_t table_oid, const std::string &table_name, * @param txn TransactionContext * @return Whether deletion is Successful */ -bool TableCatalog::DeleteTable(oid_t table_oid, concurrency::TransactionContext *txn) { +bool TableCatalog::DeleteTable(oid_t table_oid, + concurrency::TransactionContext *txn) { oid_t index_offset = IndexId::PRIMARY_KEY; // Index of table_oid std::vector values; values.push_back(type::ValueFactory::GetIntegerValue(table_oid).Copy()); diff --git a/src/include/catalog/table_catalog.h b/src/include/catalog/table_catalog.h index 3ef4668d5ca..5e44beeca2e 100644 --- a/src/include/catalog/table_catalog.h +++ b/src/include/catalog/table_catalog.h @@ -45,8 +45,8 @@ class TableCatalogObject { friend class ColumnCatalog; public: - TableCatalogObject(executor::LogicalTile *tile, concurrency::TransactionContext *txn, - int tupleId = 0); + TableCatalogObject(executor::LogicalTile *tile, + concurrency::TransactionContext *txn, int tupleId = 0); public: // Get indexes @@ -71,6 +71,9 @@ class TableCatalogObject { std::shared_ptr GetColumnObject( const std::string &column_name, bool cached_only = false); + void ChangeColumnName(const std::vector &columns, + const std::vector &names); + inline oid_t GetTableOid() { return table_oid; } inline const std::string &GetTableName() { return table_name; } inline oid_t GetDatabaseOid() { return database_oid; } @@ -119,9 +122,10 @@ class TableCatalog : public AbstractCatalog { ~TableCatalog(); // Global Singleton, only the first call requires passing parameters. - static TableCatalog *GetInstance(storage::Database *pg_catalog = nullptr, - type::AbstractPool *pool = nullptr, - concurrency::TransactionContext *txn = nullptr); + static TableCatalog *GetInstance( + storage::Database *pg_catalog = nullptr, + type::AbstractPool *pool = nullptr, + concurrency::TransactionContext *txn = nullptr); inline oid_t GetNextOid() { return oid_++ | TABLE_OID_MASK; } From f0ecc68b20d84084489b6805046f1d09bb8dd031 Mon Sep 17 00:00:00 2001 From: dingshilun <524768593@qq.com> Date: Thu, 5 Apr 2018 19:17:20 +0000 Subject: [PATCH 22/58] Revert "Merge pull request #1 from DeanChensj/catlog" This reverts commit 6704d0e6ed401377c5c810da3176789f942a360a, reversing changes made to 39fa518996e8923a3577a6be6fc17a2698af9f3c. --- src/catalog/catalog.cpp | 84 ++++++++++++++--------------- src/catalog/table_catalog.cpp | 12 +---- src/include/catalog/catalog.h | 1 - src/include/catalog/schema.h | 2 +- src/include/catalog/table_catalog.h | 14 ++--- src/include/storage/database.h | 3 -- src/storage/database.cpp | 20 ------- 7 files changed, 49 insertions(+), 87 deletions(-) diff --git a/src/catalog/catalog.cpp b/src/catalog/catalog.cpp index 9db89a94c98..c45a3ecd06b 100644 --- a/src/catalog/catalog.cpp +++ b/src/catalog/catalog.cpp @@ -26,18 +26,14 @@ #include "catalog/table_metrics_catalog.h" #include "catalog/trigger_catalog.h" #include "concurrency/transaction_manager_factory.h" -#include "executor/executor_context.h" #include "function/date_functions.h" #include "function/decimal_functions.h" #include "function/old_engine_string_functions.h" #include "function/timestamp_functions.h" #include "index/index_factory.h" -#include "planner/seq_scan_plan.h" -#include "planner/insert_plan.h" #include "settings/settings_manager.h" #include "storage/storage_manager.h" #include "storage/table_factory.h" -#include "storage/tile.h" #include "type/ephemeral_pool.h" namespace peloton { @@ -152,12 +148,12 @@ void Catalog::Bootstrap() { DatabaseMetricsCatalog::GetInstance(txn); TableMetricsCatalog::GetInstance(txn); IndexMetricsCatalog::GetInstance(txn); - QueryMetricsCatalog::GetInstance(txn); + QueryMetricsCatalog::GetInstance(txn); SettingsCatalog::GetInstance(txn); TriggerCatalog::GetInstance(txn); LanguageCatalog::GetInstance(txn); ProcCatalog::GetInstance(txn); - + if (settings::SettingsManager::GetBool(settings::SettingId::brain)) { QueryHistoryCatalog::GetInstance(txn); } @@ -618,18 +614,18 @@ ResultType Catalog::DropIndex(oid_t index_oid, ResultType Catalog::DropIndex(const std::string &index_name, concurrency::TransactionContext *txn) { - if (txn == nullptr) { - throw CatalogException("Do not have transaction to drop index " + - index_name); - } - auto index_object = - catalog::IndexCatalog::GetInstance()->GetIndexObject(index_name, txn); - if (index_object == nullptr) { - throw CatalogException("Index name " + index_name + " cannot be found"); - } - ResultType result = DropIndex(index_object->GetIndexOid(), txn); + if(txn == nullptr) { + throw CatalogException("Do not have transaction to drop index " + + index_name); + } + auto index_object = catalog::IndexCatalog::GetInstance()->GetIndexObject( + index_name, txn); + if(index_object == nullptr) { + throw CatalogException("Index name " + index_name + " cannot be found"); + } + ResultType result = DropIndex(index_object->GetIndexOid(), txn); - return result; + return result; } //===--------------------------------------------------------------------===// @@ -1154,11 +1150,11 @@ void Catalog::InitializeFunctions() { /** * decimal functions */ - AddBuiltinFunction("abs", {type::TypeId::DECIMAL}, type::TypeId::DECIMAL, - internal_lang, "Abs", - function::BuiltInFuncType{ - OperatorId::Abs, function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction( + "abs", {type::TypeId::DECIMAL}, type::TypeId::DECIMAL, internal_lang, + "Abs", function::BuiltInFuncType{OperatorId::Abs, + function::DecimalFunctions::_Abs}, + txn); AddBuiltinFunction( "sqrt", {type::TypeId::TINYINT}, type::TypeId::DECIMAL, internal_lang, "Sqrt", function::BuiltInFuncType{OperatorId::Sqrt, @@ -1195,29 +1191,33 @@ void Catalog::InitializeFunctions() { /** * integer functions */ - AddBuiltinFunction("abs", {type::TypeId::TINYINT}, type::TypeId::TINYINT, - internal_lang, "Abs", - function::BuiltInFuncType{ - OperatorId::Abs, function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction( + "abs", {type::TypeId::TINYINT}, type::TypeId::TINYINT, + internal_lang, "Abs", + function::BuiltInFuncType{OperatorId::Abs, + function::DecimalFunctions::_Abs}, + txn); - AddBuiltinFunction("abs", {type::TypeId::SMALLINT}, - type::TypeId::SMALLINT, internal_lang, "Abs", - function::BuiltInFuncType{ - OperatorId::Abs, function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction( + "abs", {type::TypeId::SMALLINT}, type::TypeId::SMALLINT, + internal_lang, "Abs", + function::BuiltInFuncType{OperatorId::Abs, + function::DecimalFunctions::_Abs}, + txn); - AddBuiltinFunction("abs", {type::TypeId::INTEGER}, type::TypeId::INTEGER, - internal_lang, "Abs", - function::BuiltInFuncType{ - OperatorId::Abs, function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction( + "abs", {type::TypeId::INTEGER}, type::TypeId::INTEGER, + internal_lang, "Abs", + function::BuiltInFuncType{OperatorId::Abs, + function::DecimalFunctions::_Abs}, + txn); - AddBuiltinFunction("abs", {type::TypeId::BIGINT}, type::TypeId::BIGINT, - internal_lang, "Abs", - function::BuiltInFuncType{ - OperatorId::Abs, function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction( + "abs", {type::TypeId::BIGINT}, type::TypeId::BIGINT, + internal_lang, "Abs", + function::BuiltInFuncType{OperatorId::Abs, + function::DecimalFunctions::_Abs}, + txn); AddBuiltinFunction( "floor", {type::TypeId::INTEGER}, type::TypeId::DECIMAL, diff --git a/src/catalog/table_catalog.cpp b/src/catalog/table_catalog.cpp index 39db1bff587..49fbaed6db5 100644 --- a/src/catalog/table_catalog.cpp +++ b/src/catalog/table_catalog.cpp @@ -303,15 +303,6 @@ std::shared_ptr TableCatalogObject::GetColumnObject( return nullptr; } -void TableCatalogObject::ChangeColumnName( - const std::vector &columns, - UNUSED_ATTRIBUTE const std::vector &names) { - // TODO: Change column_names - // TODO: Change column_objects - TableCatalogObject::EvictColumnObject(columns[0]); - return; -} - TableCatalog *TableCatalog::GetInstance(storage::Database *pg_catalog, type::AbstractPool *pool, concurrency::TransactionContext *txn) { @@ -403,8 +394,7 @@ bool TableCatalog::InsertTable(oid_t table_oid, const std::string &table_name, * @param txn TransactionContext * @return Whether deletion is Successful */ -bool TableCatalog::DeleteTable(oid_t table_oid, - concurrency::TransactionContext *txn) { +bool TableCatalog::DeleteTable(oid_t table_oid, concurrency::TransactionContext *txn) { oid_t index_offset = IndexId::PRIMARY_KEY; // Index of table_oid std::vector values; values.push_back(type::ValueFactory::GetIntegerValue(table_oid).Copy()); diff --git a/src/include/catalog/catalog.h b/src/include/catalog/catalog.h index 3fac448c8fc..4092ed90631 100644 --- a/src/include/catalog/catalog.h +++ b/src/include/catalog/catalog.h @@ -15,7 +15,6 @@ #include #include "catalog/catalog_defaults.h" -#include "catalog/column_catalog.h" #include "function/functions.h" namespace peloton { diff --git a/src/include/catalog/schema.h b/src/include/catalog/schema.h index d722a21812c..d3d7d33fe27 100644 --- a/src/include/catalog/schema.h +++ b/src/include/catalog/schema.h @@ -196,7 +196,7 @@ class Schema : public Printable { } // Get the default value for the column - inline type::Value *GetDefaultValue(const oid_t column_id) const { + inline type::Value* GetDefaultValue(const oid_t column_id) const { for (auto constraint : columns[column_id].GetConstraints()) { if (constraint.GetType() == ConstraintType::DEFAULT) { return constraint.getDefaultValue(); diff --git a/src/include/catalog/table_catalog.h b/src/include/catalog/table_catalog.h index 5e44beeca2e..3ef4668d5ca 100644 --- a/src/include/catalog/table_catalog.h +++ b/src/include/catalog/table_catalog.h @@ -45,8 +45,8 @@ class TableCatalogObject { friend class ColumnCatalog; public: - TableCatalogObject(executor::LogicalTile *tile, - concurrency::TransactionContext *txn, int tupleId = 0); + TableCatalogObject(executor::LogicalTile *tile, concurrency::TransactionContext *txn, + int tupleId = 0); public: // Get indexes @@ -71,9 +71,6 @@ class TableCatalogObject { std::shared_ptr GetColumnObject( const std::string &column_name, bool cached_only = false); - void ChangeColumnName(const std::vector &columns, - const std::vector &names); - inline oid_t GetTableOid() { return table_oid; } inline const std::string &GetTableName() { return table_name; } inline oid_t GetDatabaseOid() { return database_oid; } @@ -122,10 +119,9 @@ class TableCatalog : public AbstractCatalog { ~TableCatalog(); // Global Singleton, only the first call requires passing parameters. - static TableCatalog *GetInstance( - storage::Database *pg_catalog = nullptr, - type::AbstractPool *pool = nullptr, - concurrency::TransactionContext *txn = nullptr); + static TableCatalog *GetInstance(storage::Database *pg_catalog = nullptr, + type::AbstractPool *pool = nullptr, + concurrency::TransactionContext *txn = nullptr); inline oid_t GetNextOid() { return oid_++ | TABLE_OID_MASK; } diff --git a/src/include/storage/database.h b/src/include/storage/database.h index 82412d8582b..d8eca8a4373 100644 --- a/src/include/storage/database.h +++ b/src/include/storage/database.h @@ -72,9 +72,6 @@ class Database : public Printable { std::string GetDBName(); void setDBName(const std::string &database_name); - storage::DataTable *ReplaceTableWithOid(const oid_t table_oid, - storage::DataTable *new_table); - protected: //===--------------------------------------------------------------------===// // MEMBERS diff --git a/src/storage/database.cpp b/src/storage/database.cpp index a7ea96dab93..705ad42916e 100644 --- a/src/storage/database.cpp +++ b/src/storage/database.cpp @@ -184,25 +184,5 @@ void Database::setDBName(const std::string &database_name) { Database::database_name = database_name; } -storage::DataTable *Database::ReplaceTableWithOid( - const oid_t table_oid, storage::DataTable *new_table) { - { - std::lock_guard lock(database_mutex); - - oid_t table_offset = 0; - for (auto table : tables) { - if (table->GetOid() == table_oid) { - break; - } - table_offset++; - } - PL_ASSERT(table_offset < tables.size()); - - auto old_table = tables.at(table_offset); - tables[table_offset] = new_table; - return old_table; - } -} - } // namespace storage } // namespace peloton From a2f73d903a0b6e1db51e423dd311f8da5443a647 Mon Sep 17 00:00:00 2001 From: Shaoxiong Zhang Date: Sat, 7 Apr 2018 10:18:04 -0400 Subject: [PATCH 23/58] add rename column executor --- src/include/executor/executors.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/include/executor/executors.h b/src/include/executor/executors.h index 38a0fb606fa..cbc8184b470 100644 --- a/src/include/executor/executors.h +++ b/src/include/executor/executors.h @@ -39,3 +39,4 @@ #include "executor/projection_executor.h" #include "executor/seq_scan_executor.h" #include "executor/update_executor.h" +#include "executor/alter_executor.h" From ed7a2a9b381ac6a7b22ecb54bbb2358297585282 Mon Sep 17 00:00:00 2001 From: Shangjie Chen Date: Fri, 6 Apr 2018 01:14:53 +0000 Subject: [PATCH 24/58] Catalog for change column name --- src/catalog/catalog.cpp | 84 ++++++++++++++++++------------------ src/include/catalog/schema.h | 2 +- 2 files changed, 42 insertions(+), 44 deletions(-) diff --git a/src/catalog/catalog.cpp b/src/catalog/catalog.cpp index c45a3ecd06b..6509f5a7e66 100644 --- a/src/catalog/catalog.cpp +++ b/src/catalog/catalog.cpp @@ -26,6 +26,7 @@ #include "catalog/table_metrics_catalog.h" #include "catalog/trigger_catalog.h" #include "concurrency/transaction_manager_factory.h" +#include "executor/executor_context.h" #include "function/date_functions.h" #include "function/decimal_functions.h" #include "function/old_engine_string_functions.h" @@ -34,6 +35,7 @@ #include "settings/settings_manager.h" #include "storage/storage_manager.h" #include "storage/table_factory.h" +#include "storage/tile.h" #include "type/ephemeral_pool.h" namespace peloton { @@ -148,12 +150,12 @@ void Catalog::Bootstrap() { DatabaseMetricsCatalog::GetInstance(txn); TableMetricsCatalog::GetInstance(txn); IndexMetricsCatalog::GetInstance(txn); - QueryMetricsCatalog::GetInstance(txn); + QueryMetricsCatalog::GetInstance(txn); SettingsCatalog::GetInstance(txn); TriggerCatalog::GetInstance(txn); LanguageCatalog::GetInstance(txn); ProcCatalog::GetInstance(txn); - + if (settings::SettingsManager::GetBool(settings::SettingId::brain)) { QueryHistoryCatalog::GetInstance(txn); } @@ -614,18 +616,18 @@ ResultType Catalog::DropIndex(oid_t index_oid, ResultType Catalog::DropIndex(const std::string &index_name, concurrency::TransactionContext *txn) { - if(txn == nullptr) { - throw CatalogException("Do not have transaction to drop index " + - index_name); - } - auto index_object = catalog::IndexCatalog::GetInstance()->GetIndexObject( - index_name, txn); - if(index_object == nullptr) { - throw CatalogException("Index name " + index_name + " cannot be found"); - } - ResultType result = DropIndex(index_object->GetIndexOid(), txn); + if (txn == nullptr) { + throw CatalogException("Do not have transaction to drop index " + + index_name); + } + auto index_object = + catalog::IndexCatalog::GetInstance()->GetIndexObject(index_name, txn); + if (index_object == nullptr) { + throw CatalogException("Index name " + index_name + " cannot be found"); + } + ResultType result = DropIndex(index_object->GetIndexOid(), txn); - return result; + return result; } //===--------------------------------------------------------------------===// @@ -866,7 +868,7 @@ ResultType Catalog::ChangeColumnName(const std::string &database_name, table_oid, new_column.GetName(), columnId, new_column.GetOffset(), new_column.GetType(), new_column.IsInlined(), new_column.GetConstraints(), pool_.get(), txn); - + } catch (CatalogException &e) { return ResultType::FAILURE; } @@ -1150,11 +1152,11 @@ void Catalog::InitializeFunctions() { /** * decimal functions */ - AddBuiltinFunction( - "abs", {type::TypeId::DECIMAL}, type::TypeId::DECIMAL, internal_lang, - "Abs", function::BuiltInFuncType{OperatorId::Abs, - function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction("abs", {type::TypeId::DECIMAL}, type::TypeId::DECIMAL, + internal_lang, "Abs", + function::BuiltInFuncType{ + OperatorId::Abs, function::DecimalFunctions::_Abs}, + txn); AddBuiltinFunction( "sqrt", {type::TypeId::TINYINT}, type::TypeId::DECIMAL, internal_lang, "Sqrt", function::BuiltInFuncType{OperatorId::Sqrt, @@ -1191,33 +1193,29 @@ void Catalog::InitializeFunctions() { /** * integer functions */ - AddBuiltinFunction( - "abs", {type::TypeId::TINYINT}, type::TypeId::TINYINT, - internal_lang, "Abs", - function::BuiltInFuncType{OperatorId::Abs, - function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction("abs", {type::TypeId::TINYINT}, type::TypeId::TINYINT, + internal_lang, "Abs", + function::BuiltInFuncType{ + OperatorId::Abs, function::DecimalFunctions::_Abs}, + txn); - AddBuiltinFunction( - "abs", {type::TypeId::SMALLINT}, type::TypeId::SMALLINT, - internal_lang, "Abs", - function::BuiltInFuncType{OperatorId::Abs, - function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction("abs", {type::TypeId::SMALLINT}, + type::TypeId::SMALLINT, internal_lang, "Abs", + function::BuiltInFuncType{ + OperatorId::Abs, function::DecimalFunctions::_Abs}, + txn); - AddBuiltinFunction( - "abs", {type::TypeId::INTEGER}, type::TypeId::INTEGER, - internal_lang, "Abs", - function::BuiltInFuncType{OperatorId::Abs, - function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction("abs", {type::TypeId::INTEGER}, type::TypeId::INTEGER, + internal_lang, "Abs", + function::BuiltInFuncType{ + OperatorId::Abs, function::DecimalFunctions::_Abs}, + txn); - AddBuiltinFunction( - "abs", {type::TypeId::BIGINT}, type::TypeId::BIGINT, - internal_lang, "Abs", - function::BuiltInFuncType{OperatorId::Abs, - function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction("abs", {type::TypeId::BIGINT}, type::TypeId::BIGINT, + internal_lang, "Abs", + function::BuiltInFuncType{ + OperatorId::Abs, function::DecimalFunctions::_Abs}, + txn); AddBuiltinFunction( "floor", {type::TypeId::INTEGER}, type::TypeId::DECIMAL, diff --git a/src/include/catalog/schema.h b/src/include/catalog/schema.h index d3d7d33fe27..d722a21812c 100644 --- a/src/include/catalog/schema.h +++ b/src/include/catalog/schema.h @@ -196,7 +196,7 @@ class Schema : public Printable { } // Get the default value for the column - inline type::Value* GetDefaultValue(const oid_t column_id) const { + inline type::Value *GetDefaultValue(const oid_t column_id) const { for (auto constraint : columns[column_id].GetConstraints()) { if (constraint.GetType() == ConstraintType::DEFAULT) { return constraint.getDefaultValue(); From 397cf24e3643e3bf9604cca69644b8cfc5c1b77e Mon Sep 17 00:00:00 2001 From: Shaoxiong Zhang Date: Sun, 8 Apr 2018 01:24:33 -0400 Subject: [PATCH 25/58] fix --- src/include/executor/executors.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/include/executor/executors.h b/src/include/executor/executors.h index cbc8184b470..38a0fb606fa 100644 --- a/src/include/executor/executors.h +++ b/src/include/executor/executors.h @@ -39,4 +39,3 @@ #include "executor/projection_executor.h" #include "executor/seq_scan_executor.h" #include "executor/update_executor.h" -#include "executor/alter_executor.h" From e61451efb1f51fc009246acd5d45395f2a55b938 Mon Sep 17 00:00:00 2001 From: Shangjie Chen Date: Mon, 2 Apr 2018 02:01:16 +0000 Subject: [PATCH 26/58] add alter table catalog --- src/catalog/catalog.cpp | 2 ++ src/include/catalog/catalog.h | 1 + src/include/storage/database.h | 3 +++ src/storage/database.cpp | 20 ++++++++++++++++++++ 4 files changed, 26 insertions(+) diff --git a/src/catalog/catalog.cpp b/src/catalog/catalog.cpp index 6509f5a7e66..75151d7c3b3 100644 --- a/src/catalog/catalog.cpp +++ b/src/catalog/catalog.cpp @@ -32,6 +32,8 @@ #include "function/old_engine_string_functions.h" #include "function/timestamp_functions.h" #include "index/index_factory.h" +#include "planner/seq_scan_plan.h" +#include "planner/insert_plan.h" #include "settings/settings_manager.h" #include "storage/storage_manager.h" #include "storage/table_factory.h" diff --git a/src/include/catalog/catalog.h b/src/include/catalog/catalog.h index 4092ed90631..3fac448c8fc 100644 --- a/src/include/catalog/catalog.h +++ b/src/include/catalog/catalog.h @@ -15,6 +15,7 @@ #include #include "catalog/catalog_defaults.h" +#include "catalog/column_catalog.h" #include "function/functions.h" namespace peloton { diff --git a/src/include/storage/database.h b/src/include/storage/database.h index d8eca8a4373..82412d8582b 100644 --- a/src/include/storage/database.h +++ b/src/include/storage/database.h @@ -72,6 +72,9 @@ class Database : public Printable { std::string GetDBName(); void setDBName(const std::string &database_name); + storage::DataTable *ReplaceTableWithOid(const oid_t table_oid, + storage::DataTable *new_table); + protected: //===--------------------------------------------------------------------===// // MEMBERS diff --git a/src/storage/database.cpp b/src/storage/database.cpp index 705ad42916e..a7ea96dab93 100644 --- a/src/storage/database.cpp +++ b/src/storage/database.cpp @@ -184,5 +184,25 @@ void Database::setDBName(const std::string &database_name) { Database::database_name = database_name; } +storage::DataTable *Database::ReplaceTableWithOid( + const oid_t table_oid, storage::DataTable *new_table) { + { + std::lock_guard lock(database_mutex); + + oid_t table_offset = 0; + for (auto table : tables) { + if (table->GetOid() == table_oid) { + break; + } + table_offset++; + } + PL_ASSERT(table_offset < tables.size()); + + auto old_table = tables.at(table_offset); + tables[table_offset] = new_table; + return old_table; + } +} + } // namespace storage } // namespace peloton From 098a35a2541ddadebdabe785d54fed3aa173454b Mon Sep 17 00:00:00 2001 From: Shangjie Chen Date: Thu, 5 Apr 2018 16:29:00 +0000 Subject: [PATCH 27/58] add change column catalog --- src/catalog/catalog.cpp | 12 ++++++++++++ src/catalog/table_catalog.cpp | 12 +++++++++++- src/include/catalog/table_catalog.h | 14 +++++++++----- 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/catalog/catalog.cpp b/src/catalog/catalog.cpp index 75151d7c3b3..f7080ca1003 100644 --- a/src/catalog/catalog.cpp +++ b/src/catalog/catalog.cpp @@ -814,6 +814,7 @@ ResultType Catalog::AddColumn( return ResultType::SUCCESS; } +<<<<<<< bc9252fda7aeecaeb325a11f30bc23a27569f932 ResultType Catalog::DropColumn( UNUSED_ATTRIBUTE const std::string &database_name, UNUSED_ATTRIBUTE const std::string &table_name, @@ -827,6 +828,13 @@ ResultType Catalog::ChangeColumnName(const std::string &database_name, const std::vector &old_names, const std::vector &names, concurrency::TransactionContext *txn) { +======= +ResultType ChangeColumnName(const std::string &database_name, + const std::string &table_name, + const std::vector &old_names, + const std::vector &names, + concurrency::TransactionContext *txn) { +>>>>>>> add change column catalog if (txn == nullptr) { throw CatalogException("Change Column requires transaction."); } @@ -835,8 +843,12 @@ ResultType Catalog::ChangeColumnName(const std::string &database_name, throw CatalogException("No names are given."); } +<<<<<<< bc9252fda7aeecaeb325a11f30bc23a27569f932 LOG_TRACE("Change Column Name %s to %s", old_names[0].c_str(), names[0].c_str()); +======= + LOG_TRACE("Change Column Name %s to %s", old_names[0], names[0]); +>>>>>>> add change column catalog try { // Get table from the name diff --git a/src/catalog/table_catalog.cpp b/src/catalog/table_catalog.cpp index 49fbaed6db5..39db1bff587 100644 --- a/src/catalog/table_catalog.cpp +++ b/src/catalog/table_catalog.cpp @@ -303,6 +303,15 @@ std::shared_ptr TableCatalogObject::GetColumnObject( return nullptr; } +void TableCatalogObject::ChangeColumnName( + const std::vector &columns, + UNUSED_ATTRIBUTE const std::vector &names) { + // TODO: Change column_names + // TODO: Change column_objects + TableCatalogObject::EvictColumnObject(columns[0]); + return; +} + TableCatalog *TableCatalog::GetInstance(storage::Database *pg_catalog, type::AbstractPool *pool, concurrency::TransactionContext *txn) { @@ -394,7 +403,8 @@ bool TableCatalog::InsertTable(oid_t table_oid, const std::string &table_name, * @param txn TransactionContext * @return Whether deletion is Successful */ -bool TableCatalog::DeleteTable(oid_t table_oid, concurrency::TransactionContext *txn) { +bool TableCatalog::DeleteTable(oid_t table_oid, + concurrency::TransactionContext *txn) { oid_t index_offset = IndexId::PRIMARY_KEY; // Index of table_oid std::vector values; values.push_back(type::ValueFactory::GetIntegerValue(table_oid).Copy()); diff --git a/src/include/catalog/table_catalog.h b/src/include/catalog/table_catalog.h index 3ef4668d5ca..5e44beeca2e 100644 --- a/src/include/catalog/table_catalog.h +++ b/src/include/catalog/table_catalog.h @@ -45,8 +45,8 @@ class TableCatalogObject { friend class ColumnCatalog; public: - TableCatalogObject(executor::LogicalTile *tile, concurrency::TransactionContext *txn, - int tupleId = 0); + TableCatalogObject(executor::LogicalTile *tile, + concurrency::TransactionContext *txn, int tupleId = 0); public: // Get indexes @@ -71,6 +71,9 @@ class TableCatalogObject { std::shared_ptr GetColumnObject( const std::string &column_name, bool cached_only = false); + void ChangeColumnName(const std::vector &columns, + const std::vector &names); + inline oid_t GetTableOid() { return table_oid; } inline const std::string &GetTableName() { return table_name; } inline oid_t GetDatabaseOid() { return database_oid; } @@ -119,9 +122,10 @@ class TableCatalog : public AbstractCatalog { ~TableCatalog(); // Global Singleton, only the first call requires passing parameters. - static TableCatalog *GetInstance(storage::Database *pg_catalog = nullptr, - type::AbstractPool *pool = nullptr, - concurrency::TransactionContext *txn = nullptr); + static TableCatalog *GetInstance( + storage::Database *pg_catalog = nullptr, + type::AbstractPool *pool = nullptr, + concurrency::TransactionContext *txn = nullptr); inline oid_t GetNextOid() { return oid_++ | TABLE_OID_MASK; } From f344a5572615f812895f537978127680e4e4697b Mon Sep 17 00:00:00 2001 From: dingshilun <524768593@qq.com> Date: Thu, 5 Apr 2018 19:17:20 +0000 Subject: [PATCH 28/58] Revert "Merge pull request #1 from DeanChensj/catlog" This reverts commit 6704d0e6ed401377c5c810da3176789f942a360a, reversing changes made to 39fa518996e8923a3577a6be6fc17a2698af9f3c. --- src/catalog/catalog.cpp | 91 +++++++++++++---------------- src/catalog/table_catalog.cpp | 12 +--- src/include/catalog/catalog.h | 1 - src/include/catalog/schema.h | 2 +- src/include/catalog/table_catalog.h | 14 ++--- src/include/storage/database.h | 3 - src/storage/database.cpp | 20 ------- 7 files changed, 47 insertions(+), 96 deletions(-) diff --git a/src/catalog/catalog.cpp b/src/catalog/catalog.cpp index f7080ca1003..724df2a6d43 100644 --- a/src/catalog/catalog.cpp +++ b/src/catalog/catalog.cpp @@ -32,12 +32,9 @@ #include "function/old_engine_string_functions.h" #include "function/timestamp_functions.h" #include "index/index_factory.h" -#include "planner/seq_scan_plan.h" -#include "planner/insert_plan.h" #include "settings/settings_manager.h" #include "storage/storage_manager.h" #include "storage/table_factory.h" -#include "storage/tile.h" #include "type/ephemeral_pool.h" namespace peloton { @@ -618,18 +615,18 @@ ResultType Catalog::DropIndex(oid_t index_oid, ResultType Catalog::DropIndex(const std::string &index_name, concurrency::TransactionContext *txn) { - if (txn == nullptr) { - throw CatalogException("Do not have transaction to drop index " + - index_name); - } - auto index_object = - catalog::IndexCatalog::GetInstance()->GetIndexObject(index_name, txn); - if (index_object == nullptr) { - throw CatalogException("Index name " + index_name + " cannot be found"); - } - ResultType result = DropIndex(index_object->GetIndexOid(), txn); + if(txn == nullptr) { + throw CatalogException("Do not have transaction to drop index " + + index_name); + } + auto index_object = catalog::IndexCatalog::GetInstance()->GetIndexObject( + index_name, txn); + if(index_object == nullptr) { + throw CatalogException("Index name " + index_name + " cannot be found"); + } + ResultType result = DropIndex(index_object->GetIndexOid(), txn); - return result; + return result; } //===--------------------------------------------------------------------===// @@ -814,7 +811,6 @@ ResultType Catalog::AddColumn( return ResultType::SUCCESS; } -<<<<<<< bc9252fda7aeecaeb325a11f30bc23a27569f932 ResultType Catalog::DropColumn( UNUSED_ATTRIBUTE const std::string &database_name, UNUSED_ATTRIBUTE const std::string &table_name, @@ -828,13 +824,6 @@ ResultType Catalog::ChangeColumnName(const std::string &database_name, const std::vector &old_names, const std::vector &names, concurrency::TransactionContext *txn) { -======= -ResultType ChangeColumnName(const std::string &database_name, - const std::string &table_name, - const std::vector &old_names, - const std::vector &names, - concurrency::TransactionContext *txn) { ->>>>>>> add change column catalog if (txn == nullptr) { throw CatalogException("Change Column requires transaction."); } @@ -843,12 +832,8 @@ ResultType ChangeColumnName(const std::string &database_name, throw CatalogException("No names are given."); } -<<<<<<< bc9252fda7aeecaeb325a11f30bc23a27569f932 LOG_TRACE("Change Column Name %s to %s", old_names[0].c_str(), names[0].c_str()); -======= - LOG_TRACE("Change Column Name %s to %s", old_names[0], names[0]); ->>>>>>> add change column catalog try { // Get table from the name @@ -1166,11 +1151,11 @@ void Catalog::InitializeFunctions() { /** * decimal functions */ - AddBuiltinFunction("abs", {type::TypeId::DECIMAL}, type::TypeId::DECIMAL, - internal_lang, "Abs", - function::BuiltInFuncType{ - OperatorId::Abs, function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction( + "abs", {type::TypeId::DECIMAL}, type::TypeId::DECIMAL, internal_lang, + "Abs", function::BuiltInFuncType{OperatorId::Abs, + function::DecimalFunctions::_Abs}, + txn); AddBuiltinFunction( "sqrt", {type::TypeId::TINYINT}, type::TypeId::DECIMAL, internal_lang, "Sqrt", function::BuiltInFuncType{OperatorId::Sqrt, @@ -1207,29 +1192,33 @@ void Catalog::InitializeFunctions() { /** * integer functions */ - AddBuiltinFunction("abs", {type::TypeId::TINYINT}, type::TypeId::TINYINT, - internal_lang, "Abs", - function::BuiltInFuncType{ - OperatorId::Abs, function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction( + "abs", {type::TypeId::TINYINT}, type::TypeId::TINYINT, + internal_lang, "Abs", + function::BuiltInFuncType{OperatorId::Abs, + function::DecimalFunctions::_Abs}, + txn); - AddBuiltinFunction("abs", {type::TypeId::SMALLINT}, - type::TypeId::SMALLINT, internal_lang, "Abs", - function::BuiltInFuncType{ - OperatorId::Abs, function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction( + "abs", {type::TypeId::SMALLINT}, type::TypeId::SMALLINT, + internal_lang, "Abs", + function::BuiltInFuncType{OperatorId::Abs, + function::DecimalFunctions::_Abs}, + txn); - AddBuiltinFunction("abs", {type::TypeId::INTEGER}, type::TypeId::INTEGER, - internal_lang, "Abs", - function::BuiltInFuncType{ - OperatorId::Abs, function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction( + "abs", {type::TypeId::INTEGER}, type::TypeId::INTEGER, + internal_lang, "Abs", + function::BuiltInFuncType{OperatorId::Abs, + function::DecimalFunctions::_Abs}, + txn); - AddBuiltinFunction("abs", {type::TypeId::BIGINT}, type::TypeId::BIGINT, - internal_lang, "Abs", - function::BuiltInFuncType{ - OperatorId::Abs, function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction( + "abs", {type::TypeId::BIGINT}, type::TypeId::BIGINT, + internal_lang, "Abs", + function::BuiltInFuncType{OperatorId::Abs, + function::DecimalFunctions::_Abs}, + txn); AddBuiltinFunction( "floor", {type::TypeId::INTEGER}, type::TypeId::DECIMAL, diff --git a/src/catalog/table_catalog.cpp b/src/catalog/table_catalog.cpp index 39db1bff587..49fbaed6db5 100644 --- a/src/catalog/table_catalog.cpp +++ b/src/catalog/table_catalog.cpp @@ -303,15 +303,6 @@ std::shared_ptr TableCatalogObject::GetColumnObject( return nullptr; } -void TableCatalogObject::ChangeColumnName( - const std::vector &columns, - UNUSED_ATTRIBUTE const std::vector &names) { - // TODO: Change column_names - // TODO: Change column_objects - TableCatalogObject::EvictColumnObject(columns[0]); - return; -} - TableCatalog *TableCatalog::GetInstance(storage::Database *pg_catalog, type::AbstractPool *pool, concurrency::TransactionContext *txn) { @@ -403,8 +394,7 @@ bool TableCatalog::InsertTable(oid_t table_oid, const std::string &table_name, * @param txn TransactionContext * @return Whether deletion is Successful */ -bool TableCatalog::DeleteTable(oid_t table_oid, - concurrency::TransactionContext *txn) { +bool TableCatalog::DeleteTable(oid_t table_oid, concurrency::TransactionContext *txn) { oid_t index_offset = IndexId::PRIMARY_KEY; // Index of table_oid std::vector values; values.push_back(type::ValueFactory::GetIntegerValue(table_oid).Copy()); diff --git a/src/include/catalog/catalog.h b/src/include/catalog/catalog.h index 3fac448c8fc..4092ed90631 100644 --- a/src/include/catalog/catalog.h +++ b/src/include/catalog/catalog.h @@ -15,7 +15,6 @@ #include #include "catalog/catalog_defaults.h" -#include "catalog/column_catalog.h" #include "function/functions.h" namespace peloton { diff --git a/src/include/catalog/schema.h b/src/include/catalog/schema.h index d722a21812c..d3d7d33fe27 100644 --- a/src/include/catalog/schema.h +++ b/src/include/catalog/schema.h @@ -196,7 +196,7 @@ class Schema : public Printable { } // Get the default value for the column - inline type::Value *GetDefaultValue(const oid_t column_id) const { + inline type::Value* GetDefaultValue(const oid_t column_id) const { for (auto constraint : columns[column_id].GetConstraints()) { if (constraint.GetType() == ConstraintType::DEFAULT) { return constraint.getDefaultValue(); diff --git a/src/include/catalog/table_catalog.h b/src/include/catalog/table_catalog.h index 5e44beeca2e..3ef4668d5ca 100644 --- a/src/include/catalog/table_catalog.h +++ b/src/include/catalog/table_catalog.h @@ -45,8 +45,8 @@ class TableCatalogObject { friend class ColumnCatalog; public: - TableCatalogObject(executor::LogicalTile *tile, - concurrency::TransactionContext *txn, int tupleId = 0); + TableCatalogObject(executor::LogicalTile *tile, concurrency::TransactionContext *txn, + int tupleId = 0); public: // Get indexes @@ -71,9 +71,6 @@ class TableCatalogObject { std::shared_ptr GetColumnObject( const std::string &column_name, bool cached_only = false); - void ChangeColumnName(const std::vector &columns, - const std::vector &names); - inline oid_t GetTableOid() { return table_oid; } inline const std::string &GetTableName() { return table_name; } inline oid_t GetDatabaseOid() { return database_oid; } @@ -122,10 +119,9 @@ class TableCatalog : public AbstractCatalog { ~TableCatalog(); // Global Singleton, only the first call requires passing parameters. - static TableCatalog *GetInstance( - storage::Database *pg_catalog = nullptr, - type::AbstractPool *pool = nullptr, - concurrency::TransactionContext *txn = nullptr); + static TableCatalog *GetInstance(storage::Database *pg_catalog = nullptr, + type::AbstractPool *pool = nullptr, + concurrency::TransactionContext *txn = nullptr); inline oid_t GetNextOid() { return oid_++ | TABLE_OID_MASK; } diff --git a/src/include/storage/database.h b/src/include/storage/database.h index 82412d8582b..d8eca8a4373 100644 --- a/src/include/storage/database.h +++ b/src/include/storage/database.h @@ -72,9 +72,6 @@ class Database : public Printable { std::string GetDBName(); void setDBName(const std::string &database_name); - storage::DataTable *ReplaceTableWithOid(const oid_t table_oid, - storage::DataTable *new_table); - protected: //===--------------------------------------------------------------------===// // MEMBERS diff --git a/src/storage/database.cpp b/src/storage/database.cpp index a7ea96dab93..705ad42916e 100644 --- a/src/storage/database.cpp +++ b/src/storage/database.cpp @@ -184,25 +184,5 @@ void Database::setDBName(const std::string &database_name) { Database::database_name = database_name; } -storage::DataTable *Database::ReplaceTableWithOid( - const oid_t table_oid, storage::DataTable *new_table) { - { - std::lock_guard lock(database_mutex); - - oid_t table_offset = 0; - for (auto table : tables) { - if (table->GetOid() == table_oid) { - break; - } - table_offset++; - } - PL_ASSERT(table_offset < tables.size()); - - auto old_table = tables.at(table_offset); - tables[table_offset] = new_table; - return old_table; - } -} - } // namespace storage } // namespace peloton From e930b1105a37475d3b744368d7784854591e88a1 Mon Sep 17 00:00:00 2001 From: Shaoxiong Zhang Date: Sat, 7 Apr 2018 10:18:04 -0400 Subject: [PATCH 29/58] add rename column executor --- src/include/executor/executors.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/include/executor/executors.h b/src/include/executor/executors.h index 38a0fb606fa..cbc8184b470 100644 --- a/src/include/executor/executors.h +++ b/src/include/executor/executors.h @@ -39,3 +39,4 @@ #include "executor/projection_executor.h" #include "executor/seq_scan_executor.h" #include "executor/update_executor.h" +#include "executor/alter_executor.h" From c31ef3a0944411b8ba6d4bc1dceb3e830a9025ba Mon Sep 17 00:00:00 2001 From: Shangjie Chen Date: Fri, 6 Apr 2018 01:14:53 +0000 Subject: [PATCH 30/58] Catalog for change column name --- src/include/catalog/schema.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/catalog/schema.h b/src/include/catalog/schema.h index d3d7d33fe27..d722a21812c 100644 --- a/src/include/catalog/schema.h +++ b/src/include/catalog/schema.h @@ -196,7 +196,7 @@ class Schema : public Printable { } // Get the default value for the column - inline type::Value* GetDefaultValue(const oid_t column_id) const { + inline type::Value *GetDefaultValue(const oid_t column_id) const { for (auto constraint : columns[column_id].GetConstraints()) { if (constraint.GetType() == ConstraintType::DEFAULT) { return constraint.getDefaultValue(); From 74ca51bf51b07fa3d14a4a2fc80912a419108e23 Mon Sep 17 00:00:00 2001 From: Shaoxiong Zhang Date: Sun, 8 Apr 2018 01:24:33 -0400 Subject: [PATCH 31/58] fix --- src/include/executor/executors.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/include/executor/executors.h b/src/include/executor/executors.h index cbc8184b470..38a0fb606fa 100644 --- a/src/include/executor/executors.h +++ b/src/include/executor/executors.h @@ -39,4 +39,3 @@ #include "executor/projection_executor.h" #include "executor/seq_scan_executor.h" #include "executor/update_executor.h" -#include "executor/alter_executor.h" From ed1a0de1b0a1a4b3b8c68b6904b23089addddce4 Mon Sep 17 00:00:00 2001 From: Shangjie Chen Date: Sun, 8 Apr 2018 19:58:46 +0000 Subject: [PATCH 32/58] AlterTable init test --- src/catalog/catalog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/catalog/catalog.cpp b/src/catalog/catalog.cpp index 724df2a6d43..0787a18b80a 100644 --- a/src/catalog/catalog.cpp +++ b/src/catalog/catalog.cpp @@ -867,7 +867,7 @@ ResultType Catalog::ChangeColumnName(const std::string &database_name, table_oid, new_column.GetName(), columnId, new_column.GetOffset(), new_column.GetType(), new_column.IsInlined(), new_column.GetConstraints(), pool_.get(), txn); - + } catch (CatalogException &e) { return ResultType::FAILURE; } From ef6b9f41771a722cd336584c962d543ce8fca035 Mon Sep 17 00:00:00 2001 From: Shangjie Chen Date: Thu, 12 Apr 2018 02:06:48 +0000 Subject: [PATCH 33/58] Add transactional test --- script/testing/junit/AlterTableTest.java | 123 +++++++++++++++++++---- 1 file changed, 103 insertions(+), 20 deletions(-) diff --git a/script/testing/junit/AlterTableTest.java b/script/testing/junit/AlterTableTest.java index 630a93db882..0793f4123de 100644 --- a/script/testing/junit/AlterTableTest.java +++ b/script/testing/junit/AlterTableTest.java @@ -17,7 +17,7 @@ public class AlterTableTest extends PLTestBase { private Connection conn; - private String s_sql = "SELECT * FROM foo;"; + private Connection conn2; private static final String SQL_DROP_TABLE = "DROP TABLE IF EXISTS foo;"; @@ -27,6 +27,12 @@ public class AlterTableTest extends PLTestBase { "id integer, " + "year integer);"; + private static final String SQL_SELECT_STAR = "SELECT * FROM foo;"; + + private static final String SQL_RENAME_COLUMN = + "ALTER TABLE foo RENAME year to month;"; + + @Rule public ExpectedException thrown = ExpectedException.none(); @@ -37,12 +43,16 @@ private void InitDatabase() throws SQLException { Statement stmt = conn.createStatement(); stmt.execute(SQL_DROP_TABLE); stmt.execute(SQL_CREATE_TABLE); + + String sql = "INSERT INTO foo VALUES (5, 400);"; + conn.createStatement().execute(sql); } @Before public void Setup() throws SQLException { conn = makeDefaultConnection(); conn.setAutoCommit(true); + conn2 = makeDefaultConnection(); InitDatabase(); } @@ -57,29 +67,17 @@ public void Teardown() throws SQLException { */ @Test public void test_RenameColumn_1() throws SQLException { - String sql_1 = "INSERT INTO foo VALUES (5, 400);"; - conn.createStatement().execute(sql_1); - - ResultSet rs_1 = conn.createStatement().executeQuery(s_sql); - rs_1.next(); - checkRow(rs_1, - new String [] {"id", "year"}, - new int [] {5, 400}); - assertNoMoreRows(rs_1); - - String sql_2 = "ALTER TABLE foo RENAME year to month;"; - conn.createStatement().execute(sql_2); - ResultSet rs_2 = conn.createStatement().executeQuery(s_sql); - - rs_2.next(); - checkRow(rs_2, + conn.createStatement().execute(SQL_RENAME_COLUMN); + ResultSet rs = conn.createStatement().executeQuery(SQL_SELECT_STAR); + rs.next(); + checkRow(rs, new String [] {"id", "month"}, new int [] {5, 400}); - assertNoMoreRows(rs_2); + assertNoMoreRows(rs); } /** - * Rename a column that does not exist, should throw exception + * Rename a column that does not exists, should throw exception */ @Test public void test_RenameColumn_2() throws SQLException { @@ -91,7 +89,7 @@ public void test_RenameColumn_2() throws SQLException { } /** - * Rename a column to a name that already exists, should throw exception + * Rename a column that does not exists, should throw exception */ @Test public void test_RenameColumn_3() throws SQLException { @@ -102,4 +100,89 @@ public void test_RenameColumn_3() throws SQLException { conn.createStatement().execute(sql); } + /** + * Two transactions try to rename at the same time, should throw exception + */ + @Test + public void test_RenameColumn_4() throws SQLException { + conn.setAutoCommit(false); + conn2.setAutoCommit(false); + + conn.createStatement().execute(SQL_RENAME_COLUMN); + + thrown.expect(PSQLException.class); + conn2.createStatement().execute(SQL_RENAME_COLUMN); + + conn.commit(); + conn2.commit(); + } + +// The following tests are currently broken. +// @Test +// public void test_RenameColumn_5() throws SQLException { +// conn.setAutoCommit(false); +// conn2.setAutoCommit(false); +// +// String sql = "ALTER TABLE foo RENAME year to month;"; +// conn.createStatement().execute(sql); +// +// ResultSet rs = conn2.createStatement().executeQuery(SQL_SELECT_STAR); +// rs.next(); +// checkRow(rs, +// new String [] {"id", "year"}, +// new int [] {5, 400}); +// assertNoMoreRows(rs); +// +// conn.commit(); +// conn2.commit(); +// } +// +// /** +// * 2 transactions, t2 read the table before and after t1 change the column +// * name and should not see the changes. +// */ +// @Test +// public void test_RenameColumn_6() throws SQLException { +// conn.setAutoCommit(false); +// conn2.setAutoCommit(false); +// +// ResultSet rs_1 = conn2.createStatement().executeQuery(SQL_SELECT_STAR); +// rs_1.next(); +// checkRow(rs_1, +// new String [] {"id", "year"}, +// new int [] {5, 400}); +// assertNoMoreRows(rs_1); +// +// conn.createStatement().execute(SQL_RENAME_COLUMN); +// conn.commit(); +// +// ResultSet rs_2 = conn2.createStatement().executeQuery(SQL_SELECT_STAR); +// rs_2.next(); +// checkRow(rs_2, +// new String [] {"id", "year"}, +// new int [] {5, 400}); +// assertNoMoreRows(rs_2); +// conn2.commit(); +// } + +// @Test +// public void test_RenameColumn_7() throws SQLException { +// conn.setAutoCommit(false); +// conn2.setAutoCommit(false); +// +// Statement alter_statement = conn.createStatement(); +// Statement select_statement = conn2.createStatement(); +// +// alter_statement.execute(SQL_RENAME_COLUMN); +// conn.commit(); +// +// ResultSet rs = select_statement.executeQuery(SQL_SELECT_STAR); +// rs.next(); +// checkRow(rs, +// new String [] {"id", "year"}, +// new int [] {5, 400}); +// assertNoMoreRows(rs); +// conn2.commit(); +// } + } From 844e5647c5f75a87cf03e830c5ae93ca0f8ab57f Mon Sep 17 00:00:00 2001 From: Dean Chen Date: Sat, 28 Apr 2018 15:05:40 -0400 Subject: [PATCH 34/58] Fix mac compile error --- src/include/planner/alter_plan.h | 6 ++++-- src/include/planner/rename_plan.h | 8 +++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/include/planner/alter_plan.h b/src/include/planner/alter_plan.h index a65fb622c01..1148e7c6cc4 100644 --- a/src/include/planner/alter_plan.h +++ b/src/include/planner/alter_plan.h @@ -27,9 +27,11 @@ class AlterPlan : public AbstractPlan { } virtual ~AlterPlan() {} - virtual PlanNodeType GetPlanNodeType() { return PlanNodeType::ALTER; } + virtual PlanNodeType GetPlanNodeType() const override { + return PlanNodeType::ALTER; + } - virtual std::unique_ptr Copy() { return nullptr; } + virtual std::unique_ptr Copy() const override { return nullptr; } }; } } diff --git a/src/include/planner/rename_plan.h b/src/include/planner/rename_plan.h index 3d0f0429730..1542584d5e7 100644 --- a/src/include/planner/rename_plan.h +++ b/src/include/planner/rename_plan.h @@ -52,7 +52,9 @@ class RenamePlan : public AbstractPlan { virtual ~RenamePlan() {} - virtual PlanNodeType GetPlanNodeType() const { return PlanNodeType::RENAME; } + virtual PlanNodeType GetPlanNodeType() const override { + return PlanNodeType::RENAME; + } const std::string GetInfo() const override { return StringUtil::Format( @@ -63,12 +65,12 @@ class RenamePlan : public AbstractPlan { const_cast(this->db_name_.c_str())); } - std::unique_ptr Copy() const { + std::unique_ptr Copy() const override { return std::unique_ptr( new RenamePlan(this->obj_type, this->table_name_, this->db_name_, this->old_names_, this->new_names_)); } - + std::string GetOldName() const { return this->old_names_[0]; } std::string GetNewName() const { return this->new_names_[0]; } From 8cdea77db13e1b681c2f92c3981172a11777024e Mon Sep 17 00:00:00 2001 From: Dean Chen Date: Sat, 28 Apr 2018 19:40:28 -0400 Subject: [PATCH 35/58] Addressed comments in test and catalog --- script/testing/junit/AlterTableTest.java | 30 ++++++----- src/catalog/catalog.cpp | 63 ++++++++++++++++++------ src/executor/alter_executor.cpp | 9 ++-- src/include/catalog/catalog.h | 10 ++-- src/include/common/logger.h | 2 +- 5 files changed, 78 insertions(+), 36 deletions(-) diff --git a/script/testing/junit/AlterTableTest.java b/script/testing/junit/AlterTableTest.java index 0793f4123de..eb82edbc261 100644 --- a/script/testing/junit/AlterTableTest.java +++ b/script/testing/junit/AlterTableTest.java @@ -66,7 +66,7 @@ public void Teardown() throws SQLException { * Insert 1 tuple, rename the column, and see if the change is visible. */ @Test - public void test_RenameColumn_1() throws SQLException { + public void test_RenameCol_Base() throws SQLException { conn.createStatement().execute(SQL_RENAME_COLUMN); ResultSet rs = conn.createStatement().executeQuery(SQL_SELECT_STAR); rs.next(); @@ -80,7 +80,7 @@ public void test_RenameColumn_1() throws SQLException { * Rename a column that does not exists, should throw exception */ @Test - public void test_RenameColumn_2() throws SQLException { + public void test_RenameCol_NotExist() throws SQLException { String sql = "ALTER TABLE foo RENAME a to b;"; // Old column does not exist @@ -89,10 +89,10 @@ public void test_RenameColumn_2() throws SQLException { } /** - * Rename a column that does not exists, should throw exception + * Rename a column to a name that already exists, should throw exception */ @Test - public void test_RenameColumn_3() throws SQLException { + public void test_RenameCol_Exist() throws SQLException { String sql = "ALTER TABLE foo RENAME year to id;"; // New column already exists @@ -104,7 +104,7 @@ public void test_RenameColumn_3() throws SQLException { * Two transactions try to rename at the same time, should throw exception */ @Test - public void test_RenameColumn_4() throws SQLException { + public void test_RenameCol_Concurrent() throws SQLException { conn.setAutoCommit(false); conn2.setAutoCommit(false); @@ -118,8 +118,13 @@ public void test_RenameColumn_4() throws SQLException { } // The following tests are currently broken. +// +// /** +// * 2 transactions, t2 reads the table between t1 executes the rename +// * and commits the changes. +// */ // @Test -// public void test_RenameColumn_5() throws SQLException { +// public void test_RenameCol_ReadBeforeCommit() throws SQLException { // conn.setAutoCommit(false); // conn2.setAutoCommit(false); // @@ -138,11 +143,11 @@ public void test_RenameColumn_4() throws SQLException { // } // // /** -// * 2 transactions, t2 read the table before and after t1 change the column -// * name and should not see the changes. +// * 2 transactions, t2 reads the table before and after t1 changes the +// * column name and should not see the changes. // */ // @Test -// public void test_RenameColumn_6() throws SQLException { +// public void test_RenameCol_ReadBeforeAndAfterCommit() throws SQLException { // conn.setAutoCommit(false); // conn2.setAutoCommit(false); // @@ -164,9 +169,12 @@ public void test_RenameColumn_4() throws SQLException { // assertNoMoreRows(rs_2); // conn2.commit(); // } - +// +// /** +// * 2 transactions, t2 reads the table after t1 commits the changes. +// */ // @Test -// public void test_RenameColumn_7() throws SQLException { +// public void test_RenameCol_ReadAfterCommit() throws SQLException { // conn.setAutoCommit(false); // conn2.setAutoCommit(false); // diff --git a/src/catalog/catalog.cpp b/src/catalog/catalog.cpp index 0787a18b80a..5852b8340c7 100644 --- a/src/catalog/catalog.cpp +++ b/src/catalog/catalog.cpp @@ -791,7 +791,14 @@ std::shared_ptr Catalog::GetTableObject( //===--------------------------------------------------------------------===// // ALTER TABLE //===--------------------------------------------------------------------===// -/* Helper function for alter table, called internally + +/** + * @brief Helper function for alter table, called internally + * @param database_oid database to which the table belongs to + * @param table_oid table to which the column belongs to + * @param new_schema the new table schema + * @param txn the transaction Context + * @return TransactionContext ResultType(SUCCESS or FAILURE) */ ResultType Catalog::AlterTable( UNUSED_ATTRIBUTE oid_t database_oid, UNUSED_ATTRIBUTE oid_t table_oid, @@ -803,37 +810,65 @@ ResultType Catalog::AlterTable( return ResultType::SUCCESS; } +/** + * @brief Add new columns to the table. + * @param database_name database to which the table belongs to + * @param table_name table to which the column belongs to + * @param columns the column to be added + * @param txn the transaction Context + * @return TransactionContext ResultType(SUCCESS or FAILURE) + * + */ ResultType Catalog::AddColumn( UNUSED_ATTRIBUTE const std::string &database_name, UNUSED_ATTRIBUTE const std::string &table_name, UNUSED_ATTRIBUTE const std::vector &columns, UNUSED_ATTRIBUTE concurrency::TransactionContext *txn) { + // TODO: perform ADD Operation return ResultType::SUCCESS; } +/** + * @brief Drop the column from the table. + * @param database_name database to which the table belongs to + * @param table_name table to which the columns belong to + * @param columns the columns to be dropped + * @param txn the transaction Context + * @return TransactionContext ResultType(SUCCESS or FAILURE) + */ + ResultType Catalog::DropColumn( UNUSED_ATTRIBUTE const std::string &database_name, UNUSED_ATTRIBUTE const std::string &table_name, UNUSED_ATTRIBUTE const std::vector &columns, UNUSED_ATTRIBUTE concurrency::TransactionContext *txn) { + // TODO: perform DROP Operation return ResultType::SUCCESS; } -ResultType Catalog::ChangeColumnName(const std::string &database_name, - const std::string &table_name, - const std::vector &old_names, - const std::vector &names, - concurrency::TransactionContext *txn) { +/** + * @brief Change the column name in the catalog. + * @param database_name database to which the table belongs to + * @param table_name table to which the column belongs to + * @param columns the column to be dropped + * @param txn the transaction Context + * @return TransactionContext ResultType(SUCCESS or FAILURE) + */ +ResultType Catalog::RenameColumn(const std::string &database_name, + const std::string &table_name, + const std::string &old_name, + const std::string &new_name, + concurrency::TransactionContext *txn) { if (txn == nullptr) { throw CatalogException("Change Column requires transaction."); } - if (old_names.size() == 0 || names.size() == 0) { - throw CatalogException("No names are given."); + if (new_name.size() == 0) { + throw CatalogException("Name can not be empty string."); } - LOG_TRACE("Change Column Name %s to %s", old_names[0].c_str(), - names[0].c_str()); + LOG_TRACE("Change Column Name %s to %s", old_name.c_str(), + new_name.c_str()); try { // Get table from the name @@ -844,23 +879,23 @@ ResultType Catalog::ChangeColumnName(const std::string &database_name, // Currently we only support change the first column name! // Check the validity of old name and the new name - oid_t columnId = schema->GetColumnID(names[0]); + oid_t columnId = schema->GetColumnID(new_name); if (columnId != INVALID_OID) { throw CatalogException("New column already exists in the table."); } - columnId = schema->GetColumnID(old_names[0]); + columnId = schema->GetColumnID(old_name); if (columnId == INVALID_OID) { throw CatalogException("Old column does not exist in the table."); } // Change column name in the global schema - schema->ChangeColumnName(columnId, names[0]); + schema->ChangeColumnName(columnId, new_name); // Change cached ColumnCatalog oid_t table_oid = Catalog::GetInstance() ->GetTableObject(database_name, table_name, txn) ->GetTableOid(); - catalog::ColumnCatalog::GetInstance()->DeleteColumn(table_oid, old_names[0], + catalog::ColumnCatalog::GetInstance()->DeleteColumn(table_oid, old_name, txn); auto new_column = schema->GetColumn(columnId); catalog::ColumnCatalog::GetInstance()->InsertColumn( diff --git a/src/executor/alter_executor.cpp b/src/executor/alter_executor.cpp index 49845a14b63..015cf013daa 100644 --- a/src/executor/alter_executor.cpp +++ b/src/executor/alter_executor.cpp @@ -34,7 +34,7 @@ bool AlterExecutor::DInit() { } bool AlterExecutor::DExecute() { - LOG_TRACE("Executing Drop..."); + LOG_TRACE("Executing Alter..."); bool result = false; const planner::RenamePlan &node = GetPlanNode(); auto current_txn = executor_context_->GetTransaction(); @@ -60,16 +60,15 @@ bool AlterExecutor::RenameColumn( auto new_column_name = node.GetNewName(); auto old_column_name = node.GetOldName(); - std::vector old_names = {old_column_name}; - std::vector names = {new_column_name}; - ResultType result = catalog::Catalog::GetInstance()->ChangeColumnName( - database_name, table_name, old_names, names, txn); + ResultType result = catalog::Catalog::GetInstance()->RenameColumn( + database_name, table_name, old_column_name, new_column_name, txn); txn->SetResult(result); if (txn->GetResult() == ResultType::SUCCESS) { LOG_TRACE("Rename column succeeded!"); // Add on succeed logic if necessary + executor_context_->num_processed = 1; } else { LOG_TRACE("Result is: %s", ResultTypeToString(txn->GetResult()).c_str()); } diff --git a/src/include/catalog/catalog.h b/src/include/catalog/catalog.h index 4092ed90631..ae7758228e6 100644 --- a/src/include/catalog/catalog.h +++ b/src/include/catalog/catalog.h @@ -194,11 +194,11 @@ class Catalog { const std::vector &columns, concurrency::TransactionContext *txn); - ResultType ChangeColumnName(const std::string &database_name, - const std::string &table_name, - const std::vector &old_columns, - const std::vector &names, - concurrency::TransactionContext *txn); + ResultType RenameColumn(const std::string &database_name, + const std::string &table_name, + const std::string &old_name, + const std::string &new_name, + concurrency::TransactionContext *txn); //===--------------------------------------------------------------------===// // DEPRECATED FUNCTIONS diff --git a/src/include/common/logger.h b/src/include/common/logger.h index bd57c1f20fd..72a4286251a 100644 --- a/src/include/common/logger.h +++ b/src/include/common/logger.h @@ -46,7 +46,7 @@ namespace peloton { #define LOG_LOG_TIME_FORMAT "%Y-%m-%d %H:%M:%S" #define LOG_OUTPUT_STREAM stdout -#define LOG_LEVEL LOG_LEVEL_TRACE + // Compile Option #ifndef LOG_LEVEL // TODO : any way to use pragma message in GCC? From c70353ea01bc24d6a2a8ea9c6d3ab5eafbadb2d9 Mon Sep 17 00:00:00 2001 From: Shaoxiong Zhang Date: Sat, 7 Apr 2018 10:18:04 -0400 Subject: [PATCH 36/58] add rename column executor --- src/include/executor/executors.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/include/executor/executors.h b/src/include/executor/executors.h index 38a0fb606fa..cbc8184b470 100644 --- a/src/include/executor/executors.h +++ b/src/include/executor/executors.h @@ -39,3 +39,4 @@ #include "executor/projection_executor.h" #include "executor/seq_scan_executor.h" #include "executor/update_executor.h" +#include "executor/alter_executor.h" From d3b1321488018720407d30a61eb71f9f641888fd Mon Sep 17 00:00:00 2001 From: Shaoxiong Zhang Date: Sun, 8 Apr 2018 01:24:33 -0400 Subject: [PATCH 37/58] fix --- src/include/executor/executors.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/include/executor/executors.h b/src/include/executor/executors.h index cbc8184b470..38a0fb606fa 100644 --- a/src/include/executor/executors.h +++ b/src/include/executor/executors.h @@ -39,4 +39,3 @@ #include "executor/projection_executor.h" #include "executor/seq_scan_executor.h" #include "executor/update_executor.h" -#include "executor/alter_executor.h" From 6a294fc1216833eca7196aff81f668d37ab1c46e Mon Sep 17 00:00:00 2001 From: dingshilun Date: Thu, 5 Apr 2018 16:52:21 -0400 Subject: [PATCH 38/58] This commit added parser support of alter table - added alter and rename plan and statements - modified optimizor to bind db name and make plans - modified parsenodes - added node to string support and vice versa - added nodetransform of alter table --- src/include/parser/alter_statement.h | 32 +++--- .../parser/rename_function_statement.h | 53 ---------- src/include/planner/alter_plan.h | 95 ++++++++++++++++-- src/include/planner/rename_plan.h | 97 ------------------- 4 files changed, 108 insertions(+), 169 deletions(-) delete mode 100644 src/include/parser/rename_function_statement.h delete mode 100644 src/include/planner/rename_plan.h diff --git a/src/include/parser/alter_statement.h b/src/include/parser/alter_statement.h index a733f988e4f..f3e03171bcf 100644 --- a/src/include/parser/alter_statement.h +++ b/src/include/parser/alter_statement.h @@ -22,36 +22,42 @@ namespace parser { * @brief Represents "ALTER TABLE add column COLUMN_NAME COLUMN_TYPE" * TODO: add implementation of AlterTableStatement */ -class AlterTableStatement : public TableRefStatement { - public: - enum class AlterTableType { INVALID = 0, ADD = 1, DROP = 2 }; +struct AlterTableStatement : TableRefStatement { + enum class AlterTableType { INVALID = 0, ADD = 1, DROP = 2, RENAME = 3 }; AlterTableStatement(AlterTableType type) : TableRefStatement(StatementType::ALTER), type(type), - names(new std::vector) {} + names(new std::vector), + oldName(nullptr), + newName(nullptr) + {}; virtual ~AlterTableStatement() { + /*if (columns != nullptr) { + for (auto col : *columns) delete col; + delete columns; + }*/ if (names != nullptr) { for (auto name : *names) delete name; delete names; } + if (oldName) delete oldName; + if (newName) delete newName; } - virtual void Accept(SqlNodeVisitor *v) override { v->Visit(this); } - - const std::string GetInfo(UNUSED_ATTRIBUTE int num_indent) const override { - return std::string{}; - } - - const std::string GetInfo() const override { return std::string{}; } + virtual void Accept(SqlNodeVisitor* v) override { v->Visit(this); } AlterTableType type; // Dropped columns - std::vector *names; + std::vector* names; // Added columns - // std::vector* columns; + //std::vector* columns; + + // the name that needs to be changed + char *oldName; + char *newName; }; } // End parser namespace diff --git a/src/include/parser/rename_function_statement.h b/src/include/parser/rename_function_statement.h deleted file mode 100644 index 1a07a1ef4a6..00000000000 --- a/src/include/parser/rename_function_statement.h +++ /dev/null @@ -1,53 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Peloton -// -// rename_function_statement.h -// -// Identification: src/include/parser/rename_function_statement.h -// -// Copyright (c) 2015-17, Carnegie Mellon University Database Group -// -//===----------------------------------------------------------------------===// - -#pragma once - -#include "parser/sql_statement.h" -#include "common/sql_node_visitor.h" - -namespace peloton { -namespace parser { -/** @brief Rename statement - * The statement that used for transform from postgress statement - * to Peloton statement - */ -class RenameFuncStatement : public TableRefStatement { - public: - enum class ObjectType { INVALID = 0, COLUMN = 1 }; - RenameFuncStatement(ObjectType type) - : TableRefStatement(StatementType::RENAME), - type(type), - oldName(nullptr), - newName(nullptr) {} - - virtual ~RenameFuncStatement() { - if (oldName) delete oldName; - if (newName) delete newName; - } - - virtual void Accept(SqlNodeVisitor *v) override { v->Visit(this); } - - const std::string GetInfo(UNUSED_ATTRIBUTE int num_indent) const override { - return std::string{""}; - } - - const std::string GetInfo() const override { return std::string{""}; } - - ObjectType type; - - // the name that needs to be changed - char *oldName; - char *newName; -}; -} -} \ No newline at end of file diff --git a/src/include/planner/alter_plan.h b/src/include/planner/alter_plan.h index 1148e7c6cc4..420b6700357 100644 --- a/src/include/planner/alter_plan.h +++ b/src/include/planner/alter_plan.h @@ -15,6 +15,16 @@ #include "parser/alter_statement.h" namespace peloton { +namespace parser { +class AlterTableStatement; +} +namespace catalog { +class Schema; +} +namespace storage { +class DataTable; +} + namespace planner { /** @brief The plan used for altering * TODO: adding support for add/drop column @@ -22,16 +32,89 @@ namespace planner { class AlterPlan : public AbstractPlan { public: AlterPlan() = delete; - explicit AlterPlan(UNUSED_ATTRIBUTE parser::AlterTableStatement *parse_tree) { - LOG_TRACE("%s", parse_tree->GetInfo().c_str()); - } + + explicit AlterPlan(const std::string &database_name, + const std::string &table_name, + //std::unique_ptr added_columns, + const std::vector &dropped_columns, + AlterType a_type); + explicit AlterPlan(const std::string &database_name, + const std::string &table_name, + const std::vector &old_names, + const std::vector &new_names, AlterType a_type); + explicit AlterPlan(parser::AlterTableStatement *parse_tree); + virtual ~AlterPlan() {} - virtual PlanNodeType GetPlanNodeType() const override { - return PlanNodeType::ALTER; + virtual PlanNodeType GetPlanNodeType() const { return PlanNodeType::ALTER; } + + virtual std::unique_ptr Copy() { return nullptr; } + + const std::string GetInfo() const { + return StringUtil::Format("AlterPlan table:%s, database:%s", + this->table_name.c_str(), this->database_name.c_str()); + } + + std::unique_ptr Copy() const { + switch(this->type) { + case AlterType::DROP: + case AlterType::ADD: + return std::unique_ptr( + new AlterPlan(database_name, table_name, + //std::unique_ptr( + // catalog::Schema::CopySchema(added_columns)), + dropped_columns, type)); + case AlterType::RENAME: + return std::unique_ptr( + new AlterPlan(database_name, table_name, old_names_, new_names_, type)); + default: + LOG_ERROR("Not supported Copy of Alter type yet"); + return nullptr; + } } - virtual std::unique_ptr Copy() const override { return nullptr; } + std::string GetTableName() const { return table_name; } + + std::string GetDatabaseName() const { return database_name; } + + //catalog::Schema *GetAddedColumns() const { return added_columns; } + + const std::vector &GetDroppedColumns() const { + return dropped_columns; + } + + AlterType GetAlterTableType() const { return type; } + + //function used for rename statement + std::string GetOldName() const { return this->old_names_[0]; } + + //function used for rename statement + std::string GetNewName() const { return this->new_names_[0]; } + + //return true if the alter plan is rename statement + bool IsRename() const { return this->type==AlterType::RENAME;} +private: +// Target Table + storage::DataTable *target_table_ = nullptr; + + // Table Name + std::string table_name; + + // Database Name + std::string database_name; + + // Schema delta, define the column txn want to add + // catalog::Schema *added_columns; + // dropped_column, define the column you want to drop + std::vector dropped_columns; + + //used for store rename function data + std::vector old_names_; + std::vector new_names_; + + // Check to either AlterTable Table, INDEX or Rename + AlterType type; + }; } } diff --git a/src/include/planner/rename_plan.h b/src/include/planner/rename_plan.h deleted file mode 100644 index 1542584d5e7..00000000000 --- a/src/include/planner/rename_plan.h +++ /dev/null @@ -1,97 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Peloton -// -// rename_plan.h -// -// Identification: src/include/parser/rename_plan.h -// -// Copyright (c) 2015-17, Carnegie Mellon University Database Group -// -//===----------------------------------------------------------------------===// - -#pragma once - -#include "planner/abstract_plan.h" -#include "parser/rename_function_statement.h" - -/** @brief: The Plan used for rename - * The plan contains the necessary information for - * renaming, including old names, new names and - * which object and database - */ -namespace peloton { -namespace planner { -class RenamePlan : public AbstractPlan { - public: - explicit RenamePlan() = delete; - - explicit RenamePlan(parser::RenameFuncStatement *tree) - : AbstractPlan(), - obj_type(tree->type), - table_name_(tree->table_info_->table_name), - db_name_(tree->GetDatabaseName()) { - old_names_.emplace_back(std::string{tree->oldName}); - new_names_.emplace_back(std::string{tree->newName}); - LOG_TRACE("Build rename plan table: %s, db: %s, oldname: %s, new name: %s", - const_cast(table_name_.c_str()), - const_cast(db_name_.c_str()), - const_cast(old_names_[0].c_str()), - const_cast(new_names_[0].c_str())); - } - - RenamePlan(parser::RenameFuncStatement::ObjectType obj_t, std::string tb_name, - std::string db_name, std::vector old_names, - std::vector new_names) - : AbstractPlan(), - old_names_(old_names), - new_names_(new_names), - obj_type(obj_t), - table_name_(tb_name), - db_name_(db_name) {} - - virtual ~RenamePlan() {} - - virtual PlanNodeType GetPlanNodeType() const override { - return PlanNodeType::RENAME; - } - - const std::string GetInfo() const override { - return StringUtil::Format( - "Rename Object %d, old name %s, new name %s, table %s, db %s\n", - this->obj_type, const_cast(this->old_names_[0].c_str()), - const_cast(this->new_names_[0].c_str()), - const_cast(this->table_name_.c_str()), - const_cast(this->db_name_.c_str())); - } - - std::unique_ptr Copy() const override { - return std::unique_ptr( - new RenamePlan(this->obj_type, this->table_name_, this->db_name_, - this->old_names_, this->new_names_)); - } - - std::string GetOldName() const { return this->old_names_[0]; } - - std::string GetNewName() const { return this->new_names_[0]; } - - std::string GetDatabaseName() const { return this->db_name_; } - - std::string GetTableName() const { return this->table_name_; } - - parser::RenameFuncStatement::ObjectType GetObjectType() { - return this->obj_type; - } - - private: - // those names are corresponding with their indexes - std::vector old_names_; - std::vector new_names_; - - parser::RenameFuncStatement::ObjectType obj_type; - - std::string table_name_; - std::string db_name_; -}; -} -} From f7af80f1e9023ad0525bd436244325950e9372bb Mon Sep 17 00:00:00 2001 From: dingshilun Date: Sun, 15 Apr 2018 22:27:05 -0400 Subject: [PATCH 39/58] added alter table drop column parser, planner, and catalog support, waiting for executor --- src/catalog/catalog.cpp | 18 +++++-- src/include/common/internal_types.h | 2 + src/optimizer/optimizer.cpp | 5 +- src/parser/postgresparser.cpp | 40 +++++++-------- src/planner/alter_plan.cpp | 75 +++++++++++++++++++++++++++++ 5 files changed, 115 insertions(+), 25 deletions(-) create mode 100644 src/planner/alter_plan.cpp diff --git a/src/catalog/catalog.cpp b/src/catalog/catalog.cpp index 0787a18b80a..730d5823404 100644 --- a/src/catalog/catalog.cpp +++ b/src/catalog/catalog.cpp @@ -812,10 +812,20 @@ ResultType Catalog::AddColumn( } ResultType Catalog::DropColumn( - UNUSED_ATTRIBUTE const std::string &database_name, - UNUSED_ATTRIBUTE const std::string &table_name, - UNUSED_ATTRIBUTE const std::vector &columns, - UNUSED_ATTRIBUTE concurrency::TransactionContext *txn) { + const std::string &database_name, + const std::string &table_name, + const std::vector &columns, + concurrency::TransactionContext *txn) { + try { + oid_t table_oid = Catalog::GetInstance() + ->GetTableObject(database_name, table_name, txn) + ->GetTableOid(); + for (std::string name: columns) { + catalog::ColumnCatalog::GetInstance()->DeleteColumn(table_oid, name, txn); + } + } catch(CatalogException &e){ + return ResultType::FAILURE; + } return ResultType::SUCCESS; } diff --git a/src/include/common/internal_types.h b/src/include/common/internal_types.h index 5b198050e8e..895042c6732 100644 --- a/src/include/common/internal_types.h +++ b/src/include/common/internal_types.h @@ -646,6 +646,8 @@ std::ostream &operator<<(std::ostream &os, const DropType &type); enum class AlterType { INVALID = INVALID_TYPE_ID, // invalid alter type RENAME = 1, // rename table, column, database... + ADD = 2, + DROP = 3 }; std::string AlterTypeToString(AlterType type); AlterType StringToAlterType(const std::string &str); diff --git a/src/optimizer/optimizer.cpp b/src/optimizer/optimizer.cpp index bb17abbd634..4edbde21056 100644 --- a/src/optimizer/optimizer.cpp +++ b/src/optimizer/optimizer.cpp @@ -149,7 +149,10 @@ unique_ptr Optimizer::HandleDDLStatement( switch (stmt_type) { case StatementType::ALTER: { // TODO (shilun) adding support of Alter - LOG_TRACE("TO BE Implemented..."); + LOG_TRACE("Adding Alter Plan"); + unique_ptr alter_plan( + new planner::AlterPlan((parser::AlterTableStatement *)tree)); + ddl_plan = move(alter_plan); break; } case StatementType::RENAME: { diff --git a/src/parser/postgresparser.cpp b/src/parser/postgresparser.cpp index 2a336fe049f..2a0217277a2 100644 --- a/src/parser/postgresparser.cpp +++ b/src/parser/postgresparser.cpp @@ -1732,13 +1732,13 @@ parser::TransactionStatement *PostgresParser::TransactionTransform( parser::AlterTableStatement *PostgresParser::AlterTransform( AlterTableStmt *root) { // TODO (shilun) adding alter type check - parser::AlterTableStatement *result = new AlterTableStatement( - parser::AlterTableStatement::AlterTableType::INVALID); + // Currently we only support add/drop column type + parser::AlterTableStatement* result = + new AlterTableStatement(AlterTableStatement::AlterTableType::INVALID); // Get database and table name - RangeVar *relation = root->relation; - result->table_info_ = - std::unique_ptr(new parser::TableInfo()); + RangeVar* relation = root->relation; + result->table_info_ = std::unique_ptr(new parser::TableInfo()); if (relation->relname) { result->table_info_->table_name = strdup(relation->relname); } @@ -1747,22 +1747,22 @@ parser::AlterTableStatement *PostgresParser::AlterTransform( } for (auto cell = root->cmds->head; cell != NULL; cell = cell->next) { - auto cmd = reinterpret_cast(cell->data.ptr_value); + auto cmd = reinterpret_cast(cell->data.ptr_value); switch (cmd->subtype) { - /*case AT_AddColumn: { - auto column = - ColumnDefTransform(reinterpret_cast(cmd->def)); - result->columns->push_back(column); - break; - } - case AT_DropColumn: - result->names->push_back(strdup(cmd->name)); - break; - case AT_AlterColumnGenericOptions:*/ - default: { - throw NotImplementedException(StringUtil::Format( - "Alter Table type %d not supported yet...\n", cmd->subtype)); - } + /*case AT_AddColumn: { + auto column = + ColumnDefTransform(reinterpret_cast(cmd->def)); + result->columns->push_back(column); + break; + }*/ + case AT_DropColumn: + result->names->push_back(strdup(cmd->name)); + result->type = AlterTableStatement::AlterTableType::DROP; + break; + default: { + throw NotImplementedException(StringUtil::Format( + "Alter Table type %d not supported yet...\n", cmd->subtype)); + } } } return result; diff --git a/src/planner/alter_plan.cpp b/src/planner/alter_plan.cpp new file mode 100644 index 00000000000..7b0576522f7 --- /dev/null +++ b/src/planner/alter_plan.cpp @@ -0,0 +1,75 @@ +//===----------------------------------------------------------------------===// +// +// Peloton +// +// alter_table_plan.cpp +// +// Identification: src/planner/alter_table_plan.cpp +// +// Copyright (c) 2015-16, Carnegie Mellon University Database Group +// +//===----------------------------------------------------------------------===// + +#include "planner/alter_plan.h" + +#include "catalog/column.h" +#include "catalog/schema.h" +#include "parser/alter_statement.h" +#include "storage/data_table.h" + +namespace peloton { +namespace planner { + +AlterPlan::AlterPlan(const std::string &database_name, + const std::string &table_name, + //std::unique_ptr added_columns, + const std::vector &dropped_columns, + AlterType a_type) + : table_name(table_name), + database_name(database_name), + //added_columns(added_columns.release()), + dropped_columns(dropped_columns), + type(a_type) {} + +AlterPlan::AlterPlan(parser::AlterTableStatement *parse_tree) { + table_name = std::string(parse_tree->GetTableName()); + database_name = std::string(parse_tree->GetDatabaseName()); + switch (parse_tree->type){ + case parser::AlterTableStatement::AlterTableType::DROP: + for (auto col : *parse_tree->names) { + LOG_TRACE("Drooped column name: %s", col); + dropped_columns.push_back(std::string(col)); + type = AlterType::DROP; + } + case parser::AlterTableStatement::AlterTableType::ADD: + default: + LOG_TRACE("Not Implemented the plan yet!"); + } + //std::vector columns; + // case 1: add column(column name + column data type) + //if (parse_tree->type == AlterTableType::COLUMN) { + // Add columns: traverse through vector of ColumnDefinition + /*for (auto col : *parse_tree->columns) { + type::TypeId val = col->GetValueType(col->type); + LOG_TRACE("Column name: %s", col->name); + + bool is_inline = (val == type::TypeId::VARCHAR) ? false : true; + auto column = catalog::Column(val, type::Type::GetTypeSize(val), + std::string(col->name), is_inline); + LOG_TRACE("Column is_line: %d", is_inline); + // Add not_null constraints + if (col->not_null) { + catalog::Constraint constraint(ConstraintType::NOTNULL, "con_not_null"); + column.AddConstraint(constraint); + } + columns.push_back(column); + } + added_columns = new catalog::Schema(columns);*/ + + // Drop columns: traverse through vector of char*(column name) + + } + + +} // namespace planner +} // namespace peloton From d7465e3e391079b9030975ee7692c572fcdfa27c Mon Sep 17 00:00:00 2001 From: Shaoxiong Zhang Date: Mon, 16 Apr 2018 00:20:42 -0400 Subject: [PATCH 40/58] add drop column executor --- src/executor/alter_executor.cpp | 49 ++++++++++++++++++++------- src/executor/plan_executor.cpp | 7 +++- src/include/executor/alter_executor.h | 8 ++++- 3 files changed, 50 insertions(+), 14 deletions(-) diff --git a/src/executor/alter_executor.cpp b/src/executor/alter_executor.cpp index 49845a14b63..aa868954d92 100644 --- a/src/executor/alter_executor.cpp +++ b/src/executor/alter_executor.cpp @@ -21,8 +21,8 @@ namespace executor { // Constructor for alter table executor AlterExecutor::AlterExecutor(const planner::AbstractPlan *node, - ExecutorContext *executor_context) - : AbstractExecutor(node, executor_context) {} + ExecutorContext *executor_context, bool isAlter) + : AbstractExecutor(node, executor_context), isAlter_(isAlter) {} // Initialize executor // Nothing to initialize for now @@ -36,17 +36,22 @@ bool AlterExecutor::DInit() { bool AlterExecutor::DExecute() { LOG_TRACE("Executing Drop..."); bool result = false; - const planner::RenamePlan &node = GetPlanNode(); - auto current_txn = executor_context_->GetTransaction(); - PlanNodeType plan_node_type = node.GetPlanNodeType(); - if (plan_node_type == PlanNodeType::RENAME) { + if (!isAlter_) { + const planner::RenamePlan &node = GetPlanNode(); + auto current_txn = executor_context_->GetTransaction(); result = RenameColumn(node, current_txn); - } else if (plan_node_type == PlanNodeType::ALTER) { - LOG_TRACE("Will perform alter table operations"); } else { - throw NotImplementedException( - StringUtil::Format("Plan node type not supported, %s", - PlanNodeTypeToString(plan_node_type).c_str())); + const planner::AlterPlan &node = GetPlanNode(); + auto current_txn = executor_context_->GetTransaction(); + AlterType type = node.GetAlterTableType(); + switch (type) { + case AlterType::DROP: + result = DropColumn(node, current_txn); + break; + default: + throw NotImplementedException(StringUtil::Format( + "Alter Type not supported, %s", AlterTypeToString(type).c_str())); + } } return result; @@ -69,7 +74,27 @@ bool AlterExecutor::RenameColumn( if (txn->GetResult() == ResultType::SUCCESS) { LOG_TRACE("Rename column succeeded!"); - // Add on succeed logic if necessary + // TODO Add on succeed logic if necessary + } else { + LOG_TRACE("Result is: %s", ResultTypeToString(txn->GetResult()).c_str()); + } + return false; +} + +bool AlterExecutor::DropColumn(const peloton::planner::AlterPlan &node, + peloton::concurrency::TransactionContext *txn) { + auto database_name = node.GetDatabaseName(); + auto table_name = node.GetTableName(); + auto drop_columns = node.GetDroppedColumns(); + + ResultType result = catalog::Catalog::GetInstance()->DropColumn( + database_name, table_name, drop_columns, txn); + txn->SetResult(result); + + if (txn->GetResult() == ResultType::SUCCESS) { + LOG_TRACE("Drop column succeed!"); + + // TODO Add on succeed logic if necessary } else { LOG_TRACE("Result is: %s", ResultTypeToString(txn->GetResult()).c_str()); } diff --git a/src/executor/plan_executor.cpp b/src/executor/plan_executor.cpp index 855de14d498..de6a81b1513 100644 --- a/src/executor/plan_executor.cpp +++ b/src/executor/plan_executor.cpp @@ -337,7 +337,12 @@ executor::AbstractExecutor *BuildExecutorTree( new executor::PopulateIndexExecutor(plan, executor_context); break; case PlanNodeType::RENAME: - child_executor = new executor::AlterExecutor(plan, executor_context); + child_executor = + new executor::AlterExecutor(plan, executor_context, false); + break; + case PlanNodeType::ALTER: + child_executor = + new executor::AlterExecutor(plan, executor_context, true); break; default: LOG_ERROR("Unsupported plan node type : %s", diff --git a/src/include/executor/alter_executor.h b/src/include/executor/alter_executor.h index d2e271f0f16..0768ecf7309 100644 --- a/src/include/executor/alter_executor.h +++ b/src/include/executor/alter_executor.h @@ -33,7 +33,7 @@ class AlterExecutor : public AbstractExecutor { AlterExecutor &operator=(AlterExecutor &&) = delete; AlterExecutor(const planner::AbstractPlan *node, - ExecutorContext *executor_context); + ExecutorContext *executor_context, bool isAlter); ~AlterExecutor() {} @@ -44,6 +44,12 @@ class AlterExecutor : public AbstractExecutor { bool RenameColumn(const planner::RenamePlan &node, concurrency::TransactionContext *txn); + + bool DropColumn(const planner::AlterPlan &node, + concurrency::TransactionContext *txn); + + private: + bool isAlter_; }; } // executor From bf20b05331edafad4f081bc21866011da51996f1 Mon Sep 17 00:00:00 2001 From: dingshilun Date: Fri, 27 Apr 2018 23:07:22 -0400 Subject: [PATCH 41/58] refacted the rename into alter (parser, planner) --- src/binder/bind_node_visitor.cpp | 3 - src/executor/alter_executor.cpp | 9 +- src/executor/plan_executor.cpp | 6 +- src/include/binder/bind_node_visitor.h | 1 - src/include/common/sql_node_visitor.h | 2 - src/include/executor/alter_executor.h | 5 +- src/include/optimizer/query_node_visitor.h | 1 - .../optimizer/query_to_operator_transformer.h | 1 - src/include/parser/postgresparser.h | 4 +- src/include/parser/statements.h | 1 - src/optimizer/optimizer.cpp | 9 -- .../query_to_operator_transformer.cpp | 2 - src/parser/postgresparser.cpp | 140 +++++++++--------- src/planner/alter_plan.cpp | 50 +++++-- 14 files changed, 115 insertions(+), 119 deletions(-) diff --git a/src/binder/bind_node_visitor.cpp b/src/binder/bind_node_visitor.cpp index 8f3373ddca5..2a161a55ab3 100644 --- a/src/binder/bind_node_visitor.cpp +++ b/src/binder/bind_node_visitor.cpp @@ -190,9 +190,6 @@ void BindNodeVisitor::Visit(parser::TransactionStatement *) {} void BindNodeVisitor::Visit(parser::AlterTableStatement *node) { node->TryBindDatabaseName(default_database_name_); } -void BindNodeVisitor::Visit(parser::RenameFuncStatement *node) { - node->TryBindDatabaseName(default_database_name_); -} void BindNodeVisitor::Visit(parser::AnalyzeStatement *node) { node->TryBindDatabaseName(default_database_name_); } diff --git a/src/executor/alter_executor.cpp b/src/executor/alter_executor.cpp index aa868954d92..a268ed7836e 100644 --- a/src/executor/alter_executor.cpp +++ b/src/executor/alter_executor.cpp @@ -21,8 +21,9 @@ namespace executor { // Constructor for alter table executor AlterExecutor::AlterExecutor(const planner::AbstractPlan *node, - ExecutorContext *executor_context, bool isAlter) - : AbstractExecutor(node, executor_context), isAlter_(isAlter) {} + ExecutorContext *executor_context) + : AbstractExecutor(node, executor_context), + isAlter_(!reinterpret_cast(node)->IsRename()) {} // Initialize executor // Nothing to initialize for now @@ -37,7 +38,7 @@ bool AlterExecutor::DExecute() { LOG_TRACE("Executing Drop..."); bool result = false; if (!isAlter_) { - const planner::RenamePlan &node = GetPlanNode(); + const planner::AlterPlan &node = GetPlanNode(); auto current_txn = executor_context_->GetTransaction(); result = RenameColumn(node, current_txn); } else { @@ -58,7 +59,7 @@ bool AlterExecutor::DExecute() { } bool AlterExecutor::RenameColumn( - const peloton::planner::RenamePlan &node, + const peloton::planner::AlterPlan &node, peloton::concurrency::TransactionContext *txn) { auto database_name = node.GetDatabaseName(); auto table_name = node.GetTableName(); diff --git a/src/executor/plan_executor.cpp b/src/executor/plan_executor.cpp index de6a81b1513..74105756902 100644 --- a/src/executor/plan_executor.cpp +++ b/src/executor/plan_executor.cpp @@ -336,13 +336,9 @@ executor::AbstractExecutor *BuildExecutorTree( child_executor = new executor::PopulateIndexExecutor(plan, executor_context); break; - case PlanNodeType::RENAME: - child_executor = - new executor::AlterExecutor(plan, executor_context, false); - break; case PlanNodeType::ALTER: child_executor = - new executor::AlterExecutor(plan, executor_context, true); + new executor::AlterExecutor(plan, executor_context); break; default: LOG_ERROR("Unsupported plan node type : %s", diff --git a/src/include/binder/bind_node_visitor.h b/src/include/binder/bind_node_visitor.h index ab84e5548ac..3812e1f8e0d 100644 --- a/src/include/binder/bind_node_visitor.h +++ b/src/include/binder/bind_node_visitor.h @@ -68,7 +68,6 @@ class BindNodeVisitor : public SqlNodeVisitor { void Visit(parser::CopyStatement *) override; void Visit(parser::AnalyzeStatement *) override; void Visit(parser::AlterTableStatement *) override; - void Visit(parser::RenameFuncStatement *) override; void Visit(expression::CaseExpression *expr) override; void Visit(expression::SubqueryExpression *expr) override; diff --git a/src/include/common/sql_node_visitor.h b/src/include/common/sql_node_visitor.h index 53346eb933c..2adcbb19696 100644 --- a/src/include/common/sql_node_visitor.h +++ b/src/include/common/sql_node_visitor.h @@ -21,7 +21,6 @@ class CreateFunctionStatement; class InsertStatement; class DeleteStatement; class DropStatement; -class RenameFuncStatement; class AlterTableStatement; class ExplainStatement; class PrepareStatement; @@ -84,7 +83,6 @@ class SqlNodeVisitor { virtual void Visit(parser::CopyStatement *) {} virtual void Visit(parser::AnalyzeStatement *) {} virtual void Visit(parser::AlterTableStatement *) {} - virtual void Visit(parser::RenameFuncStatement *) {} virtual void Visit(parser::ExplainStatement *){}; virtual void Visit(expression::ComparisonExpression *expr); diff --git a/src/include/executor/alter_executor.h b/src/include/executor/alter_executor.h index 0768ecf7309..500b4e679b9 100644 --- a/src/include/executor/alter_executor.h +++ b/src/include/executor/alter_executor.h @@ -15,7 +15,6 @@ #include "concurrency/transaction_context.h" #include "executor/abstract_executor.h" #include "planner/alter_plan.h" -#include "planner/rename_plan.h" namespace peloton { @@ -33,7 +32,7 @@ class AlterExecutor : public AbstractExecutor { AlterExecutor &operator=(AlterExecutor &&) = delete; AlterExecutor(const planner::AbstractPlan *node, - ExecutorContext *executor_context, bool isAlter); + ExecutorContext *executor_context); ~AlterExecutor() {} @@ -42,7 +41,7 @@ class AlterExecutor : public AbstractExecutor { bool DExecute(); - bool RenameColumn(const planner::RenamePlan &node, + bool RenameColumn(const planner::AlterPlan &node, concurrency::TransactionContext *txn); bool DropColumn(const planner::AlterPlan &node, diff --git a/src/include/optimizer/query_node_visitor.h b/src/include/optimizer/query_node_visitor.h index 7f611c63e30..305be8e972a 100644 --- a/src/include/optimizer/query_node_visitor.h +++ b/src/include/optimizer/query_node_visitor.h @@ -29,7 +29,6 @@ class CopyStatement; class AnalyzeStatement; class VariableSetStatement; class JoinDefinition; -class RenameFuncStatement; class AlterTableStatement; struct TableRef; diff --git a/src/include/optimizer/query_to_operator_transformer.h b/src/include/optimizer/query_to_operator_transformer.h index 7fcd4e59bfb..103aade4922 100644 --- a/src/include/optimizer/query_to_operator_transformer.h +++ b/src/include/optimizer/query_to_operator_transformer.h @@ -63,7 +63,6 @@ class QueryToOperatorTransformer : public SqlNodeVisitor { void Visit(parser::UpdateStatement *op) override; void Visit(parser::CopyStatement *op) override; void Visit(parser::AnalyzeStatement *op) override; - void Visit(parser::RenameFuncStatement *op) override; void Visit(parser::AlterTableStatement *op) override; void Visit(expression::ComparisonExpression *expr) override; void Visit(expression::OperatorExpression *expr) override; diff --git a/src/include/parser/postgresparser.h b/src/include/parser/postgresparser.h index 9a23517dbeb..87345629cbd 100644 --- a/src/include/parser/postgresparser.h +++ b/src/include/parser/postgresparser.h @@ -293,10 +293,8 @@ class PostgresParser { static expression::AbstractExpression *SubqueryExprTransform(SubLink *node); // transform helper for alter table statement - static parser::AlterTableStatement *AlterTransform(AlterTableStmt *root); + static parser::AlterTableStatement *AlterTransform(Node *root); - // transform helper for alter rename statement - static parser::RenameFuncStatement *RenameTransform(RenameStmt *root); }; } // namespace parser diff --git a/src/include/parser/statements.h b/src/include/parser/statements.h index e668794a8f5..3b062c02748 100644 --- a/src/include/parser/statements.h +++ b/src/include/parser/statements.h @@ -25,7 +25,6 @@ #include "explain_statement.h" #include "insert_statement.h" #include "prepare_statement.h" -#include "rename_function_statement.h" #include "select_statement.h" #include "sql_statement.h" #include "transaction_statement.h" diff --git a/src/optimizer/optimizer.cpp b/src/optimizer/optimizer.cpp index 4edbde21056..918a95107b7 100644 --- a/src/optimizer/optimizer.cpp +++ b/src/optimizer/optimizer.cpp @@ -42,7 +42,6 @@ #include "planner/projection_plan.h" #include "planner/seq_scan_plan.h" #include "planner/alter_plan.h" -#include "planner/rename_plan.h" #include "storage/data_table.h" @@ -155,14 +154,6 @@ unique_ptr Optimizer::HandleDDLStatement( ddl_plan = move(alter_plan); break; } - case StatementType::RENAME: { - LOG_TRACE("Adding Rename Plan"); - unique_ptr rename_plan( - new planner::RenamePlan((parser::RenameFuncStatement *)tree)); - ddl_plan = move(rename_plan); - LOG_TRACE("plan build complete"); - break; - } case StatementType::DROP: { LOG_TRACE("Adding Drop plan..."); unique_ptr drop_plan( diff --git a/src/optimizer/query_to_operator_transformer.cpp b/src/optimizer/query_to_operator_transformer.cpp index 5c0725d00a8..8e183f20054 100644 --- a/src/optimizer/query_to_operator_transformer.cpp +++ b/src/optimizer/query_to_operator_transformer.cpp @@ -336,8 +336,6 @@ void QueryToOperatorTransformer::Visit( UNUSED_ATTRIBUTE parser::ExecuteStatement *op) {} void QueryToOperatorTransformer::Visit( UNUSED_ATTRIBUTE parser::TransactionStatement *op) {} -void QueryToOperatorTransformer::Visit( - UNUSED_ATTRIBUTE parser::RenameFuncStatement *op) {} void QueryToOperatorTransformer::Visit( UNUSED_ATTRIBUTE parser::AlterTableStatement *op) {} void QueryToOperatorTransformer::Visit(parser::UpdateStatement *op) { diff --git a/src/parser/postgresparser.cpp b/src/parser/postgresparser.cpp index 2a0217277a2..432890e6699 100644 --- a/src/parser/postgresparser.cpp +++ b/src/parser/postgresparser.cpp @@ -1730,81 +1730,81 @@ parser::TransactionStatement *PostgresParser::TransactionTransform( } parser::AlterTableStatement *PostgresParser::AlterTransform( - AlterTableStmt *root) { - // TODO (shilun) adding alter type check - // Currently we only support add/drop column type - parser::AlterTableStatement* result = - new AlterTableStatement(AlterTableStatement::AlterTableType::INVALID); - - // Get database and table name - RangeVar* relation = root->relation; - result->table_info_ = std::unique_ptr(new parser::TableInfo()); - if (relation->relname) { - result->table_info_->table_name = strdup(relation->relname); - } - if (relation->catalogname) { - result->table_info_->database_name = strdup(relation->catalogname); - } - - for (auto cell = root->cmds->head; cell != NULL; cell = cell->next) { - auto cmd = reinterpret_cast(cell->data.ptr_value); - switch (cmd->subtype) { - /*case AT_AddColumn: { - auto column = - ColumnDefTransform(reinterpret_cast(cmd->def)); - result->columns->push_back(column); - break; - }*/ - case AT_DropColumn: - result->names->push_back(strdup(cmd->name)); - result->type = AlterTableStatement::AlterTableType::DROP; - break; - default: { + Node *root) { + switch(root->type){ + case T_RenameStmt:{ + RenameStmt *newRoot = reinterpret_cast(root); + if (newRoot->renameType != ObjectType::OBJECT_COLUMN) { throw NotImplementedException(StringUtil::Format( - "Alter Table type %d not supported yet...\n", cmd->subtype)); + "Rename type %d not supported yes...\n", newRoot->relationType)); } + parser::AlterTableStatement *result = new parser::AlterTableStatement( + parser::AlterTableStatement::AlterTableType::RENAME); + RangeVar *relation = newRoot->relation; + result->table_info_ = + std::unique_ptr(new parser::TableInfo()); + if (relation->relname) { + result->table_info_.get()->table_name = strdup(relation->relname); } + if (relation->catalogname) { + result->table_info_.get()->database_name = strdup(relation->catalogname); + } + if (newRoot->subname) { + result->oldName = strdup(newRoot->subname); + } + if (newRoot->newname) { + result->newName = strdup(newRoot->newname); + } + LOG_TRACE("finished transform"); + return result; } - return result; -} - -/** - * RenameTransorm - right now we only support - * ALTER TABLE [ ONLY ] name [ * ] - RENAME [ COLUMN ] column TO new_column - * @param root - * @return - */ -parser::RenameFuncStatement *PostgresParser::RenameTransform(RenameStmt *root) { - if (root->renameType != ObjectType::OBJECT_COLUMN) { - throw NotImplementedException(StringUtil::Format( - "Rename type %d not supported yes...\n", root->relationType)); - } - parser::RenameFuncStatement *result = new parser::RenameFuncStatement( - parser::RenameFuncStatement::ObjectType::COLUMN); - RangeVar *relation = root->relation; - result->table_info_ = - std::unique_ptr(new parser::TableInfo()); - if (relation->relname) { - result->table_info_->table_name = strdup(relation->relname); - LOG_TRACE("root->relname: %s", relation->relname); - } - if (relation->catalogname) { - result->table_info_->database_name = strdup(relation->catalogname); - LOG_TRACE("root->catalogname: %s", relation->catalogname); - } - if (root->subname) { - result->oldName = strdup(root->subname); - LOG_TRACE("root->subname: %s", root->subname); + case T_AlterTableStmt: { + // TODO (shilun) adding alter type check + // Currently we only support add/drop column type + AlterTableStmt *newRoot = reinterpret_cast(root); + parser::AlterTableStatement* result = + new AlterTableStatement(AlterTableStatement::AlterTableType::INVALID); + + // Get database and table name + RangeVar* relation = newRoot->relation; + result->table_info_ = std::unique_ptr(new parser::TableInfo()); + if (relation->relname) { + result->table_info_.get()->table_name = strdup(relation->relname); + } + if (relation->catalogname) { + result->table_info_.get()->database_name = strdup(relation->catalogname); + } + + for (auto cell = newRoot->cmds->head; cell != NULL; cell = cell->next) { + auto cmd = reinterpret_cast(cell->data.ptr_value); + switch (cmd->subtype) { + /*case AT_AddColumn: { + auto column = + ColumnDefTransform(reinterpret_cast(cmd->def)); + result->columns->push_back(column); + break; + }*/ + case AT_DropColumn: + result->names->push_back(strdup(cmd->name)); + result->type = AlterTableStatement::AlterTableType::DROP; + break; + default: { + throw NotImplementedException(StringUtil::Format( + "Alter Table type %d not supported yet...\n", cmd->subtype)); + } + } + } + return result; } - if (root->newname) { - result->newName = strdup(root->newname); - LOG_TRACE("root->newname: %s", root->newname); + default: + LOG_ERROR("Not supported Alter Node type yet"); + throw NotImplementedException(StringUtil::Format( + "Alter Table type %d not supported yet...", root->type)); } - LOG_TRACE("finished transform"); - return result; + } + // This function transfers a single Postgres statement into // a Peloton SQLStatement object. It checks the type of // Postgres parsenode of the input and call the corresponding @@ -1812,12 +1812,10 @@ parser::RenameFuncStatement *PostgresParser::RenameTransform(RenameStmt *root) { parser::SQLStatement *PostgresParser::NodeTransform(Node *stmt) { parser::SQLStatement *result = nullptr; switch (stmt->type) { + case T_RenameStmt:// also use alter transform to transform the node case T_AlterTableStmt: // TODO (Shilun): adding T_ALTER_TABLE_STMT - result = AlterTransform(reinterpret_cast(stmt)); - break; - case T_RenameStmt: - result = RenameTransform(reinterpret_cast(stmt)); + result = AlterTransform(stmt); break; case T_SelectStmt: result = SelectTransform(reinterpret_cast(stmt)); diff --git a/src/planner/alter_plan.cpp b/src/planner/alter_plan.cpp index 7b0576522f7..59217ac9a7f 100644 --- a/src/planner/alter_plan.cpp +++ b/src/planner/alter_plan.cpp @@ -31,23 +31,43 @@ AlterPlan::AlterPlan(const std::string &database_name, dropped_columns(dropped_columns), type(a_type) {} +AlterPlan::AlterPlan(const std::string &database_name, + const std::string &table_name, + const std::vector &old_names, + const std::vector &new_names, + const AlterType a_type) + : table_name(table_name), + database_name(database_name), + old_names_(old_names), + new_names_(new_names), + type(a_type) {} + + AlterPlan::AlterPlan(parser::AlterTableStatement *parse_tree) { table_name = std::string(parse_tree->GetTableName()); database_name = std::string(parse_tree->GetDatabaseName()); - switch (parse_tree->type){ - case parser::AlterTableStatement::AlterTableType::DROP: - for (auto col : *parse_tree->names) { - LOG_TRACE("Drooped column name: %s", col); - dropped_columns.push_back(std::string(col)); - type = AlterType::DROP; - } - case parser::AlterTableStatement::AlterTableType::ADD: - default: - LOG_TRACE("Not Implemented the plan yet!"); + switch (parse_tree->type) { + case parser::AlterTableStatement::AlterTableType::RENAME: { + old_names_.emplace_back(std::string{parse_tree->oldName}); + new_names_.emplace_back(std::string{parse_tree->newName}); + type = AlterType::RENAME; + break; } - //std::vector columns; - // case 1: add column(column name + column data type) - //if (parse_tree->type == AlterTableType::COLUMN) { + case parser::AlterTableStatement::AlterTableType::DROP: + for (auto col : *parse_tree->names) { + LOG_TRACE("Drooped column name: %s", col); + dropped_columns.push_back(std::string(col)); + type = AlterType::DROP; + } + break; + case parser::AlterTableStatement::AlterTableType::ADD: + default: + LOG_ERROR("Not Implemented the plan yet!"); + type = AlterType::INVALID; + } + //std::vector columns; + // case 1: add column(column name + column data type) + //if (parse_tree->type == AlterTableType::COLUMN) { // Add columns: traverse through vector of ColumnDefinition /*for (auto col : *parse_tree->columns) { type::TypeId val = col->GetValueType(col->type); @@ -71,5 +91,9 @@ AlterPlan::AlterPlan(parser::AlterTableStatement *parse_tree) { } + + + + } // namespace planner } // namespace peloton From 32ec8fda4c2a77e9bb019759e1cdf95357871ceb Mon Sep 17 00:00:00 2001 From: dingshilun Date: Sun, 29 Apr 2018 11:29:46 -0400 Subject: [PATCH 42/58] added parser support for change column type and add column small modification --- src/common/internal_types.cpp | 5 + src/executor/alter_executor.cpp | 5 +- src/include/common/internal_types.h | 6 +- src/include/parser/alter_statement.h | 42 +++--- src/include/planner/alter_plan.h | 63 +++++---- src/parser/postgresparser.cpp | 190 +++++++++++++++------------ src/planner/alter_plan.cpp | 108 ++++++++------- 7 files changed, 233 insertions(+), 186 deletions(-) diff --git a/src/common/internal_types.cpp b/src/common/internal_types.cpp index 383a5f95d5f..80873b44171 100644 --- a/src/common/internal_types.cpp +++ b/src/common/internal_types.cpp @@ -426,6 +426,9 @@ std::string AlterTypeToString(AlterType type) { case AlterType::RENAME: { return "RENAME"; } + case AlterType::ALTER: { + return "ALTER"; + } default: { throw ConversionException( StringUtil::Format("No string conversion for AlterType value '%d'", @@ -440,6 +443,8 @@ AlterType StringToAlterType(const std::string &str) { return AlterType::INVALID; } else if (upper_str == "RENAME") { return AlterType::RENAME; + } else if (upper_str == "ALTER") { + return AlterType::ALTER; } else { throw ConversionException(StringUtil::Format( "No AlterType conversion from string '%s'", upper_str.c_str())); diff --git a/src/executor/alter_executor.cpp b/src/executor/alter_executor.cpp index ce9fdee20bf..12eef5c6d60 100644 --- a/src/executor/alter_executor.cpp +++ b/src/executor/alter_executor.cpp @@ -23,7 +23,8 @@ namespace executor { AlterExecutor::AlterExecutor(const planner::AbstractPlan *node, ExecutorContext *executor_context) : AbstractExecutor(node, executor_context), - isAlter_(!reinterpret_cast(node)->IsRename()) {} + isAlter_( + !reinterpret_cast(node)->IsRename()) {} // Initialize executor // Nothing to initialize for now @@ -46,7 +47,7 @@ bool AlterExecutor::DExecute() { auto current_txn = executor_context_->GetTransaction(); AlterType type = node.GetAlterTableType(); switch (type) { - case AlterType::DROP: + case AlterType::ALTER: result = DropColumn(node, current_txn); break; default: diff --git a/src/include/common/internal_types.h b/src/include/common/internal_types.h index 895042c6732..15839189841 100644 --- a/src/include/common/internal_types.h +++ b/src/include/common/internal_types.h @@ -646,8 +646,7 @@ std::ostream &operator<<(std::ostream &os, const DropType &type); enum class AlterType { INVALID = INVALID_TYPE_ID, // invalid alter type RENAME = 1, // rename table, column, database... - ADD = 2, - DROP = 3 + ALTER = 2 }; std::string AlterTypeToString(AlterType type); AlterType StringToAlterType(const std::string &str); @@ -1230,7 +1229,8 @@ std::ostream &operator<<(std::ostream &os, const RWType &type); typedef CuckooMap ReadWriteSet; -typedef tbb::concurrent_unordered_set WriteSet; +typedef tbb::concurrent_unordered_set WriteSet; // this enum is to identify why the version should be GC'd. enum class GCVersionType { diff --git a/src/include/parser/alter_statement.h b/src/include/parser/alter_statement.h index de6c27f9f0d..7262e6abb04 100644 --- a/src/include/parser/alter_statement.h +++ b/src/include/parser/alter_statement.h @@ -14,6 +14,7 @@ #include "parser/sql_statement.h" #include "common/sql_node_visitor.h" +#include "parser/create_statement.h" namespace peloton { namespace parser { @@ -24,39 +25,50 @@ namespace parser { */ class AlterTableStatement : public TableRefStatement { public: - enum class AlterTableType { INVALID = 0, ADD = 1, DROP = 2, RENAME = 3 }; + enum class AlterTableType { INVALID = 0, ALTER = 1, RENAME = 2 }; AlterTableStatement(AlterTableType type) : TableRefStatement(StatementType::ALTER), type(type), - names(new std::vector), oldName(nullptr), - newName(nullptr) - {}; + newName(nullptr) { + dropped_names = + type == AlterTableType::RENAME ? nullptr : (new std::vector); + added_columns = type == AlterTableType::RENAME + ? nullptr + : (new std::vector>); + changed_type_columns = + type == AlterTableType::RENAME + ? nullptr + : (new std::vector>); + } virtual ~AlterTableStatement() { - /*if (columns != nullptr) { - for (auto col : *columns) delete col; - delete columns; - }*/ - if (names != nullptr) { - for (auto name : *names) delete name; - delete names; + if (added_columns != nullptr) { + delete added_columns; + } + if (dropped_names != nullptr) { + for (auto name : *dropped_names) delete name; + delete dropped_names; + } + if (changed_type_columns != nullptr) { + delete changed_type_columns; } if (oldName) delete oldName; if (newName) delete newName; } - virtual void Accept(SqlNodeVisitor* v) override { v->Visit(this); } + virtual void Accept(SqlNodeVisitor *v) override { v->Visit(this); } AlterTableType type; // Dropped columns - std::vector* names; + std::vector *dropped_names; // Added columns - //std::vector* columns; + std::vector> *added_columns; - // the name that needs to be changed + std::vector> *changed_type_columns; + // the name that needs to be changed char *oldName; char *newName; }; diff --git a/src/include/planner/alter_plan.h b/src/include/planner/alter_plan.h index 420b6700357..27ab8e3d9cb 100644 --- a/src/include/planner/alter_plan.h +++ b/src/include/planner/alter_plan.h @@ -33,15 +33,16 @@ class AlterPlan : public AbstractPlan { public: AlterPlan() = delete; - explicit AlterPlan(const std::string &database_name, - const std::string &table_name, - //std::unique_ptr added_columns, - const std::vector &dropped_columns, - AlterType a_type); + explicit AlterPlan( + const std::string &database_name, const std::string &table_name, + const std::vector &dropped_columns, + const std::vector> &added_columns, + AlterType a_type); explicit AlterPlan(const std::string &database_name, const std::string &table_name, const std::vector &old_names, - const std::vector &new_names, AlterType a_type); + const std::vector &new_names, + AlterType a_type); explicit AlterPlan(parser::AlterTableStatement *parse_tree); virtual ~AlterPlan() {} @@ -52,24 +53,21 @@ class AlterPlan : public AbstractPlan { const std::string GetInfo() const { return StringUtil::Format("AlterPlan table:%s, database:%s", - this->table_name.c_str(), this->database_name.c_str()); + this->table_name.c_str(), + this->database_name.c_str()); } std::unique_ptr Copy() const { - switch(this->type) { - case AlterType::DROP: - case AlterType::ADD: - return std::unique_ptr( - new AlterPlan(database_name, table_name, - //std::unique_ptr( - // catalog::Schema::CopySchema(added_columns)), - dropped_columns, type)); - case AlterType::RENAME: - return std::unique_ptr( - new AlterPlan(database_name, table_name, old_names_, new_names_, type)); - default: - LOG_ERROR("Not supported Copy of Alter type yet"); - return nullptr; + switch (this->type) { + case AlterType::ALTER: + return std::unique_ptr(new AlterPlan( + database_name, table_name, dropped_columns, added_columns, type)); + case AlterType::RENAME: + return std::unique_ptr(new AlterPlan( + database_name, table_name, old_names_, new_names_, type)); + default: + LOG_ERROR("Not supported Copy of Alter type yet"); + return nullptr; } } @@ -77,7 +75,7 @@ class AlterPlan : public AbstractPlan { std::string GetDatabaseName() const { return database_name; } - //catalog::Schema *GetAddedColumns() const { return added_columns; } + // catalog::Schema *GetAddedColumns() const { return added_columns; } const std::vector &GetDroppedColumns() const { return dropped_columns; @@ -85,16 +83,17 @@ class AlterPlan : public AbstractPlan { AlterType GetAlterTableType() const { return type; } - //function used for rename statement + // function used for rename statement std::string GetOldName() const { return this->old_names_[0]; } - //function used for rename statement + // function used for rename statement std::string GetNewName() const { return this->new_names_[0]; } - //return true if the alter plan is rename statement - bool IsRename() const { return this->type==AlterType::RENAME;} -private: -// Target Table + // return true if the alter plan is rename statement + bool IsRename() const { return this->type == AlterType::RENAME; } + + private: + // Target Table storage::DataTable *target_table_ = nullptr; // Table Name @@ -104,17 +103,17 @@ class AlterPlan : public AbstractPlan { std::string database_name; // Schema delta, define the column txn want to add - // catalog::Schema *added_columns; + std::vector> added_columns; // dropped_column, define the column you want to drop std::vector dropped_columns; - - //used for store rename function data + // changed-type columns, define the column you want to change type + std::vector> changed_type_columns; + // used for store rename function data std::vector old_names_; std::vector new_names_; // Check to either AlterTable Table, INDEX or Rename AlterType type; - }; } } diff --git a/src/parser/postgresparser.cpp b/src/parser/postgresparser.cpp index 432890e6699..02fec77ea20 100644 --- a/src/parser/postgresparser.cpp +++ b/src/parser/postgresparser.cpp @@ -490,8 +490,9 @@ expression::AbstractExpression *PostgresParser::TypeCastTransform( } TypeName *type_name = root->typeName; - char *name = (reinterpret_cast( - type_name->names->tail->data.ptr_value)->val.str); + char *name = + (reinterpret_cast(type_name->names->tail->data.ptr_value) + ->val.str); type::VarlenType temp(StringToTypeId("INVALID")); result = new expression::ConstantValueExpression( temp.CastAs(source_value, ColumnDefinition::StrToValueType(name))); @@ -557,8 +558,8 @@ expression::AbstractExpression *PostgresParser::FuncCallTransform( // This function takes in the whereClause part of a Postgres SelectStmt // parsenode and transfers it into the select_list of a Peloton SelectStatement. // It checks the type of each target and call the corresponding helpers. -std::vector> * -PostgresParser::TargetTransform(List *root) { +std::vector> + *PostgresParser::TargetTransform(List *root) { // Statement like 'SELECT;' cannot detect by postgres parser and would lead to // null list if (root == nullptr) { @@ -864,8 +865,9 @@ expression::AbstractExpression *PostgresParser::WhenTransform(Node *root) { void PostgresParser::ColumnDefTransform(ColumnDef *root, parser::CreateStatement *stmt) { TypeName *type_name = root->typeName; - char *name = (reinterpret_cast( - type_name->names->tail->data.ptr_value)->val.str); + char *name = + (reinterpret_cast(type_name->names->tail->data.ptr_value) + ->val.str); parser::ColumnDefinition *result = nullptr; parser::ColumnDefinition::DataType data_type = @@ -1053,8 +1055,9 @@ parser::FuncParameter *PostgresParser::FunctionParameterTransform( FunctionParameter *root) { parser::FuncParameter::DataType data_type; TypeName *type_name = root->argType; - char *name = (reinterpret_cast( - type_name->names->tail->data.ptr_value)->val.str); + char *name = + (reinterpret_cast(type_name->names->tail->data.ptr_value) + ->val.str); parser::FuncParameter *result = nullptr; // Transform parameter type @@ -1512,8 +1515,8 @@ std::vector *PostgresParser::ColumnNameTransform(List *root) { // parsenode and transfers it into Peloton AbstractExpression. // This is a vector pointer of vector pointers because one InsertStmt can insert // multiple tuples. -std::vector>> * -PostgresParser::ValueListsTransform(List *root) { +std::vector>> + *PostgresParser::ValueListsTransform(List *root) { auto result = new std::vector< std::vector>>(); @@ -1624,8 +1627,8 @@ parser::SQLStatement *PostgresParser::InsertTransform(InsertStmt *root) { result = new parser::InsertStatement(InsertType::VALUES); PELOTON_ASSERT(select_stmt->valuesLists != NULL); - std::vector>> * - insert_values = nullptr; + std::vector>> + *insert_values = nullptr; try { insert_values = ValueListsTransform(select_stmt->valuesLists); } catch (Exception e) { @@ -1729,82 +1732,101 @@ parser::TransactionStatement *PostgresParser::TransactionTransform( } } -parser::AlterTableStatement *PostgresParser::AlterTransform( - Node *root) { - switch(root->type){ - case T_RenameStmt:{ - RenameStmt *newRoot = reinterpret_cast(root); - if (newRoot->renameType != ObjectType::OBJECT_COLUMN) { - throw NotImplementedException(StringUtil::Format( - "Rename type %d not supported yes...\n", newRoot->relationType)); - } - parser::AlterTableStatement *result = new parser::AlterTableStatement( - parser::AlterTableStatement::AlterTableType::RENAME); - RangeVar *relation = newRoot->relation; - result->table_info_ = - std::unique_ptr(new parser::TableInfo()); - if (relation->relname) { - result->table_info_.get()->table_name = strdup(relation->relname); - } - if (relation->catalogname) { - result->table_info_.get()->database_name = strdup(relation->catalogname); - } - if (newRoot->subname) { - result->oldName = strdup(newRoot->subname); - } - if (newRoot->newname) { - result->newName = strdup(newRoot->newname); - } - LOG_TRACE("finished transform"); - return result; - } - case T_AlterTableStmt: { - // TODO (shilun) adding alter type check - // Currently we only support add/drop column type - AlterTableStmt *newRoot = reinterpret_cast(root); - parser::AlterTableStatement* result = - new AlterTableStatement(AlterTableStatement::AlterTableType::INVALID); - - // Get database and table name - RangeVar* relation = newRoot->relation; - result->table_info_ = std::unique_ptr(new parser::TableInfo()); - if (relation->relname) { - result->table_info_.get()->table_name = strdup(relation->relname); - } - if (relation->catalogname) { - result->table_info_.get()->database_name = strdup(relation->catalogname); - } - - for (auto cell = newRoot->cmds->head; cell != NULL; cell = cell->next) { - auto cmd = reinterpret_cast(cell->data.ptr_value); - switch (cmd->subtype) { - /*case AT_AddColumn: { - auto column = - ColumnDefTransform(reinterpret_cast(cmd->def)); - result->columns->push_back(column); - break; - }*/ - case AT_DropColumn: - result->names->push_back(strdup(cmd->name)); - result->type = AlterTableStatement::AlterTableType::DROP; - break; - default: { +parser::AlterTableStatement *PostgresParser::AlterTransform(Node *root) { + switch (root->type) { + case T_RenameStmt: { + RenameStmt *newRoot = reinterpret_cast(root); + if (newRoot->renameType != ObjectType::OBJECT_COLUMN) { throw NotImplementedException(StringUtil::Format( - "Alter Table type %d not supported yet...\n", cmd->subtype)); + "Rename type %d not supported yes...\n", newRoot->relationType)); + } + parser::AlterTableStatement *result = new parser::AlterTableStatement( + parser::AlterTableStatement::AlterTableType::RENAME); + RangeVar *relation = newRoot->relation; + result->table_info_ = + std::unique_ptr(new parser::TableInfo()); + if (relation->relname) { + result->table_info_.get()->table_name = strdup(relation->relname); + } + if (relation->catalogname) { + result->table_info_.get()->database_name = + strdup(relation->catalogname); } + if (newRoot->subname) { + result->oldName = strdup(newRoot->subname); } + if (newRoot->newname) { + result->newName = strdup(newRoot->newname); + } + LOG_TRACE("finished transform"); + return result; + } + case T_AlterTableStmt: { + // TODO (shilun) adding alter type check + // Currently we only support add/drop column type + AlterTableStmt *newRoot = reinterpret_cast(root); + parser::AlterTableStatement *result = + new AlterTableStatement(AlterTableStatement::AlterTableType::ALTER); + + // Get database and table name + RangeVar *relation = newRoot->relation; + result->table_info_ = + std::unique_ptr(new parser::TableInfo()); + if (relation->relname) { + result->table_info_.get()->table_name = strdup(relation->relname); + } + if (relation->catalogname) { + result->table_info_.get()->database_name = + strdup(relation->catalogname); + } + + for (auto cell = newRoot->cmds->head; cell != NULL; cell = cell->next) { + auto cmd = reinterpret_cast(cell->data.ptr_value); + switch (cmd->subtype) { + case AT_AddColumn: { + // as the ColumnDefTransform only accepts CreateStatement + // we have to create one here + parser::CreateStatement tmpStatement( + parser::CreateStatement::CreateType::kTable); + ColumnDefTransform(reinterpret_cast(cmd->def), + &tmpStatement); + for (size_t i = 0; i < tmpStatement.columns.size(); i++) { + result->added_columns->emplace_back( + std::move(tmpStatement.columns[i])); + } + break; + } + case AT_DropColumn: { + result->dropped_names->push_back(strdup(cmd->name)); + break; + } + case AT_AlterColumnType: { + ColumnDef *def = (ColumnDef *)cmd->def; + TypeName *type_name = def->typeName; + char *name = (reinterpret_cast( + type_name->names->tail->data.ptr_value) + ->val.str); + LOG_TRACE("DATA Type is :%s", name); + auto type_id = ColumnDefinition::StrToDataType(name); + std::unique_ptr col_def( + new ColumnDefinition(cmd->name, type_id)); + result->changed_type_columns->push_back(std::move(col_def)); + } + default: { + throw NotImplementedException(StringUtil::Format( + "Alter Table type %d not supported yet...\n", cmd->subtype)); + } + } + } + return result; } - return result; - } - default: - LOG_ERROR("Not supported Alter Node type yet"); - throw NotImplementedException(StringUtil::Format( - "Alter Table type %d not supported yet...", root->type)); + default: + LOG_ERROR("Not supported Alter Node type yet"); + throw NotImplementedException(StringUtil::Format( + "Alter Table type %d not supported yet...", root->type)); } - } - // This function transfers a single Postgres statement into // a Peloton SQLStatement object. It checks the type of // Postgres parsenode of the input and call the corresponding @@ -1812,7 +1834,7 @@ parser::AlterTableStatement *PostgresParser::AlterTransform( parser::SQLStatement *PostgresParser::NodeTransform(Node *stmt) { parser::SQLStatement *result = nullptr; switch (stmt->type) { - case T_RenameStmt:// also use alter transform to transform the node + case T_RenameStmt: // also use alter transform to transform the node case T_AlterTableStmt: // TODO (Shilun): adding T_ALTER_TABLE_STMT result = AlterTransform(stmt); @@ -1921,8 +1943,8 @@ parser::SQLStatementList *PostgresParser::ListTransform(List *root) { return result; } -std::vector> * -PostgresParser::UpdateTargetTransform(List *root) { +std::vector> + *PostgresParser::UpdateTargetTransform(List *root) { auto result = new std::vector>(); for (auto cell = root->head; cell != NULL; cell = cell->next) { auto update_clause = new UpdateClause(); diff --git a/src/planner/alter_plan.cpp b/src/planner/alter_plan.cpp index 59217ac9a7f..3623ed3df0f 100644 --- a/src/planner/alter_plan.cpp +++ b/src/planner/alter_plan.cpp @@ -20,16 +20,20 @@ namespace peloton { namespace planner { -AlterPlan::AlterPlan(const std::string &database_name, - const std::string &table_name, - //std::unique_ptr added_columns, - const std::vector &dropped_columns, - AlterType a_type) +AlterPlan::AlterPlan( + const std::string &database_name, const std::string &table_name, + const std::vector &dropped_columns, + UNUSED_ATTRIBUTE const std::vector> + &added_columns_, + AlterType a_type) : table_name(table_name), database_name(database_name), - //added_columns(added_columns.release()), dropped_columns(dropped_columns), - type(a_type) {} + type(a_type) { + // for (size_t i=0;iadded_columns.push_back(std::move(added_columns_[i])); + // } +} AlterPlan::AlterPlan(const std::string &database_name, const std::string &table_name, @@ -42,58 +46,62 @@ AlterPlan::AlterPlan(const std::string &database_name, new_names_(new_names), type(a_type) {} - AlterPlan::AlterPlan(parser::AlterTableStatement *parse_tree) { table_name = std::string(parse_tree->GetTableName()); database_name = std::string(parse_tree->GetDatabaseName()); switch (parse_tree->type) { - case parser::AlterTableStatement::AlterTableType::RENAME: { - old_names_.emplace_back(std::string{parse_tree->oldName}); - new_names_.emplace_back(std::string{parse_tree->newName}); - type = AlterType::RENAME; - break; - } - case parser::AlterTableStatement::AlterTableType::DROP: - for (auto col : *parse_tree->names) { - LOG_TRACE("Drooped column name: %s", col); - dropped_columns.push_back(std::string(col)); - type = AlterType::DROP; + case parser::AlterTableStatement::AlterTableType::RENAME: { + old_names_.emplace_back(std::string{parse_tree->oldName}); + new_names_.emplace_back(std::string{parse_tree->newName}); + type = AlterType::RENAME; + break; } - break; - case parser::AlterTableStatement::AlterTableType::ADD: - default: - LOG_ERROR("Not Implemented the plan yet!"); - type = AlterType::INVALID; - } - //std::vector columns; - // case 1: add column(column name + column data type) - //if (parse_tree->type == AlterTableType::COLUMN) { - // Add columns: traverse through vector of ColumnDefinition - /*for (auto col : *parse_tree->columns) { - type::TypeId val = col->GetValueType(col->type); - LOG_TRACE("Column name: %s", col->name); + case parser::AlterTableStatement::AlterTableType::ALTER: { + // deal with dropped columns + for (auto col : *parse_tree->dropped_names) { + LOG_TRACE("Drooped column name: %s", col); + dropped_columns.push_back(std::string(col)); + type = AlterType::ALTER; + } - bool is_inline = (val == type::TypeId::VARCHAR) ? false : true; - auto column = catalog::Column(val, type::Type::GetTypeSize(val), - std::string(col->name), is_inline); - LOG_TRACE("Column is_line: %d", is_inline); - // Add not_null constraints - if (col->not_null) { - catalog::Constraint constraint(ConstraintType::NOTNULL, "con_not_null"); - column.AddConstraint(constraint); + // deal with added columns + std::vector columns; + for (size_t i = 0; i < (*parse_tree->added_columns).size(); i++) { + type::TypeId val = parser::ColumnDefinition::GetValueType( + (*parse_tree->added_columns)[i].get()->type); + // LOG_TRACE("Column Name: %s", (char + // *)((*parse_tree->columns)[i].get()->name.c_str())); + + bool is_inline = (val == type::TypeId::VARCHAR) ? false : true; + auto column = catalog::Column( + val, type::Type::GetTypeSize(val), + std::string((*parse_tree->added_columns)[i].get()->name), + is_inline); + + if ((*parse_tree->added_columns)[i].get()->not_null) { + catalog::Constraint constraint(ConstraintType::NOTNULL, + "con_not_null"); + column.AddConstraint(constraint); + } + columns.emplace_back(column); + } + added_columns.emplace_back( + std::unique_ptr(new catalog::Schema(columns))); + + // deal with change column types + for (size_t i = 0; i < (*parse_tree->changed_type_columns).size(); i++) { + auto &tmp = (*parse_tree->changed_type_columns)[i]; + type::TypeId val = + parser::ColumnDefinition::GetValueType(tmp.get()->type); + std::string name = tmp.get()->name; + changed_type_columns.emplace_back(std::make_pair(name, val)); } - columns.push_back(column); } - added_columns = new catalog::Schema(columns);*/ - - // Drop columns: traverse through vector of char*(column name) - + default: + LOG_ERROR("Not Implemented the plan yet!"); + type = AlterType::INVALID; } - - - - - +} } // namespace planner } // namespace peloton From 253b4717d73cf994faac2ba21bc1aaf1ff62b5ca Mon Sep 17 00:00:00 2001 From: Shangjie Chen Date: Sun, 29 Apr 2018 22:34:42 +0000 Subject: [PATCH 43/58] new implement of rename --- src/catalog/abstract_catalog.cpp | 68 +++++++++++++++ src/catalog/catalog.cpp | 110 ++++++++++++------------- src/catalog/column_catalog.cpp | 36 +++++++- src/include/catalog/abstract_catalog.h | 6 ++ src/include/catalog/column_catalog.h | 13 ++- 5 files changed, 167 insertions(+), 66 deletions(-) diff --git a/src/catalog/abstract_catalog.cpp b/src/catalog/abstract_catalog.cpp index 692e14b9c98..f1fb595985d 100644 --- a/src/catalog/abstract_catalog.cpp +++ b/src/catalog/abstract_catalog.cpp @@ -33,6 +33,7 @@ #include "executor/index_scan_executor.h" #include "executor/insert_executor.h" #include "executor/seq_scan_executor.h" +#include "executor/update_executor.h" #include "storage/database.h" #include "storage/storage_manager.h" @@ -166,6 +167,73 @@ bool AbstractCatalog::DeleteWithIndexScan( return status; } +/* @brief Update specific columns using index scan + * @param update_columns Columns to be updated + * @param update_values Values to be updated + * @param scan_values Value to be scaned (used in index scan) + * @param index_offset Offset of index for scan + * @return true if successfully executes + */ +bool AbstractCatalog::UpdateWithIndexScan( + std::vector update_columns, std::vector update_values, + std::vector scan_values, oid_t index_offset, + concurrency::TransactionContext *txn) { + if (txn == nullptr) { + throw CatalogException("Scan table requires transaction"); + } + + std::unique_ptr context( + new executor::ExecutorContext(txn)); + // Construct index scan executor + auto index = catalog_table_->GetIndex(index_offset); + oid_t index_oid = index->GetOid(); + std::vector key_column_offsets = + index->GetMetadata()->GetKeySchema()->GetIndexedColumns(); + PELOTON_ASSERT(scan_values.size() == key_column_offsets.size()); + std::vector expr_types(scan_values.size(), + ExpressionType::COMPARE_EQUAL); + std::vector runtime_keys; + + planner::IndexScanPlan::IndexScanDesc index_scan_desc( + index_oid, key_column_offsets, expr_types, scan_values, runtime_keys); + + planner::IndexScanPlan index_scan_node(catalog_table_, nullptr, + update_columns, index_scan_desc); + + executor::IndexScanExecutor index_scan_executor(&index_scan_node, + context.get()); + // Construct update executor + TargetList target_list; + DirectMapList direct_map_list; + + size_t column_count = catalog_table_->GetSchema()->GetColumnCount(); + for (size_t col_itr = 0; col_itr < column_count; col_itr++) { + // Skip any column for update + if (std::find(std::begin(update_columns), std::end(update_columns), + col_itr) == std::end(update_columns)) { + direct_map_list.emplace_back(col_itr, std::make_pair(0, col_itr)); + } + } + + PELOTON_ASSERT(update_columns.size() == update_values.size()); + for (size_t i = 0; i < update_values.size(); i++) { + planner::DerivedAttribute update_attribute{ + new expression::ConstantValueExpression(update_values[i])}; + target_list.emplace_back(update_columns[i], update_attribute); + } + + std::unique_ptr project_info( + new planner::ProjectInfo(std::move(target_list), + std::move(direct_map_list))); + planner::UpdatePlan update_node(catalog_table_, std::move(project_info)); + + executor::UpdateExecutor update_executor(&update_node, context.get()); + update_executor.AddChild(&index_scan_executor); + // Execute + update_executor.Init(); + return update_executor.Execute(); +} + /*@brief Index scan helper function * @param column_offsets Column ids for search (projection) * @param index_offset Offset of index for scan diff --git a/src/catalog/catalog.cpp b/src/catalog/catalog.cpp index 920cc0da5ba..d9b37424d09 100644 --- a/src/catalog/catalog.cpp +++ b/src/catalog/catalog.cpp @@ -615,18 +615,18 @@ ResultType Catalog::DropIndex(oid_t index_oid, ResultType Catalog::DropIndex(const std::string &index_name, concurrency::TransactionContext *txn) { - if(txn == nullptr) { - throw CatalogException("Do not have transaction to drop index " + - index_name); - } - auto index_object = catalog::IndexCatalog::GetInstance()->GetIndexObject( - index_name, txn); - if(index_object == nullptr) { - throw CatalogException("Index name " + index_name + " cannot be found"); - } - ResultType result = DropIndex(index_object->GetIndexOid(), txn); + if (txn == nullptr) { + throw CatalogException("Do not have transaction to drop index " + + index_name); + } + auto index_object = + catalog::IndexCatalog::GetInstance()->GetIndexObject(index_name, txn); + if (index_object == nullptr) { + throw CatalogException("Index name " + index_name + " cannot be found"); + } + ResultType result = DropIndex(index_object->GetIndexOid(), txn); - return result; + return result; } //===--------------------------------------------------------------------===// @@ -837,19 +837,18 @@ ResultType Catalog::AddColumn( * @return TransactionContext ResultType(SUCCESS or FAILURE) */ -ResultType Catalog::DropColumn( - const std::string &database_name, - const std::string &table_name, - const std::vector &columns, - concurrency::TransactionContext *txn) { +ResultType Catalog::DropColumn(const std::string &database_name, + const std::string &table_name, + const std::vector &columns, + concurrency::TransactionContext *txn) { try { oid_t table_oid = Catalog::GetInstance() - ->GetTableObject(database_name, table_name, txn) - ->GetTableOid(); - for (std::string name: columns) { + ->GetTableObject(database_name, table_name, txn) + ->GetTableOid(); + for (std::string name : columns) { catalog::ColumnCatalog::GetInstance()->DeleteColumn(table_oid, name, txn); } - } catch(CatalogException &e){ + } catch (CatalogException &e) { return ResultType::FAILURE; } return ResultType::SUCCESS; @@ -876,8 +875,7 @@ ResultType Catalog::RenameColumn(const std::string &database_name, throw CatalogException("Name can not be empty string."); } - LOG_TRACE("Change Column Name %s to %s", old_name.c_str(), - new_name.c_str()); + LOG_TRACE("Change Column Name %s to %s", old_name.c_str(), new_name.c_str()); try { // Get table from the name @@ -900,17 +898,15 @@ ResultType Catalog::RenameColumn(const std::string &database_name, // Change column name in the global schema schema->ChangeColumnName(columnId, new_name); - // Change cached ColumnCatalog + // Modify the pg_table oid_t table_oid = Catalog::GetInstance() ->GetTableObject(database_name, table_name, txn) ->GetTableOid(); - catalog::ColumnCatalog::GetInstance()->DeleteColumn(table_oid, old_name, - txn); - auto new_column = schema->GetColumn(columnId); - catalog::ColumnCatalog::GetInstance()->InsertColumn( - table_oid, new_column.GetName(), columnId, new_column.GetOffset(), - new_column.GetType(), new_column.IsInlined(), - new_column.GetConstraints(), pool_.get(), txn); + bool res = catalog::ColumnCatalog::GetInstance()->RenameColumn( + table_oid, old_name, new_name, txn); + if (!res) { + throw CatalogException("Change Column name failed."); + } } catch (CatalogException &e) { return ResultType::FAILURE; @@ -1195,11 +1191,11 @@ void Catalog::InitializeFunctions() { /** * decimal functions */ - AddBuiltinFunction( - "abs", {type::TypeId::DECIMAL}, type::TypeId::DECIMAL, internal_lang, - "Abs", function::BuiltInFuncType{OperatorId::Abs, - function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction("abs", {type::TypeId::DECIMAL}, type::TypeId::DECIMAL, + internal_lang, "Abs", + function::BuiltInFuncType{ + OperatorId::Abs, function::DecimalFunctions::_Abs}, + txn); AddBuiltinFunction( "sqrt", {type::TypeId::TINYINT}, type::TypeId::DECIMAL, internal_lang, "Sqrt", function::BuiltInFuncType{OperatorId::Sqrt, @@ -1236,33 +1232,29 @@ void Catalog::InitializeFunctions() { /** * integer functions */ - AddBuiltinFunction( - "abs", {type::TypeId::TINYINT}, type::TypeId::TINYINT, - internal_lang, "Abs", - function::BuiltInFuncType{OperatorId::Abs, - function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction("abs", {type::TypeId::TINYINT}, type::TypeId::TINYINT, + internal_lang, "Abs", + function::BuiltInFuncType{ + OperatorId::Abs, function::DecimalFunctions::_Abs}, + txn); - AddBuiltinFunction( - "abs", {type::TypeId::SMALLINT}, type::TypeId::SMALLINT, - internal_lang, "Abs", - function::BuiltInFuncType{OperatorId::Abs, - function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction("abs", {type::TypeId::SMALLINT}, + type::TypeId::SMALLINT, internal_lang, "Abs", + function::BuiltInFuncType{ + OperatorId::Abs, function::DecimalFunctions::_Abs}, + txn); - AddBuiltinFunction( - "abs", {type::TypeId::INTEGER}, type::TypeId::INTEGER, - internal_lang, "Abs", - function::BuiltInFuncType{OperatorId::Abs, - function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction("abs", {type::TypeId::INTEGER}, type::TypeId::INTEGER, + internal_lang, "Abs", + function::BuiltInFuncType{ + OperatorId::Abs, function::DecimalFunctions::_Abs}, + txn); - AddBuiltinFunction( - "abs", {type::TypeId::BIGINT}, type::TypeId::BIGINT, - internal_lang, "Abs", - function::BuiltInFuncType{OperatorId::Abs, - function::DecimalFunctions::_Abs}, - txn); + AddBuiltinFunction("abs", {type::TypeId::BIGINT}, type::TypeId::BIGINT, + internal_lang, "Abs", + function::BuiltInFuncType{ + OperatorId::Abs, function::DecimalFunctions::_Abs}, + txn); AddBuiltinFunction( "floor", {type::TypeId::INTEGER}, type::TypeId::DECIMAL, diff --git a/src/catalog/column_catalog.cpp b/src/catalog/column_catalog.cpp index d5cbc3c2c10..348a3ea1171 100644 --- a/src/catalog/column_catalog.cpp +++ b/src/catalog/column_catalog.cpp @@ -41,9 +41,9 @@ ColumnCatalogObject::ColumnCatalogObject(executor::LogicalTile *tile, is_not_null(tile->GetValue(tupleId, ColumnCatalog::ColumnId::IS_NOT_NULL) .GetAs()) {} -ColumnCatalog *ColumnCatalog::GetInstance(storage::Database *pg_catalog, - type::AbstractPool *pool, - concurrency::TransactionContext *txn) { +ColumnCatalog *ColumnCatalog::GetInstance( + storage::Database *pg_catalog, type::AbstractPool *pool, + concurrency::TransactionContext *txn) { static ColumnCatalog column_catalog{pg_catalog, pool, txn}; return &column_catalog; } @@ -250,5 +250,35 @@ ColumnCatalog::GetColumnObjects(oid_t table_oid, return table_object->GetColumnObjects(); } +/* + * @brief Rename the column name to a new name. + * @ return whether the update succeed + */ +bool ColumnCatalog::RenameColumn(oid_t table_oid, + const std::string &column_name, + const std::string &new_name, + concurrency::TransactionContext *txn) { + std::vector update_columns({ColumnId::COLUMN_NAME}); + + std::vector update_values; + update_values.push_back(type::ValueFactory::GetVarcharValue(new_name).Copy()); + + // values to execute index scan + std::vector scan_values; + scan_values.push_back(type::ValueFactory::GetIntegerValue(table_oid).Copy()); + scan_values.push_back( + type::ValueFactory::GetVarcharValue(column_name, nullptr).Copy()); + + // Index of table_oid & column_name + oid_t index_offset = IndexId::PRIMARY_KEY; + + auto table_object = + TableCatalog::GetInstance()->GetTableObject(table_oid, txn); + table_object->EvictColumnObject(column_name); + + return UpdateWithIndexScan(update_columns, update_values, scan_values, + index_offset, txn); +} + } // namespace catalog } // namespace peloton diff --git a/src/include/catalog/abstract_catalog.h b/src/include/catalog/abstract_catalog.h index 9acf67773b9..5c737d082c2 100644 --- a/src/include/catalog/abstract_catalog.h +++ b/src/include/catalog/abstract_catalog.h @@ -62,6 +62,12 @@ class AbstractCatalog { bool DeleteWithIndexScan(oid_t index_offset, std::vector values, concurrency::TransactionContext *txn); + bool UpdateWithIndexScan(std::vector update_columns, + std::vector update_values, + std::vector scan_values, + oid_t index_offset, + concurrency::TransactionContext *txn); + std::unique_ptr>> GetResultWithIndexScan(std::vector column_offsets, oid_t index_offset, std::vector values, diff --git a/src/include/catalog/column_catalog.h b/src/include/catalog/column_catalog.h index 56d8bf5c6b7..13947b6e6fe 100644 --- a/src/include/catalog/column_catalog.h +++ b/src/include/catalog/column_catalog.h @@ -70,9 +70,10 @@ class ColumnCatalog : public AbstractCatalog { public: // Global Singleton, only the first call requires passing parameters. - static ColumnCatalog *GetInstance(storage::Database *pg_catalog = nullptr, - type::AbstractPool *pool = nullptr, - concurrency::TransactionContext *txn = nullptr); + static ColumnCatalog *GetInstance( + storage::Database *pg_catalog = nullptr, + type::AbstractPool *pool = nullptr, + concurrency::TransactionContext *txn = nullptr); ~ColumnCatalog(); @@ -86,10 +87,14 @@ class ColumnCatalog : public AbstractCatalog { oid_t column_id, oid_t column_offset, type::TypeId column_type, bool is_inlined, const std::vector &constraints, - type::AbstractPool *pool, concurrency::TransactionContext *txn); + type::AbstractPool *pool, + concurrency::TransactionContext *txn); bool DeleteColumn(oid_t table_oid, const std::string &column_name, concurrency::TransactionContext *txn); bool DeleteColumns(oid_t table_oid, concurrency::TransactionContext *txn); + bool RenameColumn(oid_t table_oid, const std::string &column_name, + const std::string &new_name, + concurrency::TransactionContext *txn); private: //===--------------------------------------------------------------------===// From 4df594b21fea557855fe4098e03a95206b3cdc76 Mon Sep 17 00:00:00 2001 From: Shangjie Chen Date: Mon, 30 Apr 2018 23:42:05 +0000 Subject: [PATCH 44/58] alter table in catalog --- src/catalog/catalog.cpp | 164 ++++++++++++++++++++++++++++++++- src/include/storage/database.h | 3 + src/storage/database.cpp | 26 ++++++ 3 files changed, 188 insertions(+), 5 deletions(-) diff --git a/src/catalog/catalog.cpp b/src/catalog/catalog.cpp index d9b37424d09..3534be15e59 100644 --- a/src/catalog/catalog.cpp +++ b/src/catalog/catalog.cpp @@ -27,11 +27,15 @@ #include "catalog/trigger_catalog.h" #include "concurrency/transaction_manager_factory.h" #include "executor/executor_context.h" +#include "executor/insert_executor.h" +#include "executor/seq_scan_executor.h" #include "function/date_functions.h" #include "function/decimal_functions.h" #include "function/old_engine_string_functions.h" #include "function/timestamp_functions.h" #include "index/index_factory.h" +#include "planner/insert_plan.h" +#include "planner/seq_scan_plan.h" #include "settings/settings_manager.h" #include "storage/storage_manager.h" #include "storage/table_factory.h" @@ -800,13 +804,163 @@ std::shared_ptr Catalog::GetTableObject( * @param txn the transaction Context * @return TransactionContext ResultType(SUCCESS or FAILURE) */ -ResultType Catalog::AlterTable( - UNUSED_ATTRIBUTE oid_t database_oid, UNUSED_ATTRIBUTE oid_t table_oid, - UNUSED_ATTRIBUTE std::unique_ptr new_schema, - UNUSED_ATTRIBUTE concurrency::TransactionContext *txn) { +ResultType Catalog::AlterTable(oid_t database_oid, oid_t table_oid, + std::unique_ptr new_schema, + concurrency::TransactionContext *txn) { LOG_TRACE("AlterTable in Catalog"); - // TODO: perform AlterTable Operation + if (txn == nullptr) + throw CatalogException("Alter table requires transaction"); + try { + auto storage_manager = storage::StorageManager::GetInstance(); + auto database = storage_manager->GetDatabaseWithOid(database_oid); + try { + auto old_table = database->GetTableWithOid(table_oid); + auto old_schema = old_table->GetSchema(); + + // Step 1: build empty table with new schema + bool own_schema = true; + bool adapt_table = false; + auto new_table = storage::TableFactory::GetDataTable( + database_oid, table_oid, + catalog::Schema::CopySchema(new_schema.get()), old_table->GetName(), + DEFAULT_TUPLES_PER_TILEGROUP, own_schema, adapt_table); + + // Step 2: Copy indexes + auto old_index_oids = + IndexCatalog::GetInstance()->GetIndexObjects(table_oid, txn); + for (auto index_oid_pair : old_index_oids) { + oid_t index_oid = index_oid_pair.first; + // delete record in pg_index + IndexCatalog::GetInstance()->DeleteIndex(index_oid, txn); + // Check if all indexed columns still exists + auto old_index = old_table->GetIndexWithOid(index_oid); + bool index_exist = true; + std::vector new_key_attrs; + + for (oid_t column_id : old_index->GetMetadata()->GetKeyAttrs()) { + bool is_found = false; + std::string column_name = old_schema->GetColumn(column_id).GetName(); + oid_t i = 0; + for (auto new_column : new_schema->GetColumns()) { + if (column_name == new_column.GetName()) { + is_found = true; + new_key_attrs.push_back(i); + break; + } + i++; + } + if (!is_found) { + index_exist = false; + break; + } + } + if (!index_exist) continue; + + // construct index on new table + auto index_metadata = new index::IndexMetadata( + old_index->GetName(), index_oid, table_oid, database_oid, + old_index->GetMetadata()->GetIndexType(), + old_index->GetMetadata()->GetIndexConstraintType(), + new_schema.get(), + // catalog::Schema::CopySchema(old_index->GetKeySchema()), + catalog::Schema::CopySchema(new_schema.get(), new_key_attrs), + new_key_attrs, old_index->GetMetadata()->HasUniqueKeys()); + + std::shared_ptr new_index( + index::IndexFactory::GetIndex(index_metadata)); + new_table->AddIndex(new_index); + + // reinsert record into pg_index + IndexCatalog::GetInstance()->InsertIndex( + index_oid, old_index->GetName(), table_oid, + old_index->GetMetadata()->GetIndexType(), + old_index->GetMetadata()->GetIndexConstraintType(), + old_index->GetMetadata()->HasUniqueKeys(), new_key_attrs, + pool_.get(), txn); + } + + std::unique_ptr context( + new executor::ExecutorContext(txn, {})); + // Step 3: build column mapping between old table and new table + // we're using column name as unique identifier + std::vector old_column_ids; + std::unordered_map column_map; + for (oid_t old_column_id = 0; + old_column_id < old_schema->GetColumnCount(); old_column_id++) { + old_column_ids.push_back(old_column_id); + for (oid_t new_column_id = 0; + new_column_id < new_schema->GetColumnCount(); new_column_id++) { + if (old_schema->GetColumn(old_column_id).GetName() == + new_schema->GetColumn(new_column_id).GetName()) { + column_map[new_column_id] = old_column_id; + } + } + } + // Step 4: Get tuples from old table with sequential scan + // TODO: Try to reuse Sequential scan function and insert function in + // abstract catalog + planner::SeqScanPlan seq_scan_node(old_table, nullptr, old_column_ids); + executor::SeqScanExecutor seq_scan_executor(&seq_scan_node, + context.get()); + seq_scan_executor.Init(); + while (seq_scan_executor.Execute()) { + std::unique_ptr result_tile( + seq_scan_executor.GetOutput()); + for (size_t i = 0; i < result_tile->GetTupleCount(); i++) { + // Transform tuple into new schema + std::unique_ptr tuple( + new storage::Tuple(new_schema.get(), true)); + + for (oid_t new_column_id = 0; + new_column_id < new_schema->GetColumnCount(); new_column_id++) { + auto it = column_map.find(new_column_id); + type::Value val; + if (it == column_map.end()) { + // new column, set value to null + val = type::ValueFactory::GetNullValueByType( + new_schema->GetColumn(new_column_id).GetType()); + } else { + // otherwise, copy value in old table + // TODO: Change type if necessary + val = result_tile->GetValue(i, it->second); + } + tuple->SetValue(new_column_id, val, pool_.get()); + } + // insert new tuple into new table + planner::InsertPlan node(new_table, std::move(tuple)); + executor::InsertExecutor executor(&node, context.get()); + executor.Init(); + executor.Execute(); + } + } + // Step 5: delete all the column(attribute) records in pg_attribute + // and reinsert them using new schema(column offset needs to change + // accordingly) + catalog::ColumnCatalog::GetInstance()->DeleteColumns(table_oid, txn); + oid_t column_offset = 0; + for (auto new_column : new_schema->GetColumns()) { + catalog::ColumnCatalog::GetInstance()->InsertColumn( + table_oid, new_column.GetName(), column_offset, + new_column.GetOffset(), new_column.GetType(), + new_column.IsInlined(), new_column.GetConstraints(), pool_.get(), + txn); + column_offset++; + } + + // Final step of physical change should be moved to commit time + database->ReplaceTableWithOid(table_oid, new_table); + + // Record table drop + txn->RecordDrop(database_oid, table_oid, INVALID_OID); + + } catch (CatalogException &e) { + LOG_TRACE("Alter table failed."); + return ResultType::FAILURE; + } + } catch (CatalogException &e) { + return ResultType::FAILURE; + } return ResultType::SUCCESS; } diff --git a/src/include/storage/database.h b/src/include/storage/database.h index d8eca8a4373..a34a7b01950 100644 --- a/src/include/storage/database.h +++ b/src/include/storage/database.h @@ -61,6 +61,9 @@ class Database : public Printable { void DropTableWithOid(const oid_t table_oid); + storage::DataTable *ReplaceTableWithOid(const oid_t table_oid, + storage::DataTable *new_table); + //===--------------------------------------------------------------------===// // UTILITIES //===--------------------------------------------------------------------===// diff --git a/src/storage/database.cpp b/src/storage/database.cpp index 705ad42916e..74b11427794 100644 --- a/src/storage/database.cpp +++ b/src/storage/database.cpp @@ -102,6 +102,32 @@ void Database::DropTableWithOid(const oid_t table_oid) { } } +/** + * Replace the the data table with oid. + * @param table_oid the oid of that table + * @param new_table the new table storage + * @return pointer to that table. + */ +storage::DataTable *Database::ReplaceTableWithOid( + const oid_t table_oid, storage::DataTable *new_table) { + { + std::lock_guard lock(database_mutex); + + oid_t table_offset = 0; + for (auto table : tables) { + if (table->GetOid() == table_oid) { + break; + } + table_offset++; + } + PELOTON_ASSERT(table_offset < tables.size()); + + auto old_table = tables.at(table_offset); + tables[table_offset] = new_table; + return old_table; + } +} + storage::DataTable *Database::GetTable(const oid_t table_offset) const { PELOTON_ASSERT(table_offset < tables.size()); auto table = tables.at(table_offset); From 21ee68d2428e55b98872cdb958c3681ea7443d6a Mon Sep 17 00:00:00 2001 From: dingshilun Date: Wed, 2 May 2018 20:14:52 -0400 Subject: [PATCH 45/58] added change type into alter tabe --- src/catalog/catalog.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/catalog/catalog.cpp b/src/catalog/catalog.cpp index 3534be15e59..2676e4c617d 100644 --- a/src/catalog/catalog.cpp +++ b/src/catalog/catalog.cpp @@ -924,6 +924,10 @@ ResultType Catalog::AlterTable(oid_t database_oid, oid_t table_oid, // otherwise, copy value in old table // TODO: Change type if necessary val = result_tile->GetValue(i, it->second); + if (new_schema->GetColumn(new_column_id).GetType() != old_schema->GetColumn(it->second).GetType()) { + //change the value's type + val = val.CastAs(new_schema->GetColumn(new_column_id).GetType()); + } } tuple->SetValue(new_column_id, val, pool_.get()); } From 68f492f1c8a4aa6696733627def46138dc6ab485 Mon Sep 17 00:00:00 2001 From: Shaoxiong Zhang Date: Tue, 1 May 2018 19:07:08 -0400 Subject: [PATCH 46/58] add alter executor --- src/catalog/catalog.cpp | 7 +- src/executor/alter_executor.cpp | 147 ++++++++++++++++++++------ src/include/catalog/catalog.h | 2 +- src/include/catalog/column.h | 7 +- src/include/catalog/schema.h | 5 + src/include/executor/alter_executor.h | 5 +- src/include/planner/alter_plan.h | 9 +- 7 files changed, 137 insertions(+), 45 deletions(-) diff --git a/src/catalog/catalog.cpp b/src/catalog/catalog.cpp index 3534be15e59..e238775d018 100644 --- a/src/catalog/catalog.cpp +++ b/src/catalog/catalog.cpp @@ -804,9 +804,10 @@ std::shared_ptr Catalog::GetTableObject( * @param txn the transaction Context * @return TransactionContext ResultType(SUCCESS or FAILURE) */ -ResultType Catalog::AlterTable(oid_t database_oid, oid_t table_oid, - std::unique_ptr new_schema, - concurrency::TransactionContext *txn) { +ResultType Catalog::AlterTable( + UNUSED_ATTRIBUTE oid_t database_oid, UNUSED_ATTRIBUTE oid_t table_oid, + UNUSED_ATTRIBUTE std::unique_ptr &new_schema, + UNUSED_ATTRIBUTE concurrency::TransactionContext *txn) { LOG_TRACE("AlterTable in Catalog"); if (txn == nullptr) diff --git a/src/executor/alter_executor.cpp b/src/executor/alter_executor.cpp index 12eef5c6d60..bf346ed8fc5 100644 --- a/src/executor/alter_executor.cpp +++ b/src/executor/alter_executor.cpp @@ -10,11 +10,12 @@ // //===----------------------------------------------------------------------===// -#include "executor/alter_executor.h" - #include "catalog/catalog.h" +#include "catalog/table_catalog.h" #include "common/logger.h" +#include "executor/alter_executor.h" #include "executor/executor_context.h" +#include "storage/data_table.h" namespace peloton { namespace executor { @@ -22,9 +23,7 @@ namespace executor { // Constructor for alter table executor AlterExecutor::AlterExecutor(const planner::AbstractPlan *node, ExecutorContext *executor_context) - : AbstractExecutor(node, executor_context), - isAlter_( - !reinterpret_cast(node)->IsRename()) {} + : AbstractExecutor(node, executor_context) {} // Initialize executor // Nothing to initialize for now @@ -38,24 +37,20 @@ bool AlterExecutor::DInit() { bool AlterExecutor::DExecute() { LOG_TRACE("Executing Alter..."); bool result = false; - if (!isAlter_) { - const planner::AlterPlan &node = GetPlanNode(); - auto current_txn = executor_context_->GetTransaction(); - result = RenameColumn(node, current_txn); - } else { - const planner::AlterPlan &node = GetPlanNode(); - auto current_txn = executor_context_->GetTransaction(); - AlterType type = node.GetAlterTableType(); - switch (type) { - case AlterType::ALTER: - result = DropColumn(node, current_txn); - break; - default: - throw NotImplementedException(StringUtil::Format( - "Alter Type not supported, %s", AlterTypeToString(type).c_str())); - } + const planner::AlterPlan &node = GetPlanNode(); + auto current_txn = executor_context_->GetTransaction(); + AlterType type = node.GetAlterTableType(); + switch (type) { + case AlterType::RENAME: + result = RenameColumn(node, current_txn); + break; + case AlterType::ALTER: + result = AlterTable(node, current_txn); + break; + default: + throw NotImplementedException(StringUtil::Format( + "Alter Type not supported, %s", AlterTypeToString(type).c_str())); } - return result; } @@ -82,23 +77,109 @@ bool AlterExecutor::RenameColumn( return false; } -bool AlterExecutor::DropColumn(const peloton::planner::AlterPlan &node, +bool AlterExecutor::AlterTable(const peloton::planner::AlterPlan &node, peloton::concurrency::TransactionContext *txn) { auto database_name = node.GetDatabaseName(); auto table_name = node.GetTableName(); - auto drop_columns = node.GetDroppedColumns(); - ResultType result = catalog::Catalog::GetInstance()->DropColumn( - database_name, table_name, drop_columns, txn); - txn->SetResult(result); + auto table_catalog_obj = catalog::Catalog::GetInstance()->GetTableObject( + database_name, table_name, txn); + oid_t database_oid = table_catalog_obj->GetDatabaseOid(); + oid_t table_oid = table_catalog_obj->GetTableOid(); + + auto old_table = catalog::Catalog::GetInstance()->GetTableWithName( + database_name, table_name, txn); + auto old_schema = old_table->GetSchema(); + std::vector column_ids; + + // Step 1: remove drop columns from old schema + for (oid_t i = 0; i < old_schema->GetColumnCount(); ++i) { + bool is_found = false; + for (auto drop_column : node.GetDroppedColumns()) { + if (old_schema->GetColumn(i).GetName() == drop_column) { + is_found = true; + } + } + if (!is_found) { + column_ids.push_back(i); + } + } + // Check if dropped column exists + if (column_ids.size() + node.GetDroppedColumns().size() != + old_schema->GetColumnCount()) { + LOG_TRACE("Dropped column not exists"); + txn->SetResult(ResultType::FAILURE); + return false; + } + std::unique_ptr temp_schema( + catalog::Schema::CopySchema(old_schema, column_ids)); + + // Step 2: change column type if exists + for (auto change_pair : node.GetChangedTypeColumns()) { + bool is_found = false; + oid_t i = 0; + for (; i < temp_schema->GetColumnCount(); ++i) { + if (temp_schema->GetColumn(i).GetName() == change_pair.first) { + is_found = true; + break; + } + } + if (!is_found) { + LOG_TRACE("Change column type failed: Column %s does not exists", + change_pair.first.c_str()); + txn->SetResult(ResultType::FAILURE); + return false; + } else { + temp_schema->ChangeColumnType(i, change_pair.second); + } + } - if (txn->GetResult() == ResultType::SUCCESS) { - LOG_TRACE("Drop column succeed!"); + // Step 3: append add column to new schema + // construct add column schema + std::vector add_columns; + for (size_t i = 0; i < node.GetAddedColumns().size(); ++i) { + for (auto column : node.GetAddedColumns()[i]->GetColumns()) { + add_columns.push_back(column); + } + } + std::unique_ptr add_column_schema( + new catalog::Schema(add_columns)); + // Check if added column exists + for (auto new_column : add_column_schema->GetColumns()) { + for (auto old_column : old_schema->GetColumns()) { + if (new_column.GetName() == old_column.GetName()) { + LOG_TRACE("Add column failed: Column %s already exists", + new_column.GetName().c_str()); + txn->SetResult(ResultType::FAILURE); + return false; + } + } + } - // TODO: Add on succeed logic if necessary - executor_context_->num_processed = 1; - } else { - LOG_TRACE("Result is: %s", ResultTypeToString(txn->GetResult()).c_str()); + // Construct new schema + std::unique_ptr new_schema(catalog::Schema::AppendSchema( + temp_schema.get(), add_column_schema.get())); + + // Copy and replace table content to new schema in catalog + ResultType result = catalog::Catalog::GetInstance()->AlterTable( + database_oid, table_oid, new_schema, txn); + txn->SetResult(result); + + switch (txn->GetResult()) { + case ResultType::SUCCESS: + LOG_TRACE("Alter table succeed!"); + + // TODO: Add on succeed logic if necessary + executor_context_->num_processed = 1; + break; + case ResultType::FAILURE: + LOG_TRACE("Alter table failed!"); + + // TODO: Add on failed logic if necessary + break; + default: + LOG_TRACE("Result is: %s", ResultTypeToString(txn->GetResult()).c_str()); + break; } return false; } diff --git a/src/include/catalog/catalog.h b/src/include/catalog/catalog.h index ae7758228e6..9aff30801bc 100644 --- a/src/include/catalog/catalog.h +++ b/src/include/catalog/catalog.h @@ -181,7 +181,7 @@ class Catalog { // ALTER TABLE //===--------------------------------------------------------------------===// ResultType AlterTable(oid_t database_oid, oid_t table_oid, - std::unique_ptr new_schema, + std::unique_ptr &new_schema, concurrency::TransactionContext *txn); ResultType AddColumn(const std::string &database_name, diff --git a/src/include/catalog/column.h b/src/include/catalog/column.h index f351f72c5b9..9917c5e2829 100644 --- a/src/include/catalog/column.h +++ b/src/include/catalog/column.h @@ -33,9 +33,8 @@ class Column : public Printable { // Nothing to see... } - Column(type::TypeId value_type, size_t column_length, - std::string column_name, bool is_inlined = false, - oid_t column_offset = INVALID_OID) + Column(type::TypeId value_type, size_t column_length, std::string column_name, + bool is_inlined = false, oid_t column_offset = INVALID_OID) : column_name(column_name), column_type(value_type), fixed_length(INVALID_OID), @@ -78,6 +77,8 @@ class Column : public Printable { inline type::TypeId GetType() const { return column_type; } + inline void SetType(const type::TypeId &new_type) { column_type = new_type; } + inline bool IsInlined() const { return is_inlined; } inline bool IsPrimary() const { return is_primary_; } diff --git a/src/include/catalog/schema.h b/src/include/catalog/schema.h index d722a21812c..6f401f5e0a2 100644 --- a/src/include/catalog/schema.h +++ b/src/include/catalog/schema.h @@ -149,6 +149,11 @@ class Schema : public Printable { columns[column_id].column_name = new_name; } + inline void ChangeColumnType(const oid_t column_id, + const type::TypeId &new_type) { + columns[column_id].SetType(new_type); + } + inline oid_t GetUninlinedColumn(const oid_t column_id) const { return uninlined_columns[column_id]; } diff --git a/src/include/executor/alter_executor.h b/src/include/executor/alter_executor.h index 500b4e679b9..b644d48456b 100644 --- a/src/include/executor/alter_executor.h +++ b/src/include/executor/alter_executor.h @@ -44,11 +44,8 @@ class AlterExecutor : public AbstractExecutor { bool RenameColumn(const planner::AlterPlan &node, concurrency::TransactionContext *txn); - bool DropColumn(const planner::AlterPlan &node, + bool AlterTable(const planner::AlterPlan &node, concurrency::TransactionContext *txn); - - private: - bool isAlter_; }; } // executor diff --git a/src/include/planner/alter_plan.h b/src/include/planner/alter_plan.h index 27ab8e3d9cb..9b73ec4c9d4 100644 --- a/src/include/planner/alter_plan.h +++ b/src/include/planner/alter_plan.h @@ -75,12 +75,19 @@ class AlterPlan : public AbstractPlan { std::string GetDatabaseName() const { return database_name; } - // catalog::Schema *GetAddedColumns() const { return added_columns; } + const std::vector> &GetAddedColumns() const { + return added_columns; + } const std::vector &GetDroppedColumns() const { return dropped_columns; } + const std::vector> & + GetChangedTypeColumns() const { + return changed_type_columns; + }; + AlterType GetAlterTableType() const { return type; } // function used for rename statement From 9904788f163e4070e1ce5405cb8db563e1e9d17f Mon Sep 17 00:00:00 2001 From: Shaoxiong Zhang Date: Wed, 2 May 2018 20:42:57 -0400 Subject: [PATCH 47/58] resolve pr comments --- src/executor/alter_executor.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/executor/alter_executor.cpp b/src/executor/alter_executor.cpp index bf346ed8fc5..e0e0c71a32d 100644 --- a/src/executor/alter_executor.cpp +++ b/src/executor/alter_executor.cpp @@ -10,10 +10,11 @@ // //===----------------------------------------------------------------------===// +#include "executor/alter_executor.h" + #include "catalog/catalog.h" #include "catalog/table_catalog.h" #include "common/logger.h" -#include "executor/alter_executor.h" #include "executor/executor_context.h" #include "storage/data_table.h" From fdce5cfbfee6622a612330b298b37fcfd4bce88f Mon Sep 17 00:00:00 2001 From: dingshilun Date: Wed, 2 May 2018 21:03:31 -0400 Subject: [PATCH 48/58] modified alter plan, fixed bugs --- src/planner/alter_plan.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/planner/alter_plan.cpp b/src/planner/alter_plan.cpp index 3623ed3df0f..6cd456892dc 100644 --- a/src/planner/alter_plan.cpp +++ b/src/planner/alter_plan.cpp @@ -58,10 +58,10 @@ AlterPlan::AlterPlan(parser::AlterTableStatement *parse_tree) { } case parser::AlterTableStatement::AlterTableType::ALTER: { // deal with dropped columns + type = AlterType::ALTER; for (auto col : *parse_tree->dropped_names) { LOG_TRACE("Drooped column name: %s", col); dropped_columns.push_back(std::string(col)); - type = AlterType::ALTER; } // deal with added columns @@ -96,6 +96,7 @@ AlterPlan::AlterPlan(parser::AlterTableStatement *parse_tree) { std::string name = tmp.get()->name; changed_type_columns.emplace_back(std::make_pair(name, val)); } + break; } default: LOG_ERROR("Not Implemented the plan yet!"); From ae65f67287f56646d44993231ed342d8849c9871 Mon Sep 17 00:00:00 2001 From: dingshilun Date: Thu, 3 May 2018 14:42:27 -0400 Subject: [PATCH 49/58] added change type, changed logic in alter_executor, varchar still not suppport --- src/catalog/catalog.cpp | 21 +++++++++++++++------ src/executor/alter_executor.cpp | 26 ++++++++++++++++---------- src/parser/postgresparser.cpp | 1 + src/storage/database.cpp | 1 + 4 files changed, 33 insertions(+), 16 deletions(-) diff --git a/src/catalog/catalog.cpp b/src/catalog/catalog.cpp index e7a2b657763..d3ef31e3397 100644 --- a/src/catalog/catalog.cpp +++ b/src/catalog/catalog.cpp @@ -917,6 +917,7 @@ ResultType Catalog::AlterTable( new_column_id < new_schema->GetColumnCount(); new_column_id++) { auto it = column_map.find(new_column_id); type::Value val; + auto cast_flag = false; if (it == column_map.end()) { // new column, set value to null val = type::ValueFactory::GetNullValueByType( @@ -927,10 +928,18 @@ ResultType Catalog::AlterTable( val = result_tile->GetValue(i, it->second); if (new_schema->GetColumn(new_column_id).GetType() != old_schema->GetColumn(it->second).GetType()) { //change the value's type - val = val.CastAs(new_schema->GetColumn(new_column_id).GetType()); + LOG_TRACE("CASTED: %s TO %s", val.GetInfo().c_str(),new_schema->GetColumn(new_column_id).GetInfo() + .c_str()); + auto casted_val = val.CastAs(new_schema->GetColumn(new_column_id).GetType()); + cast_flag = true; + tuple->SetValue(new_column_id, casted_val, pool_.get()); } } - tuple->SetValue(new_column_id, val, pool_.get()); + if (!cast_flag) { + tuple->SetValue(new_column_id, val, pool_.get()); + } else { + LOG_TRACE("CASTED: %s", val.GetInfo().c_str()); + } } // insert new tuple into new table planner::InsertPlan node(new_table, std::move(tuple)); @@ -946,19 +955,19 @@ ResultType Catalog::AlterTable( oid_t column_offset = 0; for (auto new_column : new_schema->GetColumns()) { catalog::ColumnCatalog::GetInstance()->InsertColumn( - table_oid, new_column.GetName(), column_offset, + new_table->GetOid(), new_column.GetName(), column_offset, new_column.GetOffset(), new_column.GetType(), new_column.IsInlined(), new_column.GetConstraints(), pool_.get(), txn); column_offset++; } + // Record table drop + // txn->RecordDrop(database_oid, old_table->GetOid(), INVALID_OID); // Final step of physical change should be moved to commit time database->ReplaceTableWithOid(table_oid, new_table); - // Record table drop - txn->RecordDrop(database_oid, table_oid, INVALID_OID); - + LOG_TRACE("Alter table with oid %d", new_table->GetOid()); } catch (CatalogException &e) { LOG_TRACE("Alter table failed."); return ResultType::FAILURE; diff --git a/src/executor/alter_executor.cpp b/src/executor/alter_executor.cpp index e0e0c71a32d..fb5c129fbf6 100644 --- a/src/executor/alter_executor.cpp +++ b/src/executor/alter_executor.cpp @@ -114,13 +114,13 @@ bool AlterExecutor::AlterTable(const peloton::planner::AlterPlan &node, } std::unique_ptr temp_schema( catalog::Schema::CopySchema(old_schema, column_ids)); - + auto columns = temp_schema->GetColumns(); // Step 2: change column type if exists for (auto change_pair : node.GetChangedTypeColumns()) { bool is_found = false; oid_t i = 0; - for (; i < temp_schema->GetColumnCount(); ++i) { - if (temp_schema->GetColumn(i).GetName() == change_pair.first) { + for (; i < columns.size(); ++i) { + if (columns[i].GetName() == change_pair.first) { is_found = true; break; } @@ -131,7 +131,16 @@ bool AlterExecutor::AlterTable(const peloton::planner::AlterPlan &node, txn->SetResult(ResultType::FAILURE); return false; } else { - temp_schema->ChangeColumnType(i, change_pair.second); + if (change_pair.second != type::TypeId::VARCHAR) { + columns[i].SetType(change_pair.second); + columns[i].SetLength(type::VarlenType::GetTypeSize(change_pair.second)); + } else { + //TODO decide VARCHAR's size when change type + //It is broken now! + columns[i].SetType(change_pair.second); + //columns[i].SetLength(type::VarlenType::GetTypeSize(change_pair.second)); + columns[i].SetInlined(); + } } } @@ -143,10 +152,8 @@ bool AlterExecutor::AlterTable(const peloton::planner::AlterPlan &node, add_columns.push_back(column); } } - std::unique_ptr add_column_schema( - new catalog::Schema(add_columns)); // Check if added column exists - for (auto new_column : add_column_schema->GetColumns()) { + for (auto new_column : add_columns) { for (auto old_column : old_schema->GetColumns()) { if (new_column.GetName() == old_column.GetName()) { LOG_TRACE("Add column failed: Column %s already exists", @@ -156,10 +163,9 @@ bool AlterExecutor::AlterTable(const peloton::planner::AlterPlan &node, } } } - + columns.insert(columns.end(), add_columns.begin(), add_columns.end()); // Construct new schema - std::unique_ptr new_schema(catalog::Schema::AppendSchema( - temp_schema.get(), add_column_schema.get())); + std::unique_ptr new_schema(new catalog::Schema(columns)); // Copy and replace table content to new schema in catalog ResultType result = catalog::Catalog::GetInstance()->AlterTable( diff --git a/src/parser/postgresparser.cpp b/src/parser/postgresparser.cpp index 02fec77ea20..da976d60ff0 100644 --- a/src/parser/postgresparser.cpp +++ b/src/parser/postgresparser.cpp @@ -1811,6 +1811,7 @@ parser::AlterTableStatement *PostgresParser::AlterTransform(Node *root) { std::unique_ptr col_def( new ColumnDefinition(cmd->name, type_id)); result->changed_type_columns->push_back(std::move(col_def)); + break; } default: { throw NotImplementedException(StringUtil::Format( diff --git a/src/storage/database.cpp b/src/storage/database.cpp index 74b11427794..45d5e7dadf5 100644 --- a/src/storage/database.cpp +++ b/src/storage/database.cpp @@ -112,6 +112,7 @@ storage::DataTable *Database::ReplaceTableWithOid( const oid_t table_oid, storage::DataTable *new_table) { { std::lock_guard lock(database_mutex); + codegen::QueryCache::Instance().Remove(table_oid); oid_t table_offset = 0; for (auto table : tables) { From 4e4dfdc2ac5c576ab0a9735915d69b230005b5f3 Mon Sep 17 00:00:00 2001 From: Dean Chen Date: Fri, 4 May 2018 00:29:26 -0400 Subject: [PATCH 50/58] addressed comments and fix varchar --- src/catalog/catalog.cpp | 37 ++++++++++++++------------------- src/catalog/column.cpp | 1 + src/executor/alter_executor.cpp | 16 ++++++-------- 3 files changed, 23 insertions(+), 31 deletions(-) diff --git a/src/catalog/catalog.cpp b/src/catalog/catalog.cpp index d3ef31e3397..71b568e9db2 100644 --- a/src/catalog/catalog.cpp +++ b/src/catalog/catalog.cpp @@ -804,10 +804,9 @@ std::shared_ptr Catalog::GetTableObject( * @param txn the transaction Context * @return TransactionContext ResultType(SUCCESS or FAILURE) */ -ResultType Catalog::AlterTable( - UNUSED_ATTRIBUTE oid_t database_oid, UNUSED_ATTRIBUTE oid_t table_oid, - UNUSED_ATTRIBUTE std::unique_ptr &new_schema, - UNUSED_ATTRIBUTE concurrency::TransactionContext *txn) { +ResultType Catalog::AlterTable(oid_t database_oid, oid_t table_oid, + std::unique_ptr &new_schema, + concurrency::TransactionContext *txn) { LOG_TRACE("AlterTable in Catalog"); if (txn == nullptr) @@ -864,7 +863,6 @@ ResultType Catalog::AlterTable( old_index->GetMetadata()->GetIndexType(), old_index->GetMetadata()->GetIndexConstraintType(), new_schema.get(), - // catalog::Schema::CopySchema(old_index->GetKeySchema()), catalog::Schema::CopySchema(new_schema.get(), new_key_attrs), new_key_attrs, old_index->GetMetadata()->HasUniqueKeys()); @@ -917,29 +915,26 @@ ResultType Catalog::AlterTable( new_column_id < new_schema->GetColumnCount(); new_column_id++) { auto it = column_map.find(new_column_id); type::Value val; - auto cast_flag = false; if (it == column_map.end()) { // new column, set value to null val = type::ValueFactory::GetNullValueByType( new_schema->GetColumn(new_column_id).GetType()); } else { // otherwise, copy value in old table - // TODO: Change type if necessary val = result_tile->GetValue(i, it->second); - if (new_schema->GetColumn(new_column_id).GetType() != old_schema->GetColumn(it->second).GetType()) { - //change the value's type - LOG_TRACE("CASTED: %s TO %s", val.GetInfo().c_str(),new_schema->GetColumn(new_column_id).GetInfo() - .c_str()); - auto casted_val = val.CastAs(new_schema->GetColumn(new_column_id).GetType()); - cast_flag = true; + if (new_schema->GetColumn(new_column_id).GetType() != + old_schema->GetColumn(it->second).GetType()) { + // change the value's type + LOG_TRACE( + "CASTED: %s TO %s", val.GetInfo().c_str(), + new_schema->GetColumn(new_column_id).GetInfo().c_str()); + auto casted_val = + val.CastAs(new_schema->GetColumn(new_column_id).GetType()); tuple->SetValue(new_column_id, casted_val, pool_.get()); + } else { + tuple->SetValue(new_column_id, val, pool_.get()); } } - if (!cast_flag) { - tuple->SetValue(new_column_id, val, pool_.get()); - } else { - LOG_TRACE("CASTED: %s", val.GetInfo().c_str()); - } } // insert new tuple into new table planner::InsertPlan node(new_table, std::move(tuple)); @@ -955,19 +950,19 @@ ResultType Catalog::AlterTable( oid_t column_offset = 0; for (auto new_column : new_schema->GetColumns()) { catalog::ColumnCatalog::GetInstance()->InsertColumn( - new_table->GetOid(), new_column.GetName(), column_offset, + table_oid, new_column.GetName(), column_offset, new_column.GetOffset(), new_column.GetType(), new_column.IsInlined(), new_column.GetConstraints(), pool_.get(), txn); column_offset++; } - // Record table drop + // TODO: Add gc logic // txn->RecordDrop(database_oid, old_table->GetOid(), INVALID_OID); // Final step of physical change should be moved to commit time database->ReplaceTableWithOid(table_oid, new_table); - LOG_TRACE("Alter table with oid %d", new_table->GetOid()); + LOG_TRACE("Alter table with oid %d succeed.", table_oid); } catch (CatalogException &e) { LOG_TRACE("Alter table failed."); return ResultType::FAILURE; diff --git a/src/catalog/column.cpp b/src/catalog/column.cpp index 50406bef954..48efc98ddfa 100644 --- a/src/catalog/column.cpp +++ b/src/catalog/column.cpp @@ -34,6 +34,7 @@ void Column::SetInlined() { switch (column_type) { case type::TypeId::VARCHAR: case type::TypeId::VARBINARY: + is_inlined = false; break; // No change of inlined setting default: diff --git a/src/executor/alter_executor.cpp b/src/executor/alter_executor.cpp index fb5c129fbf6..0681f4ee74f 100644 --- a/src/executor/alter_executor.cpp +++ b/src/executor/alter_executor.cpp @@ -131,16 +131,12 @@ bool AlterExecutor::AlterTable(const peloton::planner::AlterPlan &node, txn->SetResult(ResultType::FAILURE); return false; } else { - if (change_pair.second != type::TypeId::VARCHAR) { - columns[i].SetType(change_pair.second); - columns[i].SetLength(type::VarlenType::GetTypeSize(change_pair.second)); - } else { - //TODO decide VARCHAR's size when change type - //It is broken now! - columns[i].SetType(change_pair.second); - //columns[i].SetLength(type::VarlenType::GetTypeSize(change_pair.second)); - columns[i].SetInlined(); - } + columns[i].SetType(change_pair.second); + columns[i].SetInlined(); + columns[i].SetLength(type::VarlenType::GetTypeSize(change_pair.second)); + + // TODO: decide VARCHAR's size when change type + // if (change_pair.second == type::TypeId::VARCHAR) {} } } From 5e454d4f85f3f306c92570a4e3a8b9586e5d4b8f Mon Sep 17 00:00:00 2001 From: Dean Chen Date: Fri, 4 May 2018 11:35:19 -0400 Subject: [PATCH 51/58] basic test for alterTable --- script/testing/junit/AlterTableTest.java | 114 +++++++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/script/testing/junit/AlterTableTest.java b/script/testing/junit/AlterTableTest.java index eb82edbc261..71719a4b295 100644 --- a/script/testing/junit/AlterTableTest.java +++ b/script/testing/junit/AlterTableTest.java @@ -14,6 +14,7 @@ import org.junit.*; import org.junit.rules.ExpectedException; import org.postgresql.util.PSQLException; +import static org.junit.Assert.assertEquals; public class AlterTableTest extends PLTestBase { private Connection conn; @@ -193,4 +194,117 @@ public void test_RenameCol_Concurrent() throws SQLException { // conn2.commit(); // } + /** + * Add a column to the table. + */ + @Test + public void test_AddCol_Basic() throws SQLException { + String sql = "ALTER TABLE foo add month int;"; + conn.createStatement().execute(sql); + ResultSet rs = conn.createStatement().executeQuery(SQL_SELECT_STAR); + rs.next(); + checkRow(rs, + new String [] {"id", "year", "month"}, + new int [] {5, 400, 0}); + assertNoMoreRows(rs); + } + + /** + * Add a column to a name that already exists, should throw exception + */ + @Test + public void test_AddCol_Exist() throws SQLException { + String sql = "ALTER TABLE foo ADD year int;"; + + // New column already exists + thrown.expect(PSQLException.class); + conn.createStatement().execute(sql); + } + + /** + * Drop a column from the table. + */ + @Test + public void test_DropCol_Basic() throws SQLException { + String sql = "ALTER TABLE foo DROP year;"; + conn.createStatement().execute(sql); + ResultSet rs = conn.createStatement().executeQuery(SQL_SELECT_STAR); + rs.next(); + checkRow(rs, + new String [] {"id"}, + new int [] {5}); + assertNoMoreRows(rs); + } + + /** + * Drop a column that does not exists, should throw exception + */ + @Test + public void test_DropCol_NotExist() throws SQLException { + String sql = "ALTER TABLE foo DROP month;"; + + // Old column does not exist + thrown.expect(PSQLException.class); + conn.createStatement().execute(sql); + } + + /** + * Alter column type from int to float and then alter to int again. + */ + @Test + public void test_AlterType_Basic() throws SQLException { + String sql = "ALTER TABLE foo ALTER year TYPE float;"; + conn.createStatement().execute(sql); + ResultSet rs = conn.createStatement().executeQuery(SQL_SELECT_STAR); + rs.next(); + assertEquals(rs.getInt("id"), 5); + assertEquals(rs.getFloat("year"), 400, 1e-3); + assertNoMoreRows(rs); + + String sql2 = "INSERT INTO foo VALUES (6, 3.5);"; + conn.createStatement().execute(sql2); + rs = conn.createStatement().executeQuery(SQL_SELECT_STAR); + rs.next(); + assertEquals(rs.getInt("id"), 5); + assertEquals(rs.getFloat("year"), 400, 1e-3); + rs.next(); + assertEquals(rs.getInt("id"), 6); + assertEquals(rs.getFloat("year"), 3.5, 1e-3); + assertNoMoreRows(rs); + + + String sql3 = "ALTER TABLE foo ALTER year TYPE int;"; + conn.createStatement().execute(sql3); + rs = conn.createStatement().executeQuery(SQL_SELECT_STAR); + rs.next(); + assertEquals(rs.getInt("id"), 5); + assertEquals(rs.getInt("year"), 400); + rs.next(); + assertEquals(rs.getInt("id"), 6); + assertEquals(rs.getInt("year"), 3); + assertNoMoreRows(rs); + } + + + /** + * Alter column type from int to varchar and backwards. + */ + @Test + public void test_AlterType_Varchar() throws SQLException { + String sql = "ALTER TABLE foo ALTER year TYPE varchar;"; + conn.createStatement().execute(sql); + ResultSet rs = conn.createStatement().executeQuery(SQL_SELECT_STAR); + rs.next(); + assertEquals(rs.getInt("id"), 5); + assertEquals(rs.getString("year"), Integer.toString(400)); + assertNoMoreRows(rs); + + String sql2 = "ALTER TABLE foo ALTER year TYPE int;"; + conn.createStatement().execute(sql2); + rs = conn.createStatement().executeQuery(SQL_SELECT_STAR); + rs.next(); + assertEquals(rs.getInt("id"), 5); + assertEquals(rs.getInt("year"), 400); + assertNoMoreRows(rs); + } } From bc264113535514cb8fcfd0fb181d3ece6b24602e Mon Sep 17 00:00:00 2001 From: Shaoxiong Zhang Date: Fri, 4 May 2018 16:53:53 -0400 Subject: [PATCH 52/58] add alter table tests, change unsupported type, multiple operation in a statement --- script/testing/junit/AlterTableTest.java | 106 +++++++++++++++++++++-- 1 file changed, 99 insertions(+), 7 deletions(-) diff --git a/script/testing/junit/AlterTableTest.java b/script/testing/junit/AlterTableTest.java index 71719a4b295..c134a74bc70 100644 --- a/script/testing/junit/AlterTableTest.java +++ b/script/testing/junit/AlterTableTest.java @@ -33,6 +33,8 @@ public class AlterTableTest extends PLTestBase { private static final String SQL_RENAME_COLUMN = "ALTER TABLE foo RENAME year to month;"; + private static final double EPSILON = 1e-6; + @Rule public ExpectedException thrown = ExpectedException.none(); @@ -195,11 +197,11 @@ public void test_RenameCol_Concurrent() throws SQLException { // } /** - * Add a column to the table. + * Add a column to the table, and do some insertion. */ @Test public void test_AddCol_Basic() throws SQLException { - String sql = "ALTER TABLE foo add month int;"; + String sql = "ALTER TABLE foo ADD month int;"; conn.createStatement().execute(sql); ResultSet rs = conn.createStatement().executeQuery(SQL_SELECT_STAR); rs.next(); @@ -207,6 +209,19 @@ public void test_AddCol_Basic() throws SQLException { new String [] {"id", "year", "month"}, new int [] {5, 400, 0}); assertNoMoreRows(rs); + + String sql2 = "INSERT INTO foo VALUES (6, 500, 1);"; + conn.createStatement().execute(sql2); + rs = conn.createStatement().executeQuery(SQL_SELECT_STAR); + rs.next(); + checkRow(rs, + new String [] {"id", "year", "month"}, + new int [] {5, 400, 0}); + rs.next(); + checkRow(rs, + new String [] {"id", "year", "month"}, + new int [] {6, 500, 1}); + assertNoMoreRows(rs); } /** @@ -234,6 +249,19 @@ public void test_DropCol_Basic() throws SQLException { new String [] {"id"}, new int [] {5}); assertNoMoreRows(rs); + + String sql2 = "INSERT INTO foo VALUES (6);"; + conn.createStatement().execute(sql2); + rs = conn.createStatement().executeQuery(SQL_SELECT_STAR); + rs.next(); + checkRow(rs, + new String [] {"id"}, + new int [] {5}); + rs.next(); + checkRow(rs, + new String [] {"id"}, + new int [] {6}); + assertNoMoreRows(rs); } /** @@ -258,7 +286,7 @@ public void test_AlterType_Basic() throws SQLException { ResultSet rs = conn.createStatement().executeQuery(SQL_SELECT_STAR); rs.next(); assertEquals(rs.getInt("id"), 5); - assertEquals(rs.getFloat("year"), 400, 1e-3); + assertEquals(rs.getFloat("year"), 400, EPSILON); assertNoMoreRows(rs); String sql2 = "INSERT INTO foo VALUES (6, 3.5);"; @@ -266,13 +294,12 @@ public void test_AlterType_Basic() throws SQLException { rs = conn.createStatement().executeQuery(SQL_SELECT_STAR); rs.next(); assertEquals(rs.getInt("id"), 5); - assertEquals(rs.getFloat("year"), 400, 1e-3); + assertEquals(rs.getFloat("year"), 400, EPSILON); rs.next(); assertEquals(rs.getInt("id"), 6); - assertEquals(rs.getFloat("year"), 3.5, 1e-3); + assertEquals(rs.getFloat("year"), 3.5, EPSILON); assertNoMoreRows(rs); - String sql3 = "ALTER TABLE foo ALTER year TYPE int;"; conn.createStatement().execute(sql3); rs = conn.createStatement().executeQuery(SQL_SELECT_STAR); @@ -285,7 +312,6 @@ public void test_AlterType_Basic() throws SQLException { assertNoMoreRows(rs); } - /** * Alter column type from int to varchar and backwards. */ @@ -307,4 +333,70 @@ public void test_AlterType_Varchar() throws SQLException { assertEquals(rs.getInt("year"), 400); assertNoMoreRows(rs); } + + /** + * Alter type to column that does not exist + */ + @Test + public void test_AlterType_NonExist() throws SQLException { + String sql = "ALTER TABLE foo ALTER a TYPE int;"; + + thrown.expect(PSQLException.class); + conn.createStatement().execute(sql); + } + + /** + * Alter to an unsupported column type + */ + @Test + public void test_AlterType_UnSupported() throws SQLException { + String sql = "ALTER TABLE foo ALTER year TYPE non;"; + thrown.expect(PSQLException.class); + conn.createStatement().execute(sql); + } + + /** + * Add columns, drop columns, change column type in one sql statement + */ + @Test + public void test_MultiOperation() throws SQLException { + String sql = + "ALTER TABLE foo ADD month INT, DROP year, ALTER id TYPE float;"; + conn.createStatement().execute(sql); + ResultSet rs = conn.createStatement().executeQuery(SQL_SELECT_STAR); + rs.next(); + assertEquals(rs.getFloat("id"), 5, EPSILON); + assertEquals(rs.getInt("month"), 0); + assertNoMoreRows(rs); + + String sql2 = "INSERT INTO foo VALUES (4.5, 3);"; + conn.createStatement().execute(sql2); + rs = conn.createStatement().executeQuery(SQL_SELECT_STAR); + rs.next(); + assertEquals(rs.getFloat("id"), 5, EPSILON); + assertEquals(rs.getInt("month"), 0); + rs.next(); + assertEquals(rs.getFloat("id"), 4.5, EPSILON); + assertEquals(rs.getInt("month"), 3); + assertNoMoreRows(rs); + } + + /** + * If multiple operations in one statement failed, schema will not change + */ + @Test + public void test_MultiOperationFailed() throws SQLException { + String sql = + "ALTER TABLE foo ADD month int, DROP month, ALTER year TYPE float;"; + + thrown.expect(PSQLException.class); + conn.createStatement().execute(sql); + + ResultSet rs = conn.createStatement().executeQuery(SQL_SELECT_STAR); + rs.next(); + checkRow(rs, + new String [] {"id", "year"}, + new int [] {5, 400}); + assertNoMoreRows(rs); + } } From 72c35ace2d3b8c83de2b75157c7060105579a6d9 Mon Sep 17 00:00:00 2001 From: dingshilun Date: Fri, 4 May 2018 20:55:37 -0400 Subject: [PATCH 53/58] added alter varchar length support, changed the plan to use schema addressed bug --- src/executor/alter_executor.cpp | 17 ++++++----------- src/include/planner/alter_plan.h | 13 +++++++------ src/parser/postgresparser.cpp | 19 ++++++++++--------- src/planner/alter_plan.cpp | 31 +++++++++++++++++++------------ 4 files changed, 42 insertions(+), 38 deletions(-) diff --git a/src/executor/alter_executor.cpp b/src/executor/alter_executor.cpp index 0681f4ee74f..1fa9f21fec0 100644 --- a/src/executor/alter_executor.cpp +++ b/src/executor/alter_executor.cpp @@ -116,25 +116,22 @@ bool AlterExecutor::AlterTable(const peloton::planner::AlterPlan &node, catalog::Schema::CopySchema(old_schema, column_ids)); auto columns = temp_schema->GetColumns(); // Step 2: change column type if exists - for (auto change_pair : node.GetChangedTypeColumns()) { + for (auto &change_col : node.GetChangedTypeColumns().get()->GetColumns()) { bool is_found = false; oid_t i = 0; for (; i < columns.size(); ++i) { - if (columns[i].GetName() == change_pair.first) { + if (columns[i].GetName() == change_col.GetName()) { is_found = true; break; } } if (!is_found) { LOG_TRACE("Change column type failed: Column %s does not exists", - change_pair.first.c_str()); + change_col.GetName().c_str()); txn->SetResult(ResultType::FAILURE); return false; } else { - columns[i].SetType(change_pair.second); - columns[i].SetInlined(); - columns[i].SetLength(type::VarlenType::GetTypeSize(change_pair.second)); - + columns[i] = std::move(change_col); // TODO: decide VARCHAR's size when change type // if (change_pair.second == type::TypeId::VARCHAR) {} } @@ -143,10 +140,8 @@ bool AlterExecutor::AlterTable(const peloton::planner::AlterPlan &node, // Step 3: append add column to new schema // construct add column schema std::vector add_columns; - for (size_t i = 0; i < node.GetAddedColumns().size(); ++i) { - for (auto column : node.GetAddedColumns()[i]->GetColumns()) { - add_columns.push_back(column); - } + for (auto column : node.GetAddedColumns()->GetColumns()) { + add_columns.push_back(column); } // Check if added column exists for (auto new_column : add_columns) { diff --git a/src/include/planner/alter_plan.h b/src/include/planner/alter_plan.h index 9b73ec4c9d4..8abc4d24c36 100644 --- a/src/include/planner/alter_plan.h +++ b/src/include/planner/alter_plan.h @@ -36,7 +36,8 @@ class AlterPlan : public AbstractPlan { explicit AlterPlan( const std::string &database_name, const std::string &table_name, const std::vector &dropped_columns, - const std::vector> &added_columns, + const std::unique_ptr &added_columns, + const std::unique_ptr &changed_type_columns, AlterType a_type); explicit AlterPlan(const std::string &database_name, const std::string &table_name, @@ -61,7 +62,7 @@ class AlterPlan : public AbstractPlan { switch (this->type) { case AlterType::ALTER: return std::unique_ptr(new AlterPlan( - database_name, table_name, dropped_columns, added_columns, type)); + database_name, table_name, dropped_columns, added_columns, changed_type_columns, type)); case AlterType::RENAME: return std::unique_ptr(new AlterPlan( database_name, table_name, old_names_, new_names_, type)); @@ -75,7 +76,7 @@ class AlterPlan : public AbstractPlan { std::string GetDatabaseName() const { return database_name; } - const std::vector> &GetAddedColumns() const { + const std::unique_ptr &GetAddedColumns() const { return added_columns; } @@ -83,7 +84,7 @@ class AlterPlan : public AbstractPlan { return dropped_columns; } - const std::vector> & + const std::unique_ptr & GetChangedTypeColumns() const { return changed_type_columns; }; @@ -110,11 +111,11 @@ class AlterPlan : public AbstractPlan { std::string database_name; // Schema delta, define the column txn want to add - std::vector> added_columns; + std::unique_ptr added_columns; // dropped_column, define the column you want to drop std::vector dropped_columns; // changed-type columns, define the column you want to change type - std::vector> changed_type_columns; + std::unique_ptr changed_type_columns; // used for store rename function data std::vector old_names_; std::vector new_names_; diff --git a/src/parser/postgresparser.cpp b/src/parser/postgresparser.cpp index da976d60ff0..a96749d2a10 100644 --- a/src/parser/postgresparser.cpp +++ b/src/parser/postgresparser.cpp @@ -1802,15 +1802,16 @@ parser::AlterTableStatement *PostgresParser::AlterTransform(Node *root) { } case AT_AlterColumnType: { ColumnDef *def = (ColumnDef *)cmd->def; - TypeName *type_name = def->typeName; - char *name = (reinterpret_cast( - type_name->names->tail->data.ptr_value) - ->val.str); - LOG_TRACE("DATA Type is :%s", name); - auto type_id = ColumnDefinition::StrToDataType(name); - std::unique_ptr col_def( - new ColumnDefinition(cmd->name, type_id)); - result->changed_type_columns->push_back(std::move(col_def)); + def->colname = cmd->name; + parser::CreateStatement tmp_statement( + parser::CreateStatement::CreateType::kTable); + LOG_TRACE("Adding change type column"); + ColumnDefTransform(reinterpret_cast(def), + &tmp_statement); + for (size_t i = 0; i < tmp_statement.columns.size();i++){ + result->changed_type_columns->emplace_back(std::move(tmp_statement.columns[i])); + } + LOG_TRACE("adding end"); break; } default: { diff --git a/src/planner/alter_plan.cpp b/src/planner/alter_plan.cpp index 6cd456892dc..f37d8b43e50 100644 --- a/src/planner/alter_plan.cpp +++ b/src/planner/alter_plan.cpp @@ -23,16 +23,15 @@ namespace planner { AlterPlan::AlterPlan( const std::string &database_name, const std::string &table_name, const std::vector &dropped_columns, - UNUSED_ATTRIBUTE const std::vector> - &added_columns_, + const std::unique_ptr &added_columns, + const std::unique_ptr &changed_type_columns, AlterType a_type) : table_name(table_name), database_name(database_name), dropped_columns(dropped_columns), type(a_type) { - // for (size_t i=0;iadded_columns.push_back(std::move(added_columns_[i])); - // } + this->added_columns = std::unique_ptr(new catalog::Schema(*added_columns)); + this->changed_type_columns = std::unique_ptr(new catalog::Schema(*changed_type_columns)); } AlterPlan::AlterPlan(const std::string &database_name, @@ -85,17 +84,25 @@ AlterPlan::AlterPlan(parser::AlterTableStatement *parse_tree) { } columns.emplace_back(column); } - added_columns.emplace_back( - std::unique_ptr(new catalog::Schema(columns))); - + added_columns = std::unique_ptr(new catalog::Schema(columns)); + columns.clear(); // deal with change column types for (size_t i = 0; i < (*parse_tree->changed_type_columns).size(); i++) { auto &tmp = (*parse_tree->changed_type_columns)[i]; - type::TypeId val = - parser::ColumnDefinition::GetValueType(tmp.get()->type); - std::string name = tmp.get()->name; - changed_type_columns.emplace_back(std::make_pair(name, val)); + type::TypeId val = parser::ColumnDefinition::GetValueType(tmp.get()->type); + bool is_inline = (val == type::TypeId::VARCHAR) ? false : true; + auto column = catalog::Column( + val, type::Type::GetTypeSize(val), + std::string((*parse_tree->changed_type_columns)[i].get()->name), + is_inline); + if ((*parse_tree->changed_type_columns)[i].get()->not_null) { + catalog::Constraint constraint(ConstraintType::NOTNULL, + "con_not_null"); + column.AddConstraint(constraint); + } + columns.emplace_back(column); } + changed_type_columns = std::unique_ptr(new catalog::Schema(columns)); break; } default: From 5b9818c7e67b248ea08e1fd254ba6b94680aba84 Mon Sep 17 00:00:00 2001 From: dingshilun Date: Sat, 5 May 2018 00:06:34 -0400 Subject: [PATCH 54/58] addressed the modification from cmu-db master --- src/catalog/catalog.cpp | 52 +++++++++++++--------------- src/catalog/column_catalog.cpp | 5 +-- src/executor/alter_executor.cpp | 11 +++--- src/include/catalog/catalog.h | 3 +- src/include/catalog/column_catalog.h | 2 +- src/include/planner/alter_plan.h | 4 +++ src/parser/postgresparser.cpp | 6 ++++ src/planner/alter_plan.cpp | 1 + 8 files changed, 47 insertions(+), 37 deletions(-) diff --git a/src/catalog/catalog.cpp b/src/catalog/catalog.cpp index 8e32619bee8..1bfc2702e54 100644 --- a/src/catalog/catalog.cpp +++ b/src/catalog/catalog.cpp @@ -947,7 +947,7 @@ std::shared_ptr Catalog::GetSystemCatalogs( * @param txn the transaction Context * @return TransactionContext ResultType(SUCCESS or FAILURE) */ -ResultType Catalog::AlterTable(oid_t database_oid, oid_t table_oid, +ResultType Catalog::AlterTable(oid_t database_oid, oid_t table_oid, const std::string &schema_name, std::unique_ptr &new_schema, concurrency::TransactionContext *txn) { LOG_TRACE("AlterTable in Catalog"); @@ -960,6 +960,7 @@ ResultType Catalog::AlterTable(oid_t database_oid, oid_t table_oid, try { auto old_table = database->GetTableWithOid(table_oid); auto old_schema = old_table->GetSchema(); + auto pg_index = catalog_map_[database_oid]->GetIndexCatalog(); // Step 1: build empty table with new schema bool own_schema = true; @@ -968,14 +969,12 @@ ResultType Catalog::AlterTable(oid_t database_oid, oid_t table_oid, database_oid, table_oid, catalog::Schema::CopySchema(new_schema.get()), old_table->GetName(), DEFAULT_TUPLES_PER_TILEGROUP, own_schema, adapt_table); - // Step 2: Copy indexes - auto old_index_oids = - IndexCatalog::GetInstance()->GetIndexObjects(table_oid, txn); + auto old_index_oids = pg_index->GetIndexObjects(table_oid, txn); for (auto index_oid_pair : old_index_oids) { oid_t index_oid = index_oid_pair.first; // delete record in pg_index - IndexCatalog::GetInstance()->DeleteIndex(index_oid, txn); + pg_index->DeleteIndex(index_oid, txn); // Check if all indexed columns still exists auto old_index = old_table->GetIndexWithOid(index_oid); bool index_exist = true; @@ -1014,14 +1013,13 @@ ResultType Catalog::AlterTable(oid_t database_oid, oid_t table_oid, new_table->AddIndex(new_index); // reinsert record into pg_index - IndexCatalog::GetInstance()->InsertIndex( - index_oid, old_index->GetName(), table_oid, + pg_index->InsertIndex( + index_oid, old_index->GetName(), table_oid, schema_name, old_index->GetMetadata()->GetIndexType(), old_index->GetMetadata()->GetIndexConstraintType(), old_index->GetMetadata()->HasUniqueKeys(), new_key_attrs, pool_.get(), txn); } - std::unique_ptr context( new executor::ExecutorContext(txn, {})); // Step 3: build column mapping between old table and new table @@ -1089,10 +1087,12 @@ ResultType Catalog::AlterTable(oid_t database_oid, oid_t table_oid, // Step 5: delete all the column(attribute) records in pg_attribute // and reinsert them using new schema(column offset needs to change // accordingly) - catalog::ColumnCatalog::GetInstance()->DeleteColumns(table_oid, txn); + auto pg_attributes = + catalog_map_[database_oid]->GetColumnCatalog(); + pg_attributes->DeleteColumns(table_oid, txn); oid_t column_offset = 0; for (auto new_column : new_schema->GetColumns()) { - catalog::ColumnCatalog::GetInstance()->InsertColumn( + pg_attributes->InsertColumn( table_oid, new_column.GetName(), column_offset, new_column.GetOffset(), new_column.GetType(), new_column.IsInlined(), new_column.GetConstraints(), pool_.get(), @@ -1143,20 +1143,10 @@ ResultType Catalog::AddColumn( * @return TransactionContext ResultType(SUCCESS or FAILURE) */ -ResultType Catalog::DropColumn(const std::string &database_name, - const std::string &table_name, - const std::vector &columns, - concurrency::TransactionContext *txn) { - try { - oid_t table_oid = Catalog::GetInstance() - ->GetTableObject(database_name, table_name, txn) - ->GetTableOid(); - for (std::string name : columns) { - catalog::ColumnCatalog::GetInstance()->DeleteColumn(table_oid, name, txn); - } - } catch (CatalogException &e) { - return ResultType::FAILURE; - } +ResultType Catalog::DropColumn(UNUSED_ATTRIBUTE const std::string &database_name, + UNUSED_ATTRIBUTE const std::string &table_name, + UNUSED_ATTRIBUTE const std::vector &columns, + UNUSED_ATTRIBUTE concurrency::TransactionContext *txn) { return ResultType::SUCCESS; } @@ -1172,6 +1162,7 @@ ResultType Catalog::RenameColumn(const std::string &database_name, const std::string &table_name, const std::string &old_name, const std::string &new_name, + const std::string &schema_name, concurrency::TransactionContext *txn) { if (txn == nullptr) { throw CatalogException("Change Column requires transaction."); @@ -1185,7 +1176,7 @@ ResultType Catalog::RenameColumn(const std::string &database_name, try { // Get table from the name - auto table = Catalog::GetInstance()->GetTableWithName(database_name, + auto table = Catalog::GetInstance()->GetTableWithName(database_name, schema_name, table_name, txn); auto schema = table->GetSchema(); @@ -1206,10 +1197,15 @@ ResultType Catalog::RenameColumn(const std::string &database_name, // Modify the pg_table oid_t table_oid = Catalog::GetInstance() - ->GetTableObject(database_name, table_name, txn) + ->GetTableObject(database_name, schema_name, table_name, txn) ->GetTableOid(); - bool res = catalog::ColumnCatalog::GetInstance()->RenameColumn( - table_oid, old_name, new_name, txn); + oid_t database_oid = Catalog::GetInstance() + ->GetTableObject(database_name, schema_name, table_name, txn) + ->GetDatabaseOid(); + auto pg_attributes = + catalog_map_[database_oid]->GetColumnCatalog(); + bool res = pg_attributes->RenameColumn( + database_oid, table_oid, old_name, new_name, txn); if (!res) { throw CatalogException("Change Column name failed."); } diff --git a/src/catalog/column_catalog.cpp b/src/catalog/column_catalog.cpp index 091d6045f8a..9a17313a948 100644 --- a/src/catalog/column_catalog.cpp +++ b/src/catalog/column_catalog.cpp @@ -256,7 +256,8 @@ ColumnCatalog::GetColumnObjects(oid_t table_oid, * @brief Rename the column name to a new name. * @ return whether the update succeed */ -bool ColumnCatalog::RenameColumn(oid_t table_oid, +bool ColumnCatalog::RenameColumn(oid_t database_oid, + oid_t table_oid, const std::string &column_name, const std::string &new_name, concurrency::TransactionContext *txn) { @@ -275,7 +276,7 @@ bool ColumnCatalog::RenameColumn(oid_t table_oid, oid_t index_offset = IndexId::PRIMARY_KEY; auto table_object = - TableCatalog::GetInstance()->GetTableObject(table_oid, txn); + Catalog::GetInstance()->GetTableObject(database_oid, table_oid, txn); table_object->EvictColumnObject(column_name); return UpdateWithIndexScan(update_columns, update_values, scan_values, diff --git a/src/executor/alter_executor.cpp b/src/executor/alter_executor.cpp index 1fa9f21fec0..4f0b0fc09b9 100644 --- a/src/executor/alter_executor.cpp +++ b/src/executor/alter_executor.cpp @@ -60,11 +60,12 @@ bool AlterExecutor::RenameColumn( peloton::concurrency::TransactionContext *txn) { auto database_name = node.GetDatabaseName(); auto table_name = node.GetTableName(); + auto schema_name = node.GetSchemaName(); auto new_column_name = node.GetNewName(); auto old_column_name = node.GetOldName(); ResultType result = catalog::Catalog::GetInstance()->RenameColumn( - database_name, table_name, old_column_name, new_column_name, txn); + database_name, table_name, old_column_name, new_column_name, schema_name, txn); txn->SetResult(result); if (txn->GetResult() == ResultType::SUCCESS) { @@ -82,14 +83,14 @@ bool AlterExecutor::AlterTable(const peloton::planner::AlterPlan &node, peloton::concurrency::TransactionContext *txn) { auto database_name = node.GetDatabaseName(); auto table_name = node.GetTableName(); - + auto schema_name = node.GetSchemaName(); auto table_catalog_obj = catalog::Catalog::GetInstance()->GetTableObject( - database_name, table_name, txn); + database_name, schema_name, table_name, txn); oid_t database_oid = table_catalog_obj->GetDatabaseOid(); oid_t table_oid = table_catalog_obj->GetTableOid(); auto old_table = catalog::Catalog::GetInstance()->GetTableWithName( - database_name, table_name, txn); + database_name, schema_name, table_name, txn); auto old_schema = old_table->GetSchema(); std::vector column_ids; @@ -160,7 +161,7 @@ bool AlterExecutor::AlterTable(const peloton::planner::AlterPlan &node, // Copy and replace table content to new schema in catalog ResultType result = catalog::Catalog::GetInstance()->AlterTable( - database_oid, table_oid, new_schema, txn); + database_oid, table_oid, schema_name, new_schema, txn); txn->SetResult(result); switch (txn->GetResult()) { diff --git a/src/include/catalog/catalog.h b/src/include/catalog/catalog.h index db3e7deffcb..2d89e35db01 100644 --- a/src/include/catalog/catalog.h +++ b/src/include/catalog/catalog.h @@ -188,7 +188,7 @@ class Catalog { //===--------------------------------------------------------------------===// // ALTER TABLE //===--------------------------------------------------------------------===// - ResultType AlterTable(oid_t database_oid, oid_t table_oid, + ResultType AlterTable(oid_t database_oid, oid_t table_oid, const std::string &schema_name, std::unique_ptr &new_schema, concurrency::TransactionContext *txn); @@ -206,6 +206,7 @@ class Catalog { const std::string &table_name, const std::string &old_name, const std::string &new_name, + const std::string &schema_name, concurrency::TransactionContext *txn); /* diff --git a/src/include/catalog/column_catalog.h b/src/include/catalog/column_catalog.h index 4634ab530c3..ffa5037c364 100644 --- a/src/include/catalog/column_catalog.h +++ b/src/include/catalog/column_catalog.h @@ -89,7 +89,7 @@ class ColumnCatalog : public AbstractCatalog { bool DeleteColumn(oid_t table_oid, const std::string &column_name, concurrency::TransactionContext *txn); bool DeleteColumns(oid_t table_oid, concurrency::TransactionContext *txn); - bool RenameColumn(oid_t table_oid, const std::string &column_name, + bool RenameColumn(oid_t database_oid, oid_t table_oid, const std::string &column_name, const std::string &new_name, concurrency::TransactionContext *txn); diff --git a/src/include/planner/alter_plan.h b/src/include/planner/alter_plan.h index 8abc4d24c36..0e0c5cfe6d4 100644 --- a/src/include/planner/alter_plan.h +++ b/src/include/planner/alter_plan.h @@ -100,6 +100,8 @@ class AlterPlan : public AbstractPlan { // return true if the alter plan is rename statement bool IsRename() const { return this->type == AlterType::RENAME; } + // return schema name + std::string GetSchemaName() const { return this->schema_name; } private: // Target Table storage::DataTable *target_table_ = nullptr; @@ -110,6 +112,8 @@ class AlterPlan : public AbstractPlan { // Database Name std::string database_name; + // Schema Name + std::string schema_name; // Schema delta, define the column txn want to add std::unique_ptr added_columns; // dropped_column, define the column you want to drop diff --git a/src/parser/postgresparser.cpp b/src/parser/postgresparser.cpp index a66b65b79b2..668b96b5701 100644 --- a/src/parser/postgresparser.cpp +++ b/src/parser/postgresparser.cpp @@ -1796,6 +1796,9 @@ parser::AlterTableStatement *PostgresParser::AlterTransform(Node *root) { result->table_info_.get()->database_name = strdup(relation->catalogname); } + if (relation->schemaname) { + result->table_info_.get()->schema_name = strdup(relation->schemaname); + } if (newRoot->subname) { result->oldName = strdup(newRoot->subname); } @@ -1823,6 +1826,9 @@ parser::AlterTableStatement *PostgresParser::AlterTransform(Node *root) { result->table_info_.get()->database_name = strdup(relation->catalogname); } + if (relation->schemaname) { + result->table_info_.get()->schema_name = strdup(relation->schemaname); + } for (auto cell = newRoot->cmds->head; cell != NULL; cell = cell->next) { auto cmd = reinterpret_cast(cell->data.ptr_value); diff --git a/src/planner/alter_plan.cpp b/src/planner/alter_plan.cpp index f37d8b43e50..ecebaa2a235 100644 --- a/src/planner/alter_plan.cpp +++ b/src/planner/alter_plan.cpp @@ -48,6 +48,7 @@ AlterPlan::AlterPlan(const std::string &database_name, AlterPlan::AlterPlan(parser::AlterTableStatement *parse_tree) { table_name = std::string(parse_tree->GetTableName()); database_name = std::string(parse_tree->GetDatabaseName()); + schema_name = std::string(parse_tree->GetSchemaName()); switch (parse_tree->type) { case parser::AlterTableStatement::AlterTableType::RENAME: { old_names_.emplace_back(std::string{parse_tree->oldName}); From 939df3513fce703aca97280b859256912f07f79a Mon Sep 17 00:00:00 2001 From: Shangjie Chen Date: Sun, 13 May 2018 17:03:42 +0000 Subject: [PATCH 55/58] change type quick fix --- src/catalog/column.cpp | 1 - src/planner/alter_plan.cpp | 19 +++++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/catalog/column.cpp b/src/catalog/column.cpp index 48efc98ddfa..50406bef954 100644 --- a/src/catalog/column.cpp +++ b/src/catalog/column.cpp @@ -34,7 +34,6 @@ void Column::SetInlined() { switch (column_type) { case type::TypeId::VARCHAR: case type::TypeId::VARBINARY: - is_inlined = false; break; // No change of inlined setting default: diff --git a/src/planner/alter_plan.cpp b/src/planner/alter_plan.cpp index ecebaa2a235..62d7dd4e5cc 100644 --- a/src/planner/alter_plan.cpp +++ b/src/planner/alter_plan.cpp @@ -30,8 +30,10 @@ AlterPlan::AlterPlan( database_name(database_name), dropped_columns(dropped_columns), type(a_type) { - this->added_columns = std::unique_ptr(new catalog::Schema(*added_columns)); - this->changed_type_columns = std::unique_ptr(new catalog::Schema(*changed_type_columns)); + this->added_columns = + std::unique_ptr(new catalog::Schema(*added_columns)); + this->changed_type_columns = std::unique_ptr( + new catalog::Schema(*changed_type_columns)); } AlterPlan::AlterPlan(const std::string &database_name, @@ -85,17 +87,17 @@ AlterPlan::AlterPlan(parser::AlterTableStatement *parse_tree) { } columns.emplace_back(column); } - added_columns = std::unique_ptr(new catalog::Schema(columns)); + added_columns = + std::unique_ptr(new catalog::Schema(columns)); columns.clear(); // deal with change column types for (size_t i = 0; i < (*parse_tree->changed_type_columns).size(); i++) { auto &tmp = (*parse_tree->changed_type_columns)[i]; - type::TypeId val = parser::ColumnDefinition::GetValueType(tmp.get()->type); - bool is_inline = (val == type::TypeId::VARCHAR) ? false : true; + type::TypeId val = + parser::ColumnDefinition::GetValueType(tmp.get()->type); auto column = catalog::Column( val, type::Type::GetTypeSize(val), - std::string((*parse_tree->changed_type_columns)[i].get()->name), - is_inline); + std::string((*parse_tree->changed_type_columns)[i].get()->name)); if ((*parse_tree->changed_type_columns)[i].get()->not_null) { catalog::Constraint constraint(ConstraintType::NOTNULL, "con_not_null"); @@ -103,7 +105,8 @@ AlterPlan::AlterPlan(parser::AlterTableStatement *parse_tree) { } columns.emplace_back(column); } - changed_type_columns = std::unique_ptr(new catalog::Schema(columns)); + changed_type_columns = + std::unique_ptr(new catalog::Schema(columns)); break; } default: From 20f5d272997f3d718b0638bcc71d0532e1a6d705 Mon Sep 17 00:00:00 2001 From: Dean Chen Date: Sun, 13 May 2018 19:55:26 -0400 Subject: [PATCH 56/58] add gc logic --- src/catalog/catalog.cpp | 4 ++-- src/gc/transaction_level_gc_manager.cpp | 5 +++++ src/include/concurrency/transaction_context.h | 15 +++++++++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/catalog/catalog.cpp b/src/catalog/catalog.cpp index 1bfc2702e54..64c952febbb 100644 --- a/src/catalog/catalog.cpp +++ b/src/catalog/catalog.cpp @@ -1099,8 +1099,8 @@ ResultType Catalog::AlterTable(oid_t database_oid, oid_t table_oid, const std::s txn); column_offset++; } - // TODO: Add gc logic - // txn->RecordDrop(database_oid, old_table->GetOid(), INVALID_OID); + // Garbage collection + txn->RecordDropTable(old_table); // Final step of physical change should be moved to commit time database->ReplaceTableWithOid(table_oid, new_table); diff --git a/src/gc/transaction_level_gc_manager.cpp b/src/gc/transaction_level_gc_manager.cpp index c2274a330e0..077c66dc258 100644 --- a/src/gc/transaction_level_gc_manager.cpp +++ b/src/gc/transaction_level_gc_manager.cpp @@ -278,6 +278,11 @@ void TransactionLevelGCManager::AddToRecycleMap( LOG_DEBUG("GCing index %u", index_oid); } + for (auto table : txn_ctx->GetDroppedTables()) { + LOG_TRACE("deleting table when txn commits"); + delete table; + } + delete txn_ctx; } diff --git a/src/include/concurrency/transaction_context.h b/src/include/concurrency/transaction_context.h index 892149b510e..55a1841f78f 100644 --- a/src/include/concurrency/transaction_context.h +++ b/src/include/concurrency/transaction_context.h @@ -33,6 +33,10 @@ class TriggerSet; class TriggerData; } // namespace trigger +namespace storage { +class DataTable; +} + namespace concurrency { //===--------------------------------------------------------------------===// @@ -173,6 +177,14 @@ class TransactionContext : public Printable { void RecordInsert(const ItemPointer &); + void RecordDropTable(storage::DataTable *table) { + dropped_tables.push_back(table); + } + + std::vector &GetDroppedTables() { + return dropped_tables; + } + /** * @brief Delete the record. * @@ -341,6 +353,9 @@ class TransactionContext : public Printable { IsolationLevelType isolation_level_; std::unique_ptr on_commit_triggers_; + + /** vector of dropped data tables **/ + std::vector dropped_tables; }; } // namespace concurrency From dbf6d7db6582b5a19ecba72a8e13c2113e840120 Mon Sep 17 00:00:00 2001 From: dingshilun Date: Mon, 14 May 2018 00:53:22 -0400 Subject: [PATCH 57/58] added alter benchmark, leave all workload of benchmark to be empty --- script/testing/junit/AlterBenchmarkTest.java | 211 +++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 script/testing/junit/AlterBenchmarkTest.java diff --git a/script/testing/junit/AlterBenchmarkTest.java b/script/testing/junit/AlterBenchmarkTest.java new file mode 100644 index 00000000000..38d8ce42203 --- /dev/null +++ b/script/testing/junit/AlterBenchmarkTest.java @@ -0,0 +1,211 @@ +//===----------------------------------------------------------------------===// +// +// Peloton +// +// AlterTableTest.java +// +// Identification: script/testing/junit/AlterBenchmarkTest.java +// +// Copyright (c) 2015-2018, Carnegie Mellon University Database Group +// +//===----------------------------------------------------------------------===// + +import java.sql.*; +import org.junit.*; +import org.junit.rules.ExpectedException; +import org.postgresql.util.PSQLException; +import static org.junit.Assert.assertEquals; + +/* + * Test case that compare performance under different workload + * Will need to contact with different local SQL + */ +public class AlterBenchmarkTest extends PLTestBase { + private Connection conn; + private Connection conn2; + + private static final String SQL_DROP_TABLE = + "DROP TABLE IF EXISTS tbl;"; + + private static final String SQL_CREATE_TABLE = + "CREATE TABLE tbl (" + + "id integer, " + + "year integer," + + "month integer);"; + + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + /** + * Initialize the database and table for testing + */ + private void InitDatabase() throws SQLException { + Statement stmt = conn.createStatement(); + stmt.execute(SQL_DROP_TABLE); + stmt.execute(SQL_CREATE_TABLE); + } + + public static Connection makePostgresConnection(String host, + int port, + String username, + String pass) throws SQLException { + String url = String.format("jdbc:postgresql://%s:%d/postgres", + host, port); + Connection conn = DriverManager.getConnection(url, username, pass); + return conn; + } + + /** + * Setup the connection to peloton or other DBMS + * @throws SQLException + */ + @Before + public void Setup() throws SQLException { + //connection to Postgres + //conn = makePostgresConnection("localhost", 5432, "dingshilun", ""); + conn = makeDefaultConnection(); + conn.setAutoCommit(true); + InitDatabase(); + } + + @After + public void Teardown() throws SQLException { + Statement stmt = conn.createStatement(); + stmt.execute(SQL_DROP_TABLE); + } + + /** + * Insert workload{} tuples into the table + * In order to test performancce variance under different workload + * @throws SQLException + */ + @Test + public void test_tuple_number_varies() throws SQLException { + int[] workload = {}; + for (int i = 0; i< workload.length;i++) { + // firstly use select * to make sure all tuples are in memory + // for postgres and other disk based DBMS + InitDatabase(); + NumVarInsertHelper(workload[i]); + String sql = "select * from tbl;"; + conn.createStatement().execute(sql); + + try { + Thread.sleep(1000); + } catch (Exception e) { + e.printStackTrace(); + } + + String alterSql1 = "alter table tbl add day integer;"; + long startTime1 = System.currentTimeMillis(); + conn.createStatement().execute(alterSql1); + long endTime1 = System.currentTimeMillis(); + + String alterSql2 = "alter table tbl drop month;"; + long startTime2 = System.currentTimeMillis(); + conn.createStatement().execute(alterSql2); + long endTime2 = System.currentTimeMillis(); + + String alterSql3 = "alter table tbl alter year type varchar"; + long startTime3 = System.currentTimeMillis(); + conn.createStatement().execute(alterSql3); + long endTime3 = System.currentTimeMillis(); + + String alterSql4 = "alter table tbl alter year type integer USING year::INTEGER"; + long startTime4 = System.currentTimeMillis(); + conn.createStatement().execute(alterSql4); + long endTime4 = System.currentTimeMillis(); + + System.out.println("Alter add column " + workload[i] + " tuples took: " + (endTime1 - startTime1) + " milliseconds"); + System.out.println("Alter drop column " + workload[i] + " tuples took: " + (endTime2 - startTime2) + " milliseconds"); + System.out.println("Alter change type from inline to not inline " + workload[i] + " tuples took: " + + (endTime3 - startTime3) + " milliseconds"); + System.out.println("Alter change type from not inline to inline " + workload[i] + " tuples took: " + + (endTime4 - startTime4) + " milliseconds"); + + } + } + + private void NumVarInsertHelper(int insertNum) throws SQLException { + String sql = "INSERT INTO tbl VALUES (?, ?, ?);"; + PreparedStatement pstmt = conn.prepareStatement(sql); + for (int i = 0; i < insertNum; i++) { + setValues(pstmt, new int [] {i, i+1, i+2}); + pstmt.addBatch(); + } + pstmt.executeBatch(); + } + + /** + * Insert 10000 tuple, and test performance under different + * length of the tuple + * @throws SQLException + */ + @Test + public void test_tuple_length_variance() throws SQLException { + int[] workload = {}; + int tupleNum = 10000; + String dropSQL = "DROP TABLE IF EXISTS tbl"; + String sql = ""; + conn.createStatement().execute(dropSQL); + for (int i = 0; i < workload.length; i++) { + sql = "CREATE TABLE tbl(id INTEGER PRIMARY KEY, " + + "payload1 VARCHAR(" + workload[i] + ")," + + "payload2 VARCHAR(" + workload[i] + ")," + + "payload3 INTEGER);"; + conn.createStatement().execute(sql); + LengthVarInsertHelper(tupleNum, workload[i]); + + try { + Thread.sleep(1000); + } catch (Exception e) { + e.printStackTrace(); + } + + long startTime1 = System.currentTimeMillis(); + conn.createStatement().execute("ALTER TABLE tbl add payload4 integer;"); + long endTime1 = System.currentTimeMillis(); + + long startTime2 = System.currentTimeMillis(); + conn.createStatement().execute("ALTER TABLE tbl drop payload1;"); + long endTime2 = System.currentTimeMillis(); + + long startTime3 = System.currentTimeMillis(); + conn.createStatement().execute("ALTER TABLE tbl alter payload3 type varchar;"); + long endTime3 = System.currentTimeMillis(); + + System.out.println("Alter add column " + workload[i] + " length took: " + (endTime1 - startTime1) + + " milliseconds"); + System.out.println("Alter drop column " + workload[i] + " length took: " + (endTime2 - startTime2) + + " milliseconds"); + System.out.println("Alter change type from not inline to inline " + workload[i] + " length took: " + + (endTime3 - startTime3) + " milliseconds"); + + conn.createStatement().execute(dropSQL); + } + } + + // will simply generate string with length and return + private String PayloadGenerate(int length) { + long seed = System.currentTimeMillis() % 26 + 'a'; + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < length; i++) { + builder.append((char)seed); + } + return builder.toString(); + } + + private void LengthVarInsertHelper(int insertNum, int varLen) throws SQLException { + String payload1 = PayloadGenerate(varLen); + String payload2 = PayloadGenerate(varLen); + for (int i = 0; i Date: Mon, 14 May 2018 08:51:11 -0400 Subject: [PATCH 58/58] cache-only set to true when get db object --- src/catalog/column_catalog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/catalog/column_catalog.cpp b/src/catalog/column_catalog.cpp index 9a17313a948..18b67c2daf2 100644 --- a/src/catalog/column_catalog.cpp +++ b/src/catalog/column_catalog.cpp @@ -249,7 +249,7 @@ ColumnCatalog::GetColumnObjects(oid_t table_oid, } } - return table_object->GetColumnObjects(); + return table_object->GetColumnObjects(true); } /*