mirror of
https://github.com/jackfoxy/urQL.git
synced 2024-12-14 18:41:40 +03:00
clean-up and a few more predicate test cases
This commit is contained in:
parent
f04d177ab4
commit
4e31d022d2
@ -55,45 +55,9 @@
|
||||
is-clustered=?
|
||||
columns=(list ordered-column:ast)
|
||||
==
|
||||
::+$ expression ?(qualified-column:ast value-literal:ast value-literal-list:ast aggregate:ast) :: fish-loop
|
||||
+$ expression ?(qualified-column:ast value-literal:ast value-literal-list:ast) :: aggregate:ast)
|
||||
+$ parens ?(%pal %par)
|
||||
+$ raw-predicate-component ?(parens predicate-component:ast predicate:ast)
|
||||
+$ raw-predicate-component2 ?(%pal %par ternary-operator:ast binary-operator:ast unary-operator:ast conjunction:ast qualified-column:ast value-literal:ast value-literal-list:ast)
|
||||
+$ list6
|
||||
$:
|
||||
%list6
|
||||
l1=raw-predicate-component
|
||||
l2=raw-predicate-component
|
||||
l3=raw-predicate-component
|
||||
l4=raw-predicate-component
|
||||
l5=raw-predicate-component
|
||||
l6=raw-predicate-component
|
||||
==
|
||||
+$ list5
|
||||
$:
|
||||
%list5
|
||||
l1=raw-predicate-component
|
||||
l2=raw-predicate-component
|
||||
l3=raw-predicate-component
|
||||
l4=raw-predicate-component
|
||||
l5=raw-predicate-component
|
||||
==
|
||||
+$ list4
|
||||
$:
|
||||
%list4
|
||||
l1=raw-predicate-component
|
||||
l2=raw-predicate-component
|
||||
l3=raw-predicate-component
|
||||
l4=raw-predicate-component
|
||||
==
|
||||
+$ try-fail %fail
|
||||
+$ try-success
|
||||
$:
|
||||
%try-success
|
||||
result=raw-predicate-component
|
||||
==
|
||||
+$ try-result $%(try-success try-fail)
|
||||
+$ raw-predicate-component2 ?(parens predicate-component:ast)
|
||||
::
|
||||
:: get next position in script
|
||||
::
|
||||
@ -525,7 +489,6 @@
|
||||
(query-object:ast %query-object -.parsed `+.parsed)
|
||||
~|("cannot parse query-object {<parsed>}" !!)
|
||||
++ parse-cross-joined-object ~+ ;~(plug parse-cross-join-type parse-query-object)
|
||||
::(cook cook-joined-object ;~(plug parse-cross-join-type parse-query-object))
|
||||
++ parse-joined-object ~+ ;~ plug
|
||||
parse-join-type
|
||||
parse-query-object
|
||||
@ -533,24 +496,9 @@
|
||||
::;~(pfix whitespace ;~(pfix (jester 'on') ;~(less predicate-stop prn)))
|
||||
::(easy ~)
|
||||
==
|
||||
++ build-joined-object parse-joined-object
|
||||
::(cook cook-joined-object parse-joined-object)
|
||||
::++ cook-joined-object
|
||||
:: |= parsed=*
|
||||
:: ~+
|
||||
:: ~| "-.parsed: {<-.parsed>}"
|
||||
:: ~| "+<.parsed: {<+<.parsed>}"
|
||||
:: ~| "+>.parsed: {<+>.parsed>}"
|
||||
:: ^- joined-object:ast
|
||||
:: ?> ?=(join-type:ast -.parsed)
|
||||
:: ?: ?&(?=([@ @ [@ @ @ @ @] @ @] parsed) ?=(query-object:ast +.parsed))
|
||||
:: (joined-object:ast %joined-object -.parsed +.parsed ~)
|
||||
:: ?: ?&(?=([@ @ [@ @ @ @ @] @] parsed) ?=(query-object:ast +.parsed))
|
||||
:: (joined-object:ast %joined-object -.parsed +.parsed ~)
|
||||
:: (joined-object:ast %joined-object -.parsed +<.parsed (produce-predicate (predicate-list +>.parsed)))
|
||||
++ parse-object-and-joins ~+ ;~ plug
|
||||
parse-query-object
|
||||
;~(pose parse-cross-joined-object (star build-joined-object))
|
||||
;~(pose parse-cross-joined-object (star parse-joined-object))
|
||||
==
|
||||
::
|
||||
:: column in "join on" or "where" predicate, qualified or aliased
|
||||
@ -611,135 +559,39 @@
|
||||
(cold %pal pal)
|
||||
(cold %par par)
|
||||
==
|
||||
++ resolve-between-operator
|
||||
|= [operator=ternary-operator:ast c1=expression c2=expression c3=expression]
|
||||
~+
|
||||
^- (tree predicate-component:ast)
|
||||
=/ left `(tree predicate-component:ast)`[%gte `(tree predicate-component:ast)`[c1 ~ ~] `(tree predicate-component:ast)`[c2 ~ ~]]
|
||||
=/ right `(tree predicate-component:ast)`[%lte `(tree predicate-component:ast)`[c1 ~ ~] `(tree predicate-component:ast)`[c3 ~ ~]]
|
||||
`(tree predicate-component:ast)`[operator left right]
|
||||
++ resolve-not-between-operator
|
||||
|= [operator=ternary-operator:ast c1=expression c2=expression c3=expression]
|
||||
~+
|
||||
^- (tree predicate-component:ast)
|
||||
=/ left `(tree predicate-component:ast)`[%gte `(tree predicate-component:ast)`[c1 ~ ~] `(tree predicate-component:ast)`[c2 ~ ~]]
|
||||
=/ right `(tree predicate-component:ast)`[%lte `(tree predicate-component:ast)`[c1 ~ ~] `(tree predicate-component:ast)`[c3 ~ ~]]
|
||||
`(tree predicate-component:ast)`[%not `(tree predicate-component:ast)`[operator left right] ~]
|
||||
++ resolve-binary-operator
|
||||
|= [operator=binary-operator:ast c1=expression c2=expression]
|
||||
~+
|
||||
^- (tree predicate-component:ast)
|
||||
`(tree predicate-component:ast)`[operator `(tree predicate-component:ast)`[`predicate-component:ast`c1 ~ ~] `(tree predicate-component:ast)`[`predicate-component:ast`c2 ~ ~]]
|
||||
++ resolve-all-any
|
||||
|= b=[l1=expression l2=inequality-operator:ast l3=all-any-operator:ast l4=expression]
|
||||
~+
|
||||
^- (tree predicate-component:ast)
|
||||
=/ all-any `(tree predicate-component:ast)`[l3.b `(tree predicate-component:ast)`[l4.b ~ ~] ~]
|
||||
`(tree predicate-component:ast)`[l2.b `(tree predicate-component:ast)`[l1.b ~ ~] all-any]
|
||||
++ try-not-between-and
|
||||
|= b=list6
|
||||
~+
|
||||
^- try-result
|
||||
?. ?&(?=(expression l1.b) ?=(%not l2.b) ?=(ternary-operator:ast l3.b) ?=(expression l4.b) ?=(%and l5.b) ?=(expression l6.b))
|
||||
`try-result`%fail
|
||||
(try-success %try-success (resolve-not-between-operator [l3.b l1.b l4.b l6.b]))
|
||||
++ try-5
|
||||
|= b=list5
|
||||
~+
|
||||
^- try-result
|
||||
?: ?&(?=(expression l1.b) ?=(%not l2.b) ?=(ternary-operator:ast l3.b) ?=(expression l4.b) ?=(expression l5.b))
|
||||
(try-success %try-success (resolve-not-between-operator [l3.b l1.b l4.b l5.b]))
|
||||
?: ?&(?=(expression l1.b) ?=(ternary-operator:ast l2.b) ?=(expression l3.b) ?=(%and l4.b) ?=(expression l5.b))
|
||||
(try-success %try-success (resolve-between-operator [l2.b l1.b l3.b l5.b]))
|
||||
`try-result`%fail
|
||||
++ try-4
|
||||
|= b=list4
|
||||
~+
|
||||
^- try-result
|
||||
:: expression between expression expression
|
||||
?: ?&(?=(expression l1.b) ?=(ternary-operator:ast l2.b) ?=(expression l3.b) ?=(expression l4.b))
|
||||
(try-success %try-success (resolve-between-operator [l2.b l1.b l3.b l4.b]))
|
||||
:: expression inequality all/any cte-one-column-query
|
||||
?: ?&(?=(expression l1.b) ?=(inequality-operator:ast l2.b) ?=(all-any-operator:ast l3.b) ?=(expression l4.b))
|
||||
(try-success %try-success (resolve-all-any [l1.b l2.b l3.b l4.b]))
|
||||
:: expression not in query or value list
|
||||
?: ?&(?=(expression l1.b) ?=(%not l2.b) ?=(%in l3.b) ?=(expression l4.b))
|
||||
(try-success %try-success `(tree predicate-component:ast)`[%not `(tree predicate-component:ast)`[%in [l1.b ~ ~] [l4.b ~ ~]] ~])
|
||||
`try-result`%fail
|
||||
++ resolve-operators
|
||||
::
|
||||
:: resolve non-unary (and some unary) operators into trees
|
||||
|= a=(list raw-predicate-component)
|
||||
~+
|
||||
^- (list raw-predicate-component)
|
||||
=/ resolved=(list raw-predicate-component) ~
|
||||
=+ result=`try-result`%fail
|
||||
=+ result2=`try-result`%fail
|
||||
=+ result3=`try-result`%fail
|
||||
++ predicate-list
|
||||
|= a=*
|
||||
^- (list raw-predicate-component2)
|
||||
=/ new-list=(list raw-predicate-component2) ~
|
||||
|-
|
||||
?: =(a ~) (flop resolved)
|
||||
::
|
||||
:: expression not between expression and expression
|
||||
=. result ?: (gte (lent a) 6)
|
||||
(try-not-between-and (list6 %list6 -.a +<.a +>-.a +>+<.a +>+>-.a +>+>+<.a))
|
||||
`try-result`%fail
|
||||
?. ?=(try-fail result) $(a +>+>+>.a, resolved [result.result resolved])
|
||||
::
|
||||
:: expression not between expression expression
|
||||
:: expression between expression and expression
|
||||
=. result2 ?: (gte (lent a) 5)
|
||||
(try-5 (list5 %list5 -.a +<.a +>-.a +>+<.a +>+>-.a))
|
||||
`try-result`%fail
|
||||
?. ?=(try-fail result2) $(a +>+>+.a, resolved [result.result2 resolved])
|
||||
::
|
||||
:: expression between expression expression
|
||||
:: expression inequality all/any cte-one-column-query
|
||||
:: expression not in query or value list
|
||||
=. result3 ?: (gte (lent a) 4)
|
||||
(try-4 (list4 %list4 -.a +<.a +>-.a +>+<.a))
|
||||
`try-result`%fail
|
||||
?. ?=(try-fail result3) $(a +>+>.a, resolved [result.result3 resolved])
|
||||
::
|
||||
:: expression binary operator expression
|
||||
?: ?&((gte (lent a) 3) ?=(expression -.a) ?=(binary-operator:ast +<.a) ?=(expression +>-.a))
|
||||
$(a +>+.a, resolved [(resolve-binary-operator [+<.a -.a +>-.a]) resolved])
|
||||
::
|
||||
:: not exists column or cte-one-column-query
|
||||
?: ?&((gte (lent a) 3) ?=(%not -.a) ?=(%exists +<.a) ?=(expression +>-.a))
|
||||
$(a +>+.a, resolved [`(tree predicate-component:ast)`[%not `(tree predicate-component:ast)`[%exists [`(tree predicate-component:ast)`[+>-.a ~ ~]] ~] ~] resolved])
|
||||
::
|
||||
:: exists column or cte-one-column-query
|
||||
?: ?&((gte (lent a) 2) ?=(%exists -.a) ?=(expression +<.a))
|
||||
$(a +>.a, resolved [`(tree predicate-component:ast)`[%exists [`(tree predicate-component:ast)`[+<.a ~ ~]] ~] resolved])
|
||||
$(a +.a, resolved [-.a resolved])
|
||||
++ resolve-depth
|
||||
::
|
||||
:: determine deepest parenthesis nesting, eliminating superfluous nesting
|
||||
|= a=(list raw-predicate-component)
|
||||
~+
|
||||
^- [@ud (list raw-predicate-component)]
|
||||
=/ resolved=(list raw-predicate-component) ~
|
||||
=/ depth 0
|
||||
=/ working-depth 0
|
||||
|-
|
||||
?: =(a ~) [depth (flop resolved)]
|
||||
?: =(-.a %pal)
|
||||
?: ?&((gte (lent +.a) 2) =(+>-.a %par)) :: single parenthesised entity
|
||||
$(a +>+.a, resolved [+<.a resolved])
|
||||
?. (gth (add working-depth 1) depth) $(working-depth (add working-depth 1), a +.a, resolved [-.a resolved])
|
||||
%= $
|
||||
depth (add depth 1)
|
||||
working-depth (add working-depth 1)
|
||||
a +.a
|
||||
resolved [-.a resolved]
|
||||
?: =(a ~) (flop new-list)
|
||||
?: ?=(parens -.a) $(new-list [i=`parens`-.a t=new-list], a +.a)
|
||||
?: ?=(ops-and-conjs:ast -.a) $(new-list [i=`ops-and-conjs:ast`-.a t=new-list], a +.a)
|
||||
?: ?=(qualified-column:ast -.a) $(new-list [i=`qualified-column:ast`-.a t=new-list], a +.a)
|
||||
?: ?=(value-literal:ast -.a) $(new-list [i=`value-literal:ast`-.a t=new-list], a +.a)
|
||||
?: ?=(value-literal-list:ast -.a) $(new-list [i=`value-literal-list:ast`-.a t=new-list], a +.a)
|
||||
:: ?: ?=(aggregate:ast -.a) $(new-list [i=`aggregate:ast`-.a t=new-list], a +.a) :: to do
|
||||
~|("problem with predicate noun: {<a>}" !!)
|
||||
++ predicate-stop ~+ ;~ pose
|
||||
;~(plug whitespace mic)
|
||||
mic
|
||||
;~(plug whitespace (jester 'where'))
|
||||
;~(plug whitespace (jester 'select'))
|
||||
;~(plug whitespace (jester 'as'))
|
||||
;~(plug whitespace (jester 'join'))
|
||||
;~(plug whitespace (jester 'left'))
|
||||
;~(plug whitespace (jester 'right'))
|
||||
;~(plug whitespace (jester 'outer'))
|
||||
;~(plug whitespace (jester 'then'))
|
||||
==
|
||||
?. =(-.a %par) $(a +.a, resolved [-.a resolved])
|
||||
%= $
|
||||
working-depth (sub working-depth 1)
|
||||
a +.a
|
||||
resolved [-.a resolved]
|
||||
++ predicate-part ~+ ;~ pose
|
||||
:: parse-aggregate
|
||||
value-literal-list
|
||||
;~(pose ;~(pfix whitespace parse-operator) parse-operator)
|
||||
parse-datum
|
||||
==
|
||||
++ resolve-conjunctions
|
||||
++ parse-predicate
|
||||
(star ;~(less predicate-stop predicate-part))
|
||||
::
|
||||
:: when not qualified by () right conjunction takes precedence and "or" takes precedence over "and"
|
||||
::
|
||||
@ -789,198 +641,6 @@
|
||||
:: /\
|
||||
:: 1=2 3=3
|
||||
::
|
||||
|= a=[target-depth=@ud components=(list raw-predicate-component) predicates=(list predicate:ast)]
|
||||
^- [(list raw-predicate-component) (list predicate:ast)]
|
||||
::~& "(lent components.a): {<(lent components.a)>}"
|
||||
::?: =((lent components.a) 1) [~ `(list predicate:ast)`[-.components.a ~]]
|
||||
=/ resolved=(list raw-predicate-component) ~
|
||||
=/ working-depth 0
|
||||
=/ working-tree=predicate:ast ~
|
||||
=/ resolved-trees=(list predicate:ast) ~
|
||||
|-
|
||||
?: =(components.a ~) [(flop resolved) (flop resolved-trees)]
|
||||
?: ?&(=(-.components.a %pal) !=(+>-.components.a %par))
|
||||
%= $
|
||||
components.a +.components.a
|
||||
resolved [-.components.a resolved]
|
||||
working-depth (add working-depth 1)
|
||||
==
|
||||
?. =(working-depth target-depth.a)
|
||||
$(components.a +.components.a, resolved [-.components.a resolved])
|
||||
|-
|
||||
::
|
||||
:: if there are superfluous levels of nesting we will end up here
|
||||
:: to do: test if this is still working/required
|
||||
?: =(components.a ~) ^$(resolved [working-tree resolved])
|
||||
::
|
||||
:: if () enclosed tree is first thing, then it is always the left subtree
|
||||
:: ~& "(lent components.a): {<(lent components.a)>}"
|
||||
?: =(-.components.a %pal)
|
||||
?: =(+>-.components.a %par)
|
||||
:: stand-alone tree
|
||||
?: =((lent components.a) 3)
|
||||
%= ^$
|
||||
components.a ~ :: end of comonents +>+.components.a
|
||||
resolved [+<.components.a resolved]
|
||||
:: working-tree -.resolved-trees (not necessary, we are at end)
|
||||
resolved-trees +.resolved-trees
|
||||
==
|
||||
?: ?&((gth (lent resolved) 1) =(-.resolved %pal))
|
||||
|
||||
::$(components.a +>+.components.a, working-tree +<.components.a)
|
||||
%= ^$
|
||||
components.a +>+.components.a
|
||||
working-tree -.predicates.a
|
||||
predicates.a +.predicates.a
|
||||
==
|
||||
|
||||
?: =((lent components.a) 4)
|
||||
|
||||
::$(components.a ~, working-tree +<.components.a)
|
||||
%= ^$
|
||||
components.a ~
|
||||
working-tree -.predicates.a
|
||||
predicates.a +.predicates.a
|
||||
==
|
||||
|
||||
::$(components.a +>+>+.components.a, working-tree [+>+<.components.a +<.components.a +>+>-.components.a])
|
||||
::%= $
|
||||
:: components.a +>+>+.components.a
|
||||
:: working-tree [+>+<.components.a +<.components.a +>+>-.components.a]
|
||||
::==
|
||||
!!
|
||||
|
||||
::$(components.a +>.components.a, working-tree [+>-.components.a +<.components.a +>+<.components.a])
|
||||
!!
|
||||
|
||||
|
||||
?: =(-.components.a %par) :: time to close out the nested tree
|
||||
?: =(working-depth 0)
|
||||
%= ^$
|
||||
components.a +.components.a
|
||||
resolved [%par [working-tree resolved]]
|
||||
resolved-trees [working-tree resolved-trees]
|
||||
working-tree ~
|
||||
==
|
||||
%= ^$
|
||||
components.a +.components.a
|
||||
resolved [%par [working-tree resolved]]
|
||||
working-depth (sub working-depth 1)
|
||||
resolved-trees [working-tree resolved-trees]
|
||||
working-tree ~
|
||||
==
|
||||
::
|
||||
:: below this point we deal with components only
|
||||
?@ -.components.a
|
||||
?: =(-.components.a %or) :: "or" the whole tree
|
||||
?: =(%pal +<.components.a) :: new right is () enclosed tree
|
||||
%= ^$
|
||||
components.a +>+>.components.a
|
||||
working-tree (next-working-tree [%or working-tree +>-.components.a])
|
||||
==
|
||||
%= $
|
||||
components.a +>.components.a
|
||||
working-tree (next-working-tree [%or working-tree +<.components.a])
|
||||
==
|
||||
:: working tree is an "or" and we are given an "and"; "and" the right tree
|
||||
?: ?&(!=(working-tree ~) =(-.working-tree %or))
|
||||
?: =(%pal +<.components.a) :: new right is () enclosed tree
|
||||
%= ^$
|
||||
components.a +>+.components.a
|
||||
working-tree
|
||||
(next-working-tree [%or +<.working-tree (next-working-tree [%and +>.working-tree +>-.components.a])])
|
||||
==
|
||||
%= ^$
|
||||
components.a +>.components.a
|
||||
working-tree
|
||||
(next-working-tree [%or +<.working-tree (next-working-tree [%and +>.working-tree +<.components.a])])
|
||||
==
|
||||
:: working tree is an "and" and we are given an "and"
|
||||
:: "and" the whole tree
|
||||
:: new right is () enclosed tree
|
||||
?: =(%pal +<.components.a)
|
||||
%= ^$
|
||||
components.a +>+>.components.a
|
||||
working-tree (next-working-tree [%and working-tree +>-.components.a])
|
||||
==
|
||||
%= ^$
|
||||
components.a +>.components.a
|
||||
working-tree (next-working-tree [%and working-tree +<.components.a])
|
||||
::working-tree
|
||||
:: (next-working-tree [working-tree `(list raw-predicate-component)`+<.components.a predicates.a])
|
||||
==
|
||||
::
|
||||
::
|
||||
::~|('betting for now this never happens' !!)
|
||||
:: can only be tree on first time
|
||||
^$(components.a +.components.a, working-tree -.predicates.a)
|
||||
++ next-working-tree
|
||||
|= a=[conjunction=conjunction:ast working-tree=predicate:ast component=raw-predicate-component]
|
||||
~| "working-tree: {<working-tree.a>}"
|
||||
~| "component: {<component.a>}"
|
||||
^- predicate:ast
|
||||
?+ component.a ~|("next component unexpected type: {<component.a>}" !!)
|
||||
qualified-column:ast [conjunction.a working-tree.a [`predicate-component:ast`component.a ~ ~]]
|
||||
value-literal:ast [conjunction.a working-tree.a [`predicate-component:ast`component.a ~ ~]]
|
||||
value-literal-list:ast [conjunction.a working-tree.a [`predicate-component:ast`component.a ~ ~]]
|
||||
==
|
||||
++ predicate-list
|
||||
|= a=*
|
||||
^- (list raw-predicate-component2)
|
||||
=/ new-list=(list raw-predicate-component2) ~
|
||||
|-
|
||||
?: =(a ~) (flop new-list)
|
||||
?: ?=(parens -.a) $(new-list [i=`parens`-.a t=new-list], a +.a)
|
||||
?: ?=(ops-and-conjs:ast -.a) $(new-list [i=`ops-and-conjs:ast`-.a t=new-list], a +.a)
|
||||
?: ?=(qualified-column:ast -.a) $(new-list [i=`qualified-column:ast`-.a t=new-list], a +.a)
|
||||
?: ?=(value-literal:ast -.a) $(new-list [i=`value-literal:ast`-.a t=new-list], a +.a)
|
||||
?: ?=(value-literal-list:ast -.a) $(new-list [i=`value-literal-list:ast`-.a t=new-list], a +.a)
|
||||
:: ?: ?=(aggregate:ast -.a) $(new-list [i=`aggregate:ast`-.a t=new-list], a +.a) :: to do
|
||||
~|("problem with predicate noun: {<a>}" !!)
|
||||
++ predicate-stop ~+ ;~ pose
|
||||
;~(plug whitespace mic)
|
||||
mic
|
||||
;~(plug whitespace (jester 'where'))
|
||||
;~(plug whitespace (jester 'select'))
|
||||
;~(plug whitespace (jester 'as'))
|
||||
;~(plug whitespace (jester 'join'))
|
||||
;~(plug whitespace (jester 'left'))
|
||||
;~(plug whitespace (jester 'right'))
|
||||
;~(plug whitespace (jester 'outer'))
|
||||
;~(plug whitespace (jester 'then'))
|
||||
==
|
||||
++ predicate-part ~+ ;~ pose
|
||||
:: parse-aggregate
|
||||
value-literal-list
|
||||
;~(pose ;~(pfix whitespace parse-operator) parse-operator)
|
||||
parse-datum
|
||||
==
|
||||
++ parse-predicate
|
||||
(star ;~(less predicate-stop predicate-part))
|
||||
++ produce-predicate
|
||||
::
|
||||
:: 1. resolve operators into trees
|
||||
:: 2. determine deepest parenthesis nesting
|
||||
:: 3. work from deepest nesting up to resolve conjunctions into trees
|
||||
|= a=(list raw-predicate-component)
|
||||
~& "raw-predicate2: {<a>}"
|
||||
^- predicate:ast
|
||||
=/ b=[@ud (list raw-predicate-component)] (resolve-depth (resolve-operators a))
|
||||
=/ target-depth=@ud -.b
|
||||
=/ working-list=(list raw-predicate-component) +.b
|
||||
=/ parm=[(list raw-predicate-component) (list predicate:ast)] [working-list ~]
|
||||
|-
|
||||
?. (gth target-depth 0)
|
||||
:: ~| "target-depth: {<target-depth>}"
|
||||
:: ~| "-.parm: {<-.parm>}"
|
||||
:: ~| "+.parm: {<+.parm>}"
|
||||
::`predicate:ast`(snag 0 `(list predicate:ast)`+:(resolve-conjunctions [target-depth `(list raw-predicate-component)`-.parm `(list predicate:ast)`+.parm]))
|
||||
::(snag 0 +:(resolve-conjunctions [target-depth -.parm +.parm]))
|
||||
+<:(resolve-conjunctions [target-depth -.parm +.parm])
|
||||
%= $
|
||||
target-depth (sub target-depth 1)
|
||||
parm (resolve-conjunctions [target-depth -.parm +.parm])
|
||||
==
|
||||
++ predicate-state-machine
|
||||
|= parsed=(list raw-predicate-component2)
|
||||
^- predicate:ast
|
||||
@ -1024,6 +684,17 @@
|
||||
?~ l.working-tree !!
|
||||
?~ r.working-tree !!
|
||||
!!
|
||||
all-any-operator:ast
|
||||
?~ working-tree ~|("operator {<-.parsed>} can only follow equality or inequality operator" !!)
|
||||
?~ r.working-tree
|
||||
?: ?&(?=(binary-operator:ast n.working-tree) ?!(=(%in n.working-tree)))
|
||||
?> ?=(qualified-column:ast +<.parsed) :: to do: this must resolve to a CTE
|
||||
%= $
|
||||
working-tree [-.working-tree +<.working-tree [-.parsed [+<.parsed ~ ~] ~]]
|
||||
parsed +>.parsed
|
||||
==
|
||||
~|("operator {<-.parsed>} can only follow equality or inequality operator" !!)
|
||||
~|("can't get here" !!)
|
||||
qualified-column:ast
|
||||
?~ working-tree
|
||||
?: ?=(binary-operator:ast +<.parsed)
|
||||
@ -1043,12 +714,24 @@
|
||||
[%not [%between (predicate-state-machine ~[-.parsed %gte +>+<.parsed]) (predicate-state-machine ~[-.parsed %lte +>+>-.parsed])] ~]
|
||||
parsed +>+>+.parsed
|
||||
==
|
||||
!!
|
||||
?~ l.working-tree
|
||||
?: =(%between +<.parsed)
|
||||
?: =(%and +>+<.parsed)
|
||||
%= $
|
||||
working-tree [-.working-tree [-.parsed ~ ~] ~]
|
||||
parsed +.parsed
|
||||
working-tree
|
||||
[%between (predicate-state-machine ~[-.parsed %gte +>-.parsed]) (predicate-state-machine ~[-.parsed %lte +>+>-.parsed])]
|
||||
parsed +>+>+.parsed
|
||||
==
|
||||
%= $
|
||||
working-tree
|
||||
[%between (predicate-state-machine ~[-.parsed %gte +>-.parsed]) (predicate-state-machine ~[-.parsed %lte +>+<.parsed])]
|
||||
parsed +>+>.parsed
|
||||
==
|
||||
!!
|
||||
:: ?~ l.working-tree :: probably do not have to address this case
|
||||
:: %= $
|
||||
:: working-tree [-.working-tree [-.parsed ~ ~] ~]
|
||||
:: parsed +.parsed
|
||||
:: ==
|
||||
?~ r.working-tree
|
||||
%= $
|
||||
working-tree [-.working-tree +<.working-tree [-.parsed ~ ~]]
|
||||
@ -1280,25 +963,6 @@
|
||||
(cold %order-by ;~(plug whitespace (jester 'order') whitespace (jester 'by')))
|
||||
(more com parse-ordering-column)
|
||||
==
|
||||
::@@@@@@@@@@@@@@@@@@@@@@
|
||||
::++ produce-joins
|
||||
:: |= a=* ::(list *)
|
||||
:: =/ joins=(list joined-object:ast) ~
|
||||
:: ^- (list joined-object:ast)
|
||||
:: |-
|
||||
:: ?: =(a ~) (flop joins)
|
||||
:: ?: ?=(joined-object:ast -.a) $(joins [-.a joins], a +.a)
|
||||
::(crash "cannot produce join from {<-.a>}")
|
||||
:: !!
|
||||
::++ produce-from
|
||||
:: |= a=* ::(list *)
|
||||
:: ^- from:ast
|
||||
:: ?: =(%query-object -<.a) ::?&(=(%query-object -<.a) (gth (lent a) 0))
|
||||
:: ?: =(+.a ~) (from:ast %from -.a ~)
|
||||
:: (from:ast -.a (produce-joins +.a))
|
||||
::(crash "cannot produce query-object from {<-.a>}")
|
||||
:: !!
|
||||
::@@@@@@@@@@@@@@@@@@@@@@
|
||||
++ produce-from
|
||||
|= a=*
|
||||
^- from:ast
|
||||
|
@ -74,11 +74,10 @@
|
||||
+$ ternary-operator %between
|
||||
+$ inequality-operator ?(%neq %gt %gte %lt %lte)
|
||||
+$ all-any-operator ?(%all %any)
|
||||
+$ binary-operator ?(%eq inequality-operator %distinct %not-distinct %in all-any-operator)
|
||||
+$ binary-operator ?(%eq inequality-operator %distinct %not-distinct %in)
|
||||
+$ unary-operator ?(%not %exists)
|
||||
+$ conjunction ?(%and %or)
|
||||
+$ ops-and-conjs ?(ternary-operator binary-operator unary-operator conjunction)
|
||||
::+$ predicate-component ?(ternary-operator binary-operator unary-operator conjunction qualified-column value-literal value-literal-list) :: aggregate)
|
||||
+$ ops-and-conjs ?(ternary-operator binary-operator unary-operator all-any-operator conjunction)
|
||||
+$ predicate-component ?(ops-and-conjs qualified-column value-literal value-literal-list) :: aggregate)
|
||||
+$ predicate (tree predicate-component)
|
||||
+$ datum $%(qualified-column value-literal)
|
||||
|
@ -975,159 +975,6 @@
|
||||
++ king-and [%and [second-and] last-or]
|
||||
|
||||
|
||||
++ test-predicate-12
|
||||
%+ expect-eq
|
||||
!> [%between foobar-gte-foo foobar-lte-bar]
|
||||
!> (wonk (parse-predicate:parse [[1 1] " foobar Between foo And bar"]))
|
||||
++ test-predicate-13
|
||||
%+ expect-eq
|
||||
!> [%between foobar-gte-foo foobar-lte-bar]
|
||||
!> (wonk (parse-predicate:parse [[1 1] "foobar Between foo bar"]))
|
||||
++ test-predicate-14
|
||||
%+ expect-eq
|
||||
!> [%gte t1-foo [%all bar ~]]
|
||||
!> (wonk (parse-predicate:parse [[1 1] "T1.foo>=aLl bar"]))
|
||||
++ test-predicate-15
|
||||
%+ expect-eq
|
||||
!> [%not [%in t1-foo bar] ~]
|
||||
!> (wonk (parse-predicate:parse [[1 1] "T1.foo nOt In bar"]))
|
||||
++ test-predicate-16
|
||||
%+ expect-eq
|
||||
!> [%not [%in t1-foo value-literal-list] ~]
|
||||
!> (wonk (parse-predicate:parse [[1 1] "T1.foo not in (1,2,3)"]))
|
||||
++ test-predicate-17
|
||||
%+ expect-eq
|
||||
!> [%in t1-foo bar]
|
||||
!> (wonk (parse-predicate:parse [[1 1] "T1.foo in bar"]))
|
||||
++ test-predicate-18
|
||||
%+ expect-eq
|
||||
!> [%in t1-foo value-literal-list]
|
||||
!> (wonk (parse-predicate:parse [[1 1] "T1.foo in (1,2,3)"]))
|
||||
++ test-predicate-19
|
||||
%+ expect-eq
|
||||
!> [%not [%exists t1-foo ~] ~]
|
||||
!> (wonk (parse-predicate:parse [[1 1] "NOT EXISTS T1.foo"]))
|
||||
++ test-predicate-20
|
||||
%+ expect-eq
|
||||
!> [%not [%exists foo ~] ~]
|
||||
!> (wonk (parse-predicate:parse [[1 1] "NOT exists foo"]))
|
||||
++ test-predicate-21
|
||||
%+ expect-eq
|
||||
!> [%exists t1-foo ~]
|
||||
!> (wonk (parse-predicate:parse [[1 1] "EXISTS T1.foo"]))
|
||||
++ test-predicate-22
|
||||
%+ expect-eq
|
||||
!> [%exists foo ~]
|
||||
!> (wonk (parse-predicate:parse [[1 1] "EXISTS foo"]))
|
||||
::
|
||||
:: test conjunctions, varying spacing and keyword casing
|
||||
++ test-predicate-23
|
||||
%+ expect-eq
|
||||
!> and-fb-gte-f--fb-lte-b
|
||||
!> (wonk (parse-predicate:parse [[1 1] "foobar >=foo And foobar<=bar"]))
|
||||
++ test-predicate-24
|
||||
=/ predicate "foobar >=foo And foobar<=bar ".
|
||||
" and T1.foo2 = ~zod"
|
||||
%+ expect-eq
|
||||
!> and-and
|
||||
!> (wonk (parse-predicate:parse [[1 1] predicate]))
|
||||
++ test-predicate-25
|
||||
=/ predicate "foobar >=foo And foobar<=bar ".
|
||||
" and T1.foo2 = ~zod ".
|
||||
" or T2.bar in (1,2,3)"
|
||||
%+ expect-eq
|
||||
!> and-and-or
|
||||
!> (wonk (parse-predicate:parse [[1 1] predicate]))
|
||||
++ test-predicate-26
|
||||
=/ predicate "foobar >=foo And foobar<=bar ".
|
||||
" and T1.foo2 = ~zod ".
|
||||
" or ".
|
||||
" foobar>=foo ".
|
||||
" AND T1.foo2=~zod"
|
||||
%+ expect-eq
|
||||
!> and-and-or-and
|
||||
!> (wonk (parse-predicate:parse [[1 1] predicate]))
|
||||
++ test-predicate-27
|
||||
=/ predicate "foobar >=foo And foobar<=bar ".
|
||||
" and T1.foo2 = ~zod ".
|
||||
" or ".
|
||||
" foobar>=foo ".
|
||||
" AND T1.foo2=~zod ".
|
||||
" OR ".
|
||||
" foo = 1 ".
|
||||
" AND T1.foo3 < any (1,2,3)"
|
||||
%+ expect-eq
|
||||
!> and-and-or-and-or-and
|
||||
!> (wonk (parse-predicate:parse [[1 1] predicate]))
|
||||
::
|
||||
:: simple nesting
|
||||
++ test-predicate-28
|
||||
=/ predicate "(foobar > foo OR foobar < bar) ".
|
||||
" AND T1.foo>foo2 ".
|
||||
" AND T2.bar IN (1,2,3) ".
|
||||
" AND (T1.foo3< any (1,2,3) OR T1.foo2=~zod AND foo=1 ) "
|
||||
%+ expect-eq
|
||||
!> king-and
|
||||
!> (wonk (parse-predicate:parse [[1 1] predicate]))
|
||||
::
|
||||
:: nesting
|
||||
++ test-predicate-29
|
||||
=/ predicate "foobar > foo AND foobar < bar ".
|
||||
" AND ( T1.foo>foo2 AND T2.bar IN (1,2,3) ".
|
||||
" OR (T1.foo3< any (1,2,3) AND T1.foo2=~zod AND foo=1 ) ".
|
||||
" OR (foo3=foo4 AND foo5=foo6) ".
|
||||
" OR foo4=foo5 ".
|
||||
" ) ".
|
||||
" AND foo6=foo7"
|
||||
%+ expect-eq
|
||||
!> a-a-l-a-o-l-a-a-r-o-r-a-l-o-r-a
|
||||
!> (wonk (parse-predicate:parse [[1 1] predicate]))
|
||||
::
|
||||
:: simple nesting, superfluous () around entire predicate
|
||||
++ test-predicate-30
|
||||
=/ predicate "((foobar > foo OR foobar < bar) ".
|
||||
" AND T1.foo>foo2 ".
|
||||
" AND T2.bar IN (1,2,3) ".
|
||||
" AND (T1.foo3< any (1,2,3) OR T1.foo2=~zod AND foo=1 )) "
|
||||
%+ expect-eq
|
||||
!> king-and
|
||||
!> (wonk (parse-predicate:parse [[1 1] predicate]))
|
||||
::
|
||||
:: aggregate inequality
|
||||
++ test-predicate-31
|
||||
=/ predicate " count( foo ) > 10 "
|
||||
%+ expect-eq
|
||||
!> [%gt [aggregate-count-foo 0 0] literal-10]
|
||||
!> (wonk (parse-predicate:parse [[1 1] predicate]))
|
||||
::
|
||||
:: aggregate inequality, no whitespace
|
||||
++ test-predicate-32
|
||||
=/ predicate "count(foo) > 10"
|
||||
%+ expect-eq
|
||||
!> [%gt [aggregate-count-foo 0 0] literal-10]
|
||||
!> (wonk (parse-predicate:parse [[1 1] predicate]))
|
||||
::
|
||||
:: aggregate equality
|
||||
++ test-predicate-33
|
||||
=/ predicate "bar = count(foo)"
|
||||
%+ expect-eq
|
||||
!> [%eq bar [aggregate-count-foo 0 0]]
|
||||
!> (wonk (parse-predicate:parse [[1 1] predicate]))
|
||||
::
|
||||
:: complext predicate, bug test
|
||||
++ test-predicate-34
|
||||
=/ predicate " A1.adoption-email = A2.adoption-email ".
|
||||
" AND A1.adoption-date = A2.adoption-date ".
|
||||
" AND foo = bar ".
|
||||
" AND ((A1.name = A2.name AND A1.species > A2.species) ".
|
||||
" OR ".
|
||||
" (A1.name > A2.name AND A1.species = A2.species) ".
|
||||
" OR ".
|
||||
" (A1.name > A2.name AND A1.species > A2.species) ".
|
||||
" ) "
|
||||
%+ expect-eq
|
||||
!> [%and [%and [%and [%eq a1-adoption-email a2-adoption-email] [%eq a1-adoption-date a2-adoption-date]] [%eq foo bar]] [%or [%or [%and [%eq a1-name a2-name] [%gt a1-species a2-species]] [%and [%gt a1-name a2-name] [%eq a1-species a2-species]]] [%and [%gt a1-name a2-name] [%gt a1-species a2-species]]]]
|
||||
!> (wonk (parse-predicate:parse [[1 1] predicate]))
|
||||
::
|
||||
:: scalar
|
||||
::
|
||||
|
@ -160,5 +160,201 @@
|
||||
%+ expect-eq
|
||||
!> ~[expected]
|
||||
!> (parse:parse(current-database 'db1') query)
|
||||
++ test-predicate-12
|
||||
=/ query "FROM adoptions AS T1 JOIN adoptions AS T2 ON T1.foo = T2.bar ".
|
||||
" WHERE foobar Between foo And bar ".
|
||||
" SELECT *"
|
||||
=/ joinpred=(tree predicate-component:ast) [%eq t1-foo t2-bar]
|
||||
=/ pred=(tree predicate-component:ast) [%between foobar-gte-foo foobar-lte-bar]
|
||||
=/ expected=simple-query:ast
|
||||
[%simple-query [~ [%priori [~ [%from object=[%query-object object=[%qualified-object ship=~ database='db1' namespace='dbo' name='adoptions'] alias=[~ 'T1']] joins=~[[%joined-object join=%join object=[%query-object object=[%qualified-object ship=~ database='db1' namespace='dbo' name='adoptions'] alias=[~ 'T2']] predicate=`joinpred]]]] ~ `pred]] [%select top=~ bottom=~ distinct=%.n columns=~[%all]] ~]
|
||||
%+ expect-eq
|
||||
!> ~[expected]
|
||||
!> (parse:parse(current-database 'db1') query)
|
||||
++ test-predicate-13
|
||||
=/ query "FROM adoptions AS T1 JOIN adoptions AS T2 ON T1.foo = T2.bar ".
|
||||
" WHERE foobar between foo And bar ".
|
||||
" SELECT *"
|
||||
=/ joinpred=(tree predicate-component:ast) [%eq t1-foo t2-bar]
|
||||
=/ pred=(tree predicate-component:ast) [%between foobar-gte-foo foobar-lte-bar]
|
||||
=/ expected=simple-query:ast
|
||||
[%simple-query [~ [%priori [~ [%from object=[%query-object object=[%qualified-object ship=~ database='db1' namespace='dbo' name='adoptions'] alias=[~ 'T1']] joins=~[[%joined-object join=%join object=[%query-object object=[%qualified-object ship=~ database='db1' namespace='dbo' name='adoptions'] alias=[~ 'T2']] predicate=`joinpred]]]] ~ `pred]] [%select top=~ bottom=~ distinct=%.n columns=~[%all]] ~]
|
||||
%+ expect-eq
|
||||
!> ~[expected]
|
||||
!> (parse:parse(current-database 'db1') query)
|
||||
++ test-predicate-14
|
||||
=/ query "FROM adoptions AS T1 JOIN adoptions AS T2 ON T1.foo = T2.bar ".
|
||||
" WHERE T1.foo>=aLl bar ".
|
||||
" SELECT *"
|
||||
=/ joinpred=(tree predicate-component:ast) [%eq t1-foo t2-bar]
|
||||
=/ pred=(tree predicate-component:ast) [%gte t1-foo [%all bar ~]]
|
||||
=/ expected=simple-query:ast
|
||||
[%simple-query [~ [%priori [~ [%from object=[%query-object object=[%qualified-object ship=~ database='db1' namespace='dbo' name='adoptions'] alias=[~ 'T1']] joins=~[[%joined-object join=%join object=[%query-object object=[%qualified-object ship=~ database='db1' namespace='dbo' name='adoptions'] alias=[~ 'T2']] predicate=`joinpred]]]] ~ `pred]] [%select top=~ bottom=~ distinct=%.n columns=~[%all]] ~]
|
||||
%+ expect-eq
|
||||
!> ~[expected]
|
||||
!> (parse:parse(current-database 'db1') query)
|
||||
::++ test-predicate-15
|
||||
:: %+ expect-eq
|
||||
:: !> [%not [%in t1-foo bar] ~]
|
||||
:: !> (wonk (parse-predicate:parse [[1 1] "T1.foo nOt In bar"]))
|
||||
::++ test-predicate-16
|
||||
:: %+ expect-eq
|
||||
:: !> [%not [%in t1-foo value-literal-list] ~]
|
||||
:: !> (wonk (parse-predicate:parse [[1 1] "T1.foo not in (1,2,3)"]))
|
||||
|
||||
++ test-predicate-17
|
||||
=/ query "FROM adoptions AS T1 JOIN adoptions AS T2 ON T1.foo = T2.bar ".
|
||||
" WHERE T1.foo in bar ".
|
||||
" SELECT *"
|
||||
=/ joinpred=(tree predicate-component:ast) [%eq t1-foo t2-bar]
|
||||
=/ pred=(tree predicate-component:ast) [%in t1-foo bar]
|
||||
=/ expected=simple-query:ast
|
||||
[%simple-query [~ [%priori [~ [%from object=[%query-object object=[%qualified-object ship=~ database='db1' namespace='dbo' name='adoptions'] alias=[~ 'T1']] joins=~[[%joined-object join=%join object=[%query-object object=[%qualified-object ship=~ database='db1' namespace='dbo' name='adoptions'] alias=[~ 'T2']] predicate=`joinpred]]]] ~ `pred]] [%select top=~ bottom=~ distinct=%.n columns=~[%all]] ~]
|
||||
%+ expect-eq
|
||||
!> ~[expected]
|
||||
!> (parse:parse(current-database 'db1') query)
|
||||
|
||||
++ test-predicate-18
|
||||
:: %+ expect-eq
|
||||
:: !> [%in t1-foo value-literal-list]
|
||||
:: !> (wonk (parse-predicate:parse [[1 1] "T1.foo in (1,2,3)"]))
|
||||
=/ query "FROM adoptions AS T1 JOIN adoptions AS T2 ON T1.foo = T2.bar ".
|
||||
" WHERE T1.foo in (1,2,3) ".
|
||||
" SELECT *"
|
||||
=/ joinpred=(tree predicate-component:ast) [%eq t1-foo t2-bar]
|
||||
=/ pred=(tree predicate-component:ast) [%in t1-foo value-literal-list]
|
||||
=/ expected=simple-query:ast
|
||||
[%simple-query [~ [%priori [~ [%from object=[%query-object object=[%qualified-object ship=~ database='db1' namespace='dbo' name='adoptions'] alias=[~ 'T1']] joins=~[[%joined-object join=%join object=[%query-object object=[%qualified-object ship=~ database='db1' namespace='dbo' name='adoptions'] alias=[~ 'T2']] predicate=`joinpred]]]] ~ `pred]] [%select top=~ bottom=~ distinct=%.n columns=~[%all]] ~]
|
||||
%+ expect-eq
|
||||
!> ~[expected]
|
||||
!> (parse:parse(current-database 'db1') query)
|
||||
|
||||
|
||||
|
||||
::++ test-predicate-19
|
||||
:: %+ expect-eq
|
||||
:: !> [%not [%exists t1-foo ~] ~]
|
||||
:: !> (wonk (parse-predicate:parse [[1 1] "NOT EXISTS T1.foo"]))
|
||||
::++ test-predicate-20
|
||||
:: %+ expect-eq
|
||||
:: !> [%not [%exists foo ~] ~]
|
||||
:: !> (wonk (parse-predicate:parse [[1 1] "NOT exists foo"]))
|
||||
::++ test-predicate-21
|
||||
:: %+ expect-eq
|
||||
:: !> [%exists t1-foo ~]
|
||||
:: !> (wonk (parse-predicate:parse [[1 1] "EXISTS T1.foo"]))
|
||||
::++ test-predicate-22
|
||||
:: %+ expect-eq
|
||||
:: !> [%exists foo ~]
|
||||
:: !> (wonk (parse-predicate:parse [[1 1] "EXISTS foo"]))
|
||||
::
|
||||
:: test conjunctions, varying spacing and keyword casing
|
||||
::++ test-predicate-23
|
||||
:: %+ expect-eq
|
||||
:: !> and-fb-gte-f--fb-lte-b
|
||||
:: !> (wonk (parse-predicate:parse [[1 1] "foobar >=foo And foobar<=bar"]))
|
||||
::++ test-predicate-24
|
||||
:: =/ predicate "foobar >=foo And foobar<=bar ".
|
||||
:: " and T1.foo2 = ~zod"
|
||||
:: %+ expect-eq
|
||||
:: !> and-and
|
||||
:: !> (wonk (parse-predicate:parse [[1 1] predicate]))
|
||||
::++ test-predicate-25
|
||||
:: =/ predicate "foobar >=foo And foobar<=bar ".
|
||||
:: " and T1.foo2 = ~zod ".
|
||||
:: " or T2.bar in (1,2,3)"
|
||||
:: %+ expect-eq
|
||||
:: !> and-and-or
|
||||
:: !> (wonk (parse-predicate:parse [[1 1] predicate]))
|
||||
::++ test-predicate-26
|
||||
:: =/ predicate "foobar >=foo And foobar<=bar ".
|
||||
:: " and T1.foo2 = ~zod ".
|
||||
:: " or ".
|
||||
:: " foobar>=foo ".
|
||||
:: " AND T1.foo2=~zod"
|
||||
:: %+ expect-eq
|
||||
:: !> and-and-or-and
|
||||
:: !> (wonk (parse-predicate:parse [[1 1] predicate]))
|
||||
::++ test-predicate-27
|
||||
:: =/ predicate "foobar >=foo And foobar<=bar ".
|
||||
:: " and T1.foo2 = ~zod ".
|
||||
:: " or ".
|
||||
:: " foobar>=foo ".
|
||||
:: " AND T1.foo2=~zod ".
|
||||
:: " OR ".
|
||||
:: " foo = 1 ".
|
||||
:: " AND T1.foo3 < any (1,2,3)"
|
||||
:: %+ expect-eq
|
||||
:: !> and-and-or-and-or-and
|
||||
:: !> (wonk (parse-predicate:parse [[1 1] predicate]))
|
||||
::
|
||||
:: simple nesting
|
||||
::++ test-predicate-28
|
||||
:: =/ predicate "(foobar > foo OR foobar < bar) ".
|
||||
:: " AND T1.foo>foo2 ".
|
||||
:: " AND T2.bar IN (1,2,3) ".
|
||||
:: " AND (T1.foo3< any (1,2,3) OR T1.foo2=~zod AND foo=1 ) "
|
||||
:: %+ expect-eq
|
||||
:: !> king-and
|
||||
:: !> (wonk (parse-predicate:parse [[1 1] predicate]))
|
||||
::
|
||||
:: nesting
|
||||
::++ test-predicate-29
|
||||
:: =/ predicate "foobar > foo AND foobar < bar ".
|
||||
:: " AND ( T1.foo>foo2 AND T2.bar IN (1,2,3) ".
|
||||
:: " OR (T1.foo3< any (1,2,3) AND T1.foo2=~zod AND foo=1 ) ".
|
||||
:: " OR (foo3=foo4 AND foo5=foo6) ".
|
||||
:: " OR foo4=foo5 ".
|
||||
:: " ) ".
|
||||
:: " AND foo6=foo7"
|
||||
:: %+ expect-eq
|
||||
:: !> a-a-l-a-o-l-a-a-r-o-r-a-l-o-r-a
|
||||
:: !> (wonk (parse-predicate:parse [[1 1] predicate]))
|
||||
::
|
||||
:: simple nesting, superfluous () around entire predicate
|
||||
::++ test-predicate-30
|
||||
:: =/ predicate "((foobar > foo OR foobar < bar) ".
|
||||
:: " AND T1.foo>foo2 ".
|
||||
:: " AND T2.bar IN (1,2,3) ".
|
||||
:: " AND (T1.foo3< any (1,2,3) OR T1.foo2=~zod AND foo=1 )) "
|
||||
:: %+ expect-eq
|
||||
:: !> king-and
|
||||
:: !> (wonk (parse-predicate:parse [[1 1] predicate]))
|
||||
::
|
||||
:: aggregate inequality
|
||||
::++ test-predicate-31
|
||||
:: =/ predicate " count( foo ) > 10 "
|
||||
:: %+ expect-eq
|
||||
:: !> [%gt [aggregate-count-foo 0 0] literal-10]
|
||||
:: !> (wonk (parse-predicate:parse [[1 1] predicate]))
|
||||
::
|
||||
:: aggregate inequality, no whitespace
|
||||
::++ test-predicate-32
|
||||
:: =/ predicate "count(foo) > 10"
|
||||
:: %+ expect-eq
|
||||
:: !> [%gt [aggregate-count-foo 0 0] literal-10]
|
||||
:: !> (wonk (parse-predicate:parse [[1 1] predicate]))
|
||||
::
|
||||
:: aggregate equality
|
||||
::++ test-predicate-33
|
||||
:: =/ predicate "bar = count(foo)"
|
||||
:: %+ expect-eq
|
||||
:: !> [%eq bar [aggregate-count-foo 0 0]]
|
||||
:: !> (wonk (parse-predicate:parse [[1 1] predicate]))
|
||||
::
|
||||
:: complext predicate, bug test
|
||||
::++ test-predicate-34
|
||||
:: =/ predicate " A1.adoption-email = A2.adoption-email ".
|
||||
:: " AND A1.adoption-date = A2.adoption-date ".
|
||||
:: " AND foo = bar ".
|
||||
:: " AND ((A1.name = A2.name AND A1.species > A2.species) ".
|
||||
:: " OR ".
|
||||
:: " (A1.name > A2.name AND A1.species = A2.species) ".
|
||||
:: " OR ".
|
||||
:: " (A1.name > A2.name AND A1.species > A2.species) ".
|
||||
:: " ) "
|
||||
:: %+ expect-eq
|
||||
:: !> [%and [%and [%and [%eq a1-adoption-email a2-adoption-email] [%eq a1-adoption-date a2-adoption-date]] [%eq foo bar]] [%or [%or [%and [%eq a1-name a2-name] [%gt a1-species a2-species]] [%and [%gt a1-name a2-name] [%eq a1-species a2-species]]] [%and [%gt a1-name a2-name] [%gt a1-species a2-species]]]]
|
||||
:: !> (wonk (parse-predicate:parse [[1 1] predicate]))
|
||||
|
||||
--
|
Loading…
Reference in New Issue
Block a user