000001  # 2010 August 27
000002  #
000003  # The author disclaims copyright to this source code.  In place of
000004  # a legal notice, here is a blessing:
000005  #
000006  #    May you do good and not evil.
000007  #    May you find forgiveness for yourself and forgive others.
000008  #    May you share freely, never taking more than you give.
000009  #
000010  #***********************************************************************
000011  # This file implements regression tests for SQLite library. The
000012  # focus of this file is testing that destructor functions associated
000013  # with functions created using sqlite3_create_function_v2() is 
000014  # correctly invoked.
000015  #
000016  set testdir [file dirname $argv0]
000017  source $testdir/tester.tcl
000018  
000019  
000020  ifcapable utf16 {
000021    do_test func3-1.1 {
000022      set destroyed 0
000023      proc destroy {} { set ::destroyed 1 }
000024      sqlite3_create_function_v2 db f2 -1 any -func f2 -destroy destroy
000025      set destroyed
000026    } 0
000027    do_test func3-1.2 {
000028      sqlite3_create_function_v2 db f2 -1 utf8 -func f2
000029      set destroyed
000030    } 0
000031    do_test func3-1.3 {
000032      sqlite3_create_function_v2 db f2 -1 utf16le -func f2
000033      set destroyed
000034    } 0
000035    do_test func3-1.4 {
000036      sqlite3_create_function_v2 db f2 -1 utf16be -func f2
000037      set destroyed
000038    } 1
000039  }
000040  
000041  do_test func3-2.1 {
000042    set destroyed 0
000043    proc destroy {} { set ::destroyed 1 }
000044    sqlite3_create_function_v2 db f3 -1 utf8 -func f3 -destroy destroy
000045    set destroyed
000046  } 0
000047  do_test func3-2.2 {
000048    sqlite3_create_function_v2 db f3 -1 utf8 -func f3
000049    set destroyed
000050  } 1
000051  
000052  do_test func3-3.1 {
000053    set destroyed 0
000054    proc destroy {} { set ::destroyed 1 }
000055    sqlite3_create_function_v2 db f3 -1 any -func f3 -destroy destroy
000056    set destroyed
000057  } 0
000058  do_test func3-3.2 {
000059    db close
000060    set destroyed
000061  } 1
000062  
000063  sqlite3 db test.db
000064  do_test func3-4.1 {
000065    set destroyed 0
000066    set rc [catch { 
000067      sqlite3_create_function_v2 db f3 -1 any -func f3 -step f3 -destroy destroy
000068    } msg]
000069    list $rc $msg
000070  } {1 SQLITE_MISUSE}
000071  do_test func3-4.2 { set destroyed } 1
000072  
000073  # EVIDENCE-OF: R-41921-05214 The likelihood(X,Y) function returns
000074  # argument X unchanged.
000075  #
000076  do_execsql_test func3-5.1 {
000077    SELECT likelihood(9223372036854775807, 0.5);
000078  } {9223372036854775807}
000079  do_execsql_test func3-5.2 {
000080    SELECT likelihood(-9223372036854775808, 0.5);
000081  } {-9223372036854775808}
000082  do_execsql_test func3-5.3 {
000083    SELECT likelihood(14.125, 0.5);
000084  } {14.125}
000085  do_execsql_test func3-5.4 {
000086    SELECT likelihood(NULL, 0.5);
000087  } {{}}
000088  do_execsql_test func3-5.5 {
000089    SELECT likelihood('test-string', 0.5);
000090  } {test-string}
000091  do_execsql_test func3-5.6 {
000092    SELECT quote(likelihood(x'010203000405', 0.5));
000093  } {X'010203000405'}
000094  
000095  # EVIDENCE-OF: R-44133-61651 The value Y in likelihood(X,Y) must be a
000096  # floating point constant between 0.0 and 1.0, inclusive.
000097  #
000098  do_execsql_test func3-5.7 {
000099    SELECT likelihood(123, 1.0), likelihood(456, 0.0);
000100  } {123 456}
000101  do_test func3-5.8 {
000102    catchsql {
000103      SELECT likelihood(123, 1.000001);
000104    }
000105  } {1 {second argument to likelihood() must be a constant between 0.0 and 1.0}}
000106  do_test func3-5.9 {
000107    catchsql {
000108      SELECT likelihood(123, -0.000001);
000109    }
000110  } {1 {second argument to likelihood() must be a constant between 0.0 and 1.0}}
000111  do_test func3-5.10 {
000112    catchsql {
000113      SELECT likelihood(123, 0.5+0.3);
000114    }
000115  } {1 {second argument to likelihood() must be a constant between 0.0 and 1.0}}
000116  
000117  # EVIDENCE-OF: R-28535-44631 The likelihood(X) function is a no-op that
000118  # the code generator optimizes away so that it consumes no CPU cycles
000119  # during run-time (that is, during calls to sqlite3_step()).
000120  #
000121  do_test func3-5.20 {
000122    db eval {EXPLAIN SELECT likelihood(min(1.0+'2.0',4*11), 0.5)}
000123  } [db eval {EXPLAIN SELECT min(1.0+'2.0',4*11)}]
000124  
000125  
000126  # EVIDENCE-OF: R-11152-23456 The unlikely(X) function returns the
000127  # argument X unchanged.
000128  #
000129  do_execsql_test func3-5.30 {
000130    SELECT unlikely(9223372036854775807);
000131  } {9223372036854775807}
000132  do_execsql_test func3-5.31 {
000133    SELECT unlikely(-9223372036854775808);
000134  } {-9223372036854775808}
000135  do_execsql_test func3-5.32 {
000136    SELECT unlikely(14.125);
000137  } {14.125}
000138  do_execsql_test func3-5.33 {
000139    SELECT unlikely(NULL);
000140  } {{}}
000141  do_execsql_test func3-5.34 {
000142    SELECT unlikely('test-string');
000143  } {test-string}
000144  do_execsql_test func3-5.35 {
000145    SELECT quote(unlikely(x'010203000405'));
000146  } {X'010203000405'}
000147  
000148  # EVIDENCE-OF: R-22887-63324 The unlikely(X) function is a no-op that
000149  # the code generator optimizes away so that it consumes no CPU cycles at
000150  # run-time (that is, during calls to sqlite3_step()).
000151  #
000152  do_test func3-5.39 {
000153    db eval {EXPLAIN SELECT unlikely(min(1.0+'2.0',4*11))}
000154  } [db eval {EXPLAIN SELECT min(1.0+'2.0',4*11)}]
000155  
000156  # Unlikely() does not preserve the affinity of X.
000157  # ticket https://www.sqlite.org/src/tktview/0c620df60b
000158  #
000159  do_execsql_test func3-5.40 {
000160    SELECT likely(CAST(1 AS INT))=='1';
000161  } 0
000162  do_execsql_test func3-5.41 {
000163    SELECT unlikely(CAST(1 AS INT))=='1';
000164  } 0
000165  do_execsql_test func3-5.41 {
000166    SELECT likelihood(CAST(1 AS INT),0.5)=='1';
000167  } 0
000168  
000169  
000170  # EVIDENCE-OF: R-23735-03107 The likely(X) function returns the argument
000171  # X unchanged.
000172  #
000173  do_execsql_test func3-5.50 {
000174    SELECT likely(9223372036854775807);
000175  } {9223372036854775807}
000176  do_execsql_test func3-5.51 {
000177    SELECT likely(-9223372036854775808);
000178  } {-9223372036854775808}
000179  do_execsql_test func3-5.52 {
000180    SELECT likely(14.125);
000181  } {14.125}
000182  do_execsql_test func3-5.53 {
000183    SELECT likely(NULL);
000184  } {{}}
000185  do_execsql_test func3-5.54 {
000186    SELECT likely('test-string');
000187  } {test-string}
000188  do_execsql_test func3-5.55 {
000189    SELECT quote(likely(x'010203000405'));
000190  } {X'010203000405'}
000191  
000192  # EVIDENCE-OF: R-43464-09689 The likely(X) function is a no-op that the
000193  # code generator optimizes away so that it consumes no CPU cycles at
000194  # run-time (that is, during calls to sqlite3_step()).
000195  #
000196  do_test func3-5.59 {
000197    db eval {EXPLAIN SELECT likely(min(1.0+'2.0',4*11))}
000198  } [db eval {EXPLAIN SELECT min(1.0+'2.0',4*11)}]
000199  
000200  
000201  # Test the outcome of specifying NULL xStep and xFinal pointers (normally
000202  # used to delete any existing function) and a non-NULL xDestroy when there 
000203  # is no existing function to destroy.
000204  #
000205  do_test func3-6.0 {
000206    sqlite3_create_function_v2 db nofunc 1 utf8
000207  } {}
000208  
000209  
000210  
000211  finish_test