misc2.test 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. # 2003 June 21
  2. #
  3. # The author disclaims copyright to this source code. In place of
  4. # a legal notice, here is a blessing:
  5. #
  6. # May you do good and not evil.
  7. # May you find forgiveness for yourself and forgive others.
  8. # May you share freely, never taking more than you give.
  9. #
  10. #***********************************************************************
  11. # This file implements regression tests for SQLite library.
  12. #
  13. # This file implements tests for miscellanous features that were
  14. # left out of other test files.
  15. #
  16. # $Id: misc2.test,v 1.28 2007/09/12 17:01:45 danielk1977 Exp $
  17. set testdir [file dirname $argv0]
  18. source $testdir/tester.tcl
  19. # The tests in this file were written before SQLite supported recursive
  20. # trigger invocation, and some tests depend on that to pass. So disable
  21. # recursive triggers for this file.
  22. catchsql { pragma recursive_triggers = off }
  23. ifcapable {trigger} {
  24. # Test for ticket #360
  25. #
  26. do_test misc2-1.1 {
  27. catchsql {
  28. CREATE TABLE FOO(bar integer);
  29. CREATE TRIGGER foo_insert BEFORE INSERT ON foo BEGIN
  30. SELECT CASE WHEN (NOT new.bar BETWEEN 0 AND 20)
  31. THEN raise(rollback, 'aiieee') END;
  32. END;
  33. INSERT INTO foo(bar) VALUES (1);
  34. }
  35. } {0 {}}
  36. do_test misc2-1.2 {
  37. catchsql {
  38. INSERT INTO foo(bar) VALUES (111);
  39. }
  40. } {1 aiieee}
  41. } ;# endif trigger
  42. # Make sure ROWID works on a view and a subquery. Ticket #364
  43. #
  44. do_test misc2-2.1 {
  45. execsql {
  46. CREATE TABLE t1(a,b,c);
  47. INSERT INTO t1 VALUES(1,2,3);
  48. CREATE TABLE t2(a,b,c);
  49. INSERT INTO t2 VALUES(7,8,9);
  50. }
  51. } {}
  52. ifcapable subquery {
  53. do_test misc2-2.2 {
  54. execsql {
  55. SELECT rowid, * FROM (SELECT * FROM t1, t2);
  56. }
  57. } {{} 1 2 3 7 8 9}
  58. }
  59. ifcapable view {
  60. do_test misc2-2.3 {
  61. execsql {
  62. CREATE VIEW v1 AS SELECT * FROM t1, t2;
  63. SELECT rowid, * FROM v1;
  64. }
  65. } {{} 1 2 3 7 8 9}
  66. } ;# ifcapable view
  67. # Ticket #2002 and #1952.
  68. ifcapable subquery {
  69. do_test misc2-2.4 {
  70. execsql2 {
  71. SELECT * FROM (SELECT a, b AS 'a', c AS 'a', 4 AS 'a' FROM t1)
  72. }
  73. } {a 1 a:1 2 a:2 3 a:3 4}
  74. }
  75. # Check name binding precedence. Ticket #387
  76. #
  77. do_test misc2-3.1 {
  78. catchsql {
  79. SELECT t1.b+t2.b AS a, t1.a, t2.a FROM t1, t2 WHERE a==10
  80. }
  81. } {1 {ambiguous column name: a}}
  82. # Make sure 32-bit integer overflow is handled properly in queries.
  83. # ticket #408
  84. #
  85. do_test misc2-4.1 {
  86. execsql {
  87. INSERT INTO t1 VALUES(4000000000,'a','b');
  88. SELECT a FROM t1 WHERE a>1;
  89. }
  90. } {4000000000}
  91. do_test misc2-4.2 {
  92. execsql {
  93. INSERT INTO t1 VALUES(2147483648,'b2','c2');
  94. INSERT INTO t1 VALUES(2147483647,'b3','c3');
  95. SELECT a FROM t1 WHERE a>2147483647;
  96. }
  97. } {4000000000 2147483648}
  98. do_test misc2-4.3 {
  99. execsql {
  100. SELECT a FROM t1 WHERE a<2147483648;
  101. }
  102. } {1 2147483647}
  103. do_test misc2-4.4 {
  104. execsql {
  105. SELECT a FROM t1 WHERE a<=2147483648;
  106. }
  107. } {1 2147483648 2147483647}
  108. do_test misc2-4.5 {
  109. execsql {
  110. SELECT a FROM t1 WHERE a<10000000000;
  111. }
  112. } {1 4000000000 2147483648 2147483647}
  113. do_test misc2-4.6 {
  114. execsql {
  115. SELECT a FROM t1 WHERE a<1000000000000 ORDER BY 1;
  116. }
  117. } {1 2147483647 2147483648 4000000000}
  118. # There were some issues with expanding a SrcList object using a call
  119. # to sqliteSrcListAppend() if the SrcList had previously been duplicated
  120. # using a call to sqliteSrcListDup(). Ticket #416. The following test
  121. # makes sure the problem has been fixed.
  122. #
  123. ifcapable view {
  124. do_test misc2-5.1 {
  125. execsql {
  126. CREATE TABLE x(a,b);
  127. CREATE VIEW y AS
  128. SELECT x1.b AS p, x2.b AS q FROM x AS x1, x AS x2 WHERE x1.a=x2.a;
  129. CREATE VIEW z AS
  130. SELECT y1.p, y2.p FROM y AS y1, y AS y2 WHERE y1.q=y2.q;
  131. SELECT * from z;
  132. }
  133. } {}
  134. }
  135. # Make sure we can open a database with an empty filename. What this
  136. # does is store the database in a temporary file that is deleted when
  137. # the database is closed. Ticket #432.
  138. #
  139. do_test misc2-6.1 {
  140. db close
  141. sqlite3 db {}
  142. execsql {
  143. CREATE TABLE t1(a,b);
  144. INSERT INTO t1 VALUES(1,2);
  145. SELECT * FROM t1;
  146. }
  147. } {1 2}
  148. # Make sure we get an error message (not a segfault) on an attempt to
  149. # update a table from within the callback of a select on that same
  150. # table.
  151. #
  152. # 2006-08-16: This has changed. It is now permitted to update
  153. # the table being SELECTed from within the callback of the query.
  154. #
  155. ifcapable tclvar {
  156. do_test misc2-7.1 {
  157. db close
  158. forcedelete test.db
  159. sqlite3 db test.db
  160. execsql {
  161. CREATE TABLE t1(x);
  162. INSERT INTO t1 VALUES(1);
  163. INSERT INTO t1 VALUES(2);
  164. INSERT INTO t1 VALUES(3);
  165. SELECT * FROM t1;
  166. }
  167. } {1 2 3}
  168. do_test misc2-7.2 {
  169. set rc [catch {
  170. db eval {SELECT rowid FROM t1} {} {
  171. db eval "DELETE FROM t1 WHERE rowid=$rowid"
  172. }
  173. } msg]
  174. lappend rc $msg
  175. } {0 {}}
  176. do_test misc2-7.3 {
  177. execsql {SELECT * FROM t1}
  178. } {}
  179. do_test misc2-7.4 {
  180. execsql {
  181. DELETE FROM t1;
  182. INSERT INTO t1 VALUES(1);
  183. INSERT INTO t1 VALUES(2);
  184. INSERT INTO t1 VALUES(3);
  185. INSERT INTO t1 VALUES(4);
  186. }
  187. db eval {SELECT rowid, x FROM t1} {
  188. if {$x & 1} {
  189. db eval {DELETE FROM t1 WHERE rowid=$rowid}
  190. }
  191. }
  192. execsql {SELECT * FROM t1}
  193. } {2 4}
  194. do_test misc2-7.5 {
  195. execsql {
  196. DELETE FROM t1;
  197. INSERT INTO t1 VALUES(1);
  198. INSERT INTO t1 VALUES(2);
  199. INSERT INTO t1 VALUES(3);
  200. INSERT INTO t1 VALUES(4);
  201. }
  202. db eval {SELECT rowid, x FROM t1} {
  203. if {$x & 1} {
  204. db eval {DELETE FROM t1 WHERE rowid=$rowid+1}
  205. }
  206. }
  207. execsql {SELECT * FROM t1}
  208. } {1 3}
  209. do_test misc2-7.6 {
  210. execsql {
  211. DELETE FROM t1;
  212. INSERT INTO t1 VALUES(1);
  213. INSERT INTO t1 VALUES(2);
  214. INSERT INTO t1 VALUES(3);
  215. INSERT INTO t1 VALUES(4);
  216. }
  217. db eval {SELECT rowid, x FROM t1} {
  218. if {$x & 1} {
  219. db eval {DELETE FROM t1}
  220. }
  221. }
  222. execsql {SELECT * FROM t1}
  223. } {}
  224. do_test misc2-7.7 {
  225. execsql {
  226. DELETE FROM t1;
  227. INSERT INTO t1 VALUES(1);
  228. INSERT INTO t1 VALUES(2);
  229. INSERT INTO t1 VALUES(3);
  230. INSERT INTO t1 VALUES(4);
  231. }
  232. db eval {SELECT rowid, x FROM t1} {
  233. if {$x & 1} {
  234. db eval {UPDATE t1 SET x=x+100 WHERE rowid=$rowid}
  235. }
  236. }
  237. execsql {SELECT * FROM t1}
  238. } {101 2 103 4}
  239. do_test misc2-7.8 {
  240. execsql {
  241. DELETE FROM t1;
  242. INSERT INTO t1 VALUES(1);
  243. }
  244. db eval {SELECT rowid, x FROM t1} {
  245. if {$x<10} {
  246. db eval {INSERT INTO t1 VALUES($x+1)}
  247. }
  248. }
  249. execsql {SELECT * FROM t1}
  250. } {1 2 3 4 5 6 7 8 9 10}
  251. # Repeat the tests 7.1 through 7.8 about but this time do the SELECTs
  252. # in reverse order so that we exercise the sqlite3BtreePrev() routine
  253. # instead of sqlite3BtreeNext()
  254. #
  255. do_test misc2-7.11 {
  256. db close
  257. forcedelete test.db
  258. sqlite3 db test.db
  259. execsql {
  260. CREATE TABLE t1(x);
  261. INSERT INTO t1 VALUES(1);
  262. INSERT INTO t1 VALUES(2);
  263. INSERT INTO t1 VALUES(3);
  264. SELECT * FROM t1;
  265. }
  266. } {1 2 3}
  267. do_test misc2-7.12 {
  268. set rc [catch {
  269. db eval {SELECT rowid FROM t1 ORDER BY rowid DESC} {} {
  270. db eval "DELETE FROM t1 WHERE rowid=$rowid"
  271. }
  272. } msg]
  273. lappend rc $msg
  274. } {0 {}}
  275. do_test misc2-7.13 {
  276. execsql {SELECT * FROM t1}
  277. } {}
  278. do_test misc2-7.14 {
  279. execsql {
  280. DELETE FROM t1;
  281. INSERT INTO t1 VALUES(1);
  282. INSERT INTO t1 VALUES(2);
  283. INSERT INTO t1 VALUES(3);
  284. INSERT INTO t1 VALUES(4);
  285. }
  286. db eval {SELECT rowid, x FROM t1 ORDER BY rowid DESC} {
  287. if {$x & 1} {
  288. db eval {DELETE FROM t1 WHERE rowid=$rowid}
  289. }
  290. }
  291. execsql {SELECT * FROM t1}
  292. } {2 4}
  293. do_test misc2-7.15 {
  294. execsql {
  295. DELETE FROM t1;
  296. INSERT INTO t1 VALUES(1);
  297. INSERT INTO t1 VALUES(2);
  298. INSERT INTO t1 VALUES(3);
  299. INSERT INTO t1 VALUES(4);
  300. }
  301. db eval {SELECT rowid, x FROM t1} {
  302. if {$x & 1} {
  303. db eval {DELETE FROM t1 WHERE rowid=$rowid+1}
  304. }
  305. }
  306. execsql {SELECT * FROM t1}
  307. } {1 3}
  308. do_test misc2-7.16 {
  309. execsql {
  310. DELETE FROM t1;
  311. INSERT INTO t1 VALUES(1);
  312. INSERT INTO t1 VALUES(2);
  313. INSERT INTO t1 VALUES(3);
  314. INSERT INTO t1 VALUES(4);
  315. }
  316. db eval {SELECT rowid, x FROM t1 ORDER BY rowid DESC} {
  317. if {$x & 1} {
  318. db eval {DELETE FROM t1}
  319. }
  320. }
  321. execsql {SELECT * FROM t1}
  322. } {}
  323. do_test misc2-7.17 {
  324. execsql {
  325. DELETE FROM t1;
  326. INSERT INTO t1 VALUES(1);
  327. INSERT INTO t1 VALUES(2);
  328. INSERT INTO t1 VALUES(3);
  329. INSERT INTO t1 VALUES(4);
  330. }
  331. db eval {SELECT rowid, x FROM t1 ORDER BY rowid DESC} {
  332. if {$x & 1} {
  333. db eval {UPDATE t1 SET x=x+100 WHERE rowid=$rowid}
  334. }
  335. }
  336. execsql {SELECT * FROM t1}
  337. } {101 2 103 4}
  338. do_test misc2-7.18 {
  339. execsql {
  340. DELETE FROM t1;
  341. INSERT INTO t1(rowid,x) VALUES(10,10);
  342. }
  343. db eval {SELECT rowid, x FROM t1 ORDER BY rowid DESC} {
  344. if {$x>1} {
  345. db eval {INSERT INTO t1(rowid,x) VALUES($x-1,$x-1)}
  346. }
  347. }
  348. execsql {SELECT * FROM t1}
  349. } {1 2 3 4 5 6 7 8 9 10}
  350. }
  351. db close
  352. forcedelete test.db
  353. sqlite3 db test.db
  354. catchsql { pragma recursive_triggers = off }
  355. # Ticket #453. If the SQL ended with "-", the tokenizer was calling that
  356. # an incomplete token, which caused problem. The solution was to just call
  357. # it a minus sign.
  358. #
  359. do_test misc2-8.1 {
  360. catchsql {-}
  361. } {1 {near "-": syntax error}}
  362. # Ticket #513. Make sure the VDBE stack does not grow on a 3-way join.
  363. #
  364. ifcapable tempdb {
  365. do_test misc2-9.1 {
  366. execsql {
  367. BEGIN;
  368. CREATE TABLE counts(n INTEGER PRIMARY KEY);
  369. INSERT INTO counts VALUES(0);
  370. INSERT INTO counts VALUES(1);
  371. INSERT INTO counts SELECT n+2 FROM counts;
  372. INSERT INTO counts SELECT n+4 FROM counts;
  373. INSERT INTO counts SELECT n+8 FROM counts;
  374. COMMIT;
  375. CREATE TEMP TABLE x AS
  376. SELECT dim1.n, dim2.n, dim3.n
  377. FROM counts AS dim1, counts AS dim2, counts AS dim3
  378. WHERE dim1.n<10 AND dim2.n<10 AND dim3.n<10;
  379. SELECT count(*) FROM x;
  380. }
  381. } {1000}
  382. do_test misc2-9.2 {
  383. execsql {
  384. DROP TABLE x;
  385. CREATE TEMP TABLE x AS
  386. SELECT dim1.n, dim2.n, dim3.n
  387. FROM counts AS dim1, counts AS dim2, counts AS dim3
  388. WHERE dim1.n>=6 AND dim2.n>=6 AND dim3.n>=6;
  389. SELECT count(*) FROM x;
  390. }
  391. } {1000}
  392. do_test misc2-9.3 {
  393. execsql {
  394. DROP TABLE x;
  395. CREATE TEMP TABLE x AS
  396. SELECT dim1.n, dim2.n, dim3.n, dim4.n
  397. FROM counts AS dim1, counts AS dim2, counts AS dim3, counts AS dim4
  398. WHERE dim1.n<5 AND dim2.n<5 AND dim3.n<5 AND dim4.n<5;
  399. SELECT count(*) FROM x;
  400. }
  401. } [expr 5*5*5*5]
  402. }
  403. # Ticket #1229. Sometimes when a "NEW.X" appears in a SELECT without
  404. # a FROM clause deep within a trigger, the code generator is unable to
  405. # trace the NEW.X back to an original table and thus figure out its
  406. # declared datatype.
  407. #
  408. # The SQL code below was causing a segfault.
  409. #
  410. ifcapable subquery&&trigger {
  411. do_test misc2-10.1 {
  412. execsql {
  413. CREATE TABLE t1229(x);
  414. CREATE TRIGGER r1229 BEFORE INSERT ON t1229 BEGIN
  415. INSERT INTO t1229 SELECT y FROM (SELECT new.x y);
  416. END;
  417. INSERT INTO t1229 VALUES(1);
  418. }
  419. } {}
  420. }
  421. finish_test