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>