Skip to content

Commit 00e6b3f

Browse files
committed
initial
1 parent 3e93048 commit 00e6b3f

5 files changed

Lines changed: 67 additions & 0 deletions

File tree

vortex-duckdb/cpp/include/duckdb_vx/table_function.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ typedef struct {
125125

126126
void (*cardinality)(void *bind_data, duckdb_vx_node_statistics *node_stats_out);
127127

128+
void (*pushdown_column_type)(void *bind_data, idx_t id, duckdb_logical_type type);
128129
bool (*pushdown_complex_filter)(void *bind_data, duckdb_vx_expr expr, duckdb_vx_error *error_out);
129130

130131
void (*to_string)(void *bind_data, duckdb_vx_string_map map);

vortex-duckdb/cpp/table_function.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,20 @@ void function(ClientContext &, TableFunctionInput &input, DataChunk &output) {
263263
}
264264
}
265265

266+
void type_pushdown(ClientContext &, optional_ptr<FunctionData> bind_data,
267+
const unordered_map<idx_t, LogicalType> &new_column_types) {
268+
const auto &bind = bind_data->Cast<CTableBindData>();
269+
void *const ffi_bind = bind.ffi_data->DataPtr();
270+
for (const auto& [id, type] : new_column_types) {
271+
const duckdb_logical_type casted_type = reinterpret_cast<duckdb_logical_type>(
272+
// This is a flaw of duckdb api which doesn't allow passing const
273+
// LogicalTypes. We guarantee this variable won't be mutated on
274+
// Rust side
275+
const_cast<LogicalType*>(&type));
276+
bind.info.vtab.pushdown_column_type(ffi_bind, id, casted_type);
277+
}
278+
}
279+
266280
void c_pushdown_complex_filter(ClientContext &,
267281
LogicalGet &,
268282
FunctionData *bind_data,
@@ -394,6 +408,7 @@ extern "C" duckdb_state duckdb_vx_tfunc_register(duckdb_database ffi_db, const d
394408
tf.filter_prune = true;
395409
tf.sampling_pushdown = false;
396410

411+
tf.type_pushdown = type_pushdown;
397412
tf.pushdown_complex_filter = c_pushdown_complex_filter;
398413
tf.cardinality = c_cardinality;
399414
tf.get_partition_info = get_partition_info;

vortex-duckdb/src/convert/dtype.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,14 @@ impl TryFrom<&DType> for LogicalType {
282282
}
283283
}
284284

285+
impl TryFrom<&LogicalTypeRef> for DType {
286+
type Error = VortexError;
287+
288+
fn try_from(value: &LogicalTypeRef) -> Result<Self, Self::Error> {
289+
DType::from_logical_type(value, Nullability::Nullable)
290+
}
291+
}
292+
285293
impl TryFrom<StructFields> for LogicalType {
286294
type Error = VortexError;
287295

vortex-duckdb/src/datasource.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ use vortex::dtype::FieldNames;
3232
use vortex::error::VortexExpect;
3333
use vortex::error::VortexResult;
3434
use vortex::error::vortex_err;
35+
use vortex::error::vortex_panic;
3536
use vortex::expr::Expression;
3637
use vortex::expr::and_collect;
3738
use vortex::expr::col;
@@ -73,6 +74,7 @@ use crate::duckdb::DataChunkRef;
7374
use crate::duckdb::DuckdbStringMapRef;
7475
use crate::duckdb::ExpressionRef;
7576
use crate::duckdb::LogicalType;
77+
use crate::duckdb::LogicalTypeRef;
7678
use crate::duckdb::PartitionData;
7779
use crate::duckdb::TableFilterSetRef;
7880
use crate::duckdb::TableFunction;
@@ -118,6 +120,7 @@ pub struct DataSourceBindData {
118120
data_source: Arc<MultiLayoutDataSource>,
119121
filter_exprs: Vec<Expression>,
120122
column_fields: Vec<DuckdbField>,
123+
//column_casts: Vec<(usize, DType)>,
121124
}
122125

123126
impl Clone for DataSourceBindData {
@@ -569,6 +572,27 @@ impl<T: DataSourceTableFunction> TableFunction for T {
569572
map.push("Filters", &filters.join(" /\\\n"));
570573
}
571574
}
575+
576+
fn pushdown_column_type(
577+
bind_data: &mut Self::BindData,
578+
column_id: u64,
579+
new_type: &LogicalTypeRef,
580+
) {
581+
// TODO virtual column count?
582+
let column_id: usize = column_id.as_();
583+
if column_id >= bind_data.column_fields.len() {
584+
vortex_panic!("column_id {column_id} >= {}", bind_data.column_fields.len());
585+
}
586+
// TODO casting?
587+
let field = &mut bind_data.column_fields[column_id];
588+
let old_dtype = field.dtype.clone();
589+
// TODO we don't need a copy?
590+
field.logical_type = LogicalType::new(new_type.as_type_id());
591+
field.dtype = new_type
592+
.try_into()
593+
.vortex_expect("logical type -> dtype conversion failed");
594+
println!("Cast {} -> {}", old_dtype, field.dtype);
595+
}
572596
}
573597

574598
/// Extracts DuckDB column names and logical types from a Vortex struct DType.

vortex-duckdb/src/duckdb/table_function/mod.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use crate::duckdb::DataChunk;
2121
use crate::duckdb::DatabaseRef;
2222
use crate::duckdb::Expression;
2323
use crate::duckdb::LogicalType;
24+
use crate::duckdb::LogicalTypeRef;
2425
use crate::duckdb::Value;
2526
use crate::duckdb::client_context::ClientContextRef;
2627
use crate::duckdb::data_chunk::DataChunkRef;
@@ -103,6 +104,12 @@ pub trait TableFunction: Sized + Debug {
103104
/// Return table scanning progress from 0. to 100.
104105
fn table_scan_progress(global_state: &Self::GlobalState) -> f64;
105106

107+
fn pushdown_column_type(
108+
bind_data: &mut Self::BindData,
109+
column_id: u64,
110+
new_type: &LogicalTypeRef
111+
);
112+
106113
/// Pushes down a filter expression to the table function.
107114
///
108115
/// Returns `true` if the filter was successfully pushed down (and stored on the bind data),
@@ -157,6 +164,7 @@ impl DatabaseRef {
157164
function: Some(function::<T>),
158165
statistics: Some(statistics::<T>),
159166
cardinality: Some(cardinality_callback::<T>),
167+
pushdown_column_type: Some(pushdown_column_type::<T>),
160168
pushdown_complex_filter: Some(pushdown_complex_filter_callback::<T>),
161169
to_string: Some(to_string_callback::<T>),
162170
table_scan_progress: Some(table_scan_progress_callback::<T>),
@@ -225,6 +233,17 @@ unsafe extern "C-unwind" fn get_partition_data_callback<T: TableFunction>(
225233
out.file_index = data.file_index;
226234
}
227235

236+
unsafe extern "C-unwind" fn pushdown_column_type<T: TableFunction>(
237+
bind_data: *mut c_void,
238+
column_id: u64,
239+
new_type: cpp::duckdb_logical_type
240+
) {
241+
let bind_data =
242+
unsafe { bind_data.cast::<T::BindData>().as_mut() }.vortex_expect("bind_data null pointer");
243+
let new_type = unsafe { LogicalType::borrow(new_type) };
244+
T::pushdown_column_type(bind_data, column_id, new_type);
245+
}
246+
228247
unsafe extern "C-unwind" fn pushdown_complex_filter_callback<T: TableFunction>(
229248
bind_data: *mut c_void,
230249
expr: cpp::duckdb_vx_expr,

0 commit comments

Comments
 (0)