/ Hex Artifact Content
Login

Artifact 40dec52119ed3a2b8b2a773bce24b63a3a746459:


0000: 23 20 52 75 6e 20 74 68 69 73 20 54 43 4c 20 73  # Run this TCL s
0010: 63 72 69 70 74 20 74 6f 20 67 65 6e 65 72 61 74  cript to generat
0020: 65 20 74 68 6f 75 73 61 6e 64 73 20 6f 66 20 74  e thousands of t
0030: 65 73 74 20 63 61 73 65 73 20 63 6f 6e 74 61 69  est cases contai
0040: 6e 69 6e 67 0a 23 20 63 6f 6d 70 6c 69 63 61 74  ning.# complicat
0050: 65 64 20 65 78 70 72 65 73 73 69 6f 6e 73 2e 0a  ed expressions..
0060: 23 0a 23 20 54 68 65 20 67 65 6e 65 72 61 74 65  #.# The generate
0070: 64 20 74 65 73 74 73 20 61 72 65 20 69 6e 74 65  d tests are inte
0080: 6e 64 65 64 20 74 6f 20 76 65 72 69 66 79 20 65  nded to verify e
0090: 78 70 72 65 73 73 69 6f 6e 20 65 76 61 6c 75 61  xpression evalua
00a0: 74 69 6f 6e 0a 23 20 69 6e 20 53 51 4c 69 74 65  tion.# in SQLite
00b0: 20 61 67 61 69 6e 73 74 20 65 78 70 72 65 73 73   against express
00c0: 69 6f 6e 20 65 76 61 6c 75 61 74 69 6f 6e 20 54  ion evaluation T
00d0: 43 4c 2e 20 20 0a 23 0a 0a 23 20 54 65 72 6d 73  CL.  .#..# Terms
00e0: 20 6f 66 20 74 68 65 20 24 69 6e 74 65 78 70 72   of the $intexpr
00f0: 20 6c 69 73 74 20 65 61 63 68 20 63 6f 6e 74 61   list each conta
0100: 69 6e 20 74 77 6f 20 73 75 62 2d 74 65 72 6d 73  in two sub-terms
0110: 2e 0a 23 0a 23 20 20 20 20 20 2a 20 20 41 6e 20  ..#.#     *  An 
0120: 53 51 4c 20 65 78 70 72 65 73 73 69 6f 6e 20 74  SQL expression t
0130: 65 6d 70 6c 61 74 65 0a 23 20 20 20 20 20 2a 20  emplate.#     * 
0140: 20 54 68 65 20 65 71 75 69 76 61 6c 65 6e 74 20   The equivalent 
0150: 54 43 4c 20 65 78 70 72 65 73 73 69 6f 6e 0a 23  TCL expression.#
0160: 0a 23 20 45 58 50 52 20 69 73 20 72 65 70 6c 61  .# EXPR is repla
0170: 63 65 64 20 62 79 20 61 6e 20 69 6e 74 65 67 65  ced by an intege
0180: 72 20 73 75 62 65 78 70 72 65 73 73 69 6f 6e 2e  r subexpression.
0190: 20 20 42 4f 4f 4c 20 69 73 20 72 65 70 6c 61 63    BOOL is replac
01a0: 65 64 0a 23 20 62 79 20 61 20 62 6f 6f 6c 65 61  ed.# by a boolea
01b0: 6e 20 73 75 62 65 78 70 72 65 73 73 69 6f 6e 2e  n subexpression.
01c0: 0a 23 0a 73 65 74 20 69 6e 74 65 78 70 72 20 7b  .#.set intexpr {
01d0: 0a 20 20 7b 31 31 20 77 69 64 65 28 31 31 29 7d  .  {11 wide(11)}
01e0: 0a 20 20 7b 31 33 20 77 69 64 65 28 31 33 29 7d  .  {13 wide(13)}
01f0: 0a 20 20 7b 31 37 20 77 69 64 65 28 31 37 29 7d  .  {17 wide(17)}
0200: 0a 20 20 7b 31 39 20 77 69 64 65 28 31 39 29 7d  .  {19 wide(19)}
0210: 0a 20 20 7b 61 20 24 61 7d 0a 20 20 7b 62 20 24  .  {a $a}.  {b $
0220: 62 7d 0a 20 20 7b 63 20 24 63 7d 0a 20 20 7b 64  b}.  {c $c}.  {d
0230: 20 24 64 7d 0a 20 20 7b 65 20 24 65 7d 0a 20 20   $d}.  {e $e}.  
0240: 7b 66 20 24 66 7d 0a 20 20 7b 74 31 2e 61 20 24  {f $f}.  {t1.a $
0250: 61 7d 0a 20 20 7b 74 31 2e 62 20 24 62 7d 0a 20  a}.  {t1.b $b}. 
0260: 20 7b 74 31 2e 63 20 24 63 7d 0a 20 20 7b 74 31   {t1.c $c}.  {t1
0270: 2e 64 20 24 64 7d 0a 20 20 7b 74 31 2e 65 20 24  .d $d}.  {t1.e $
0280: 65 7d 0a 20 20 7b 74 31 2e 66 20 24 66 7d 0a 20  e}.  {t1.f $f}. 
0290: 20 7b 28 45 58 50 52 29 20 28 45 58 50 52 29 7d   {(EXPR) (EXPR)}
02a0: 0a 20 20 7b 7b 20 2d 45 58 50 52 7d 20 7b 2d 45  .  {{ -EXPR} {-E
02b0: 58 50 52 7d 7d 0a 20 20 7b 2b 45 58 50 52 20 2b  XPR}}.  {+EXPR +
02c0: 45 58 50 52 7d 0a 20 20 7b 7e 45 58 50 52 20 7e  EXPR}.  {~EXPR ~
02d0: 45 58 50 52 7d 0a 20 20 7b 45 58 50 52 2b 45 58  EXPR}.  {EXPR+EX
02e0: 50 52 20 45 58 50 52 2b 45 58 50 52 7d 0a 20 20  PR EXPR+EXPR}.  
02f0: 7b 45 58 50 52 2d 45 58 50 52 20 45 58 50 52 2d  {EXPR-EXPR EXPR-
0300: 45 58 50 52 7d 0a 20 20 7b 45 58 50 52 2a 45 58  EXPR}.  {EXPR*EX
0310: 50 52 20 45 58 50 52 2a 45 58 50 52 7d 0a 20 20  PR EXPR*EXPR}.  
0320: 7b 45 58 50 52 2b 45 58 50 52 20 45 58 50 52 2b  {EXPR+EXPR EXPR+
0330: 45 58 50 52 7d 0a 20 20 7b 45 58 50 52 2d 45 58  EXPR}.  {EXPR-EX
0340: 50 52 20 45 58 50 52 2d 45 58 50 52 7d 0a 20 20  PR EXPR-EXPR}.  
0350: 7b 45 58 50 52 2a 45 58 50 52 20 45 58 50 52 2a  {EXPR*EXPR EXPR*
0360: 45 58 50 52 7d 0a 20 20 7b 45 58 50 52 2b 45 58  EXPR}.  {EXPR+EX
0370: 50 52 20 45 58 50 52 2b 45 58 50 52 7d 0a 20 20  PR EXPR+EXPR}.  
0380: 7b 45 58 50 52 2d 45 58 50 52 20 45 58 50 52 2d  {EXPR-EXPR EXPR-
0390: 45 58 50 52 7d 0a 20 20 7b 45 58 50 52 2a 45 58  EXPR}.  {EXPR*EX
03a0: 50 52 20 45 58 50 52 2a 45 58 50 52 7d 0a 20 20  PR EXPR*EXPR}.  
03b0: 7b 7b 45 58 50 52 20 7c 20 45 58 50 52 7d 20 7b  {{EXPR | EXPR} {
03c0: 45 58 50 52 20 7c 20 45 58 50 52 7d 7d 0a 20 20  EXPR | EXPR}}.  
03d0: 7b 28 61 62 73 28 45 58 50 52 29 2f 61 62 73 28  {(abs(EXPR)/abs(
03e0: 45 58 50 52 29 29 20 28 61 62 73 28 45 58 50 52  EXPR)) (abs(EXPR
03f0: 29 2f 61 62 73 28 45 58 50 52 29 29 7d 0a 20 20  )/abs(EXPR))}.  
0400: 7b 0a 20 20 20 20 7b 63 61 73 65 20 77 68 65 6e  {.    {case when
0410: 20 42 4f 4f 4c 20 74 68 65 6e 20 45 58 50 52 20   BOOL then EXPR 
0420: 65 6c 73 65 20 45 58 50 52 20 65 6e 64 7d 0a 20  else EXPR end}. 
0430: 20 20 20 7b 28 28 42 4f 4f 4c 29 3f 45 58 50 52     {((BOOL)?EXPR
0440: 3a 45 58 50 52 29 7d 0a 20 20 7d 0a 20 20 7b 0a  :EXPR)}.  }.  {.
0450: 20 20 20 20 7b 63 61 73 65 20 77 68 65 6e 20 42      {case when B
0460: 4f 4f 4c 20 74 68 65 6e 20 45 58 50 52 20 77 68  OOL then EXPR wh
0470: 65 6e 20 42 4f 4f 4c 20 74 68 65 6e 20 45 58 50  en BOOL then EXP
0480: 52 20 65 6c 73 65 20 45 58 50 52 20 65 6e 64 7d  R else EXPR end}
0490: 0a 20 20 20 20 7b 28 28 42 4f 4f 4c 29 3f 45 58  .    {((BOOL)?EX
04a0: 50 52 3a 28 28 42 4f 4f 4c 29 3f 45 58 50 52 3a  PR:((BOOL)?EXPR:
04b0: 45 58 50 52 29 29 7d 0a 20 20 7d 0a 20 20 7b 0a  EXPR))}.  }.  {.
04c0: 20 20 20 20 7b 63 61 73 65 20 45 58 50 52 20 77      {case EXPR w
04d0: 68 65 6e 20 45 58 50 52 20 74 68 65 6e 20 45 58  hen EXPR then EX
04e0: 50 52 20 65 6c 73 65 20 45 58 50 52 20 65 6e 64  PR else EXPR end
04f0: 7d 0a 20 20 20 20 7b 28 28 28 45 58 50 52 29 3d  }.    {(((EXPR)=
0500: 3d 28 45 58 50 52 29 29 3f 45 58 50 52 3a 45 58  =(EXPR))?EXPR:EX
0510: 50 52 29 7d 0a 20 20 7d 0a 20 20 7b 0a 20 20 20  PR)}.  }.  {.   
0520: 20 7b 28 73 65 6c 65 63 74 20 41 47 47 20 66 72   {(select AGG fr
0530: 6f 6d 20 74 31 29 7d 0a 20 20 20 20 7b 28 41 47  om t1)}.    {(AG
0540: 47 29 7d 0a 20 20 7d 0a 20 20 7b 0a 20 20 20 20  G)}.  }.  {.    
0550: 7b 63 6f 61 6c 65 73 63 65 28 28 73 65 6c 65 63  {coalesce((selec
0560: 74 20 6d 61 78 28 45 58 50 52 29 20 66 72 6f 6d  t max(EXPR) from
0570: 20 74 31 20 77 68 65 72 65 20 42 4f 4f 4c 29 2c   t1 where BOOL),
0580: 45 58 50 52 29 7d 0a 20 20 20 20 7b 5b 63 6f 61  EXPR)}.    {[coa
0590: 6c 65 73 63 65 5f 73 75 62 71 75 65 72 79 20 5b  lesce_subquery [
05a0: 65 78 70 72 20 7b 45 58 50 52 7d 5d 20 5b 65 78  expr {EXPR}] [ex
05b0: 70 72 20 7b 42 4f 4f 4c 7d 5d 20 5b 65 78 70 72  pr {BOOL}] [expr
05c0: 20 7b 45 58 50 52 7d 5d 5d 7d 0a 20 20 7d 0a 20   {EXPR}]]}.  }. 
05d0: 20 7b 0a 20 20 20 20 7b 63 6f 61 6c 65 73 63 65   {.    {coalesce
05e0: 28 28 73 65 6c 65 63 74 20 45 58 50 52 20 66 72  ((select EXPR fr
05f0: 6f 6d 20 74 31 20 77 68 65 72 65 20 42 4f 4f 4c  om t1 where BOOL
0600: 29 2c 45 58 50 52 29 7d 0a 20 20 20 20 7b 5b 63  ),EXPR)}.    {[c
0610: 6f 61 6c 65 73 63 65 5f 73 75 62 71 75 65 72 79  oalesce_subquery
0620: 20 5b 65 78 70 72 20 7b 45 58 50 52 7d 5d 20 5b   [expr {EXPR}] [
0630: 65 78 70 72 20 7b 42 4f 4f 4c 7d 5d 20 5b 65 78  expr {BOOL}] [ex
0640: 70 72 20 7b 45 58 50 52 7d 5d 5d 7d 0a 20 20 7d  pr {EXPR}]]}.  }
0650: 0a 7d 0a 0a 23 20 54 68 65 20 24 62 6f 6f 6c 65  .}..# The $boole
0660: 78 70 72 20 6c 69 73 74 20 63 6f 6e 74 61 69 6e  xpr list contain
0670: 73 20 74 65 72 6d 73 20 74 68 61 74 20 73 68 6f  s terms that sho
0680: 77 20 62 6f 74 68 20 61 6e 20 53 51 4c 20 62 6f  w both an SQL bo
0690: 6f 6c 65 61 6e 0a 23 20 65 78 70 72 65 73 73 69  olean.# expressi
06a0: 6f 6e 20 61 6e 64 20 69 74 73 20 65 71 75 69 76  on and its equiv
06b0: 61 6c 65 6e 74 20 54 43 4c 2e 0a 23 0a 73 65 74  alent TCL..#.set
06c0: 20 62 6f 6f 6c 65 78 70 72 20 7b 0a 20 20 7b 45   boolexpr {.  {E
06d0: 58 50 52 3d 45 58 50 52 20 20 20 28 28 45 58 50  XPR=EXPR   ((EXP
06e0: 52 29 3d 3d 28 45 58 50 52 29 29 7d 0a 20 20 7b  R)==(EXPR))}.  {
06f0: 45 58 50 52 3c 45 58 50 52 20 20 20 28 28 45 58  EXPR<EXPR   ((EX
0700: 50 52 29 3c 28 45 58 50 52 29 29 7d 0a 20 20 7b  PR)<(EXPR))}.  {
0710: 45 58 50 52 3e 45 58 50 52 20 20 20 28 28 45 58  EXPR>EXPR   ((EX
0720: 50 52 29 3e 28 45 58 50 52 29 29 7d 0a 20 20 7b  PR)>(EXPR))}.  {
0730: 45 58 50 52 3c 3d 45 58 50 52 20 20 28 28 45 58  EXPR<=EXPR  ((EX
0740: 50 52 29 3c 3d 28 45 58 50 52 29 29 7d 0a 20 20  PR)<=(EXPR))}.  
0750: 7b 45 58 50 52 3e 3d 45 58 50 52 20 20 28 28 45  {EXPR>=EXPR  ((E
0760: 58 50 52 29 3e 3d 28 45 58 50 52 29 29 7d 0a 20  XPR)>=(EXPR))}. 
0770: 20 7b 45 58 50 52 3c 3e 45 58 50 52 20 20 28 28   {EXPR<>EXPR  ((
0780: 45 58 50 52 29 21 3d 28 45 58 50 52 29 29 7d 0a  EXPR)!=(EXPR))}.
0790: 20 20 7b 0a 20 20 20 20 7b 45 58 50 52 20 62 65    {.    {EXPR be
07a0: 74 77 65 65 6e 20 45 58 50 52 20 61 6e 64 20 45  tween EXPR and E
07b0: 58 50 52 7d 0a 20 20 20 20 7b 5b 62 65 74 77 65  XPR}.    {[betwe
07c0: 65 6e 6f 70 20 5b 65 78 70 72 20 7b 45 58 50 52  enop [expr {EXPR
07d0: 7d 5d 20 5b 65 78 70 72 20 7b 45 58 50 52 7d 5d  }] [expr {EXPR}]
07e0: 20 5b 65 78 70 72 20 7b 45 58 50 52 7d 5d 5d 7d   [expr {EXPR}]]}
07f0: 0a 20 20 7d 0a 20 20 7b 0a 20 20 20 20 7b 45 58  .  }.  {.    {EX
0800: 50 52 20 6e 6f 74 20 62 65 74 77 65 65 6e 20 45  PR not between E
0810: 58 50 52 20 61 6e 64 20 45 58 50 52 7d 0a 20 20  XPR and EXPR}.  
0820: 20 20 7b 28 21 5b 62 65 74 77 65 65 6e 6f 70 20    {(![betweenop 
0830: 5b 65 78 70 72 20 7b 45 58 50 52 7d 5d 20 5b 65  [expr {EXPR}] [e
0840: 78 70 72 20 7b 45 58 50 52 7d 5d 20 5b 65 78 70  xpr {EXPR}] [exp
0850: 72 20 7b 45 58 50 52 7d 5d 5d 29 7d 0a 20 20 7d  r {EXPR}]])}.  }
0860: 0a 20 20 7b 0a 20 20 20 20 7b 45 58 50 52 20 69  .  {.    {EXPR i
0870: 6e 20 28 45 58 50 52 2c 45 58 50 52 2c 45 58 50  n (EXPR,EXPR,EXP
0880: 52 29 7d 0a 20 20 20 20 7b 28 5b 69 6e 6f 70 20  R)}.    {([inop 
0890: 5b 65 78 70 72 20 7b 45 58 50 52 7d 5d 20 5b 65  [expr {EXPR}] [e
08a0: 78 70 72 20 7b 45 58 50 52 7d 5d 20 5b 65 78 70  xpr {EXPR}] [exp
08b0: 72 20 7b 45 58 50 52 7d 5d 20 5b 65 78 70 72 20  r {EXPR}] [expr 
08c0: 7b 45 58 50 52 7d 5d 5d 29 7d 0a 20 20 7d 0a 20  {EXPR}]])}.  }. 
08d0: 20 7b 0a 20 20 20 20 7b 45 58 50 52 20 6e 6f 74   {.    {EXPR not
08e0: 20 69 6e 20 28 45 58 50 52 2c 45 58 50 52 2c 45   in (EXPR,EXPR,E
08f0: 58 50 52 29 7d 0a 20 20 20 20 7b 28 21 5b 69 6e  XPR)}.    {(![in
0900: 6f 70 20 5b 65 78 70 72 20 7b 45 58 50 52 7d 5d  op [expr {EXPR}]
0910: 20 5b 65 78 70 72 20 7b 45 58 50 52 7d 5d 20 5b   [expr {EXPR}] [
0920: 65 78 70 72 20 7b 45 58 50 52 7d 5d 20 5b 65 78  expr {EXPR}] [ex
0930: 70 72 20 7b 45 58 50 52 7d 5d 5d 29 7d 0a 20 20  pr {EXPR}]])}.  
0940: 7d 0a 20 20 7b 0a 20 20 20 20 7b 45 58 50 52 20  }.  {.    {EXPR 
0950: 69 6e 20 28 73 65 6c 65 63 74 20 45 58 50 52 20  in (select EXPR 
0960: 66 72 6f 6d 20 74 31 20 75 6e 69 6f 6e 20 73 65  from t1 union se
0970: 6c 65 63 74 20 45 58 50 52 20 66 72 6f 6d 20 74  lect EXPR from t
0980: 31 29 7d 0a 20 20 20 20 7b 5b 69 6e 6f 70 20 5b  1)}.    {[inop [
0990: 65 78 70 72 20 7b 45 58 50 52 7d 5d 20 5b 65 78  expr {EXPR}] [ex
09a0: 70 72 20 7b 45 58 50 52 7d 5d 20 5b 65 78 70 72  pr {EXPR}] [expr
09b0: 20 7b 45 58 50 52 7d 5d 5d 7d 0a 20 20 7d 0a 20   {EXPR}]]}.  }. 
09c0: 20 7b 0a 20 20 20 20 7b 45 58 50 52 20 69 6e 20   {.    {EXPR in 
09d0: 28 73 65 6c 65 63 74 20 41 47 47 20 66 72 6f 6d  (select AGG from
09e0: 20 74 31 20 75 6e 69 6f 6e 20 73 65 6c 65 63 74   t1 union select
09f0: 20 41 47 47 20 66 72 6f 6d 20 74 31 29 7d 0a 20   AGG from t1)}. 
0a00: 20 20 20 7b 5b 69 6e 6f 70 20 5b 65 78 70 72 20     {[inop [expr 
0a10: 7b 45 58 50 52 7d 5d 20 5b 65 78 70 72 20 7b 41  {EXPR}] [expr {A
0a20: 47 47 7d 5d 20 5b 65 78 70 72 20 7b 41 47 47 7d  GG}] [expr {AGG}
0a30: 5d 5d 7d 0a 20 20 7d 0a 20 20 7b 0a 20 20 20 20  ]]}.  }.  {.    
0a40: 7b 65 78 69 73 74 73 28 73 65 6c 65 63 74 20 31  {exists(select 1
0a50: 20 66 72 6f 6d 20 74 31 20 77 68 65 72 65 20 42   from t1 where B
0a60: 4f 4f 4c 29 7d 0a 20 20 20 20 7b 28 42 4f 4f 4c  OOL)}.    {(BOOL
0a70: 29 7d 0a 20 20 7d 0a 20 20 7b 0a 20 20 20 20 7b  )}.  }.  {.    {
0a80: 6e 6f 74 20 65 78 69 73 74 73 28 73 65 6c 65 63  not exists(selec
0a90: 74 20 31 20 66 72 6f 6d 20 74 31 20 77 68 65 72  t 1 from t1 wher
0aa0: 65 20 42 4f 4f 4c 29 7d 0a 20 20 20 20 7b 21 28  e BOOL)}.    {!(
0ab0: 42 4f 4f 4c 29 7d 0a 20 20 7d 0a 20 20 7b 7b 6e  BOOL)}.  }.  {{n
0ac0: 6f 74 20 42 4f 4f 4c 7d 20 20 21 42 4f 4f 4c 7d  ot BOOL}  !BOOL}
0ad0: 0a 20 20 7b 7b 42 4f 4f 4c 20 61 6e 64 20 42 4f  .  {{BOOL and BO
0ae0: 4f 4c 7d 20 7b 42 4f 4f 4c 20 74 63 6c 61 6e 64  OL} {BOOL tcland
0af0: 20 42 4f 4f 4c 7d 7d 0a 20 20 7b 7b 42 4f 4f 4c   BOOL}}.  {{BOOL
0b00: 20 6f 72 20 42 4f 4f 4c 7d 20 20 7b 42 4f 4f 4c   or BOOL}  {BOOL
0b10: 20 7c 7c 20 42 4f 4f 4c 7d 7d 0a 20 20 7b 7b 42   || BOOL}}.  {{B
0b20: 4f 4f 4c 20 61 6e 64 20 42 4f 4f 4c 7d 20 7b 42  OOL and BOOL} {B
0b30: 4f 4f 4c 20 74 63 6c 61 6e 64 20 42 4f 4f 4c 7d  OOL tcland BOOL}
0b40: 7d 0a 20 20 7b 7b 42 4f 4f 4c 20 6f 72 20 42 4f  }.  {{BOOL or BO
0b50: 4f 4c 7d 20 20 7b 42 4f 4f 4c 20 7c 7c 20 42 4f  OL}  {BOOL || BO
0b60: 4f 4c 7d 7d 0a 20 20 7b 28 42 4f 4f 4c 29 20 28  OL}}.  {(BOOL) (
0b70: 42 4f 4f 4c 29 7d 0a 20 20 7b 28 42 4f 4f 4c 29  BOOL)}.  {(BOOL)
0b80: 20 28 42 4f 4f 4c 29 7d 0a 7d 0a 0a 23 20 41 67   (BOOL)}.}..# Ag
0b90: 67 72 65 67 61 74 65 20 65 78 70 72 65 73 73 69  gregate expressi
0ba0: 6f 6e 73 0a 23 0a 73 65 74 20 61 67 67 65 78 70  ons.#.set aggexp
0bb0: 72 20 7b 0a 20 20 7b 63 6f 75 6e 74 28 2a 29 20  r {.  {count(*) 
0bc0: 77 69 64 65 28 31 29 7d 0a 20 20 7b 7b 63 6f 75  wide(1)}.  {{cou
0bd0: 6e 74 28 64 69 73 74 69 6e 63 74 20 45 58 50 52  nt(distinct EXPR
0be0: 29 7d 20 7b 5b 6f 6e 65 20 7b 45 58 50 52 7d 5d  )} {[one {EXPR}]
0bf0: 7d 7d 0a 20 20 7b 7b 63 61 73 74 28 61 76 67 28  }}.  {{cast(avg(
0c00: 45 58 50 52 29 20 41 53 20 69 6e 74 65 67 65 72  EXPR) AS integer
0c10: 29 7d 20 28 45 58 50 52 29 7d 0a 20 20 7b 6d 69  )} (EXPR)}.  {mi
0c20: 6e 28 45 58 50 52 29 20 28 45 58 50 52 29 7d 0a  n(EXPR) (EXPR)}.
0c30: 20 20 7b 6d 61 78 28 45 58 50 52 29 20 28 45 58    {max(EXPR) (EX
0c40: 50 52 29 7d 0a 20 20 7b 28 41 47 47 29 20 28 41  PR)}.  {(AGG) (A
0c50: 47 47 29 7d 0a 20 20 7b 7b 20 2d 41 47 47 7d 20  GG)}.  {{ -AGG} 
0c60: 7b 2d 41 47 47 7d 7d 0a 20 20 7b 2b 41 47 47 20  {-AGG}}.  {+AGG 
0c70: 2b 41 47 47 7d 0a 20 20 7b 7e 41 47 47 20 7e 41  +AGG}.  {~AGG ~A
0c80: 47 47 7d 0a 20 20 7b 61 62 73 28 41 47 47 29 20  GG}.  {abs(AGG) 
0c90: 20 61 62 73 28 41 47 47 29 7d 0a 20 20 7b 41 47   abs(AGG)}.  {AG
0ca0: 47 2b 41 47 47 20 20 20 41 47 47 2b 41 47 47 7d  G+AGG   AGG+AGG}
0cb0: 0a 20 20 7b 41 47 47 2d 41 47 47 20 20 20 41 47  .  {AGG-AGG   AG
0cc0: 47 2d 41 47 47 7d 0a 20 20 7b 41 47 47 2a 41 47  G-AGG}.  {AGG*AG
0cd0: 47 20 20 20 41 47 47 2a 41 47 47 7d 0a 20 20 7b  G   AGG*AGG}.  {
0ce0: 7b 41 47 47 20 7c 20 41 47 47 7d 20 20 7b 41 47  {AGG | AGG}  {AG
0cf0: 47 20 7c 20 41 47 47 7d 7d 0a 20 20 7b 0a 20 20  G | AGG}}.  {.  
0d00: 20 20 7b 63 61 73 65 20 41 47 47 20 77 68 65 6e    {case AGG when
0d10: 20 41 47 47 20 74 68 65 6e 20 41 47 47 20 65 6c   AGG then AGG el
0d20: 73 65 20 41 47 47 20 65 6e 64 7d 0a 20 20 20 20  se AGG end}.    
0d30: 7b 28 28 28 41 47 47 29 3d 3d 28 41 47 47 29 29  {(((AGG)==(AGG))
0d40: 3f 41 47 47 3a 41 47 47 29 7d 0a 20 20 7d 0a 7d  ?AGG:AGG)}.  }.}
0d50: 0a 0a 23 20 43 6f 6e 76 65 72 74 20 61 20 73 74  ..# Convert a st
0d60: 72 69 6e 67 20 63 6f 6e 74 61 69 6e 69 6e 67 20  ring containing 
0d70: 45 58 50 52 2c 20 41 47 47 2c 20 61 6e 64 20 42  EXPR, AGG, and B
0d80: 4f 4f 4c 20 69 6e 74 6f 20 61 20 73 74 72 69 6e  OOL into a strin
0d90: 67 0a 23 20 74 68 61 74 20 63 6f 6e 74 61 69 6e  g.# that contain
0da0: 73 20 6e 6f 74 68 69 6e 67 20 62 75 74 20 58 2c  s nothing but X,
0db0: 20 59 2c 20 61 6e 64 20 5a 2e 0a 23 0a 70 72 6f   Y, and Z..#.pro
0dc0: 63 20 65 78 74 72 61 63 74 5f 76 61 72 73 20 7b  c extract_vars {
0dd0: 61 7d 20 7b 0a 20 20 72 65 67 73 75 62 20 2d 61  a} {.  regsub -a
0de0: 6c 6c 20 7b 45 58 50 52 7d 20 24 61 20 58 20 61  ll {EXPR} $a X a
0df0: 0a 20 20 72 65 67 73 75 62 20 2d 61 6c 6c 20 7b  .  regsub -all {
0e00: 41 47 47 7d 20 24 61 20 59 20 61 0a 20 20 72 65  AGG} $a Y a.  re
0e10: 67 73 75 62 20 2d 61 6c 6c 20 7b 42 4f 4f 4c 7d  gsub -all {BOOL}
0e20: 20 24 61 20 5a 20 61 0a 20 20 72 65 67 73 75 62   $a Z a.  regsub
0e30: 20 2d 61 6c 6c 20 7b 5b 5e 58 59 5a 5d 7d 20 24   -all {[^XYZ]} $
0e40: 61 20 7b 7d 20 61 0a 20 20 72 65 74 75 72 6e 20  a {} a.  return 
0e50: 24 61 0a 7d 0a 0a 0a 23 20 54 65 73 74 20 61 6c  $a.}...# Test al
0e60: 6c 20 74 65 6d 70 6c 61 74 65 73 20 74 6f 20 6d  l templates to m
0e70: 61 6b 65 20 73 75 72 65 20 74 68 65 20 6e 75 6d  ake sure the num
0e80: 62 65 72 20 6f 66 20 45 58 50 52 2c 20 41 47 47  ber of EXPR, AGG
0e90: 2c 20 61 6e 64 20 42 4f 4f 4c 0a 23 20 65 78 70  , and BOOL.# exp
0ea0: 72 65 73 73 69 6f 6e 73 20 6d 61 74 63 68 2e 0a  ressions match..
0eb0: 23 0a 66 6f 72 65 61 63 68 20 74 65 72 6d 20 5b  #.foreach term [
0ec0: 63 6f 6e 63 61 74 20 24 61 67 67 65 78 70 72 20  concat $aggexpr 
0ed0: 24 69 6e 74 65 78 70 72 20 24 62 6f 6f 6c 65 78  $intexpr $boolex
0ee0: 70 72 5d 20 7b 0a 20 20 66 6f 72 65 61 63 68 20  pr] {.  foreach 
0ef0: 7b 61 20 62 7d 20 24 74 65 72 6d 20 62 72 65 61  {a b} $term brea
0f00: 6b 0a 20 20 69 66 20 7b 5b 65 78 74 72 61 63 74  k.  if {[extract
0f10: 5f 76 61 72 73 20 24 61 5d 21 3d 5b 65 78 74 72  _vars $a]!=[extr
0f20: 61 63 74 5f 76 61 72 73 20 24 62 5d 7d 20 7b 0a  act_vars $b]} {.
0f30: 20 20 20 20 65 72 72 6f 72 20 22 6d 69 73 6d 61      error "misma
0f40: 74 63 68 3a 20 24 74 65 72 6d 22 0a 20 20 7d 0a  tch: $term".  }.
0f50: 7d 0a 0a 23 20 47 65 6e 65 72 61 74 65 20 61 20  }..# Generate a 
0f60: 72 61 6e 64 6f 6d 20 65 78 70 72 65 73 73 69 6f  random expressio
0f70: 6e 20 61 63 63 6f 72 64 69 6e 67 20 74 6f 20 74  n according to t
0f80: 68 65 20 74 65 6d 70 6c 61 74 65 73 20 67 69 76  he templates giv
0f90: 65 6e 20 61 62 6f 76 65 2e 0a 23 20 49 66 20 74  en above..# If t
0fa0: 68 65 20 61 72 67 75 6d 65 6e 74 20 69 73 20 45  he argument is E
0fb0: 58 50 52 20 6f 72 20 6f 6d 69 74 74 65 64 2c 20  XPR or omitted, 
0fc0: 74 68 65 6e 20 61 6e 20 69 6e 74 65 67 65 72 20  then an integer 
0fd0: 65 78 70 72 65 73 73 69 6f 6e 20 69 73 0a 23 20  expression is.# 
0fe0: 67 65 6e 65 72 61 74 65 64 2e 20 20 49 66 20 74  generated.  If t
0ff0: 68 65 20 61 72 67 75 6d 65 6e 74 20 69 73 20 42  he argument is B
1000: 4f 4f 4c 20 74 68 65 6e 20 61 20 62 6f 6f 6c 65  OOL then a boole
1010: 61 6e 20 65 78 70 72 65 73 73 69 6f 6e 20 69 73  an expression is
1020: 0a 23 20 70 72 6f 64 75 63 65 64 2e 0a 23 0a 70  .# produced..#.p
1030: 72 6f 63 20 67 65 6e 65 72 61 74 65 5f 65 78 70  roc generate_exp
1040: 72 20 7b 7b 65 20 45 58 50 52 7d 7d 20 7b 0a 20  r {{e EXPR}} {. 
1050: 20 73 65 74 20 74 63 6c 65 20 24 65 0a 20 20 73   set tcle $e.  s
1060: 65 74 20 6e 65 20 5b 6c 6c 65 6e 67 74 68 20 24  et ne [llength $
1070: 3a 3a 69 6e 74 65 78 70 72 5d 0a 20 20 73 65 74  ::intexpr].  set
1080: 20 6e 62 20 5b 6c 6c 65 6e 67 74 68 20 24 3a 3a   nb [llength $::
1090: 62 6f 6f 6c 65 78 70 72 5d 0a 20 20 73 65 74 20  boolexpr].  set 
10a0: 6e 61 20 5b 6c 6c 65 6e 67 74 68 20 24 3a 3a 61  na [llength $::a
10b0: 67 67 65 78 70 72 5d 0a 20 20 73 65 74 20 64 69  ggexpr].  set di
10c0: 76 20 32 0a 20 20 73 65 74 20 6d 78 20 35 30 0a  v 2.  set mx 50.
10d0: 20 20 73 65 74 20 69 20 30 0a 20 20 77 68 69 6c    set i 0.  whil
10e0: 65 20 7b 31 7d 20 7b 0a 20 20 20 20 73 65 74 20  e {1} {.    set 
10f0: 63 6e 74 20 30 0a 20 20 20 20 73 65 74 20 72 65  cnt 0.    set re
1100: 20 5b 6c 69 6e 64 65 78 20 24 3a 3a 69 6e 74 65   [lindex $::inte
1110: 78 70 72 20 5b 65 78 70 72 20 7b 69 6e 74 28 72  xpr [expr {int(r
1120: 61 6e 64 28 29 2a 24 6e 65 29 7d 5d 5d 0a 20 20  and()*$ne)}]].  
1130: 20 20 69 6e 63 72 20 63 6e 74 20 5b 72 65 67 73    incr cnt [regs
1140: 75 62 20 7b 45 58 50 52 7d 20 24 65 20 5b 6c 69  ub {EXPR} $e [li
1150: 6e 64 65 78 20 24 72 65 20 30 5d 20 65 5d 0a 20  ndex $re 0] e]. 
1160: 20 20 20 72 65 67 73 75 62 20 7b 45 58 50 52 7d     regsub {EXPR}
1170: 20 24 74 63 6c 65 20 5b 6c 69 6e 64 65 78 20 24   $tcle [lindex $
1180: 72 65 20 31 5d 20 74 63 6c 65 0a 20 20 20 20 73  re 1] tcle.    s
1190: 65 74 20 72 62 20 5b 6c 69 6e 64 65 78 20 24 3a  et rb [lindex $:
11a0: 3a 62 6f 6f 6c 65 78 70 72 20 5b 65 78 70 72 20  :boolexpr [expr 
11b0: 7b 69 6e 74 28 72 61 6e 64 28 29 2a 24 6e 62 29  {int(rand()*$nb)
11c0: 7d 5d 5d 0a 20 20 20 20 69 6e 63 72 20 63 6e 74  }]].    incr cnt
11d0: 20 5b 72 65 67 73 75 62 20 7b 42 4f 4f 4c 7d 20   [regsub {BOOL} 
11e0: 24 65 20 5b 6c 69 6e 64 65 78 20 24 72 62 20 30  $e [lindex $rb 0
11f0: 5d 20 65 5d 0a 20 20 20 20 72 65 67 73 75 62 20  ] e].    regsub 
1200: 7b 42 4f 4f 4c 7d 20 24 74 63 6c 65 20 5b 6c 69  {BOOL} $tcle [li
1210: 6e 64 65 78 20 24 72 62 20 31 5d 20 74 63 6c 65  ndex $rb 1] tcle
1220: 0a 20 20 20 20 73 65 74 20 72 61 20 5b 6c 69 6e  .    set ra [lin
1230: 64 65 78 20 24 3a 3a 61 67 67 65 78 70 72 20 5b  dex $::aggexpr [
1240: 65 78 70 72 20 7b 69 6e 74 28 72 61 6e 64 28 29  expr {int(rand()
1250: 2a 24 6e 61 29 7d 5d 5d 0a 20 20 20 20 69 6e 63  *$na)}]].    inc
1260: 72 20 63 6e 74 20 5b 72 65 67 73 75 62 20 7b 41  r cnt [regsub {A
1270: 47 47 7d 20 24 65 20 5b 6c 69 6e 64 65 78 20 24  GG} $e [lindex $
1280: 72 61 20 30 5d 20 65 5d 0a 20 20 20 20 72 65 67  ra 0] e].    reg
1290: 73 75 62 20 7b 41 47 47 7d 20 24 74 63 6c 65 20  sub {AGG} $tcle 
12a0: 5b 6c 69 6e 64 65 78 20 24 72 61 20 31 5d 20 74  [lindex $ra 1] t
12b0: 63 6c 65 0a 0a 20 20 20 20 69 66 20 7b 24 63 6e  cle..    if {$cn
12c0: 74 3d 3d 30 7d 20 62 72 65 61 6b 0a 20 20 20 20  t==0} break.    
12d0: 69 6e 63 72 20 69 20 24 63 6e 74 0a 0a 20 20 20  incr i $cnt..   
12e0: 20 73 65 74 20 76 31 20 5b 65 78 74 72 61 63 74   set v1 [extract
12f0: 5f 76 61 72 73 20 24 65 5d 0a 20 20 20 20 69 66  _vars $e].    if
1300: 20 7b 24 76 31 21 3d 5b 65 78 74 72 61 63 74 5f   {$v1!=[extract_
1310: 76 61 72 73 20 24 74 63 6c 65 5d 7d 20 7b 0a 20  vars $tcle]} {. 
1320: 20 20 20 20 20 65 78 69 74 0a 20 20 20 20 7d 0a       exit.    }.
1330: 0a 20 20 20 20 69 66 20 7b 24 69 2b 5b 73 74 72  .    if {$i+[str
1340: 69 6e 67 20 6c 65 6e 67 74 68 20 24 76 31 5d 3e  ing length $v1]>
1350: 3d 24 6d 78 7d 20 7b 0a 20 20 20 20 20 20 73 65  =$mx} {.      se
1360: 74 20 6e 65 20 5b 65 78 70 72 20 7b 24 6e 65 2f  t ne [expr {$ne/
1370: 24 64 69 76 7d 5d 0a 20 20 20 20 20 20 73 65 74  $div}].      set
1380: 20 6e 62 20 5b 65 78 70 72 20 7b 24 6e 62 2f 24   nb [expr {$nb/$
1390: 64 69 76 7d 5d 0a 20 20 20 20 20 20 73 65 74 20  div}].      set 
13a0: 6e 61 20 5b 65 78 70 72 20 7b 24 6e 61 2f 24 64  na [expr {$na/$d
13b0: 69 76 7d 5d 0a 20 20 20 20 20 20 73 65 74 20 64  iv}].      set d
13c0: 69 76 20 31 0a 20 20 20 20 20 20 73 65 74 20 6d  iv 1.      set m
13d0: 78 20 5b 65 78 70 72 20 7b 24 6d 78 2a 31 30 30  x [expr {$mx*100
13e0: 30 7d 5d 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20  0}].    }.  }.  
13f0: 72 65 67 73 75 62 20 2d 61 6c 6c 20 7b 20 74 63  regsub -all { tc
1400: 6c 61 6e 64 20 7d 20 24 74 63 6c 65 20 7b 20 5c  land } $tcle { \
1410: 26 5c 26 20 7d 20 74 63 6c 65 0a 20 20 72 65 74  &\& } tcle.  ret
1420: 75 72 6e 20 5b 6c 69 73 74 20 24 65 20 24 74 63  urn [list $e $tc
1430: 6c 65 5d 0a 7d 0a 0a 23 20 49 6d 70 6c 65 6d 65  le].}..# Impleme
1440: 6e 74 61 74 69 6f 6e 20 6f 66 20 72 6f 75 74 69  ntation of routi
1450: 6e 65 73 20 75 73 65 64 20 74 6f 20 69 6d 70 6c  nes used to impl
1460: 65 6d 65 6e 74 20 74 68 65 20 49 4e 20 61 6e 64  ement the IN and
1470: 20 42 45 54 57 45 45 4e 0a 23 20 6f 70 65 72 61   BETWEEN.# opera
1480: 74 6f 72 73 2e 0a 70 72 6f 63 20 69 6e 6f 70 20  tors..proc inop 
1490: 7b 6c 68 73 20 61 72 67 73 7d 20 7b 0a 20 20 66  {lhs args} {.  f
14a0: 6f 72 65 61 63 68 20 61 20 24 61 72 67 73 20 7b  oreach a $args {
14b0: 0a 20 20 20 20 69 66 20 7b 24 61 3d 3d 24 6c 68  .    if {$a==$lh
14c0: 73 7d 20 7b 72 65 74 75 72 6e 20 31 7d 0a 20 20  s} {return 1}.  
14d0: 7d 0a 20 20 72 65 74 75 72 6e 20 30 0a 7d 0a 70  }.  return 0.}.p
14e0: 72 6f 63 20 62 65 74 77 65 65 6e 6f 70 20 7b 6c  roc betweenop {l
14f0: 68 73 20 66 69 72 73 74 20 73 65 63 6f 6e 64 7d  hs first second}
1500: 20 7b 0a 20 20 72 65 74 75 72 6e 20 5b 65 78 70   {.  return [exp
1510: 72 20 7b 24 6c 68 73 3e 3d 24 66 69 72 73 74 20  r {$lhs>=$first 
1520: 26 26 20 24 6c 68 73 3c 3d 24 73 65 63 6f 6e 64  && $lhs<=$second
1530: 7d 5d 0a 7d 0a 70 72 6f 63 20 63 6f 61 6c 65 73  }].}.proc coales
1540: 63 65 5f 73 75 62 71 75 65 72 79 20 7b 61 20 62  ce_subquery {a b
1550: 20 65 7d 20 7b 0a 20 20 69 66 20 7b 24 62 7d 20   e} {.  if {$b} 
1560: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 24 61 0a  {.    return $a.
1570: 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 72    } else {.    r
1580: 65 74 75 72 6e 20 24 65 0a 20 20 7d 0a 7d 0a 70  eturn $e.  }.}.p
1590: 72 6f 63 20 6f 6e 65 20 7b 61 72 67 73 7d 20 7b  roc one {args} {
15a0: 0a 20 20 72 65 74 75 72 6e 20 31 0a 7d 0a 0a 23  .  return 1.}..#
15b0: 20 42 65 67 69 6e 20 67 65 6e 65 72 61 74 69 6e   Begin generatin
15c0: 67 20 74 68 65 20 74 65 73 74 20 73 63 72 69 70  g the test scrip
15d0: 74 3a 0a 23 0a 70 75 74 73 20 7b 23 20 32 30 30  t:.#.puts {# 200
15e0: 38 20 44 65 63 65 6d 62 65 72 20 31 36 0a 23 0a  8 December 16.#.
15f0: 23 20 54 68 65 20 61 75 74 68 6f 72 20 64 69 73  # The author dis
1600: 63 6c 61 69 6d 73 20 63 6f 70 79 72 69 67 68 74  claims copyright
1610: 20 74 6f 20 74 68 69 73 20 73 6f 75 72 63 65 20   to this source 
1620: 63 6f 64 65 2e 20 20 49 6e 20 70 6c 61 63 65 20  code.  In place 
1630: 6f 66 0a 23 20 61 20 6c 65 67 61 6c 20 6e 6f 74  of.# a legal not
1640: 69 63 65 2c 20 68 65 72 65 20 69 73 20 61 20 62  ice, here is a b
1650: 6c 65 73 73 69 6e 67 3a 0a 23 0a 23 20 20 20 20  lessing:.#.#    
1660: 4d 61 79 20 79 6f 75 20 64 6f 20 67 6f 6f 64 20  May you do good 
1670: 61 6e 64 20 6e 6f 74 20 65 76 69 6c 2e 0a 23 20  and not evil..# 
1680: 20 20 20 4d 61 79 20 79 6f 75 20 66 69 6e 64 20     May you find 
1690: 66 6f 72 67 69 76 65 6e 65 73 73 20 66 6f 72 20  forgiveness for 
16a0: 79 6f 75 72 73 65 6c 66 20 61 6e 64 20 66 6f 72  yourself and for
16b0: 67 69 76 65 20 6f 74 68 65 72 73 2e 0a 23 20 20  give others..#  
16c0: 20 20 4d 61 79 20 79 6f 75 20 73 68 61 72 65 20    May you share 
16d0: 66 72 65 65 6c 79 2c 20 6e 65 76 65 72 20 74 61  freely, never ta
16e0: 6b 69 6e 67 20 6d 6f 72 65 20 74 68 61 6e 20 79  king more than y
16f0: 6f 75 20 67 69 76 65 2e 0a 23 0a 23 2a 2a 2a 2a  ou give..#.#****
1700: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1710: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1720: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1730: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1740: 2a 2a 2a 0a 23 20 54 68 69 73 20 66 69 6c 65 20  ***.# This file 
1750: 69 6d 70 6c 65 6d 65 6e 74 73 20 72 65 67 72 65  implements regre
1760: 73 73 69 6f 6e 20 74 65 73 74 73 20 66 6f 72 20  ssion tests for 
1770: 53 51 4c 69 74 65 20 6c 69 62 72 61 72 79 2e 0a  SQLite library..
1780: 23 0a 23 20 54 68 69 73 20 66 69 6c 65 20 74 65  #.# This file te
1790: 73 74 73 20 72 61 6e 64 6f 6d 6c 79 20 67 65 6e  sts randomly gen
17a0: 65 72 61 74 65 64 20 53 51 4c 20 65 78 70 72 65  erated SQL expre
17b0: 73 73 69 6f 6e 73 2e 20 20 54 68 65 20 65 78 70  ssions.  The exp
17c0: 72 65 73 73 69 6f 6e 73 0a 23 20 61 72 65 20 67  ressions.# are g
17d0: 65 6e 65 72 61 74 65 64 20 62 79 20 61 20 54 43  enerated by a TC
17e0: 4c 20 73 63 72 69 70 74 2e 20 20 54 68 65 20 73  L script.  The s
17f0: 61 6d 65 20 54 43 4c 20 73 63 72 69 70 74 20 61  ame TCL script a
1800: 6c 73 6f 20 63 6f 6d 70 75 74 65 73 20 74 68 65  lso computes the
1810: 0a 23 20 63 6f 72 72 65 63 74 20 76 61 6c 75 65  .# correct value
1820: 20 6f 66 20 74 68 65 20 65 78 70 72 65 73 73 69   of the expressi
1830: 6f 6e 2e 20 20 53 6f 2c 20 66 72 6f 6d 20 6f 6e  on.  So, from on
1840: 65 20 70 6f 69 6e 74 20 6f 66 20 76 69 65 77 2c  e point of view,
1850: 20 74 68 69 73 0a 23 20 66 69 6c 65 20 76 65 72   this.# file ver
1860: 69 66 69 65 73 20 74 68 65 20 65 78 70 72 65 73  ifies the expres
1870: 73 69 6f 6e 20 65 76 61 6c 75 61 74 69 6f 6e 20  sion evaluation 
1880: 6c 6f 67 69 63 20 6f 66 20 53 51 4c 69 74 65 20  logic of SQLite 
1890: 61 67 61 69 6e 73 74 20 74 68 65 0a 23 20 65 78  against the.# ex
18a0: 70 72 65 73 73 69 6f 6e 20 65 76 61 6c 75 61 74  pression evaluat
18b0: 69 6f 6e 20 6c 6f 67 69 63 20 6f 66 20 54 43 4c  ion logic of TCL
18c0: 2e 0a 23 0a 23 20 41 6e 20 65 61 72 6c 79 20 76  ..#.# An early v
18d0: 65 72 73 69 6f 6e 20 6f 66 20 74 68 69 73 20 73  ersion of this s
18e0: 63 72 69 70 74 20 69 73 20 68 6f 77 20 62 75 67  cript is how bug
18f0: 20 23 33 35 34 31 20 77 61 73 20 64 65 74 65 63   #3541 was detec
1900: 74 65 64 2e 0a 23 0a 23 20 24 49 64 3a 20 72 61  ted..#.# $Id: ra
1910: 6e 64 65 78 70 72 31 2e 74 63 6c 2c 76 20 31 2e  ndexpr1.tcl,v 1.
1920: 31 20 32 30 30 38 2f 31 32 2f 31 35 20 31 36 3a  1 2008/12/15 16:
1930: 33 33 3a 33 30 20 64 72 68 20 45 78 70 20 24 0a  33:30 drh Exp $.
1940: 73 65 74 20 74 65 73 74 64 69 72 20 5b 66 69 6c  set testdir [fil
1950: 65 20 64 69 72 6e 61 6d 65 20 24 61 72 67 76 30  e dirname $argv0
1960: 5d 0a 73 6f 75 72 63 65 20 24 74 65 73 74 64 69  ].source $testdi
1970: 72 2f 74 65 73 74 65 72 2e 74 63 6c 0a 0a 23 20  r/tester.tcl..# 
1980: 43 72 65 61 74 65 20 74 65 73 74 20 64 61 74 61  Create test data
1990: 0a 23 0a 64 6f 5f 74 65 73 74 20 72 61 6e 64 65  .#.do_test rande
19a0: 78 70 72 31 2d 31 2e 31 20 7b 0a 20 20 64 62 20  xpr1-1.1 {.  db 
19b0: 65 76 61 6c 20 7b 0a 20 20 20 20 43 52 45 41 54  eval {.    CREAT
19c0: 45 20 54 41 42 4c 45 20 74 31 28 61 2c 62 2c 63  E TABLE t1(a,b,c
19d0: 2c 64 2c 65 2c 66 29 3b 0a 20 20 20 20 49 4e 53  ,d,e,f);.    INS
19e0: 45 52 54 20 49 4e 54 4f 20 74 31 20 56 41 4c 55  ERT INTO t1 VALU
19f0: 45 53 28 31 30 30 2c 32 30 30 2c 33 30 30 2c 34  ES(100,200,300,4
1a00: 30 30 2c 35 30 30 2c 36 30 30 29 3b 0a 20 20 20  00,500,600);.   
1a10: 20 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 74   SELECT * FROM t
1a20: 31 0a 20 20 7d 0a 7d 20 7b 31 30 30 20 32 30 30  1.  }.} {100 200
1a30: 20 33 30 30 20 34 30 30 20 35 30 30 20 36 30 30   300 400 500 600
1a40: 7d 0a 7d 0a 0a 23 20 54 65 73 74 20 64 61 74 61  }.}..# Test data
1a50: 20 66 6f 72 20 54 43 4c 20 65 76 61 6c 75 61 74   for TCL evaluat
1a60: 69 6f 6e 2e 0a 23 0a 73 65 74 20 61 20 5b 65 78  ion..#.set a [ex
1a70: 70 72 20 7b 77 69 64 65 28 31 30 30 29 7d 5d 0a  pr {wide(100)}].
1a80: 73 65 74 20 62 20 5b 65 78 70 72 20 7b 77 69 64  set b [expr {wid
1a90: 65 28 32 30 30 29 7d 5d 0a 73 65 74 20 63 20 5b  e(200)}].set c [
1aa0: 65 78 70 72 20 7b 77 69 64 65 28 33 30 30 29 7d  expr {wide(300)}
1ab0: 5d 0a 73 65 74 20 64 20 5b 65 78 70 72 20 7b 77  ].set d [expr {w
1ac0: 69 64 65 28 34 30 30 29 7d 5d 0a 73 65 74 20 65  ide(400)}].set e
1ad0: 20 5b 65 78 70 72 20 7b 77 69 64 65 28 35 30 30   [expr {wide(500
1ae0: 29 7d 5d 0a 73 65 74 20 66 20 5b 65 78 70 72 20  )}].set f [expr 
1af0: 7b 77 69 64 65 28 36 30 30 29 7d 5d 0a 0a 23 20  {wide(600)}]..# 
1b00: 41 20 70 72 6f 63 65 64 75 72 65 20 74 6f 20 67  A procedure to g
1b10: 65 6e 65 72 61 74 65 20 61 20 74 65 73 74 20 63  enerate a test c
1b20: 61 73 65 2e 0a 23 0a 73 65 74 20 74 6e 20 30 0a  ase..#.set tn 0.
1b30: 70 72 6f 63 20 6d 61 6b 65 5f 74 65 73 74 5f 63  proc make_test_c
1b40: 61 73 65 20 7b 73 71 6c 20 72 65 73 75 6c 74 7d  ase {sql result}
1b50: 20 7b 0a 20 20 67 6c 6f 62 61 6c 20 74 6e 0a 20   {.  global tn. 
1b60: 20 69 6e 63 72 20 74 6e 0a 20 20 70 75 74 73 20   incr tn.  puts 
1b70: 22 64 6f 5f 74 65 73 74 20 72 61 6e 64 65 78 70  "do_test randexp
1b80: 72 2d 32 2e 24 74 6e 20 7b 5c 6e 20 20 64 62 20  r-2.$tn {\n  db 
1b90: 65 76 61 6c 20 7b 24 73 71 6c 7d 5c 6e 7d 20 7b  eval {$sql}\n} {
1ba0: 24 72 65 73 75 6c 74 7d 22 0a 7d 0a 0a 23 20 47  $result}".}..# G
1bb0: 65 6e 65 72 61 74 65 20 6d 61 6e 79 20 72 61 6e  enerate many ran
1bc0: 64 6f 6d 20 74 65 73 74 20 63 61 73 65 73 2e 0a  dom test cases..
1bd0: 23 0a 65 78 70 72 20 73 72 61 6e 64 28 30 29 0a  #.expr srand(0).
1be0: 66 6f 72 20 7b 73 65 74 20 69 20 30 7d 20 7b 24  for {set i 0} {$
1bf0: 69 3c 31 30 30 30 7d 20 7b 69 6e 63 72 20 69 7d  i<1000} {incr i}
1c00: 20 7b 0a 20 20 77 68 69 6c 65 20 7b 31 7d 20 7b   {.  while {1} {
1c10: 0a 20 20 20 20 66 6f 72 65 61 63 68 20 7b 73 71  .    foreach {sq
1c20: 6c 65 20 74 63 6c 65 7d 20 5b 67 65 6e 65 72 61  le tcle} [genera
1c30: 74 65 5f 65 78 70 72 20 45 58 50 52 5d 20 62 72  te_expr EXPR] br
1c40: 65 61 6b 3b 0a 20 20 20 20 69 66 20 7b 5b 63 61  eak;.    if {[ca
1c50: 74 63 68 20 7b 65 78 70 72 20 24 74 63 6c 65 7d  tch {expr $tcle}
1c60: 20 61 6e 73 5d 7d 20 7b 0a 20 20 20 20 20 20 23   ans]} {.      #
1c70: 70 75 74 73 20 73 74 64 65 72 72 20 5b 6c 69 73  puts stderr [lis
1c80: 74 20 24 74 63 6c 65 5d 0a 20 20 20 20 20 20 23  t $tcle].      #
1c90: 70 75 74 73 20 73 74 64 65 72 72 20 61 6e 73 3d  puts stderr ans=
1ca0: 24 61 6e 73 0a 20 20 20 20 20 20 69 66 20 7b 21  $ans.      if {!
1cb0: 5b 72 65 67 65 78 70 20 7b 64 69 76 69 64 65 20  [regexp {divide 
1cc0: 62 79 20 7a 65 72 6f 7d 20 24 61 6e 73 5d 7d 20  by zero} $ans]} 
1cd0: 65 78 69 74 0a 20 20 20 20 20 20 63 6f 6e 74 69  exit.      conti
1ce0: 6e 75 65 0a 20 20 20 20 7d 0a 20 20 20 20 73 65  nue.    }.    se
1cf0: 74 20 6c 65 6e 20 5b 73 74 72 69 6e 67 20 6c 65  t len [string le
1d00: 6e 67 74 68 20 24 73 71 6c 65 5d 0a 20 20 20 20  ngth $sqle].    
1d10: 69 66 20 7b 24 6c 65 6e 3c 31 30 30 20 7c 7c 20  if {$len<100 || 
1d20: 24 6c 65 6e 3e 32 30 30 30 7d 20 63 6f 6e 74 69  $len>2000} conti
1d30: 6e 75 65 0a 20 20 20 20 69 66 20 7b 5b 69 6e 66  nue.    if {[inf
1d40: 6f 20 65 78 69 73 74 73 20 73 65 65 6e 28 24 73  o exists seen($s
1d50: 71 6c 65 29 5d 7d 20 63 6f 6e 74 69 6e 75 65 0a  qle)]} continue.
1d60: 20 20 20 20 73 65 74 20 73 65 65 6e 28 24 73 71      set seen($sq
1d70: 6c 65 29 20 31 0a 20 20 20 20 62 72 65 61 6b 0a  le) 1.    break.
1d80: 20 20 7d 0a 20 20 77 68 69 6c 65 20 7b 31 7d 20    }.  while {1} 
1d90: 7b 0a 20 20 20 20 66 6f 72 65 61 63 68 20 7b 73  {.    foreach {s
1da0: 71 6c 62 20 74 63 6c 62 7d 20 5b 67 65 6e 65 72  qlb tclb} [gener
1db0: 61 74 65 5f 65 78 70 72 20 42 4f 4f 4c 5d 20 62  ate_expr BOOL] b
1dc0: 72 65 61 6b 3b 0a 20 20 20 20 69 66 20 7b 5b 63  reak;.    if {[c
1dd0: 61 74 63 68 20 7b 65 78 70 72 20 24 74 63 6c 62  atch {expr $tclb
1de0: 7d 20 62 61 6e 73 5d 7d 20 7b 0a 20 20 20 20 20  } bans]} {.     
1df0: 20 23 70 75 74 73 20 73 74 64 65 72 72 20 5b 6c   #puts stderr [l
1e00: 69 73 74 20 24 74 63 6c 62 5d 0a 20 20 20 20 20  ist $tclb].     
1e10: 20 23 70 75 74 73 20 73 74 64 65 72 72 20 62 61   #puts stderr ba
1e20: 6e 73 3d 24 62 61 6e 73 0a 20 20 20 20 20 20 69  ns=$bans.      i
1e30: 66 20 7b 21 5b 72 65 67 65 78 70 20 7b 64 69 76  f {![regexp {div
1e40: 69 64 65 20 62 79 20 7a 65 72 6f 7d 20 24 62 61  ide by zero} $ba
1e50: 6e 73 5d 7d 20 65 78 69 74 0a 20 20 20 20 20 20  ns]} exit.      
1e60: 63 6f 6e 74 69 6e 75 65 0a 20 20 20 20 7d 0a 20  continue.    }. 
1e70: 20 20 20 62 72 65 61 6b 0a 20 20 7d 0a 20 20 69     break.  }.  i
1e80: 66 20 7b 24 62 61 6e 73 7d 20 7b 0a 20 20 20 20  f {$bans} {.    
1e90: 6d 61 6b 65 5f 74 65 73 74 5f 63 61 73 65 20 22  make_test_case "
1ea0: 53 45 4c 45 43 54 20 24 73 71 6c 65 20 46 52 4f  SELECT $sqle FRO
1eb0: 4d 20 74 31 20 57 48 45 52 45 20 24 73 71 6c 62  M t1 WHERE $sqlb
1ec0: 22 20 24 61 6e 73 0a 20 20 20 20 6d 61 6b 65 5f  " $ans.    make_
1ed0: 74 65 73 74 5f 63 61 73 65 20 22 53 45 4c 45 43  test_case "SELEC
1ee0: 54 20 24 73 71 6c 65 20 46 52 4f 4d 20 74 31 20  T $sqle FROM t1 
1ef0: 57 48 45 52 45 20 4e 4f 54 20 28 24 73 71 6c 62  WHERE NOT ($sqlb
1f00: 29 22 20 7b 7d 0a 20 20 7d 20 65 6c 73 65 20 7b  )" {}.  } else {
1f10: 0a 20 20 20 20 6d 61 6b 65 5f 74 65 73 74 5f 63  .    make_test_c
1f20: 61 73 65 20 22 53 45 4c 45 43 54 20 24 73 71 6c  ase "SELECT $sql
1f30: 65 20 46 52 4f 4d 20 74 31 20 57 48 45 52 45 20  e FROM t1 WHERE 
1f40: 24 73 71 6c 62 22 20 7b 7d 0a 20 20 20 20 6d 61  $sqlb" {}.    ma
1f50: 6b 65 5f 74 65 73 74 5f 63 61 73 65 20 22 53 45  ke_test_case "SE
1f60: 4c 45 43 54 20 24 73 71 6c 65 20 46 52 4f 4d 20  LECT $sqle FROM 
1f70: 74 31 20 57 48 45 52 45 20 4e 4f 54 20 28 24 73  t1 WHERE NOT ($s
1f80: 71 6c 62 29 22 20 24 61 6e 73 0a 20 20 7d 0a 20  qlb)" $ans.  }. 
1f90: 20 69 66 20 7b 5b 72 65 67 65 78 70 20 7b 20 5c   if {[regexp { \
1fa0: 7c 20 7d 20 24 73 71 6c 65 5d 7d 20 7b 0a 20 20  | } $sqle]} {.  
1fb0: 20 20 72 65 67 73 75 62 20 2d 61 6c 6c 20 7b 20    regsub -all { 
1fc0: 5c 7c 20 7d 20 24 73 71 6c 65 20 7b 20 5c 26 20  \| } $sqle { \& 
1fd0: 7d 20 73 71 6c 65 0a 20 20 20 20 72 65 67 73 75  } sqle.    regsu
1fe0: 62 20 2d 61 6c 6c 20 7b 20 5c 7c 20 7d 20 24 74  b -all { \| } $t
1ff0: 63 6c 65 20 7b 20 5c 26 20 7d 20 74 63 6c 65 0a  cle { \& } tcle.
2000: 20 20 20 20 69 66 20 7b 5b 63 61 74 63 68 20 7b      if {[catch {
2010: 65 78 70 72 20 24 74 63 6c 65 7d 20 61 6e 73 5d  expr $tcle} ans]
2020: 3d 3d 30 7d 20 7b 0a 20 20 20 20 20 20 69 66 20  ==0} {.      if 
2030: 7b 24 62 61 6e 73 7d 20 7b 0a 20 20 20 20 20 20  {$bans} {.      
2040: 20 20 6d 61 6b 65 5f 74 65 73 74 5f 63 61 73 65    make_test_case
2050: 20 22 53 45 4c 45 43 54 20 24 73 71 6c 65 20 46   "SELECT $sqle F
2060: 52 4f 4d 20 74 31 20 57 48 45 52 45 20 24 73 71  ROM t1 WHERE $sq
2070: 6c 62 22 20 24 61 6e 73 0a 20 20 20 20 20 20 7d  lb" $ans.      }
2080: 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 20 20   else {.        
2090: 6d 61 6b 65 5f 74 65 73 74 5f 63 61 73 65 20 22  make_test_case "
20a0: 53 45 4c 45 43 54 20 24 73 71 6c 65 20 46 52 4f  SELECT $sqle FRO
20b0: 4d 20 74 31 20 57 48 45 52 45 20 4e 4f 54 20 28  M t1 WHERE NOT (
20c0: 24 73 71 6c 62 29 22 20 24 61 6e 73 0a 20 20 20  $sqlb)" $ans.   
20d0: 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d     }.    }.  }.}
20e0: 0a 0a 23 20 54 65 72 6d 69 6e 61 74 65 20 74 68  ..# Terminate th
20f0: 65 20 74 65 73 74 20 73 63 72 69 70 74 0a 23 0a  e test script.#.
2100: 70 75 74 73 20 7b 66 69 6e 69 73 68 5f 74 65 73  puts {finish_tes
2110: 74 7d 0a                                         t}.