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

/trunk/src/sqlite/test/types.test

#
Unknown | 325 lines | 299 code | 26 blank | 0 comment | 0 complexity | 3108cfa6e31516761431c39609adbaa7 MD5 | raw file
Possible License(s): BSD-3-Clause
  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. Specfically
  12. # it tests that the different storage classes (integer, real, text etc.)
  13. # all work correctly.
  14. #
  15. # $Id: types.test,v 1.20 2009/06/29 06:00:37 danielk1977 Exp $
  16. set testdir [file dirname $argv0]
  17. source $testdir/tester.tcl
  18. # Tests in this file are organized roughly as follows:
  19. #
  20. # types-1.*.*: Test that values are stored using the expected storage
  21. # classes when various forms of literals are inserted into
  22. # columns with different affinities.
  23. # types-1.1.*: INSERT INTO <table> VALUES(...)
  24. # types-1.2.*: INSERT INTO <table> SELECT...
  25. # types-1.3.*: UPDATE <table> SET...
  26. #
  27. # types-2.*.*: Check that values can be stored and retrieving using the
  28. # various storage classes.
  29. # types-2.1.*: INTEGER
  30. # types-2.2.*: REAL
  31. # types-2.3.*: NULL
  32. # types-2.4.*: TEXT
  33. # types-2.5.*: Records with a few different storage classes.
  34. #
  35. # types-3.*: Test that the '=' operator respects manifest types.
  36. #
  37. # Disable encryption on the database for this test.
  38. db close
  39. set DB [sqlite3 db test.db; sqlite3_connection_pointer db]
  40. sqlite3_rekey $DB {}
  41. # Create a table with one column for each type of affinity
  42. do_test types-1.1.0 {
  43. execsql {
  44. CREATE TABLE t1(i integer, n numeric, t text, o blob);
  45. }
  46. } {}
  47. # Each element of the following list represents one test case.
  48. #
  49. # The first value of each sub-list is an SQL literal. The following
  50. # four value are the storage classes that would be used if the
  51. # literal were inserted into a column with affinity INTEGER, NUMERIC, TEXT
  52. # or NONE, respectively.
  53. set values {
  54. { 5.0 integer integer text real }
  55. { 5.1 real real text real }
  56. { 5 integer integer text integer }
  57. { '5.0' integer integer text text }
  58. { '5.1' real real text text }
  59. { '-5.0' integer integer text text }
  60. { '-5.0' integer integer text text }
  61. { '5' integer integer text text }
  62. { 'abc' text text text text }
  63. { NULL null null null null }
  64. }
  65. ifcapable {bloblit} {
  66. lappend values { X'00' blob blob blob blob }
  67. }
  68. # This code tests that the storage classes specified above (in the $values
  69. # table) are correctly assigned when values are inserted using a statement
  70. # of the form:
  71. #
  72. # INSERT INTO <table> VALUE(<values>);
  73. #
  74. set tnum 1
  75. foreach val $values {
  76. set lit [lindex $val 0]
  77. execsql "DELETE FROM t1;"
  78. execsql "INSERT INTO t1 VALUES($lit, $lit, $lit, $lit);"
  79. do_test types-1.1.$tnum {
  80. execsql {
  81. SELECT typeof(i), typeof(n), typeof(t), typeof(o) FROM t1;
  82. }
  83. } [lrange $val 1 end]
  84. incr tnum
  85. }
  86. # This code tests that the storage classes specified above (in the $values
  87. # table) are correctly assigned when values are inserted using a statement
  88. # of the form:
  89. #
  90. # INSERT INTO t1 SELECT ....
  91. #
  92. set tnum 1
  93. foreach val $values {
  94. set lit [lindex $val 0]
  95. execsql "DELETE FROM t1;"
  96. execsql "INSERT INTO t1 SELECT $lit, $lit, $lit, $lit;"
  97. do_test types-1.2.$tnum {
  98. execsql {
  99. SELECT typeof(i), typeof(n), typeof(t), typeof(o) FROM t1;
  100. }
  101. } [lrange $val 1 end]
  102. incr tnum
  103. }
  104. # This code tests that the storage classes specified above (in the $values
  105. # table) are correctly assigned when values are inserted using a statement
  106. # of the form:
  107. #
  108. # UPDATE <table> SET <column> = <value>;
  109. #
  110. set tnum 1
  111. foreach val $values {
  112. set lit [lindex $val 0]
  113. execsql "UPDATE t1 SET i = $lit, n = $lit, t = $lit, o = $lit;"
  114. do_test types-1.3.$tnum {
  115. execsql {
  116. SELECT typeof(i), typeof(n), typeof(t), typeof(o) FROM t1;
  117. }
  118. } [lrange $val 1 end]
  119. incr tnum
  120. }
  121. execsql {
  122. DROP TABLE t1;
  123. }
  124. # Open the table with root-page $rootpage at the btree
  125. # level. Return a list that is the length of each record
  126. # in the table, in the tables default scanning order.
  127. proc record_sizes {rootpage} {
  128. set bt [btree_open test.db 10]
  129. btree_begin_transaction $bt
  130. set c [btree_cursor $bt $rootpage 0]
  131. btree_first $c
  132. while 1 {
  133. lappend res [btree_payload_size $c]
  134. if {[btree_next $c]} break
  135. }
  136. btree_close_cursor $c
  137. btree_close $bt
  138. set res
  139. }
  140. # Create a table and insert some 1-byte integers. Make sure they
  141. # can be read back OK. These should be 3 byte records.
  142. do_test types-2.1.1 {
  143. execsql {
  144. CREATE TABLE t1(a integer);
  145. INSERT INTO t1 VALUES(0);
  146. INSERT INTO t1 VALUES(120);
  147. INSERT INTO t1 VALUES(-120);
  148. }
  149. } {}
  150. do_test types-2.1.2 {
  151. execsql {
  152. SELECT a FROM t1;
  153. }
  154. } {0 120 -120}
  155. # Try some 2-byte integers (4 byte records)
  156. do_test types-2.1.3 {
  157. execsql {
  158. INSERT INTO t1 VALUES(30000);
  159. INSERT INTO t1 VALUES(-30000);
  160. }
  161. } {}
  162. do_test types-2.1.4 {
  163. execsql {
  164. SELECT a FROM t1;
  165. }
  166. } {0 120 -120 30000 -30000}
  167. # 4-byte integers (6 byte records)
  168. do_test types-2.1.5 {
  169. execsql {
  170. INSERT INTO t1 VALUES(2100000000);
  171. INSERT INTO t1 VALUES(-2100000000);
  172. }
  173. } {}
  174. do_test types-2.1.6 {
  175. execsql {
  176. SELECT a FROM t1;
  177. }
  178. } {0 120 -120 30000 -30000 2100000000 -2100000000}
  179. # 8-byte integers (10 byte records)
  180. do_test types-2.1.7 {
  181. execsql {
  182. INSERT INTO t1 VALUES(9000000*1000000*1000000);
  183. INSERT INTO t1 VALUES(-9000000*1000000*1000000);
  184. }
  185. } {}
  186. do_test types-2.1.8 {
  187. execsql {
  188. SELECT a FROM t1;
  189. }
  190. } [list 0 120 -120 30000 -30000 2100000000 -2100000000 \
  191. 9000000000000000000 -9000000000000000000]
  192. # Check that all the record sizes are as we expected.
  193. ifcapable legacyformat {
  194. do_test types-2.1.9 {
  195. set root [db eval {select rootpage from sqlite_master where name = 't1'}]
  196. record_sizes $root
  197. } {3 3 3 4 4 6 6 10 10}
  198. } else {
  199. do_test types-2.1.9 {
  200. set root [db eval {select rootpage from sqlite_master where name = 't1'}]
  201. record_sizes $root
  202. } {2 3 3 4 4 6 6 10 10}
  203. }
  204. # Insert some reals. These should be 10 byte records.
  205. do_test types-2.2.1 {
  206. execsql {
  207. CREATE TABLE t2(a float);
  208. INSERT INTO t2 VALUES(0.0);
  209. INSERT INTO t2 VALUES(12345.678);
  210. INSERT INTO t2 VALUES(-12345.678);
  211. }
  212. } {}
  213. do_test types-2.2.2 {
  214. execsql {
  215. SELECT a FROM t2;
  216. }
  217. } {0.0 12345.678 -12345.678}
  218. # Check that all the record sizes are as we expected.
  219. ifcapable legacyformat {
  220. do_test types-2.2.3 {
  221. set root [db eval {select rootpage from sqlite_master where name = 't2'}]
  222. record_sizes $root
  223. } {3 10 10}
  224. } else {
  225. do_test types-2.2.3 {
  226. set root [db eval {select rootpage from sqlite_master where name = 't2'}]
  227. record_sizes $root
  228. } {2 10 10}
  229. }
  230. # Insert a NULL. This should be a two byte record.
  231. do_test types-2.3.1 {
  232. execsql {
  233. CREATE TABLE t3(a nullvalue);
  234. INSERT INTO t3 VALUES(NULL);
  235. }
  236. } {}
  237. do_test types-2.3.2 {
  238. execsql {
  239. SELECT a ISNULL FROM t3;
  240. }
  241. } {1}
  242. # Check that all the record sizes are as we expected.
  243. do_test types-2.3.3 {
  244. set root [db eval {select rootpage from sqlite_master where name = 't3'}]
  245. record_sizes $root
  246. } {2}
  247. # Insert a couple of strings.
  248. do_test types-2.4.1 {
  249. set string10 abcdefghij
  250. set string500 [string repeat $string10 50]
  251. set string500000 [string repeat $string10 50000]
  252. execsql "
  253. CREATE TABLE t4(a string);
  254. INSERT INTO t4 VALUES('$string10');
  255. INSERT INTO t4 VALUES('$string500');
  256. INSERT INTO t4 VALUES('$string500000');
  257. "
  258. } {}
  259. do_test types-2.4.2 {
  260. execsql {
  261. SELECT a FROM t4;
  262. }
  263. } [list $string10 $string500 $string500000]
  264. # Check that all the record sizes are as we expected. This is dependant on
  265. # the database encoding.
  266. if { $sqlite_options(utf16)==0 || [execsql {pragma encoding}] == "UTF-8" } {
  267. do_test types-2.4.3 {
  268. set root [db eval {select rootpage from sqlite_master where name = 't4'}]
  269. record_sizes $root
  270. } {12 503 500004}
  271. } else {
  272. do_test types-2.4.3 {
  273. set root [db eval {select rootpage from sqlite_master where name = 't4'}]
  274. record_sizes $root
  275. } {22 1003 1000004}
  276. }
  277. do_test types-2.5.1 {
  278. execsql {
  279. DROP TABLE t1;
  280. DROP TABLE t2;
  281. DROP TABLE t3;
  282. DROP TABLE t4;
  283. CREATE TABLE t1(a, b, c);
  284. }
  285. } {}
  286. do_test types-2.5.2 {
  287. set string10 abcdefghij
  288. set string500 [string repeat $string10 50]
  289. set string500000 [string repeat $string10 50000]
  290. execsql "INSERT INTO t1 VALUES(NULL, '$string10', 4000);"
  291. execsql "INSERT INTO t1 VALUES('$string500', 4000, NULL);"
  292. execsql "INSERT INTO t1 VALUES(4000, NULL, '$string500000');"
  293. } {}
  294. do_test types-2.5.3 {
  295. execsql {
  296. SELECT * FROM t1;
  297. }
  298. } [list {} $string10 4000 $string500 4000 {} 4000 {} $string500000]
  299. finish_test