Annotation of embedaddon/sqlite3/test/intpkey.test, revision 1.1.1.1
1.1 misho 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.
12: #
13: # This file implements tests for the special processing associated
14: # with INTEGER PRIMARY KEY columns.
15: #
16: # $Id: intpkey.test,v 1.24 2007/11/29 17:43:28 danielk1977 Exp $
17:
18: set testdir [file dirname $argv0]
19: source $testdir/tester.tcl
20:
21: # Create a table with a primary key and a datatype other than
22: # integer
23: #
24: do_test intpkey-1.0 {
25: execsql {
26: CREATE TABLE t1(a TEXT PRIMARY KEY, b, c);
27: }
28: } {}
29:
30: # There should be an index associated with the primary key
31: #
32: do_test intpkey-1.1 {
33: execsql {
34: SELECT name FROM sqlite_master
35: WHERE type='index' AND tbl_name='t1';
36: }
37: } {sqlite_autoindex_t1_1}
38:
39: # Now create a table with an integer primary key and verify that
40: # there is no associated index.
41: #
42: do_test intpkey-1.2 {
43: execsql {
44: DROP TABLE t1;
45: CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
46: SELECT name FROM sqlite_master
47: WHERE type='index' AND tbl_name='t1';
48: }
49: } {}
50:
51: # Insert some records into the new table. Specify the primary key
52: # and verify that the key is used as the record number.
53: #
54: do_test intpkey-1.3 {
55: execsql {
56: INSERT INTO t1 VALUES(5,'hello','world');
57: }
58: db last_insert_rowid
59: } {5}
60: do_test intpkey-1.4 {
61: execsql {
62: SELECT * FROM t1;
63: }
64: } {5 hello world}
65: do_test intpkey-1.5 {
66: execsql {
67: SELECT rowid, * FROM t1;
68: }
69: } {5 5 hello world}
70:
71: # Attempting to insert a duplicate primary key should give a constraint
72: # failure.
73: #
74: do_test intpkey-1.6 {
75: set r [catch {execsql {
76: INSERT INTO t1 VALUES(5,'second','entry');
77: }} msg]
78: lappend r $msg
79: } {1 {PRIMARY KEY must be unique}}
80: do_test intpkey-1.7 {
81: execsql {
82: SELECT rowid, * FROM t1;
83: }
84: } {5 5 hello world}
85: do_test intpkey-1.8 {
86: set r [catch {execsql {
87: INSERT INTO t1 VALUES(6,'second','entry');
88: }} msg]
89: lappend r $msg
90: } {0 {}}
91: do_test intpkey-1.8.1 {
92: db last_insert_rowid
93: } {6}
94: do_test intpkey-1.9 {
95: execsql {
96: SELECT rowid, * FROM t1;
97: }
98: } {5 5 hello world 6 6 second entry}
99:
100: # A ROWID is automatically generated for new records that do not specify
101: # the integer primary key.
102: #
103: do_test intpkey-1.10 {
104: execsql {
105: INSERT INTO t1(b,c) VALUES('one','two');
106: SELECT b FROM t1 ORDER BY b;
107: }
108: } {hello one second}
109:
110: # Try to change the ROWID for the new entry.
111: #
112: do_test intpkey-1.11 {
113: execsql {
114: UPDATE t1 SET a=4 WHERE b='one';
115: SELECT * FROM t1;
116: }
117: } {4 one two 5 hello world 6 second entry}
118:
119: # Make sure SELECT statements are able to use the primary key column
120: # as an index.
121: #
122: do_test intpkey-1.12.1 {
123: execsql {
124: SELECT * FROM t1 WHERE a==4;
125: }
126: } {4 one two}
127: do_test intpkey-1.12.2 {
128: set sqlite_query_plan
129: } {t1 *}
130:
131: # Try to insert a non-integer value into the primary key field. This
132: # should result in a data type mismatch.
133: #
134: do_test intpkey-1.13.1 {
135: set r [catch {execsql {
136: INSERT INTO t1 VALUES('x','y','z');
137: }} msg]
138: lappend r $msg
139: } {1 {datatype mismatch}}
140: do_test intpkey-1.13.2 {
141: set r [catch {execsql {
142: INSERT INTO t1 VALUES('','y','z');
143: }} msg]
144: lappend r $msg
145: } {1 {datatype mismatch}}
146: do_test intpkey-1.14 {
147: set r [catch {execsql {
148: INSERT INTO t1 VALUES(3.4,'y','z');
149: }} msg]
150: lappend r $msg
151: } {1 {datatype mismatch}}
152: do_test intpkey-1.15 {
153: set r [catch {execsql {
154: INSERT INTO t1 VALUES(-3,'y','z');
155: }} msg]
156: lappend r $msg
157: } {0 {}}
158: do_test intpkey-1.16 {
159: execsql {SELECT * FROM t1}
160: } {-3 y z 4 one two 5 hello world 6 second entry}
161:
162: #### INDICES
163: # Check to make sure indices work correctly with integer primary keys
164: #
165: do_test intpkey-2.1 {
166: execsql {
167: CREATE INDEX i1 ON t1(b);
168: SELECT * FROM t1 WHERE b=='y'
169: }
170: } {-3 y z}
171: do_test intpkey-2.1.1 {
172: execsql {
173: SELECT * FROM t1 WHERE b=='y' AND rowid<0
174: }
175: } {-3 y z}
176: do_test intpkey-2.1.2 {
177: execsql {
178: SELECT * FROM t1 WHERE b=='y' AND rowid<0 AND rowid>=-20
179: }
180: } {-3 y z}
181: do_test intpkey-2.1.3 {
182: execsql {
183: SELECT * FROM t1 WHERE b>='y'
184: }
185: } {-3 y z}
186: do_test intpkey-2.1.4 {
187: execsql {
188: SELECT * FROM t1 WHERE b>='y' AND rowid<10
189: }
190: } {-3 y z}
191:
192: do_test intpkey-2.2 {
193: execsql {
194: UPDATE t1 SET a=8 WHERE b=='y';
195: SELECT * FROM t1 WHERE b=='y';
196: }
197: } {8 y z}
198: do_test intpkey-2.3 {
199: execsql {
200: SELECT rowid, * FROM t1;
201: }
202: } {4 4 one two 5 5 hello world 6 6 second entry 8 8 y z}
203: do_test intpkey-2.4 {
204: execsql {
205: SELECT rowid, * FROM t1 WHERE b<'second'
206: }
207: } {5 5 hello world 4 4 one two}
208: do_test intpkey-2.4.1 {
209: execsql {
210: SELECT rowid, * FROM t1 WHERE 'second'>b
211: }
212: } {5 5 hello world 4 4 one two}
213: do_test intpkey-2.4.2 {
214: execsql {
215: SELECT rowid, * FROM t1 WHERE 8>rowid AND 'second'>b
216: }
217: } {4 4 one two 5 5 hello world}
218: do_test intpkey-2.4.3 {
219: execsql {
220: SELECT rowid, * FROM t1 WHERE 8>rowid AND 'second'>b AND 0<rowid
221: }
222: } {4 4 one two 5 5 hello world}
223: do_test intpkey-2.5 {
224: execsql {
225: SELECT rowid, * FROM t1 WHERE b>'a'
226: }
227: } {5 5 hello world 4 4 one two 6 6 second entry 8 8 y z}
228: do_test intpkey-2.6 {
229: execsql {
230: DELETE FROM t1 WHERE rowid=4;
231: SELECT * FROM t1 WHERE b>'a';
232: }
233: } {5 hello world 6 second entry 8 y z}
234: do_test intpkey-2.7 {
235: execsql {
236: UPDATE t1 SET a=-4 WHERE rowid=8;
237: SELECT * FROM t1 WHERE b>'a';
238: }
239: } {5 hello world 6 second entry -4 y z}
240: do_test intpkey-2.7 {
241: execsql {
242: SELECT * FROM t1
243: }
244: } {-4 y z 5 hello world 6 second entry}
245:
246: # Do an SQL statement. Append the search count to the end of the result.
247: #
248: proc count sql {
249: set ::sqlite_search_count 0
250: return [concat [execsql $sql] $::sqlite_search_count]
251: }
252:
253: # Create indices that include the integer primary key as one of their
254: # columns.
255: #
256: do_test intpkey-3.1 {
257: execsql {
258: CREATE INDEX i2 ON t1(a);
259: }
260: } {}
261: do_test intpkey-3.2 {
262: count {
263: SELECT * FROM t1 WHERE a=5;
264: }
265: } {5 hello world 0}
266: do_test intpkey-3.3 {
267: count {
268: SELECT * FROM t1 WHERE a>4 AND a<6;
269: }
270: } {5 hello world 2}
271: do_test intpkey-3.4 {
272: count {
273: SELECT * FROM t1 WHERE b>='hello' AND b<'hello2';
274: }
275: } {5 hello world 3}
276: do_test intpkey-3.5 {
277: execsql {
278: CREATE INDEX i3 ON t1(c,a);
279: }
280: } {}
281: do_test intpkey-3.6 {
282: count {
283: SELECT * FROM t1 WHERE c=='world';
284: }
285: } {5 hello world 3}
286: do_test intpkey-3.7 {
287: execsql {INSERT INTO t1 VALUES(11,'hello','world')}
288: count {
289: SELECT * FROM t1 WHERE c=='world';
290: }
291: } {5 hello world 11 hello world 5}
292: do_test intpkey-3.8 {
293: count {
294: SELECT * FROM t1 WHERE c=='world' AND a>7;
295: }
296: } {11 hello world 4}
297: do_test intpkey-3.9 {
298: count {
299: SELECT * FROM t1 WHERE 7<a;
300: }
301: } {11 hello world 1}
302:
303: # Test inequality constraints on integer primary keys and rowids
304: #
305: do_test intpkey-4.1 {
306: count {
307: SELECT * FROM t1 WHERE 11=rowid
308: }
309: } {11 hello world 0}
310: do_test intpkey-4.2 {
311: count {
312: SELECT * FROM t1 WHERE 11=rowid AND b=='hello'
313: }
314: } {11 hello world 0}
315: do_test intpkey-4.3 {
316: count {
317: SELECT * FROM t1 WHERE 11=rowid AND b=='hello' AND c IS NOT NULL;
318: }
319: } {11 hello world 0}
320: do_test intpkey-4.4 {
321: count {
322: SELECT * FROM t1 WHERE rowid==11
323: }
324: } {11 hello world 0}
325: do_test intpkey-4.5 {
326: count {
327: SELECT * FROM t1 WHERE oid==11 AND b=='hello'
328: }
329: } {11 hello world 0}
330: do_test intpkey-4.6 {
331: count {
332: SELECT * FROM t1 WHERE a==11 AND b=='hello' AND c IS NOT NULL;
333: }
334: } {11 hello world 0}
335:
336: do_test intpkey-4.7 {
337: count {
338: SELECT * FROM t1 WHERE 8<rowid;
339: }
340: } {11 hello world 1}
341: do_test intpkey-4.8 {
342: count {
343: SELECT * FROM t1 WHERE 8<rowid AND 11>=oid;
344: }
345: } {11 hello world 1}
346: do_test intpkey-4.9 {
347: count {
348: SELECT * FROM t1 WHERE 11<=_rowid_ AND 12>=a;
349: }
350: } {11 hello world 1}
351: do_test intpkey-4.10 {
352: count {
353: SELECT * FROM t1 WHERE 0>=_rowid_;
354: }
355: } {-4 y z 1}
356: do_test intpkey-4.11 {
357: count {
358: SELECT * FROM t1 WHERE a<0;
359: }
360: } {-4 y z 1}
361: do_test intpkey-4.12 {
362: count {
363: SELECT * FROM t1 WHERE a<0 AND a>10;
364: }
365: } {1}
366:
367: # Make sure it is OK to insert a rowid of 0
368: #
369: do_test intpkey-5.1 {
370: execsql {
371: INSERT INTO t1 VALUES(0,'zero','entry');
372: }
373: count {
374: SELECT * FROM t1 WHERE a=0;
375: }
376: } {0 zero entry 0}
377: do_test intpkey-5.2 {
378: execsql {
379: SELECT rowid, a FROM t1
380: }
381: } {-4 -4 0 0 5 5 6 6 11 11}
382:
383: # Test the ability of the COPY command to put data into a
384: # table that contains an integer primary key.
385: #
386: # COPY command has been removed. But we retain these tests so
387: # that the tables will contain the right data for tests that follow.
388: #
389: do_test intpkey-6.1 {
390: execsql {
391: BEGIN;
392: INSERT INTO t1 VALUES(20,'b-20','c-20');
393: INSERT INTO t1 VALUES(21,'b-21','c-21');
394: INSERT INTO t1 VALUES(22,'b-22','c-22');
395: COMMIT;
396: SELECT * FROM t1 WHERE a>=20;
397: }
398: } {20 b-20 c-20 21 b-21 c-21 22 b-22 c-22}
399: do_test intpkey-6.2 {
400: execsql {
401: SELECT * FROM t1 WHERE b=='hello'
402: }
403: } {5 hello world 11 hello world}
404: do_test intpkey-6.3 {
405: execsql {
406: DELETE FROM t1 WHERE b='b-21';
407: SELECT * FROM t1 WHERE b=='b-21';
408: }
409: } {}
410: do_test intpkey-6.4 {
411: execsql {
412: SELECT * FROM t1 WHERE a>=20
413: }
414: } {20 b-20 c-20 22 b-22 c-22}
415:
416: # Do an insert of values with the columns specified out of order.
417: #
418: do_test intpkey-7.1 {
419: execsql {
420: INSERT INTO t1(c,b,a) VALUES('row','new',30);
421: SELECT * FROM t1 WHERE rowid>=30;
422: }
423: } {30 new row}
424: do_test intpkey-7.2 {
425: execsql {
426: SELECT * FROM t1 WHERE rowid>20;
427: }
428: } {22 b-22 c-22 30 new row}
429:
430: # Do an insert from a select statement.
431: #
432: do_test intpkey-8.1 {
433: execsql {
434: CREATE TABLE t2(x INTEGER PRIMARY KEY, y, z);
435: INSERT INTO t2 SELECT * FROM t1;
436: SELECT rowid FROM t2;
437: }
438: } {-4 0 5 6 11 20 22 30}
439: do_test intpkey-8.2 {
440: execsql {
441: SELECT x FROM t2;
442: }
443: } {-4 0 5 6 11 20 22 30}
444:
445: do_test intpkey-9.1 {
446: execsql {
447: UPDATE t1 SET c='www' WHERE c='world';
448: SELECT rowid, a, c FROM t1 WHERE c=='www';
449: }
450: } {5 5 www 11 11 www}
451:
452:
453: # Check insert of NULL for primary key
454: #
455: do_test intpkey-10.1 {
456: execsql {
457: DROP TABLE t2;
458: CREATE TABLE t2(x INTEGER PRIMARY KEY, y, z);
459: INSERT INTO t2 VALUES(NULL, 1, 2);
460: SELECT * from t2;
461: }
462: } {1 1 2}
463: do_test intpkey-10.2 {
464: execsql {
465: INSERT INTO t2 VALUES(NULL, 2, 3);
466: SELECT * from t2 WHERE x=2;
467: }
468: } {2 2 3}
469: do_test intpkey-10.3 {
470: execsql {
471: INSERT INTO t2 SELECT NULL, z, y FROM t2;
472: SELECT * FROM t2;
473: }
474: } {1 1 2 2 2 3 3 2 1 4 3 2}
475:
476: # This tests checks to see if a floating point number can be used
477: # to reference an integer primary key.
478: #
479: do_test intpkey-11.1 {
480: execsql {
481: SELECT b FROM t1 WHERE a=2.0+3.0;
482: }
483: } {hello}
484: do_test intpkey-11.1 {
485: execsql {
486: SELECT b FROM t1 WHERE a=2.0+3.5;
487: }
488: } {}
489:
490: integrity_check intpkey-12.1
491:
492: # Try to use a string that looks like a floating point number as
493: # an integer primary key. This should actually work when the floating
494: # point value can be rounded to an integer without loss of data.
495: #
496: do_test intpkey-13.1 {
497: execsql {
498: SELECT * FROM t1 WHERE a=1;
499: }
500: } {}
501: do_test intpkey-13.2 {
502: execsql {
503: INSERT INTO t1 VALUES('1.0',2,3);
504: SELECT * FROM t1 WHERE a=1;
505: }
506: } {1 2 3}
507: do_test intpkey-13.3 {
508: catchsql {
509: INSERT INTO t1 VALUES('1.5',3,4);
510: }
511: } {1 {datatype mismatch}}
512: ifcapable {bloblit} {
513: do_test intpkey-13.4 {
514: catchsql {
515: INSERT INTO t1 VALUES(x'123456',3,4);
516: }
517: } {1 {datatype mismatch}}
518: }
519: do_test intpkey-13.5 {
520: catchsql {
521: INSERT INTO t1 VALUES('+1234567890',3,4);
522: }
523: } {0 {}}
524:
525: # Compare an INTEGER PRIMARY KEY against a TEXT expression. The INTEGER
526: # affinity should be applied to the text value before the comparison
527: # takes place.
528: #
529: do_test intpkey-14.1 {
530: execsql {
531: CREATE TABLE t3(a INTEGER PRIMARY KEY, b INTEGER, c TEXT);
532: INSERT INTO t3 VALUES(1, 1, 'one');
533: INSERT INTO t3 VALUES(2, 2, '2');
534: INSERT INTO t3 VALUES(3, 3, 3);
535: }
536: } {}
537: do_test intpkey-14.2 {
538: execsql {
539: SELECT * FROM t3 WHERE a>2;
540: }
541: } {3 3 3}
542: do_test intpkey-14.3 {
543: execsql {
544: SELECT * FROM t3 WHERE a>'2';
545: }
546: } {3 3 3}
547: do_test intpkey-14.4 {
548: execsql {
549: SELECT * FROM t3 WHERE a<'2';
550: }
551: } {1 1 one}
552: do_test intpkey-14.5 {
553: execsql {
554: SELECT * FROM t3 WHERE a<c;
555: }
556: } {1 1 one}
557: do_test intpkey-14.6 {
558: execsql {
559: SELECT * FROM t3 WHERE a=c;
560: }
561: } {2 2 2 3 3 3}
562:
563: # Check for proper handling of primary keys greater than 2^31.
564: # Ticket #1188
565: #
566: do_test intpkey-15.1 {
567: execsql {
568: INSERT INTO t1 VALUES(2147483647, 'big-1', 123);
569: SELECT * FROM t1 WHERE a>2147483648;
570: }
571: } {}
572: do_test intpkey-15.2 {
573: execsql {
574: INSERT INTO t1 VALUES(NULL, 'big-2', 234);
575: SELECT b FROM t1 WHERE a>=2147483648;
576: }
577: } {big-2}
578: do_test intpkey-15.3 {
579: execsql {
580: SELECT b FROM t1 WHERE a>2147483648;
581: }
582: } {}
583: do_test intpkey-15.4 {
584: execsql {
585: SELECT b FROM t1 WHERE a>=2147483647;
586: }
587: } {big-1 big-2}
588: do_test intpkey-15.5 {
589: execsql {
590: SELECT b FROM t1 WHERE a<2147483648;
591: }
592: } {y zero 2 hello second hello b-20 b-22 new 3 big-1}
593: do_test intpkey-15.6 {
594: execsql {
595: SELECT b FROM t1 WHERE a<12345678901;
596: }
597: } {y zero 2 hello second hello b-20 b-22 new 3 big-1 big-2}
598: do_test intpkey-15.7 {
599: execsql {
600: SELECT b FROM t1 WHERE a>12345678901;
601: }
602: } {}
603:
604:
605: finish_test
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>