Annotation of embedaddon/sqlite3/test/enc2.test, revision 1.1
1.1 ! misho 1: # 2002 May 24
! 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 focus of
! 12: # this file is testing the SQLite routines used for converting between the
! 13: # various suported unicode encodings (UTF-8, UTF-16, UTF-16le and
! 14: # UTF-16be).
! 15: #
! 16: # $Id: enc2.test,v 1.29 2007/10/09 08:29:32 danielk1977 Exp $
! 17:
! 18: set testdir [file dirname $argv0]
! 19: source $testdir/tester.tcl
! 20:
! 21: # If UTF16 support is disabled, ignore the tests in this file
! 22: #
! 23: ifcapable {!utf16} {
! 24: finish_test
! 25: return
! 26: }
! 27:
! 28: # The rough organisation of tests in this file is:
! 29: #
! 30: # enc2.1.*: Simple tests with a UTF-8 db.
! 31: # enc2.2.*: Simple tests with a UTF-16LE db.
! 32: # enc2.3.*: Simple tests with a UTF-16BE db.
! 33: # enc2.4.*: Test that attached databases must have the same text encoding
! 34: # as the main database.
! 35: # enc2.5.*: Test the behaviour of the library when a collation sequence is
! 36: # not available for the most desirable text encoding.
! 37: # enc2.6.*: Similar test for user functions.
! 38: # enc2.7.*: Test that the VerifyCookie opcode protects against assuming the
! 39: # wrong text encoding for the database.
! 40: # enc2.8.*: Test sqlite3_complete16()
! 41: #
! 42:
! 43: db close
! 44:
! 45: # Return the UTF-8 representation of the supplied UTF-16 string $str.
! 46: proc utf8 {str} {
! 47: # If $str ends in two 0x00 0x00 bytes, knock these off before
! 48: # converting to UTF-8 using TCL.
! 49: binary scan $str \c* vals
! 50: if {[lindex $vals end]==0 && [lindex $vals end-1]==0} {
! 51: set str [binary format \c* [lrange $vals 0 end-2]]
! 52: }
! 53:
! 54: set r [encoding convertfrom unicode $str]
! 55: return $r
! 56: }
! 57:
! 58: #
! 59: # This proc contains all the tests in this file. It is run
! 60: # three times. Each time the file 'test.db' contains a database
! 61: # with the following contents:
! 62: set dbcontents {
! 63: CREATE TABLE t1(a PRIMARY KEY, b, c);
! 64: INSERT INTO t1 VALUES('one', 'I', 1);
! 65: }
! 66: # This proc tests that we can open and manipulate the test.db
! 67: # database, and that it is possible to retreive values in
! 68: # various text encodings.
! 69: #
! 70: proc run_test_script {t enc} {
! 71:
! 72: # Open the database and pull out a (the) row.
! 73: do_test $t.1 {
! 74: sqlite3 db test.db; set DB [sqlite3_connection_pointer db]
! 75: execsql {SELECT * FROM t1}
! 76: } {one I 1}
! 77:
! 78: # Insert some data
! 79: do_test $t.2 {
! 80: execsql {INSERT INTO t1 VALUES('two', 'II', 2);}
! 81: execsql {SELECT * FROM t1}
! 82: } {one I 1 two II 2}
! 83:
! 84: # Insert some data
! 85: do_test $t.3 {
! 86: execsql {
! 87: INSERT INTO t1 VALUES('three','III',3);
! 88: INSERT INTO t1 VALUES('four','IV',4);
! 89: INSERT INTO t1 VALUES('five','V',5);
! 90: }
! 91: execsql {SELECT * FROM t1}
! 92: } {one I 1 two II 2 three III 3 four IV 4 five V 5}
! 93:
! 94: # Use the index
! 95: do_test $t.4 {
! 96: execsql {
! 97: SELECT * FROM t1 WHERE a = 'one';
! 98: }
! 99: } {one I 1}
! 100: do_test $t.5 {
! 101: execsql {
! 102: SELECT * FROM t1 WHERE a = 'four';
! 103: }
! 104: } {four IV 4}
! 105: ifcapable subquery {
! 106: do_test $t.6 {
! 107: execsql {
! 108: SELECT * FROM t1 WHERE a IN ('one', 'two');
! 109: }
! 110: } {one I 1 two II 2}
! 111: }
! 112:
! 113: # Now check that we can retrieve data in both UTF-16 and UTF-8
! 114: do_test $t.7 {
! 115: set STMT [sqlite3_prepare $DB "SELECT a FROM t1 WHERE c>3;" -1 TAIL]
! 116: sqlite3_step $STMT
! 117: sqlite3_column_text $STMT 0
! 118: } {four}
! 119:
! 120: do_test $t.8 {
! 121: sqlite3_step $STMT
! 122: utf8 [sqlite3_column_text16 $STMT 0]
! 123: } {five}
! 124:
! 125: do_test $t.9 {
! 126: sqlite3_finalize $STMT
! 127: } SQLITE_OK
! 128:
! 129: ifcapable vacuum {
! 130: execsql VACUUM
! 131: }
! 132:
! 133: do_test $t.10 {
! 134: db eval {PRAGMA encoding}
! 135: } $enc
! 136:
! 137: }
! 138:
! 139: # The three unicode encodings understood by SQLite.
! 140: set encodings [list UTF-8 UTF-16le UTF-16be]
! 141:
! 142: set sqlite_os_trace 0
! 143: set i 1
! 144: foreach enc $encodings {
! 145: forcedelete test.db
! 146: sqlite3 db test.db
! 147: db eval "PRAGMA encoding = \"$enc\""
! 148: execsql $dbcontents
! 149: do_test enc2-$i.0.1 {
! 150: db eval {PRAGMA encoding}
! 151: } $enc
! 152: do_test enc2-$i.0.2 {
! 153: db eval {PRAGMA encoding=UTF8}
! 154: db eval {PRAGMA encoding}
! 155: } $enc
! 156: do_test enc2-$i.0.3 {
! 157: db eval {PRAGMA encoding=UTF16le}
! 158: db eval {PRAGMA encoding}
! 159: } $enc
! 160: do_test enc2-$i.0.4 {
! 161: db eval {PRAGMA encoding=UTF16be}
! 162: db eval {PRAGMA encoding}
! 163: } $enc
! 164:
! 165: db close
! 166: run_test_script enc2-$i $enc
! 167: db close
! 168: incr i
! 169: }
! 170:
! 171: # Test that it is an error to try to attach a database with a different
! 172: # encoding to the main database.
! 173: ifcapable attach {
! 174: do_test enc2-4.1 {
! 175: forcedelete test.db
! 176: sqlite3 db test.db
! 177: db eval "PRAGMA encoding = 'UTF-8'"
! 178: db eval "CREATE TABLE abc(a, b, c);"
! 179: } {}
! 180: do_test enc2-4.2 {
! 181: forcedelete test2.db
! 182: sqlite3 db2 test2.db
! 183: db2 eval "PRAGMA encoding = 'UTF-16'"
! 184: db2 eval "CREATE TABLE abc(a, b, c);"
! 185: } {}
! 186: do_test enc2-4.3 {
! 187: catchsql {
! 188: ATTACH 'test2.db' as aux;
! 189: }
! 190: } {1 {attached databases must use the same text encoding as main database}}
! 191: db2 close
! 192: db close
! 193: }
! 194:
! 195: # The following tests - enc2-5.* - test that SQLite selects the correct
! 196: # collation sequence when more than one is available.
! 197:
! 198: set ::values [list one two three four five]
! 199: set ::test_collate_enc INVALID
! 200: proc test_collate {enc lhs rhs} {
! 201: set ::test_collate_enc $enc
! 202: set l [lsearch -exact $::values $lhs]
! 203: set r [lsearch -exact $::values $rhs]
! 204: set res [expr $l - $r]
! 205: # puts "enc=$enc lhs=$lhs/$l rhs=$rhs/$r res=$res"
! 206: return $res
! 207: }
! 208:
! 209: forcedelete test.db
! 210: sqlite3 db test.db; set DB [sqlite3_connection_pointer db]
! 211: do_test enc2-5.0 {
! 212: execsql {
! 213: CREATE TABLE t5(a);
! 214: INSERT INTO t5 VALUES('one');
! 215: INSERT INTO t5 VALUES('two');
! 216: INSERT INTO t5 VALUES('five');
! 217: INSERT INTO t5 VALUES('three');
! 218: INSERT INTO t5 VALUES('four');
! 219: }
! 220: } {}
! 221: do_test enc2-5.1 {
! 222: add_test_collate $DB 1 1 1
! 223: set res [execsql {SELECT * FROM t5 ORDER BY 1 COLLATE test_collate;}]
! 224: lappend res $::test_collate_enc
! 225: } {one two three four five UTF-8}
! 226: do_test enc2-5.2 {
! 227: add_test_collate $DB 0 1 0
! 228: set res [execsql {SELECT * FROM t5 ORDER BY 1 COLLATE test_collate}]
! 229: lappend res $::test_collate_enc
! 230: } {one two three four five UTF-16LE}
! 231: do_test enc2-5.3 {
! 232: add_test_collate $DB 0 0 1
! 233: set res [execsql {SELECT * FROM t5 ORDER BY 1 COLLATE test_collate}]
! 234: lappend res $::test_collate_enc
! 235: } {one two three four five UTF-16BE}
! 236:
! 237: db close
! 238: forcedelete test.db
! 239: sqlite3 db test.db; set DB [sqlite3_connection_pointer db]
! 240: execsql {pragma encoding = 'UTF-16LE'}
! 241: do_test enc2-5.4 {
! 242: execsql {
! 243: CREATE TABLE t5(a);
! 244: INSERT INTO t5 VALUES('one');
! 245: INSERT INTO t5 VALUES('two');
! 246: INSERT INTO t5 VALUES('five');
! 247: INSERT INTO t5 VALUES('three');
! 248: INSERT INTO t5 VALUES('four');
! 249: }
! 250: } {}
! 251: do_test enc2-5.5 {
! 252: add_test_collate $DB 1 1 1
! 253: set res [execsql {SELECT * FROM t5 ORDER BY 1 COLLATE test_collate}]
! 254: lappend res $::test_collate_enc
! 255: } {one two three four five UTF-16LE}
! 256: do_test enc2-5.6 {
! 257: add_test_collate $DB 1 0 1
! 258: set res [execsql {SELECT * FROM t5 ORDER BY 1 COLLATE test_collate}]
! 259: lappend res $::test_collate_enc
! 260: } {one two three four five UTF-16BE}
! 261: do_test enc2-5.7 {
! 262: add_test_collate $DB 1 0 0
! 263: set res [execsql {SELECT * FROM t5 ORDER BY 1 COLLATE test_collate}]
! 264: lappend res $::test_collate_enc
! 265: } {one two three four five UTF-8}
! 266:
! 267: db close
! 268: forcedelete test.db
! 269: sqlite3 db test.db; set DB [sqlite3_connection_pointer db]
! 270: execsql {pragma encoding = 'UTF-16BE'}
! 271: do_test enc2-5.8 {
! 272: execsql {
! 273: CREATE TABLE t5(a);
! 274: INSERT INTO t5 VALUES('one');
! 275: INSERT INTO t5 VALUES('two');
! 276: INSERT INTO t5 VALUES('five');
! 277: INSERT INTO t5 VALUES('three');
! 278: INSERT INTO t5 VALUES('four');
! 279: }
! 280: } {}
! 281: do_test enc2-5.9 {
! 282: add_test_collate $DB 1 1 1
! 283: set res [execsql {SELECT * FROM t5 ORDER BY 1 COLLATE test_collate}]
! 284: lappend res $::test_collate_enc
! 285: } {one two three four five UTF-16BE}
! 286: do_test enc2-5.10 {
! 287: add_test_collate $DB 1 1 0
! 288: set res [execsql {SELECT * FROM t5 ORDER BY 1 COLLATE test_collate}]
! 289: lappend res $::test_collate_enc
! 290: } {one two three four five UTF-16LE}
! 291: do_test enc2-5.11 {
! 292: add_test_collate $DB 1 0 0
! 293: set res [execsql {SELECT * FROM t5 ORDER BY 1 COLLATE test_collate}]
! 294: lappend res $::test_collate_enc
! 295: } {one two three four five UTF-8}
! 296:
! 297: # Also test that a UTF-16 collation factory works.
! 298: do_test enc2-5-12 {
! 299: add_test_collate $DB 0 0 0
! 300: catchsql {
! 301: SELECT * FROM t5 ORDER BY 1 COLLATE test_collate
! 302: }
! 303: } {1 {no such collation sequence: test_collate}}
! 304: do_test enc2-5.13 {
! 305: add_test_collate_needed $DB
! 306: set res [execsql {SELECT * FROM t5 ORDER BY 1 COLLATE test_collate; }]
! 307: lappend res $::test_collate_enc
! 308: } {one two three four five UTF-16BE}
! 309: do_test enc2-5.14 {
! 310: set ::sqlite_last_needed_collation
! 311: } test_collate
! 312:
! 313: db close
! 314: forcedelete test.db
! 315:
! 316: do_test enc2-5.15 {
! 317: sqlite3 db test.db; set ::DB [sqlite3_connection_pointer db]
! 318: add_test_collate_needed $::DB
! 319: set ::sqlite_last_needed_collation
! 320: } {}
! 321: do_test enc2-5.16 {
! 322: execsql {CREATE TABLE t1(a varchar collate test_collate);}
! 323: } {}
! 324: do_test enc2-5.17 {
! 325: set ::sqlite_last_needed_collation
! 326: } {test_collate}
! 327:
! 328: # The following tests - enc2-6.* - test that SQLite selects the correct
! 329: # user function when more than one is available.
! 330:
! 331: proc test_function {enc arg} {
! 332: return "$enc $arg"
! 333: }
! 334:
! 335: db close
! 336: forcedelete test.db
! 337: sqlite3 db test.db; set DB [sqlite3_connection_pointer db]
! 338: execsql {pragma encoding = 'UTF-8'}
! 339: do_test enc2-6.0 {
! 340: execsql {
! 341: CREATE TABLE t5(a);
! 342: INSERT INTO t5 VALUES('one');
! 343: }
! 344: } {}
! 345: do_test enc2-6.1 {
! 346: add_test_function $DB 1 1 1
! 347: execsql {
! 348: SELECT test_function('sqlite')
! 349: }
! 350: } {{UTF-8 sqlite}}
! 351: db close
! 352: sqlite3 db test.db; set DB [sqlite3_connection_pointer db]
! 353: do_test enc2-6.2 {
! 354: add_test_function $DB 0 1 0
! 355: execsql {
! 356: SELECT test_function('sqlite')
! 357: }
! 358: } {{UTF-16LE sqlite}}
! 359: db close
! 360: sqlite3 db test.db; set DB [sqlite3_connection_pointer db]
! 361: do_test enc2-6.3 {
! 362: add_test_function $DB 0 0 1
! 363: execsql {
! 364: SELECT test_function('sqlite')
! 365: }
! 366: } {{UTF-16BE sqlite}}
! 367:
! 368: db close
! 369: forcedelete test.db
! 370: sqlite3 db test.db; set DB [sqlite3_connection_pointer db]
! 371: execsql {pragma encoding = 'UTF-16LE'}
! 372: do_test enc2-6.3 {
! 373: execsql {
! 374: CREATE TABLE t5(a);
! 375: INSERT INTO t5 VALUES('sqlite');
! 376: }
! 377: } {}
! 378: do_test enc2-6.4 {
! 379: add_test_function $DB 1 1 1
! 380: execsql {
! 381: SELECT test_function('sqlite')
! 382: }
! 383: } {{UTF-16LE sqlite}}
! 384: db close
! 385: sqlite3 db test.db; set DB [sqlite3_connection_pointer db]
! 386: do_test enc2-6.5 {
! 387: add_test_function $DB 0 1 0
! 388: execsql {
! 389: SELECT test_function('sqlite')
! 390: }
! 391: } {{UTF-16LE sqlite}}
! 392: db close
! 393: sqlite3 db test.db; set DB [sqlite3_connection_pointer db]
! 394: do_test enc2-6.6 {
! 395: add_test_function $DB 0 0 1
! 396: execsql {
! 397: SELECT test_function('sqlite')
! 398: }
! 399: } {{UTF-16BE sqlite}}
! 400:
! 401: db close
! 402: forcedelete test.db
! 403: sqlite3 db test.db; set DB [sqlite3_connection_pointer db]
! 404: execsql {pragma encoding = 'UTF-16BE'}
! 405: do_test enc2-6.7 {
! 406: execsql {
! 407: CREATE TABLE t5(a);
! 408: INSERT INTO t5 VALUES('sqlite');
! 409: }
! 410: } {}
! 411: do_test enc2-6.8 {
! 412: add_test_function $DB 1 1 1
! 413: execsql {
! 414: SELECT test_function('sqlite')
! 415: }
! 416: } {{UTF-16BE sqlite}}
! 417: db close
! 418: sqlite3 db test.db; set DB [sqlite3_connection_pointer db]
! 419: do_test enc2-6.9 {
! 420: add_test_function $DB 0 1 0
! 421: execsql {
! 422: SELECT test_function('sqlite')
! 423: }
! 424: } {{UTF-16LE sqlite}}
! 425: db close
! 426: sqlite3 db test.db; set DB [sqlite3_connection_pointer db]
! 427: do_test enc2-6.10 {
! 428: add_test_function $DB 0 0 1
! 429: execsql {
! 430: SELECT test_function('sqlite')
! 431: }
! 432: } {{UTF-16BE sqlite}}
! 433:
! 434:
! 435: db close
! 436: forcedelete test.db
! 437:
! 438: # The following tests - enc2-7.* - function as follows:
! 439: #
! 440: # 1: Open an empty database file assuming UTF-16 encoding.
! 441: # 2: Open the same database with a different handle assuming UTF-8. Create
! 442: # a table using this handle.
! 443: # 3: Read the sqlite_master table from the first handle.
! 444: # 4: Ensure the first handle recognises the database encoding is UTF-8.
! 445: #
! 446: do_test enc2-7.1 {
! 447: sqlite3 db test.db
! 448: execsql {
! 449: PRAGMA encoding = 'UTF-16';
! 450: SELECT * FROM sqlite_master;
! 451: }
! 452: } {}
! 453: do_test enc2-7.2 {
! 454: set enc [execsql {
! 455: PRAGMA encoding;
! 456: }]
! 457: string range $enc 0 end-2 ;# Chop off the "le" or "be"
! 458: } {UTF-16}
! 459: do_test enc2-7.3 {
! 460: sqlite3 db2 test.db
! 461: execsql {
! 462: PRAGMA encoding = 'UTF-8';
! 463: CREATE TABLE abc(a, b, c);
! 464: } db2
! 465: } {}
! 466: do_test enc2-7.4 {
! 467: execsql {
! 468: SELECT * FROM sqlite_master;
! 469: }
! 470: } "table abc abc [expr $AUTOVACUUM?3:2] {CREATE TABLE abc(a, b, c)}"
! 471: do_test enc2-7.5 {
! 472: execsql {
! 473: PRAGMA encoding;
! 474: }
! 475: } {UTF-8}
! 476:
! 477: db close
! 478: db2 close
! 479:
! 480: proc utf16 {utf8} {
! 481: set utf16 [encoding convertto unicode $utf8]
! 482: append utf16 "\x00\x00"
! 483: return $utf16
! 484: }
! 485: ifcapable {complete} {
! 486: do_test enc2-8.1 {
! 487: sqlite3_complete16 [utf16 "SELECT * FROM t1;"]
! 488: } {1}
! 489: do_test enc2-8.2 {
! 490: sqlite3_complete16 [utf16 "SELECT * FROM"]
! 491: } {0}
! 492: }
! 493:
! 494: # Test that the encoding of an empty database may still be set after the
! 495: # (empty) schema has been initialized.
! 496: forcedelete test.db
! 497: do_test enc2-9.1 {
! 498: sqlite3 db test.db
! 499: execsql {
! 500: PRAGMA encoding = 'UTF-8';
! 501: PRAGMA encoding;
! 502: }
! 503: } {UTF-8}
! 504: do_test enc2-9.2 {
! 505: sqlite3 db test.db
! 506: execsql {
! 507: PRAGMA encoding = 'UTF-16le';
! 508: PRAGMA encoding;
! 509: }
! 510: } {UTF-16le}
! 511: do_test enc2-9.3 {
! 512: sqlite3 db test.db
! 513: execsql {
! 514: SELECT * FROM sqlite_master;
! 515: PRAGMA encoding = 'UTF-8';
! 516: PRAGMA encoding;
! 517: }
! 518: } {UTF-8}
! 519: do_test enc2-9.4 {
! 520: sqlite3 db test.db
! 521: execsql {
! 522: PRAGMA encoding = 'UTF-16le';
! 523: CREATE TABLE abc(a, b, c);
! 524: PRAGMA encoding;
! 525: }
! 526: } {UTF-16le}
! 527: do_test enc2-9.5 {
! 528: sqlite3 db test.db
! 529: execsql {
! 530: PRAGMA encoding = 'UTF-8';
! 531: PRAGMA encoding;
! 532: }
! 533: } {UTF-16le}
! 534:
! 535: # Ticket #1987.
! 536: # Disallow encoding changes once the encoding has been set.
! 537: #
! 538: do_test enc2-10.1 {
! 539: db close
! 540: forcedelete test.db test.db-journal
! 541: sqlite3 db test.db
! 542: db eval {
! 543: PRAGMA encoding=UTF16;
! 544: CREATE TABLE t1(a);
! 545: PRAGMA encoding=UTF8;
! 546: CREATE TABLE t2(b);
! 547: }
! 548: db close
! 549: sqlite3 db test.db
! 550: db eval {
! 551: SELECT name FROM sqlite_master
! 552: }
! 553: } {t1 t2}
! 554:
! 555: finish_test
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>