Skip to content

Commit

Permalink
Merge pull request #11329 from Mytherin/relassertscanfail
Browse files Browse the repository at this point in the history
In ColumnData, limit scan to the current count in the column
  • Loading branch information
Mytherin committed Mar 25, 2024
2 parents 4f80905 + cc85a34 commit 9dd1969
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 21 deletions.
60 changes: 43 additions & 17 deletions src/core_functions/scalar/generic/system_functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "duckdb/catalog/catalog_entry/aggregate_function_catalog_entry.hpp"
#include "duckdb/transaction/duck_transaction.hpp"
#include "duckdb/main/database_manager.hpp"
#include "duckdb/execution/expression_executor.hpp"

namespace duckdb {

Expand All @@ -28,25 +29,49 @@ static void CurrentDatabaseFunction(DataChunk &input, ExpressionState &state, Ve
result.Reference(val);
}

// current_schemas
static void CurrentSchemasFunction(DataChunk &input, ExpressionState &state, Vector &result) {
if (!input.AllConstant()) {
struct CurrentSchemasBindData : public FunctionData {
explicit CurrentSchemasBindData(Value result_value) : result(std::move(result_value)) {
}

Value result;

public:
unique_ptr<FunctionData> Copy() const override {
return make_uniq<CurrentSchemasBindData>(result);
}
bool Equals(const FunctionData &other_p) const override {
auto &other = other_p.Cast<CurrentSchemasBindData>();
return Value::NotDistinctFrom(result, other.result);
}
};

static unique_ptr<FunctionData> CurrentSchemasBind(ClientContext &context, ScalarFunction &bound_function,
vector<unique_ptr<Expression>> &arguments) {
if (!arguments[0]->IsFoldable()) {
throw NotImplementedException("current_schemas requires a constant input");
}
if (ConstantVector::IsNull(input.data[0])) {
result.SetVectorType(VectorType::CONSTANT_VECTOR);
ConstantVector::SetNull(result, true);
return;
Value schema_value = ExpressionExecutor::EvaluateScalar(context, *arguments[0]);
Value result_val;
if (schema_value.IsNull()) {
// null
result_val = Value(LogicalType::LIST(LogicalType::VARCHAR));
} else {
auto implicit_schemas = BooleanValue::Get(schema_value);
vector<Value> schema_list;
auto &catalog_search_path = ClientData::Get(context).catalog_search_path;
auto &search_path = implicit_schemas ? catalog_search_path->Get() : catalog_search_path->GetSetPaths();
std::transform(search_path.begin(), search_path.end(), std::back_inserter(schema_list),
[](const CatalogSearchEntry &s) -> Value { return Value(s.schema); });
result_val = Value::LIST(LogicalType::VARCHAR, schema_list);
}
auto implicit_schemas = *ConstantVector::GetData<bool>(input.data[0]);
vector<Value> schema_list;
auto &catalog_search_path = ClientData::Get(state.GetContext()).catalog_search_path;
auto &search_path = implicit_schemas ? catalog_search_path->Get() : catalog_search_path->GetSetPaths();
std::transform(search_path.begin(), search_path.end(), std::back_inserter(schema_list),
[](const CatalogSearchEntry &s) -> Value { return Value(s.schema); });

auto val = Value::LIST(LogicalType::VARCHAR, schema_list);
result.Reference(val);
return make_uniq<CurrentSchemasBindData>(std::move(result_val));
}

// current_schemas
static void CurrentSchemasFunction(DataChunk &input, ExpressionState &state, Vector &result) {
auto &func_expr = state.expr.Cast<BoundFunctionExpression>();
auto &info = func_expr.bind_info->Cast<CurrentSchemasBindData>();
result.Reference(info.result);
}

// in_search_path
Expand Down Expand Up @@ -94,7 +119,8 @@ ScalarFunction CurrentDatabaseFun::GetFunction() {

ScalarFunction CurrentSchemasFun::GetFunction() {
auto varchar_list_type = LogicalType::LIST(LogicalType::VARCHAR);
ScalarFunction current_schemas({LogicalType::BOOLEAN}, varchar_list_type, CurrentSchemasFunction);
ScalarFunction current_schemas({LogicalType::BOOLEAN}, varchar_list_type, CurrentSchemasFunction,
CurrentSchemasBind);
current_schemas.stability = FunctionStability::CONSISTENT_WITHIN_QUERY;
return current_schemas;
}
Expand Down
5 changes: 4 additions & 1 deletion src/storage/table/column_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,10 @@ idx_t ColumnData::ScanVector(TransactionData transaction, idx_t vector_index, Co
lock_guard<mutex> update_guard(update_lock);
has_updates = updates ? true : false;
}
auto scan_count = ScanVector(state, result, STANDARD_VECTOR_SIZE, has_updates);
idx_t current_row = vector_index * STANDARD_VECTOR_SIZE;
auto vector_count = MinValue<idx_t>(STANDARD_VECTOR_SIZE, count - current_row);

auto scan_count = ScanVector(state, result, vector_count, has_updates);
if (has_updates) {
lock_guard<mutex> update_guard(update_lock);
if (!ALLOW_UPDATES && updates->HasUncommittedUpdates(vector_index)) {
Expand Down
3 changes: 0 additions & 3 deletions test/fuzzer/sqlsmith/current_schemas_null.test
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@ SELECT current_schemas(NULL);
----
NULL

# the test below succeeds with a constant vector (it probably should just always succeed or always fail - but it's not that important)
require no_vector_verification

statement error
SELECT current_schemas(ref_0.bool) AS c4 FROM booleans AS ref_0;
----

0 comments on commit 9dd1969

Please sign in to comment.