collate3.test 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526
  1. # 2001 September 15
  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. The
  12. # focus of this script is page cache subsystem.
  13. #
  14. # $Id: collate3.test,v 1.13 2008/08/20 16:35:10 drh Exp $
  15. set testdir [file dirname $argv0]
  16. source $testdir/tester.tcl
  17. #
  18. # Tests are organised as follows:
  19. #
  20. # collate3.1.* - Errors related to unknown collation sequences.
  21. # collate3.2.* - Errors related to undefined collation sequences.
  22. # collate3.3.* - Writing to a table that has an index with an undefined c.s.
  23. # collate3.4.* - Misc errors.
  24. # collate3.5.* - Collation factory.
  25. #
  26. #
  27. # These tests ensure that when a user executes a statement with an
  28. # unknown collation sequence an error is returned.
  29. #
  30. do_test collate3-1.0 {
  31. execsql {
  32. CREATE TABLE collate3t1(c1);
  33. }
  34. } {}
  35. do_test collate3-1.1 {
  36. catchsql {
  37. SELECT * FROM collate3t1 ORDER BY 1 collate garbage;
  38. }
  39. } {1 {no such collation sequence: garbage}}
  40. do_test collate3-1.2 {
  41. catchsql {
  42. CREATE TABLE collate3t2(c1 collate garbage);
  43. }
  44. } {1 {no such collation sequence: garbage}}
  45. do_test collate3-1.3 {
  46. catchsql {
  47. CREATE INDEX collate3i1 ON collate3t1(c1 COLLATE garbage);
  48. }
  49. } {1 {no such collation sequence: garbage}}
  50. execsql {
  51. DROP TABLE collate3t1;
  52. }
  53. proc caseless {a b} { string compare -nocase $a $b }
  54. do_test collate3-1.4 {
  55. db collate caseless caseless
  56. execsql {
  57. CREATE TABLE t1(a COLLATE caseless);
  58. INSERT INTO t1 VALUES('Abc2');
  59. INSERT INTO t1 VALUES('abc1');
  60. INSERT INTO t1 VALUES('aBc3');
  61. }
  62. execsql { SELECT * FROM t1 ORDER BY a }
  63. } {abc1 Abc2 aBc3}
  64. do_test collate3-1.5 {
  65. db close
  66. sqlite3 db test.db
  67. catchsql { SELECT * FROM t1 ORDER BY a }
  68. } {1 {no such collation sequence: caseless}}
  69. do_test collate3-1.6.1 {
  70. db collate caseless caseless
  71. execsql { CREATE INDEX i1 ON t1(a) }
  72. execsql { SELECT * FROM t1 ORDER BY a }
  73. } {abc1 Abc2 aBc3}
  74. do_test collate3-1.6.2 {
  75. db close
  76. sqlite3 db test.db
  77. catchsql { SELECT * FROM t1 ORDER BY a }
  78. } {1 {no such collation sequence: caseless}}
  79. do_test collate3-1.6.3 {
  80. db close
  81. sqlite3 db test.db
  82. catchsql { PRAGMA integrity_check }
  83. } {1 {no such collation sequence: caseless}}
  84. do_test collate3-1.6.4 {
  85. db close
  86. sqlite3 db test.db
  87. catchsql { REINDEX }
  88. } {1 {no such collation sequence: caseless}}
  89. do_test collate3-1.7.1 {
  90. db collate caseless caseless
  91. execsql {
  92. DROP TABLE t1;
  93. CREATE TABLE t1(a);
  94. CREATE INDEX i1 ON t1(a COLLATE caseless);
  95. INSERT INTO t1 VALUES('Abc2');
  96. INSERT INTO t1 VALUES('abc1');
  97. INSERT INTO t1 VALUES('aBc3');
  98. SELECT * FROM t1 ORDER BY a COLLATE caseless;
  99. }
  100. } {abc1 Abc2 aBc3}
  101. do_test collate3-1.7.2 {
  102. db close
  103. sqlite3 db test.db
  104. catchsql { SELECT * FROM t1 ORDER BY a COLLATE caseless}
  105. } {1 {no such collation sequence: caseless}}
  106. do_test collate3-1.7.4 {
  107. db close
  108. sqlite3 db test.db
  109. catchsql { REINDEX }
  110. } {1 {no such collation sequence: caseless}}
  111. do_test collate3-1.7.3 {
  112. db close
  113. sqlite3 db test.db
  114. catchsql { PRAGMA integrity_check }
  115. } {1 {no such collation sequence: caseless}}
  116. do_test collate3-1.7.4 {
  117. db close
  118. sqlite3 db test.db
  119. catchsql { REINDEX }
  120. } {1 {no such collation sequence: caseless}}
  121. do_test collate3-1.7.5 {
  122. db close
  123. sqlite3 db test.db
  124. db collate caseless caseless
  125. catchsql { PRAGMA integrity_check }
  126. } {0 ok}
  127. proc needed {nm} { db collate caseless caseless }
  128. do_test collate3-1.7.6 {
  129. db close
  130. sqlite3 db test.db
  131. db collation_needed needed
  132. catchsql { PRAGMA integrity_check }
  133. } {0 ok}
  134. do_test collate3-1.8 {
  135. execsql { DROP TABLE t1 }
  136. } {}
  137. #
  138. # Create a table with a default collation sequence, then close
  139. # and re-open the database without re-registering the collation
  140. # sequence. Then make sure the library stops us from using
  141. # the collation sequence in:
  142. # * an explicitly collated ORDER BY
  143. # * an ORDER BY that uses the default collation sequence
  144. # * an expression (=)
  145. # * a CREATE TABLE statement
  146. # * a CREATE INDEX statement that uses a default collation sequence
  147. # * a GROUP BY that uses the default collation sequence
  148. # * a SELECT DISTINCT that uses the default collation sequence
  149. # * Compound SELECTs that uses the default collation sequence
  150. # * An ORDER BY on a compound SELECT with an explicit ORDER BY.
  151. #
  152. do_test collate3-2.0 {
  153. db collate string_compare {string compare}
  154. execsql {
  155. CREATE TABLE collate3t1(c1 COLLATE string_compare, c2);
  156. }
  157. db close
  158. sqlite3 db test.db
  159. expr 0
  160. } 0
  161. do_test collate3-2.1 {
  162. catchsql {
  163. SELECT * FROM collate3t1 ORDER BY 1 COLLATE string_compare;
  164. }
  165. } {1 {no such collation sequence: string_compare}}
  166. do_test collate3-2.2 {
  167. catchsql {
  168. SELECT * FROM collate3t1 ORDER BY c1;
  169. }
  170. } {1 {no such collation sequence: string_compare}}
  171. do_test collate3-2.3 {
  172. catchsql {
  173. SELECT * FROM collate3t1 WHERE c1 = 'xxx';
  174. }
  175. } {1 {no such collation sequence: string_compare}}
  176. do_test collate3-2.4 {
  177. catchsql {
  178. CREATE TABLE collate3t2(c1 COLLATE string_compare);
  179. }
  180. } {1 {no such collation sequence: string_compare}}
  181. do_test collate3-2.5 {
  182. catchsql {
  183. CREATE INDEX collate3t1_i1 ON collate3t1(c1);
  184. }
  185. } {1 {no such collation sequence: string_compare}}
  186. do_test collate3-2.6 {
  187. catchsql {
  188. SELECT * FROM collate3t1;
  189. }
  190. } {0 {}}
  191. do_test collate3-2.7.1 {
  192. catchsql {
  193. SELECT count(*) FROM collate3t1 GROUP BY c1;
  194. }
  195. } {1 {no such collation sequence: string_compare}}
  196. # do_test collate3-2.7.2 {
  197. # catchsql {
  198. # SELECT * FROM collate3t1 GROUP BY c1;
  199. # }
  200. # } {1 {GROUP BY may only be used on aggregate queries}}
  201. do_test collate3-2.7.2 {
  202. catchsql {
  203. SELECT * FROM collate3t1 GROUP BY c1;
  204. }
  205. } {1 {no such collation sequence: string_compare}}
  206. do_test collate3-2.8 {
  207. catchsql {
  208. SELECT DISTINCT c1 FROM collate3t1;
  209. }
  210. } {1 {no such collation sequence: string_compare}}
  211. ifcapable compound {
  212. do_test collate3-2.9 {
  213. catchsql {
  214. SELECT c1 FROM collate3t1 UNION SELECT c1 FROM collate3t1;
  215. }
  216. } {1 {no such collation sequence: string_compare}}
  217. do_test collate3-2.10 {
  218. catchsql {
  219. SELECT c1 FROM collate3t1 EXCEPT SELECT c1 FROM collate3t1;
  220. }
  221. } {1 {no such collation sequence: string_compare}}
  222. do_test collate3-2.11 {
  223. catchsql {
  224. SELECT c1 FROM collate3t1 INTERSECT SELECT c1 FROM collate3t1;
  225. }
  226. } {1 {no such collation sequence: string_compare}}
  227. do_test collate3-2.12 {
  228. catchsql {
  229. SELECT c1 FROM collate3t1 UNION ALL SELECT c1 FROM collate3t1;
  230. }
  231. } {0 {}}
  232. do_test collate3-2.13 {
  233. catchsql {
  234. SELECT 10 UNION ALL SELECT 20 ORDER BY 1 COLLATE string_compare;
  235. }
  236. } {1 {no such collation sequence: string_compare}}
  237. do_test collate3-2.14 {
  238. catchsql {
  239. SELECT 10 INTERSECT SELECT 20 ORDER BY 1 COLLATE string_compare;
  240. }
  241. } {1 {no such collation sequence: string_compare}}
  242. do_test collate3-2.15 {
  243. catchsql {
  244. SELECT 10 EXCEPT SELECT 20 ORDER BY 1 COLLATE string_compare;
  245. }
  246. } {1 {no such collation sequence: string_compare}}
  247. do_test collate3-2.16 {
  248. catchsql {
  249. SELECT 10 UNION SELECT 20 ORDER BY 1 COLLATE string_compare;
  250. }
  251. } {1 {no such collation sequence: string_compare}}
  252. do_test collate3-2.17 {
  253. catchsql {
  254. SELECT c1 FROM collate3t1 UNION ALL SELECT c1 FROM collate3t1 ORDER BY 1;
  255. }
  256. } {1 {no such collation sequence: string_compare}}
  257. } ;# ifcapable compound
  258. #
  259. # Create an index that uses a collation sequence then close and
  260. # re-open the database without re-registering the collation
  261. # sequence. Then check that for the table with the index
  262. # * An INSERT fails,
  263. # * An UPDATE on the column with the index fails,
  264. # * An UPDATE on a different column succeeds.
  265. # * A DELETE with a WHERE clause fails
  266. # * A DELETE without a WHERE clause succeeds
  267. #
  268. # Also, ensure that the restrictions tested by collate3-2.* still
  269. # apply after the index has been created.
  270. #
  271. do_test collate3-3.0 {
  272. db collate string_compare {string compare}
  273. execsql {
  274. CREATE INDEX collate3t1_i1 ON collate3t1(c1);
  275. INSERT INTO collate3t1 VALUES('xxx', 'yyy');
  276. }
  277. db close
  278. sqlite3 db test.db
  279. expr 0
  280. } 0
  281. db eval {select * from collate3t1}
  282. do_test collate3-3.1 {
  283. catchsql {
  284. INSERT INTO collate3t1 VALUES('xxx', 0);
  285. }
  286. } {1 {no such collation sequence: string_compare}}
  287. do_test collate3-3.2 {
  288. catchsql {
  289. UPDATE collate3t1 SET c1 = 'xxx';
  290. }
  291. } {1 {no such collation sequence: string_compare}}
  292. do_test collate3-3.3 {
  293. catchsql {
  294. UPDATE collate3t1 SET c2 = 'xxx';
  295. }
  296. } {0 {}}
  297. do_test collate3-3.4 {
  298. catchsql {
  299. DELETE FROM collate3t1 WHERE 1;
  300. }
  301. } {1 {no such collation sequence: string_compare}}
  302. do_test collate3-3.5 {
  303. catchsql {
  304. SELECT * FROM collate3t1;
  305. }
  306. } {0 {xxx xxx}}
  307. do_test collate3-3.6 {
  308. catchsql {
  309. DELETE FROM collate3t1;
  310. }
  311. } {0 {}}
  312. ifcapable {integrityck} {
  313. do_test collate3-3.8 {
  314. catchsql {
  315. PRAGMA integrity_check
  316. }
  317. } {1 {no such collation sequence: string_compare}}
  318. }
  319. do_test collate3-3.9 {
  320. catchsql {
  321. SELECT * FROM collate3t1;
  322. }
  323. } {0 {}}
  324. do_test collate3-3.10 {
  325. catchsql {
  326. SELECT * FROM collate3t1 ORDER BY 1 COLLATE string_compare;
  327. }
  328. } {1 {no such collation sequence: string_compare}}
  329. do_test collate3-3.11 {
  330. catchsql {
  331. SELECT * FROM collate3t1 ORDER BY c1;
  332. }
  333. } {1 {no such collation sequence: string_compare}}
  334. do_test collate3-3.12 {
  335. catchsql {
  336. SELECT * FROM collate3t1 WHERE c1 = 'xxx';
  337. }
  338. } {1 {no such collation sequence: string_compare}}
  339. do_test collate3-3.13 {
  340. catchsql {
  341. CREATE TABLE collate3t2(c1 COLLATE string_compare);
  342. }
  343. } {1 {no such collation sequence: string_compare}}
  344. do_test collate3-3.14 {
  345. catchsql {
  346. CREATE INDEX collate3t1_i2 ON collate3t1(c1);
  347. }
  348. } {1 {no such collation sequence: string_compare}}
  349. do_test collate3-3.15 {
  350. execsql {
  351. DROP TABLE collate3t1;
  352. }
  353. } {}
  354. # Check we can create an index that uses an explicit collation
  355. # sequence and then close and re-open the database.
  356. do_test collate3-4.6 {
  357. db collate user_defined "string compare"
  358. execsql {
  359. CREATE TABLE collate3t1(a, b);
  360. INSERT INTO collate3t1 VALUES('hello', NULL);
  361. CREATE INDEX collate3i1 ON collate3t1(a COLLATE user_defined);
  362. }
  363. } {}
  364. do_test collate3-4.7 {
  365. db close
  366. sqlite3 db test.db
  367. catchsql {
  368. SELECT * FROM collate3t1 ORDER BY a COLLATE user_defined;
  369. }
  370. } {1 {no such collation sequence: user_defined}}
  371. do_test collate3-4.8.1 {
  372. db collate user_defined "string compare"
  373. catchsql {
  374. SELECT * FROM collate3t1 ORDER BY a COLLATE user_defined;
  375. }
  376. } {0 {hello {}}}
  377. do_test collate3-4.8.2 {
  378. db close
  379. lindex [catch {
  380. sqlite3 db test.db
  381. }] 0
  382. } {0}
  383. do_test collate3-4.8.3 {
  384. execsql {
  385. DROP TABLE collate3t1;
  386. }
  387. } {}
  388. # Compare strings as numbers.
  389. proc numeric_compare {lhs rhs} {
  390. if {$rhs > $lhs} {
  391. set res -1
  392. } else {
  393. set res [expr ($lhs > $rhs)?1:0]
  394. }
  395. return $res
  396. }
  397. # Check we can create a view that uses an explicit collation
  398. # sequence and then close and re-open the database.
  399. ifcapable view {
  400. do_test collate3-4.9 {
  401. db collate user_defined numeric_compare
  402. execsql {
  403. CREATE TABLE collate3t1(a, b);
  404. INSERT INTO collate3t1 VALUES('2', NULL);
  405. INSERT INTO collate3t1 VALUES('101', NULL);
  406. INSERT INTO collate3t1 VALUES('12', NULL);
  407. CREATE VIEW collate3v1 AS SELECT * FROM collate3t1
  408. ORDER BY 1 COLLATE user_defined;
  409. SELECT * FROM collate3v1;
  410. }
  411. } {2 {} 12 {} 101 {}}
  412. do_test collate3-4.10 {
  413. db close
  414. sqlite3 db test.db
  415. catchsql {
  416. SELECT * FROM collate3v1;
  417. }
  418. } {1 {no such collation sequence: user_defined}}
  419. do_test collate3-4.11 {
  420. db collate user_defined numeric_compare
  421. catchsql {
  422. SELECT * FROM collate3v1;
  423. }
  424. } {0 {2 {} 12 {} 101 {}}}
  425. do_test collate3-4.12 {
  426. execsql {
  427. DROP TABLE collate3t1;
  428. }
  429. } {}
  430. } ;# ifcapable view
  431. #
  432. # Test the collation factory. In the code, the "no such collation sequence"
  433. # message is only generated in two places. So these tests just test that
  434. # the collation factory can be called once from each of those points.
  435. #
  436. do_test collate3-5.0 {
  437. catchsql {
  438. CREATE TABLE collate3t1(a);
  439. INSERT INTO collate3t1 VALUES(10);
  440. SELECT a FROM collate3t1 ORDER BY 1 COLLATE unk;
  441. }
  442. } {1 {no such collation sequence: unk}}
  443. do_test collate3-5.1 {
  444. set ::cfact_cnt 0
  445. proc cfact {nm} {
  446. db collate $nm {string compare}
  447. incr ::cfact_cnt
  448. }
  449. db collation_needed cfact
  450. } {}
  451. do_test collate3-5.2 {
  452. catchsql {
  453. SELECT a FROM collate3t1 ORDER BY 1 COLLATE unk;
  454. }
  455. } {0 10}
  456. do_test collate3-5.3 {
  457. set ::cfact_cnt
  458. } {1}
  459. do_test collate3-5.4 {
  460. catchsql {
  461. SELECT a FROM collate3t1 ORDER BY 1 COLLATE unk;
  462. }
  463. } {0 10}
  464. do_test collate3-5.5 {
  465. set ::cfact_cnt
  466. } {1}
  467. do_test collate3-5.6 {
  468. catchsql {
  469. SELECT a FROM collate3t1 ORDER BY 1 COLLATE unk;
  470. }
  471. } {0 10}
  472. do_test collate3-5.7 {
  473. execsql {
  474. DROP TABLE collate3t1;
  475. CREATE TABLE collate3t1(a COLLATE unk);
  476. }
  477. db close
  478. sqlite3 db test.db
  479. catchsql {
  480. SELECT a FROM collate3t1 ORDER BY 1;
  481. }
  482. } {1 {no such collation sequence: unk}}
  483. do_test collate3-5.8 {
  484. set ::cfact_cnt 0
  485. proc cfact {nm} {
  486. db collate $nm {string compare}
  487. incr ::cfact_cnt
  488. }
  489. db collation_needed cfact
  490. catchsql {
  491. SELECT a FROM collate3t1 ORDER BY 1;
  492. }
  493. } {0 {}}
  494. do_test collate3-5.9 {
  495. execsql {
  496. DROP TABLE collate3t1;
  497. }
  498. } {}
  499. finish_test