sql_json_path/
eval.rs

1// Copyright 2023 RisingWave Labs
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use serde_json::Number;
16
17use crate::{
18    ast::*,
19    json::{ArrayRef, Cow, Json, JsonRef, ObjectRef},
20};
21
22pub type Result<T> = std::result::Result<T, Error>;
23
24/// The error type returned when evaluating a JSON path.
25#[non_exhaustive]
26#[derive(Debug, thiserror::Error, PartialEq, Eq)]
27pub enum Error {
28    // structural errors
29    #[error("JSON object does not contain key \"{0}\"")]
30    NoKey(Box<str>),
31    #[error("jsonpath array accessor can only be applied to an array")]
32    ArrayAccess,
33    #[error("jsonpath wildcard array accessor can only be applied to an array")]
34    WildcardArrayAccess,
35    #[error("jsonpath member accessor can only be applied to an object")]
36    MemberAccess,
37    #[error("jsonpath wildcard member accessor can only be applied to an object")]
38    WildcardMemberAccess,
39    #[error("jsonpath array subscript is out of bounds")]
40    ArrayIndexOutOfBounds,
41
42    #[error("jsonpath array subscript is out of integer range")]
43    ArrayIndexOutOfRange,
44    #[error("jsonpath array subscript is not a single numeric value")]
45    ArrayIndexNotNumeric,
46    #[error("could not find jsonpath variable \"{0}\"")]
47    NoVariable(Box<str>),
48    #[error("\"vars\" argument is not an object")]
49    VarsNotObject,
50    #[error("operand of unary jsonpath operator {0} is not a numeric value")]
51    UnaryOperandNotNumeric(UnaryOp),
52    #[error("left operand of jsonpath operator {0} is not a single numeric value")]
53    LeftOperandNotNumeric(BinaryOp),
54    #[error("right operand of jsonpath operator {0} is not a single numeric value")]
55    RightOperandNotNumeric(BinaryOp),
56    #[error("jsonpath item method .{0}() can only be applied to a numeric value")]
57    MethodNotNumeric(&'static str),
58    #[error("jsonpath item method .size() can only be applied to an array")]
59    SizeNotArray,
60    #[error("jsonpath item method .double() can only be applied to a string or numeric value")]
61    DoubleTypeError,
62    #[error("numeric argument of jsonpath item method .double() is out of range for type double precision")]
63    DoubleOutOfRange,
64    #[error("string argument of jsonpath item method .double() is not a valid representation of a double precision number")]
65    InvalidDouble,
66    #[error("jsonpath item method .keyvalue() can only be applied to an object")]
67    KeyValueNotObject,
68    #[error("division by zero")]
69    DivisionByZero,
70    #[error("single boolean result is expected")]
71    ExpectSingleBoolean,
72}
73
74impl Error {
75    /// Returns true if the error can be suppressed.
76    pub const fn can_silent(&self) -> bool {
77        // missing object field or array element
78        // unexpected JSON item type
79        // datetime and numeric errors.
80        !matches!(self, Self::NoVariable(_))
81    }
82
83    // A structural error is an attempt to access a non-existent member of an object or element of an array.
84    pub const fn is_structural(&self) -> bool {
85        matches!(
86            self,
87            Self::NoKey(_)
88                | Self::ArrayAccess
89                | Self::WildcardArrayAccess
90                | Self::MemberAccess
91                | Self::WildcardMemberAccess
92                | Self::ArrayIndexOutOfBounds
93        )
94    }
95}
96
97/// Truth value used in SQL/JSON path predicates.
98#[derive(Debug, Clone, Copy, PartialEq, Eq)]
99enum Truth {
100    True,
101    False,
102    Unknown,
103}
104
105impl From<bool> for Truth {
106    fn from(b: bool) -> Self {
107        if b {
108            Truth::True
109        } else {
110            Truth::False
111        }
112    }
113}
114
115impl Truth {
116    /// Returns true if the value is true.
117    fn is_true(self) -> bool {
118        matches!(self, Truth::True)
119    }
120
121    /// Returns true if the value is false.
122    #[allow(unused)]
123    fn is_false(self) -> bool {
124        matches!(self, Truth::False)
125    }
126
127    /// Returns true if the value is unknown.
128    fn is_unknown(self) -> bool {
129        matches!(self, Truth::Unknown)
130    }
131
132    /// AND operation.
133    fn and(self, other: Self) -> Self {
134        match (self, other) {
135            (Truth::True, Truth::True) => Truth::True,
136            (Truth::False, _) | (_, Truth::False) => Truth::False,
137            _ => Truth::Unknown,
138        }
139    }
140
141    /// OR operation.
142    fn or(self, other: Self) -> Self {
143        match (self, other) {
144            (Truth::True, _) | (_, Truth::True) => Truth::True,
145            (Truth::False, Truth::False) => Truth::False,
146            _ => Truth::Unknown,
147        }
148    }
149
150    /// NOT operation.
151    fn not(self) -> Self {
152        match self {
153            Truth::True => Truth::False,
154            Truth::False => Truth::True,
155            Truth::Unknown => Truth::Unknown,
156        }
157    }
158
159    /// Merge two predicate results.
160    fn merge(self, other: Self) -> Self {
161        match (self, other) {
162            (Truth::Unknown, _) | (_, Truth::Unknown) => Truth::Unknown,
163            (Truth::True, _) | (_, Truth::True) => Truth::True,
164            (Truth::False, Truth::False) => Truth::False,
165        }
166    }
167
168    /// Converts to JSON value.
169    fn to_json<T: Json>(self) -> T {
170        match self {
171            Truth::True => T::bool(true),
172            Truth::False => T::bool(false),
173            Truth::Unknown => T::null(),
174        }
175    }
176}
177
178impl JsonPath {
179    /// Evaluate the JSON path against the given JSON value.
180    pub fn query<'a, T: JsonRef<'a>>(&self, value: T) -> Result<Vec<Cow<'a, T::Owned>>> {
181        Evaluator {
182            root: value,
183            current: value,
184            vars: T::null(),
185            array: T::null(),
186            mode: self.mode,
187            first: false,
188        }
189        .eval_expr_or_predicate(&self.expr)
190    }
191
192    /// Evaluate the JSON path against the given JSON value with variables.
193    pub fn query_with_vars<'a, T: JsonRef<'a>>(
194        &self,
195        value: T,
196        vars: T,
197    ) -> Result<Vec<Cow<'a, T::Owned>>> {
198        if !vars.is_object() {
199            return Err(Error::VarsNotObject);
200        }
201        Evaluator {
202            root: value,
203            current: value,
204            vars,
205            array: T::null(),
206            mode: self.mode,
207            first: false,
208        }
209        .eval_expr_or_predicate(&self.expr)
210    }
211
212    /// Evaluate the JSON path against the given JSON value.
213    pub fn query_first<'a, T: JsonRef<'a>>(&self, value: T) -> Result<Option<Cow<'a, T::Owned>>> {
214        Evaluator {
215            root: value,
216            current: value,
217            vars: T::null(),
218            array: T::null(),
219            mode: self.mode,
220            first: true,
221        }
222        .eval_expr_or_predicate(&self.expr)
223        .map(|set| set.into_iter().next())
224    }
225
226    /// Evaluate the JSON path against the given JSON value with variables.
227    pub fn query_first_with_vars<'a, T: JsonRef<'a>>(
228        &self,
229        value: T,
230        vars: T,
231    ) -> Result<Option<Cow<'a, T::Owned>>> {
232        if !vars.is_object() {
233            return Err(Error::VarsNotObject);
234        }
235        Evaluator {
236            root: value,
237            current: value,
238            vars,
239            array: T::null(),
240            mode: self.mode,
241            first: true,
242        }
243        .eval_expr_or_predicate(&self.expr)
244        .map(|set| set.into_iter().next())
245    }
246
247    /// Checks whether the JSON path returns any item for the specified JSON value.
248    pub fn exists<'a, T: JsonRef<'a>>(&self, value: T) -> Result<bool> {
249        self.query_first(value).map(|v| v.is_some())
250    }
251
252    /// Checks whether the JSON path returns any item for the specified JSON value,
253    /// with variables.
254    pub fn exists_with_vars<'a, T: JsonRef<'a>>(&self, value: T, vars: T) -> Result<bool> {
255        self.query_first_with_vars(value, vars).map(|v| v.is_some())
256    }
257}
258
259/// Evaluation context.
260#[derive(Debug, Clone, Copy)]
261struct Evaluator<'a, T: Json + 'a> {
262    /// The current value referenced by `@`.
263    current: T::Borrowed<'a>,
264    /// The root value referenced by `$`.
265    root: T::Borrowed<'a>,
266    /// The innermost array value referenced by `last`.
267    array: T::Borrowed<'a>,
268    /// An object containing the variables referenced by `$var`.
269    vars: T::Borrowed<'a>,
270    /// The path mode.
271    /// If the query is in lax mode, then errors are ignored and the result is empty or unknown.
272    mode: Mode,
273    /// Only return the first result.
274    first: bool,
275}
276
277/// Unwrap the result or return an empty result if the evaluator is in lax mode.
278macro_rules! lax {
279    // for `Option`
280    ($self:expr, $expr:expr, $err:expr) => {
281        match $expr {
282            Some(x) => x,
283            None if $self.is_lax() => return Ok(vec![]),
284            None => return Err($err),
285        }
286    };
287    // for `Option`
288    ($self:expr, $expr:expr, $err:expr; continue) => {
289        match $expr {
290            Some(x) => x,
291            None if $self.is_lax() => continue,
292            None => return Err($err),
293        }
294    };
295    // for `Option`
296    ($self:expr, $expr:expr, $err:expr; break) => {
297        match $expr {
298            Some(x) => x,
299            None if $self.is_lax() => break,
300            None => return Err($err),
301        }
302    };
303    // for `Result` in predicate
304    ($self:expr, $expr:expr) => {
305        match $expr {
306            Ok(x) => x,
307            Err(e @ Error::NoVariable(_)) => return Err(e),
308            Err(_) => return Ok(Truth::Unknown),
309        }
310    };
311}
312
313impl<'a, T: Json> Evaluator<'a, T> {
314    /// Returns true if the evaluator is in lax mode.
315    fn is_lax(&self) -> bool {
316        matches!(self.mode, Mode::Lax)
317    }
318
319    /// Returns true if the path engine is permitted to stop evaluation early on the first success.
320    fn is_first(&self) -> bool {
321        self.first && self.is_lax()
322    }
323
324    /// Creates a new evaluator with the given current value.
325    fn with_current<'b>(&self, current: T::Borrowed<'b>) -> Evaluator<'b, T>
326    where
327        'a: 'b,
328    {
329        Evaluator {
330            current,
331            root: T::borrow(self.root),
332            vars: T::borrow(self.vars),
333            array: T::borrow(self.array),
334            mode: self.mode,
335            first: self.first,
336        }
337    }
338
339    fn all(&self) -> Self {
340        Evaluator {
341            first: false,
342            ..*self
343        }
344    }
345
346    fn first(&self) -> Self {
347        Evaluator {
348            first: true,
349            ..*self
350        }
351    }
352
353    /// Returns the value of the given variable.
354    fn get_variable(&self, name: &str) -> Result<T::Borrowed<'a>> {
355        self.vars
356            .as_object()
357            // no `vars` input
358            .ok_or_else(|| Error::NoVariable(name.into()))?
359            .get(name)
360            .ok_or_else(|| Error::NoVariable(name.into()))
361    }
362
363    /// Evaluates the expression or predicate.
364    fn eval_expr_or_predicate(&self, expr: &ExprOrPredicate) -> Result<Vec<Cow<'a, T>>> {
365        match expr {
366            ExprOrPredicate::Expr(expr) => self.eval_expr(expr),
367            ExprOrPredicate::Pred(pred) => self
368                .eval_predicate(pred)
369                .map(|t| vec![Cow::Owned(t.to_json())]),
370        }
371    }
372
373    /// Evaluates the predicate.
374    fn eval_predicate(&self, pred: &Predicate) -> Result<Truth> {
375        match pred {
376            Predicate::Compare(op, left, right) => {
377                let left = lax!(self, self.all().eval_expr(left));
378                let right = lax!(self, self.all().eval_expr(right));
379
380                let mut result = Truth::False;
381                // The cross product of these SQL/JSON sequences is formed.
382                // Each SQL/JSON item in one SQL/JSON sequence is compared to each item in the other SQL/JSON sequence.
383                'product: for r in right.iter() {
384                    for l in left.iter() {
385                        let res = eval_compare::<T>(*op, l.as_ref(), r.as_ref());
386                        result = result.merge(res);
387                        // The predicate is Unknown if there any pair of SQL/JSON items in the cross product is not comparable.
388                        // the predicate is True if any pair is comparable and satisfies the comparison operator.
389                        if res.is_unknown() || res.is_true() && self.is_lax() {
390                            // In lax mode, the path engine is permitted to stop evaluation early if it detects either an error or a success.
391                            break 'product;
392                        }
393                        // In strict mode, the path engine must test all comparisons in the cross product.
394                    }
395                }
396                Ok(result)
397            }
398            Predicate::Exists(expr) => {
399                let set = lax!(self, self.first().eval_expr(expr));
400                // If the result of the path expression is an empty SQL/JSON sequence, then result is False.
401                // Otherwise, result is True.
402                Ok(Truth::from(!set.is_empty()))
403            }
404            Predicate::And(left, right) => {
405                let left = self.eval_predicate(left)?;
406                let right = self.eval_predicate(right)?;
407                Ok(left.and(right))
408            }
409            Predicate::Or(left, right) => {
410                let left = self.eval_predicate(left)?;
411                let right = self.eval_predicate(right)?;
412                Ok(left.or(right))
413            }
414            Predicate::Not(inner) => {
415                let inner = self.eval_predicate(inner)?;
416                Ok(inner.not())
417            }
418            Predicate::IsUnknown(inner) => {
419                let inner = self.eval_predicate(inner)?;
420                Ok(Truth::from(inner.is_unknown()))
421            }
422            Predicate::StartsWith(expr, prefix) => {
423                let set = lax!(self, self.all().eval_expr(expr));
424                let prefix = self.eval_value(prefix)?;
425                let prefix = prefix.as_ref().as_str().unwrap();
426                let mut result = Truth::False;
427                for v in set {
428                    let res = match v.as_ref().as_str() {
429                        Some(s) => s.starts_with(prefix).into(),
430                        None => Truth::Unknown,
431                    };
432                    result = result.merge(res);
433                    if result.is_unknown() || result.is_true() && self.is_lax() {
434                        break;
435                    }
436                }
437                Ok(result)
438            }
439            Predicate::LikeRegex(expr, regex) => {
440                let set = lax!(self, self.all().eval_expr(expr));
441                let mut result = Truth::False;
442                for v in set {
443                    let res = match v.as_ref().as_str() {
444                        Some(s) => regex.is_match(s).into(),
445                        None => Truth::Unknown,
446                    };
447                    result = result.merge(res);
448                    if result.is_unknown() || result.is_true() && self.is_lax() {
449                        break;
450                    }
451                }
452                Ok(result)
453            }
454        }
455    }
456
457    /// Evaluates the expression.
458    fn eval_expr(&self, expr: &Expr) -> Result<Vec<Cow<'a, T>>> {
459        match expr {
460            Expr::PathPrimary(primary) => self.eval_path_primary(primary),
461            Expr::Accessor(base, op) => {
462                let set = self.all().eval_expr(base)?;
463                let mut new_set = vec![];
464                for v in &set {
465                    match v {
466                        Cow::Owned(v) => {
467                            let sset = self.with_current(v.as_ref()).eval_accessor_op(op)?;
468                            new_set.extend(
469                                // the returned set requires lifetime 'a,
470                                // however, elements in `sset` only have lifetime 'b < 'v = 'set < 'a
471                                // therefore, we need to convert them to owned values
472                                sset.into_iter().map(|cow| Cow::Owned(cow.into_owned())),
473                            )
474                        }
475                        Cow::Borrowed(v) => {
476                            new_set.extend(self.with_current(*v).eval_accessor_op(op)?);
477                        }
478                    }
479                    if self.is_first() && !new_set.is_empty() {
480                        break;
481                    }
482                }
483                Ok(new_set)
484            }
485            Expr::UnaryOp(op, expr) => {
486                let set = self.eval_expr(expr)?;
487                let mut new_set = Vec::with_capacity(set.len());
488                for v in set {
489                    let v = v.as_ref();
490                    if v.is_array() && self.is_lax() {
491                        // unwrap the array and apply the operator to each element
492                        for v in v.as_array().unwrap().list() {
493                            new_set.push(Cow::Owned(eval_unary_op(*op, v)?));
494                        }
495                    } else {
496                        new_set.push(Cow::Owned(eval_unary_op(*op, v)?));
497                    }
498                }
499                Ok(new_set)
500            }
501            Expr::BinaryOp(op, left, right) => {
502                let left = self.eval_expr(left)?;
503                let right = self.eval_expr(right)?;
504                if left.len() != 1 {
505                    return Err(Error::LeftOperandNotNumeric(*op));
506                }
507                if right.len() != 1 {
508                    return Err(Error::RightOperandNotNumeric(*op));
509                }
510                // unwrap left if it is an array
511                let left = if self.is_lax() {
512                    if let Some(array) = left[0].as_ref().as_array() {
513                        if array.len() != 1 {
514                            return Err(Error::LeftOperandNotNumeric(*op));
515                        }
516                        array.get(0).unwrap()
517                    } else {
518                        left[0].as_ref()
519                    }
520                } else {
521                    left[0].as_ref()
522                };
523                // unwrap right if it is an array
524                let right = if self.is_lax() {
525                    if let Some(array) = right[0].as_ref().as_array() {
526                        if array.len() != 1 {
527                            return Err(Error::RightOperandNotNumeric(*op));
528                        }
529                        array.get(0).unwrap()
530                    } else {
531                        right[0].as_ref()
532                    }
533                } else {
534                    right[0].as_ref()
535                };
536                Ok(vec![Cow::Owned(eval_binary_op(*op, left, right)?)])
537            }
538        }
539    }
540
541    /// Evaluates the path primary.
542    fn eval_path_primary(&self, primary: &PathPrimary) -> Result<Vec<Cow<'a, T>>> {
543        match primary {
544            PathPrimary::Root => Ok(vec![Cow::Borrowed(self.root)]),
545            PathPrimary::Current => Ok(vec![Cow::Borrowed(self.current)]),
546            PathPrimary::Value(v) => Ok(vec![self.eval_value(v)?]),
547            PathPrimary::Last => {
548                let array = self
549                    .array
550                    .as_array()
551                    .expect("LAST is allowed only in array subscripts");
552                Ok(vec![Cow::Owned(T::from_i64(array.len() as i64 - 1))])
553            }
554            PathPrimary::ExprOrPred(expr) => self.eval_expr_or_predicate(expr),
555        }
556    }
557
558    /// Evaluates the accessor operator.
559    fn eval_accessor_op(&self, op: &AccessorOp) -> Result<Vec<Cow<'a, T>>> {
560        match op {
561            AccessorOp::MemberWildcard => self.eval_member_wildcard(),
562            AccessorOp::DescendantMemberWildcard(levels) => {
563                self.eval_descendant_member_wildcard(levels)
564            }
565            AccessorOp::ElementWildcard => self.eval_element_wildcard(),
566            AccessorOp::Member(name) => self.eval_member(name),
567            AccessorOp::Element(indices) => self.eval_element_accessor(indices),
568            AccessorOp::FilterExpr(pred) => self.eval_filter_expr(pred),
569            AccessorOp::Method(method) => self.eval_method(method),
570        }
571    }
572
573    fn eval_member_wildcard(&self) -> Result<Vec<Cow<'a, T>>> {
574        let set = match self.current.as_array() {
575            Some(array) if self.is_lax() => array.list(),
576            _ => vec![self.current],
577        };
578        let mut new_set = vec![];
579        for v in set {
580            let object = lax!(self, v.as_object(), Error::WildcardMemberAccess);
581            for v in object.list_value() {
582                new_set.push(Cow::Borrowed(v));
583            }
584        }
585        Ok(new_set)
586    }
587
588    fn eval_descendant_member_wildcard(&self, levels: &LevelRange) -> Result<Vec<Cow<'a, T>>> {
589        let mut set = match self.current.as_array() {
590            Some(array) if self.is_lax() => array.list(),
591            _ => vec![self.current],
592        };
593        // expand all levels
594        // level i is set[level_start[i] .. level_start[i+1]]
595        let mut level_start = vec![0, set.len()];
596        for l in 1..=levels.end() {
597            let last_level_range = level_start[l as usize - 1]..level_start[l as usize];
598            for i in last_level_range {
599                if let Some(object) = set[i].as_object() {
600                    set.extend(object.list_value());
601                }
602            }
603            if set.len() == level_start[l as usize] {
604                // this level is empty
605                break;
606            }
607            level_start.push(set.len());
608        }
609        // return the set in level range
610        let last_level = level_start.len() - 2;
611        let level_range = levels.to_range(last_level);
612        let set_range = level_start[level_range.start]..level_start[level_range.end];
613        let new_set = set[set_range].iter().cloned().map(Cow::Borrowed).collect();
614        Ok(new_set)
615    }
616
617    fn eval_element_wildcard(&self) -> Result<Vec<Cow<'a, T>>> {
618        if !self.current.is_array() && self.is_lax() {
619            // wrap the current value into an array
620            return Ok(vec![Cow::Borrowed(self.current)]);
621        }
622        let array = lax!(self, self.current.as_array(), Error::WildcardArrayAccess);
623        if self.is_first() {
624            return Ok(array.get(0).map(Cow::Borrowed).into_iter().collect());
625        }
626        Ok(array.list().into_iter().map(Cow::Borrowed).collect())
627    }
628
629    /// Evaluates the member accessor.
630    fn eval_member(&self, name: &str) -> Result<Vec<Cow<'a, T>>> {
631        let set = match self.current.as_array() {
632            Some(array) if self.is_lax() => array.list(),
633            _ => vec![self.current],
634        };
635        let mut new_set = vec![];
636        for v in set {
637            let object = lax!(self, v.as_object(), Error::MemberAccess);
638            let elem = lax!(self, object.get(name), Error::NoKey(name.into()));
639            new_set.push(Cow::Borrowed(elem));
640        }
641        Ok(new_set)
642    }
643
644    /// Evaluates the element accessor.
645    fn eval_element_accessor(&self, indices: &[ArrayIndex]) -> Result<Vec<Cow<'a, T>>> {
646        // wrap the scalar value into an array in lax mode
647        enum ArrayOrScalar<'a, T: JsonRef<'a>> {
648            Array(T::Array),
649            Scalar(T),
650        }
651        impl<'a, T: JsonRef<'a>> ArrayOrScalar<'a, T> {
652            fn get(&self, index: usize) -> Option<T> {
653                match self {
654                    ArrayOrScalar::Array(array) => array.get(index),
655                    ArrayOrScalar::Scalar(scalar) if index == 0 => Some(*scalar),
656                    _ => None,
657                }
658            }
659        }
660        let array = match self.current.as_array() {
661            Some(array) => ArrayOrScalar::Array(array),
662            None if self.is_lax() => ArrayOrScalar::Scalar(self.current),
663            None => return Err(Error::ArrayAccess),
664        };
665        let mut elems = Vec::with_capacity(indices.len());
666        for index in indices {
667            let eval_index = |expr: &Expr| {
668                // errors in this closure can not be ignored
669                let set = Self {
670                    // update `array` context
671                    array: self.current,
672                    ..*self
673                }
674                .eval_expr(expr)?;
675                if set.len() != 1 {
676                    return Err(Error::ArrayIndexNotNumeric);
677                }
678                set[0]
679                    .as_ref()
680                    .as_number()
681                    .ok_or(Error::ArrayIndexNotNumeric)?
682                    .to_i64()
683                    .ok_or(Error::ArrayIndexOutOfRange)
684            };
685            match index {
686                ArrayIndex::Index(expr) => {
687                    let index = eval_index(expr)?;
688                    let index =
689                        lax!(self, index.try_into().ok(), Error::ArrayIndexOutOfBounds; continue);
690                    let elem = lax!(self, array.get(index), Error::ArrayIndexOutOfBounds; continue);
691                    elems.push(Cow::Borrowed(elem));
692                }
693                ArrayIndex::Slice(begin, end) => {
694                    let begin = eval_index(begin)?;
695                    let end = eval_index(end)?;
696                    let begin: usize = match begin.try_into() {
697                        Ok(i) => i,
698                        Err(_) if self.is_lax() => 0,
699                        Err(_) => return Err(Error::ArrayIndexOutOfBounds),
700                    };
701                    let end: usize =
702                        lax!(self, end.try_into().ok(), Error::ArrayIndexOutOfBounds; continue);
703                    if begin > end && !self.is_lax() {
704                        return Err(Error::ArrayIndexOutOfBounds);
705                    }
706                    for i in begin..=end {
707                        let elem = lax!(self, array.get(i), Error::ArrayIndexOutOfBounds; break);
708                        elems.push(Cow::Borrowed(elem));
709                    }
710                }
711            }
712        }
713        Ok(elems)
714    }
715
716    fn eval_filter_expr(&self, pred: &Predicate) -> Result<Vec<Cow<'a, T>>> {
717        let set = match self.current.as_array() {
718            Some(array) if self.is_lax() => array.list(),
719            _ => vec![self.current],
720        };
721        let mut new_set = vec![];
722        for v in set {
723            if self.with_current(v).eval_predicate(pred)?.is_true() {
724                new_set.push(Cow::Borrowed(v));
725                if self.is_first() {
726                    break;
727                }
728            }
729        }
730        Ok(new_set)
731    }
732
733    /// Evaluates the item method.
734    fn eval_method(&self, method: &Method) -> Result<Vec<Cow<'a, T>>> {
735        // unwrap the current value if it is an array
736        if self.current.is_array()
737            && self.is_lax()
738            && !matches!(method, Method::Size | Method::Type)
739        {
740            let mut new_set = vec![];
741            for v in self.current.as_array().unwrap().list() {
742                new_set.extend(self.with_current(v).eval_method(method)?);
743            }
744            return Ok(new_set);
745        }
746        match method {
747            Method::Type => self.eval_method_type().map(|v| vec![v]),
748            Method::Size => self.eval_method_size().map(|v| vec![v]),
749            Method::Double => self.eval_method_double().map(|v| vec![v]),
750            Method::Ceiling => self.eval_method_ceiling().map(|v| vec![v]),
751            Method::Floor => self.eval_method_floor().map(|v| vec![v]),
752            Method::Abs => self.eval_method_abs().map(|v| vec![v]),
753            Method::Keyvalue => self.eval_method_keyvalue(),
754        }
755    }
756
757    fn eval_method_type(&self) -> Result<Cow<'a, T>> {
758        let s = if self.current.is_null() {
759            "null"
760        } else if self.current.is_bool() {
761            "boolean"
762        } else if self.current.is_number() {
763            "number"
764        } else if self.current.is_string() {
765            "string"
766        } else if self.current.is_array() {
767            "array"
768        } else if self.current.is_object() {
769            "object"
770        } else {
771            unreachable!()
772        };
773        Ok(Cow::Owned(T::from_string(s)))
774    }
775
776    fn eval_method_size(&self) -> Result<Cow<'a, T>> {
777        let size = if let Some(array) = self.current.as_array() {
778            // The size of an SQL/JSON array is the number of elements in the array.
779            array.len()
780        } else if self.is_lax() {
781            // The size of an SQL/JSON object or a scalar is 1.
782            1
783        } else {
784            return Err(Error::SizeNotArray);
785        };
786        Ok(Cow::Owned(T::from_u64(size as u64)))
787    }
788
789    fn eval_method_double(&self) -> Result<Cow<'a, T>> {
790        if let Some(s) = self.current.as_str() {
791            let n = s.parse::<f64>().map_err(|_| Error::InvalidDouble)?;
792            if n.is_infinite() || n.is_nan() {
793                return Err(Error::InvalidDouble);
794            }
795            Ok(Cow::Owned(T::from_f64(n)))
796        } else if self.current.is_number() {
797            Ok(Cow::Borrowed(self.current))
798        } else {
799            Err(Error::DoubleTypeError)
800        }
801    }
802
803    fn eval_method_ceiling(&self) -> Result<Cow<'a, T>> {
804        let n = self
805            .current
806            .as_number()
807            .ok_or(Error::MethodNotNumeric("ceiling"))?;
808        Ok(Cow::Owned(T::from_number(n.ceil())))
809    }
810
811    fn eval_method_floor(&self) -> Result<Cow<'a, T>> {
812        let n = self
813            .current
814            .as_number()
815            .ok_or(Error::MethodNotNumeric("floor"))?;
816        Ok(Cow::Owned(T::from_number(n.floor())))
817    }
818
819    fn eval_method_abs(&self) -> Result<Cow<'a, T>> {
820        let n = self
821            .current
822            .as_number()
823            .ok_or(Error::MethodNotNumeric("abs"))?;
824        Ok(Cow::Owned(T::from_number(n.abs())))
825    }
826
827    fn eval_method_keyvalue(&self) -> Result<Vec<Cow<'a, T>>> {
828        let object = self.current.as_object().ok_or(Error::KeyValueNotObject)?;
829        Ok(object
830            .list()
831            .into_iter()
832            .map(|(k, v)| {
833                Cow::Owned(T::object([
834                    ("key", T::from_string(k)),
835                    ("value", v.to_owned()),
836                    ("id", T::from_i64(0)), // FIXME: provide unique id
837                ]))
838            })
839            .collect())
840    }
841
842    /// Evaluates the scalar value.
843    fn eval_value(&self, value: &Value) -> Result<Cow<'a, T>> {
844        Ok(match value {
845            Value::Null => Cow::Owned(T::null()),
846            Value::Boolean(b) => Cow::Owned(T::bool(*b)),
847            Value::Number(n) => Cow::Owned(T::from_number(n.clone())),
848            Value::String(s) => Cow::Owned(T::from_string(s)),
849            Value::Variable(v) => Cow::Borrowed(self.get_variable(v)?),
850        })
851    }
852}
853
854/// Compare two values.
855///
856/// Return unknown if the values are not comparable.
857fn eval_compare<T: Json>(op: CompareOp, left: T::Borrowed<'_>, right: T::Borrowed<'_>) -> Truth {
858    use CompareOp::*;
859    // arrays and objects are not comparable
860    if left.is_array() || left.is_object() || right.is_array() || right.is_object() {
861        return Truth::Unknown;
862    }
863    // SQL/JSON null is equal to SQL/JSON null, and is not greater than or less than anything.
864    if left.is_null() && right.is_null() {
865        return compare_ord(op, (), ()).into();
866    }
867    if left.is_null() || right.is_null() {
868        return (op == CompareOp::Ne).into();
869    }
870    if let (Some(left), Some(right)) = (left.as_bool(), right.as_bool()) {
871        return compare_ord(op, left, right).into();
872    }
873    if let (Some(left), Some(right)) = (left.as_number(), right.as_number()) {
874        return match op {
875            Eq => left.equal(&right),
876            Ne => !left.equal(&right),
877            Gt => right.less_than(&left),
878            Ge => !left.less_than(&right),
879            Lt => left.less_than(&right),
880            Le => !right.less_than(&left),
881        }
882        .into();
883    }
884    if let (Some(left), Some(right)) = (left.as_str(), right.as_str()) {
885        return compare_ord(op, left, right).into();
886    }
887    // others are not comparable
888    Truth::Unknown
889}
890
891/// Evaluate the unary operator.
892fn eval_unary_op<T: Json>(op: UnaryOp, value: T::Borrowed<'_>) -> Result<T> {
893    let n = value
894        .as_number()
895        .ok_or_else(|| Error::UnaryOperandNotNumeric(op))?;
896    Ok(match op {
897        UnaryOp::Plus => value.to_owned(),
898        UnaryOp::Minus => T::from_number(n.neg()),
899    })
900}
901
902/// Evaluate the binary operator.
903fn eval_binary_op<T: Json>(
904    op: BinaryOp,
905    left: T::Borrowed<'_>,
906    right: T::Borrowed<'_>,
907) -> Result<T> {
908    let left = left
909        .as_number()
910        .ok_or_else(|| Error::LeftOperandNotNumeric(op))?;
911    let right = right
912        .as_number()
913        .ok_or_else(|| Error::RightOperandNotNumeric(op))?;
914    Ok(T::from_number(match op {
915        BinaryOp::Add => left.add(&right),
916        BinaryOp::Sub => left.sub(&right),
917        BinaryOp::Mul => left.mul(&right),
918        BinaryOp::Div => left.div(&right)?,
919        BinaryOp::Rem => left.rem(&right)?,
920    }))
921}
922
923/// Compare two values that implement `Ord`.
924fn compare_ord<T: Ord>(op: CompareOp, left: T, right: T) -> bool {
925    use CompareOp::*;
926    match op {
927        Eq => left == right,
928        Ne => left != right,
929        Gt => left > right,
930        Ge => left >= right,
931        Lt => left < right,
932        Le => left <= right,
933    }
934}
935
936/// Extension methods for `Number`.
937pub trait NumberExt: Sized {
938    fn equal(&self, other: &Self) -> bool;
939    fn less_than(&self, other: &Self) -> bool;
940    fn neg(&self) -> Self;
941    fn add(&self, other: &Self) -> Self;
942    fn sub(&self, other: &Self) -> Self;
943    fn mul(&self, other: &Self) -> Self;
944    fn div(&self, other: &Self) -> Result<Self>;
945    fn rem(&self, other: &Self) -> Result<Self>;
946    fn ceil(&self) -> Self;
947    fn floor(&self) -> Self;
948    fn abs(&self) -> Self;
949    fn to_i64(&self) -> Option<i64>;
950}
951
952impl NumberExt for Number {
953    fn equal(&self, other: &Self) -> bool {
954        // The original `Eq` implementation of `Number` does not work
955        // if the two numbers have different types. (i64, u64, f64)
956        self.as_f64().unwrap() == other.as_f64().unwrap()
957    }
958
959    fn less_than(&self, other: &Self) -> bool {
960        self.as_f64().unwrap() < other.as_f64().unwrap()
961    }
962
963    fn neg(&self) -> Self {
964        if let Some(n) = self.as_i64() {
965            Number::from(-n)
966        } else if let Some(n) = self.as_f64() {
967            Number::from_f64(-n).unwrap()
968        } else {
969            // `as_f64` should always return a value
970            unreachable!()
971        }
972    }
973
974    fn add(&self, other: &Self) -> Self {
975        if let (Some(a), Some(b)) = (self.as_i64(), other.as_i64()) {
976            Number::from(a + b)
977        } else if let (Some(a), Some(b)) = (self.as_f64(), other.as_f64()) {
978            Number::from_f64(a + b).unwrap()
979        } else {
980            unreachable!()
981        }
982    }
983
984    fn sub(&self, other: &Self) -> Self {
985        if let (Some(a), Some(b)) = (self.as_i64(), other.as_i64()) {
986            Number::from(a - b)
987        } else if let (Some(a), Some(b)) = (self.as_f64(), other.as_f64()) {
988            Number::from_f64(a - b).unwrap()
989        } else {
990            unreachable!()
991        }
992    }
993
994    fn mul(&self, other: &Self) -> Self {
995        if let (Some(a), Some(b)) = (self.as_i64(), other.as_i64()) {
996            Number::from(a * b)
997        } else if let (Some(a), Some(b)) = (self.as_f64(), other.as_f64()) {
998            Number::from_f64(a * b).unwrap()
999        } else {
1000            unreachable!()
1001        }
1002    }
1003
1004    fn div(&self, other: &Self) -> Result<Self> {
1005        if let (Some(a), Some(b)) = (self.as_f64(), other.as_f64()) {
1006            if b == 0.0 {
1007                return Err(Error::DivisionByZero);
1008            }
1009            Ok(Number::from_f64(a / b).unwrap())
1010        } else {
1011            unreachable!()
1012        }
1013    }
1014
1015    fn rem(&self, other: &Self) -> Result<Self> {
1016        if let (Some(a), Some(b)) = (self.as_i64(), other.as_i64()) {
1017            if b == 0 {
1018                return Err(Error::DivisionByZero);
1019            }
1020            Ok(Number::from(a % b))
1021        } else if let (Some(a), Some(b)) = (self.as_f64(), other.as_f64()) {
1022            if b == 0.0 {
1023                return Err(Error::DivisionByZero);
1024            }
1025            Ok(Number::from_f64(a % b).unwrap())
1026        } else {
1027            unreachable!()
1028        }
1029    }
1030
1031    fn ceil(&self) -> Self {
1032        if self.is_f64() {
1033            Number::from(self.as_f64().unwrap().ceil() as i64)
1034        } else {
1035            self.clone()
1036        }
1037    }
1038
1039    fn floor(&self) -> Self {
1040        if self.is_f64() {
1041            Number::from(self.as_f64().unwrap().floor() as i64)
1042        } else {
1043            self.clone()
1044        }
1045    }
1046
1047    fn abs(&self) -> Self {
1048        if let Some(n) = self.as_i64() {
1049            Number::from(n.abs())
1050        } else if let Some(n) = self.as_f64() {
1051            Number::from_f64(n.abs()).unwrap()
1052        } else {
1053            unreachable!()
1054        }
1055    }
1056
1057    /// Converts to json integer if possible.
1058    /// Float values are truncated.
1059    /// Returns `None` if the value is out of range.
1060    /// Range: [-2^53 + 1, 2^53 - 1]
1061    fn to_i64(&self) -> Option<i64> {
1062        const INT_MIN: i64 = -(1 << 53) + 1;
1063        const INT_MAX: i64 = (1 << 53) - 1;
1064        if let Some(i) = self.as_i64() {
1065            if (INT_MIN..=INT_MAX).contains(&i) {
1066                Some(i)
1067            } else {
1068                None
1069            }
1070        } else if let Some(f) = self.as_f64() {
1071            if (INT_MIN as f64..=INT_MAX as f64).contains(&f) {
1072                Some(f as i64)
1073            } else {
1074                None
1075            }
1076        } else {
1077            unreachable!()
1078        }
1079    }
1080}