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