Skip to content

Commit 3451cb0

Browse files
authored
move optimizer code to scalar_fn_pushdown (#8605)
This is preparatory work for aggregate pushdown Signed-off-by: Mikhail Kot <mikhail@spiraldb.com>
1 parent ba00e83 commit 3451cb0

7 files changed

Lines changed: 43 additions & 52 deletions

File tree

vortex-array/src/executor.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ impl ExecutionCtx {
368368
/// Use the [`format_args!`] macro to create the `msg` argument.
369369
pub fn log(&mut self, msg: fmt::Arguments<'_>) {
370370
#[cfg(debug_assertions)]
371-
if tracing::enabled!(tracing::Level::DEBUG) {
371+
if tracing::enabled!(tracing::Level::TRACE) {
372372
let formatted = format!(" - {msg}");
373373
tracing::trace!("exec[{}]: {formatted}", self.id);
374374
self.ops.push(formatted);

vortex-duckdb/build.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ const SOURCE_FILES: [&str; 7] = [
3131
"cpp/vortex_duckdb.cpp",
3232
"cpp/copy_function.cpp",
3333
"cpp/expr.cpp",
34-
"cpp/optimizer.cpp",
34+
"cpp/scalar_fn_pushdown.cpp",
3535
"cpp/table_filter.cpp",
3636
"cpp/table_function.cpp",
3737
"cpp/vector.cpp",
@@ -175,14 +175,13 @@ const DUCKDB_C_API_FUNCTIONS: [&str; 133] = [
175175
"duckdb_vector_size",
176176
];
177177

178-
const DUCKDB_C_API_HEADERS: [&str; 7] = [
178+
const DUCKDB_C_API_HEADERS: [&str; 6] = [
179179
"cpp/include/vortex_duckdb.h",
180180
"cpp/include/expr.h",
181181
"cpp/include/table_filter.h",
182182
"cpp/include/vector.h",
183183
"cpp/include/copy_function.h",
184184
"cpp/include/table_function.h",
185-
"cpp/include/optimizer.h",
186185
];
187186

188187
const DOWNLOAD_MAX_RETRIES: i32 = 3;

vortex-duckdb/cpp/include/optimizer.h

Lines changed: 0 additions & 14 deletions
This file was deleted.

vortex-duckdb/cpp/include/optimizer.hpp renamed to vortex-duckdb/cpp/include/scalar_fn_pushdown.hpp

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
// SPDX-License-Identifier: Apache-2.0
22
// SPDX-FileCopyrightText: Copyright the Vortex contributors
3-
43
#pragma once
4+
#include "duckdb.h"
55

66
#include "duckdb/optimizer/optimizer_extension.hpp"
77
#include "duckdb/planner/expression/bound_columnref_expression.hpp"
88
#include "duckdb/planner/expression/bound_function_expression.hpp"
99
#include "duckdb/planner/operator/logical_get.hpp"
1010
#include <optional>
1111

12-
// Only one consumer of this header file, so "using" is fine
1312
using namespace duckdb;
1413

1514
using ExpressionPtr = unique_ptr<Expression>;
@@ -50,6 +49,8 @@ struct GetAnalysis {
5049
* or without function application in the query plan.
5150
*/
5251
unordered_map<TableColumnScanIndex, const BoundFunctionExpression *> col_to_fn;
52+
53+
TableColumnStorageIndex StorageIndex(TableColumnScanIndex idx) const;
5354
};
5455

5556
using Analyses = unordered_map<TableIndex, GetAnalysis>;
@@ -74,6 +75,8 @@ using Analyses = unordered_map<TableIndex, GetAnalysis>;
7475
*/
7576
using Projections = unordered_map<TableIndex, LogicalProjection &>;
7677

78+
LogicalOperatorPtr TryPushdownScalarFunctions(ClientContext &context, LogicalOperatorPtr plan);
79+
7780
/**
7881
* Collect fn(col) expressions i.e. expressions where a single function (not
7982
* a function chain) wraps a single bound column. If "col" is used without
@@ -105,14 +108,6 @@ struct ScalarFnReplace final : LogicalOperatorVisitor {
105108

106109
void FindGetsAndProjections(LogicalOperator &op, Analyses &analyses, Projections &aliases);
107110

108-
LogicalOperatorPtr TryPushdownScalarFunctions(ClientContext &context, LogicalOperatorPtr plan);
109-
void VortexOptimizeFunction(OptimizerExtensionInput &input, LogicalOperatorPtr &plan);
110-
111-
struct VortexOptimizerExtension final : OptimizerExtension {
112-
inline VortexOptimizerExtension() : OptimizerExtension(VortexOptimizeFunction, nullptr, {}) {
113-
}
114-
};
115-
116111
struct GetBinding {
117112
GetAnalysis &analysis;
118113
TableColumnScanIndex column_index;

vortex-duckdb/cpp/include/vortex_duckdb.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ duckdb_logical_type duckdb_vx_create_geometry(const char *crs);
4343

4444
duckdb_state duckdb_vx_register_scan_replacement(duckdb_database duckdb_database);
4545

46+
duckdb_state duckdb_vx_optimizer_extension_register(duckdb_database ffi_db);
47+
4648
/// Creates a new reusable dictionary from a logical type and size.
4749
duckdb_vx_reusable_dict duckdb_vx_reusable_dict_create(duckdb_logical_type logical_type, idx_t size);
4850

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
// SPDX-License-Identifier: Apache-2.0
22
// SPDX-FileCopyrightText: Copyright the Vortex contributors
3-
#include "optimizer.hpp"
4-
#include "table_function.hpp"
53
#include "duckdb/catalog/catalog.hpp"
6-
#include "duckdb/main/config.hpp"
7-
#include "duckdb/main/capi/capi_internal.hpp"
84
#include "duckdb/planner/operator/logical_projection.hpp"
5+
#include "scalar_fn_pushdown.hpp"
6+
#include "table_function.hpp"
97
#include <optional>
108

119
/**
@@ -15,24 +13,6 @@
1513
* may produce conflicts (e.g. WHERE prefix("str", 'h')).
1614
*/
1715

18-
extern "C" duckdb_state duckdb_vx_optimizer_extension_register(duckdb_database ffi_db) {
19-
D_ASSERT(ffi_db);
20-
const DatabaseWrapper &wrapper = *reinterpret_cast<DatabaseWrapper *>(ffi_db);
21-
DatabaseInstance &db = *wrapper.database->instance;
22-
try {
23-
DBConfig::GetConfig(db).GetCallbackManager().Register(VortexOptimizerExtension());
24-
} catch (const std::exception &e) {
25-
ErrorData data(e);
26-
DUCKDB_LOG_ERROR(db, "Failed to create Vortex optimizer extension:\t" + data.Message());
27-
return DuckDBError;
28-
}
29-
return DuckDBSuccess;
30-
}
31-
32-
void VortexOptimizeFunction(OptimizerExtensionInput &input, LogicalOperatorPtr &plan) {
33-
plan = TryPushdownScalarFunctions(input.context, std::move(plan));
34-
}
35-
3616
LogicalOperatorPtr TryPushdownScalarFunctions(ClientContext &context, LogicalOperatorPtr plan) {
3717
Analyses analyses;
3818
Projections projections;
@@ -48,8 +28,7 @@ LogicalOperatorPtr TryPushdownScalarFunctions(ClientContext &context, LogicalOpe
4828
if (expr == nullptr) { // Conflict for column
4929
continue;
5030
}
51-
const TableColumnStorageIndex storage_index =
52-
analysis.get.GetColumnIds()[column_index].GetPrimaryIndex();
31+
const TableColumnStorageIndex storage_index = analysis.StorageIndex(column_index);
5332
TableFunctionProjectionExpressionInput input {analysis.get, *expr, storage_index};
5433
if (projection_expression_pushdown(context, input)) {
5534
analysis.get.types[column_index] = expr->return_type;
@@ -248,3 +227,7 @@ ScalarFnCollect::ScalarFnCollect(Analyses &analyses, const Projections &projecti
248227
ScalarFnReplace::ScalarFnReplace(Analyses &analyses, const Projections &projections)
249228
: analyses(analyses), projections(projections) {
250229
}
230+
231+
TableColumnStorageIndex GetAnalysis::StorageIndex(TableColumnScanIndex idx) const {
232+
return get.GetColumnIds()[idx].GetPrimaryIndex();
233+
}

vortex-duckdb/cpp/vortex_duckdb.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33

44
#include "data.hpp"
55
#include "error.hpp"
6+
#include "scalar_fn_pushdown.hpp"
67
#include "vortex_duckdb.h"
78

9+
#include "duckdb/catalog/catalog.hpp"
810
#include "duckdb/common/assert.hpp"
911
#include "duckdb/common/types.hpp"
1012
#include "duckdb/common/types/data_chunk.hpp"
@@ -15,6 +17,7 @@
1517
#include "duckdb/main/client_context.hpp"
1618
#include "duckdb/main/config.hpp"
1719
#include "duckdb/main/connection.hpp"
20+
#include "duckdb/optimizer/optimizer_extension.hpp"
1821
#include "duckdb/parser/expression/constant_expression.hpp"
1922
#include "duckdb/parser/expression/function_expression.hpp"
2023
#include "duckdb/parser/tableref/table_function_ref.hpp"
@@ -263,3 +266,26 @@ extern "C" duckdb_blob duckdb_vx_value_get_geometry(duckdb_value value) {
263266
}
264267
return {buf, size};
265268
}
269+
270+
static void VortexOptimizeFunction(OptimizerExtensionInput &input, unique_ptr<LogicalOperator> &plan) {
271+
plan = TryPushdownScalarFunctions(input.context, std::move(plan));
272+
}
273+
274+
struct VortexOptimizerExtension final : OptimizerExtension {
275+
inline VortexOptimizerExtension() : OptimizerExtension(VortexOptimizeFunction, nullptr, {}) {
276+
}
277+
};
278+
279+
extern "C" duckdb_state duckdb_vx_optimizer_extension_register(duckdb_database ffi_db) {
280+
D_ASSERT(ffi_db);
281+
const DatabaseWrapper &wrapper = *reinterpret_cast<DatabaseWrapper *>(ffi_db);
282+
DatabaseInstance &db = *wrapper.database->instance;
283+
try {
284+
DBConfig::GetConfig(db).GetCallbackManager().Register(VortexOptimizerExtension());
285+
} catch (const std::exception &e) {
286+
ErrorData data(e);
287+
DUCKDB_LOG_ERROR(db, "Failed to create Vortex optimizer extension:\t" + data.Message());
288+
return DuckDBError;
289+
}
290+
return DuckDBSuccess;
291+
}

0 commit comments

Comments
 (0)