PageRenderTime 25ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/test/temptable.test

https://bitbucket.org/aware/sqlite
Unknown | 441 lines | 426 code | 15 blank | 0 comment | 0 complexity | ec0b6fe0175e6b796935f487694a1bf5 MD5 | raw file
  1. # 2001 October 7
  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 temporary tables and indices.
  14. #
  15. # $Id:$
  16. set testdir [file dirname $argv0]
  17. source $testdir/tester.tcl
  18. ifcapable !tempdb {
  19. finish_test
  20. return
  21. }
  22. # Create an alternative connection to the database
  23. #
  24. do_test temptable-1.0 {
  25. sqlite3 db2 ./test.db
  26. set dummy {}
  27. } {}
  28. # Create a permanent table.
  29. #
  30. do_test temptable-1.1 {
  31. execsql {CREATE TABLE t1(a,b,c);}
  32. execsql {INSERT INTO t1 VALUES(1,2,3);}
  33. execsql {SELECT * FROM t1}
  34. } {1 2 3}
  35. do_test temptable-1.2 {
  36. catch {db2 eval {SELECT * FROM sqlite_master}}
  37. db2 eval {SELECT * FROM t1}
  38. } {1 2 3}
  39. do_test temptable-1.3 {
  40. execsql {SELECT name FROM sqlite_master}
  41. } {t1}
  42. do_test temptable-1.4 {
  43. db2 eval {SELECT name FROM sqlite_master}
  44. } {t1}
  45. # Create a temporary table. Verify that only one of the two
  46. # processes can see it.
  47. #
  48. do_test temptable-1.5 {
  49. db2 eval {
  50. CREATE TEMP TABLE t2(x,y,z);
  51. INSERT INTO t2 VALUES(4,5,6);
  52. }
  53. db2 eval {SELECT * FROM t2}
  54. } {4 5 6}
  55. do_test temptable-1.6 {
  56. catch {execsql {SELECT * FROM sqlite_master}}
  57. catchsql {SELECT * FROM t2}
  58. } {1 {no such table: t2}}
  59. do_test temptable-1.7 {
  60. catchsql {INSERT INTO t2 VALUES(8,9,0);}
  61. } {1 {no such table: t2}}
  62. do_test temptable-1.8 {
  63. db2 eval {INSERT INTO t2 VALUES(8,9,0);}
  64. db2 eval {SELECT * FROM t2 ORDER BY x}
  65. } {4 5 6 8 9 0}
  66. do_test temptable-1.9 {
  67. db2 eval {DELETE FROM t2 WHERE x==8}
  68. db2 eval {SELECT * FROM t2 ORDER BY x}
  69. } {4 5 6}
  70. do_test temptable-1.10 {
  71. db2 eval {DELETE FROM t2}
  72. db2 eval {SELECT * FROM t2}
  73. } {}
  74. do_test temptable-1.11 {
  75. db2 eval {
  76. INSERT INTO t2 VALUES(7,6,5);
  77. INSERT INTO t2 VALUES(4,3,2);
  78. SELECT * FROM t2 ORDER BY x;
  79. }
  80. } {4 3 2 7 6 5}
  81. do_test temptable-1.12 {
  82. db2 eval {DROP TABLE t2;}
  83. set r [catch {db2 eval {SELECT * FROM t2}} msg]
  84. lappend r $msg
  85. } {1 {no such table: t2}}
  86. # Make sure temporary tables work with transactions
  87. #
  88. do_test temptable-2.1 {
  89. execsql {
  90. BEGIN TRANSACTION;
  91. CREATE TEMPORARY TABLE t2(x,y);
  92. INSERT INTO t2 VALUES(1,2);
  93. SELECT * FROM t2;
  94. }
  95. } {1 2}
  96. do_test temptable-2.2 {
  97. execsql {ROLLBACK}
  98. catchsql {SELECT * FROM t2}
  99. } {1 {no such table: t2}}
  100. do_test temptable-2.3 {
  101. execsql {
  102. BEGIN TRANSACTION;
  103. CREATE TEMPORARY TABLE t2(x,y);
  104. INSERT INTO t2 VALUES(1,2);
  105. SELECT * FROM t2;
  106. }
  107. } {1 2}
  108. do_test temptable-2.4 {
  109. execsql {COMMIT}
  110. catchsql {SELECT * FROM t2}
  111. } {0 {1 2}}
  112. do_test temptable-2.5 {
  113. set r [catch {db2 eval {SELECT * FROM t2}} msg]
  114. lappend r $msg
  115. } {1 {no such table: t2}}
  116. # Make sure indices on temporary tables are also temporary.
  117. #
  118. do_test temptable-3.1 {
  119. execsql {
  120. CREATE INDEX i2 ON t2(x);
  121. SELECT name FROM sqlite_master WHERE type='index';
  122. }
  123. } {}
  124. do_test temptable-3.2 {
  125. execsql {
  126. SELECT y FROM t2 WHERE x=1;
  127. }
  128. } {2}
  129. do_test temptable-3.3 {
  130. execsql {
  131. DROP INDEX i2;
  132. SELECT y FROM t2 WHERE x=1;
  133. }
  134. } {2}
  135. do_test temptable-3.4 {
  136. execsql {
  137. CREATE INDEX i2 ON t2(x);
  138. DROP TABLE t2;
  139. }
  140. catchsql {DROP INDEX i2}
  141. } {1 {no such index: i2}}
  142. # Check for correct name collision processing. A name collision can
  143. # occur when process A creates a temporary table T then process B
  144. # creates a permanent table also named T. The temp table in process A
  145. # hides the existance of the permanent table.
  146. #
  147. do_test temptable-4.1 {
  148. execsql {
  149. CREATE TEMP TABLE t2(x,y);
  150. INSERT INTO t2 VALUES(10,20);
  151. SELECT * FROM t2;
  152. } db2
  153. } {10 20}
  154. do_test temptable-4.2 {
  155. execsql {
  156. CREATE TABLE t2(x,y,z);
  157. INSERT INTO t2 VALUES(9,8,7);
  158. SELECT * FROM t2;
  159. }
  160. } {9 8 7}
  161. do_test temptable-4.3 {
  162. catchsql {
  163. SELECT * FROM t2;
  164. } db2
  165. } {0 {10 20}}
  166. do_test temptable-4.4.1 {
  167. catchsql {
  168. SELECT * FROM temp.t2;
  169. } db2
  170. } {0 {10 20}}
  171. do_test temptable-4.4.2 {
  172. catchsql {
  173. SELECT * FROM main.t2;
  174. } db2
  175. } {0 {9 8 7}}
  176. #do_test temptable-4.4.3 {
  177. # catchsql {
  178. # SELECT name FROM main.sqlite_master WHERE type='table';
  179. # } db2
  180. #} {1 {database schema has changed}}
  181. do_test temptable-4.4.4 {
  182. catchsql {
  183. SELECT name FROM main.sqlite_master WHERE type='table';
  184. } db2
  185. } {0 {t1 t2}}
  186. do_test temptable-4.4.5 {
  187. catchsql {
  188. SELECT * FROM main.t2;
  189. } db2
  190. } {0 {9 8 7}}
  191. do_test temptable-4.4.6 {
  192. # TEMP takes precedence over MAIN
  193. catchsql {
  194. SELECT * FROM t2;
  195. } db2
  196. } {0 {10 20}}
  197. do_test temptable-4.5 {
  198. catchsql {
  199. DROP TABLE t2; -- should drop TEMP
  200. SELECT * FROM t2; -- data should be from MAIN
  201. } db2
  202. } {0 {9 8 7}}
  203. do_test temptable-4.6 {
  204. db2 close
  205. sqlite3 db2 ./test.db
  206. catchsql {
  207. SELECT * FROM t2;
  208. } db2
  209. } {0 {9 8 7}}
  210. do_test temptable-4.7 {
  211. catchsql {
  212. DROP TABLE t2;
  213. SELECT * FROM t2;
  214. }
  215. } {1 {no such table: t2}}
  216. do_test temptable-4.8 {
  217. db2 close
  218. sqlite3 db2 ./test.db
  219. execsql {
  220. CREATE TEMP TABLE t2(x unique,y);
  221. INSERT INTO t2 VALUES(1,2);
  222. SELECT * FROM t2;
  223. } db2
  224. } {1 2}
  225. do_test temptable-4.9 {
  226. execsql {
  227. CREATE TABLE t2(x unique, y);
  228. INSERT INTO t2 VALUES(3,4);
  229. SELECT * FROM t2;
  230. }
  231. } {3 4}
  232. do_test temptable-4.10.1 {
  233. catchsql {
  234. SELECT * FROM t2;
  235. } db2
  236. } {0 {1 2}}
  237. # Update: The schema is reloaded in test temptable-4.10.1. And tclsqlite.c
  238. # handles it and retries the query anyway.
  239. # do_test temptable-4.10.2 {
  240. # catchsql {
  241. # SELECT name FROM sqlite_master WHERE type='table'
  242. # } db2
  243. # } {1 {database schema has changed}}
  244. do_test temptable-4.10.3 {
  245. catchsql {
  246. SELECT name FROM sqlite_master WHERE type='table'
  247. } db2
  248. } {0 {t1 t2}}
  249. do_test temptable-4.11 {
  250. execsql {
  251. SELECT * FROM t2;
  252. } db2
  253. } {1 2}
  254. do_test temptable-4.12 {
  255. execsql {
  256. SELECT * FROM t2;
  257. }
  258. } {3 4}
  259. do_test temptable-4.13 {
  260. catchsql {
  261. DROP TABLE t2; -- drops TEMP.T2
  262. SELECT * FROM t2; -- uses MAIN.T2
  263. } db2
  264. } {0 {3 4}}
  265. do_test temptable-4.14 {
  266. execsql {
  267. SELECT * FROM t2;
  268. }
  269. } {3 4}
  270. do_test temptable-4.15 {
  271. db2 close
  272. sqlite3 db2 ./test.db
  273. execsql {
  274. SELECT * FROM t2;
  275. } db2
  276. } {3 4}
  277. # Now create a temporary table in db2 and a permanent index in db. The
  278. # temporary table in db2 should mask the name of the permanent index,
  279. # but the permanent index should still be accessible and should still
  280. # be updated when its corresponding table changes.
  281. #
  282. do_test temptable-5.1 {
  283. execsql {
  284. CREATE TEMP TABLE mask(a,b,c)
  285. } db2
  286. if {[permutation]=="prepare"} { db2 cache flush }
  287. execsql {
  288. CREATE INDEX mask ON t2(x);
  289. SELECT * FROM t2;
  290. }
  291. } {3 4}
  292. #do_test temptable-5.2 {
  293. # catchsql {
  294. # SELECT * FROM t2;
  295. # } db2
  296. #} {1 {database schema has changed}}
  297. do_test temptable-5.3 {
  298. catchsql {
  299. SELECT * FROM t2;
  300. } db2
  301. } {0 {3 4}}
  302. do_test temptable-5.4 {
  303. execsql {
  304. SELECT y FROM t2 WHERE x=3
  305. }
  306. } {4}
  307. do_test temptable-5.5 {
  308. execsql {
  309. SELECT y FROM t2 WHERE x=3
  310. } db2
  311. } {4}
  312. do_test temptable-5.6 {
  313. execsql {
  314. INSERT INTO t2 VALUES(1,2);
  315. SELECT y FROM t2 WHERE x=1;
  316. } db2
  317. } {2}
  318. do_test temptable-5.7 {
  319. execsql {
  320. SELECT y FROM t2 WHERE x=3
  321. } db2
  322. } {4}
  323. do_test temptable-5.8 {
  324. execsql {
  325. SELECT y FROM t2 WHERE x=1;
  326. }
  327. } {2}
  328. do_test temptable-5.9 {
  329. execsql {
  330. SELECT y FROM t2 WHERE x=3
  331. }
  332. } {4}
  333. db2 close
  334. # Test for correct operation of read-only databases
  335. #
  336. do_test temptable-6.1 {
  337. execsql {
  338. CREATE TABLE t8(x);
  339. INSERT INTO t8 VALUES('xyzzy');
  340. SELECT * FROM t8;
  341. }
  342. } {xyzzy}
  343. do_test temptable-6.2 {
  344. db close
  345. catch {file attributes test.db -permissions 0444}
  346. catch {file attributes test.db -readonly 1}
  347. sqlite3 db test.db
  348. if {[file writable test.db]} {
  349. error "Unable to make the database file test.db readonly - rerun this test as an unprivileged user"
  350. }
  351. execsql {
  352. SELECT * FROM t8;
  353. }
  354. } {xyzzy}
  355. do_test temptable-6.3 {
  356. if {[file writable test.db]} {
  357. error "Unable to make the database file test.db readonly - rerun this test as an unprivileged user"
  358. }
  359. catchsql {
  360. CREATE TABLE t9(x,y);
  361. }
  362. } {1 {attempt to write a readonly database}}
  363. do_test temptable-6.4 {
  364. catchsql {
  365. CREATE TEMP TABLE t9(x,y);
  366. }
  367. } {0 {}}
  368. do_test temptable-6.5 {
  369. catchsql {
  370. INSERT INTO t9 VALUES(1,2);
  371. SELECT * FROM t9;
  372. }
  373. } {0 {1 2}}
  374. do_test temptable-6.6 {
  375. if {[file writable test.db]} {
  376. error "Unable to make the database file test.db readonly - rerun this test as an unprivileged user"
  377. }
  378. catchsql {
  379. INSERT INTO t8 VALUES('hello');
  380. SELECT * FROM t8;
  381. }
  382. } {1 {attempt to write a readonly database}}
  383. do_test temptable-6.7 {
  384. catchsql {
  385. SELECT * FROM t8,t9;
  386. }
  387. } {0 {xyzzy 1 2}}
  388. do_test temptable-6.8 {
  389. db close
  390. sqlite3 db test.db
  391. catchsql {
  392. SELECT * FROM t8,t9;
  393. }
  394. } {1 {no such table: t9}}
  395. forcedelete test2.db test2.db-journal
  396. ifcapable attach {
  397. do_test temptable-7.1 {
  398. catchsql {
  399. ATTACH 'test2.db' AS two;
  400. CREATE TEMP TABLE two.abc(x,y);
  401. }
  402. } {1 {temporary table name must be unqualified}}
  403. }
  404. # Need to do the following for tcl 8.5 on mac. On that configuration, the
  405. # -readonly flag is taken so seriously that a subsequent [forcedelete]
  406. # (required before the next test file can be executed) will fail.
  407. #
  408. catch {file attributes test.db -readonly 0}
  409. do_test temptable-8.0 {
  410. db close
  411. catch {forcedelete test.db}
  412. sqlite3 db test.db
  413. } {}
  414. do_test temptable-8.1 {
  415. execsql { CREATE TEMP TABLE tbl2(a, b); }
  416. execsql {
  417. CREATE TABLE tbl(a, b);
  418. INSERT INTO tbl VALUES(1, 2);
  419. }
  420. execsql {SELECT * FROM tbl}
  421. } {1 2}
  422. do_test temptable-8.2 {
  423. execsql { CREATE TEMP TABLE tbl(a, b); }
  424. execsql {SELECT * FROM tbl}
  425. } {}
  426. finish_test