Skip to content

Commit 67b5c3c

Browse files
committed
review fixes, but keep the leak
1 parent bc6ab5f commit 67b5c3c

File tree

5 files changed

+191
-179
lines changed

5 files changed

+191
-179
lines changed

.github/workflows/ci.yml

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -384,10 +384,10 @@ jobs:
384384
fail-fast: false
385385
matrix:
386386
include:
387+
# We don't run memory sanitizer as it provides many false positives
388+
# for std
387389
- sanitizer: asan
388-
sanitizer_flags: "-Zsanitizer=address -Zsanitize=leak"
389-
- sanitizer: msan
390-
sanitizer_flags: "-Zsanitizer=memory"
390+
sanitizer_flags: "-Zsanitizer=address,leak"
391391
- sanitizer: tsan
392392
sanitizer_flags: "-Zsanitizer=thread"
393393
name: "Rust tests (${{ matrix.sanitizer }})"
@@ -419,15 +419,16 @@ jobs:
419419
run: |
420420
rustup toolchain install $NIGHTLY_TOOLCHAIN
421421
rustup component add --toolchain $NIGHTLY_TOOLCHAIN rust-src rustfmt clippy llvm-tools-preview
422-
export RUSTFLAGS="${RUSTFLAGS} ${{ matrix.sanitizer_flags }}"
423422
- name: Build tests with sanitizer
424423
run: |
424+
RUSTFLAGS="${RUSTFLAGS} ${{ matrix.sanitizer_flags }}" \
425425
cargo +$NIGHTLY_TOOLCHAIN build --locked --all-features \
426426
--target x86_64-unknown-linux-gnu -Zbuild-std \
427427
-p vortex-buffer -p vortex-fastlanes -p vortex-fsst -p vortex-alp -p vortex-array
428428
429429
- name: Run tests with sanitizer
430430
run: |
431+
RUSTFLAGS="${RUSTFLAGS} ${{ matrix.sanitizer_flags }}" \
431432
cargo +$NIGHTLY_TOOLCHAIN nextest run --locked --all-features \
432433
--target x86_64-unknown-linux-gnu --no-fail-fast -Zbuild-std \
433434
-p vortex-buffer -p vortex-fastlanes -p vortex-fsst -p vortex-alp -p vortex-array
@@ -438,6 +439,7 @@ jobs:
438439
# TODO(myrrc): remove --no-default-features once we make Mimalloc opt-in
439440
- name: Run vortex-ffi tests with sanitizer
440441
run: |
442+
RUSTFLAGS="${RUSTFLAGS} ${{ matrix.sanitizer_flags }}" \
441443
cargo +$NIGHTLY_TOOLCHAIN test --locked --no-default-features \
442444
--target x86_64-unknown-linux-gnu --no-fail-fast -Zbuild-std \
443445
-p vortex-ffi -- --no-capture
@@ -450,7 +452,7 @@ jobs:
450452
# We don't run memory sanitizer as it's clang-only and provides many
451453
# false positives for Catch2
452454
- sanitizer: asan
453-
sanitizer_flags: "-Zsanitizer=address -Zsanitize=leak"
455+
sanitizer_flags: "-Zsanitizer=address,leak"
454456
- sanitizer: tsan
455457
sanitizer_flags: "-Zsanitizer=thread"
456458
name: "Rust/C++ FFI tests (${{ matrix.sanitizer }})"
@@ -484,15 +486,13 @@ jobs:
484486
run: |
485487
rustup toolchain install $NIGHTLY_TOOLCHAIN
486488
rustup component add --toolchain $NIGHTLY_TOOLCHAIN rust-src rustfmt clippy llvm-tools-preview
487-
488-
# Export flags here so that rustfilt won't be built with sanitizers
489-
export RUSTFLAGS="-A warnings -Cunsafe-allow-abi-mismatch=sanitizer \
490-
--cfg disable_loom --cfg vortex_nightly -C debuginfo=2 \
491-
-C opt-level=0 -C strip=none -Zexternal-clangrt \
492-
${{ matrix.sanitizer_flags }}"
493489
- name: Build FFI library
494490
run: |
495491
# TODO(myrrc): remove --no-default-features
492+
RUSTFLAGS="-A warnings -Cunsafe-allow-abi-mismatch=sanitizer \
493+
--cfg disable_loom --cfg vortex_nightly -C debuginfo=2 \
494+
-C opt-level=0 -C strip=none -Zexternal-clangrt \
495+
${{ matrix.sanitizer_flags }}" \
496496
cargo +$NIGHTLY_TOOLCHAIN build --locked --no-default-features \
497497
--target x86_64-unknown-linux-gnu -Zbuild-std \
498498
-p vortex-ffi

vortex-ffi/cinclude/vortex.h

Lines changed: 51 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -165,14 +165,14 @@ typedef enum {
165165
*/
166166
VX_OPERATOR_SUB = 9,
167167
/**
168-
* Multiple two numbers
168+
* Multiply two numbers
169169
*/
170170
VX_OPERATOR_MUL = 10,
171171
/**
172172
* Divide the left side by the right side
173173
*/
174174
VX_OPERATOR_DIV = 11,
175-
} vx_operator;
175+
} vx_binary_operator;
176176

177177
/**
178178
* Log levels for the Vortex library.
@@ -555,7 +555,9 @@ const vx_string *vx_array_get_utf8(const vx_array *array, uint32_t index);
555555
const vx_binary *vx_array_get_binary(const vx_array *array, uint32_t index);
556556

557557
/**
558-
* Apply the expression to the array, producing a new array in constant time
558+
* Apply the expression to the array, wrapping it with a ScalarFnArray.
559+
* This operation takes constant time as it doesn't execute the underlying
560+
* array. Executing the underlying array still takes O(n) time.
559561
*/
560562
const vx_array *vx_array_apply(const vx_array *array, const vx_expression *expression, vx_error **error);
561563

@@ -758,86 +760,91 @@ void vx_error_free(vx_error *ptr);
758760
*/
759761
const vx_string *vx_error_get_message(const vx_error *error);
760762

761-
/**
762-
* Clone a borrowed [`vx_expression`], returning an owned [`vx_expression`].
763-
*
764-
*
765-
* Must be released with [`vx_expression_free`].
766-
*/
767-
const vx_expression *vx_expression_clone(const vx_expression *ptr);
768-
769763
/**
770764
* Free an owned [`vx_expression`] object.
771765
*/
772-
void vx_expression_free(const vx_expression *ptr);
766+
void vx_expression_free(vx_expression *ptr);
773767

774768
/**
775-
* Create a root expression
769+
* Create a root expression. A root expression, applied to an array in
770+
* vx_array_apply, takes the array itself as opposed to functions like
771+
* vx_expression_column or vx_expression_select which take the array's parts.
772+
*
773+
* Example:
774+
*
775+
* const vx_array* array = ...;
776+
* vx_expression* root = vx_expression_root();
777+
* const vx_error* error = NULL;
778+
* vx_array* applied_array = vx_array_apply(array, root, &error);
779+
* // array and applied_array are identical
780+
* vx_array_free(applied_array);
781+
* vx_expression_free(root);
782+
* vx_array_free(array);
783+
*
776784
*/
777-
const vx_expression *vx_expression_root(void);
785+
vx_expression *vx_expression_root(void);
778786

779787
/**
780788
* Create an expression that accesses a field from the root array.
789+
* Errors in vx_array_apply if the root array doesn't have a specified field.
781790
*
782791
* Equivalent to get_item(name, root()).
783792
*/
784-
const vx_expression *vx_expression_column(const char *name);
793+
vx_expression *vx_expression_column(const char *name);
785794

786795
/**
787796
* Create an expression that selects (includes) specific fields from a child
788-
* expression. Child expression must have a DTYPE_STRUCT dtype.
797+
* expression. Child expression must have a DTYPE_STRUCT dtype. Errors in
798+
* vx_array_apply if the child expression doesn't have a specified field.
789799
*
790800
* Example:
791801
*
792-
* const vx_expression* root = vx_expression_root();
802+
* vx_expression* root = vx_expression_root();
793803
* const char* names[] = {"name", "age"};
794-
* const vx_expression* select = vx_expression_select(names, 2, root);
804+
* vx_expression* select = vx_expression_select(names, 2, root);
795805
* vx_expression_free(select);
796806
* vx_expression_free(root);
797807
*
798808
*/
799-
const vx_expression *vx_expression_select(const char *const *names, size_t len, const vx_expression *child);
809+
vx_expression *vx_expression_select(const char *const *names, size_t len, const vx_expression *child);
800810

801811
/**
802812
* Create an AND expression for multiple child expressions.
803-
* If there are no input expressions, returns NULL.
813+
* If there are no input expressions, returns a logical true expression
804814
*/
805-
const vx_expression *vx_expression_and(const vx_expression *const *expressions, size_t len);
815+
vx_expression *vx_expression_and(const vx_expression *const *expressions, size_t len);
806816

807817
/**
808818
* Create an OR disjunction expression for multiple child expressions.
809819
* If there are no input expressions, returns NULL.
810820
*/
811-
const vx_expression *vx_expression_or(const vx_expression *const *expressions, size_t len);
821+
vx_expression *vx_expression_or(const vx_expression *const *expressions, size_t len);
812822

813823
/**
814824
* Create a binary expression for two expressions of form lhs OP rhs.
815825
* If either input is NULL, returns NULL.
816826
*
817-
* Example:
827+
* Example for a binary sum:
818828
*
819-
* const vx_expression* age = vx_expression_column("age");
820-
* const vx_expression* height = vx_expression_column("height");
821-
* const vx_expression* sum = vx_expression_binary(VX_OPERATOR_SUM, age, height);
829+
* vx_expression* age = vx_expression_column("age");
830+
* vx_expression* height = vx_expression_column("height");
831+
* vx_expression* sum = vx_expression_binary(VX_OPERATOR_ADD, age, height);
822832
* vx_expression_free(sum);
823833
* vx_expression_free(height);
824834
* vx_expression_free(age);
825835
*
836+
* Example for a binary equality function:
837+
*
838+
* vx_expression* vx_expression_eq(
839+
* const vx_expression* lhs,
840+
* const vx_expression* rhs
841+
* ) {
842+
* return vx_expression_binary(VX_OPERATOR_EQ, lhs, rhs);
843+
* }
844+
*
826845
*/
827-
const vx_expression *
828-
vx_expression_binary(vx_operator operator_, const vx_expression *lhs, const vx_expression *rhs);
829-
830-
const vx_expression *vx_expression_eq(const vx_expression *lhs, const vx_expression *rhs);
831-
832-
const vx_expression *vx_expression_not_eq(const vx_expression *lhs, const vx_expression *rhs);
833-
834-
const vx_expression *vx_expression_lt(const vx_expression *lhs, const vx_expression *rhs);
835-
836-
const vx_expression *vx_expression_lt_eq(const vx_expression *lhs, const vx_expression *rhs);
837-
838-
const vx_expression *vx_expression_gt(const vx_expression *lhs, const vx_expression *rhs);
839-
840-
const vx_expression *vx_expression_gt_eq(const vx_expression *lhs, const vx_expression *rhs);
846+
vx_expression *
847+
vx_expression_binary(vx_binary_operator operator_, const vx_expression *lhs, const vx_expression *rhs);
841848

842849
/**
843850
* Create a logical NOT of the child expression.
@@ -851,23 +858,24 @@ const vx_expression *vx_expression_not(const vx_expression *child);
851858
*
852859
* Returns a boolean array indicating which positions contain null values.
853860
*/
854-
const vx_expression *vx_expression_is_null(const vx_expression *child);
861+
vx_expression *vx_expression_is_null(const vx_expression *child);
855862

856863
/**
857864
* Create an expression that extracts a named field from a struct expression.
858865
* Child expression must have a DTYPE_STRUCT dtype.
866+
* Errors in vx_array_apply if the root array doesn't have a specified field.
859867
*
860868
* Accesses the specified field from the result of the child expression.
861869
* Equivalent to select(&item, 1, child).
862870
*/
863-
const vx_expression *vx_expression_get_item(const char *item, const vx_expression *child);
871+
vx_expression *vx_expression_get_item(const char *item, const vx_expression *child);
864872

865873
/**
866874
* Create an expression that checks if a value is contained in a list.
867875
*
868876
* Returns a boolean array indicating whether the value appears in each list.
869877
*/
870-
const vx_expression *vx_expression_list_contains(const vx_expression *list, const vx_expression *value);
878+
vx_expression *vx_expression_list_contains(const vx_expression *list, const vx_expression *value);
871879

872880
/**
873881
* Clone a borrowed [`vx_file`], returning an owned [`vx_file`].

vortex-ffi/src/array.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,9 @@ pub unsafe extern "C-unwind" fn vx_array_get_binary(
188188
}
189189
}
190190

191-
/// Apply the expression to the array, producing a new array in constant time
191+
/// Apply the expression to the array, wrapping it with a ScalarFnArray.
192+
/// This operation takes constant time as it doesn't execute the underlying
193+
/// array. Executing the underlying array still takes O(n) time.
192194
#[unsafe(no_mangle)]
193195
pub unsafe extern "C" fn vx_array_apply(
194196
array: *const vx_array,
@@ -473,7 +475,7 @@ mod tests {
473475
// Test with Vortex Rust-side expressions here, test C API for
474476
// expressions in src/expressions.rs
475477
let expression = eq(root(), lit(3i32));
476-
let expression = vx_expression::new(Arc::new(expression));
478+
let expression = vx_expression::new(Box::new(expression));
477479

478480
let res = vx_array_apply(ptr::null(), expression, &raw mut error);
479481
assert!(res.is_null());

0 commit comments

Comments
 (0)