Skip to content

Commit 29731a8

Browse files
authored
chore: prepare 0.0.11 release (#65)
Bump substrait to 0.20.0
1 parent f86bb1d commit 29731a8

File tree

17 files changed

+132
-58
lines changed

17 files changed

+132
-58
lines changed

Cargo.lock

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

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ older version. Refer to the table below for the version compatibility matrix.
2727

2828
| Substrait... | ... is supported by validator ... |
2929
| -------------- | ------------------------------------ |
30+
| 0.20.x | 0.0.11 (current version) |
3031
| 0.19.x | 0.0.10 |
3132
| 0.18.x | 0.0.9 |
3233
| 0.9.x - 0.17.x | 0.0.8 |

c/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "substrait-validator-c"
3-
version = "0.0.10"
3+
version = "0.0.11"
44
edition = "2021"
55
license = "Apache-2.0"
66

@@ -12,7 +12,7 @@ doc = false
1212
cbindgen = "0.20.0"
1313

1414
[dependencies]
15-
substrait-validator = { path = "../rs", version = "0.0.10" }
15+
substrait-validator = { path = "../rs", version = "0.0.11" }
1616
libc = "0.2"
1717
thiserror = "1.0"
1818
once_cell = "1.9"

ci/version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.0.10
1+
0.0.11

derive/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ description = "Procedural macros for substrait-validator"
44
homepage = "https://substrait.io/"
55
repository = "https://github.com/substrait-io/substrait"
66
readme = "README.md"
7-
version = "0.0.10"
7+
version = "0.0.11"
88
edition = "2021"
99
license = "Apache-2.0"
1010

py/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "substrait-validator-py"
3-
version = "0.0.10"
3+
version = "0.0.11"
44
edition = "2018"
55
license = "Apache-2.0"
66
include = [
@@ -29,7 +29,7 @@ name = "substrait_validator"
2929
doc = false
3030

3131
[dependencies]
32-
substrait-validator = { path = "../rs", version = "0.0.10" }
32+
substrait-validator = { path = "../rs", version = "0.0.11" }
3333
pyo3 = { version = "0.17.3", features = ["extension-module"] }
3434

3535
[build-dependencies]

py/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ backend-path = ["."]
55

66
[project]
77
name = "substrait-validator"
8-
version = "0.0.10"
8+
version = "0.0.11"
99
description = "Validator for Substrait query plans"
1010
readme = "README.md"
1111
license = { file = "LICENSE" }

rs/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ description = "Substrait validator"
44
homepage = "https://substrait.io/"
55
repository = "https://github.com/substrait-io/substrait"
66
readme = "README.md"
7-
version = "0.0.10"
7+
version = "0.0.11"
88
edition = "2021"
99
license = "Apache-2.0"
1010
include = ["src", "build.rs", "README.md"]
@@ -24,7 +24,7 @@ prost-types = "0.10"
2424

2525
# Prost doesn't generate any introspection stuff, so we hack that stuff in with
2626
# our own procedural macros.
27-
substrait-validator-derive = { path = "../derive", version = "0.0.10" }
27+
substrait-validator-derive = { path = "../derive", version = "0.0.11" }
2828

2929
# Google/protobuf has a funny idea about case conventions (it converts them all
3030
# over the place) and prost remaps to Rust's conventions to boot. So, to

rs/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ plans.
66

77
```
88
[dependencies]
9-
substrait-validator = "0.0.10"
9+
substrait-validator = "0.0.11"
1010
```
1111

1212
YAML file resolution
@@ -20,7 +20,7 @@ dependency:
2020

2121
```
2222
[dependencies]
23-
substrait-validator = { version = "0.0.10", features = ["curl"] }
23+
substrait-validator = { version = "0.0.11", features = ["curl"] }
2424
```
2525

2626
This adds the `substrait_validator::Config::add_curl_yaml_uri_resolver()`

rs/src/output/extension/simple/function.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ pub struct Definition {
2525
/// The expected arguments of the function.
2626
pub arguments: Vec<ArgumentSlot>,
2727

28+
/// The options of the function.
29+
pub options: HashMap<OptionName, OptionValues>,
30+
2831
/// Specifies the variadic behavior of the last argument slot, if any.
2932
pub variadic: VariadicBehavior,
3033

@@ -136,6 +139,20 @@ pub struct EnumerationArgumentSlot {
136139
pub required: bool,
137140
}
138141

142+
/// Definition of a function option name.
143+
#[derive(Clone, Debug)]
144+
pub struct OptionName {
145+
/// A human-readable name for this option.
146+
pub name: String,
147+
}
148+
149+
/// Definition of a valid options for a function option.
150+
#[derive(Clone, Debug)]
151+
pub struct OptionValues {
152+
/// A list of valid strings for this option.
153+
pub values: Vec<String>,
154+
}
155+
139156
/// Definition of the variadic behavior of the last argument slot.
140157
#[derive(Clone, Debug)]
141158
pub struct VariadicBehavior {

rs/src/parse/expressions/functions.rs

Lines changed: 77 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ pub enum FunctionArgument {
4141
/// Used for type arguments.
4242
Type(data::Type),
4343

44-
/// Used for enum option arguments.
45-
Enum(Option<String>),
44+
/// Used for enum arguments.
45+
Enum(String),
4646
}
4747

4848
impl Default for FunctionArgument {
@@ -61,8 +61,7 @@ impl Describe for FunctionArgument {
6161
FunctionArgument::Unresolved => write!(f, "!"),
6262
FunctionArgument::Value(_, e) => e.describe(f, limit),
6363
FunctionArgument::Type(t) => t.describe(f, limit),
64-
FunctionArgument::Enum(Some(s)) => util::string::describe_identifier(f, s, limit),
65-
FunctionArgument::Enum(None) => write!(f, "-"),
64+
FunctionArgument::Enum(s) => util::string::describe_identifier(f, s, limit),
6665
}
6766
}
6867
}
@@ -73,6 +72,16 @@ impl std::fmt::Display for FunctionArgument {
7372
}
7473
}
7574

75+
/// An optional function argument. Typically used for specifying behavior in
76+
/// invalid or corner cases.
77+
#[derive(Clone, Debug)]
78+
pub struct FunctionOption {
79+
/// Name of the option to set.
80+
pub name: String,
81+
/// List of behavior options allowed by the producer.
82+
pub preference: Vec<String>,
83+
}
84+
7685
/// Information about the context in which a function is being called.
7786
#[derive(Clone, Debug)]
7887
pub struct FunctionContext {
@@ -82,6 +91,9 @@ pub struct FunctionContext {
8291
/// The list of arguments bound to the function.
8392
pub arguments: Vec<FunctionArgument>,
8493

94+
/// The list of optional function arguments.
95+
pub options: Vec<FunctionOption>,
96+
8597
/// If known, the expected return type of the function. If not known this
8698
/// can just be set to unresolved.
8799
pub return_type: data::Type,
@@ -101,17 +113,16 @@ pub struct FunctionBinding {
101113
}
102114

103115
impl FunctionBinding {
104-
/// Try to bind one of the provided function implementations to the
105-
/// provided function context.
116+
/// Try to bind one of the provided function implementations to the provided
117+
/// function context.
106118
///
107119
/// This is purely a validator thing. For valid plans, there should only
108120
/// ever be one implementation after name resolution, and the return type
109-
/// should already have been specified. Much more intelligence was thrown
110-
/// in here just to help people find and correct mistakes efficiently.
111-
/// Common misconceptions and mistakes, like using the simple function name
112-
/// vs. the compound name, not specifying optional arguments, or not
113-
/// specifying the (correct) return type should yield more than just a
114-
/// generic error message here!
121+
/// should already have been specified. Much more intelligence was thrown in
122+
/// here just to help people find and correct mistakes efficiently. Common
123+
/// misconceptions and mistakes, like using the simple function name vs. the
124+
/// compound name. or not specifying the (correct) return type should yield
125+
/// more than just a generic error message here!
115126
pub fn new(
116127
functions: Option<&extension::simple::function::ResolutionResult>,
117128
function_context: &FunctionContext,
@@ -154,36 +165,13 @@ impl FunctionBinding {
154165
}
155166
}
156167

157-
/// Parse an enum option argument type.
158-
fn parse_enum_type(
159-
x: &substrait::function_argument::r#enum::EnumKind,
160-
_y: &mut context::Context,
161-
) -> diagnostic::Result<Option<String>> {
162-
match x {
163-
substrait::function_argument::r#enum::EnumKind::Specified(x) => Ok(Some(x.clone())),
164-
substrait::function_argument::r#enum::EnumKind::Unspecified(_) => Ok(None),
165-
}
166-
}
167-
168-
/// Parse an enum option argument.
169-
fn parse_enum(
170-
x: &substrait::function_argument::Enum,
171-
y: &mut context::Context,
172-
) -> diagnostic::Result<Option<String>> {
173-
Ok(proto_required_field!(x, y, enum_kind, parse_enum_type)
174-
.1
175-
.flatten())
176-
}
177-
178168
/// Parse a 0.3.0+ function argument type.
179169
fn parse_function_argument_type(
180170
x: &substrait::function_argument::ArgType,
181171
y: &mut context::Context,
182172
) -> diagnostic::Result<FunctionArgument> {
183173
match x {
184-
substrait::function_argument::ArgType::Enum(x) => {
185-
Ok(FunctionArgument::Enum(parse_enum(x, y)?))
186-
}
174+
substrait::function_argument::ArgType::Enum(x) => Ok(FunctionArgument::Enum(x.to_string())),
187175
substrait::function_argument::ArgType::Type(x) => {
188176
types::parse_type(x, y)?;
189177
Ok(FunctionArgument::Type(y.data_type()))
@@ -207,14 +195,48 @@ fn parse_function_argument(
207195
)
208196
}
209197

198+
fn parse_function_option(
199+
x: &substrait::FunctionOption,
200+
y: &mut context::Context,
201+
) -> diagnostic::Result<FunctionOption> {
202+
proto_primitive_field!(x, y, name);
203+
proto_required_repeated_field!(x, y, preference);
204+
205+
if x.preference.is_empty() {
206+
let err = cause!(IllegalValue, "at least one option must be specified");
207+
diagnostic!(y, Error, err.clone());
208+
comment!(
209+
y,
210+
"To leave an option unspecified, simply don't add an entry to `options`"
211+
);
212+
Err(err)
213+
} else {
214+
Ok(FunctionOption {
215+
name: x.name.clone(),
216+
preference: x.preference.clone(),
217+
})
218+
}
219+
}
220+
210221
/// Parse a pre-0.3.0 function argument expression.
211222
fn parse_legacy_function_argument(
212223
x: &substrait::Expression,
213224
y: &mut context::Context,
214225
) -> diagnostic::Result<FunctionArgument> {
215226
expressions::parse_legacy_function_argument(x, y).map(|x| match x {
216227
expressions::ExpressionOrEnum::Value(x) => FunctionArgument::Value(y.data_type(), x),
217-
expressions::ExpressionOrEnum::Enum(x) => FunctionArgument::Enum(x),
228+
expressions::ExpressionOrEnum::Enum(x) => match x {
229+
Some(x) => FunctionArgument::Enum(x),
230+
None => {
231+
diagnostic!(
232+
y,
233+
Error,
234+
Deprecation,
235+
"support for optional enum arguments was removed in Substrait 0.20.0 (#342)"
236+
);
237+
FunctionArgument::Unresolved
238+
}
239+
},
218240
})
219241
}
220242

@@ -279,6 +301,11 @@ pub fn parse_scalar_function(
279301
.into_iter()
280302
.map(|x| x.unwrap_or_default())
281303
.collect();
304+
let options = proto_repeated_field!(x, y, options, parse_function_option)
305+
.1
306+
.into_iter()
307+
.flatten()
308+
.collect();
282309
let return_type = proto_required_field!(x, y, output_type, types::parse_type)
283310
.0
284311
.data_type();
@@ -288,6 +315,7 @@ pub fn parse_scalar_function(
288315
let context = FunctionContext {
289316
function_type: FunctionType::Scalar,
290317
arguments,
318+
options,
291319
return_type,
292320
};
293321
let binding = FunctionBinding::new(functions.as_ref(), &context, y);
@@ -341,6 +369,11 @@ pub fn parse_window_function(
341369
.into_iter()
342370
.map(|x| x.unwrap_or_default())
343371
.collect();
372+
let options = proto_repeated_field!(x, y, options, parse_function_option)
373+
.1
374+
.into_iter()
375+
.flatten()
376+
.collect();
344377
let return_type = proto_required_field!(x, y, output_type, types::parse_type)
345378
.0
346379
.data_type();
@@ -359,6 +392,7 @@ pub fn parse_window_function(
359392
let context = FunctionContext {
360393
function_type: FunctionType::Window,
361394
arguments,
395+
options,
362396
return_type,
363397
};
364398
let binding = FunctionBinding::new(functions.as_ref(), &context, y);
@@ -395,6 +429,11 @@ pub fn parse_aggregate_function(
395429
.into_iter()
396430
.map(|x| x.unwrap_or_default())
397431
.collect();
432+
let options = proto_repeated_field!(x, y, options, parse_function_option)
433+
.1
434+
.into_iter()
435+
.flatten()
436+
.collect();
398437
let return_type = proto_required_field!(x, y, output_type, types::parse_type)
399438
.0
400439
.data_type();
@@ -416,6 +455,7 @@ pub fn parse_aggregate_function(
416455
let context = FunctionContext {
417456
function_type: FunctionType::Aggregate,
418457
arguments,
458+
options,
419459
return_type,
420460
};
421461
let binding = FunctionBinding::new(functions.as_ref(), &context, y);

0 commit comments

Comments
 (0)