Files
turso/testing/select.test
Alex Miller eb00226cfe Add support for CASE expressions.
There's two forms of case:
  CASE (WHEN [bool expr] THEN [value])+ (ELSE [value])? END
which checks a series of boolean conditions, and:
  CASE expr (WHEN [expr] THEN [value})+ (ELSE [value])? END
Which checks a series of equality conditions.

This implements support for both. Note that the ELSE is optional, and
will be equivalent to `ELSE null` if not specified.

sqlite3 gives the implementation as:

sqlite> explain select case a WHEN a THEN b WHEN c THEN d ELSE 0 END from casetest;
addr  opcode         p1    p2    p3    p4             p5  comment
----  -------------  ----  ----  ----  -------------  --  -------------
0     Init           0     16    0                    0   Start at 16
1     OpenRead       0     3     0     4              0   root=3 iDb=0; casetest
2     Rewind         0     15    0                    0
3       Column         0     0     2                    0   r[2]= cursor 0 column 0
4       Column         0     0     3                    0   r[3]= cursor 0 column 0
5       Ne             3     8     2     BINARY-8       83  if r[2]!=r[3] goto 8
6       Column         0     1     1                    0   r[1]= cursor 0 column 1
7       Goto           0     13    0                    0
8       Column         0     2     3                    0   r[3]= cursor 0 column 2
9       Ne             3     12    2     BINARY-8       83  if r[2]!=r[3] goto 12
10      Column         0     3     1                    0   r[1]= cursor 0 column 3
11      Goto           0     13    0                    0
12      Integer        0     1     0                    0   r[1]=0
13      ResultRow      1     1     0                    0   output=r[1]
14    Next           0     3     0                    1
15    Halt           0     0     0                    0
16    Transaction    0     0     2     0              1   usesStmtJournal=0
17    Goto           0     1     0                    0

and after this patch, limbo gives:

addr  opcode             p1    p2    p3    p4             p5  comment
----  -----------------  ----  ----  ----  -------------  --  -------
0     Init               0     18    0                    0   Start at 18
1     OpenReadAsync      0     4     0                    0   table=casetest, root=4
2     OpenReadAwait      0     0     0                    0
3     RewindAsync        0     0     0                    0
4     RewindAwait        0     17    0                    0   Rewind table casetest
5       Column           0     0     2                    0   r[2]=casetest.a
6       Column           0     0     3                    0   r[3]=casetest.a
7       Ne               2     3     10                   0   if r[2]!=r[3] goto 10
8       Column           0     1     1                    0   r[1]=casetest.b
9       Goto             0     14    0                    0
10      Column           0     2     3                    0   r[3]=casetest.c
11      Ne               2     3     14                   0   if r[2]!=r[3] goto 14
12      Column           0     3     1                    0   r[1]=casetest.d
13      Goto             0     14    0                    0
14      ResultRow        1     1     0                    0   output=r[1]
15    NextAsync          0     0     0                    0
16    NextAwait          0     5     0                    0
17    Halt               0     0     0                    0
18    Transaction        0     0     0                    0
19    Integer            0     1     0                    0   r[1]=0
20    Goto               0     1     0                    0

And then as there's nowhere to annotate this new support in COMPAT.md, I
added a corresponding heading for SELECT expressions and what is/isn't
supported.
2024-12-08 14:09:03 -08:00

77 lines
1.7 KiB
Tcl
Executable File

#!/usr/bin/env tclsh
set testdir [file dirname $argv0]
source $testdir/tester.tcl
do_execsql_test select-const-1 {
SELECT 1
} {1}
do_execsql_test select-const-2 {
SELECT 2
} {2}
do_execsql_test select-blob-empty {
SELECT x'';
} {}
do_execsql_test select-blob-ascii {
SELECT x'6C696D626f';
} {limbo}
do_execsql_test select-blob-emoji {
SELECT x'F09FA680';
} {🦀}
do_execsql_test select-limit-0 {
SELECT id FROM users LIMIT 0;
} {}
do_execsql_test realify {
select price from products limit 1;
} {79.0}
do_execsql_test select-add {
select u.age + 1 from users u where u.age = 91 limit 1;
} {92}
do_execsql_test select-subtract {
select u.age - 1 from users u where u.age = 91 limit 1;
} {90}
do_execsql_test case-insensitive-columns {
select u.aGe + 1 from USERS u where U.AGe = 91 limit 1;
} {92}
do_execsql_test table-star {
select p.*, p.name from products p limit 1;
} {1|hat|79.0|hat}
do_execsql_test table-star-2 {
select p.*, u.first_name from users u join products p on u.id = p.id limit 1;
} {1|hat|79.0|Jamie}
do_execsql_test seekrowid {
select * from users u where u.id = 5;
} {"5|Edward|Miller|christiankramer@example.com|725-281-1033|08522 English Plain|Lake Keith|ID|23283|15"}
do_execsql_test select_parenthesized {
select (price + 100) from products limit 1;
} {179.0}
do_execsql_test select_case_base_else {
select case when 0 then 0 when 1 then 1 else 2 end;
} {1}
do_execsql_test select_case_noelse_null {
select case when 0 then 0 end;
} {}
do_execsql_test select_base_case_else {
select case 1 when 0 then 0 when 1 then 1 else 2 end;
} {1}
do_execsql_test select_base_case_noelse_null {
select case 4 when 0 then 0 when 1 then 1 end;
} {}