Skip to content

Commit

Permalink
Merge branch 'main' into feature
Browse files Browse the repository at this point in the history
  • Loading branch information
Mytherin committed Oct 7, 2024
2 parents f152d4b + 222c0eb commit 42df770
Show file tree
Hide file tree
Showing 17 changed files with 111 additions and 10 deletions.
5 changes: 0 additions & 5 deletions extension/icu/third_party/icu/common/putil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,6 @@
// First, the platform type. Need this for U_PLATFORM.
#include "unicode/platform.h"

#if U_PLATFORM == U_PF_MINGW && defined __STRICT_ANSI__
/* tzset isn't defined in strict ANSI on MinGW. */
#undef __STRICT_ANSI__
#endif

/*
* Cygwin with GCC requires inclusion of time.h after the above disabling strict asci mode statement.
*/
Expand Down
9 changes: 8 additions & 1 deletion src/catalog/catalog_entry/duck_schema_entry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,13 @@ optional_ptr<CatalogEntry> DuckSchemaEntry::AddEntryInternal(CatalogTransaction
// first find the set for this entry
auto &set = GetCatalogSet(entry_type);
dependencies.AddDependency(*this);
if (on_conflict == OnCreateConflict::IGNORE_ON_CONFLICT) {
auto old_entry = set.GetEntry(transaction, entry_name);
if (old_entry) {
return nullptr;
}
}

if (on_conflict == OnCreateConflict::REPLACE_ON_CONFLICT) {
// CREATE OR REPLACE: first try to drop the entry
auto old_entry = set.GetEntry(transaction, entry_name);
Expand Down Expand Up @@ -315,7 +322,7 @@ void DuckSchemaEntry::DropEntry(ClientContext &context, DropInfo &info) {
throw InternalException("Failed to drop entry \"%s\" - entry could not be found", info.name);
}
if (existing_entry->type != info.type) {
throw CatalogException("Existing object %s is of type %s, trying to replace with type %s", info.name,
throw CatalogException("Existing object %s is of type %s, trying to drop type %s", info.name,
CatalogTypeToString(existing_entry->type), CatalogTypeToString(info.type));
}

Expand Down
3 changes: 3 additions & 0 deletions src/common/exception.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,9 @@ PermissionException::PermissionException(const string &msg) : Exception(Exceptio
SyntaxException::SyntaxException(const string &msg) : Exception(ExceptionType::SYNTAX, msg) {
}

ExecutorException::ExecutorException(const string &msg) : Exception(ExceptionType::EXECUTOR, msg) {
}

ConstraintException::ConstraintException(const string &msg) : Exception(ExceptionType::CONSTRAINT, msg) {
}

Expand Down
10 changes: 10 additions & 0 deletions src/include/duckdb/common/exception.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,16 @@ class InvalidInputException : public Exception {
}
};

class ExecutorException : public Exception {
public:
DUCKDB_API explicit ExecutorException(const string &msg);

template <typename... ARGS>
explicit ExecutorException(const string &msg, ARGS... params)
: ExecutorException(ConstructMessage(msg, params...)) {
}
};

class InvalidConfigurationException : public Exception {
public:
DUCKDB_API explicit InvalidConfigurationException(const string &msg);
Expand Down
3 changes: 2 additions & 1 deletion src/include/duckdb/common/windows_undefs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
//
//===----------------------------------------------------------------------===//

#pragma once
// Do not add a header inclusion guard to this file. Otherwise these Win32 macros
// may get defined and stomp on DuckDB symbols

#ifdef WIN32

Expand Down
2 changes: 1 addition & 1 deletion src/include/duckdb/function/table_function.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ class TableFunction : public SimpleNamedParameterFunction { // NOLINT: work-arou
//! The returned FunctionData object should be constant and should not be changed during execution.
table_function_bind_t bind;
//! (Optional) Bind replace function
//! This function is called before the regular bind function. It allows returning a TableRef will be used to
//! This function is called before the regular bind function. It allows returning a TableRef that will be used to
//! to generate a logical plan that replaces the LogicalGet of a regularly bound TableFunction. The BindReplace can
//! also return a nullptr to indicate a regular bind needs to be performed instead.
table_function_bind_replace_t bind_replace;
Expand Down
9 changes: 9 additions & 0 deletions src/parallel/task_scheduler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -335,8 +335,13 @@ idx_t TaskScheduler::GetEstimatedCPUId() {
#elif defined(_GNU_SOURCE)
auto cpu = sched_getcpu();
if (cpu < 0) {
#ifndef DUCKDB_NO_THREADS
// fallback to thread id
return (idx_t)std::hash<std::thread::id>()(std::this_thread::get_id());
#else

return 0;
#endif
}
return (idx_t)cpu;
#elif defined(__aarch64__) && defined(__APPLE__)
Expand All @@ -345,8 +350,12 @@ idx_t TaskScheduler::GetEstimatedCPUId() {
asm volatile("mrs %x0, tpidrro_el0" : "=r"(c)::"memory");
return (idx_t)(c & (1 << 3) - 1);
#else
#ifndef DUCKDB_NO_THREADS
// fallback to thread id
return (idx_t)std::hash<std::thread::id>()(std::this_thread::get_id());
#else
return 0;
#endif
#endif
#endif
}
Expand Down
5 changes: 4 additions & 1 deletion src/planner/binder/statement/bind_create_table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,10 @@ void Binder::BindGeneratedColumns(BoundCreateTableInfo &info) {

auto bound_expression = expr_binder.Bind(expression);
D_ASSERT(bound_expression);
D_ASSERT(!bound_expression->HasSubquery());
if (bound_expression->HasSubquery()) {
throw BinderException("Failed to bind generated column '%s' because the expression contains a subquery",
col.Name());
}
if (col.Type().id() == LogicalTypeId::ANY) {
// Do this before changing the type, so we know it's the first time the type is set
col.ChangeGeneratedExpressionType(bound_expression->return_type);
Expand Down
23 changes: 23 additions & 0 deletions test/catalog/test_catalog_version.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,29 @@ TEST_CASE("Test catalog versioning", "[catalog]") {
REQUIRE(catalog.GetCatalogVersion(*con1.context) == 2);
});

// The following should not increment the version
REQUIRE_NO_FAIL(con1.Query("CREATE TABLE IF NOT EXISTS foo3 as SELECT 42"));

con1.context->RunFunctionInTransaction([&]() {
auto &catalog = Catalog::GetCatalog(*con1.context, "");
REQUIRE(catalog.GetCatalogVersion(*con1.context) == 2);
});

REQUIRE_NO_FAIL(con1.Query("CREATE SCHEMA IF NOT EXISTS my_schema"));

con1.context->RunFunctionInTransaction([&]() {
auto &catalog = Catalog::GetCatalog(*con1.context, "");
REQUIRE(catalog.GetCatalogVersion(*con1.context) == 3);
});

// The following should not increment the version
REQUIRE_NO_FAIL(con1.Query("CREATE SCHEMA IF NOT EXISTS my_schema"));

con1.context->RunFunctionInTransaction([&]() {
auto &catalog = Catalog::GetCatalog(*con1.context, "");
REQUIRE(catalog.GetCatalogVersion(*con1.context) == 3);
});

// check catalog version of system catalog
con1.context->RunFunctionInTransaction([&]() {
auto &catalog = Catalog::GetCatalog(*con1.context, "system");
Expand Down
9 changes: 9 additions & 0 deletions test/sql/catalog/test_if_not_exists.test
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@ CREATE TABLE IF NOT EXISTS integers2 AS SELECT 42
statement ok
CREATE TABLE IF NOT EXISTS integers2 AS SELECT 42

# similar to Postgres, treat as NOOP if the entry exists but the type is different
statement ok
CREATE VIEW IF NOT EXISTS integers2 AS SELECT 42

statement error
DROP VIEW IF EXISTS integers
----
Catalog Error: Existing object integers is of type Table, trying to drop type View

statement ok
DROP TABLE IF EXISTS integers

Expand Down
8 changes: 8 additions & 0 deletions test/sql/create/create_or_replace.test
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ CREATE TABLE integers(i INTEGER)
statement ok
CREATE OR REPLACE TABLE integers(i INTEGER, j INTEGER)

statement ok
CREATE VIEW integers2 AS SELECT 42

statement error
CREATE OR REPLACE TABLE integers2(i INTEGER)
----
Catalog Error: integers2 is not an table

statement ok
CREATE TABLE IF NOT EXISTS integers(i INTEGER)

Expand Down
17 changes: 17 additions & 0 deletions test/sql/generated_columns/virtual/create_table.test
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,23 @@ CREATE TABLE unit (
amount_sold INTEGER,
);
----
Expression of generated column "total_profit" contains a subquery, which isn't allowed

statement ok
CREATE MACRO my_macro() AS (
(select 42)
);

# Expression contains a subquery - through a macro
statement error
CREATE TABLE unit (
total_profit INTEGER GENERATED ALWAYS AS(my_macro()) VIRTUAL,
word VARCHAR,
price INTEGER,
amount_sold INTEGER,
);
----
Failed to bind generated column 'total_profit' because the expression contains a subquery

# Duplicate column definition
statement error
Expand Down
2 changes: 1 addition & 1 deletion test/sql/types/union/union_cast.test
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ i32 1 NULL NULL
str NULL two NULL
str NULL three NULL

# Allow explict casts
# Allow explicit casts
statement ok
CREATE TABLE tbl3 (u UNION(i INT));

Expand Down
2 changes: 2 additions & 0 deletions tools/juliapkg/src/database.jl
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,9 @@ DBInterface.connect(db::DB) = Connection(db.handle)
DBInterface.close!(db::DB) = close_database(db)
DBInterface.close!(con::Connection) = _close_connection(con)
Base.close(db::DB) = close_database(db)
Base.close(con::Connection) = _close_connection(con)
Base.isopen(db::DB) = db.handle.handle != C_NULL
Base.isopen(con::Connection) = con.handle != C_NULL

Base.show(io::IO, db::DuckDB.DB) = print(io, string("DuckDB.DB(", "\"$(db.handle.file)\"", ")"))
Base.show(io::IO, con::DuckDB.Connection) = print(io, string("DuckDB.Connection(", "\"$(con.db.file)\"", ")"))
5 changes: 5 additions & 0 deletions tools/juliapkg/test/test_connection.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
DBInterface.close!(con)
DBInterface.close!(con)
@test 1 == 1

con = DBInterface.connect(DuckDB.DB, ":memory:")
@test isopen(con)
close(con)
@test !isopen(con)
end

@testset "Test opening a bogus directory" begin
Expand Down
3 changes: 3 additions & 0 deletions tools/pythonpkg/src/typing/pytype.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,9 @@ static LogicalType FromGenericAlias(const py::object &obj) {
static LogicalType FromDictionary(const py::object &obj) {
auto dict = py::reinterpret_steal<py::dict>(obj);
child_list_t<LogicalType> children;
if (dict.size() == 0) {
throw InvalidInputException("Could not convert empty dictionary to a duckdb STRUCT type");
}
children.reserve(dict.size());
for (auto &item : dict) {
auto &name_p = item.first;
Expand Down
6 changes: 6 additions & 0 deletions tools/pythonpkg/tests/fast/test_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,12 @@ def test_struct_type(self):
type = duckdb.struct_type([BIGINT, BOOLEAN])
assert str(type) == 'STRUCT(v1 BIGINT, v2 BOOLEAN)'

def test_incomplete_struct_type(self):
with pytest.raises(
duckdb.InvalidInputException, match='Could not convert empty dictionary to a duckdb STRUCT type'
):
type = duckdb.typing.DuckDBPyType(dict())

def test_map_type(self):
type = duckdb.map_type(duckdb.sqltype("BIGINT"), duckdb.sqltype("DECIMAL(10, 2)"))
assert str(type) == 'MAP(BIGINT, DECIMAL(10,2))'
Expand Down

0 comments on commit 42df770

Please sign in to comment.