Skip to content

Commit

Permalink
Indexes for temporary tables
Browse files Browse the repository at this point in the history
  • Loading branch information
pdet committed Jan 23, 2020
1 parent a50df3b commit 00ed0b3
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 12 deletions.
5 changes: 4 additions & 1 deletion src/catalog/catalog_entry/schema_catalog_entry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,10 @@ void SchemaCatalogEntry::DropSequence(Transaction &transaction, DropInfo *info)

bool SchemaCatalogEntry::CreateIndex(Transaction &transaction, CreateIndexInfo *info) {
auto index = make_unique_base<CatalogEntry, IndexCatalogEntry>(catalog, this, info);
unordered_set<CatalogEntry *> dependencies{this};
unordered_set<CatalogEntry *> dependencies;
if (name != TEMP_SCHEMA) {
dependencies.insert(this);
}
if (!indexes.CreateEntry(transaction, info->index_name, move(index), dependencies)) {
if (!info->if_not_exists) {
throw CatalogException("Index with name \"%s\" already exists!", info->index_name.c_str());
Expand Down
2 changes: 1 addition & 1 deletion src/catalog/dependency_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ void DependencyManager::AddObject(Transaction &transaction, CatalogEntry *object
throw TransactionException("Catalog write-write conflict on create with \"%s\"", object->name.c_str());
}
}
// add the object to the dependents_map of each object that it depents on
// add the object to the dependents_map of each object that it depends on
for (auto &dependency : dependencies) {
dependents_map[dependency].insert(object);
}
Expand Down
2 changes: 1 addition & 1 deletion src/execution/operator/schema/physical_create_index.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ using namespace duckdb;
using namespace std;

void PhysicalCreateIndex::CreateARTIndex() {
auto art = make_unique<ART>(*table.storage, column_ids, move(unbound_expressions));
auto art = make_unique<ART>(*table.storage, column_ids, move(unbound_expressions), info->unique);

table.storage->AddIndex(move(art), expressions);
}
Expand Down
5 changes: 0 additions & 5 deletions src/planner/binder/statement/bind_create_index.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,6 @@ unique_ptr<BoundSQLStatement> Binder::Bind(CreateIndexStatement &stmt) {
if (result->table->type != TableReferenceType::BASE_TABLE) {
throw BinderException("Cannot create index on a view!");
}
auto table_ref = (BoundBaseTableRef *)result->table.get();
if (table_ref->table->temporary) {
throw BinderException("Cannot create index on a temporary table!");
}
// visit the expressions
IndexBinder binder(*this, context);
for (auto &expr : stmt.expressions) {
result->expressions.push_back(binder.Bind(expr));
Expand Down
2 changes: 1 addition & 1 deletion src/storage/local_storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ void LocalStorage::RevertCommit(LocalStorage::CommitState &commit_state) {
auto storage = table_storage[table].get();
auto &append_state = *entry.second;

if (table->indexes.size() > 0) {
if (table->indexes.size() > 0 && !table->schema.compare("\"temp\"")) {
row_t current_row = append_state.row_start;
// remove the data from the indexes, if there are any indexes
ScanTableStorage(table, storage, [&](DataChunk &chunk) -> bool {
Expand Down
3 changes: 0 additions & 3 deletions test/sql/catalog/test_table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,6 @@ TEST_CASE("Test temporary table creation", "[catalog]") {

REQUIRE_FAIL(con.Query("CREATE TABLE temp.integersy(i INTEGER)"));

// no indexes on temp tables
REQUIRE_FAIL(con.Query("CREATE INDEX i_index ON integers(i)"));

REQUIRE_FAIL(con.Query("CREATE SCHEMA temp"));

REQUIRE_FAIL(con.Query("DROP TABLE main.integersx"));
Expand Down
43 changes: 43 additions & 0 deletions test/sql/constraints/test_unique.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,49 @@ TEST_CASE("Single UNIQUE constraint", "[constraints]") {
REQUIRE_NO_FAIL(con.Query("DROP TABLE integers"));
}

TEST_CASE("UNIQUE constraint on temporary tables", "[constraints]") {
unique_ptr<QueryResult> result;
DuckDB db(nullptr);
Connection con(db);

REQUIRE_NO_FAIL(con.Query("CREATE TEMPORARY TABLE integers(i INTEGER, j INTEGER)"));
REQUIRE_NO_FAIL(con.Query("CREATE UNIQUE INDEX uidx ON integers (i) "));

// insert unique values
REQUIRE_NO_FAIL(con.Query("INSERT INTO integers VALUES (3, 4), (2, 5)"));

result = con.Query("SELECT * FROM integers");
REQUIRE(CHECK_COLUMN(result, 0, {3, 2}));
REQUIRE(CHECK_COLUMN(result, 1, {4, 5}));

// insert a duplicate value as part of a chain of values, this should fail
REQUIRE_FAIL(con.Query("INSERT INTO integers VALUES (6, 6), (3, 4);"));

// unique constraints accept NULL values, unlike PRIMARY KEY columns
REQUIRE_NO_FAIL(con.Query("INSERT INTO integers VALUES (NULL, 6), (NULL, 7)"));

// but if we try to replace them like this it's going to fail
REQUIRE_FAIL(con.Query("UPDATE integers SET i=77 WHERE i IS NULL"));

result = con.Query("SELECT * FROM integers ORDER BY i, j");
REQUIRE(CHECK_COLUMN(result, 0, {Value(), Value(), 2, 3}));
REQUIRE(CHECK_COLUMN(result, 1, {6, 7, 5, 4}));

// we can replace them like this though
REQUIRE_NO_FAIL(con.Query("UPDATE integers SET i=77 WHERE i IS NULL AND j=6"));

result = con.Query("SELECT * FROM integers ORDER BY i, j");
REQUIRE(CHECK_COLUMN(result, 0, {Value(), 2, 3, 77}));
REQUIRE(CHECK_COLUMN(result, 1, {7, 5, 4, 6}));

for (index_t i = 0; i < 10; i++) {
REQUIRE_NO_FAIL(con.Query("INSERT INTO integers VALUES (NULL, 6), (NULL, 7)"));
}
REQUIRE_FAIL(con.Query("INSERT INTO integers VALUES (3, 4)"));

REQUIRE_NO_FAIL(con.Query("DROP TABLE integers"));
}

TEST_CASE("Multiple constraints", "[constraints]") {
unique_ptr<QueryResult> result;
DuckDB db(nullptr);
Expand Down

0 comments on commit 00ed0b3

Please sign in to comment.