Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch collseq-checking Excluding Merge-Ins
This is equivalent to a diff from 71f589e3f8 to 68b23c3d41
2014-12-05
| ||
14:44 | When closing a (shared-cache) database connection, be sure to clear out all KeyInfo objects cached on Index objects. Fix for ticket [e4a18565a36884b00edf]. (check-in: adca7688de user: drh tags: trunk) | |
14:36 | Add code to check the validity of CollSeq objects during runtime. This code was not able to detect anomalies such as came up as a result of ticket [e4a18565a36884b00edf66541f38c693827968ab] so it is put into a branch for historical reference, with the intent of leaving it out of trunk. (Closed-Leaf check-in: 68b23c3d41 user: drh tags: collseq-checking) | |
14:34 | Improved comment on the sharedB.test test script. (Closed-Leaf check-in: 71f589e3f8 user: drh tags: fix-stale-keyinfo-cache) | |
14:07 | Test case demonstrating the problem described by ticket [e4a18565a36884b00edf]. (check-in: ffea3e905a user: drh tags: fix-stale-keyinfo-cache) | |
Changes to src/callback.c.
︙ | ︙ | |||
98 99 100 101 102 103 104 | */ callCollNeeded(db, enc, zName); p = sqlite3FindCollSeq(db, enc, zName, 0); } if( p && !p->xCmp && synthCollSeq(db, p) ){ p = 0; } | | | 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | */ callCollNeeded(db, enc, zName); p = sqlite3FindCollSeq(db, enc, zName, 0); } if( p && !p->xCmp && synthCollSeq(db, p) ){ p = 0; } assert( p==0 || (sqlite3ValidCollSeq(p) && p->xCmp!=0) ); if( p==0 ){ sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName); } return p; } /* |
︙ | ︙ | |||
182 183 184 185 186 187 188 189 190 191 192 193 194 195 | pColl = 0; } } } return pColl; } /* ** Parameter zName points to a UTF-8 encoded string nName bytes long. ** Return the CollSeq* pointer for the collation sequence named zName ** for the encoding 'enc' from the database 'db'. ** ** If the entry specified is not found and 'create' is true, then create a ** new entry. Otherwise return NULL. | > > > > > > > > > > > > > > > > > > > > > > > > > | 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 | pColl = 0; } } } return pColl; } #ifdef SQLITE_DEBUG /* ** The following routine does sanity checking on a CollSeq object and ** returns 1 if everything looks ok and 0 if the CollSeq object appears ** to be corrupt. This routine is used only inside of assert() statements. */ int sqlite3ValidCollSeq(const CollSeq *p){ /* The CollSeq must be one of a triple and the zName field must ** point to the first byte after that triple */ int n = (int)(p->zName - (char*)p)/sizeof(CollSeq); if( n<=0 || n>3 ) return 0; /* Check for valid enc values */ if( p->enc==SQLITE_UTF8 ) return 1; if( p->enc==SQLITE_UTF16LE ) return 1; if( p->enc==SQLITE_UTF16BE ) return 1; if( p->enc==(SQLITE_UTF16LE|SQLITE_UTF16_ALIGNED) ) return 1; if( p->enc==(SQLITE_UTF16BE|SQLITE_UTF16_ALIGNED) ) return 1; /* Otherwise, malformed */ return 0; } #endif /* SQLITE_DEBUG */ /* ** Parameter zName points to a UTF-8 encoded string nName bytes long. ** Return the CollSeq* pointer for the collation sequence named zName ** for the encoding 'enc' from the database 'db'. ** ** If the entry specified is not found and 'create' is true, then create a ** new entry. Otherwise return NULL. |
︙ | ︙ | |||
211 212 213 214 215 216 217 | if( zName ){ pColl = findCollSeqEntry(db, zName, create); }else{ pColl = db->pDfltColl; } assert( SQLITE_UTF8==1 && SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 ); assert( enc>=SQLITE_UTF8 && enc<=SQLITE_UTF16BE ); | | > > > | 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 | if( zName ){ pColl = findCollSeqEntry(db, zName, create); }else{ pColl = db->pDfltColl; } assert( SQLITE_UTF8==1 && SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 ); assert( enc>=SQLITE_UTF8 && enc<=SQLITE_UTF16BE ); if( pColl ){ pColl += enc-1; assert( sqlite3ValidCollSeq(pColl) ); } return pColl; } /* During the search for the best function definition, this procedure ** is called to test how well the function passed as the first argument ** matches the request for a function with nArg arguments in a system ** that uses encoding enc. The value returned indicates how well the |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 | #if defined(SQLITE_TEST) const char *sqlite3ErrName(int); #endif const char *sqlite3ErrStr(int); int sqlite3ReadSchema(Parse *pParse); CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int); CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName); CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr); Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*); Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*); Expr *sqlite3ExprSkipCollate(Expr*); int sqlite3CheckCollSeq(Parse *, CollSeq *); | > > > | 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 | #if defined(SQLITE_TEST) const char *sqlite3ErrName(int); #endif const char *sqlite3ErrStr(int); int sqlite3ReadSchema(Parse *pParse); #if defined(SQLITE_DEBUG) int sqlite3ValidCollSeq(const CollSeq*); #endif CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int); CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName); CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr); Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*); Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*); Expr *sqlite3ExprSkipCollate(Expr*); int sqlite3CheckCollSeq(Parse *, CollSeq *); |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 | assert( pKeyInfo->aSortOrder!=0 ); sqlite3_snprintf(nTemp, zTemp, "k(%d", pKeyInfo->nField); i = sqlite3Strlen30(zTemp); for(j=0; j<pKeyInfo->nField; j++){ CollSeq *pColl = pKeyInfo->aColl[j]; const char *zColl = pColl ? pColl->zName : "nil"; int n = sqlite3Strlen30(zColl); if( n==6 && memcmp(zColl,"BINARY",6)==0 ){ zColl = "B"; n = 1; } if( i+n>nTemp-6 ){ memcpy(&zTemp[i],",...",4); break; | > | 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 | assert( pKeyInfo->aSortOrder!=0 ); sqlite3_snprintf(nTemp, zTemp, "k(%d", pKeyInfo->nField); i = sqlite3Strlen30(zTemp); for(j=0; j<pKeyInfo->nField; j++){ CollSeq *pColl = pKeyInfo->aColl[j]; const char *zColl = pColl ? pColl->zName : "nil"; int n = sqlite3Strlen30(zColl); assert( pColl==0 || sqlite3ValidCollSeq(pColl) ); if( n==6 && memcmp(zColl,"BINARY",6)==0 ){ zColl = "B"; n = 1; } if( i+n>nTemp-6 ){ memcpy(&zTemp[i],",...",4); break; |
︙ | ︙ | |||
3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 | */ static int vdbeCompareMemString( const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl, u8 *prcErr /* If an OOM occurs, set to SQLITE_NOMEM */ ){ 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{ int rc; const void *v1, *v2; | > | 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 | */ static int vdbeCompareMemString( const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl, u8 *prcErr /* If an OOM occurs, set to SQLITE_NOMEM */ ){ assert( sqlite3ValidCollSeq(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{ int rc; const void *v1, *v2; |
︙ | ︙ | |||
3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 | /* The collation sequence must be defined at this point, even if ** the user deletes the collation sequence after the vdbe program is ** compiled (this was not always the case). */ assert( !pColl || pColl->xCmp ); if( pColl ){ return vdbeCompareMemString(pMem1, pMem2, pColl, 0); } /* If a NULL pointer was passed as the collate function, fall through ** to the blob case and use memcmp(). */ } /* Both values must be blobs. Compare using memcmp(). */ | > | 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 | /* The collation sequence must be defined at this point, even if ** the user deletes the collation sequence after the vdbe program is ** compiled (this was not always the case). */ assert( !pColl || pColl->xCmp ); if( pColl ){ assert( sqlite3ValidCollSeq(pColl) ); return vdbeCompareMemString(pMem1, pMem2, pColl, 0); } /* If a NULL pointer was passed as the collate function, fall through ** to the blob case and use memcmp(). */ } /* Both values must be blobs. Compare using memcmp(). */ |
︙ | ︙ |