Skip to content

Commit 2fbc5b6

Browse files
authored
feat: support Substrait version 0.18 (#56)
BREAKING CHANGE: - buffer passed to substrait_validator::parse() must now be Clone, in order to be able to parse it as both substrait.Plan and substrait.PlanVersion (if the former fails) - substrait_validator::version() and substrait_validator::substrait_version() now return semver::Version objects rather than strings
1 parent a3a2fbc commit 2fbc5b6

File tree

175 files changed

+537
-67
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

175 files changed

+537
-67
lines changed

Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ older version. Refer to the table below for the version compatibility matrix.
2727

2828
| Substrait... | ... is supported by validator ... |
2929
| -------------- | ------------------------------------ |
30-
| 0.9.x - 0.12.x | current version |
30+
| 0.18.x | current version |
31+
| 0.9.x - 0.17.x | 0.0.8 |
3132
| 0.7.x - 0.8.x | 0.0.7 |
3233
| 0.5.x - 0.6.x | 0.0.6 |
3334
| 0.3.x - 0.4.x | 0.0.4 - 0.0.5 |

c/src/lib.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -833,7 +833,7 @@ pub extern "C" fn substrait_validator_export_proto(
833833
pub extern "C" fn substrait_validator_version() -> *const libc::c_char {
834834
static VERSION: once_cell::sync::OnceCell<std::ffi::CString> = once_cell::sync::OnceCell::new();
835835
VERSION
836-
.get_or_init(|| std::ffi::CString::new(substrait_validator::version()).unwrap())
836+
.get_or_init(|| std::ffi::CString::new(substrait_validator::version().to_string()).unwrap())
837837
.as_bytes_with_nul()
838838
.as_ptr() as *const libc::c_char
839839
}
@@ -843,7 +843,9 @@ pub extern "C" fn substrait_validator_version() -> *const libc::c_char {
843843
pub extern "C" fn substrait_validator_substrait_version() -> *const libc::c_char {
844844
static VERSION: once_cell::sync::OnceCell<std::ffi::CString> = once_cell::sync::OnceCell::new();
845845
VERSION
846-
.get_or_init(|| std::ffi::CString::new(substrait_validator::substrait_version()).unwrap())
846+
.get_or_init(|| {
847+
std::ffi::CString::new(substrait_validator::substrait_version().to_string()).unwrap()
848+
})
847849
.as_bytes_with_nul()
848850
.as_ptr() as *const libc::c_char
849851
}

c/tests/test.cc

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,14 @@ TEST(BasicTest, BasicTest) {
3131
ASSERT_NE(data_ptr, nullptr);
3232
EXPECT_GT(data_size, 0);
3333
EXPECT_EQ(strlen(reinterpret_cast<const char *>(data_ptr)), data_size);
34-
EXPECT_EQ(reinterpret_cast<const char *>(data_ptr),
35-
std::string("Error at plan: failed to decode Protobuf message: "
36-
"invalid wire type value: 7 (code 1001)\n"));
34+
EXPECT_EQ(
35+
reinterpret_cast<const char *>(data_ptr),
36+
std::string("Error at plan: failed to parse as substrait.Plan: "
37+
"failed to decode Protobuf message: "
38+
"invalid wire type value: 7 (code 1001) (code 1001)\n"
39+
"Error at plan: failed to parse as substrait.PlanVersion: "
40+
"failed to decode Protobuf message: "
41+
"invalid wire type value: 7 (code 1001) (code 1001)\n"));
3742

3843
// Free the buffer.
3944
substrait_validator_free_exported(data_ptr);

py/src/lib.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,14 +263,16 @@ fn substrait_validator(_py: Python, m: &PyModule) -> PyResult<()> {
263263
#[pyfn(m)]
264264
#[pyo3(name = "get_version")]
265265
fn get_version_py(py: Python) -> PyResult<PyObject> {
266-
Ok(substrait_validator::version().to_object(py))
266+
Ok(substrait_validator::version().to_string().to_object(py))
267267
}
268268

269269
/// Returns the version of Substrait that the validator was built against.
270270
#[pyfn(m)]
271271
#[pyo3(name = "get_substrait_version")]
272272
fn get_substrait_version_py(py: Python) -> PyResult<PyObject> {
273-
Ok(substrait_validator::substrait_version().to_object(py))
273+
Ok(substrait_validator::substrait_version()
274+
.to_string()
275+
.to_object(py))
274276
}
275277

276278
m.add_class::<Config>()?;

py/tests/data.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
BASIC_PLAN = """
44
{
5+
"version": {
6+
"minor": 1,
7+
"producer": "validator-test"
8+
},
59
"extensionUris": [],
610
"extensions": [],
711
"relations": [

py/tests/test_api.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,9 @@ def resolver(s):
124124
# Disable "not yet implemented" warnings.
125125
config.override_diagnostic_level(1, "info", "info")
126126

127+
# Disable versioning warnings.
128+
config.override_diagnostic_level(7, "info", "info")
129+
127130
# Disable missing root relation error, so we don't have to supply one.
128131
config.override_diagnostic_level(5001, "info", "info")
129132

@@ -136,12 +139,16 @@ def resolver(s):
136139

137140
sv.check_plan_valid(
138141
{
142+
"version": {
143+
"minor": 1,
144+
"producer": "validator-test",
145+
},
139146
"extensionUris": [
140147
{
141148
"extension_uri_anchor": 1,
142149
"uri": "test:hello",
143150
}
144-
]
151+
],
145152
},
146153
config,
147154
)
@@ -152,12 +159,16 @@ def resolver(s):
152159
):
153160
sv.check_plan_valid(
154161
{
162+
"version": {
163+
"minor": 1,
164+
"producer": "validator-test",
165+
},
155166
"extensionUris": [
156167
{
157168
"extension_uri_anchor": 1,
158169
"uri": "test:bye",
159170
}
160-
]
171+
],
161172
},
162173
config,
163174
)

rs/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ float-pretty-print = "0.1"
8585
base64 = "0.13"
8686
percent-encoding = "2.1"
8787

88+
# Used for representing and checking Substrait versions.
89+
semver = "1.0"
90+
8891
[build-dependencies]
8992

9093
# Used for generating Rust structs from the protobuf definitions.

rs/src/lib.rs

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,8 @@ pub mod input;
169169

170170
mod util;
171171

172+
use std::str::FromStr;
173+
172174
use strum::IntoEnumIterator;
173175

174176
// Aliases for common types used on the crate interface.
@@ -182,7 +184,7 @@ pub use output::parse_result::ParseResult;
182184
pub use output::parse_result::Validity;
183185

184186
/// Validates the given substrait.Plan message and returns the parse tree.
185-
pub fn parse<B: prost::bytes::Buf>(buffer: B, config: &Config) -> ParseResult {
187+
pub fn parse<B: prost::bytes::Buf + Clone>(buffer: B, config: &Config) -> ParseResult {
186188
parse::parse(buffer, config)
187189
}
188190

@@ -192,12 +194,31 @@ pub fn iter_diagnostics() -> impl Iterator<Item = Classification> {
192194
}
193195

194196
/// Returns the version of the validator.
195-
pub fn version() -> &'static str {
196-
env!("CARGO_PKG_VERSION")
197+
pub fn version() -> semver::Version {
198+
semver::Version::from_str(env!("CARGO_PKG_VERSION")).expect("invalid embedded crate version")
197199
}
198200

199201
/// Returns the version of Substrait that this version of the validator was
200202
/// built against.
201-
pub fn substrait_version() -> &'static str {
202-
include_str!("resources/substrait-version")
203+
pub fn substrait_version() -> semver::Version {
204+
semver::Version::from_str(include_str!("resources/substrait-version"))
205+
.expect("invalid embedded Substrait version")
206+
}
207+
208+
/// Returns the Substrait version requirement for plans to be known to be
209+
/// supported.
210+
pub fn substrait_version_req() -> semver::VersionReq {
211+
let version = substrait_version();
212+
if version.major == 0 {
213+
semver::VersionReq::parse(&format!("={}.{}", version.major, version.minor)).unwrap()
214+
} else {
215+
semver::VersionReq::parse(&format!("={}", version.major)).unwrap()
216+
}
217+
}
218+
219+
/// Returns the Substrait version requirement for plans to possibly be
220+
/// supported.
221+
pub fn substrait_version_req_loose() -> semver::VersionReq {
222+
let version = substrait_version();
223+
semver::VersionReq::parse(&format!("={}", version.major)).unwrap()
203224
}

rs/src/output/diagnostic.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,9 @@ pub enum Classification {
174174
#[strum(props(Description = "deprecation"))]
175175
Deprecation = 6,
176176

177+
#[strum(props(HiddenDescription = "versioning"))]
178+
Versioning = 7,
179+
177180
#[strum(props(HiddenDescription = "experimental"))]
178181
Experimental = 999,
179182

0 commit comments

Comments
 (0)