Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Or the SQLITE_UTF16_ALIGNED with the encoding field in sqlite3_create_collation and UTF16 strings will always be aligned on an even byte boundary when passed into the comparison function. (CVS 3103) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
7a1701e8c562087d364dff28cd7cad7c |
User & Date: | drh 2006-02-16 18:16:37.000 |
Context
2006-02-17
| ||
12:25 | Ensure temp db is open before executing a pragma like "temp.cachesize = xxx". Fix for #1682. (CVS 3104) (check-in: 1e4644b236 user: danielk1977 tags: trunk) | |
2006-02-16
| ||
18:16 | Or the SQLITE_UTF16_ALIGNED with the encoding field in sqlite3_create_collation and UTF16 strings will always be aligned on an even byte boundary when passed into the comparison function. (CVS 3103) (check-in: 7a1701e8c5 user: drh tags: trunk) | |
00:32 | Fix more typos in the file format document. (CVS 3102) (check-in: d7495be806 user: drh tags: trunk) | |
Changes
Changes to src/main.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** ** $Id: main.c,v 1.335 2006/02/16 18:16:37 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> /* ** The following constant value is used by the SQLITE_BIGENDIAN and |
︙ | ︙ | |||
739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 | sqlite3* db, const char *zName, int enc, void* pCtx, int(*xCompare)(void*,int,const void*,int,const void*) ){ CollSeq *pColl; if( sqlite3SafetyCheck(db) ){ return SQLITE_MISUSE; } /* If SQLITE_UTF16 is specified as the encoding type, transform this ** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the ** SQLITE_UTF16NATIVE macro. SQLITE_UTF16 is not used internally. */ | > > | | < > | < < < | | | | 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 | sqlite3* db, const char *zName, int enc, void* pCtx, int(*xCompare)(void*,int,const void*,int,const void*) ){ CollSeq *pColl; int enc2; if( sqlite3SafetyCheck(db) ){ return SQLITE_MISUSE; } /* If SQLITE_UTF16 is specified as the encoding type, transform this ** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the ** SQLITE_UTF16NATIVE macro. SQLITE_UTF16 is not used internally. */ enc2 = enc & ~SQLITE_UTF16_ALIGNED; if( enc2==SQLITE_UTF16 ){ enc2 = SQLITE_UTF16NATIVE; } if( (enc2&~3)!=0 ){ sqlite3Error(db, SQLITE_ERROR, "unknown encoding"); return SQLITE_ERROR; } /* Check if this call is removing or replacing an existing collation ** sequence. If so, and there are active VMs, return busy. If there ** are no active VMs, invalidate any pre-compiled statements. */ pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, strlen(zName), 0); if( pColl && pColl->xCmp ){ if( db->activeVdbeCnt ){ sqlite3Error(db, SQLITE_BUSY, "Unable to delete/modify collation sequence due to active statements"); return SQLITE_BUSY; } sqlite3ExpirePreparedStatements(db); } pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, strlen(zName), 1); if( pColl ){ pColl->xCmp = xCompare; pColl->pUser = pCtx; pColl->enc = enc2 | (enc & SQLITE_UTF16_ALIGNED); } sqlite3Error(db, SQLITE_OK, 0); return SQLITE_OK; } /* |
︙ | ︙ | |||
1226 1227 1228 1229 1230 1231 1232 | rc = SQLITE_ERROR; } sqlite3Error(db, rc, (zErrMsg?"%s":0), zErrMsg); sqliteFree(zErrMsg); return sqlite3ApiExit(db, rc); } #endif | < | 1225 1226 1227 1228 1229 1230 1231 | rc = SQLITE_ERROR; } sqlite3Error(db, rc, (zErrMsg?"%s":0), zErrMsg); sqliteFree(zErrMsg); return sqlite3ApiExit(db, rc); } #endif |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the SQLite library ** presents to client programs. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the SQLite library ** presents to client programs. ** ** @(#) $Id: sqlite.h.in,v 1.163 2006/02/16 18:16:37 drh Exp $ */ #ifndef _SQLITE3_H_ #define _SQLITE3_H_ #include <stdarg.h> /* Needed for the definition of va_list */ /* ** Make sure we can call this stuff from C++. |
︙ | ︙ | |||
1110 1111 1112 1113 1114 1115 1116 | void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); void sqlite3_result_value(sqlite3_context*, sqlite3_value*); /* ** These are the allowed values for the eTextRep argument to ** sqlite3_create_collation and sqlite3_create_function. */ | | | | | | > | 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 | void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); void sqlite3_result_value(sqlite3_context*, sqlite3_value*); /* ** These are the allowed values for the eTextRep argument to ** sqlite3_create_collation and sqlite3_create_function. */ #define SQLITE_UTF8 1 #define SQLITE_UTF16LE 2 #define SQLITE_UTF16BE 3 #define SQLITE_UTF16 4 /* Use native byte order */ #define SQLITE_ANY 5 /* sqlite3_create_function only */ #define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */ /* ** These two functions are used to add new collation sequences to the ** sqlite3 handle specified as the first argument. ** ** The name of the new collation sequence is specified as a UTF-8 string ** for sqlite3_create_collation() and a UTF-16 string for |
︙ | ︙ |
Changes to src/sqliteInt.h.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** ** @(#) $Id: sqliteInt.h,v 1.484 2006/02/16 18:16:37 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ /* ** Extra interface definitions for those who need them */ |
︙ | ︙ | |||
247 248 249 250 251 252 253 | ** Defer sourcing vdbe.h and btree.h until after the "u8" and ** "BusyHandler typedefs. */ #include "vdbe.h" #include "btree.h" #include "pager.h" | < < < < < < | 247 248 249 250 251 252 253 254 255 256 257 258 259 260 | ** Defer sourcing vdbe.h and btree.h until after the "u8" and ** "BusyHandler typedefs. */ #include "vdbe.h" #include "btree.h" #include "pager.h" #ifdef SQLITE_MEMDEBUG /* ** The following global variables are used for testing and debugging ** only. They only work if SQLITE_MEMDEBUG is defined. */ extern int sqlite3_nMalloc; /* Number of sqliteMalloc() calls */ extern int sqlite3_nFree; /* Number of sqliteFree() calls */ |
︙ | ︙ |
Changes to src/test1.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the printf() interface to SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the printf() interface to SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** ** $Id: test1.c,v 1.207 2006/02/16 18:16:37 drh Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include "os.h" #include <stdlib.h> #include <string.h> |
︙ | ︙ | |||
1525 1526 1527 1528 1529 1530 1531 | if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; return TCL_OK; bad_args: Tcl_WrongNumArgs(interp, 1, objv, "DB"); return TCL_ERROR; } | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 | if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; return TCL_OK; bad_args: Tcl_WrongNumArgs(interp, 1, objv, "DB"); return TCL_ERROR; } /* ** tclcmd: add_alignment_test_collations DB ** ** Add two new collating sequences to the database DB ** ** utf16_aligned ** utf16_unaligned ** ** Both collating sequences use the same sort order as BINARY. ** The only difference is that the utf16_aligned collating ** sequence is declared with the SQLITE_UTF16_ALIGNED flag. ** Both collating functions increment the unaligned utf16 counter ** whenever they see a string that begins on an odd byte boundary. */ static int unaligned_string_counter = 0; static int alignmentCollFunc( void *NotUsed, int nKey1, const void *pKey1, int nKey2, const void *pKey2 ){ int rc, n; n = nKey1<nKey2 ? nKey1 : nKey2; if( nKey1>0 && 1==(1&(int)pKey1) ) unaligned_string_counter++; if( nKey2>0 && 1==(1&(int)pKey2) ) unaligned_string_counter++; rc = memcmp(pKey1, pKey2, n); if( rc==0 ){ rc = nKey1 - nKey2; } return rc; } static int add_alignment_test_collations( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ sqlite3 *db; if( objc>=2 ){ if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; sqlite3_create_collation(db, "utf16_unaligned", SQLITE_UTF16, 0, alignmentCollFunc); sqlite3_create_collation(db, "utf16_aligned", SQLITE_UTF16 | SQLITE_UTF16_ALIGNED, 0, alignmentCollFunc); } return SQLITE_OK; } #endif /* !defined(SQLITE_OMIT_UTF16) */ /* ** Usage: add_test_function <db ptr> <utf8> <utf16le> <utf16be> ** ** This function is used to test that SQLite selects the correct user ** function callback when multiple versions (for different text encodings) ** are available. |
︙ | ︙ | |||
3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 | #endif #ifndef SQLITE_OMIT_UTF16 { "sqlite3_column_bytes16", test_stmt_int, sqlite3_column_bytes16 }, { "sqlite3_column_text16", test_stmt_utf16, sqlite3_column_text16 }, { "sqlite3_column_decltype16", test_stmt_utf16, sqlite3_column_decltype16}, { "sqlite3_column_name16", test_stmt_utf16, sqlite3_column_name16 }, #ifdef SQLITE_ENABLE_COLUMN_METADATA {"sqlite3_column_database_name16", test_stmt_utf16, sqlite3_column_database_name16}, {"sqlite3_column_table_name16", test_stmt_utf16, sqlite3_column_table_name16}, {"sqlite3_column_origin_name16", test_stmt_utf16, sqlite3_column_origin_name16}, #endif #endif | > | 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 | #endif #ifndef SQLITE_OMIT_UTF16 { "sqlite3_column_bytes16", test_stmt_int, sqlite3_column_bytes16 }, { "sqlite3_column_text16", test_stmt_utf16, sqlite3_column_text16 }, { "sqlite3_column_decltype16", test_stmt_utf16, sqlite3_column_decltype16}, { "sqlite3_column_name16", test_stmt_utf16, sqlite3_column_name16 }, { "add_alignment_test_collations", add_alignment_test_collations, 0 }, #ifdef SQLITE_ENABLE_COLUMN_METADATA {"sqlite3_column_database_name16", test_stmt_utf16, sqlite3_column_database_name16}, {"sqlite3_column_table_name16", test_stmt_utf16, sqlite3_column_table_name16}, {"sqlite3_column_origin_name16", test_stmt_utf16, sqlite3_column_origin_name16}, #endif #endif |
︙ | ︙ | |||
3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 | (char*)&sqlite3_open_file_count, TCL_LINK_INT); Tcl_LinkVar(interp, "sqlite_current_time", (char*)&sqlite3_current_time, TCL_LINK_INT); Tcl_LinkVar(interp, "sqlite_os_trace", (char*)&sqlite3_os_trace, TCL_LINK_INT); Tcl_LinkVar(interp, "sqlite3_tsd_count", (char*)&sqlite3_tsd_count, TCL_LINK_INT); #if OS_UNIX && defined(SQLITE_TEST) && defined(THREADSAFE) && THREADSAFE Tcl_LinkVar(interp, "threadsOverrideEachOthersLocks", (char*)&threadsOverrideEachOthersLocks, TCL_LINK_INT); #endif #ifndef SQLITE_OMIT_UTF16 Tcl_LinkVar(interp, "sqlite_last_needed_collation", (char*)&pzNeededCollation, TCL_LINK_STRING|TCL_LINK_READ_ONLY); | > > | 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 | (char*)&sqlite3_open_file_count, TCL_LINK_INT); Tcl_LinkVar(interp, "sqlite_current_time", (char*)&sqlite3_current_time, TCL_LINK_INT); Tcl_LinkVar(interp, "sqlite_os_trace", (char*)&sqlite3_os_trace, TCL_LINK_INT); Tcl_LinkVar(interp, "sqlite3_tsd_count", (char*)&sqlite3_tsd_count, TCL_LINK_INT); Tcl_LinkVar(interp, "unaligned_string_counter", (char*)&unaligned_string_counter, TCL_LINK_INT); #if OS_UNIX && defined(SQLITE_TEST) && defined(THREADSAFE) && THREADSAFE Tcl_LinkVar(interp, "threadsOverrideEachOthersLocks", (char*)&threadsOverrideEachOthersLocks, TCL_LINK_INT); #endif #ifndef SQLITE_OMIT_UTF16 Tcl_LinkVar(interp, "sqlite_last_needed_collation", (char*)&pzNeededCollation, TCL_LINK_STRING|TCL_LINK_READ_ONLY); |
︙ | ︙ |
Changes to src/vdbemem.c.
︙ | ︙ | |||
37 38 39 40 41 42 43 44 45 46 47 48 49 50 | int rc; if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){ return SQLITE_OK; } #ifdef SQLITE_OMIT_UTF16 return SQLITE_ERROR; #else /* MemTranslate() may return SQLITE_OK or SQLITE_NOMEM. If NOMEM is returned, ** then the encoding of the value may not have changed. */ rc = sqlite3VdbeMemTranslate(pMem, desiredEnc); assert(rc==SQLITE_OK || rc==SQLITE_NOMEM); assert(rc==SQLITE_OK || pMem->enc!=desiredEnc); | > | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | int rc; if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){ return SQLITE_OK; } #ifdef SQLITE_OMIT_UTF16 return SQLITE_ERROR; #else /* MemTranslate() may return SQLITE_OK or SQLITE_NOMEM. If NOMEM is returned, ** then the encoding of the value may not have changed. */ rc = sqlite3VdbeMemTranslate(pMem, desiredEnc); assert(rc==SQLITE_OK || rc==SQLITE_NOMEM); assert(rc==SQLITE_OK || pMem->enc!=desiredEnc); |
︙ | ︙ | |||
592 593 594 595 596 597 598 599 600 601 | ** the user deletes the collation sequence after the vdbe program is ** compiled (this was not always the case). */ assert( !pColl || pColl->xCmp ); if( pColl ){ if( pMem1->enc==pColl->enc ){ return pColl->xCmp(pColl->pUser,pMem1->n,pMem1->z,pMem2->n,pMem2->z); }else{ u8 origEnc = pMem1->enc; | > > | | | > | > | | < > | > > > < | 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 | ** the user deletes the collation sequence after the vdbe program is ** compiled (this was not always the case). */ assert( !pColl || pColl->xCmp ); if( pColl ){ if( pMem1->enc==pColl->enc ){ /* The strings are already in the correct encoding. Call the ** comparison function directly */ return pColl->xCmp(pColl->pUser,pMem1->n,pMem1->z,pMem2->n,pMem2->z); }else{ u8 origEnc = pMem1->enc; const void *v1, *v2; int n1, n2; /* Convert the strings into the encoding that the comparison ** function expects */ v1 = sqlite3ValueText((sqlite3_value*)pMem1, pColl->enc); n1 = v1==0 ? 0 : pMem1->n; assert( n1==sqlite3ValueBytes((sqlite3_value*)pMem1, pColl->enc) ); v2 = sqlite3ValueText((sqlite3_value*)pMem2, pColl->enc); n2 = v2==0 ? 0 : pMem2->n; assert( n2==sqlite3ValueBytes((sqlite3_value*)pMem2, pColl->enc) ); /* Do the comparison */ rc = pColl->xCmp(pColl->pUser, n1, v1, n2, v2); /* Convert the strings back into the database encoding */ sqlite3ValueText((sqlite3_value*)pMem1, origEnc); sqlite3ValueText((sqlite3_value*)pMem2, origEnc); return rc; } } /* If a NULL pointer was passed as the collate function, fall through ** to the blob case and use memcmp(). */ } |
︙ | ︙ | |||
748 749 750 751 752 753 754 755 756 757 | #endif /* This function is only available internally, it is not part of the ** external API. It works in a similar way to sqlite3_value_text(), ** except the data returned is in the encoding specified by the second ** parameter, which must be one of SQLITE_UTF16BE, SQLITE_UTF16LE or ** SQLITE_UTF8. */ const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){ if( !pVal ) return 0; | > > > > | | > > > > > > > | > > > | > | 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 | #endif /* This function is only available internally, it is not part of the ** external API. It works in a similar way to sqlite3_value_text(), ** except the data returned is in the encoding specified by the second ** parameter, which must be one of SQLITE_UTF16BE, SQLITE_UTF16LE or ** SQLITE_UTF8. ** ** (2006-02-16:) The enc value can be or-ed with SQLITE_UTF16_ALIGNED. ** If that is the case, then the result must be aligned on an even byte ** boundary. */ const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){ if( !pVal ) return 0; assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) ); if( pVal->flags&MEM_Null ){ return 0; } assert( (MEM_Blob>>3) == MEM_Str ); pVal->flags |= (pVal->flags & MEM_Blob)>>3; if( pVal->flags&MEM_Str ){ sqlite3VdbeChangeEncoding(pVal, enc & ~SQLITE_UTF16_ALIGNED); if( (enc & SQLITE_UTF16_ALIGNED)!=0 && 1==(1&(int)pVal->z) ){ assert( (pVal->flags & (MEM_Ephem|MEM_Static))!=0 ); if( sqlite3VdbeMemMakeWriteable(pVal)!=SQLITE_OK ){ return 0; } } }else if( !(pVal->flags&MEM_Blob) ){ sqlite3VdbeMemStringify(pVal, enc); assert( 0==(1&(int)pVal->z) ); } assert(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) || sqlite3MallocFailed() ); if( pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) ){ return pVal->z; }else{ return 0; } } /* ** Create a new sqlite3_value object. */ sqlite3_value* sqlite3ValueNew(void){ Mem *p = sqliteMalloc(sizeof(*p)); |
︙ | ︙ |
Added test/utf16align.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | # 2006 February 16 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # # This file contains code to verify that the SQLITE_UTF16_ALIGNED # flag passed into the sqlite3_create_collation() function insures # that all strings passed to that function are aligned on an even # byte boundary. # # $Id: utf16align.test,v 1.1 2006/02/16 18:16:38 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Skip this entire test if we do not support UTF16 # ifcapable !utf16 { finish_test return } # Create a database with a UTF16 encoding. Put in lots of string # data of varying lengths. # do_test utf16align-1.0 { set unaligned_string_counter 0 add_alignment_test_collations [sqlite3_connection_pointer db] execsql { PRAGMA encoding=UTF16; CREATE TABLE t1( id INTEGER PRIMARY KEY, spacer TEXT, a TEXT COLLATE utf16_aligned, b TEXT COLLATE utf16_unaligned ); INSERT INTO t1(a) VALUES("abc"); INSERT INTO t1(a) VALUES("defghi"); INSERT INTO t1(a) VALUES("jklmnopqrstuv"); INSERT INTO t1(a) VALUES("wxyz0123456789-"); UPDATE t1 SET b=a||'-'||a; INSERT INTO t1(a,b) SELECT a||b, b||a FROM t1; INSERT INTO t1(a,b) SELECT a||b, b||a FROM t1; INSERT INTO t1(a,b) SELECT a||b, b||a FROM t1; INSERT INTO t1(a,b) VALUES('one','two'); INSERT INTO t1(a,b) SELECT a, b FROM t1; UPDATE t1 SET spacer = CASE WHEN rowid&1 THEN 'x' ELSE 'xx' END; SELECT count(*) FROM t1; } } 66 do_test utf16align-1.1 { set unaligned_string_counter } 0 # Creating an index that uses the unaligned collation. We should see # some unaligned strings passed to the collating function. # do_test utf16align-1.2 { execsql { CREATE INDEX t1i1 ON t1(spacer, b); } # puts $unaligned_string_counter expr {$unaligned_string_counter>0} } 1 # Create another index that uses the aligned collation. This time # there should be no unaligned accesses # do_test utf16align-1.3 { set unaligned_string_counter 0 execsql { CREATE INDEX t1i2 ON t1(spacer, a); } expr {$unaligned_string_counter>0} } 0 integrity_check utf16align-1.4 finish_test |