@@ -44,6 +44,145 @@ const SOURCE_FILES: [&str; 17] = [
4444 "cpp/vector_buffer.cpp" ,
4545] ;
4646
47+ // Duckdb C API function we use.
48+ // This lowers codegen'd src/cpp.rs by four times.
49+ const DUCKDB_C_API_FUNCTIONS : [ & str ; 134 ] = [
50+ "duckdb_array_type_array_size" ,
51+ "duckdb_array_type_child_type" ,
52+ "duckdb_array_vector_get_child" ,
53+ "duckdb_client_context_try_get_current_setting" ,
54+ "duckdb_close" ,
55+ "duckdb_column_count" ,
56+ "duckdb_column_logical_type" ,
57+ "duckdb_column_name" ,
58+ "duckdb_column_type" ,
59+ "duckdb_config_count" ,
60+ "duckdb_connect" ,
61+ "duckdb_create_array_type" ,
62+ "duckdb_create_blob" ,
63+ "duckdb_create_bool" ,
64+ "duckdb_create_config" ,
65+ "duckdb_create_data_chunk" ,
66+ "duckdb_create_date" ,
67+ "duckdb_create_decimal" ,
68+ "duckdb_create_decimal_type" ,
69+ "duckdb_create_double" ,
70+ "duckdb_create_float" ,
71+ "duckdb_create_int16" ,
72+ "duckdb_create_int32" ,
73+ "duckdb_create_int64" ,
74+ "duckdb_create_int8" ,
75+ "duckdb_create_list_type" ,
76+ "duckdb_create_logical_type" ,
77+ "duckdb_create_map_type" ,
78+ "duckdb_create_null_value" ,
79+ "duckdb_create_selection_vector" ,
80+ "duckdb_create_struct_type" ,
81+ "duckdb_create_time" ,
82+ "duckdb_create_timestamp" ,
83+ "duckdb_create_timestamp_ms" ,
84+ "duckdb_create_timestamp_ns" ,
85+ "duckdb_create_timestamp_s" ,
86+ "duckdb_create_timestamp_tz" ,
87+ "duckdb_create_uint16" ,
88+ "duckdb_create_uint32" ,
89+ "duckdb_create_uint64" ,
90+ "duckdb_create_uint8" ,
91+ "duckdb_create_union_type" ,
92+ "duckdb_create_varchar_length" ,
93+ "duckdb_create_vector" ,
94+ "duckdb_data_chunk_get_column_count" ,
95+ "duckdb_data_chunk_get_size" ,
96+ "duckdb_data_chunk_get_vector" ,
97+ "duckdb_data_chunk_reset" ,
98+ "duckdb_data_chunk_set_size" ,
99+ "duckdb_data_chunk_to_string" ,
100+ "duckdb_data_chunk_verify" ,
101+ "duckdb_decimal_scale" ,
102+ "duckdb_decimal_width" ,
103+ "duckdb_destroy_client_context" ,
104+ "duckdb_destroy_config" ,
105+ "duckdb_destroy_data_chunk" ,
106+ "duckdb_destroy_logical_type" ,
107+ "duckdb_destroy_result" ,
108+ "duckdb_destroy_selection_vector" ,
109+ "duckdb_destroy_value" ,
110+ "duckdb_destroy_vector" ,
111+ "duckdb_disconnect" ,
112+ "duckdb_fetch_chunk" ,
113+ "duckdb_free" ,
114+ "duckdb_geometry_type_get_crs" ,
115+ "duckdb_get_blob" ,
116+ "duckdb_get_bool" ,
117+ "duckdb_get_config_flag" ,
118+ "duckdb_get_date" ,
119+ "duckdb_get_decimal" ,
120+ "duckdb_get_double" ,
121+ "duckdb_get_float" ,
122+ "duckdb_get_hugeint" ,
123+ "duckdb_get_int16" ,
124+ "duckdb_get_int32" ,
125+ "duckdb_get_int64" ,
126+ "duckdb_get_int8" ,
127+ "duckdb_get_list_child" ,
128+ "duckdb_get_list_size" ,
129+ "duckdb_get_struct_child" ,
130+ "duckdb_get_time" ,
131+ "duckdb_get_time_ns" ,
132+ "duckdb_get_timestamp" ,
133+ "duckdb_get_timestamp_ms" ,
134+ "duckdb_get_timestamp_ns" ,
135+ "duckdb_get_timestamp_s" ,
136+ "duckdb_get_timestamp_tz" ,
137+ "duckdb_get_type_id" ,
138+ "duckdb_get_uhugeint" ,
139+ "duckdb_get_uint16" ,
140+ "duckdb_get_uint32" ,
141+ "duckdb_get_uint64" ,
142+ "duckdb_get_uint8" ,
143+ "duckdb_get_value_type" ,
144+ "duckdb_get_varchar" ,
145+ "duckdb_is_null_value" ,
146+ "duckdb_library_version" ,
147+ "duckdb_list_type_child_type" ,
148+ "duckdb_list_vector_get_child" ,
149+ "duckdb_list_vector_get_size" ,
150+ "duckdb_list_vector_reserve" ,
151+ "duckdb_list_vector_set_size" ,
152+ "duckdb_malloc" ,
153+ "duckdb_map_type_key_type" ,
154+ "duckdb_map_type_value_type" ,
155+ "duckdb_open" ,
156+ "duckdb_open_ext" ,
157+ "duckdb_query" ,
158+ "duckdb_result_error" ,
159+ "duckdb_row_count" ,
160+ "duckdb_rows_changed" ,
161+ "duckdb_selection_vector_get_data_ptr" ,
162+ "duckdb_set_config" ,
163+ "duckdb_string_t_data" ,
164+ "duckdb_string_t_length" ,
165+ "duckdb_struct_type_child_count" ,
166+ "duckdb_struct_type_child_name" ,
167+ "duckdb_struct_type_child_type" ,
168+ "duckdb_struct_vector_get_child" ,
169+ "duckdb_union_type_member_count" ,
170+ "duckdb_union_type_member_name" ,
171+ "duckdb_union_type_member_type" ,
172+ "duckdb_value_to_string" ,
173+ "duckdb_vector_assign_string_element" ,
174+ "duckdb_vector_assign_string_element_len" ,
175+ "duckdb_vector_ensure_validity_writable" ,
176+ "duckdb_vector_flatten" ,
177+ "duckdb_vector_get_column_type" ,
178+ "duckdb_vector_get_data" ,
179+ "duckdb_vector_get_validity" ,
180+ "duckdb_vector_reference_value" ,
181+ "duckdb_vector_reference_vector" ,
182+ "duckdb_vector_size" ,
183+ "duckdb_vector_to_string" ,
184+ ] ;
185+
47186const DOWNLOAD_MAX_RETRIES : i32 = 3 ;
48187const DOWNLOAD_TIMEOUT : u64 = 90 ;
49188
@@ -218,7 +357,7 @@ fn build_duckdb(version: &DuckDBVersion, duckdb_repo_dir: &Path) {
218357 ( "1" , "0" )
219358 } ;
220359
221- // If we're building from a commit we need to build httpfs and benchmark
360+ // If we're building from a commit we need to build httpfs and benchmark
222361 // extensions statically, otherwise DuckDB tries to load them from an http
223362 // endpoint with version 0.0.1 (all non-tagged builds) which doesn't exist.
224363 // httpfs static build also requires CURL dev headers
@@ -306,31 +445,41 @@ fn try_build_duckdb(
306445
307446/// Generate rust functions with bindgen from C sources.
308447fn bindgen_c2rust ( crate_dir : & Path , duckdb_include_dir : & Path ) {
309- let bindings = bindgen:: Builder :: default ( )
448+ let mut builder = bindgen:: Builder :: default ( )
310449 . header ( "cpp/include/duckdb_vx.h" )
311450 . override_abi ( Abi :: CUnwind , ".*" )
312- // Allow for auto-generated cpp.rs code.
313451 . raw_line ( "#![allow(dead_code)]" )
314452 . raw_line ( "#![allow(non_camel_case_types)]" )
315453 . raw_line ( "#![allow(non_upper_case_globals)]" )
316454 . raw_line ( "#![allow(non_snake_case)]" )
317455 . raw_line ( "#![allow(clippy::absolute_paths)]" )
318456 . raw_line ( "#![allow(clippy::suspicious_doc_comments)]" )
319457 . raw_line ( "#![allow(clippy::enum_variant_names)]" )
458+ . allowlist_function ( "duckdb_vx_.*" )
459+ . allowlist_type ( "duckdb_vx_.*" )
460+ . allowlist_type ( "DUCKDB_VX_.*" )
461+ . allowlist_var ( "DUCKDB_VX_.*" )
462+ // Two types read from raw vector data
463+ . allowlist_type ( "duckdb_list_entry" )
464+ . allowlist_type ( "duckdb_column_statistics" )
320465 // Add the #[must_use] attribute to FFI functions that return results.
321466 . must_use_type ( "duckdb_state" )
322467 . rustified_enum ( "duckdb_state" )
323468 . rustified_enum ( "DUCKDB_VX_EXPR_CLASS" )
324469 . rustified_enum ( "DUCKDB_VX_EXPR_TYPE" )
325470 . rustified_enum ( "DUCKDB_VX_TABLE_FILTER_TYPE" )
326- . rustified_enum ( "DUCKDB_VX_VECTOR_TYPE" )
327471 . rustified_non_exhaustive_enum ( "DUCKDB_TYPE" )
328472 . size_t_is_usize ( true )
329473 . clang_arg ( format ! ( "-I{}" , duckdb_include_dir. display( ) ) )
330474 . clang_arg ( format ! ( "-I{}" , crate_dir. join( "cpp/include" ) . display( ) ) )
331475 . generate_comments ( true )
332- . parse_callbacks ( Box :: new ( BindgenCargoCallbacks ) )
333- . generate ( ) ;
476+ . parse_callbacks ( Box :: new ( BindgenCargoCallbacks ) ) ;
477+
478+ for function in DUCKDB_C_API_FUNCTIONS {
479+ builder = builder. allowlist_function ( function) ;
480+ }
481+
482+ let bindings = builder. generate ( ) ;
334483
335484 let bindings = match bindings {
336485 Ok ( b) => b,
@@ -340,12 +489,7 @@ fn bindgen_c2rust(crate_dir: &Path, duckdb_include_dir: &Path) {
340489 }
341490 } ;
342491 let out_path = crate_dir. join ( "src/cpp.rs" ) ;
343- let new_contents = bindings. to_string ( ) ;
344- let write = match fs:: read_to_string ( & out_path) {
345- Ok ( existing) => existing != new_contents,
346- Err ( _) => true ,
347- } ;
348- if write && let Err ( e) = fs:: write ( & out_path, new_contents) {
492+ if let Err ( e) = fs:: write ( & out_path, bindings. to_string ( ) ) {
349493 println ! ( "cargo:error=Failed to write Rust bindings: {e}" ) ;
350494 exit ( 1 ) ;
351495 }
0 commit comments