@@ -2,14 +2,16 @@ use itertools::Itertools;
2
2
use std:: collections:: HashMap ;
3
3
use std:: fmt:: Debug ;
4
4
5
+ use thiserror:: Error ;
6
+
5
7
use petgraph:: algo:: toposort;
6
8
use petgraph:: prelude:: StableGraph ;
7
9
use petgraph:: { Directed , Incoming , Outgoing } ;
8
10
9
11
use partiql_value:: Value :: { Boolean , Missing , Null } ;
10
12
use partiql_value:: {
11
- partiql_bag, Bag , BinaryAnd , BinaryOr , BindingsName , NullableEq , NullableOrd , Tuple , UnaryPlus ,
12
- Value ,
13
+ partiql_bag, Bag , BinaryAnd , BinaryOr , BindingsName , List , NullableEq , NullableOrd , Tuple ,
14
+ UnaryPlus , Value ,
13
15
} ;
14
16
15
17
use crate :: env:: basic:: MapBindings ;
@@ -40,7 +42,9 @@ pub struct EvalErr {
40
42
pub errors : Vec < EvaluationError > ,
41
43
}
42
44
45
+ #[ derive( Error , Debug ) ]
43
46
pub enum EvaluationError {
47
+ #[ error( "Evaluation Error: malformed evaluation plan detected `{}`" , _0) ]
44
48
InvalidEvaluationPlan ( String ) ,
45
49
}
46
50
@@ -231,7 +235,10 @@ impl Evaluable for EvalProject {
231
235
. as_ref ( )
232
236
. expect ( "Error in retrieving input value" )
233
237
. clone ( ) ;
234
- let mut value = partiql_bag ! [ ] ;
238
+
239
+ let ordered = & input_value. is_ordered ( ) ;
240
+ let mut value = vec ! [ ] ;
241
+
235
242
for v in input_value. into_iter ( ) {
236
243
let v_as_tuple = v. coerce_to_tuple ( ) ;
237
244
let mut t = Tuple :: new ( ) ;
@@ -242,14 +249,131 @@ impl Evaluable for EvalProject {
242
249
value. push ( Value :: Tuple ( Box :: new ( t) ) ) ;
243
250
}
244
251
245
- self . output = Some ( Value :: Bag ( Box :: new ( value) ) ) ;
252
+ self . output = match ordered {
253
+ true => Some ( Value :: List ( Box :: new ( List :: from ( value) ) ) ) ,
254
+ false => Some ( Value :: Bag ( Box :: new ( Bag :: from ( value) ) ) ) ,
255
+ } ;
256
+
257
+ self . output . clone ( )
258
+ }
259
+
260
+ fn update_input ( & mut self , input : & Value ) {
261
+ self . input = Some ( input. clone ( ) ) ;
262
+ }
263
+ }
264
+
265
+ #[ derive( Debug ) ]
266
+ pub struct EvalProjectValue {
267
+ pub expr : Box < dyn EvalExpr > ,
268
+ pub input : Option < Value > ,
269
+ pub output : Option < Value > ,
270
+ }
271
+
272
+ impl EvalProjectValue {
273
+ pub fn new ( expr : Box < dyn EvalExpr > ) -> Self {
274
+ EvalProjectValue {
275
+ expr,
276
+ input : None ,
277
+ output : None ,
278
+ }
279
+ }
280
+ }
281
+
282
+ impl Evaluable for EvalProjectValue {
283
+ fn evaluate ( & mut self , ctx : & dyn EvalContext ) -> Option < Value > {
284
+ let input_value = self
285
+ . input
286
+ . as_ref ( )
287
+ . expect ( "Error in retrieving input value" )
288
+ . clone ( ) ;
289
+
290
+ let ordered = & input_value. is_ordered ( ) ;
291
+ let mut value = vec ! [ ] ;
292
+
293
+ for v in input_value. into_iter ( ) {
294
+ let out = v. coerce_to_tuple ( ) ;
295
+ let evaluated = self . expr . evaluate ( & out, ctx) ;
296
+ value. push ( evaluated) ;
297
+ }
298
+
299
+ self . output = match ordered {
300
+ true => Some ( Value :: List ( Box :: new ( List :: from ( value) ) ) ) ,
301
+ false => Some ( Value :: Bag ( Box :: new ( Bag :: from ( value) ) ) ) ,
302
+ } ;
303
+
246
304
self . output . clone ( )
247
305
}
306
+
248
307
fn update_input ( & mut self , input : & Value ) {
249
308
self . input = Some ( input. clone ( ) ) ;
250
309
}
251
310
}
252
311
312
+ #[ derive( Debug ) ]
313
+ pub struct EvalTupleExpr {
314
+ pub attrs : Vec < Box < dyn EvalExpr > > ,
315
+ pub vals : Vec < Box < dyn EvalExpr > > ,
316
+ }
317
+
318
+ impl EvalExpr for EvalTupleExpr {
319
+ fn evaluate ( & self , bindings : & Tuple , ctx : & dyn EvalContext ) -> Value {
320
+ let mut t = Tuple :: new ( ) ;
321
+ self . attrs
322
+ . iter ( )
323
+ . filter_map ( |attr| {
324
+ let expr = attr. evaluate ( bindings, ctx) ;
325
+ match expr {
326
+ Value :: String ( s) => Some ( * s) ,
327
+ _ => None ,
328
+ }
329
+ } )
330
+ . zip ( self . vals . iter ( ) )
331
+ . for_each ( |( k, v) | {
332
+ let evaluated = v. evaluate ( bindings, ctx) ;
333
+ // Spec. section 6.1.4
334
+ if evaluated != Value :: Missing {
335
+ t. insert ( k. as_str ( ) , evaluated. clone ( ) ) ;
336
+ }
337
+ } ) ;
338
+
339
+ Value :: Tuple ( Box :: new ( t) )
340
+ }
341
+ }
342
+
343
+ #[ derive( Debug ) ]
344
+ pub struct EvalListExpr {
345
+ pub elements : Vec < Box < dyn EvalExpr > > ,
346
+ }
347
+
348
+ impl EvalExpr for EvalListExpr {
349
+ fn evaluate ( & self , bindings : & Tuple , ctx : & dyn EvalContext ) -> Value {
350
+ let evaluated_elements: Vec < Value > = self
351
+ . elements
352
+ . iter ( )
353
+ . map ( |val| val. evaluate ( bindings, ctx) )
354
+ . collect ( ) ;
355
+
356
+ Value :: List ( Box :: new ( List :: from ( evaluated_elements) ) )
357
+ }
358
+ }
359
+
360
+ #[ derive( Debug ) ]
361
+ pub struct EvalBagExpr {
362
+ pub elements : Vec < Box < dyn EvalExpr > > ,
363
+ }
364
+
365
+ impl EvalExpr for EvalBagExpr {
366
+ fn evaluate ( & self , bindings : & Tuple , ctx : & dyn EvalContext ) -> Value {
367
+ let evaluated_elements: Vec < Value > = self
368
+ . elements
369
+ . iter ( )
370
+ . map ( |val| val. evaluate ( bindings, ctx) )
371
+ . collect ( ) ;
372
+
373
+ Value :: Bag ( Box :: new ( Bag :: from ( evaluated_elements) ) )
374
+ }
375
+ }
376
+
253
377
#[ derive( Debug ) ]
254
378
pub enum EvalPathComponent {
255
379
Key ( String ) ,
0 commit comments