scalar functions and fix to predicate

This commit is contained in:
jackfoxy 2022-10-05 13:00:47 -07:00
parent c7a34596fc
commit 9995434833
5 changed files with 321 additions and 114 deletions

View File

@ -5,9 +5,10 @@ FROM [ <ship-qualifer> ]<table-view> [ [AS] <alias> ]
[ { { JOIN | LEFT JOIN | RIGHT JOIN | OUTER JOIN [ALL] }
[ <ship-qualifer> ]<table-view> [ [AS] <alias> ]
ON <predicate>
} [ ,...n ]
} [ ...n ]
| CROSS JOIN
]
[ { SCALAR <scalar-name> [ AS ] <scalar-function> } [ ...n ] ]
[ WHERE <predicate> ]
SELECT [ TOP <n> | BOTTOM <n> ] [ DISTINCT ]
{ *
@ -15,11 +16,9 @@ SELECT [ TOP <n> | BOTTOM <n> ] [ DISTINCT ]
{ [<ship-qualifer>]<table-view> | <alias> }.*
| { <qualified-column> | <constant> } [ [ AS ] <column-alias> ]
| <column-alias> = { <qualified-column> | <constant> }
| <scalar-name>
} [ ,...n ]
}
[ SCALAR [ [ AS ] { [^..^]<column-name> | [^..^]<column-alias> | <ordinal> } ]
{ <expression> | (TBD) *hoon }
]
[ GROUP BY { <column> | <column-ordinal> } [ ,...n ]
[ HAVING <predicate> ]
[ AGGREGATE [ [ AS ] { [^..^]<column-name> | [^..^]<column-alias> | <ordinal> } ]
@ -35,10 +34,6 @@ SELECT [ TOP <n> | BOTTOM <n> ] [ DISTINCT ]
| DIVIDED BY [ WITH REMAINDER ]
```
```
<qualified-column> ::=
```
[ [ <ship-qualifer> ]<table-view> | <alias> } ].<column>
```
<predicate> ::=
{ [ NOT ] <predicate> | ( <simple-predicate> ) }
@ -58,11 +53,23 @@ SELECT [ TOP <n> | BOTTOM <n> ] [ DISTINCT ]
| [ NOT ] EXISTS { <column-value> | <cte-one-column-query> } }
```
```
<scalar-function> ::=
IF <predicate> THEN { <expression> | <scalar-function> } ELSE { <expression> | <scalar-function> } ENDIF
| CASE <expression>
WHEN { <expression> | <predicate> } THEN { <expression> | <scalar-function> } [ ...n ]
[ ELSE { <expression> | <scalar-function> } ]
END
| COALESCE ( <expression> [ ,...n ] )
| BEGIN <arithmetic on expressions and scalar functions> END
| *hoon (TBD)
```
```
<expression> ::=
{
constant
| <column-value>
| <column>
| <scalar-function>
}
```
@ -72,6 +79,11 @@ SELECT [ TOP <n> | BOTTOM <n> ] [ DISTINCT ]
{ = | <> | != | > | >= | !> | < | <= | !< }
```
```
<qualified-column> ::=
[ [ <ship-qualifer> ]<table-view> | <alias> } ].<column>
```
```
`<column> ::=
{ [ { <alias>. | <table-view>. } ]<column-name>
@ -79,17 +91,6 @@ SELECT [ TOP <n> | BOTTOM <n> ] [ DISTINCT ]
| <column-alias> }
```
```
<scalar-function> ::=
IF <predicate> THEN <expression> ELSE <expression> ENDIF
| CASE <expression>`
WHEN { <predicate> | <expression> } THEN <expression> [ ...n ]
[ ELSE <expression> ]
END
| COALESCE ( <expression> [ ,...n ] )
| native hoon (stretch goal)
```
Discussion:
Not shown in diagrams, parentheses distinguish order of operations for binary conjunctions `AND` and `OR`.

View File

@ -51,6 +51,7 @@ Reading and/or updating data on foreign ships is allowed provided the ship's pil
## Issues
1. how to handle views shadowing tables
2. relational division
2. BUG: superfluous predicate nesting crashes
3. stored procedures
4. https://github.com/sigilante/l10n localization of date/time
5. BUG: numeric literal on left side of boolean operator must be separated by whitespace from operator

View File

@ -755,12 +755,7 @@
$(b.a +.b.a, resolved [-.b.a resolved], working-depth (add working-depth 1))
?. =(working-depth target-depth.a)
$(b.a +.b.a, resolved [-.b.a resolved])
=. working-tree ~
|-
=/ lentba (lent b.a)
~| "crashed b.a length: {<lentba>}"
~| "crashed b.a: {<b.a>}"
~| "crashed working-tree: {<working-tree>}"
::
:: if there are superfluous levels of nesting we will end up here
?: =(b.a ~) ^$(resolved [working-tree resolved])
@ -815,14 +810,14 @@
=/ working-list +.b
|-
?. (gth target-depth 0)
(resolve-conjunctions [target-depth working-list])
(snag 0 (resolve-conjunctions [target-depth working-list]))
%= $
target-depth (sub target-depth 1)
working-list (resolve-conjunctions [target-depth working-list])
==
++ predicate-stop ;~ pose
;~(plug whitespace mic)
mic
mic
;~(plug whitespace (jester 'where'))
;~(plug whitespace (jester 'select'))
;~(plug whitespace (jester 'as'))
@ -830,14 +825,153 @@
;~(plug whitespace (jester 'left'))
;~(plug whitespace (jester 'right'))
;~(plug whitespace (jester 'outer'))
;~(plug whitespace (jester 'then'))
==
++ parse-datum ~+ ;~ pose
;~(pose ;~(pfix whitespace parse-qualified-column) parse-qualified-column)
;~(pose ;~(pfix whitespace parse-value-literal) parse-value-literal)
==
++ predicate-part ;~ pose ::
value-literal-list
;~(pose ;~(pfix whitespace parse-operator) parse-operator)
;~(pose ;~(pfix whitespace parse-qualified-column) parse-qualified-column)
;~(pose ;~(pfix whitespace parse-value-literal) parse-value-literal)
parse-datum
==
++ parse-predicate ~+ (cook cook-predicate (star ;~(less predicate-stop predicate-part)))
::
:: parse scalar
::
++ get-datum ~+ ;~ pose
;~(sfix ;~(pfix whitespace parse-qualified-column) whitespace)
;~(sfix ;~(pfix whitespace parse-value-literal) whitespace)
;~(pfix whitespace parse-qualified-column)
;~(pfix whitespace parse-value-literal)
;~(sfix parse-qualified-column whitespace)
;~(sfix parse-value-literal whitespace)
parse-qualified-column
parse-value-literal
==
++ cook-if
|= parsed=*
^- if-then-else:ast
(if-then-else:ast %if-then-else -.parsed +>-.parsed +>+>-.parsed)
++ parse-if ~+ ;~ plug
parse-predicate
;~(pfix whitespace (jester 'then'))
;~(pose parse-scalar-body-2 parse-datum)
;~(pfix whitespace (jester 'else'))
;~(pose parse-scalar-body-2 parse-datum)
;~(pfix whitespace (jester 'endif'))
==
++ parse-if-2 ~+ ;~ plug
parse-predicate
;~(pfix whitespace (jester 'then'))
;~(pose parse-scalar-body-3 parse-datum)
;~(pfix whitespace (jester 'else'))
;~(pose parse-scalar-body-3 parse-datum)
;~(pfix whitespace (jester 'endif'))
==
++ parse-if-3 ~+ ;~ plug
parse-predicate
;~(pfix whitespace (jester 'then'))
;~(pose parse-coalesce parse-datum)
;~(pfix whitespace (jester 'else'))
;~(pose parse-coalesce parse-datum)
;~(pfix whitespace (jester 'endif'))
==
++ parse-when-then ;~ plug
;~(pfix whitespace (jester 'when'))
;~(pose parse-predicate parse-datum)
;~(pfix whitespace (jester 'then'))
;~(pose parse-scalar-body-2 parse-datum)
==
++ parse-when-then-2 ;~ plug
;~(pfix whitespace (jester 'when'))
;~(pose parse-predicate parse-datum)
;~(pfix whitespace (jester 'then'))
;~(pose parse-scalar-body-3 parse-datum) :: ******can stay on level if not recursive
==
++ parse-when-then-3 ;~ plug
;~(pfix whitespace (jester 'when'))
;~(pose parse-predicate parse-datum)
;~(pfix whitespace (jester 'then'))
;~(pose parse-coalesce parse-datum)
==
++ parse-case-else ;~ plug
;~(pfix whitespace (jester 'else'))
;~(pfix whitespace ;~(pose parse-scalar-body-2 parse-datum))
;~(pfix whitespace (jester 'end'))
==
++ parse-case-else-2 ;~ plug
;~(pfix whitespace (jester 'else'))
;~(pfix whitespace ;~(pose parse-scalar-body-3 parse-datum))
;~(pfix whitespace (jester 'end'))
==
++ parse-case-else-3 ;~ plug
;~(pfix whitespace (jester 'else'))
;~(pfix whitespace ;~(pose parse-coalesce parse-datum))
;~(pfix whitespace (jester 'end'))
==
++ cook-case
|= parsed=*
=/ raw-cases +<.parsed
=/ cases=(list case-when-then:ast) ~
|-
?. =(raw-cases ~)
$(cases [(case-when-then:ast ->-.raw-cases ->+>.raw-cases) cases], raw-cases +.raw-cases)
?: ?=(qualified-column:ast -.parsed)
?: =('else' +>-.parsed) (case:ast %case -.parsed (flop cases) +>+<.parsed)
(case:ast %case -.parsed (flop cases) ~)
?: ?=(value-literal:ast -.parsed)
?: =('else' +>-.parsed) (case:ast %case -.parsed (flop cases) +>+<.parsed)
(case:ast %case -.parsed (flop cases) ~)
!!
++ parse-case ;~ plug
parse-datum
(star parse-when-then)
;~(pose parse-case-else ;~(pfix whitespace (jester 'end')))
==
++ parse-case-2 ;~ plug
parse-datum
(star parse-when-then-2)
;~(pose parse-case-else-2 ;~(pfix whitespace (jester 'end')))
==
++ parse-case-3 ;~ plug
parse-datum
(star parse-when-then-3)
;~(pose parse-case-else-3 ;~(pfix whitespace (jester 'end')))
==
++ cook-coalesce
|= parsed=(list datum:ast)
^- coalesce:ast
(coalesce:ast %coalesce parsed)
++ parse-coalesce ~+ (cook cook-coalesce (more com get-datum))
++ parse-scalar-body ~+ ;~ pose
;~(pfix (jester 'if') (cook cook-if parse-if))
;~(pfix (jester 'case') (cook cook-case parse-case))
;~(pfix (jester 'coalesce') parse-coalesce)
:: ;~(pfix (jester 'begin') parse-begin) :: to do
==
++ parse-scalar-body-2 ~+ ;~ pose
;~(pfix (jester 'if') (cook cook-if parse-if-2))
;~(pfix (jester 'case') (cook cook-case parse-case-2))
;~(pfix (jester 'coalesce') parse-coalesce)
:: ;~(pfix (jester 'begin') parse-begin) :: to do
==
++ parse-scalar-body-3 ~+ ;~ pose
;~(pfix (jester 'if') (cook cook-if parse-if-3))
;~(pfix (jester 'case') (cook cook-case parse-case-3))
;~(pfix (jester 'coalesce') parse-coalesce)
:: ;~(pfix (jester 'begin') parse-begin) :: to do
==
++ scalar-stop ;~ pose
;~(plug whitespace (jester 'where'))
;~(plug whitespace (jester 'scalar'))
==
++ scalar-body ;~(pfix whitespace parse-scalar-body)
++ parse-scalar ;~ pose
;~(plug ;~(sfix ;~(pfix whitespace ;~(pfix (jester 'scalar') parse-face)) ;~(plug whitespace (jester 'as'))) scalar-body)
;~(plug ;~(pfix whitespace ;~(pfix (jester 'scalar') parse-face)) scalar-body)
==
++ parse-predicate (cook cook-predicate (star ;~(less predicate-stop predicate-part)))
::
:: parse urQL command
::
@ -907,7 +1041,7 @@
++ parse-insert ;~ plug
;~(pfix whitespace parse-qualified-object)
;~(pose ;~(plug face-list ;~(pfix whitespace (jester 'values'))) ;~(pfix whitespace (jester 'values')))
;~(pfix whitespace (more whitespace (ifix [pal par] (more com parse-insert-value)))) :: insert-value-list
;~(pfix whitespace (more whitespace (ifix [pal par] (more com parse-insert-value))))
end-or-next-command
==
++ parse-query ;~ plug
@ -1304,14 +1438,14 @@
script q.q.u.+3.q:insert-nail
script-position next-cursor
commands
[`command-ast`(insert:ast %insert -.parsed ~ (insert-values:ast %expressions +>-.parsed)) commands]
[`command-ast`(insert:ast %insert -.parsed ~ (insert-values:ast %data +>-.parsed)) commands]
==
?: ?=([[@ @ @ @ @] [* @] *] [parsed]) ::"insert column names rows"
%= $
script q.q.u.+3.q:insert-nail
script-position next-cursor
commands
[`command-ast`(insert:ast %insert -.parsed `+<-.parsed (insert-values:ast %expressions +>-.parsed)) commands]
[`command-ast`(insert:ast %insert -.parsed `+<-.parsed (insert-values:ast %data +>-.parsed)) commands]
==
!!
%query

View File

@ -9,7 +9,6 @@
+$ all-or-any ?(%all %any)
+$ bool-conjunction ?(%and %or)
+$ object-type ?(%table %view)
+$ default-or-value-literal ?(%default value-literal)
+$ join-type ?(%join %left-join %right-join %outer-join %outer-join-all %cross-join)
+$ grant-permission ?(%adminread %readonly %readwrite)
+$ grantee ?(%parent %siblings %moons (list @p))
@ -23,6 +22,12 @@
value-type=@tas
value=@
==
+$ value-literal-list
$:
%value-literal-list
value-type=@tas
value-list=@t :: (crip ; delimited tape)
==
+$ ordered-column
$:
%ordered-column
@ -44,7 +49,7 @@
name=@t
==
+$ cte-name @t
+$ column-qualifier ?(qualified-object cte-name)
+$ column-qualifier $%(qualified-object cte-name)
+$ qualified-column
$:
%qualified-column
@ -74,51 +79,43 @@
+$ conjunction ?(%and %or)
+$ predicate-component ?(ternary-operator binary-operator unary-operator conjunction qualified-column value-literal value-literal-list)
+$ predicate * :: would like to be (tree predicate-component), but type system does not support
::
+$ value-literal-list
$:
%value-literal-list
value-type=@tas
value-list=@t
==
::
+$ expression
$%
default-or-value-literal
[%scalar-function scalar-function]
[%qualified-column qualified-column]
==
::
+$ datum $%(qualified-column value-literal)
+$ datum-or-scalar $@(datum scalar-function)
+$ if-then-else
$:
if=* :: predicate | bool expression
then=expression
else=expression
%if-then-else
if=* :: predicate
then=* :: datum-or-scalar
else=* :: datum-or-scalar
==
+$ case-when-then
$:
when=* :: predicate | bool expression
then=expression
when=* :: predicate | datum
then=* :: datum-or-scalar
==
+$ case
$:
target=expression
when-thens=(list case-when-then)
else=expression
%case
target=datum
cases=(list case-when-then)
else=* :: datum-or-scalar
==
+$ coalesce
$:
%coalesce
data=(list datum)
==
+$ subset-scalars $%([%if-then-else if-then-else] [%case case])
+$ coalesce (list subset-scalars)
+$ scalar-function
$%
[%if-then-else if-then-else]
[%case case]
[%coalesce coalesce]
if-then-else
case
coalesce
==
::
:: query
::
+$ query-object
$: ::
$:
%query-object
object=qualified-object
alias=(unit @t)
@ -176,7 +173,7 @@
predicate
==
+$ insert-values
$%([%expressions (list (list expression))] [%query query])
$%([%data (list (list datum))] [%query query])
+$ insert
$:
%insert
@ -184,7 +181,7 @@
columns=(unit (list @t))
values=insert-values
==
+$ value-or-default ?(%default expression)
+$ value-or-default ?(%default datum)
+$ update
$:
%update

View File

@ -693,8 +693,8 @@
:: 2) match column count to values count
:: 3) enforce consistent value counts across rows
++ test-insert-1
=/ expected1 [%insert table=[%qualified-object ship=~ database='db' namespace='ns' name='my-table'] columns=`['col1' 'col2' 'col3' 'col4' 'col5' 'col6' 'col7' 'col8' 'col9' ~] values=[%expressions ~[~[[~.t 1.685.221.219] [~.rs 1.078.523.331] [~.sd 39] [~.ud 20] [~.rs 1.078.523.331] [~.p 28.242.037] [~.rs 3.226.006.979] [~.t 430.158.540.643] [~.sd 6]] ~[[~.default 32.770.348.699.510.116] [~.if 3.284.569.946] [~.ud 195.198.143.900]]]]]
=/ expected2 [%insert table=[%qualified-object ship=~ database='db' namespace='dbo' name='my-table'] columns=`['col1' 'col2' 'col3' 'col4' 'col5' 'col6' 'col7' 'col8' 'col9' ~] values=[%expressions ~[~[[~.t 1.685.221.219] [~.rs 1.078.523.331] [~.sd 39] [~.ud 20] [~.rs 1.078.523.331] [~.p 28.242.037] [~.rs 3.226.006.979] [~.t 430.158.540.643] [~.sd 6]]]]]
=/ expected1 [%insert table=[%qualified-object ship=~ database='db' namespace='ns' name='my-table'] columns=`['col1' 'col2' 'col3' 'col4' 'col5' 'col6' 'col7' 'col8' 'col9' ~] values=[%data ~[~[[~.t 1.685.221.219] [~.rs 1.078.523.331] [~.sd 39] [~.ud 20] [~.rs 1.078.523.331] [~.p 28.242.037] [~.rs 3.226.006.979] [~.t 430.158.540.643] [~.sd 6]] ~[[~.default 32.770.348.699.510.116] [~.if 3.284.569.946] [~.ud 195.198.143.900]]]]]
=/ expected2 [%insert table=[%qualified-object ship=~ database='db' namespace='dbo' name='my-table'] columns=`['col1' 'col2' 'col3' 'col4' 'col5' 'col6' 'col7' 'col8' 'col9' ~] values=[%data ~[~[[~.t 1.685.221.219] [~.rs 1.078.523.331] [~.sd 39] [~.ud 20] [~.rs 1.078.523.331] [~.p 28.242.037] [~.rs 3.226.006.979] [~.t 430.158.540.643] [~.sd 6]]]]]
=/ urql1 " iNsert iNto db.ns.my-table ".
"( col1 , col2 , col3 , col4 , col5 , col6 , col7 , col8 , col9 )".
" Values ('cord',3.14,-20,20,3.14,~nomryg-nilref,-3.14, 'cor\\'d', --3)".
@ -708,7 +708,7 @@
::
:: table, no columns, 3 rows
++ test-insert-2
=/ expected [%insert table=[%qualified-object ship=~ database='db1' namespace='dbo' name='my-table'] columns=~ values=[%expressions ~[~[[~.t 1.685.221.219] [~.rs 1.078.523.331] [~.sd 39] [~.ud 20] [~.rs 1.078.523.331] [~.p 28.242.037] [~.rs 3.226.006.979] [~.t 430.158.540.643] [~.sd 6]] ~[[~.default 32.770.348.699.510.116] [~.if 3.284.569.946] [~.ud 195.198.143.900]] ~[[~.ud 2.222] [~.ud 2.222] [~.ud 195.198.143.900] [~.rs 1.078.523.331] [~.rs 3.226.006.979] [~.rd 4.614.253.070.214.989.087] [~.rd 13.837.625.107.069.764.895] [~.ux 1.205.249] [~.ub 43] [~.sd 39] [~.sd 40] [~.uw 61.764.130.813.526] [~.uw 1.870.418.170.505.042.572.886]]]]]
=/ expected [%insert table=[%qualified-object ship=~ database='db1' namespace='dbo' name='my-table'] columns=~ values=[%data ~[~[[~.t 1.685.221.219] [~.rs 1.078.523.331] [~.sd 39] [~.ud 20] [~.rs 1.078.523.331] [~.p 28.242.037] [~.rs 3.226.006.979] [~.t 430.158.540.643] [~.sd 6]] ~[[~.default 32.770.348.699.510.116] [~.if 3.284.569.946] [~.ud 195.198.143.900]] ~[[~.ud 2.222] [~.ud 2.222] [~.ud 195.198.143.900] [~.rs 1.078.523.331] [~.rs 3.226.006.979] [~.rd 4.614.253.070.214.989.087] [~.rd 13.837.625.107.069.764.895] [~.ux 1.205.249] [~.ub 43] [~.sd 39] [~.sd 40] [~.uw 61.764.130.813.526] [~.uw 1.870.418.170.505.042.572.886]]]]]
=/ urql "insert into my-table ".
"values ('cord',3.14,-20,20,3.14,~nomryg-nilref,-3.14, 'cor\\'d', --3)".
" (default,.195.198.143.90, 195.198.143.900)".
@ -719,7 +719,7 @@
::
:: every column type, no spaces around values
++ test-insert-3
=/ expected [%insert table=[%qualified-object ship=~ database='db' namespace='ns' name='my-table'] columns=~ values=[%expressions ~[~[[~.t 1.685.221.219] [~.p 28.242.037] [~.p 28.242.037] [~.da 170.141.184.504.830.774.788.415.618.594.688.204.800] [~.da 170.141.184.504.830.774.788.415.618.594.688.204.800] [~.dr 114.450.695.119.985.999.668.576.256] [~.dr 114.450.695.119.985.999.668.576.256] [~.if 3.284.569.946] [~.is 123.543.654.234] [~.f 0] [~.f 1] [~.f 0] [~.f 1] [~.ud 2.222] [~.ud 2.222] [~.ud 195.198.143.900] [~.rs 1.078.523.331] [~.rs 3.226.006.979] [~.rd 4.614.253.070.214.989.087] [~.rd 13.837.625.107.069.764.895] [~.ux 1.205.249] [~.ub 43] [~.sd 39] [~.sd 40] [~.uw 61.764.130.813.526] [~.uw 1.870.418.170.505.042.572.886]]]]]
=/ expected [%insert table=[%qualified-object ship=~ database='db' namespace='ns' name='my-table'] columns=~ values=[%data ~[~[[~.t 1.685.221.219] [~.p 28.242.037] [~.p 28.242.037] [~.da 170.141.184.504.830.774.788.415.618.594.688.204.800] [~.da 170.141.184.504.830.774.788.415.618.594.688.204.800] [~.dr 114.450.695.119.985.999.668.576.256] [~.dr 114.450.695.119.985.999.668.576.256] [~.if 3.284.569.946] [~.is 123.543.654.234] [~.f 0] [~.f 1] [~.f 0] [~.f 1] [~.ud 2.222] [~.ud 2.222] [~.ud 195.198.143.900] [~.rs 1.078.523.331] [~.rs 3.226.006.979] [~.rd 4.614.253.070.214.989.087] [~.rd 13.837.625.107.069.764.895] [~.ux 1.205.249] [~.ub 43] [~.sd 39] [~.sd 40] [~.uw 61.764.130.813.526] [~.uw 1.870.418.170.505.042.572.886]]]]]
=/ urql "insert into db.ns.my-table ".
"values ('cord',~nomryg-nilref,nomryg-nilref,~2020.12.25..7.15.0..1ef5,2020.12.25..7.15.0..1ef5,".
"~d71.h19.m26.s24..9d55, d71.h19.m26.s24..9d55,.195.198.143.90,.0.0.0.0.0.1c.c3c6.8f5a,y,n,Y,N,".
@ -730,7 +730,7 @@
::
:: every column type, spaces on all sides of values, comma inside cord
++ test-insert-4
=/ expected [%insert table=[%qualified-object ship=~ database='db' namespace='ns' name='my-table'] columns=~ values=[%expressions ~[~[[~.t 430.242.426.723] [~.p 28.242.037] [~.p 28.242.037] [~.da 170.141.184.504.830.774.788.415.618.594.688.204.800] [~.da 170.141.184.504.830.774.788.415.618.594.688.204.800] [~.dr 114.450.695.119.985.999.668.576.256] [~.dr 114.450.695.119.985.999.668.576.256] [~.if 3.284.569.946] [~.is 123.543.654.234] [~.f 0] [~.f 1] [~.f 0] [~.f 1] [~.ud 2.222] [~.ud 2.222] [~.ud 195.198.143.900] [~.rs 1.078.523.331] [~.rs 3.226.006.979] [~.rd 4.614.253.070.214.989.087] [~.rd 13.837.625.107.069.764.895] [~.ux 1.205.249] [~.ub 43] [~.sd 39] [~.sd 40] [~.uw 61.764.130.813.526] [~.uw 1.870.418.170.505.042.572.886]]]]]
=/ expected [%insert table=[%qualified-object ship=~ database='db' namespace='ns' name='my-table'] columns=~ values=[%data ~[~[[~.t 430.242.426.723] [~.p 28.242.037] [~.p 28.242.037] [~.da 170.141.184.504.830.774.788.415.618.594.688.204.800] [~.da 170.141.184.504.830.774.788.415.618.594.688.204.800] [~.dr 114.450.695.119.985.999.668.576.256] [~.dr 114.450.695.119.985.999.668.576.256] [~.if 3.284.569.946] [~.is 123.543.654.234] [~.f 0] [~.f 1] [~.f 0] [~.f 1] [~.ud 2.222] [~.ud 2.222] [~.ud 195.198.143.900] [~.rs 1.078.523.331] [~.rs 3.226.006.979] [~.rd 4.614.253.070.214.989.087] [~.rd 13.837.625.107.069.764.895] [~.ux 1.205.249] [~.ub 43] [~.sd 39] [~.sd 40] [~.uw 61.764.130.813.526] [~.uw 1.870.418.170.505.042.572.886]]]]]
=/ urql "insert into db.ns.my-table ".
"values ( 'cor,d' , ~nomryg-nilref , nomryg-nilref , ~2020.12.25..7.15.0..1ef5 , 2020.12.25..7.15.0..1ef5 , ".
"~d71.h19.m26.s24..9d55 , d71.h19.m26.s24..9d55 , .195.198.143.90 , .0.0.0.0.0.1c.c3c6.8f5a , y , n , Y , N , ".
@ -913,7 +913,6 @@
%- expect-fail
|. (parse:parse(current-database 'dummy') "truncate table ~shitty-shippp db.ns.nAme")
::
::
:: predicate
::
:: re-used components
@ -968,113 +967,113 @@
:: test binary operators, varying spacing
++ test-predicate-01
%+ expect-eq
!> ~[[%eq t1-foo t2-bar]]
!> [%eq t1-foo t2-bar]
!> (wonk (parse-predicate:parse [[1 1] "T1.foo = T2.bar"]))
++ test-predicate-02
%+ expect-eq
!> ~[[%neq foo bar]]
!> [%neq foo bar]
!> (wonk (parse-predicate:parse [[1 1] "foo<>bar"]))
++ test-predicate-03
%+ expect-eq
!> ~[[%neq foo bar]]
!> [%neq foo bar]
!> (wonk (parse-predicate:parse [[1 1] "foo!= bar"]))
++ test-predicate-04
%+ expect-eq
!> ~[[%gt foo bar]]
!> [%gt foo bar]
!> (wonk (parse-predicate:parse [[1 1] " foo >bar"]))
++ test-predicate-05
%+ expect-eq
!> ~[[%lt foo bar]]
!> [%lt foo bar]
!> (wonk (parse-predicate:parse [[1 1] " foo <bar"]))
++ test-predicate-06
%+ expect-eq
!> ~[[%gte foo bar]]
!> [%gte foo bar]
!> (wonk (parse-predicate:parse [[1 1] " foo>= bar"]))
++ test-predicate-07
%+ expect-eq
!> ~[[%gte foo bar]]
!> [%gte foo bar]
!> (wonk (parse-predicate:parse [[1 1] " foo!< bar"]))
++ test-predicate-08
%+ expect-eq
!> ~[[%lte foo bar]]
!> [%lte foo bar]
!> (wonk (parse-predicate:parse [[1 1] " foo <= bar"]))
++ test-predicate-09
%+ expect-eq
!> ~[[%lte foo bar]]
!> [%lte foo bar]
!> (wonk (parse-predicate:parse [[1 1] " foo !> bar"]))
::
:: remaining simple predicates, varying spacing and keywork casing
++ test-predicate-10
%+ expect-eq
!> ~[[%not [%between foobar-gte-foo foobar-lte-bar] ~]]
!> [%not [%between foobar-gte-foo foobar-lte-bar] ~]
!> (wonk (parse-predicate:parse [[1 1] " foobar Not Between foo And bar"]))
++ test-predicate-11
%+ expect-eq
!> ~[[%not [%between foobar-gte-foo foobar-lte-bar] ~]]
!> [%not [%between foobar-gte-foo foobar-lte-bar] ~]
!> (wonk (parse-predicate:parse [[1 1] " foobar Not Between foo bar"]))
++ test-predicate-12
%+ expect-eq
!> ~[[%between foobar-gte-foo foobar-lte-bar]]
!> [%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]]
!> [%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 ~]]]
!> [%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] ~]]
!> [%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] ~]]
!> [%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]]
!> [%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]]
!> [%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 ~] ~]]
!> [%not [%exists t1-foo ~] ~]
!> (wonk (parse-predicate:parse [[1 1] "NOT EXISTS T1.foo"]))
++ test-predicate-20
%+ expect-eq
!> ~[[%not [%exists foo ~] ~]]
!> [%not [%exists foo ~] ~]
!> (wonk (parse-predicate:parse [[1 1] "NOT exists foo"]))
++ test-predicate-21
%+ expect-eq
!> ~[[%exists t1-foo ~]]
!> [%exists t1-foo ~]
!> (wonk (parse-predicate:parse [[1 1] "EXISTS T1.foo"]))
++ test-predicate-22
%+ expect-eq
!> ~[[%exists foo ~]]
!> [%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]
!> 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]
!> 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]
!> and-and-or
!> (wonk (parse-predicate:parse [[1 1] predicate]))
++ test-predicate-26
=/ predicate "foobar >=foo And foobar<=bar ".
@ -1083,7 +1082,7 @@
" foobar>=foo ".
" AND T1.foo2=~zod"
%+ expect-eq
!> ~[and-and-or-and]
!> and-and-or-and
!> (wonk (parse-predicate:parse [[1 1] predicate]))
++ test-predicate-27
=/ predicate "foobar >=foo And foobar<=bar ".
@ -1095,7 +1094,7 @@
" foo = 1 ".
" AND T1.foo3 < any (1,2,3)"
%+ expect-eq
!> ~[and-and-or-and-or-and]
!> and-and-or-and-or-and
!> (wonk (parse-predicate:parse [[1 1] predicate]))
::
:: simple nesting
@ -1105,7 +1104,7 @@
" 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]
!> king-and
!> (wonk (parse-predicate:parse [[1 1] predicate]))
::
:: nesting
@ -1118,7 +1117,7 @@
" ) ".
" AND foo6=foo7"
%+ expect-eq
!> ~[a-a-l-a-o-l-a-a-r-o-r-a-l-o-r-a]
!> 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
@ -1128,19 +1127,94 @@
" 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]
!> king-and
!> (wonk (parse-predicate:parse [[1 1] predicate]))
::
:: nesting, superfluous ()
::++ test-predicate-30
:: =/ 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)"
:: scalar
::
++ column-foo [%qualified-column qualifier=[%qualified-object ship=~ database='UNKNOWN' namespace='COLUMN-OR-CTE' name='foo'] column='foo' alias=~]
++ column-foo2 [%qualified-column qualifier=[%qualified-object ship=~ database='UNKNOWN' namespace='COLUMN-OR-CTE' name='foo2'] column='foo2' alias=~]
++ column-foo3 [%qualified-column qualifier=[%qualified-object ship=~ database='UNKNOWN' namespace='COLUMN-OR-CTE' name='foo3'] column='foo3' alias=~]
++ column-bar [%qualified-column qualifier=[%qualified-object ship=~ database='UNKNOWN' namespace='COLUMN-OR-CTE' name='bar'] column='bar' alias=~]
++ litteral-zod [value-type=%p value=0]
++ litteral-1 [value-type=%ud value=1]
++ simple-coalesce [%coalesce data=~[column-bar litteral-zod litteral-1 column-foo]]
++ simple-if [%if-then-else if=[%eq [litteral-1 0 0] litteral-1 0 0] then=column-foo else=column-bar]
++ case-predicate [when=[%eq [litteral-1 0 0] litteral-1 0 0] then=column-foo]
++ case-datum [when=column-foo2 then=column-foo]
++ case-coalesce [when=column-foo3 then=simple-coalesce]
++ case-1 [%case target=column-foo3 cases=~[case-predicate] else=column-bar]
++ case-2 [%case target=column-foo3 cases=~[case-datum] else=column-bar]
++ case-3 [%case target=column-foo3 cases=~[case-datum case-predicate] else=column-bar]
++ case-4 [%case target=column-foo3 cases=~[case-datum case-predicate] else=simple-if]
++ case-5 [%case target=column-foo3 cases=~[case-datum case-predicate case-coalesce] else=simple-if]
:: coalesce
++ test-scalar-01
=/ scalar "SCALAR foobar COALESCE bar,~zod,1,foo"
%+ expect-eq
!> ['foobar' simple-coalesce]
!> (wonk (parse-scalar:parse [[1 1] scalar]))
::
:: coalesce as
++ test-scalar-02
=/ scalar "SCALAR foobar AS COALESCE bar,~zod,1,foo"
%+ expect-eq
!> ['foobar' simple-coalesce]
!> (wonk (parse-scalar:parse [[1 1] scalar]))
::
:: simple if
++ test-scalar-03
=/ scalar "SCALAR foobar IF 1 = 1 THEN foo ELSE bar ENDIF"
%+ expect-eq
!> ['foobar' simple-if]
!> (wonk (parse-scalar:parse [[1 1] scalar]))
::
:: simple if as
++ test-scalar-04
=/ scalar "SCALAR foobar AS IF 1 = 1 THEN foo ELSE bar ENDIF"
%+ expect-eq
!> ['foobar' simple-if]
!> (wonk (parse-scalar:parse [[1 1] scalar]))
::
:: simple case with predicate
++ test-scalar-05
=/ scalar "SCALAR foobar CASE foo3 WHEN 1 = 1 THEN foo ELSE bar END"
%+ expect-eq
!> ['foobar' case-1]
!> (wonk (parse-scalar:parse [[1 1] scalar]))
::
:: simple case AS with datum
++ test-scalar-06
=/ scalar "SCALAR foobar AS CASE foo3 WHEN foo2 THEN foo ELSE bar END"
%+ expect-eq
!> ['foobar' case-2]
!> (wonk (parse-scalar:parse [[1 1] scalar]))
::
:: simple case, 2 whens
++ test-scalar-07
=/ scalar "SCALAR foobar AS CASE foo3 WHEN foo2 THEN foo WHEN 1 = 1 THEN foo ELSE bar END"
%+ expect-eq
!> ['foobar' case-3]
!> (wonk (parse-scalar:parse [[1 1] scalar]))
::
:: 2 whens, embedded if for else
++ test-scalar-08
=/ scalar "SCALAR foobar AS CASE foo3 ".
" WHEN foo2 THEN foo WHEN 1 = 1 THEN foo ".
" ELSE IF 1 = 1 THEN foo ELSE bar ENDIF END"
%+ expect-eq
!> ['foobar' case-4]
!> (wonk (parse-scalar:parse [[1 1] scalar]))
::
:: 3 whens, coalesce, embedded if for else
::++ test-scalar-09
:: =/ scalar "SCALAR foobar AS CASE foo3 ".
::" WHEN foo2 THEN foo ".
::" WHEN 1 = 1 THEN foo ".
::" WHEN foo3 THEN COALESCE bar,~zod,1,foo ".
::" ELSE IF 1 = 1 THEN foo ELSE bar ENDIF END"
:: %+ 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]))
:: !> ['foobar' case-5]
:: !> (wonk (parse-scalar:parse [[1 1] scalar]))
--