partiql_eval/
test_value.rs1use partiql_value::{EqualityValue, NullableEq, Value};
2
3use crate::eval::Evaluated;
4use partiql_extension_ion::decode::{IonDecoderBuilder, IonDecoderConfig};
5use partiql_extension_ion::Encoding;
6
7#[allow(dead_code)]
8#[derive(Debug, Ord, PartialOrd)]
9pub struct TestValue {
10 pub value: Value,
11}
12
13impl Eq for TestValue {}
14
15impl PartialEq for TestValue {
16 fn eq(&self, other: &Self) -> bool {
17 let wrap_value = EqualityValue::<'_, true, true, Value>;
19 NullableEq::eq(&wrap_value(&self.value), &wrap_value(&other.value)) == Value::Boolean(true)
20 }
21}
22
23impl From<Value> for TestValue {
24 fn from(value: Value) -> Self {
25 TestValue { value }
26 }
27}
28
29impl From<Evaluated> for TestValue {
30 fn from(value: Evaluated) -> Self {
31 value.result.into()
32 }
33}
34
35impl From<&str> for TestValue {
36 fn from(contents: &str) -> Self {
37 parse_test_value_str(contents).into()
38 }
39}
40
41fn parse_test_value_str(contents: &str) -> Value {
42 let reader = ion_rs_old::ReaderBuilder::new()
43 .build(contents)
44 .expect("reading contents");
45 let mut iter = IonDecoderBuilder::new(
46 IonDecoderConfig::default().with_mode(Encoding::PartiqlEncodedAsIon),
47 )
48 .build(reader)
49 .expect("building decoder");
50
51 let val = iter.next();
52
53 val.expect("test value to exist")
54 .expect("value decode to succeed")
55}
56
57#[cfg(test)]
58pub(crate) fn parse_partiql_value_str(contents: &str) -> Value {
59 use crate::env::basic::MapBindings;
60 use crate::eval::BasicContext;
61 use crate::plan::{EvaluationMode, EvaluatorPlanner};
62 use partiql_catalog::catalog::PartiqlCatalog;
63 use partiql_catalog::context::SystemContext;
64 use partiql_value::DateTime;
65 let catalog = PartiqlCatalog::default().to_shared_catalog();
66 let parsed = partiql_parser::Parser::default()
67 .parse(contents)
68 .expect("Expect successful parse");
69 let planner = partiql_logical_planner::LogicalPlanner::new(&catalog);
70 let logical = planner.lower(&parsed).expect("logical plan");
71 let evaluator = EvaluatorPlanner::new(EvaluationMode::Permissive, &catalog)
72 .compile(&logical)
73 .expect("Expect no plan error");
74 let sys = SystemContext {
75 now: DateTime::from_system_now_utc(),
76 };
77 let bindings = MapBindings::default();
78 let ctx = BasicContext::new(bindings, sys);
79 let value = evaluator.execute(&ctx).expect("evaluation to succeed");
80
81 value.result
82}
83
84#[cfg(test)]
85mod tests {
86 use super::parse_test_value_str;
87
88 use partiql_value::{bag, list, tuple, Value};
89
90 #[track_caller]
91 fn parse(test: &str, expected: Value) {
92 let val = parse_test_value_str(test);
93 assert_eq!(val, expected);
94 }
95
96 #[test]
97 fn simple() {
98 parse("null", Value::Null);
99 parse("$missing::null", Value::Missing);
100 parse("9", Value::Integer(9));
101 parse("true", Value::Boolean(true));
102 parse("false", Value::Boolean(false));
103 parse("\"str\"", Value::String(Box::new("str".into())));
104 }
105
106 #[test]
107 fn bag() {
108 let test = "$bag::[
109 {
110 f: 1,
111 d: 2e0,
112 s: 1
113 }
114 ]";
115 let expected = Value::from(bag![tuple![
116 ("f", 1),
117 ("d", Value::Real(2.0.into())),
118 ("s", 1)
119 ]]);
120 parse(test, expected);
121 }
122
123 #[test]
124 fn tuple() {
125 parse(
126 "{
127 sensor: 1,
128 reading: 42
129 }",
130 Value::Tuple(Box::new(tuple![("sensor", 1), ("reading", 42)])),
131 );
132 }
133
134 #[test]
135 fn tt2() {
136 parse(
137 "{
138 sensors: [
139 {
140 sensor: 1
141 },
142 {
143 sensor: 2
144 }
145 ],
146 logs: [
147 {
148 sensor: 1,
149 co: 4d-1
150 },
151 {
152 sensor: 1,
153 co: 2d-1
154 },
155 {
156 sensor: 2,
157 co: 3d-1
158 }
159 ]
160 }",
161 Value::Tuple(Box::new(tuple![
162 (
163 "sensors",
164 list![tuple![("sensor", 1)], tuple![("sensor", 2)]]
165 ),
166 (
167 "logs",
168 list![
169 tuple![("sensor", 1), ("co", rust_decimal::Decimal::new(4, 1))],
170 tuple![("sensor", 1), ("co", rust_decimal::Decimal::new(2, 1))],
171 tuple![("sensor", 2), ("co", rust_decimal::Decimal::new(3, 1))]
172 ]
173 )
174 ])),
175 );
176 }
177
178 #[test]
179 fn list() {
180 let test = "[
181 {
182 f: 1,
183 d: 2e0,
184 s: 1
185 }
186 ]";
187 let expected = Value::from(list![tuple![
188 ("f", 1),
189 ("d", Value::Real(2.0.into())),
190 ("s", 1)
191 ]]);
192 parse(test, expected);
193 }
194}