-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Description
The issues
This is the follow-up to #4067. I will keep updating this issue with new issues from fuzzers I find.
If exists flag ignored for alter statements (now fixed)
ALTER TABLE IF EXISTS t0 RENAME TO t1;
ALTER SEQUENCE IF EXISTS seq OWNED BY x;
Error: Catalog Error: Table with name t0 does not exist!
The error shouldn't be thrown.
If not exists flag ignored for alter table add column statement (now fixed)
CREATE TABLE t0 (c0 INT);
ALTER TABLE t0 ADD COLUMN IF NOT EXISTS c0 INT;
Error: Catalog Error: Column with name c0 already exists!
The error shouldn't be thrown.
Generate series with NULL value (now fixed)
SELECT c0 FROM generate_series(NULL) t3(c0);
SELECT c0 FROM range(NULL) t3(c0);
Error: INTERNAL Error: Calling GetValue on a value that is NULL
Here maybe a non-internal error should be thrown. For scalar functions, NULL values are already handled separately. For table UDF ones, maybe this is missing, ie an optional check for any NULL input throw error.
Integer overflow while flattening dependent join (now fixed)
SELECT (SELECT c0 OFFSET 1) FROM (VALUES(1)) c0;
src/planner/subquery/flatten_dependent_join.cpp:397:90: runtime error: signed integer overflow: 1 + 9223372036854775807 cannot be represented in type 'long'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior src/planner/subquery/flatten_dependent_join.cpp:397:90 in
The query should output a single NULL value.
NOT SIMILAR TO at FILTER clause (now fixed)
DuckDB db(nullptr);
Connection con(db);
con.EnableQueryVerification();
con.SendQuery("SELECT count(*) FILTER (WHERE 0 NOT SIMILAR TO '2' = FALSE);");
src/main/client_context.cpp:931: std::string duckdb::ClientContext::VerifyQuery(duckdb::ClientContextLock &, const std::string &, unique_ptrduckdb::SQLStatement): Assertion `orig_expr_list[i]->Equals(verify_statements[v_idx].select_list[i].get())' failed
I can only reproduce it via the C-API. I think the internal ToString call doesn't match the parsed query.
The query should output a single 0 value.
Escaped trim function call? (now fixed)
DuckDB db(nullptr);
Connection con(db);
con.EnableQueryVerification();
con.SendQuery("SELECT \"trim\"(1);");
src/main/client_context.cpp:931: std::string duckdb::ClientContext::VerifyQuery(duckdb::ClientContextLock &, const std::string &, unique_ptrduckdb::SQLStatement): Assertion `orig_expr_list[i]->Equals(verify_statements[v_idx].select_list[i].get())' failed
Same issue as the previous one?
The query should output a single 1 value.
Partition by UTF-8 string (now fixed)
Because the query uses non-printable UTF-8 characters, I upload it in a zip file:
window_issue.zip
/usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/stl_vector.h:1046:9: runtime error: reference binding to null pointer of type 'duckdb::RowDataBlock'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/stl_vector.h:1046:9 in
The query should output 11 11 values,
Floating-point validation (now fixed)
DuckDB db(nullptr);
Connection con(db);
con.EnableQueryVerification();
con.SendQuery("SELECT 0E6");
con.SendQuery("SELECT .0E7382504816742;");
src/main/client_context.cpp:931: std::string duckdb::ClientContext::VerifyQuery(duckdb::ClientContextLock &, const std::string &, unique_ptrduckdb::SQLStatement): Assertion `orig_expr_list[i]->Equals(verify_statements[v_idx].select_list[i].get())' failed
ToString method not matching again?
IS DISTINCT FROM validation (now fixed)
DuckDB db(nullptr);
Connection con(db);
con.EnableQueryVerification();
con.SendQuery("SELECT (0 IS DISTINCT FROM 2) = 0;");
con.SendQuery("SELECT CASE 8 WHEN(0 IS DISTINCT FROM 0) THEN 2 END;");
src/main/client_context.cpp:931: std::string duckdb::ClientContext::VerifyQuery(duckdb::ClientContextLock &, const std::string &, unique_ptrduckdb::SQLStatement): Assertion `orig_expr_list[i]->Equals(verify_statements[v_idx].select_list[i].get())' failed
Another validation issue. A single false and NULL value is expected.
UndefinedBehaviorSanitizer on downcast from correlated subquery
CREATE TABLE t0(c0 INT);
SELECT count(*) OVER() = ANY(SELECT * FROM t0 t1 WHERE(c0 = t0.c0)) FROM t0;
src/optimizer/deliminator.cpp:38:19: runtime error: downcast of address 0x608000009120 which does not point to an object of type 'duckdb::BoundColumnRefExpression'
0x608000009120: note: object is of type 'duckdb::BoundCastExpression'
00 00 00 00 50 d0 ea 09 20 56 00 00 0c 1b be be be be be be 40 91 00 00 80 60 00 00 00 00 00 00
^~~~~~~~~~~~~~~~~~~~~~~
vptr for 'duckdb::BoundCastExpression'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior src/optimizer/deliminator.cpp:38:19 in
An empty result set is expected.
Assertion error on correlated cube (now fixed)
CREATE TABLE t0(c0 INT);
INSERT INTO t0 VALUES(NULL);
SELECT (SELECT count(*) OVER() GROUP BY CUBE(c0)) FROM t0;
duckdb: src/execution/expression_executor.cpp:146: void duckdb::ExpressionExecutor::Execute(const duckdb::Expression &, duckdb::ExpressionState *, const duckdb::SelectionVector *, duckdb::idx_t, duckdb::Vector &): Assertion `FlatVector::Validity(result).CheckAllValid(count)' failed.
Because the cube returns more than one row, here the result may not be deterministic.
Limit 0% on ANY subquery (now fixed)
SELECT 1 WHERE 1 < ANY(SELECT 2 LIMIT 0%);
The query outputs 1, but because of LIMIT 0% I expect the ANY to be empty, then the predicate output should be empty.
Correlated offset subquery
SELECT (SELECT 1 OFFSET c0) FROM (VALUES(1)) c0;
src/execution/column_binding_resolver.cpp:74: virtual unique_ptrduckdb::Expression duckdb::ColumnBindingResolver::VisitReplace(duckdb::BoundColumnRefExpression &, unique_ptrduckdb::Expression *): Assertion `expr.depth == 0' failed.
The query should output NULL.
Missing error message at subquery
SELECT (WITH t2 AS (SELECT 3 WHERE count(*) FILTER (1)) SELECT 0 FROM t2);
src/execution/expression_executor.cpp:196: duckdb::idx_t duckdb::ExpressionExecutor::Select(const duckdb::Expression &, duckdb::ExpressionState *, const duckdb::SelectionVector *, duckdb::idx_t, duckdb::SelectionVector *, duckdb::SelectionVector *): Assertion `expr.return_type.id() == LogicalTypeId::BOOLEAN' failed.
This one is tricky, count(*) should bind in the inner query, then the error about aggregates in the WHERE clause should be thrown.
NaN as LIMIT % (now fixed)
SELECT 1 LIMIT CAST('NaN' AS REAL)%;
/src/execution/operator/helper/physical_limit_percent.cpp:121:18: runtime error: nan is outside the range of representable values of type 'unsigned long'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior src/execution/operator/helper/physical_limit_percent.cpp:121:18
A missing error here.
Simple multiplication issue
DuckDB db(nullptr);
Connection con(db);
con.EnableQueryVerification();
con.SendQuery("SELECT 1 * (1 < 1);");
src/main/client_context.cpp:931: std::string duckdb::ClientContext::VerifyQuery(duckdb::ClientContextLock &, const std::string &, unique_ptrduckdb::SQLStatement): Assertion `orig_expr_list[i]->Equals(verify_statements[v_idx].select_list[i].get())' failed
I didn't have time to look at the details of this yet.
Duplicate table name at CTE
CREATE TABLE t0(c0 INT);
WITH t0 AS (SELECT 2) INSERT INTO t0 (WITH t0 AS (SELECT 2) SELECT 2);
Error: INTERNAL Error: Duplicate CTE "t0" in query!
This one maybe is mine. If we consider both CTEs to be at the same level, then the error shouldn't be internal.
Order by ALL with UNION query (now fixed)
(SELECT 2 ORDER BY(SELECT 2)) UNION SELECT 1 ORDER BY ALL;
src/planner/binder/query_node/bind_select_node.cpp:241: void duckdb::Binder::BindModifierTypes(duckdb::BoundQueryNode &, const vectorduckdb::LogicalType &, duckdb::idx_t): Assertion `bound_colref.binding.column_index < sql_types.size()' failed
The query should output the rows with values 1 and 2.
Date = int optimized vs non optimized
CREATE TABLE t0 (c0 INT);
PRAGMA enable_optimizer;
SELECT 1 FROM t0 WHERE DATE '2010-1-1' = 2;
-- Error: Conversion Error: Unimplemented type for cast (INTEGER -> DATE)
PRAGMA disable_optimizer;
SELECT 1 FROM t0 WHERE DATE '2010-1-1' = 2;
-- Empty result
This one is tricky. I would expect without any optimization the error to be thrown?
Another similar issue:
PRAGMA enable_optimizer;
VALUES (1),(INTERVAL '1' MICROSECONDS) LIMIT 0;
-- Empty result
PRAGMA disable_optimizer;
VALUES (1),(INTERVAL '1' MICROSECONDS) LIMIT 0;
-- Error: Conversion Error: Unimplemented type for cast (INTEGER -> INTERVAL)
Here it's reverted and what I expect, prune with optimizers enabled.
Another similar issue:
PRAGMA enable_optimizer;
SELECT 1 FROM (VALUES (1),(2),(NULL)) t0(c0) WHERE c0 BETWEEN 3 AND (CAST('inf' AS REAL) - 2);
-- Error: Out of Range Error: Overflow in subtraction of float!
PRAGMA disable_optimizer;
SELECT 1 FROM (VALUES (1),(2),(NULL)) t0(c0) WHERE c0 BETWEEN 3 AND (CAST('inf' AS REAL) - 2);
-- Empty result
This seems to be happening with runtime errors.
Select with forced parallelism
PRAGMA verify_parallelism;
CREATE TABLE t0 (c0 INT, c1 INT);
SELECT c1 FROM t0 WHERE (c0 + c1) = 2;
src/storage/data_table.cpp:333: bool duckdb::DataTable::NextParallelScan(duckdb::ClientContext &, duckdb::ParallelTableScanState &, duckdb::TableScanState &, const vectorduckdb::column_t &): Assertion `vector_index * STANDARD_VECTOR_SIZE < state.current_row_group->count' failed
My test machine has 32 cores, and I am using 1024 as the vector size.
The documentation still mentions the pragma as force_parallelism
. It needs to be updated.
OFFSET query with wrong results
CREATE TABLE t0 (c0 INT, c1 INT);
INSERT INTO t0 (VALUES (1, 1),(2, 2),(3, 3));
SELECT c0 FROM t0 WHERE ((c0 + c1) = 2) OFFSET 10;
The query outputs 1, it should be empty instead.
OFFSET query taking too long
CREATE TABLE t0 (c0 INT, c1 INT);
INSERT INTO t0 (VALUES (1, 1),(2, 2),(3, 3));
SELECT c0 FROM t0 OFFSET 42949672960;
The SELECT query runs for a very long time. I would expect it to end very shortly.
While running this on the shell and sending the interrupt signal to it, I get:
src/common/allocator.cpp:144: duckdb::AllocatorDebugInfo::~AllocatorDebugInfo(): Assertion `allocation_count == 0' failed
Maybe this is another unrelated issue.
heap-buffer-overflow with ART index
CREATE TABLE t0 (c0 INT AS (1), c1 INT);
CREATE INDEX i0 ON t0 USING ART ((c0 + c1));
With the address sanitizer, this results in a heap-buffer-overflow at src/common/types.cpp:36:17
NULL pointer on complex OFFSET clause
SELECT 6 OFFSET count(*) FILTER ((SELECT 2 UNION (SELECT 2) OFFSET (SELECT LAST))) OVER ();
src/planner/expression_binder/order_binder.cpp:39:61: runtime error: member call on null pointer of type 'std::vector<std::unique_ptrduckdb::ParsedExpression>'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior src/planner/expression_binder/order_binder.cpp:39:61
Analyze inexisting column (now fixed)
CREATE TABLE t0(c0 TINYINT);
ANALYZE t0(c4);
src/planner/binder/statement/bind_vacuum.cpp:35: duckdb::BoundStatement duckdb::Binder::Bind(duckdb::VacuumStatement &): Assertion `!result.HasError()' failed
A proper error should be thrown.
Analyze rowid column (now fixed)
CREATE TABLE t0(c0 INT);
ANALYZE t0(rowid);
src/storage/data_table.cpp:1319: void duckdb::DataTable::SetStatistics(duckdb::column_t, const std::function<void (BaseStatistics &)> &): Assertion `column_id != COLUMN_IDENTIFIER_ROW_ID' failed
A proper error should be thrown.
Alter table statements with rowid column
CREATE TABLE t0(c0 INTEGER, c1 INTEGER);
ALTER TABLE t0 DROP COLUMN rowid;
ALTER TABLE t0 RENAME rowid TO ups;
ALTER TABLE t0 ALTER rowid TYPE VARCHAR;
ALTER TABLE t0 ALTER rowid SET DEFAULT 0;
/usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/stl_vector.h:1046:34: runtime error: addition of unsigned offset to 0x611000049880 overflowed to 0x611000049818
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/stl_vector.h:1046:34
A proper error should be thrown.
C-API invalid query
DuckDB db(nullptr);
Connection con(db);
con.EnableQueryVerification();
con.SendQuery("INSERT INTO t0(VALUES(0 = (OVER = 2)));");
Terminates the process while throwing the error.
A proper error should be thrown.
In clause optimization error
CREATE TABLE t0(c0 INT);
SELECT 0 FROM t0 WHERE $0 IN (1);
src/optimizer/in_clause_rewriter.cpp:37: virtual unique_ptrduckdb::Expression duckdb::InClauseRewriter::VisitReplace(duckdb::BoundOperatorExpression &, unique_ptrduckdb::Expression *): Assertion `expr.children[i]->return_type == in_type' failed
A proper error should be thrown.
Lag window function issue (now fixed)
SELECT lag(1) OVER (ORDER BY 0 RANGE BETWEEN CURRENT ROW AND 1 FOLLOWING);
src/include/duckdb/common/types/vector.hpp:298: static bool duckdb::FlatVector::IsNull(const duckdb::Vector &, duckdb::idx_t): Assertion `vector.GetVectorType() == VectorType::FLAT_VECTOR' failed
A single NULL value is expected.
Statistics propagation mistmatch (now fixed)
PRAGMA enable_verification;
SELECT CAST("sum"(1) AS BIGINT) FROM (SELECT CAST((SELECT EXISTS(SELECT 1)) AS BIGINT));
Error: INTERNAL Error: Statistics mismatch: value is smaller than min.
Statistics: [Min: 42, Max: 42][Has Null: false, Has No Null: true][Approx Unique: 1]
Vector: CONSTANT BIGINT: 1 = [ 1]
C-API IN query row index out chunk size (now fixed)
DuckDB db(nullptr);
Connection con(db);
con.EnableQueryVerification();
con.SendQuery("SELECT(SELECT DATE '3764356-1-1' IN(1)) HAVING 0;");
src/common/types/column_data_collection.cpp:98: duckdb::Value duckdb::ColumnDataRow::GetValue(duckdb::idx_t) const: Assertion `row_index < chunk.size()' failed.
I would expect an unimplemented type for cast error.
Force no cross-product issue (now fixed)
PRAGMA debug_force_no_cross_product=1;
SELECT 1 FROM (SELECT 1) t0(c0), (SELECT 1) t1(c1);
Error: INTERNAL Error: HyperGraph isn't connected
The query should output 1.
Subquery error
SELECT (VALUES(1 != ALL(SELECT 2)));
src/common/types/vector.cpp:94: void duckdb::Vector::Reference(duckdb::Vector &): Assertion `other.GetType() == GetType()' failed.
The query should output a single true value.
Database collation not reloaded?
On a persisted database create this table: CREATE TABLE t0 (c0 VARCHAR(0) COLLATE AF);
.
Then after the restart, will give the error: Error: unable to open database "<name>": Catalog Error: Collation with name af does not exist!
I think collations need to be loaded earlier while starting a database.
Capi error assertion (now fixed)
DuckDB db(nullptr);
Connection con(db);
con.EnableQueryVerification();
con.SendQuery("SELECT 2 UNION(SELECT 2) ORDER BY 1;");
src/main/query_result.cpp:23: void duckdb::BaseQueryResult::ThrowError(const std::string &) const: Assertion `HasError()' failed.
The query should output a single 2.
Returning clause sizes not matching
CREATE TABLE t1(c0 INT, INT AS(1));
INSERT INTO t1 VALUES (1) RETURNING *;
src/planner/logical_operator.cpp:57: void duckdb::LogicalOperator::ResolveOperatorTypes(): Assertion `types.size() == GetColumnBindings().size()' failed
The insert should succeed.
Binding assertion error
CREATE TABLE t1(c0 INT);
SELECT * FROM (t1 JOIN t1 t2 USING (c0, c0)), (SELECT 2);
src/planner/bind_context.cpp:513: void duckdb::BindContext::AddContext(duckdb::BindContext): Assertion `other_alias->bindings.find(col) == other_alias->bindings.end()' failed
An error about duplicate "c0" reference in using clause expected.
Environment:
- OS: Linux
- DuckDB Version: Latest from the development master branch
- DuckDB Client: Shell and C-API
Identity Disclosure:
- Full Name: Pedro Ferreira
- Affiliation: Huawei