mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-16 23:02:26 +03:00
Merge the latest enhancements from trunk.
FossilOrigin-Name: c0be246a740c8f33a7c07e1414688364dee56ece
This commit is contained in:
35
src/btree.c
35
src/btree.c
@@ -1051,8 +1051,7 @@ static SQLITE_NOINLINE void btreeParseCellAdjustSizeForOverflow(
|
||||
}else{
|
||||
pInfo->nLocal = (u16)minLocal;
|
||||
}
|
||||
pInfo->iOverflow = (u16)(&pInfo->pPayload[pInfo->nLocal] - pCell);
|
||||
pInfo->nSize = pInfo->iOverflow + 4;
|
||||
pInfo->nSize = (u16)(&pInfo->pPayload[pInfo->nLocal] - pCell) + 4;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1084,7 +1083,6 @@ static void btreeParseCellPtrNoPayload(
|
||||
pInfo->nSize = 4 + getVarint(&pCell[4], (u64*)&pInfo->nKey);
|
||||
pInfo->nPayload = 0;
|
||||
pInfo->nLocal = 0;
|
||||
pInfo->iOverflow = 0;
|
||||
pInfo->pPayload = 0;
|
||||
return;
|
||||
}
|
||||
@@ -1154,7 +1152,6 @@ static void btreeParseCellPtr(
|
||||
pInfo->nSize = nPayload + (u16)(pIter - pCell);
|
||||
if( pInfo->nSize<4 ) pInfo->nSize = 4;
|
||||
pInfo->nLocal = (u16)nPayload;
|
||||
pInfo->iOverflow = 0;
|
||||
}else{
|
||||
btreeParseCellAdjustSizeForOverflow(pPage, pCell, pInfo);
|
||||
}
|
||||
@@ -1193,7 +1190,6 @@ static void btreeParseCellPtrIndex(
|
||||
pInfo->nSize = nPayload + (u16)(pIter - pCell);
|
||||
if( pInfo->nSize<4 ) pInfo->nSize = 4;
|
||||
pInfo->nLocal = (u16)nPayload;
|
||||
pInfo->iOverflow = 0;
|
||||
}else{
|
||||
btreeParseCellAdjustSizeForOverflow(pPage, pCell, pInfo);
|
||||
}
|
||||
@@ -1309,8 +1305,8 @@ static void ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell, int *pRC){
|
||||
if( *pRC ) return;
|
||||
assert( pCell!=0 );
|
||||
pPage->xParseCell(pPage, pCell, &info);
|
||||
if( info.iOverflow ){
|
||||
Pgno ovfl = get4byte(&pCell[info.iOverflow]);
|
||||
if( info.nLocal<info.nPayload ){
|
||||
Pgno ovfl = get4byte(&pCell[info.nSize-4]);
|
||||
ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, pRC);
|
||||
}
|
||||
}
|
||||
@@ -3348,11 +3344,11 @@ static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){
|
||||
if( eType==PTRMAP_OVERFLOW1 ){
|
||||
CellInfo info;
|
||||
pPage->xParseCell(pPage, pCell, &info);
|
||||
if( info.iOverflow
|
||||
&& pCell+info.iOverflow+3<=pPage->aData+pPage->maskPage
|
||||
&& iFrom==get4byte(&pCell[info.iOverflow])
|
||||
if( info.nLocal<info.nPayload
|
||||
&& pCell+info.nSize-1<=pPage->aData+pPage->maskPage
|
||||
&& iFrom==get4byte(pCell+info.nSize-4)
|
||||
){
|
||||
put4byte(&pCell[info.iOverflow], iTo);
|
||||
put4byte(pCell+info.nSize-4, iTo);
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
@@ -5994,13 +5990,13 @@ static int clearCell(
|
||||
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
|
||||
pPage->xParseCell(pPage, pCell, &info);
|
||||
*pnSize = info.nSize;
|
||||
if( info.iOverflow==0 ){
|
||||
if( info.nLocal==info.nPayload ){
|
||||
return SQLITE_OK; /* No overflow pages. Return without doing anything */
|
||||
}
|
||||
if( pCell+info.iOverflow+3 > pPage->aData+pPage->maskPage ){
|
||||
if( pCell+info.nSize-1 > pPage->aData+pPage->maskPage ){
|
||||
return SQLITE_CORRUPT_BKPT; /* Cell extends past end of page */
|
||||
}
|
||||
ovflPgno = get4byte(&pCell[info.iOverflow]);
|
||||
ovflPgno = get4byte(pCell + info.nSize - 4);
|
||||
assert( pBt->usableSize > 4 );
|
||||
ovflPageSize = pBt->usableSize - 4;
|
||||
nOvfl = (info.nPayload - info.nLocal + ovflPageSize - 1)/ovflPageSize;
|
||||
@@ -6149,7 +6145,6 @@ static int fillInCell(
|
||||
assert( info.nKey==nKey );
|
||||
assert( *pnSize == info.nSize );
|
||||
assert( spaceLeft == info.nLocal );
|
||||
assert( pPrior == &pCell[info.iOverflow] );
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -6859,8 +6854,8 @@ static int ptrmapCheckPages(MemPage **apPage, int nPage){
|
||||
|
||||
z = findCell(pPage, j);
|
||||
pPage->xParseCell(pPage, z, &info);
|
||||
if( info.iOverflow ){
|
||||
Pgno ovfl = get4byte(&z[info.iOverflow]);
|
||||
if( info.nLocal<info.nPayload ){
|
||||
Pgno ovfl = get4byte(&z[info.nSize-4]);
|
||||
ptrmapGet(pBt, ovfl, &e, &n);
|
||||
assert( n==pPage->pgno && e==PTRMAP_OVERFLOW1 );
|
||||
}
|
||||
@@ -8226,7 +8221,7 @@ int sqlite3BtreeDelete(BtCursor *pCur, int bPreserve){
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
if( bSkipnext ){
|
||||
assert( bPreserve && pCur->iPage==iCellDepth );
|
||||
assert( bPreserve && (pCur->iPage==iCellDepth || CORRUPT_DB) );
|
||||
assert( pPage==pCur->apPage[pCur->iPage] );
|
||||
assert( (pPage->nCell>0 || CORRUPT_DB) && iCellIdx<=pPage->nCell );
|
||||
pCur->eState = CURSOR_SKIPNEXT;
|
||||
@@ -9166,9 +9161,9 @@ static int checkTreePage(
|
||||
if( info.nPayload>info.nLocal ){
|
||||
int nPage; /* Number of pages on the overflow chain */
|
||||
Pgno pgnoOvfl; /* First page of the overflow chain */
|
||||
assert( pc + info.iOverflow <= usableSize );
|
||||
assert( pc + info.nSize - 4 <= usableSize );
|
||||
nPage = (info.nPayload - info.nLocal + usableSize - 5)/(usableSize - 4);
|
||||
pgnoOvfl = get4byte(&pCell[info.iOverflow]);
|
||||
pgnoOvfl = get4byte(&pCell[info.nSize - 4]);
|
||||
#ifndef SQLITE_OMIT_AUTOVACUUM
|
||||
if( pBt->autoVacuum ){
|
||||
checkPtrmap(pCheck, pgnoOvfl, PTRMAP_OVERFLOW1, iPage);
|
||||
|
||||
@@ -470,7 +470,6 @@ struct CellInfo {
|
||||
u8 *pPayload; /* Pointer to the start of payload */
|
||||
u32 nPayload; /* Bytes of payload */
|
||||
u16 nLocal; /* Amount of payload held locally, not on overflow */
|
||||
u16 iOverflow; /* Offset to overflow page number. Zero if no overflow */
|
||||
u16 nSize; /* Size of the cell content on the main b-tree page */
|
||||
};
|
||||
|
||||
|
||||
23
src/build.c
23
src/build.c
@@ -444,7 +444,7 @@ static void freeIndex(sqlite3 *db, Index *p){
|
||||
sqlite3ExprDelete(db, p->pPartIdxWhere);
|
||||
sqlite3ExprListDelete(db, p->aColExpr);
|
||||
sqlite3DbFree(db, p->zColAff);
|
||||
if( p->isResized ) sqlite3DbFree(db, p->azColl);
|
||||
if( p->isResized ) sqlite3DbFree(db, (void *)p->azColl);
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
sqlite3_free(p->aiRowEst);
|
||||
#endif
|
||||
@@ -1047,15 +1047,15 @@ begin_table_error:
|
||||
/* Set properties of a table column based on the (magical)
|
||||
** name of the column.
|
||||
*/
|
||||
void sqlite3ColumnPropertiesFromName(Table *pTab, Column *pCol){
|
||||
#if SQLITE_ENABLE_HIDDEN_COLUMNS
|
||||
void sqlite3ColumnPropertiesFromName(Table *pTab, Column *pCol){
|
||||
if( sqlite3_strnicmp(pCol->zName, "__hidden__", 10)==0 ){
|
||||
pCol->colFlags |= COLFLAG_HIDDEN;
|
||||
}else if( pTab && pCol!=pTab->aCol && (pCol[-1].colFlags & COLFLAG_HIDDEN) ){
|
||||
pTab->tabFlags |= TF_OOOHidden;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
@@ -1635,7 +1635,7 @@ static int resizeIndexObject(sqlite3 *db, Index *pIdx, int N){
|
||||
zExtra = sqlite3DbMallocZero(db, nByte);
|
||||
if( zExtra==0 ) return SQLITE_NOMEM;
|
||||
memcpy(zExtra, pIdx->azColl, sizeof(char*)*pIdx->nColumn);
|
||||
pIdx->azColl = (char**)zExtra;
|
||||
pIdx->azColl = (const char**)zExtra;
|
||||
zExtra += sizeof(char*)*N;
|
||||
memcpy(zExtra, pIdx->aiColumn, sizeof(i16)*pIdx->nColumn);
|
||||
pIdx->aiColumn = (i16*)zExtra;
|
||||
@@ -1816,7 +1816,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
|
||||
if( !hasColumn(pPk->aiColumn, j, i) ){
|
||||
assert( j<pPk->nColumn );
|
||||
pPk->aiColumn[j] = i;
|
||||
pPk->azColl[j] = "BINARY";
|
||||
pPk->azColl[j] = sqlite3StrBINARY;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
@@ -2866,7 +2866,7 @@ Index *sqlite3AllocateIndexObject(
|
||||
p = sqlite3DbMallocZero(db, nByte + nExtra);
|
||||
if( p ){
|
||||
char *pExtra = ((char*)p)+ROUND8(sizeof(Index));
|
||||
p->azColl = (char**)pExtra; pExtra += ROUND8(sizeof(char*)*nCol);
|
||||
p->azColl = (const char**)pExtra; pExtra += ROUND8(sizeof(char*)*nCol);
|
||||
p->aiRowLogEst = (LogEst*)pExtra; pExtra += sizeof(LogEst)*(nCol+1);
|
||||
p->aiColumn = (i16*)pExtra; pExtra += sizeof(i16)*nCol;
|
||||
p->aSortOrder = (u8*)pExtra;
|
||||
@@ -3143,7 +3143,7 @@ Index *sqlite3CreateIndex(
|
||||
for(i=0, pListItem=pList->a; i<pList->nExpr; i++, pListItem++){
|
||||
Expr *pCExpr; /* The i-th index expression */
|
||||
int requestedSortOrder; /* ASC or DESC on the i-th expression */
|
||||
char *zColl; /* Collation sequence name */
|
||||
const char *zColl; /* Collation sequence name */
|
||||
|
||||
sqlite3StringToId(pListItem->pExpr);
|
||||
sqlite3ResolveSelfReference(pParse, pTab, NC_IdxExpr, pListItem->pExpr, 0);
|
||||
@@ -3189,7 +3189,7 @@ Index *sqlite3CreateIndex(
|
||||
}else if( j>=0 ){
|
||||
zColl = pTab->aCol[j].zColl;
|
||||
}
|
||||
if( !zColl ) zColl = "BINARY";
|
||||
if( !zColl ) zColl = sqlite3StrBINARY;
|
||||
if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl) ){
|
||||
goto exit_create_index;
|
||||
}
|
||||
@@ -3218,7 +3218,7 @@ Index *sqlite3CreateIndex(
|
||||
assert( i==pIndex->nColumn );
|
||||
}else{
|
||||
pIndex->aiColumn[i] = XN_ROWID;
|
||||
pIndex->azColl[i] = "BINARY";
|
||||
pIndex->azColl[i] = sqlite3StrBINARY;
|
||||
}
|
||||
sqlite3DefaultRowEst(pIndex);
|
||||
if( pParse->pNewTable==0 ) estimateIndexWidth(pIndex);
|
||||
@@ -4342,9 +4342,8 @@ KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){
|
||||
if( pKey ){
|
||||
assert( sqlite3KeyInfoIsWriteable(pKey) );
|
||||
for(i=0; i<nCol; i++){
|
||||
char *zColl = pIdx->azColl[i];
|
||||
assert( zColl!=0 );
|
||||
pKey->aColl[i] = strcmp(zColl,"BINARY")==0 ? 0 :
|
||||
const char *zColl = pIdx->azColl[i];
|
||||
pKey->aColl[i] = zColl==sqlite3StrBINARY ? 0 :
|
||||
sqlite3LocateCollSeq(pParse, zColl);
|
||||
pKey->aSortOrder[i] = pIdx->aSortOrder[i];
|
||||
}
|
||||
|
||||
21
src/date.c
21
src/date.c
@@ -65,6 +65,7 @@ struct DateTime {
|
||||
char validHMS; /* True (1) if h,m,s are valid */
|
||||
char validJD; /* True (1) if iJD is valid */
|
||||
char validTZ; /* True (1) if tz is valid */
|
||||
char tzSet; /* Timezone was set explicitly */
|
||||
};
|
||||
|
||||
|
||||
@@ -158,6 +159,7 @@ static int parseTimezone(const char *zDate, DateTime *p){
|
||||
p->tz = sgn*(nMn + nHr*60);
|
||||
zulu_time:
|
||||
while( sqlite3Isspace(*zDate) ){ zDate++; }
|
||||
p->tzSet = 1;
|
||||
return *zDate!=0;
|
||||
}
|
||||
|
||||
@@ -590,13 +592,18 @@ static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){
|
||||
}
|
||||
#ifndef SQLITE_OMIT_LOCALTIME
|
||||
else if( strcmp(z, "utc")==0 ){
|
||||
sqlite3_int64 c1;
|
||||
computeJD(p);
|
||||
c1 = localtimeOffset(p, pCtx, &rc);
|
||||
if( rc==SQLITE_OK ){
|
||||
p->iJD -= c1;
|
||||
clearYMD_HMS_TZ(p);
|
||||
p->iJD += c1 - localtimeOffset(p, pCtx, &rc);
|
||||
if( p->tzSet==0 ){
|
||||
sqlite3_int64 c1;
|
||||
computeJD(p);
|
||||
c1 = localtimeOffset(p, pCtx, &rc);
|
||||
if( rc==SQLITE_OK ){
|
||||
p->iJD -= c1;
|
||||
clearYMD_HMS_TZ(p);
|
||||
p->iJD += c1 - localtimeOffset(p, pCtx, &rc);
|
||||
}
|
||||
p->tzSet = 1;
|
||||
}else{
|
||||
rc = SQLITE_OK;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
18
src/expr.c
18
src/expr.c
@@ -888,7 +888,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
|
||||
assert( ExprHasProperty(p, EP_Reduced)==0 );
|
||||
memcpy(zAlloc, p, nNewSize);
|
||||
}else{
|
||||
int nSize = exprStructSize(p);
|
||||
u32 nSize = (u32)exprStructSize(p);
|
||||
memcpy(zAlloc, p, nSize);
|
||||
if( nSize<EXPR_FULLSIZE ){
|
||||
memset(&zAlloc[nSize], 0, EXPR_FULLSIZE-nSize);
|
||||
@@ -2468,7 +2468,7 @@ void sqlite3ExprCodeLoadIndexColumn(
|
||||
assert( pIdx->aColExpr );
|
||||
assert( pIdx->aColExpr->nExpr>iIdxCol );
|
||||
pParse->iSelfTab = iTabCur;
|
||||
sqlite3ExprCode(pParse, pIdx->aColExpr->a[iIdxCol].pExpr, regOut);
|
||||
sqlite3ExprCodeCopy(pParse, pIdx->aColExpr->a[iIdxCol].pExpr, regOut);
|
||||
}else{
|
||||
sqlite3ExprCodeGetColumnOfTable(pParse->pVdbe, pIdx->pTable, iTabCur,
|
||||
iTabCol, regOut);
|
||||
@@ -3321,13 +3321,25 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){
|
||||
sqlite3VdbeAddOp2(pParse->pVdbe, OP_Copy, pExpr->iTable, target);
|
||||
}else{
|
||||
inReg = sqlite3ExprCodeTarget(pParse, pExpr, target);
|
||||
assert( pParse->pVdbe || pParse->db->mallocFailed );
|
||||
assert( pParse->pVdbe!=0 || pParse->db->mallocFailed );
|
||||
if( inReg!=target && pParse->pVdbe ){
|
||||
sqlite3VdbeAddOp2(pParse->pVdbe, OP_SCopy, inReg, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Make a transient copy of expression pExpr and then code it using
|
||||
** sqlite3ExprCode(). This routine works just like sqlite3ExprCode()
|
||||
** except that the input expression is guaranteed to be unchanged.
|
||||
*/
|
||||
void sqlite3ExprCodeCopy(Parse *pParse, Expr *pExpr, int target){
|
||||
sqlite3 *db = pParse->db;
|
||||
pExpr = sqlite3ExprDup(db, pExpr, 0);
|
||||
if( !db->mallocFailed ) sqlite3ExprCode(pParse, pExpr, target);
|
||||
sqlite3ExprDelete(db, pExpr);
|
||||
}
|
||||
|
||||
/*
|
||||
** Generate code that will evaluate expression pExpr and store the
|
||||
** results in register target. The results are guaranteed to appear
|
||||
|
||||
@@ -249,7 +249,7 @@ int sqlite3FkLocateIndex(
|
||||
int i, j;
|
||||
for(i=0; i<nCol; i++){
|
||||
i16 iCol = pIdx->aiColumn[i]; /* Index of column in parent tbl */
|
||||
char *zDfltColl; /* Def. collation for column */
|
||||
const char *zDfltColl; /* Def. collation for column */
|
||||
char *zIdxCol; /* Name of indexed column */
|
||||
|
||||
if( iCol<0 ) break; /* No foreign keys against expression indexes */
|
||||
@@ -258,9 +258,7 @@ int sqlite3FkLocateIndex(
|
||||
** the default collation sequence for the column, this index is
|
||||
** unusable. Bail out early in this case. */
|
||||
zDfltColl = pParent->aCol[iCol].zColl;
|
||||
if( !zDfltColl ){
|
||||
zDfltColl = "BINARY";
|
||||
}
|
||||
if( !zDfltColl ) zDfltColl = sqlite3StrBINARY;
|
||||
if( sqlite3StrICmp(pIdx->azColl[i], zDfltColl) ) break;
|
||||
|
||||
zIdxCol = pParent->aCol[iCol].zName;
|
||||
|
||||
@@ -747,7 +747,7 @@ static int patternCompare(
|
||||
}
|
||||
c2 = Utf8Read(zString);
|
||||
if( c==c2 ) continue;
|
||||
if( noCase && c<0x80 && c2<0x80 && sqlite3Tolower(c)==sqlite3Tolower(c2) ){
|
||||
if( noCase && sqlite3Tolower(c)==sqlite3Tolower(c2) ){
|
||||
continue;
|
||||
}
|
||||
if( c==matchOne && zPattern!=zEscaped && c2!=0 ) continue;
|
||||
|
||||
@@ -260,3 +260,8 @@ int sqlite3PendingByte = 0x40000000;
|
||||
** the vdbe.c file.
|
||||
*/
|
||||
const unsigned char sqlite3OpcodeProperty[] = OPFLG_INITIALIZER;
|
||||
|
||||
/*
|
||||
** Name of the default collating sequence
|
||||
*/
|
||||
const char sqlite3StrBINARY[] = "BINARY";
|
||||
|
||||
27
src/insert.c
27
src/insert.c
@@ -1417,7 +1417,7 @@ void sqlite3GenerateConstraintChecks(
|
||||
int x;
|
||||
if( iField==XN_EXPR ){
|
||||
pParse->ckBase = regNewData+1;
|
||||
sqlite3ExprCode(pParse, pIdx->aColExpr->a[i].pExpr, regIdx+i);
|
||||
sqlite3ExprCodeCopy(pParse, pIdx->aColExpr->a[i].pExpr, regIdx+i);
|
||||
pParse->ckBase = 0;
|
||||
VdbeComment((v, "%s column %d", pIdx->zName, i));
|
||||
}else{
|
||||
@@ -1718,20 +1718,6 @@ int sqlite3_xferopt_count;
|
||||
|
||||
|
||||
#ifndef SQLITE_OMIT_XFER_OPT
|
||||
/*
|
||||
** Check to collation names to see if they are compatible.
|
||||
*/
|
||||
static int xferCompatibleCollation(const char *z1, const char *z2){
|
||||
if( z1==0 ){
|
||||
return z2==0;
|
||||
}
|
||||
if( z2==0 ){
|
||||
return 0;
|
||||
}
|
||||
return sqlite3StrICmp(z1, z2)==0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Check to see if index pSrc is compatible as a source of data
|
||||
** for index pDest in an insert transfer optimization. The rules
|
||||
@@ -1767,7 +1753,7 @@ static int xferCompatibleIndex(Index *pDest, Index *pSrc){
|
||||
if( pSrc->aSortOrder[i]!=pDest->aSortOrder[i] ){
|
||||
return 0; /* Different sort orders */
|
||||
}
|
||||
if( !xferCompatibleCollation(pSrc->azColl[i],pDest->azColl[i]) ){
|
||||
if( sqlite3_stricmp(pSrc->azColl[i],pDest->azColl[i])!=0 ){
|
||||
return 0; /* Different collating sequences */
|
||||
}
|
||||
}
|
||||
@@ -1928,7 +1914,7 @@ static int xferOptimization(
|
||||
if( pDestCol->affinity!=pSrcCol->affinity ){
|
||||
return 0; /* Affinity must be the same on all columns */
|
||||
}
|
||||
if( !xferCompatibleCollation(pDestCol->zColl, pSrcCol->zColl) ){
|
||||
if( sqlite3_stricmp(pDestCol->zColl, pSrcCol->zColl)!=0 ){
|
||||
return 0; /* Collating sequence must be the same on all columns */
|
||||
}
|
||||
if( pDestCol->notNull && !pSrcCol->notNull ){
|
||||
@@ -2075,9 +2061,10 @@ static int xferOptimization(
|
||||
** a VACUUM command. In that case keys may not be written in strictly
|
||||
** sorted order. */
|
||||
for(i=0; i<pSrcIdx->nColumn; i++){
|
||||
char *zColl = pSrcIdx->azColl[i];
|
||||
assert( zColl!=0 );
|
||||
if( sqlite3_stricmp("BINARY", zColl) ) break;
|
||||
const char *zColl = pSrcIdx->azColl[i];
|
||||
assert( sqlite3_stricmp(sqlite3StrBINARY, zColl)!=0
|
||||
|| sqlite3StrBINARY==zColl );
|
||||
if( sqlite3_stricmp(sqlite3StrBINARY, zColl) ) break;
|
||||
}
|
||||
if( i==pSrcIdx->nColumn ){
|
||||
idxInsFlags = OPFLAG_USESEEKRESULT;
|
||||
|
||||
11
src/main.c
11
src/main.c
@@ -2850,9 +2850,9 @@ static int openDatabase(
|
||||
** EVIDENCE-OF: R-52786-44878 SQLite defines three built-in collating
|
||||
** functions:
|
||||
*/
|
||||
createCollation(db, "BINARY", SQLITE_UTF8, 0, binCollFunc, 0);
|
||||
createCollation(db, "BINARY", SQLITE_UTF16BE, 0, binCollFunc, 0);
|
||||
createCollation(db, "BINARY", SQLITE_UTF16LE, 0, binCollFunc, 0);
|
||||
createCollation(db, sqlite3StrBINARY, SQLITE_UTF8, 0, binCollFunc, 0);
|
||||
createCollation(db, sqlite3StrBINARY, SQLITE_UTF16BE, 0, binCollFunc, 0);
|
||||
createCollation(db, sqlite3StrBINARY, SQLITE_UTF16LE, 0, binCollFunc, 0);
|
||||
createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0);
|
||||
createCollation(db, "RTRIM", SQLITE_UTF8, (void*)1, binCollFunc, 0);
|
||||
if( db->mallocFailed ){
|
||||
@@ -2861,7 +2861,7 @@ static int openDatabase(
|
||||
/* EVIDENCE-OF: R-08308-17224 The default collating function for all
|
||||
** strings is BINARY.
|
||||
*/
|
||||
db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 0);
|
||||
db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, sqlite3StrBINARY, 0);
|
||||
assert( db->pDfltColl!=0 );
|
||||
|
||||
/* Parse the filename/URI argument. */
|
||||
@@ -3361,7 +3361,7 @@ int sqlite3_table_column_metadata(
|
||||
primarykey = 1;
|
||||
}
|
||||
if( !zCollSeq ){
|
||||
zCollSeq = "BINARY";
|
||||
zCollSeq = sqlite3StrBINARY;
|
||||
}
|
||||
|
||||
error_out:
|
||||
@@ -3969,4 +3969,3 @@ void sqlite3_snapshot_free(sqlite3_snapshot *pSnapshot){
|
||||
sqlite3_free(pSnapshot);
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_SNAPSHOT */
|
||||
|
||||
|
||||
29
src/mem5.c
29
src/mem5.c
@@ -25,7 +25,7 @@
|
||||
**
|
||||
** This memory allocator uses the following algorithm:
|
||||
**
|
||||
** 1. All memory allocations sizes are rounded up to a power of 2.
|
||||
** 1. All memory allocation sizes are rounded up to a power of 2.
|
||||
**
|
||||
** 2. If two adjacent free blocks are the halves of a larger block,
|
||||
** then the two blocks are coalesced into the single larger block.
|
||||
@@ -117,7 +117,7 @@ static SQLITE_WSD struct Mem5Global {
|
||||
/*
|
||||
** Lists of free blocks. aiFreelist[0] is a list of free blocks of
|
||||
** size mem5.szAtom. aiFreelist[1] holds blocks of size szAtom*2.
|
||||
** and so forth.
|
||||
** aiFreelist[2] holds free blocks of size szAtom*4. And so forth.
|
||||
*/
|
||||
int aiFreelist[LOGMAX+1];
|
||||
|
||||
@@ -183,9 +183,7 @@ static void memsys5Link(int i, int iLogsize){
|
||||
}
|
||||
|
||||
/*
|
||||
** If the STATIC_MEM mutex is not already held, obtain it now. The mutex
|
||||
** will already be held (obtained by code in malloc.c) if
|
||||
** sqlite3GlobalConfig.bMemStat is true.
|
||||
** Obtain or release the mutex needed to access global data structures.
|
||||
*/
|
||||
static void memsys5Enter(void){
|
||||
sqlite3_mutex_enter(mem5.mutex);
|
||||
@@ -195,9 +193,8 @@ static void memsys5Leave(void){
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the size of an outstanding allocation, in bytes. The
|
||||
** size returned omits the 8-byte header overhead. This only
|
||||
** works for chunks that are currently checked out.
|
||||
** Return the size of an outstanding allocation, in bytes.
|
||||
** This only works for chunks that are currently checked out.
|
||||
*/
|
||||
static int memsys5Size(void *p){
|
||||
int iSize, i;
|
||||
@@ -230,16 +227,12 @@ static void *memsys5MallocUnsafe(int nByte){
|
||||
/* Keep track of the maximum allocation request. Even unfulfilled
|
||||
** requests are counted */
|
||||
if( (u32)nByte>mem5.maxRequest ){
|
||||
/* Abort if the requested allocation size is larger than the largest
|
||||
** power of two that we can represent using 32-bit signed integers. */
|
||||
if( nByte > 0x40000000 ) return 0;
|
||||
mem5.maxRequest = nByte;
|
||||
}
|
||||
|
||||
/* Abort if the requested allocation size is larger than the largest
|
||||
** power of two that we can represent using 32-bit signed integers.
|
||||
*/
|
||||
if( nByte > 0x40000000 ){
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Round nByte up to the next valid power of two */
|
||||
for(iFullSz=mem5.szAtom,iLogsize=0; iFullSz<nByte; iFullSz*=2,iLogsize++){}
|
||||
|
||||
@@ -398,13 +391,11 @@ static void *memsys5Realloc(void *pPrior, int nBytes){
|
||||
if( nBytes<=nOld ){
|
||||
return pPrior;
|
||||
}
|
||||
memsys5Enter();
|
||||
p = memsys5MallocUnsafe(nBytes);
|
||||
p = memsys5Malloc(nBytes);
|
||||
if( p ){
|
||||
memcpy(p, pPrior, nOld);
|
||||
memsys5FreeUnsafe(pPrior);
|
||||
memsys5Free(pPrior);
|
||||
}
|
||||
memsys5Leave();
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
@@ -51,6 +51,8 @@ struct sqlite3_mutex {
|
||||
};
|
||||
#if SQLITE_MUTEX_NREF
|
||||
#define SQLITE3_MUTEX_INITIALIZER {PTHREAD_MUTEX_INITIALIZER,0,0,(pthread_t)0,0}
|
||||
#elif defined(SQLITE_ENABLE_API_ARMOR)
|
||||
#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, 0 }
|
||||
#else
|
||||
#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER }
|
||||
#endif
|
||||
|
||||
702
src/shell.c
702
src/shell.c
File diff suppressed because it is too large
Load Diff
@@ -692,11 +692,6 @@ typedef INT16_TYPE LogEst;
|
||||
** -DSQLITE_RUNTIME_BYTEORDER=1 is set, then byte-order is determined
|
||||
** at run-time.
|
||||
*/
|
||||
#ifdef SQLITE_AMALGAMATION
|
||||
const int sqlite3one = 1;
|
||||
#else
|
||||
extern const int sqlite3one;
|
||||
#endif
|
||||
#if (defined(i386) || defined(__i386__) || defined(_M_IX86) || \
|
||||
defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \
|
||||
defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \
|
||||
@@ -714,6 +709,11 @@ extern const int sqlite3one;
|
||||
# define SQLITE_UTF16NATIVE SQLITE_UTF16BE
|
||||
#endif
|
||||
#if !defined(SQLITE_BYTEORDER)
|
||||
# ifdef SQLITE_AMALGAMATION
|
||||
const int sqlite3one = 1;
|
||||
# else
|
||||
extern const int sqlite3one;
|
||||
# endif
|
||||
# define SQLITE_BYTEORDER 0 /* 0 means "unknown at compile-time" */
|
||||
# define SQLITE_BIGENDIAN (*(char *)(&sqlite3one)==0)
|
||||
# define SQLITE_LITTLEENDIAN (*(char *)(&sqlite3one)==1)
|
||||
@@ -1530,7 +1530,7 @@ struct Column {
|
||||
char *zColl; /* Collating sequence. If NULL, use the default */
|
||||
u8 notNull; /* An OE_ code for handling a NOT NULL constraint */
|
||||
char affinity; /* One of the SQLITE_AFF_... values */
|
||||
u8 szEst; /* Estimated size of this column. INT==1 */
|
||||
u8 szEst; /* Estimated size of value in this column. sizeof(INT)==1 */
|
||||
u8 colFlags; /* Boolean properties. See COLFLAG_ defines below */
|
||||
};
|
||||
|
||||
@@ -1940,7 +1940,7 @@ struct Index {
|
||||
Index *pNext; /* The next index associated with the same table */
|
||||
Schema *pSchema; /* Schema containing this index */
|
||||
u8 *aSortOrder; /* for each column: True==DESC, False==ASC */
|
||||
char **azColl; /* Array of collation sequence names for index */
|
||||
const char **azColl; /* Array of collation sequence names for index */
|
||||
Expr *pPartIdxWhere; /* WHERE clause for partial indices */
|
||||
ExprList *aColExpr; /* Column expressions */
|
||||
int tnum; /* DB Page containing root of this index */
|
||||
@@ -3360,7 +3360,11 @@ void sqlite3OpenMasterTable(Parse *, int);
|
||||
Index *sqlite3PrimaryKeyIndex(Table*);
|
||||
i16 sqlite3ColumnOfIndex(Index*, i16);
|
||||
void sqlite3StartTable(Parse*,Token*,Token*,int,int,int,int);
|
||||
void sqlite3ColumnPropertiesFromName(Table*, Column*);
|
||||
#if SQLITE_ENABLE_HIDDEN_COLUMNS
|
||||
void sqlite3ColumnPropertiesFromName(Table*, Column*);
|
||||
#else
|
||||
# define sqlite3ColumnPropertiesFromName(T,C) /* no-op */
|
||||
#endif
|
||||
void sqlite3AddColumn(Parse*,Token*);
|
||||
void sqlite3AddNotNull(Parse*, int);
|
||||
void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int);
|
||||
@@ -3473,6 +3477,7 @@ void sqlite3ExprCacheRemove(Parse*, int, int);
|
||||
void sqlite3ExprCacheClear(Parse*);
|
||||
void sqlite3ExprCacheAffinityChange(Parse*, int, int);
|
||||
void sqlite3ExprCode(Parse*, Expr*, int);
|
||||
void sqlite3ExprCodeCopy(Parse*, Expr*, int);
|
||||
void sqlite3ExprCodeFactorable(Parse*, Expr*, int);
|
||||
void sqlite3ExprCodeAtInit(Parse*, Expr*, int, u8);
|
||||
int sqlite3ExprCodeTemp(Parse*, Expr*, int*);
|
||||
@@ -3710,6 +3715,7 @@ int sqlite3ValueFromExpr(sqlite3 *, Expr *, u8, u8, sqlite3_value **);
|
||||
void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8);
|
||||
#ifndef SQLITE_AMALGAMATION
|
||||
extern const unsigned char sqlite3OpcodeProperty[];
|
||||
extern const char sqlite3StrBINARY[];
|
||||
extern const unsigned char sqlite3UpperToLower[];
|
||||
extern const unsigned char sqlite3CtypeMap[];
|
||||
extern const Token sqlite3IntTokens[];
|
||||
|
||||
10
src/test8.c
10
src/test8.c
@@ -863,7 +863,7 @@ static int echoBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
|
||||
|
||||
iCol = pConstraint->iColumn;
|
||||
if( iCol<0 || pVtab->aIndex[iCol] ){
|
||||
char *zCol = iCol>=0 ? pVtab->aCol[iCol] : "rowid";
|
||||
char *zNewCol = iCol>=0 ? pVtab->aCol[iCol] : "rowid";
|
||||
char *zOp = 0;
|
||||
useIdx = 1;
|
||||
switch( pConstraint->op ){
|
||||
@@ -895,9 +895,9 @@ static int echoBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
|
||||
}
|
||||
if( zOp[0]=='L' ){
|
||||
zNew = sqlite3_mprintf(" %s %s LIKE (SELECT '%%'||?||'%%')",
|
||||
zSep, zCol);
|
||||
zSep, zNewCol);
|
||||
} else {
|
||||
zNew = sqlite3_mprintf(" %s %s %s ?", zSep, zCol, zOp);
|
||||
zNew = sqlite3_mprintf(" %s %s %s ?", zSep, zNewCol, zOp);
|
||||
}
|
||||
string_concat(&zQuery, zNew, 1, &rc);
|
||||
|
||||
@@ -915,9 +915,9 @@ static int echoBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
|
||||
pIdxInfo->aOrderBy->iColumn<0 ||
|
||||
pVtab->aIndex[pIdxInfo->aOrderBy->iColumn]) ){
|
||||
int iCol = pIdxInfo->aOrderBy->iColumn;
|
||||
char *zCol = iCol>=0 ? pVtab->aCol[iCol] : "rowid";
|
||||
char *zNewCol = iCol>=0 ? pVtab->aCol[iCol] : "rowid";
|
||||
char *zDir = pIdxInfo->aOrderBy->desc?"DESC":"ASC";
|
||||
zNew = sqlite3_mprintf(" ORDER BY %s %s", zCol, zDir);
|
||||
zNew = sqlite3_mprintf(" ORDER BY %s %s", zNewCol, zDir);
|
||||
string_concat(&zQuery, zNew, 1, &rc);
|
||||
pIdxInfo->orderByConsumed = 1;
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ static void statusFunc(
|
||||
int argc,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
int op, mx, cur, resetFlag, rc;
|
||||
int op = 0, mx, cur, resetFlag, rc;
|
||||
if( sqlite3_value_type(argv[0])==SQLITE_INTEGER ){
|
||||
op = sqlite3_value_int(argv[0]);
|
||||
}else if( sqlite3_value_type(argv[0])==SQLITE_TEXT ){
|
||||
|
||||
@@ -37,13 +37,13 @@
|
||||
#include <assert.h>
|
||||
#include "vdbeInt.h"
|
||||
|
||||
#ifndef SQLITE_AMALGAMATION
|
||||
#if !defined(SQLITE_AMALGAMATION) && SQLITE_BYTEORDER==0
|
||||
/*
|
||||
** The following constant value is used by the SQLITE_BIGENDIAN and
|
||||
** SQLITE_LITTLEENDIAN macros.
|
||||
*/
|
||||
const int sqlite3one = 1;
|
||||
#endif /* SQLITE_AMALGAMATION */
|
||||
#endif /* SQLITE_AMALGAMATION && SQLITE_BYTEORDER==0 */
|
||||
|
||||
/*
|
||||
** This lookup table is used to help decode the first byte of
|
||||
|
||||
15
src/vdbe.c
15
src/vdbe.c
@@ -2006,21 +2006,21 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
|
||||
/* Neither operand is NULL. Do a comparison. */
|
||||
affinity = pOp->p5 & SQLITE_AFF_MASK;
|
||||
if( affinity>=SQLITE_AFF_NUMERIC ){
|
||||
if( (pIn1->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
|
||||
if( (flags1 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
|
||||
applyNumericAffinity(pIn1,0);
|
||||
}
|
||||
if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
|
||||
if( (flags3 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
|
||||
applyNumericAffinity(pIn3,0);
|
||||
}
|
||||
}else if( affinity==SQLITE_AFF_TEXT ){
|
||||
if( (pIn1->flags & MEM_Str)==0 && (pIn1->flags & (MEM_Int|MEM_Real))!=0 ){
|
||||
if( (flags1 & MEM_Str)==0 && (flags1 & (MEM_Int|MEM_Real))!=0 ){
|
||||
testcase( pIn1->flags & MEM_Int );
|
||||
testcase( pIn1->flags & MEM_Real );
|
||||
sqlite3VdbeMemStringify(pIn1, encoding, 1);
|
||||
testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) );
|
||||
flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask);
|
||||
}
|
||||
if( (pIn3->flags & MEM_Str)==0 && (pIn3->flags & (MEM_Int|MEM_Real))!=0 ){
|
||||
if( (flags3 & MEM_Str)==0 && (flags3 & (MEM_Int|MEM_Real))!=0 ){
|
||||
testcase( pIn3->flags & MEM_Int );
|
||||
testcase( pIn3->flags & MEM_Real );
|
||||
sqlite3VdbeMemStringify(pIn3, encoding, 1);
|
||||
@@ -2029,15 +2029,14 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
|
||||
}
|
||||
}
|
||||
assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 );
|
||||
if( pIn1->flags & MEM_Zero ){
|
||||
if( flags1 & MEM_Zero ){
|
||||
sqlite3VdbeMemExpandBlob(pIn1);
|
||||
flags1 &= ~MEM_Zero;
|
||||
}
|
||||
if( pIn3->flags & MEM_Zero ){
|
||||
if( flags3 & MEM_Zero ){
|
||||
sqlite3VdbeMemExpandBlob(pIn3);
|
||||
flags3 &= ~MEM_Zero;
|
||||
}
|
||||
if( db->mallocFailed ) goto no_mem;
|
||||
res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl);
|
||||
}
|
||||
switch( pOp->opcode ){
|
||||
@@ -2534,6 +2533,8 @@ case OP_Column: {
|
||||
rc = SQLITE_CORRUPT_BKPT;
|
||||
goto op_column_error;
|
||||
}
|
||||
}else{
|
||||
VVA_ONLY( t = 0; ) /* Only needed by assert() statements */
|
||||
}
|
||||
|
||||
/* If after trying to extract new entries from the header, nHdrParsed is
|
||||
|
||||
@@ -3750,7 +3750,7 @@ int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){
|
||||
return -1;
|
||||
}
|
||||
|
||||
assert( pMem1->enc==pMem2->enc );
|
||||
assert( pMem1->enc==pMem2->enc || pMem1->db->mallocFailed );
|
||||
assert( pMem1->enc==SQLITE_UTF8 ||
|
||||
pMem1->enc==SQLITE_UTF16LE || pMem1->enc==SQLITE_UTF16BE );
|
||||
|
||||
|
||||
@@ -718,7 +718,7 @@ static void constructAutomaticIndex(
|
||||
idxCols |= cMask;
|
||||
pIdx->aiColumn[n] = pTerm->u.leftColumn;
|
||||
pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
|
||||
pIdx->azColl[n] = pColl ? pColl->zName : "BINARY";
|
||||
pIdx->azColl[n] = pColl ? pColl->zName : sqlite3StrBINARY;
|
||||
n++;
|
||||
}
|
||||
}
|
||||
@@ -730,20 +730,20 @@ static void constructAutomaticIndex(
|
||||
for(i=0; i<mxBitCol; i++){
|
||||
if( extraCols & MASKBIT(i) ){
|
||||
pIdx->aiColumn[n] = i;
|
||||
pIdx->azColl[n] = "BINARY";
|
||||
pIdx->azColl[n] = sqlite3StrBINARY;
|
||||
n++;
|
||||
}
|
||||
}
|
||||
if( pSrc->colUsed & MASKBIT(BMS-1) ){
|
||||
for(i=BMS-1; i<pTable->nCol; i++){
|
||||
pIdx->aiColumn[n] = i;
|
||||
pIdx->azColl[n] = "BINARY";
|
||||
pIdx->azColl[n] = sqlite3StrBINARY;
|
||||
n++;
|
||||
}
|
||||
}
|
||||
assert( n==nKeyCol );
|
||||
pIdx->aiColumn[n] = XN_ROWID;
|
||||
pIdx->azColl[n] = "BINARY";
|
||||
pIdx->azColl[n] = sqlite3StrBINARY;
|
||||
|
||||
/* Create the automatic index */
|
||||
assert( pLevel->iIdxCur>=0 );
|
||||
|
||||
@@ -288,7 +288,7 @@ struct WhereTerm {
|
||||
struct WhereScan {
|
||||
WhereClause *pOrigWC; /* Original, innermost WhereClause */
|
||||
WhereClause *pWC; /* WhereClause currently being scanned */
|
||||
char *zCollName; /* Required collating sequence, if not NULL */
|
||||
const char *zCollName; /* Required collating sequence, if not NULL */
|
||||
Expr *pIdxExpr; /* Search for this index expression */
|
||||
char idxaff; /* Must match this affinity, if zCollName!=NULL */
|
||||
unsigned char nEquiv; /* Number of entries in aEquiv[] */
|
||||
|
||||
Reference in New Issue
Block a user