Skip to content

Commit d83ecfc

Browse files
committed
vortex_version() macro
Signed-off-by: Mikhail Kot <mikhail@spiraldb.com>
1 parent b76e8fe commit d83ecfc

7 files changed

Lines changed: 92 additions & 0 deletions

File tree

‎vortex-duckdb/build.rs‎

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,35 @@ fn cbindgen_rust2c(crate_dir: &Path) {
627627
}
628628
}
629629

630+
fn git(crate_dir: &Path, args: &[&str]) -> Option<String> {
631+
let output = Command::new("git")
632+
.arg("-C")
633+
.arg(crate_dir)
634+
.args(args)
635+
.output()
636+
.ok()?;
637+
if !output.status.success() {
638+
return None;
639+
}
640+
let stdout = String::from_utf8(output.stdout).ok()?;
641+
let stdout = stdout.trim();
642+
(!stdout.is_empty()).then(|| stdout.to_owned())
643+
}
644+
645+
fn vortex_version(crate_dir: &Path) {
646+
println!("cargo:rerun-if-env-changed=VORTEX_VERSION");
647+
let version = env::var("VORTEX_VERSION")
648+
.ok()
649+
.filter(|version| !version.is_empty())
650+
// If this commit belongs to a tag
651+
.or_else(|| git(crate_dir, &["describe", "--tags", "--exact-match", "HEAD"]))
652+
// If this commit doesn't belong to a tag
653+
.or_else(|| git(crate_dir, &["rev-parse", "HEAD"]))
654+
// No version, can't build
655+
.unwrap();
656+
println!("cargo:rustc-env=VORTEX_VERSION={version}");
657+
}
658+
630659
fn main() {
631660
println!("cargo:rerun-if-changed=cpp/include");
632661
println!("cargo:rerun-if-changed=patches");
@@ -653,6 +682,7 @@ fn main() {
653682
// in vortex's CI.
654683

655684
let crate_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
685+
vortex_version(&crate_dir);
656686
if let Some(source_dir) = env::var_os("DUCKDB_SOURCE_DIR") {
657687
let source_dir = PathBuf::from(source_dir);
658688
let duckdb_include_dir = source_dir.join("src").join("include");

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ typedef struct {
7676
} duckdb_vx_written_column_statistics;
7777

7878
duckdb_state duckdb_vx_register_table_functions(duckdb_database ffi_db);
79+
duckdb_state duckdb_vx_register_version_function(duckdb_database ffi_db, const char *version);
7980

8081
typedef struct duckdb_vx_agg_input_ *duckdb_vx_agg_input;
8182
idx_t duckdb_vx_aggregate_len(duckdb_vx_agg_input ffi);

‎vortex-duckdb/cpp/table_function.cpp‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212

1313
#include "duckdb.h"
1414
#include "duckdb/catalog/catalog.hpp"
15+
#include "duckdb/catalog/default/default_functions.hpp"
1516
#include "duckdb/common/insertion_order_preserving_map.hpp"
17+
#include "duckdb/parser/keyword_helper.hpp"
1618
#include "duckdb/common/multi_file/multi_file_reader.hpp"
1719
#include "duckdb/function/table_function.hpp"
1820
#include "duckdb/main/capi/capi_internal.hpp"
@@ -220,6 +222,32 @@ duckdb_state register_table_function(DatabaseInstance &db, LogicalType parameter
220222
return DuckDBSuccess;
221223
}
222224

225+
extern "C" duckdb_state duckdb_vx_register_version_function(duckdb_database ffi_db, const char *version) {
226+
D_ASSERT(ffi_db);
227+
D_ASSERT(version);
228+
const DatabaseWrapper &wrapper = *reinterpret_cast<DatabaseWrapper *>(ffi_db);
229+
DatabaseInstance &db = *wrapper.database->instance;
230+
231+
const string quoted = KeywordHelper::WriteQuoted(version);
232+
233+
const DefaultMacro macro {DEFAULT_SCHEMA,
234+
"vortex_version",
235+
{nullptr},
236+
{{nullptr, nullptr}},
237+
quoted.c_str()};
238+
try {
239+
auto info = DefaultFunctionGenerator::CreateInternalMacroInfo(macro);
240+
auto &system_catalog = Catalog::GetSystemCatalog(db);
241+
auto data = CatalogTransaction::GetSystemTransaction(db);
242+
system_catalog.CreateFunction(data, *info);
243+
} catch (const std::exception &e) {
244+
ErrorData data(e);
245+
DUCKDB_LOG_ERROR(db, "Failed to create the vortex_version macro:\t" + data.Message());
246+
return DuckDBError;
247+
}
248+
return DuckDBSuccess;
249+
}
250+
223251
extern "C" duckdb_state duckdb_vx_register_table_functions(duckdb_database ffi_db) {
224252
D_ASSERT(ffi_db);
225253
const DatabaseWrapper &wrapper = *reinterpret_cast<DatabaseWrapper *>(ffi_db);

‎vortex-duckdb/src/duckdb/database.rs‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,16 @@ impl DatabaseRef {
6262
Ok(())
6363
}
6464

65+
pub fn register_version_function(&self, version: &str) -> VortexResult<()> {
66+
let version = CString::new(version)
67+
.map_err(|_| vortex_err!("Invalid version: string contains null bytes"))?;
68+
duckdb_try!(
69+
unsafe { cpp::duckdb_vx_register_version_function(self.as_ptr(), version.as_ptr()) },
70+
"Failed to register vortex_version function"
71+
);
72+
Ok(())
73+
}
74+
6575
pub fn register_optimizer_extension(&self) -> VortexResult<()> {
6676
duckdb_try!(
6777
unsafe { cpp::duckdb_vx_optimizer_extension_register(self.as_ptr()) },

‎vortex-duckdb/src/e2e_test/vortex_scan_test.rs‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,19 @@ fn test_scan_function_registration() {
201201
assert_eq!(string, "vortex_scan");
202202
}
203203

204+
#[test]
205+
fn test_vortex_version() -> Result<()> {
206+
let conn = database_connection();
207+
let query = format!(
208+
"SELECT (vortex_version() = '{}')::INT",
209+
env!("VORTEX_VERSION")
210+
);
211+
let result = conn.query(&query)?;
212+
let chunk = result.into_iter().next().unwrap();
213+
assert_eq!(chunk.get_vector(0).as_slice_with_len::<i32>(1), [1]);
214+
Ok(())
215+
}
216+
204217
#[test]
205218
fn test_vortex_scan_strings() {
206219
let file = RUNTIME.block_on(async {

‎vortex-duckdb/src/lib.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ fn init_tracing() {
7878
/// separately (e.g., before creating connections), call `register_extension_options` first.
7979
pub fn initialize(db: &DatabaseRef) -> VortexResult<()> {
8080
db.register_table_functions()?;
81+
db.register_version_function(env!("VORTEX_VERSION"))?;
8182
db.register_optimizer_extension()?;
8283
db.register_copy_function()
8384
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
# SPDX-FileCopyrightText: Copyright the Vortex contributors
3+
4+
include ../setup.slt.no
5+
6+
query B
7+
SELECT length(vortex_version()) > 0;
8+
----
9+
true

0 commit comments

Comments
 (0)