Skip to content

Commit

Permalink
Add TRUNCATE TABLE <tablename> syntax
Browse files Browse the repository at this point in the history
Recreate dictionary structure after truncate

Add test
  • Loading branch information
dwayneberry authored and asuhan committed Jul 25, 2017
1 parent 7ff7ea5 commit 45f8069
Show file tree
Hide file tree
Showing 8 changed files with 122 additions and 2 deletions.
73 changes: 73 additions & 0 deletions Catalog/Catalog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1123,6 +1123,79 @@ void Catalog::createShardedTable(TableDescriptor& td,
}
}

void Catalog::truncateTable(const TableDescriptor* td) {
const auto physicalTableIt = logicalToPhysicalTableMapById_.find(td->tableId);
if (physicalTableIt != logicalToPhysicalTableMapById_.end()) {
// truncate all corresponding physical tables if this is a logical table
const auto physicalTables = physicalTableIt->second;
CHECK(!physicalTables.empty());
for (size_t i = 0; i < physicalTables.size(); i++) {
int32_t physical_tb_id = physicalTables[i];
const TableDescriptor* phys_td = getMetadataForTable(physical_tb_id);
CHECK(phys_td);
doTruncateTable(phys_td);
}
}
doTruncateTable(td);
}

void Catalog::doTruncateTable(const TableDescriptor* td) {
const int tableId = td->tableId;

// must destroy fragmenter before deleteChunks is called.
if (td->fragmenter != nullptr) {
auto tableDescIt = tableDescriptorMapById_.find(tableId);
delete td->fragmenter;
tableDescIt->second->fragmenter = nullptr; // get around const-ness
}
ChunkKey chunkKeyPrefix = {currentDB_.dbId, tableId};
// assuming deleteChunksWithPrefix is atomic
dataMgr_->deleteChunksWithPrefix(chunkKeyPrefix);
// MAT TODO fix this
// NOTE This is unsafe , if there are updates occuring at same time
dataMgr_->checkpoint(currentDB_.dbId, tableId);
dataMgr_->removeTableRelatedDS(currentDB_.dbId, tableId);

std::unique_ptr<StringDictionaryClient> client;
if (g_aggregator) {
CHECK(!string_dict_hosts_.empty());
client.reset(new StringDictionaryClient(string_dict_hosts_.front(), -1, true));
}
// clean up any dictionaries
// delete all column descriptors for the table
for (int i = 1; i <= td->nColumns; i++) {
ColumnIdKey cidKey(tableId, i);
ColumnDescriptorMapById::iterator colDescIt = columnDescriptorMapById_.find(cidKey);
ColumnDescriptor* cd = colDescIt->second;
const int dictId = cd->columnType.get_comp_param();
// Dummy dictionaries created for a shard of a logical table have the id set to zero.
if (cd->columnType.get_compression() == kENCODING_DICT && dictId) {
const auto dictIt = dictDescriptorMapById_.find(dictId);
CHECK(dictIt != dictDescriptorMapById_.end());
const auto& dd = dictIt->second;
CHECK_GE(dd->refcount, 1);
// if this is the only table using this dict reset the dict
if (dd->refcount == 1) {
boost::filesystem::remove_all(dd->dictFolderPath);
if (client) {
client->drop(dd->dictId, currentDB_.dbId);
}
boost::filesystem::create_directory(dd->dictFolderPath);
}

DictDescriptor* new_dd = new DictDescriptor(
dd->dictId, dd->dictName, dd->dictNBits, dd->dictIsShared, dd->refcount, dd->dictFolderPath);
dictDescriptorMapById_.erase(dictIt);
// now create new Dict -- need to figure out what to do here for temp tables
if (client) {
client->create(new_dd->dictId, currentDB_.dbId);
}
dictDescriptorMapById_[dictId].reset(new_dd);
getMetadataForDict(dictId);
}
}
}

void Catalog::dropTable(const TableDescriptor* td) {
const auto physicalTableIt = logicalToPhysicalTableMapById_.find(td->tableId);
if (physicalTableIt != logicalToPhysicalTableMapById_.end()) {
Expand Down
2 changes: 2 additions & 0 deletions Catalog/Catalog.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ class Catalog {
void createFrontendView(FrontendViewDescriptor& vd);
std::string createLink(LinkDescriptor& ld, size_t min_length);
void dropTable(const TableDescriptor* td);
void truncateTable(const TableDescriptor* td);
void renameTable(const TableDescriptor* td, const std::string& newTableName);
void renameColumn(const TableDescriptor* td, const ColumnDescriptor* cd, const std::string& newColumnName);

Expand Down Expand Up @@ -288,6 +289,7 @@ class Catalog {
void addLinkToMap(LinkDescriptor& ld);
void removeTableFromMap(const std::string& tableName, int tableId);
void doDropTable(const TableDescriptor* td);
void doTruncateTable(const TableDescriptor* td);
void renamePhysicalTable(const TableDescriptor* td, const std::string& newTableName);
void instantiateFragmenter(TableDescriptor* td) const;
void getAllColumnMetadataForTable(const TableDescriptor* td,
Expand Down
11 changes: 11 additions & 0 deletions Parser/ParserNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2110,6 +2110,17 @@ void DropTableStmt::execute(const Catalog_Namespace::SessionInfo& session) {
catalog.dropTable(td);
}

void TruncateTableStmt::execute(const Catalog_Namespace::SessionInfo& session) {
auto& catalog = session.get_catalog();
const TableDescriptor* td = catalog.getMetadataForTable(*table);
if (td == nullptr) {
throw std::runtime_error("Table " + *table + " does not exist.");
}
if (td->isView)
throw std::runtime_error(*table + " is a view. Cannot Truncate.");
catalog.truncateTable(td);
}

void RenameTableStmt::execute(const Catalog_Namespace::SessionInfo& session) {
auto& catalog = session.get_catalog();
const TableDescriptor* td = catalog.getMetadataForTable(*table);
Expand Down
14 changes: 14 additions & 0 deletions Parser/ParserNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -938,6 +938,20 @@ class DropTableStmt : public DDLStmt {
bool if_exists;
};

/*
* @type TruncateTableStmt
* @brief TRUNCATE TABLE statement
*/
class TruncateTableStmt : public DDLStmt {
public:
TruncateTableStmt(std::string* tab) : table(tab) {}
const std::string* get_table() const { return table.get(); }
virtual void execute(const Catalog_Namespace::SessionInfo& session);

private:
std::unique_ptr<std::string> table;
};

class RenameTableStmt : public DDLStmt {
public:
RenameTableStmt(std::string* tab, std::string* new_tab_name) : table(tab), new_table_name(new_tab_name) {}
Expand Down
2 changes: 1 addition & 1 deletion Parser/ParserWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

using namespace std;

const std::vector<std::string> ParserWrapper::ddl_cmd = {"ALTER", "COPY", "GRANT", "CREATE", "DROP"};
const std::vector<std::string> ParserWrapper::ddl_cmd = {"ALTER", "COPY", "GRANT", "CREATE", "DROP", "TRUNCATE"};

const std::vector<std::string> ParserWrapper::update_dml_cmd = {
"INSERT",
Expand Down
9 changes: 8 additions & 1 deletion Parser/parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ using namespace Parser;
%token IS LANGUAGE LAST LENGTH LIKE LIMIT MOD NOW NULLX NUMERIC OF OFFSET ON OPEN OPTION
%token ORDER PARAMETER PRECISION PRIMARY PRIVILEGES PROCEDURE
%token PUBLIC REAL REFERENCES RENAME ROLLBACK SCHEMA SELECT SET SHARD SHARED SHOW
%token SMALLINT SOME TABLE TEXT THEN TIME TIMESTAMP TO UNION
%token SMALLINT SOME TABLE TEXT THEN TIME TIMESTAMP TO TRUNCATE UNION
%token UNIQUE UPDATE USER VALUES VIEW WHEN WHENEVER WHERE WITH WORK

%start sql_list
Expand All @@ -127,6 +127,7 @@ sql: /* schema { $<nodeval>$ = $<nodeval>1; } */
/* | prvililege_def { $<nodeval>$ = $<nodeval>1; } */
| drop_view_statement { $<nodeval>$ = $<nodeval>1; }
| drop_table_statement { $<nodeval>$ = $<nodeval>1; }
| truncate_table_statement { $<nodeval>$ = $<nodeval>1; }
| rename_table_statement { $<nodeval>$ = $<nodeval>1; }
| rename_column_statement { $<nodeval>$ = $<nodeval>1; }
| copy_table_statement { $<nodeval>$ = $<nodeval>1; }
Expand Down Expand Up @@ -238,6 +239,12 @@ drop_table_statement:
$<nodeval>$ = new DropTableStmt($<stringval>4, $<boolval>3);
}
;
truncate_table_statement:
TRUNCATE TABLE table
{
$<nodeval>$ = new TruncateTableStmt($<stringval>3);
}
;
rename_table_statement:
ALTER TABLE table RENAME TO table
{
Expand Down
1 change: 1 addition & 0 deletions Parser/scanner.l
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ THEN TOK(THEN)
TIME TOK(TIME)
TIMESTAMP TOK(TIMESTAMP)
TO TOK(TO)
TRUNCATE TOK(TRUNCATE)
UNION TOK(UNION)
UNIQUE TOK(UNIQUE)
UPDATE TOK(UPDATE)
Expand Down
12 changes: 12 additions & 0 deletions Tests/ExecuteTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3323,6 +3323,18 @@ TEST(Select, WatchdogTest) {
}
}

TEST(Truncate, Count) {
run_ddl_statement("create table trunc_test (i1 integer, t1 text);");
run_multiple_agg("insert into trunc_test values(1, '1');", ExecutorDeviceType::CPU);
run_multiple_agg("insert into trunc_test values(2, '2');", ExecutorDeviceType::CPU);
ASSERT_EQ(int64_t(3), v<int64_t>(run_simple_agg("SELECT SUM(i1) FROM trunc_test;", ExecutorDeviceType::CPU)));
run_ddl_statement("truncate table trunc_test;");
run_multiple_agg("insert into trunc_test values(3, '3');", ExecutorDeviceType::CPU);
run_multiple_agg("insert into trunc_test values(4, '4');", ExecutorDeviceType::CPU);
ASSERT_EQ(int64_t(7), v<int64_t>(run_simple_agg("SELECT SUM(i1) FROM trunc_test;", ExecutorDeviceType::CPU)));
run_ddl_statement("drop table trunc_test;");
}

namespace {

struct ShardInfo {
Expand Down

0 comments on commit 45f8069

Please sign in to comment.