• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

vortex-data / vortex / 16139349253

08 Jul 2025 09:26AM UTC coverage: 78.057% (-0.2%) from 78.253%
16139349253

push

github

web-flow
VortexExpr VTables (#3713)

Adds the same vtable machinery as arrays and layouts already use. It
uses the "Encoding" naming scheme from arrays and layouts. I don't
particularly like it, but it's consistent. Open to renames later.

Further, adds an expression registry to the Vortex session that will be
used for deserialization.

Expressions only decide their "options" serialization. So in theory, can
support many container formats, not just proto, provided each expression
can deserialize their own options format.

---------

Signed-off-by: Nicholas Gates <nick@nickgates.com>

800 of 1190 new or added lines in 38 files covered. (67.23%)

40 existing lines in 13 files now uncovered.

44100 of 56497 relevant lines covered (78.06%)

54989.55 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

60.0
/vortex-expr/src/vtable.rs
1
// SPDX-License-Identifier: Apache-2.0
2
// SPDX-FileCopyrightText: Copyright the Vortex contributors
3

4
use std::fmt::{Debug, Display};
5
use std::hash::Hash;
6
use std::ops::Deref;
7

8
use vortex_array::{ArrayRef, DeserializeMetadata, SerializeMetadata};
9
use vortex_dtype::DType;
10
use vortex_error::VortexResult;
11

12
use crate::{
13
    AnalysisExpr, ExprEncoding, ExprEncodingRef, ExprId, ExprRef, IntoExpr, Scope, ScopeDType,
14
    VortexExpr,
15
};
16

17
pub trait VTable: 'static + Sized + Send + Sync + Debug {
18
    type Expr: 'static
19
        + Send
20
        + Sync
21
        + Clone
22
        + Debug
23
        + Display
24
        + PartialEq
25
        + Hash
26
        + Deref<Target = dyn VortexExpr>
27
        + IntoExpr
28
        + AnalysisExpr;
29
    type Encoding: 'static + Send + Sync + Deref<Target = dyn ExprEncoding>;
30
    type Metadata: SerializeMetadata + DeserializeMetadata + Debug;
31

32
    /// Returns the ID of the expr encoding.
33
    fn id(encoding: &Self::Encoding) -> ExprId;
34

35
    /// Returns the encoding for the expr.
36
    fn encoding(expr: &Self::Expr) -> ExprEncodingRef;
37

38
    /// Returns the serialize-able metadata for the expr, or `None` if serialization is not
39
    /// supported.
40
    fn metadata(expr: &Self::Expr) -> Option<Self::Metadata>;
41

42
    /// Returns the children of the expr.
43
    fn children(expr: &Self::Expr) -> Vec<&ExprRef>;
44

45
    /// Return a new instance of the expression with the children replaced.
46
    fn with_children(expr: &Self::Expr, children: Vec<ExprRef>) -> VortexResult<Self::Expr>;
47

48
    /// Construct a new [`VortexExpr`] from the provided parts.
49
    fn build(
50
        encoding: &Self::Encoding,
51
        metadata: &<Self::Metadata as DeserializeMetadata>::Output,
52
        children: Vec<ExprRef>,
53
    ) -> VortexResult<Self::Expr>;
54

55
    /// Evaluate the expression in the given scope.
56
    fn evaluate(expr: &Self::Expr, scope: &Scope) -> VortexResult<ArrayRef>;
57

58
    /// Compute the return [`DType`] of the expression if evaluated in the given scope.
59
    fn return_dtype(expr: &Self::Expr, scope: &ScopeDType) -> VortexResult<DType>;
60
}
61

62
#[macro_export]
63
macro_rules! vtable {
64
    ($V:ident) => {
65
        $crate::aliases::paste::paste! {
66
            #[derive(Debug)]
67
            pub struct [<$V VTable>];
68

69
            impl AsRef<dyn $crate::VortexExpr> for [<$V Expr>] {
NEW
70
                fn as_ref(&self) -> &dyn $crate::VortexExpr {
×
NEW
71
                    // We can unsafe cast ourselves to a ExprAdapter.
×
NEW
72
                    unsafe { &*(self as *const [<$V Expr>] as *const $crate::ExprAdapter<[<$V VTable>]>) }
×
NEW
73
                }
×
74
            }
75

76
            impl std::ops::Deref for [<$V Expr>] {
77
                type Target = dyn $crate::VortexExpr;
78

79
                fn deref(&self) -> &Self::Target {
3,286✔
80
                    // We can unsafe cast ourselves to an ExprAdapter.
3,286✔
81
                    unsafe { &*(self as *const [<$V Expr>] as *const $crate::ExprAdapter<[<$V VTable>]>) }
3,286✔
82
                }
3,286✔
83
            }
84

85
            impl $crate::IntoExpr for [<$V Expr>] {
86
                fn into_expr(self) -> $crate::ExprRef {
28,920✔
87
                    // We can unsafe transmute ourselves to an ExprAdapter.
28,920✔
88
                    std::sync::Arc::new(unsafe { std::mem::transmute::<[<$V Expr>], $crate::ExprAdapter::<[<$V VTable>]>>(self) })
28,920✔
89
                }
28,920✔
90
            }
91

92
            impl AsRef<dyn $crate::ExprEncoding> for [<$V ExprEncoding>] {
93
                fn as_ref(&self) -> &dyn $crate::ExprEncoding {
1,177✔
94
                    // We can unsafe cast ourselves to an ExprEncodingAdapter.
1,177✔
95
                    unsafe { &*(self as *const [<$V ExprEncoding>] as *const $crate::ExprEncodingAdapter<[<$V VTable>]>) }
1,177✔
96
                }
1,177✔
97
            }
98

99
            impl std::ops::Deref for [<$V ExprEncoding>] {
100
                type Target = dyn $crate::ExprEncoding;
101

NEW
102
                fn deref(&self) -> &Self::Target {
×
NEW
103
                    // We can unsafe cast ourselves to an ExprEncodingAdapter.
×
NEW
104
                    unsafe { &*(self as *const [<$V ExprEncoding>] as *const $crate::ExprEncodingAdapter<[<$V VTable>]>) }
×
NEW
105
                }
×
106
            }
107
        }
108
    };
109
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc