Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add an xMkKey callback to the built-in collation sequence "nocase". Fix a bug in encoding text values with collation sequences into database keys. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
6c9adc9acc1d16456dc53e85296753b4 |
User & Date: | dan 2012-04-23 14:11:49.981 |
Context
2012-04-23
| ||
14:26 | Remove the VDBE merge sorter. check-in: 1073bb477e user: drh tags: trunk | |
14:11 | Add an xMkKey callback to the built-in collation sequence "nocase". Fix a bug in encoding text values with collation sequences into database keys. check-in: 6c9adc9acc user: dan tags: trunk | |
12:47 | Remove the sqlite4_get_table() API. check-in: ff68adaca1 user: drh tags: trunk | |
Changes
Changes to src/main.c.
︙ | ︙ | |||
586 587 588 589 590 591 592 | ** ** This collating sequence is intended to be used for "case independant ** comparison". SQLite's knowledge of upper and lower case equivalents ** extends only to the 26 characters used in the English language. ** ** At the moment there is only a UTF-8 implementation. */ | | > > > > > > > > > > > > > > > > | 586 587 588 589 590 591 592 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 626 627 628 | ** ** This collating sequence is intended to be used for "case independant ** comparison". SQLite's knowledge of upper and lower case equivalents ** extends only to the 26 characters used in the English language. ** ** At the moment there is only a UTF-8 implementation. */ static int collNocaseCmp( void *NotUsed, int nKey1, const void *pKey1, int nKey2, const void *pKey2 ){ int r = sqlite4StrNICmp( (const char *)pKey1, (const char *)pKey2, (nKey1<nKey2)?nKey1:nKey2); UNUSED_PARAMETER(NotUsed); if( 0==r ){ r = nKey1-nKey2; } return r; } static int collNocaseMkKey( void *NotUsed, int nIn, const void *pKey1, int nOut, void *pKey2 ){ if( nOut<nIn ){ int i; u8 *aIn = (u8 *)pKey1; u8 *aOut = (u8 *)pKey2; for(i=0; i<nIn; i++){ aOut[i] = sqlite4UpperToLower[aIn[i]]; } } return nIn; } /* ** Return the ROWID of the most recent insert */ sqlite_int64 sqlite4_last_insert_rowid(sqlite4 *db){ return db->lastRowid; } |
︙ | ︙ | |||
1436 1437 1438 1439 1440 1441 1442 | */ static int createCollation( sqlite4* db, const char *zName, u8 enc, void* pCtx, int(*xCompare)(void*,int,const void*,int,const void*), | | | 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 | */ static int createCollation( sqlite4* db, const char *zName, u8 enc, void* pCtx, int(*xCompare)(void*,int,const void*,int,const void*), int(*xMakeKey)(void*,int,const void*,int,void*), void(*xDel)(void*) ){ CollSeq *pColl; int enc2; int nName = sqlite4Strlen30(zName); assert( sqlite4_mutex_held(db->mutex) ); |
︙ | ︙ | |||
1946 1947 1948 1949 1950 1951 1952 | if( db->mallocFailed ){ goto opendb_out; } db->pDfltColl = sqlite4FindCollSeq(db, SQLITE_UTF8, "BINARY", 0); assert( db->pDfltColl!=0 ); /* Also add a UTF-8 case-insensitive collation sequence. */ | | > > | 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 | if( db->mallocFailed ){ goto opendb_out; } db->pDfltColl = sqlite4FindCollSeq(db, SQLITE_UTF8, "BINARY", 0); assert( db->pDfltColl!=0 ); /* Also add a UTF-8 case-insensitive collation sequence. */ createCollation(db, "NOCASE", SQLITE_UTF8, 0, collNocaseCmp, collNocaseMkKey, 0 ); /* Parse the filename/URI argument. */ db->openFlags = flags; rc = sqlite4ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg); if( rc!=SQLITE_OK ){ if( rc==SQLITE_NOMEM ) db->mallocFailed = 1; sqlite4Error(db, rc, zErrMsg ? "%s" : 0, zErrMsg); |
︙ | ︙ | |||
2124 2125 2126 2127 2128 2129 2130 | */ int sqlite4_create_collation( sqlite4* db, const char *zName, int enc, void* pCtx, int(*xCompare)(void*,int,const void*,int,const void*), | | | 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 | */ int sqlite4_create_collation( sqlite4* db, const char *zName, int enc, void* pCtx, int(*xCompare)(void*,int,const void*,int,const void*), int(*xMakeKey)(void*,int,const void*,int,void*), void(*xDel)(void*) ){ int rc; sqlite4_mutex_enter(db->mutex); assert( !db->mallocFailed ); rc = createCollation(db, zName, (u8)enc, pCtx, xCompare, xMakeKey, xDel); rc = sqlite4ApiExit(db, rc); |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
3897 3898 3899 3900 3901 3902 3903 | */ int sqlite4_create_collation( sqlite4*, const char *zName, int eTextRep, void *pArg, int(*xCompare)(void*,int,const void*,int,const void*), | | | 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 | */ int sqlite4_create_collation( sqlite4*, const char *zName, int eTextRep, void *pArg, int(*xCompare)(void*,int,const void*,int,const void*), int(*xMakeKey)(void*,int,const void*,int,void*), void(*xDestroy)(void*) ); /* ** CAPI3REF: Collation Needed Callbacks ** ** ^To avoid having to register all collation sequences before a database |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
1136 1137 1138 1139 1140 1141 1142 | ** collating sequence may not be read or written. */ struct CollSeq { char *zName; /* Name of the collating sequence, UTF-8 encoded */ u8 enc; /* Text encoding handled by xCmp() */ void *pUser; /* First argument to xCmp() */ int (*xCmp)(void*,int, const void*, int, const void*); | | | 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 | ** collating sequence may not be read or written. */ struct CollSeq { char *zName; /* Name of the collating sequence, UTF-8 encoded */ u8 enc; /* Text encoding handled by xCmp() */ void *pUser; /* First argument to xCmp() */ int (*xCmp)(void*,int, const void*, int, const void*); int (*xMkKey)(void*,int, const void*, int, void*); void (*xDel)(void*); /* Destructor for pUser */ }; /* ** A sort order can be either ASC or DESC. */ #define SQLITE_SO_ASC 0 /* Sort in ascending order */ |
︙ | ︙ |
Changes to src/vdbecodec.c.
︙ | ︙ | |||
566 567 568 569 570 571 572 | if( flags & MEM_Str ){ if( enlargeEncoderAllocation(p, pMem->n*4 + 2) ) return SQLITE_NOMEM; p->aOut[p->nOut++] = 0x24; /* Text */ if( pColl==0 || pColl->xMkKey==0 ){ memcpy(p->aOut+p->nOut, pMem->z, pMem->n); p->nOut += pMem->n; }else{ | > | < | | < > | 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 | if( flags & MEM_Str ){ if( enlargeEncoderAllocation(p, pMem->n*4 + 2) ) return SQLITE_NOMEM; p->aOut[p->nOut++] = 0x24; /* Text */ if( pColl==0 || pColl->xMkKey==0 ){ memcpy(p->aOut+p->nOut, pMem->z, pMem->n); p->nOut += pMem->n; }else{ int nSpc = p->nAlloc-p->nOut; n = pColl->xMkKey(pColl->pUser, pMem->n, pMem->z, nSpc, p->aOut+p->nOut); if( n>nSpc ){ if( enlargeEncoderAllocation(p, n) ) return SQLITE_NOMEM; pColl->xMkKey(pColl->pUser, pMem->n, pMem->z, n, p->aOut+p->nOut); } p->nOut += n; } p->aOut[p->nOut++] = 0x00; }else { const unsigned char *a; unsigned char s, t; assert( flags & MEM_Blob ); |
︙ | ︙ |
Changes to test/simple.test.
︙ | ︙ | |||
887 888 889 890 891 892 893 894 895 896 | do_execsql_test 46.1 { CREATE TABLE t1(x); CREATE UNIQUE INDEX i1 ON t1(x); } do_execsql_test 46.2 { INSERT INTO t1 VALUES(NULL) } do_execsql_test 46.3 { INSERT INTO t1 VALUES(NULL) } finish_test | > > > > > > > > > > > > > | 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 | do_execsql_test 46.1 { CREATE TABLE t1(x); CREATE UNIQUE INDEX i1 ON t1(x); } do_execsql_test 46.2 { INSERT INTO t1 VALUES(NULL) } do_execsql_test 46.3 { INSERT INTO t1 VALUES(NULL) } #------------------------------------------------------------------------- reset_db do_execsql_test 46.1 { CREATE TABLE t1(x, y COLLATE nocase); CREATE UNIQUE INDEX i1 ON t1(y); } do_catchsql_test 46.2 { INSERT INTO t1 VALUES(1, 'ABC'); INSERT INTO t1 VALUES(2, 'abc'); } {1 {column y is not unique}} finish_test |