diff --git a/Makefile.in b/Makefile.in index d06b3ca49d..1fe49d6789 100644 --- a/Makefile.in +++ b/Makefile.in @@ -550,7 +550,7 @@ TESTOPTS = --verbose=file --output=test-out.txt # SHELL_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5 FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1 -FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 +FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 # This is the default Makefile target. The objects listed here # are what get build when you type just "make" with no arguments. diff --git a/Makefile.msc b/Makefile.msc index aa2bd9a2f1..92561a8a32 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1218,7 +1218,7 @@ FUZZDATA = \ # SHELL_COMPILE_OPTS = -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5 FUZZERSHELL_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -FUZZCHECK_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 +FUZZCHECK_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 # Standard options to testfixture # diff --git a/ext/fts5/fts5_aux.c b/ext/fts5/fts5_aux.c index 928a26a8bb..011064d405 100644 --- a/ext/fts5/fts5_aux.c +++ b/ext/fts5/fts5_aux.c @@ -544,7 +544,7 @@ int sqlite3Fts5AuxInit(fts5_api *pApi){ int rc = SQLITE_OK; /* Return code */ int i; /* To iterate through builtin functions */ - for(i=0; rc==SQLITE_OK && ixCreateFunction(pApi, aBuiltin[i].zFunc, aBuiltin[i].pUserData, diff --git a/ext/fts5/fts5_expr.c b/ext/fts5/fts5_expr.c index c0dd0ec066..3804a2abfe 100644 --- a/ext/fts5/fts5_expr.c +++ b/ext/fts5/fts5_expr.c @@ -407,7 +407,7 @@ static int fts5ExprPhraseIsMatch( /* If the aStatic[] array is not large enough, allocate a large array ** using sqlite3_malloc(). This approach could be improved upon. */ - if( pPhrase->nTerm>(sizeof(aStatic) / sizeof(aStatic[0])) ){ + if( pPhrase->nTerm>(int)ArraySize(aStatic) ){ int nByte = sizeof(Fts5PoslistReader) * pPhrase->nTerm; aIter = (Fts5PoslistReader*)sqlite3_malloc(nByte); if( !aIter ) return SQLITE_NOMEM; @@ -543,7 +543,7 @@ static int fts5ExprNearIsMatch(int *pRc, Fts5ExprNearset *pNear){ /* If the aStatic[] array is not large enough, allocate a large array ** using sqlite3_malloc(). This approach could be improved upon. */ - if( pNear->nPhrase>(sizeof(aStatic) / sizeof(aStatic[0])) ){ + if( pNear->nPhrase>(int)ArraySize(aStatic) ){ int nByte = sizeof(Fts5NearTrimmer) * pNear->nPhrase; a = (Fts5NearTrimmer*)sqlite3Fts5MallocZero(&rc, nByte); }else{ @@ -2214,7 +2214,7 @@ int sqlite3Fts5ExprInit(Fts5Global *pGlobal, sqlite3 *db){ int rc = SQLITE_OK; void *pCtx = (void*)pGlobal; - for(i=0; rc==SQLITE_OK && i<(sizeof(aFunc) / sizeof(aFunc[0])); i++){ + for(i=0; rc==SQLITE_OK && i<(int)ArraySize(aFunc); i++){ struct Fts5ExprFunc *p = &aFunc[i]; rc = sqlite3_create_function(db, p->z, -1, SQLITE_UTF8, pCtx, p->x, 0, 0); } diff --git a/ext/fts5/fts5_main.c b/ext/fts5/fts5_main.c index 7f6f6dacef..ba8903c9a7 100644 --- a/ext/fts5/fts5_main.c +++ b/ext/fts5/fts5_main.c @@ -545,7 +545,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ for(i=0; inConstraint; i++){ struct sqlite3_index_constraint *p = &pInfo->aConstraint[i]; int j; - for(j=0; jiColumn==aColMap[pC->iCol] && p->op & pC->op ){ if( p->usable ){ @@ -592,7 +592,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ /* Assign argvIndex values to each constraint in use. */ iNext = 1; - for(i=0; iiConsIndex>=0 ){ pInfo->aConstraintUsage[pC->iConsIndex].argvIndex = iNext++; diff --git a/ext/fts5/fts5_storage.c b/ext/fts5/fts5_storage.c index f047fd99dc..4a1ce3a3d9 100644 --- a/ext/fts5/fts5_storage.c +++ b/ext/fts5/fts5_storage.c @@ -338,7 +338,7 @@ int sqlite3Fts5StorageClose(Fts5Storage *p){ int i; /* Finalize all SQL statements */ - for(i=0; iaStmt); i++){ + for(i=0; i<(int)ArraySize(p->aStmt); i++){ sqlite3_finalize(p->aStmt[i]); } diff --git a/ext/fts5/fts5_tokenize.c b/ext/fts5/fts5_tokenize.c index 1df7ba9e35..e60183c095 100644 --- a/ext/fts5/fts5_tokenize.c +++ b/ext/fts5/fts5_tokenize.c @@ -1220,7 +1220,7 @@ int sqlite3Fts5TokenizerInit(fts5_api *pApi){ int rc = SQLITE_OK; /* Return code */ int i; /* To iterate through builtin functions */ - for(i=0; rc==SQLITE_OK && ixCreateTokenizer(pApi, aBuiltin[i].zName, (void*)pApi, diff --git a/ext/misc/json1.c b/ext/misc/json1.c index 61d013ea4b..3707516660 100644 --- a/ext/misc/json1.c +++ b/ext/misc/json1.c @@ -1181,7 +1181,7 @@ static void jsonTest1Func( #endif /* SQLITE_DEBUG */ /**************************************************************************** -** SQL function implementations +** Scalar SQL function implementations ****************************************************************************/ /* @@ -1514,6 +1514,102 @@ static void jsonValidFunc( sqlite3_result_int(ctx, rc); } + +/**************************************************************************** +** Aggregate SQL function implementations +****************************************************************************/ +/* +** json_group_array(VALUE) +** +** Return a JSON array composed of all values in the aggregate. +*/ +static void jsonArrayStep( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + JsonString *pStr; + pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); + if( pStr ){ + if( pStr->zBuf==0 ){ + jsonInit(pStr, ctx); + jsonAppendChar(pStr, '['); + }else{ + jsonAppendChar(pStr, ','); + pStr->pCtx = ctx; + } + jsonAppendValue(pStr, argv[0]); + } +} +static void jsonArrayFinal(sqlite3_context *ctx){ + JsonString *pStr; + pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); + if( pStr ){ + pStr->pCtx = ctx; + jsonAppendChar(pStr, ']'); + if( pStr->bErr ){ + sqlite3_result_error_nomem(ctx); + assert( pStr->bStatic ); + }else{ + sqlite3_result_text(ctx, pStr->zBuf, pStr->nUsed, + pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free); + pStr->bStatic = 1; + } + }else{ + sqlite3_result_text(ctx, "[]", 2, SQLITE_STATIC); + } + sqlite3_result_subtype(ctx, JSON_SUBTYPE); +} + +/* +** json_group_obj(NAME,VALUE) +** +** Return a JSON object composed of all names and values in the aggregate. +*/ +static void jsonObjectStep( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + JsonString *pStr; + const char *z; + u32 n; + pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); + if( pStr ){ + if( pStr->zBuf==0 ){ + jsonInit(pStr, ctx); + jsonAppendChar(pStr, '{'); + }else{ + jsonAppendChar(pStr, ','); + pStr->pCtx = ctx; + } + z = (const char*)sqlite3_value_text(argv[0]); + n = (u32)sqlite3_value_bytes(argv[0]); + jsonAppendString(pStr, z, n); + jsonAppendChar(pStr, ':'); + jsonAppendValue(pStr, argv[1]); + } +} +static void jsonObjectFinal(sqlite3_context *ctx){ + JsonString *pStr; + pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); + if( pStr ){ + jsonAppendChar(pStr, '}'); + if( pStr->bErr ){ + sqlite3_result_error_nomem(ctx); + assert( pStr->bStatic ); + }else{ + sqlite3_result_text(ctx, pStr->zBuf, pStr->nUsed, + pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free); + pStr->bStatic = 1; + } + }else{ + sqlite3_result_text(ctx, "{}", 2, SQLITE_STATIC); + } + sqlite3_result_subtype(ctx, JSON_SUBTYPE); +} + + #ifndef SQLITE_OMIT_VIRTUALTABLE /**************************************************************************** ** The json_each virtual table @@ -2012,6 +2108,15 @@ int sqlite3Json1Init(sqlite3 *db){ { "json_test1", 1, 0, jsonTest1Func }, #endif }; + static const struct { + const char *zName; + int nArg; + void (*xStep)(sqlite3_context*,int,sqlite3_value**); + void (*xFinal)(sqlite3_context*); + } aAgg[] = { + { "json_group_array", 1, jsonArrayStep, jsonArrayFinal }, + { "json_group_object", 2, jsonObjectStep, jsonObjectFinal }, + }; #ifndef SQLITE_OMIT_VIRTUALTABLE static const struct { const char *zName; @@ -2027,6 +2132,11 @@ int sqlite3Json1Init(sqlite3 *db){ (void*)&aFunc[i].flag, aFunc[i].xFunc, 0, 0); } + for(i=0; inLocal = (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.nLocalpBt, 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.nLocalaData+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.nLocalpgno && 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); diff --git a/src/btreeInt.h b/src/btreeInt.h index e43ff1210a..a196e18a28 100644 --- a/src/btreeInt.h +++ b/src/btreeInt.h @@ -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 */ }; diff --git a/src/build.c b/src/build.c index 765196f821..63e3004657 100644 --- a/src/build.c +++ b/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; @@ -1774,7 +1774,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ ** do not enforce this for imposter tables.) */ if( !db->init.imposterTable ){ for(i=0; iaCol[pPk->aiColumn[i]].notNull = 1; + pTab->aCol[pPk->aiColumn[i]].notNull = OE_Abort; } pPk->uniqNotNull = 1; } @@ -1816,7 +1816,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ if( !hasColumn(pPk->aiColumn, j, i) ){ assert( jnColumn ); 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; inExpr; 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; iazColl[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]; } diff --git a/src/date.c b/src/date.c index 8a66eae900..3d7604ab45 100644 --- a/src/date.c +++ b/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 diff --git a/src/expr.c b/src/expr.c index 8f6377e664..d8d36afa54 100644 --- a/src/expr.c +++ b/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( nSizeaColExpr ); 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 diff --git a/src/fkey.c b/src/fkey.c index b55e2a9813..2abd06c693 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -249,7 +249,7 @@ int sqlite3FkLocateIndex( int i, j; for(i=0; iaiColumn[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; diff --git a/src/func.c b/src/func.c index 3fbd2b736b..ad4cf73c31 100644 --- a/src/func.c +++ b/src/func.c @@ -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; diff --git a/src/global.c b/src/global.c index ef4fe56ae1..64966b35d7 100644 --- a/src/global.c +++ b/src/global.c @@ -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"; diff --git a/src/insert.c b/src/insert.c index 52769e9c4f..3e4aac8f4d 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1408,7 +1408,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{ @@ -1709,20 +1709,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 @@ -1758,7 +1744,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 */ } } @@ -1919,7 +1905,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 ){ @@ -2066,9 +2052,10 @@ static int xferOptimization( ** a VACUUM command. In that case keys may not be written in strictly ** sorted order. */ for(i=0; inColumn; 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; diff --git a/src/main.c b/src/main.c index 5b2130511e..8b75e71500 100644 --- a/src/main.c +++ b/src/main.c @@ -2829,9 +2829,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 ){ @@ -2840,7 +2840,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. */ @@ -3340,7 +3340,7 @@ int sqlite3_table_column_metadata( primarykey = 1; } if( !zCollSeq ){ - zCollSeq = "BINARY"; + zCollSeq = sqlite3StrBINARY; } error_out: @@ -3948,4 +3948,3 @@ void sqlite3_snapshot_free(sqlite3_snapshot *pSnapshot){ sqlite3_free(pSnapshot); } #endif /* SQLITE_ENABLE_SNAPSHOT */ - diff --git a/src/mem5.c b/src/mem5.c index b34a04e8b6..49bebca093 100644 --- a/src/mem5.c +++ b/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; iFullSznLine ){ + zLine = realloc(zLine, nTrans); + if( zLine==0 ){ + sqlite3_free(zTrans); + return 0; + } + } + memcpy(zLine, zTrans, nTrans); + sqlite3_free(zTrans); + } + } +#endif /* defined(_WIN32) || defined(WIN32) */ return zLine; } @@ -502,6 +539,39 @@ static char *one_input_line(FILE *in, char *zPrior, int isContinuation){ return zResult; } +/* +** Render output like fprintf(). Except, if the output is going to the +** console and if this is running on a Windows machine, translate the +** output from UTF-8 into MBCS. +*/ +#if defined(_WIN32) || defined(WIN32) +void utf8_printf(FILE *out, const char *zFormat, ...){ + va_list ap; + va_start(ap, zFormat); + if( stdout_is_console && (out==stdout || out==stderr) ){ + extern char *sqlite3_win32_utf8_to_mbcs(const char*); + char *z1 = sqlite3_vmprintf(zFormat, ap); + char *z2 = sqlite3_win32_utf8_to_mbcs(z1); + sqlite3_free(z1); + fputs(z2, out); + sqlite3_free(z2); + }else{ + vfprintf(out, zFormat, ap); + } + va_end(ap); +} +#elif !defined(utf8_printf) +# define utf8_printf fprintf +#endif + +/* +** Render output like fprintf(). This should not be used on anything that +** includes string formatting (e.g. "%s"). +*/ +#if !defined(raw_printf) +# define raw_printf fprintf +#endif + /* ** Shell output mode information from before ".explain on", ** saved so that it can be restored by ".explain off" @@ -607,23 +677,13 @@ static const char *modeDescr[] = { */ #define ArraySize(X) (int)(sizeof(X)/sizeof(X[0])) -/* -** Compute a string length that is limited to what can be stored in -** lower 30 bits of a 32-bit signed integer. -*/ -static int strlen30(const char *z){ - const char *z2 = z; - while( *z2 ){ z2++; } - return 0x3fffffff & (int)(z2 - z); -} - /* ** A callback for the sqlite3_log() interface. */ static void shellLog(void *pArg, int iErrCode, const char *zMsg){ ShellState *p = (ShellState*)pArg; if( p->pLog==0 ) return; - fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg); + utf8_printf(p->pLog, "(%d) %s\n", iErrCode, zMsg); fflush(p->pLog); } @@ -633,9 +693,9 @@ static void shellLog(void *pArg, int iErrCode, const char *zMsg){ static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){ int i; char *zBlob = (char *)pBlob; - fprintf(out,"X'"); - for(i=0; i0 ){ - fprintf(out,"%.*s",i,z); + utf8_printf(out,"%.*s",i,z); } if( z[i]=='<' ){ - fprintf(out,"<"); + raw_printf(out,"<"); }else if( z[i]=='&' ){ - fprintf(out,"&"); + raw_printf(out,"&"); }else if( z[i]=='>' ){ - fprintf(out,">"); + raw_printf(out,">"); }else if( z[i]=='\"' ){ - fprintf(out,"""); + raw_printf(out,"""); }else if( z[i]=='\'' ){ - fprintf(out,"'"); + raw_printf(out,"'"); }else{ break; } @@ -768,7 +828,7 @@ static const char needCsvQuote[] = { static void output_csv(ShellState *p, const char *z, int bSep){ FILE *out = p->out; if( z==0 ){ - fprintf(out,"%s",p->nullValue); + utf8_printf(out,"%s",p->nullValue); }else{ int i; int nSep = strlen30(p->colSeparator); @@ -788,11 +848,11 @@ static void output_csv(ShellState *p, const char *z, int bSep){ } putc('"', out); }else{ - fprintf(out, "%s", z); + utf8_printf(out, "%s", z); } } if( bSep ){ - fprintf(p->out, "%s", p->colSeparator); + utf8_printf(p->out, "%s", p->colSeparator); } } @@ -830,9 +890,9 @@ static int shell_callback( int len = strlen30(azCol[i] ? azCol[i] : ""); if( len>w ) w = len; } - if( p->cnt++>0 ) fprintf(p->out, "%s", p->rowSeparator); + if( p->cnt++>0 ) utf8_printf(p->out, "%s", p->rowSeparator); for(i=0; iout,"%*s = %s%s", w, azCol[i], + utf8_printf(p->out,"%*s = %s%s", w, azCol[i], azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator); } break; @@ -858,10 +918,10 @@ static int shell_callback( } if( p->showHeader ){ if( w<0 ){ - fprintf(p->out,"%*.*s%s",-w,-w,azCol[i], + utf8_printf(p->out,"%*.*s%s",-w,-w,azCol[i], i==nArg-1 ? p->rowSeparator : " "); }else{ - fprintf(p->out,"%-*.*s%s",w,w,azCol[i], + utf8_printf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? p->rowSeparator : " "); } } @@ -875,7 +935,8 @@ static int shell_callback( }else{ w = 10; } - fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------" + utf8_printf(p->out,"%-*.*s%s",w,w, + "----------------------------------------------------------" "----------------------------------------------------------", i==nArg-1 ? p->rowSeparator : " "); } @@ -894,16 +955,16 @@ static int shell_callback( } if( i==1 && p->aiIndent && p->pStmt ){ if( p->iIndentnIndent ){ - fprintf(p->out, "%*.s", p->aiIndent[p->iIndent], ""); + utf8_printf(p->out, "%*.s", p->aiIndent[p->iIndent], ""); } p->iIndent++; } if( w<0 ){ - fprintf(p->out,"%*.*s%s",-w,-w, + utf8_printf(p->out,"%*.*s%s",-w,-w, azArg[i] ? azArg[i] : p->nullValue, i==nArg-1 ? p->rowSeparator : " "); }else{ - fprintf(p->out,"%-*.*s%s",w,w, + utf8_printf(p->out,"%-*.*s%s",w,w, azArg[i] ? azArg[i] : p->nullValue, i==nArg-1 ? p->rowSeparator : " "); } @@ -914,7 +975,7 @@ static int shell_callback( case MODE_List: { if( p->cnt++==0 && p->showHeader ){ for(i=0; iout,"%s%s",azCol[i], + utf8_printf(p->out,"%s%s",azCol[i], i==nArg-1 ? p->rowSeparator : p->colSeparator); } } @@ -922,51 +983,51 @@ static int shell_callback( for(i=0; inullValue; - fprintf(p->out, "%s", z); + utf8_printf(p->out, "%s", z); if( iout, "%s", p->colSeparator); + utf8_printf(p->out, "%s", p->colSeparator); }else if( p->mode==MODE_Semi ){ - fprintf(p->out, ";%s", p->rowSeparator); + utf8_printf(p->out, ";%s", p->rowSeparator); }else{ - fprintf(p->out, "%s", p->rowSeparator); + utf8_printf(p->out, "%s", p->rowSeparator); } } break; } case MODE_Html: { if( p->cnt++==0 && p->showHeader ){ - fprintf(p->out,""); + raw_printf(p->out,""); for(i=0; iout,""); + raw_printf(p->out,""); output_html_string(p->out, azCol[i]); - fprintf(p->out,"\n"); + raw_printf(p->out,"\n"); } - fprintf(p->out,"\n"); + raw_printf(p->out,"\n"); } if( azArg==0 ) break; - fprintf(p->out,""); + raw_printf(p->out,""); for(i=0; iout,""); + raw_printf(p->out,""); output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue); - fprintf(p->out,"\n"); + raw_printf(p->out,"\n"); } - fprintf(p->out,"\n"); + raw_printf(p->out,"\n"); break; } case MODE_Tcl: { if( p->cnt++==0 && p->showHeader ){ for(i=0; iout,azCol[i] ? azCol[i] : ""); - if(iout, "%s", p->colSeparator); + if(iout, "%s", p->colSeparator); } - fprintf(p->out, "%s", p->rowSeparator); + utf8_printf(p->out, "%s", p->rowSeparator); } if( azArg==0 ) break; for(i=0; iout, azArg[i] ? azArg[i] : p->nullValue); - if(iout, "%s", p->colSeparator); + if(iout, "%s", p->colSeparator); } - fprintf(p->out, "%s", p->rowSeparator); + utf8_printf(p->out, "%s", p->rowSeparator); break; } case MODE_Csv: { @@ -975,13 +1036,13 @@ static int shell_callback( for(i=0; iout, "%s", p->rowSeparator); + utf8_printf(p->out, "%s", p->rowSeparator); } if( nArg>0 ){ for(i=0; iout, "%s", p->rowSeparator); + utf8_printf(p->out, "%s", p->rowSeparator); } setTextMode(p->out); break; @@ -989,55 +1050,55 @@ static int shell_callback( case MODE_Insert: { p->cnt++; if( azArg==0 ) break; - fprintf(p->out,"INSERT INTO %s",p->zDestTable); + utf8_printf(p->out,"INSERT INTO %s",p->zDestTable); if( p->showHeader ){ - fprintf(p->out,"("); + raw_printf(p->out,"("); for(i=0; i0 ? ",": ""; - fprintf(p->out, "%s%s", zSep, azCol[i]); + utf8_printf(p->out, "%s%s", zSep, azCol[i]); } - fprintf(p->out,")"); + raw_printf(p->out,")"); } - fprintf(p->out," VALUES("); + raw_printf(p->out," VALUES("); for(i=0; i0 ? ",": ""; if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){ - fprintf(p->out,"%sNULL",zSep); + utf8_printf(p->out,"%sNULL",zSep); }else if( aiType && aiType[i]==SQLITE_TEXT ){ - if( zSep[0] ) fprintf(p->out,"%s",zSep); + if( zSep[0] ) utf8_printf(p->out,"%s",zSep); output_quoted_string(p->out, azArg[i]); }else if( aiType && (aiType[i]==SQLITE_INTEGER || aiType[i]==SQLITE_FLOAT) ){ - fprintf(p->out,"%s%s",zSep, azArg[i]); + utf8_printf(p->out,"%s%s",zSep, azArg[i]); }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){ const void *pBlob = sqlite3_column_blob(p->pStmt, i); int nBlob = sqlite3_column_bytes(p->pStmt, i); - if( zSep[0] ) fprintf(p->out,"%s",zSep); + if( zSep[0] ) utf8_printf(p->out,"%s",zSep); output_hex_blob(p->out, pBlob, nBlob); }else if( isNumber(azArg[i], 0) ){ - fprintf(p->out,"%s%s",zSep, azArg[i]); + utf8_printf(p->out,"%s%s",zSep, azArg[i]); }else{ - if( zSep[0] ) fprintf(p->out,"%s",zSep); + if( zSep[0] ) utf8_printf(p->out,"%s",zSep); output_quoted_string(p->out, azArg[i]); } } - fprintf(p->out,");\n"); + raw_printf(p->out,");\n"); break; } case MODE_Ascii: { if( p->cnt++==0 && p->showHeader ){ for(i=0; i0 ) fprintf(p->out, "%s", p->colSeparator); - fprintf(p->out,"%s",azCol[i] ? azCol[i] : ""); + if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator); + utf8_printf(p->out,"%s",azCol[i] ? azCol[i] : ""); } - fprintf(p->out, "%s", p->rowSeparator); + utf8_printf(p->out, "%s", p->rowSeparator); } if( azArg==0 ) break; for(i=0; i0 ) fprintf(p->out, "%s", p->colSeparator); - fprintf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue); + if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator); + utf8_printf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue); } - fprintf(p->out, "%s", p->rowSeparator); + utf8_printf(p->out, "%s", p->rowSeparator); break; } } @@ -1078,7 +1139,7 @@ static void set_table_name(ShellState *p, const char *zName){ if( needQuote ) n += 2; z = p->zDestTable = malloc( n+1 ); if( z==0 ){ - fprintf(stderr,"Error: out of memory\n"); + raw_printf(stderr,"Error: out of memory\n"); exit(1); } n = 0; @@ -1159,7 +1220,8 @@ static int run_table_dump_query( const char *z; rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0); if( rc!=SQLITE_OK || !pSelect ){ - fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db)); + utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, + sqlite3_errmsg(p->db)); if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++; return rc; } @@ -1167,26 +1229,27 @@ static int run_table_dump_query( nResult = sqlite3_column_count(pSelect); while( rc==SQLITE_ROW ){ if( zFirstRow ){ - fprintf(p->out, "%s", zFirstRow); + utf8_printf(p->out, "%s", zFirstRow); zFirstRow = 0; } z = (const char*)sqlite3_column_text(pSelect, 0); - fprintf(p->out, "%s", z); + utf8_printf(p->out, "%s", z); for(i=1; iout, ",%s", sqlite3_column_text(pSelect, i)); + utf8_printf(p->out, ",%s", sqlite3_column_text(pSelect, i)); } if( z==0 ) z = ""; while( z[0] && (z[0]!='-' || z[1]!='-') ) z++; if( z[0] ){ - fprintf(p->out, "\n;\n"); + raw_printf(p->out, "\n;\n"); }else{ - fprintf(p->out, ";\n"); + raw_printf(p->out, ";\n"); } rc = sqlite3_step(pSelect); } rc = sqlite3_finalize(pSelect); if( rc!=SQLITE_OK ){ - fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db)); + utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, + sqlite3_errmsg(p->db)); if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++; } return rc; @@ -1221,52 +1284,53 @@ static int display_stats( iHiwtr = iCur = -1; sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset); - fprintf(pArg->out, + raw_printf(pArg->out, "Memory Used: %d (max %d) bytes\n", iCur, iHiwtr); iHiwtr = iCur = -1; sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset); - fprintf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n", + raw_printf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n", iCur, iHiwtr); if( pArg->shellFlgs & SHFLG_Pagecache ){ iHiwtr = iCur = -1; sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset); - fprintf(pArg->out, + raw_printf(pArg->out, "Number of Pcache Pages Used: %d (max %d) pages\n", iCur, iHiwtr); } iHiwtr = iCur = -1; sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset); - fprintf(pArg->out, + raw_printf(pArg->out, "Number of Pcache Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr); if( pArg->shellFlgs & SHFLG_Scratch ){ iHiwtr = iCur = -1; sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset); - fprintf(pArg->out, "Number of Scratch Allocations Used: %d (max %d)\n", + raw_printf(pArg->out, + "Number of Scratch Allocations Used: %d (max %d)\n", iCur, iHiwtr); } iHiwtr = iCur = -1; sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset); - fprintf(pArg->out, + raw_printf(pArg->out, "Number of Scratch Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr); iHiwtr = iCur = -1; sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset); - fprintf(pArg->out, "Largest Allocation: %d bytes\n", + raw_printf(pArg->out, "Largest Allocation: %d bytes\n", iHiwtr); iHiwtr = iCur = -1; sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset); - fprintf(pArg->out, "Largest Pcache Allocation: %d bytes\n", + raw_printf(pArg->out, "Largest Pcache Allocation: %d bytes\n", iHiwtr); iHiwtr = iCur = -1; sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset); - fprintf(pArg->out, "Largest Scratch Allocation: %d bytes\n", + raw_printf(pArg->out, "Largest Scratch Allocation: %d bytes\n", iHiwtr); #ifdef YYTRACKMAXSTACKDEPTH iHiwtr = iCur = -1; sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset); - fprintf(pArg->out, "Deepest Parser Stack: %d (max %d)\n", + raw_printf(pArg->out, "Deepest Parser Stack: %d (max %d)\n", iCur, iHiwtr); #endif } @@ -1276,48 +1340,55 @@ static int display_stats( iHiwtr = iCur = -1; sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHiwtr, bReset); - fprintf(pArg->out, "Lookaside Slots Used: %d (max %d)\n", + raw_printf(pArg->out, + "Lookaside Slots Used: %d (max %d)\n", iCur, iHiwtr); sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &iCur, &iHiwtr, bReset); - fprintf(pArg->out, "Successful lookaside attempts: %d\n", iHiwtr); + raw_printf(pArg->out, "Successful lookaside attempts: %d\n", + iHiwtr); sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, &iCur, &iHiwtr, bReset); - fprintf(pArg->out, "Lookaside failures due to size: %d\n", iHiwtr); + raw_printf(pArg->out, "Lookaside failures due to size: %d\n", + iHiwtr); sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &iCur, &iHiwtr, bReset); - fprintf(pArg->out, "Lookaside failures due to OOM: %d\n", iHiwtr); + raw_printf(pArg->out, "Lookaside failures due to OOM: %d\n", + iHiwtr); } iHiwtr = iCur = -1; sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset); - fprintf(pArg->out, "Pager Heap Usage: %d bytes\n",iCur); + raw_printf(pArg->out, "Pager Heap Usage: %d bytes\n", + iCur); iHiwtr = iCur = -1; sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1); - fprintf(pArg->out, "Page cache hits: %d\n", iCur); + raw_printf(pArg->out, "Page cache hits: %d\n", iCur); iHiwtr = iCur = -1; sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1); - fprintf(pArg->out, "Page cache misses: %d\n", iCur); + raw_printf(pArg->out, "Page cache misses: %d\n", iCur); iHiwtr = iCur = -1; sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1); - fprintf(pArg->out, "Page cache writes: %d\n", iCur); + raw_printf(pArg->out, "Page cache writes: %d\n", iCur); iHiwtr = iCur = -1; sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset); - fprintf(pArg->out, "Schema Heap Usage: %d bytes\n",iCur); + raw_printf(pArg->out, "Schema Heap Usage: %d bytes\n", + iCur); iHiwtr = iCur = -1; sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset); - fprintf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n",iCur); + raw_printf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n", + iCur); } if( pArg && pArg->out && db && pArg->pStmt ){ iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, bReset); - fprintf(pArg->out, "Fullscan Steps: %d\n", iCur); + raw_printf(pArg->out, "Fullscan Steps: %d\n", iCur); iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset); - fprintf(pArg->out, "Sort Operations: %d\n", iCur); + raw_printf(pArg->out, "Sort Operations: %d\n", iCur); iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset); - fprintf(pArg->out, "Autoindex Inserts: %d\n", iCur); + raw_printf(pArg->out, "Autoindex Inserts: %d\n", iCur); iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset); - fprintf(pArg->out, "Virtual Machine Steps: %d\n", iCur); + raw_printf(pArg->out, "Virtual Machine Steps: %d\n", iCur); } /* Do not remove this machine readable comment: extra-stats-output-here */ @@ -1337,7 +1408,7 @@ static void display_scanstats( UNUSED_PARAMETER(pArg); #else int i, k, n, mx; - fprintf(pArg->out, "-------- scanstats --------\n"); + raw_printf(pArg->out, "-------- scanstats --------\n"); mx = 0; for(k=0; k<=mx; k++){ double rEstLoop = 1.0; @@ -1355,21 +1426,21 @@ static void display_scanstats( if( iSid!=k ) continue; if( n==0 ){ rEstLoop = (double)nLoop; - if( k>0 ) fprintf(pArg->out, "-------- subquery %d -------\n", k); + if( k>0 ) raw_printf(pArg->out, "-------- subquery %d -------\n", k); } n++; sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit); sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst); sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain); - fprintf(pArg->out, "Loop %2d: %s\n", n, zExplain); + utf8_printf(pArg->out, "Loop %2d: %s\n", n, zExplain); rEstLoop *= rEst; - fprintf(pArg->out, + raw_printf(pArg->out, " nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n", nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst ); } } - fprintf(pArg->out, "---------------------------\n"); + raw_printf(pArg->out, "---------------------------\n"); #endif } @@ -1522,7 +1593,7 @@ static int shell_exec( /* echo the sql statement if echo on */ if( pArg && pArg->echoOn ){ const char *zStmtSql = sqlite3_sql(pStmt); - fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql); + utf8_printf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql); } /* Show the EXPLAIN QUERY PLAN if .eqp is on */ @@ -1533,10 +1604,10 @@ static int shell_exec( rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0); if( rc==SQLITE_OK ){ while( sqlite3_step(pExplain)==SQLITE_ROW ){ - fprintf(pArg->out,"--EQP-- %d,", sqlite3_column_int(pExplain, 0)); - fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1)); - fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2)); - fprintf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3)); + raw_printf(pArg->out,"--EQP-- %d,",sqlite3_column_int(pExplain, 0)); + raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1)); + raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2)); + utf8_printf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3)); } } sqlite3_finalize(pExplain); @@ -1664,24 +1735,24 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){ if( strcmp(zTable, "sqlite_sequence")==0 ){ zPrepStmt = "DELETE FROM sqlite_sequence;\n"; }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){ - fprintf(p->out, "ANALYZE sqlite_master;\n"); + raw_printf(p->out, "ANALYZE sqlite_master;\n"); }else if( strncmp(zTable, "sqlite_", 7)==0 ){ return 0; }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){ char *zIns; if( !p->writableSchema ){ - fprintf(p->out, "PRAGMA writable_schema=ON;\n"); + raw_printf(p->out, "PRAGMA writable_schema=ON;\n"); p->writableSchema = 1; } zIns = sqlite3_mprintf( "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)" "VALUES('table','%q','%q',0,'%q');", zTable, zTable, zSql); - fprintf(p->out, "%s\n", zIns); + utf8_printf(p->out, "%s\n", zIns); sqlite3_free(zIns); return 0; }else{ - fprintf(p->out, "%s;\n", zSql); + utf8_printf(p->out, "%s;\n", zSql); } if( strcmp(zType, "table")==0 ){ @@ -1758,9 +1829,9 @@ static int run_schema_dump_query( if( rc==SQLITE_CORRUPT ){ char *zQ2; int len = strlen30(zQuery); - fprintf(p->out, "/****** CORRUPTION ERROR *******/\n"); + raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n"); if( zErr ){ - fprintf(p->out, "/****** %s ******/\n", zErr); + utf8_printf(p->out, "/****** %s ******/\n", zErr); sqlite3_free(zErr); zErr = 0; } @@ -1769,7 +1840,7 @@ static int run_schema_dump_query( sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery); rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr); if( rc ){ - fprintf(p->out, "/****** ERROR: %s ******/\n", zErr); + utf8_printf(p->out, "/****** ERROR: %s ******/\n", zErr); }else{ rc = SQLITE_CORRUPT; } @@ -1934,7 +2005,7 @@ static void open_db(ShellState *p, int keepAlive){ shellstaticFunc, 0, 0); } if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){ - fprintf(stderr,"Error: unable to open database \"%s\": %s\n", + utf8_printf(stderr,"Error: unable to open database \"%s\": %s\n", p->zDbFilename, sqlite3_errmsg(p->db)); if( keepAlive ) return; exit(1); @@ -2084,7 +2155,7 @@ static int booleanValue(char *zArg){ if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){ return 0; } - fprintf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n", + utf8_printf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n", zArg); return 0; } @@ -2112,7 +2183,7 @@ static FILE *output_file_open(const char *zFile){ }else{ f = fopen(zFile, "wb"); if( f==0 ){ - fprintf(stderr, "Error: cannot open \"%s\"\n", zFile); + utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile); } } return f; @@ -2126,7 +2197,7 @@ static void sql_trace_callback(void *pArg, const char *z){ if( f ){ int i = (int)strlen(z); while( i>0 && z[i-1]==';' ){ i--; } - fprintf(f, "%.*s;\n", i, z); + utf8_printf(f, "%.*s;\n", i, z); } } @@ -2161,7 +2232,7 @@ static void import_append_char(ImportCtx *p, int c){ p->nAlloc += p->nAlloc + 100; p->z = sqlite3_realloc64(p->z, p->nAlloc); if( p->z==0 ){ - fprintf(stderr, "out of memory\n"); + raw_printf(stderr, "out of memory\n"); exit(1); } } @@ -2215,11 +2286,11 @@ static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){ break; } if( pc==cQuote && c!='\r' ){ - fprintf(stderr, "%s:%d: unescaped %c character\n", + utf8_printf(stderr, "%s:%d: unescaped %c character\n", p->zFile, p->nLine, cQuote); } if( c==EOF ){ - fprintf(stderr, "%s:%d: unterminated %c-quoted field\n", + utf8_printf(stderr, "%s:%d: unterminated %c-quoted field\n", p->zFile, startLine, cQuote); p->cTerm = c; break; @@ -2301,7 +2372,7 @@ static void tryToCloneData( zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable); rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); if( rc ){ - fprintf(stderr, "Error %d: %s on [%s]\n", + utf8_printf(stderr, "Error %d: %s on [%s]\n", sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), zQuery); goto end_data_xfer; @@ -2309,7 +2380,7 @@ static void tryToCloneData( n = sqlite3_column_count(pQuery); zInsert = sqlite3_malloc64(200 + nTable + n*3); if( zInsert==0 ){ - fprintf(stderr, "out of memory\n"); + raw_printf(stderr, "out of memory\n"); goto end_data_xfer; } sqlite3_snprintf(200+nTable,zInsert, @@ -2322,7 +2393,7 @@ static void tryToCloneData( memcpy(zInsert+i, ");", 3); rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0); if( rc ){ - fprintf(stderr, "Error %d: %s on [%s]\n", + utf8_printf(stderr, "Error %d: %s on [%s]\n", sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb), zQuery); goto end_data_xfer; @@ -2359,7 +2430,7 @@ static void tryToCloneData( } /* End for */ rc = sqlite3_step(pInsert); if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){ - fprintf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb), + utf8_printf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb)); } sqlite3_reset(pInsert); @@ -2376,7 +2447,7 @@ static void tryToCloneData( zTable); rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); if( rc ){ - fprintf(stderr, "Warning: cannot step \"%s\" backwards", zTable); + utf8_printf(stderr, "Warning: cannot step \"%s\" backwards", zTable); break; } } /* End for(k=0...) */ @@ -2412,7 +2483,7 @@ static void tryToCloneSchema( " WHERE %s", zWhere); rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); if( rc ){ - fprintf(stderr, "Error: (%d) %s on [%s]\n", + utf8_printf(stderr, "Error: (%d) %s on [%s]\n", sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), zQuery); goto end_schema_xfer; @@ -2423,7 +2494,7 @@ static void tryToCloneSchema( printf("%s... ", zName); fflush(stdout); sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg); if( zErrMsg ){ - fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql); + utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql); sqlite3_free(zErrMsg); zErrMsg = 0; } @@ -2439,7 +2510,7 @@ static void tryToCloneSchema( " WHERE %s ORDER BY rowid DESC", zWhere); rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); if( rc ){ - fprintf(stderr, "Error: (%d) %s on [%s]\n", + utf8_printf(stderr, "Error: (%d) %s on [%s]\n", sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), zQuery); goto end_schema_xfer; @@ -2450,7 +2521,7 @@ static void tryToCloneSchema( printf("%s... ", zName); fflush(stdout); sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg); if( zErrMsg ){ - fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql); + utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql); sqlite3_free(zErrMsg); zErrMsg = 0; } @@ -2474,12 +2545,12 @@ static void tryToClone(ShellState *p, const char *zNewDb){ int rc; sqlite3 *newDb = 0; if( access(zNewDb,0)==0 ){ - fprintf(stderr, "File \"%s\" already exists.\n", zNewDb); + utf8_printf(stderr, "File \"%s\" already exists.\n", zNewDb); return; } rc = sqlite3_open(zNewDb, &newDb); if( rc ){ - fprintf(stderr, "Cannot create output database: %s\n", + utf8_printf(stderr, "Cannot create output database: %s\n", sqlite3_errmsg(newDb)); }else{ sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0); @@ -2576,27 +2647,27 @@ static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){ } i = pFile->pMethods->xRead(pFile, aHdr, 100, 0); if( i!=SQLITE_OK ){ - fprintf(stderr, "unable to read database header\n"); + raw_printf(stderr, "unable to read database header\n"); return 1; } i = get2byteInt(aHdr+16); if( i==1 ) i = 65536; - fprintf(p->out, "%-20s %d\n", "database page size:", i); - fprintf(p->out, "%-20s %d\n", "write format:", aHdr[18]); - fprintf(p->out, "%-20s %d\n", "read format:", aHdr[19]); - fprintf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]); + utf8_printf(p->out, "%-20s %d\n", "database page size:", i); + utf8_printf(p->out, "%-20s %d\n", "write format:", aHdr[18]); + utf8_printf(p->out, "%-20s %d\n", "read format:", aHdr[19]); + utf8_printf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]); for(i=0; iout, "%-20s %u", aField[i].zName, val); + utf8_printf(p->out, "%-20s %u", aField[i].zName, val); switch( ofst ){ case 56: { - if( val==1 ) fprintf(p->out, " (utf8)"); - if( val==2 ) fprintf(p->out, " (utf16le)"); - if( val==3 ) fprintf(p->out, " (utf16be)"); + if( val==1 ) raw_printf(p->out, " (utf8)"); + if( val==2 ) raw_printf(p->out, " (utf16le)"); + if( val==3 ) raw_printf(p->out, " (utf16be)"); } } - fprintf(p->out, "\n"); + raw_printf(p->out, "\n"); } if( zDb==0 ){ zSchemaTab = sqlite3_mprintf("main.sqlite_master"); @@ -2609,7 +2680,7 @@ static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){ char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab); int val = db_int(p, zSql); sqlite3_free(zSql); - fprintf(p->out, "%-20s %d\n", aQuery[i].zName, val); + utf8_printf(p->out, "%-20s %d\n", aQuery[i].zName, val); } sqlite3_free(zSchemaTab); return 0; @@ -2620,7 +2691,7 @@ static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){ */ static int shellDatabaseError(sqlite3 *db){ const char *zErr = sqlite3_errmsg(db); - fprintf(stderr, "Error: %s\n", zErr); + utf8_printf(stderr, "Error: %s\n", zErr); return 1; } @@ -2628,7 +2699,7 @@ static int shellDatabaseError(sqlite3 *db){ ** Print an out-of-memory message to stderr and return 1. */ static int shellNomemError(void){ - fprintf(stderr, "Error: out of memory\n"); + raw_printf(stderr, "Error: out of memory\n"); return 1; } @@ -2688,7 +2759,7 @@ static int do_meta_command(char *zLine, ShellState *p){ while( z[0]=='-' ) z++; /* No options to process at this time */ { - fprintf(stderr, "unknown option: %s\n", azArg[j]); + utf8_printf(stderr, "unknown option: %s\n", azArg[j]); return 1; } }else if( zDestFile==0 ){ @@ -2697,25 +2768,25 @@ static int do_meta_command(char *zLine, ShellState *p){ zDb = zDestFile; zDestFile = azArg[j]; }else{ - fprintf(stderr, "too many arguments to .backup\n"); + raw_printf(stderr, "too many arguments to .backup\n"); return 1; } } if( zDestFile==0 ){ - fprintf(stderr, "missing FILENAME argument on .backup\n"); + raw_printf(stderr, "missing FILENAME argument on .backup\n"); return 1; } if( zDb==0 ) zDb = "main"; rc = sqlite3_open(zDestFile, &pDest); if( rc!=SQLITE_OK ){ - fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile); + utf8_printf(stderr, "Error: cannot open \"%s\"\n", zDestFile); sqlite3_close(pDest); return 1; } open_db(p, 0); pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb); if( pBackup==0 ){ - fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest)); + utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest)); sqlite3_close(pDest); return 1; } @@ -2724,7 +2795,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( rc==SQLITE_DONE ){ rc = 0; }else{ - fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest)); + utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest)); rc = 1; } sqlite3_close(pDest); @@ -2734,7 +2805,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( nArg==2 ){ bail_on_error = booleanValue(azArg[1]); }else{ - fprintf(stderr, "Usage: .bail on|off\n"); + raw_printf(stderr, "Usage: .bail on|off\n"); rc = 1; } }else @@ -2747,7 +2818,7 @@ static int do_meta_command(char *zLine, ShellState *p){ setTextMode(p->out); } }else{ - fprintf(stderr, "Usage: .binary on|off\n"); + raw_printf(stderr, "Usage: .binary on|off\n"); rc = 1; } }else @@ -2763,7 +2834,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( nArg==2 ){ p->countChanges = booleanValue(azArg[1]); }else{ - fprintf(stderr, "Usage: .changes on|off\n"); + raw_printf(stderr, "Usage: .changes on|off\n"); rc = 1; } }else @@ -2772,7 +2843,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( nArg==2 ){ tryToClone(p, azArg[1]); }else{ - fprintf(stderr, "Usage: .clone FILENAME\n"); + raw_printf(stderr, "Usage: .clone FILENAME\n"); rc = 1; } }else @@ -2790,7 +2861,7 @@ static int do_meta_command(char *zLine, ShellState *p){ data.cnt = 0; sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg); if( zErrMsg ){ - fprintf(stderr,"Error: %s\n", zErrMsg); + utf8_printf(stderr,"Error: %s\n", zErrMsg); sqlite3_free(zErrMsg); rc = 1; } @@ -2806,12 +2877,12 @@ static int do_meta_command(char *zLine, ShellState *p){ ** which causes immediate foreign key constraints to be violated. ** So disable foreign-key constraint enforcement to prevent problems. */ if( nArg!=1 && nArg!=2 ){ - fprintf(stderr, "Usage: .dump ?LIKE-PATTERN?\n"); + raw_printf(stderr, "Usage: .dump ?LIKE-PATTERN?\n"); rc = 1; goto meta_command_exit; } - fprintf(p->out, "PRAGMA foreign_keys=OFF;\n"); - fprintf(p->out, "BEGIN TRANSACTION;\n"); + raw_printf(p->out, "PRAGMA foreign_keys=OFF;\n"); + raw_printf(p->out, "BEGIN TRANSACTION;\n"); p->writableSchema = 0; sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0); p->nErr = 0; @@ -2846,19 +2917,19 @@ static int do_meta_command(char *zLine, ShellState *p){ } } if( p->writableSchema ){ - fprintf(p->out, "PRAGMA writable_schema=OFF;\n"); + raw_printf(p->out, "PRAGMA writable_schema=OFF;\n"); p->writableSchema = 0; } sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0); sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0); - fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n"); + raw_printf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n"); }else if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){ if( nArg==2 ){ p->echoOn = booleanValue(azArg[1]); }else{ - fprintf(stderr, "Usage: .echo on|off\n"); + raw_printf(stderr, "Usage: .echo on|off\n"); rc = 1; } }else @@ -2867,7 +2938,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( nArg==2 ){ p->autoEQP = booleanValue(azArg[1]); }else{ - fprintf(stderr, "Usage: .eqp on|off\n"); + raw_printf(stderr, "Usage: .eqp on|off\n"); rc = 1; } }else @@ -2917,7 +2988,7 @@ static int do_meta_command(char *zLine, ShellState *p){ char *zErrMsg = 0; int doStats = 0; if( nArg!=1 ){ - fprintf(stderr, "Usage: .fullschema\n"); + raw_printf(stderr, "Usage: .fullschema\n"); rc = 1; goto meta_command_exit; } @@ -2944,9 +3015,9 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_finalize(pStmt); } if( doStats==0 ){ - fprintf(p->out, "/* No STAT tables available */\n"); + raw_printf(p->out, "/* No STAT tables available */\n"); }else{ - fprintf(p->out, "ANALYZE sqlite_master;\n"); + raw_printf(p->out, "ANALYZE sqlite_master;\n"); sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'", callback, &data, &zErrMsg); data.mode = MODE_Insert; @@ -2959,7 +3030,7 @@ static int do_meta_command(char *zLine, ShellState *p){ data.zDestTable = "sqlite_stat4"; shell_exec(p->db, "SELECT * FROM sqlite_stat4", shell_callback, &data, &zErrMsg); - fprintf(p->out, "ANALYZE sqlite_master;\n"); + raw_printf(p->out, "ANALYZE sqlite_master;\n"); } }else @@ -2967,13 +3038,13 @@ static int do_meta_command(char *zLine, ShellState *p){ if( nArg==2 ){ p->showHeader = booleanValue(azArg[1]); }else{ - fprintf(stderr, "Usage: .headers on|off\n"); + raw_printf(stderr, "Usage: .headers on|off\n"); rc = 1; } }else if( c=='h' && strncmp(azArg[0], "help", n)==0 ){ - fprintf(p->out, "%s", zHelp); + utf8_printf(p->out, "%s", zHelp); }else if( c=='i' && strncmp(azArg[0], "import", n)==0 ){ @@ -2991,7 +3062,7 @@ static int do_meta_command(char *zLine, ShellState *p){ int (SQLITE_CDECL *xCloser)(FILE*); /* Func to close file */ if( nArg!=3 ){ - fprintf(stderr, "Usage: .import FILE TABLE\n"); + raw_printf(stderr, "Usage: .import FILE TABLE\n"); goto meta_command_exit; } zFile = azArg[1]; @@ -3001,17 +3072,18 @@ static int do_meta_command(char *zLine, ShellState *p){ open_db(p, 0); nSep = strlen30(p->colSeparator); if( nSep==0 ){ - fprintf(stderr, "Error: non-null column separator required for import\n"); + raw_printf(stderr, + "Error: non-null column separator required for import\n"); return 1; } if( nSep>1 ){ - fprintf(stderr, "Error: multi-character column separators not allowed" + raw_printf(stderr, "Error: multi-character column separators not allowed" " for import\n"); return 1; } nSep = strlen30(p->rowSeparator); if( nSep==0 ){ - fprintf(stderr, "Error: non-null row separator required for import\n"); + raw_printf(stderr, "Error: non-null row separator required for import\n"); return 1; } if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf)==0 ){ @@ -3023,7 +3095,7 @@ static int do_meta_command(char *zLine, ShellState *p){ nSep = strlen30(p->rowSeparator); } if( nSep>1 ){ - fprintf(stderr, "Error: multi-character row separators not allowed" + raw_printf(stderr, "Error: multi-character row separators not allowed" " for import\n"); return 1; } @@ -3031,7 +3103,7 @@ static int do_meta_command(char *zLine, ShellState *p){ sCtx.nLine = 1; if( sCtx.zFile[0]=='|' ){ #ifdef SQLITE_OMIT_POPEN - fprintf(stderr, "Error: pipes are not supported in this OS\n"); + raw_printf(stderr, "Error: pipes are not supported in this OS\n"); return 1; #else sCtx.in = popen(sCtx.zFile+1, "r"); @@ -3048,14 +3120,14 @@ static int do_meta_command(char *zLine, ShellState *p){ xRead = csv_read_one_field; } if( sCtx.in==0 ){ - fprintf(stderr, "Error: cannot open \"%s\"\n", zFile); + utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile); return 1; } sCtx.cColSep = p->colSeparator[0]; sCtx.cRowSep = p->rowSeparator[0]; zSql = sqlite3_mprintf("SELECT * FROM %s", zTable); if( zSql==0 ){ - fprintf(stderr, "Error: out of memory\n"); + raw_printf(stderr, "Error: out of memory\n"); xCloser(sCtx.in); return 1; } @@ -3074,14 +3146,14 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_free(zCreate); sqlite3_free(sCtx.z); xCloser(sCtx.in); - fprintf(stderr,"%s: empty file\n", sCtx.zFile); + utf8_printf(stderr,"%s: empty file\n", sCtx.zFile); return 1; } zCreate = sqlite3_mprintf("%z\n)", zCreate); rc = sqlite3_exec(p->db, zCreate, 0, 0, 0); sqlite3_free(zCreate); if( rc ){ - fprintf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable, + utf8_printf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable, sqlite3_errmsg(p->db)); sqlite3_free(sCtx.z); xCloser(sCtx.in); @@ -3092,7 +3164,7 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_free(zSql); if( rc ){ if (pStmt) sqlite3_finalize(pStmt); - fprintf(stderr,"Error: %s\n", sqlite3_errmsg(p->db)); + utf8_printf(stderr,"Error: %s\n", sqlite3_errmsg(p->db)); xCloser(sCtx.in); return 1; } @@ -3102,7 +3174,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( nCol==0 ) return 0; /* no columns, no error */ zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 ); if( zSql==0 ){ - fprintf(stderr, "Error: out of memory\n"); + raw_printf(stderr, "Error: out of memory\n"); xCloser(sCtx.in); return 1; } @@ -3117,7 +3189,7 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); sqlite3_free(zSql); if( rc ){ - fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db)); + utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db)); if (pStmt) sqlite3_finalize(pStmt); xCloser(sCtx.in); return 1; @@ -3141,7 +3213,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break; sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT); if( idb)); + utf8_printf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile, + startLine, sqlite3_errmsg(p->db)); } } }while( sCtx.cTerm!=EOF ); @@ -3204,16 +3276,17 @@ static int do_meta_command(char *zLine, ShellState *p){ ); zShellStatic = 0; }else{ - fprintf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n"); + raw_printf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n"); rc = 1; goto meta_command_exit; } if( zErrMsg ){ - fprintf(stderr,"Error: %s\n", zErrMsg); + utf8_printf(stderr,"Error: %s\n", zErrMsg); sqlite3_free(zErrMsg); rc = 1; }else if( rc != SQLITE_OK ){ - fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n"); + raw_printf(stderr, + "Error: querying sqlite_master and sqlite_temp_master\n"); rc = 1; } }else @@ -3231,7 +3304,7 @@ static int do_meta_command(char *zLine, ShellState *p){ }else{ iotrace = fopen(azArg[1], "w"); if( iotrace==0 ){ - fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]); + utf8_printf(stderr, "Error: cannot open \"%s\"\n", azArg[1]); sqlite3IoTrace = 0; rc = 1; }else{ @@ -3266,7 +3339,7 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_limit(p->db, aLimit[i].limitCode, -1)); } }else if( nArg>3 ){ - fprintf(stderr, "Usage: .limit NAME ?NEW-VALUE?\n"); + raw_printf(stderr, "Usage: .limit NAME ?NEW-VALUE?\n"); rc = 1; goto meta_command_exit; }else{ @@ -3277,14 +3350,14 @@ static int do_meta_command(char *zLine, ShellState *p){ if( iLimit<0 ){ iLimit = i; }else{ - fprintf(stderr, "ambiguous limit: \"%s\"\n", azArg[1]); + utf8_printf(stderr, "ambiguous limit: \"%s\"\n", azArg[1]); rc = 1; goto meta_command_exit; } } } if( iLimit<0 ){ - fprintf(stderr, "unknown limit: \"%s\"\n" + utf8_printf(stderr, "unknown limit: \"%s\"\n" "enter \".limits\" with no arguments for a list.\n", azArg[1]); rc = 1; @@ -3304,7 +3377,7 @@ static int do_meta_command(char *zLine, ShellState *p){ const char *zFile, *zProc; char *zErrMsg = 0; if( nArg<2 ){ - fprintf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n"); + raw_printf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n"); rc = 1; goto meta_command_exit; } @@ -3313,7 +3386,7 @@ static int do_meta_command(char *zLine, ShellState *p){ open_db(p, 0); rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg); if( rc!=SQLITE_OK ){ - fprintf(stderr, "Error: %s\n", zErrMsg); + utf8_printf(stderr, "Error: %s\n", zErrMsg); sqlite3_free(zErrMsg); rc = 1; } @@ -3322,7 +3395,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( c=='l' && strncmp(azArg[0], "log", n)==0 ){ if( nArg!=2 ){ - fprintf(stderr, "Usage: .log FILENAME\n"); + raw_printf(stderr, "Usage: .log FILENAME\n"); rc = 1; }else{ const char *zFile = azArg[1]; @@ -3361,7 +3434,7 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit); sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record); }else { - fprintf(stderr,"Error: mode should be one of: " + raw_printf(stderr, "Error: mode should be one of: " "ascii column csv html insert line list tabs tcl\n"); rc = 1; } @@ -3372,7 +3445,7 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_snprintf(sizeof(p->nullValue), p->nullValue, "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]); }else{ - fprintf(stderr, "Usage: .nullvalue STRING\n"); + raw_printf(stderr, "Usage: .nullvalue STRING\n"); rc = 1; } }else @@ -3401,13 +3474,13 @@ static int do_meta_command(char *zLine, ShellState *p){ ){ const char *zFile = nArg>=2 ? azArg[1] : "stdout"; if( nArg>2 ){ - fprintf(stderr, "Usage: .%s FILE\n", azArg[0]); + utf8_printf(stderr, "Usage: .%s FILE\n", azArg[0]); rc = 1; goto meta_command_exit; } if( n>1 && strncmp(azArg[0], "once", n)==0 ){ if( nArg<2 ){ - fprintf(stderr, "Usage: .once FILE\n"); + raw_printf(stderr, "Usage: .once FILE\n"); rc = 1; goto meta_command_exit; } @@ -3418,13 +3491,13 @@ static int do_meta_command(char *zLine, ShellState *p){ output_reset(p); if( zFile[0]=='|' ){ #ifdef SQLITE_OMIT_POPEN - fprintf(stderr,"Error: pipes are not supported in this OS\n"); + raw_printf(stderr, "Error: pipes are not supported in this OS\n"); rc = 1; p->out = stdout; #else p->out = popen(zFile + 1, "w"); if( p->out==0 ){ - fprintf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1); + utf8_printf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1); p->out = stdout; rc = 1; }else{ @@ -3435,7 +3508,7 @@ static int do_meta_command(char *zLine, ShellState *p){ p->out = output_file_open(zFile); if( p->out==0 ){ if( strcmp(zFile,"off")!=0 ){ - fprintf(stderr,"Error: cannot write to \"%s\"\n", zFile); + utf8_printf(stderr,"Error: cannot write to \"%s\"\n", zFile); } p->out = stdout; rc = 1; @@ -3448,10 +3521,10 @@ static int do_meta_command(char *zLine, ShellState *p){ if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){ int i; for(i=1; i1 ) fprintf(p->out, " "); - fprintf(p->out, "%s", azArg[i]); + if( i>1 ) raw_printf(p->out, " "); + utf8_printf(p->out, "%s", azArg[i]); } - fprintf(p->out, "\n"); + raw_printf(p->out, "\n"); }else if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){ @@ -3470,13 +3543,13 @@ static int do_meta_command(char *zLine, ShellState *p){ if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){ FILE *alt; if( nArg!=2 ){ - fprintf(stderr, "Usage: .read FILE\n"); + raw_printf(stderr, "Usage: .read FILE\n"); rc = 1; goto meta_command_exit; } alt = fopen(azArg[1], "rb"); if( alt==0 ){ - fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]); + utf8_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]); rc = 1; }else{ rc = process_input(p, alt); @@ -3498,20 +3571,20 @@ static int do_meta_command(char *zLine, ShellState *p){ zSrcFile = azArg[2]; zDb = azArg[1]; }else{ - fprintf(stderr, "Usage: .restore ?DB? FILE\n"); + raw_printf(stderr, "Usage: .restore ?DB? FILE\n"); rc = 1; goto meta_command_exit; } rc = sqlite3_open(zSrcFile, &pSrc); if( rc!=SQLITE_OK ){ - fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile); + utf8_printf(stderr, "Error: cannot open \"%s\"\n", zSrcFile); sqlite3_close(pSrc); return 1; } open_db(p, 0); pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main"); if( pBackup==0 ){ - fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db)); + utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db)); sqlite3_close(pSrc); return 1; } @@ -3526,10 +3599,10 @@ static int do_meta_command(char *zLine, ShellState *p){ if( rc==SQLITE_DONE ){ rc = 0; }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){ - fprintf(stderr, "Error: source database is busy\n"); + raw_printf(stderr, "Error: source database is busy\n"); rc = 1; }else{ - fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db)); + utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db)); rc = 1; } sqlite3_close(pSrc); @@ -3540,10 +3613,10 @@ static int do_meta_command(char *zLine, ShellState *p){ if( nArg==2 ){ p->scanstatsOn = booleanValue(azArg[1]); #ifndef SQLITE_ENABLE_STMT_SCANSTATUS - fprintf(stderr, "Warning: .scanstats not available in this build.\n"); + raw_printf(stderr, "Warning: .scanstats not available in this build.\n"); #endif }else{ - fprintf(stderr, "Usage: .scanstats on|off\n"); + raw_printf(stderr, "Usage: .scanstats on|off\n"); rc = 1; } }else @@ -3610,16 +3683,16 @@ static int do_meta_command(char *zLine, ShellState *p){ callback, &data, &zErrMsg ); }else{ - fprintf(stderr, "Usage: .schema ?LIKE-PATTERN?\n"); + raw_printf(stderr, "Usage: .schema ?LIKE-PATTERN?\n"); rc = 1; goto meta_command_exit; } if( zErrMsg ){ - fprintf(stderr,"Error: %s\n", zErrMsg); + utf8_printf(stderr,"Error: %s\n", zErrMsg); sqlite3_free(zErrMsg); rc = 1; }else if( rc != SQLITE_OK ){ - fprintf(stderr,"Error: querying schema information\n"); + raw_printf(stderr,"Error: querying schema information\n"); rc = 1; }else{ rc = 0; @@ -3643,7 +3716,7 @@ static int do_meta_command(char *zLine, ShellState *p){ int i, v; for(i=1; iout, "%s: %d 0x%x\n", azArg[i], v, v); + utf8_printf(p->out, "%s: %d 0x%x\n", azArg[i], v, v); } } if( strncmp(azArg[0]+9, "integer", n-9)==0 ){ @@ -3652,7 +3725,7 @@ static int do_meta_command(char *zLine, ShellState *p){ char zBuf[200]; v = integerValue(azArg[i]); sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v); - fprintf(p->out, "%s", zBuf); + utf8_printf(p->out, "%s", zBuf); } } }else @@ -3660,7 +3733,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){ if( nArg<2 || nArg>3 ){ - fprintf(stderr, "Usage: .separator COL ?ROW?\n"); + raw_printf(stderr, "Usage: .separator COL ?ROW?\n"); rc = 1; } if( nArg>=2 ){ @@ -3679,7 +3752,7 @@ static int do_meta_command(char *zLine, ShellState *p){ char *zCmd; int i, x; if( nArg<2 ){ - fprintf(stderr, "Usage: .system COMMAND\n"); + raw_printf(stderr, "Usage: .system COMMAND\n"); rc = 1; goto meta_command_exit; } @@ -3690,45 +3763,45 @@ static int do_meta_command(char *zLine, ShellState *p){ } x = system(zCmd); sqlite3_free(zCmd); - if( x ) fprintf(stderr, "System command returns %d\n", x); + if( x ) raw_printf(stderr, "System command returns %d\n", x); }else if( c=='s' && strncmp(azArg[0], "show", n)==0 ){ int i; if( nArg!=1 ){ - fprintf(stderr, "Usage: .show\n"); + raw_printf(stderr, "Usage: .show\n"); rc = 1; goto meta_command_exit; } - fprintf(p->out,"%12.12s: %s\n","echo", p->echoOn ? "on" : "off"); - fprintf(p->out,"%12.12s: %s\n","eqp", p->autoEQP ? "on" : "off"); - fprintf(p->out,"%9.9s: %s\n","explain", p->normalMode.valid ? "on" :"off"); - fprintf(p->out,"%12.12s: %s\n","headers", p->showHeader ? "on" : "off"); - fprintf(p->out,"%12.12s: %s\n","mode", modeDescr[p->mode]); - fprintf(p->out,"%12.12s: ", "nullvalue"); + utf8_printf(p->out, "%12.12s: %s\n","echo", p->echoOn ? "on" : "off"); + utf8_printf(p->out, "%12.12s: %s\n","eqp", p->autoEQP ? "on" : "off"); + utf8_printf(p->out,"%9.9s: %s\n","explain",p->normalMode.valid?"on":"off"); + utf8_printf(p->out,"%12.12s: %s\n","headers", p->showHeader ? "on" : "off"); + utf8_printf(p->out, "%12.12s: %s\n","mode", modeDescr[p->mode]); + utf8_printf(p->out, "%12.12s: ", "nullvalue"); output_c_string(p->out, p->nullValue); - fprintf(p->out, "\n"); - fprintf(p->out,"%12.12s: %s\n","output", + raw_printf(p->out, "\n"); + utf8_printf(p->out,"%12.12s: %s\n","output", strlen30(p->outfile) ? p->outfile : "stdout"); - fprintf(p->out,"%12.12s: ", "colseparator"); + utf8_printf(p->out,"%12.12s: ", "colseparator"); output_c_string(p->out, p->colSeparator); - fprintf(p->out, "\n"); - fprintf(p->out,"%12.12s: ", "rowseparator"); + raw_printf(p->out, "\n"); + utf8_printf(p->out,"%12.12s: ", "rowseparator"); output_c_string(p->out, p->rowSeparator); - fprintf(p->out, "\n"); - fprintf(p->out,"%12.12s: %s\n","stats", p->statsOn ? "on" : "off"); - fprintf(p->out,"%12.12s: ","width"); + raw_printf(p->out, "\n"); + utf8_printf(p->out, "%12.12s: %s\n","stats", p->statsOn ? "on" : "off"); + utf8_printf(p->out, "%12.12s: ", "width"); for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) { - fprintf(p->out,"%d ",p->colWidth[i]); + raw_printf(p->out, "%d ", p->colWidth[i]); } - fprintf(p->out,"\n"); + raw_printf(p->out, "\n"); }else if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){ if( nArg==2 ){ p->statsOn = booleanValue(azArg[1]); }else{ - fprintf(stderr, "Usage: .stats on|off\n"); + raw_printf(stderr, "Usage: .stats on|off\n"); rc = 1; } }else @@ -3826,9 +3899,10 @@ static int do_meta_command(char *zLine, ShellState *p){ for(i=0; iout, "%s%-*s", zSp, maxlen, azResult[j] ? azResult[j]:""); + utf8_printf(p->out, "%s%-*s", zSp, maxlen, + azResult[j] ? azResult[j]:""); } - fprintf(p->out, "\n"); + raw_printf(p->out, "\n"); } } @@ -3871,7 +3945,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( testctrl<0 ){ testctrl = aCtrl[i].ctrlCode; }else{ - fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]); + utf8_printf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]); testctrl = -1; break; } @@ -3879,7 +3953,7 @@ static int do_meta_command(char *zLine, ShellState *p){ } if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]); if( (testctrlSQLITE_TESTCTRL_LAST) ){ - fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]); + utf8_printf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]); }else{ switch(testctrl){ @@ -3889,9 +3963,9 @@ static int do_meta_command(char *zLine, ShellState *p){ if( nArg==3 ){ int opt = (int)strtol(azArg[2], 0, 0); rc2 = sqlite3_test_control(testctrl, p->db, opt); - fprintf(p->out, "%d (0x%08x)\n", rc2, rc2); + raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); } else { - fprintf(stderr,"Error: testctrl %s takes a single int option\n", + utf8_printf(stderr,"Error: testctrl %s takes a single int option\n", azArg[1]); } break; @@ -3903,9 +3977,10 @@ static int do_meta_command(char *zLine, ShellState *p){ case SQLITE_TESTCTRL_BYTEORDER: if( nArg==2 ){ rc2 = sqlite3_test_control(testctrl); - fprintf(p->out, "%d (0x%08x)\n", rc2, rc2); + raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); } else { - fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]); + utf8_printf(stderr,"Error: testctrl %s takes no options\n", + azArg[1]); } break; @@ -3914,9 +3989,9 @@ static int do_meta_command(char *zLine, ShellState *p){ if( nArg==3 ){ unsigned int opt = (unsigned int)integerValue(azArg[2]); rc2 = sqlite3_test_control(testctrl, opt); - fprintf(p->out, "%d (0x%08x)\n", rc2, rc2); + raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); } else { - fprintf(stderr,"Error: testctrl %s takes a single unsigned" + utf8_printf(stderr,"Error: testctrl %s takes a single unsigned" " int option\n", azArg[1]); } break; @@ -3928,9 +4003,9 @@ static int do_meta_command(char *zLine, ShellState *p){ if( nArg==3 ){ int opt = booleanValue(azArg[2]); rc2 = sqlite3_test_control(testctrl, opt); - fprintf(p->out, "%d (0x%08x)\n", rc2, rc2); + raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); } else { - fprintf(stderr,"Error: testctrl %s takes a single int option\n", + utf8_printf(stderr,"Error: testctrl %s takes a single int option\n", azArg[1]); } break; @@ -3941,10 +4016,11 @@ static int do_meta_command(char *zLine, ShellState *p){ if( nArg==3 ){ const char *opt = azArg[2]; rc2 = sqlite3_test_control(testctrl, opt); - fprintf(p->out, "%d (0x%08x)\n", rc2, rc2); + raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); } else { - fprintf(stderr,"Error: testctrl %s takes a single char * option\n", - azArg[1]); + utf8_printf(stderr, + "Error: testctrl %s takes a single char * option\n", + azArg[1]); } break; #endif @@ -3955,9 +4031,9 @@ static int do_meta_command(char *zLine, ShellState *p){ azArg[2], integerValue(azArg[3]), integerValue(azArg[4])); - fprintf(p->out, "%d (0x%08x)\n", rc2, rc2); + raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); }else{ - fprintf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n"); + raw_printf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n"); } break; @@ -3966,8 +4042,9 @@ static int do_meta_command(char *zLine, ShellState *p){ case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS: case SQLITE_TESTCTRL_SCRATCHMALLOC: default: - fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n", - azArg[1]); + utf8_printf(stderr, + "Error: CLI support for testctrl %s not implemented\n", + azArg[1]); break; } } @@ -3982,11 +4059,11 @@ static int do_meta_command(char *zLine, ShellState *p){ if( nArg==2 ){ enableTimer = booleanValue(azArg[1]); if( enableTimer && !HAS_TIMER ){ - fprintf(stderr, "Error: timer not available on this system.\n"); + raw_printf(stderr, "Error: timer not available on this system.\n"); enableTimer = 0; } }else{ - fprintf(stderr, "Usage: .timer on|off\n"); + raw_printf(stderr, "Usage: .timer on|off\n"); rc = 1; } }else @@ -3994,7 +4071,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){ open_db(p, 0); if( nArg!=2 ){ - fprintf(stderr, "Usage: .trace FILE|off\n"); + raw_printf(stderr, "Usage: .trace FILE|off\n"); rc = 1; goto meta_command_exit; } @@ -4012,26 +4089,26 @@ static int do_meta_command(char *zLine, ShellState *p){ #if SQLITE_USER_AUTHENTICATION if( c=='u' && strncmp(azArg[0], "user", n)==0 ){ if( nArg<2 ){ - fprintf(stderr, "Usage: .user SUBCOMMAND ...\n"); + raw_printf(stderr, "Usage: .user SUBCOMMAND ...\n"); rc = 1; goto meta_command_exit; } open_db(p, 0); if( strcmp(azArg[1],"login")==0 ){ if( nArg!=4 ){ - fprintf(stderr, "Usage: .user login USER PASSWORD\n"); + raw_printf(stderr, "Usage: .user login USER PASSWORD\n"); rc = 1; goto meta_command_exit; } rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3], (int)strlen(azArg[3])); if( rc ){ - fprintf(stderr, "Authentication failed for user %s\n", azArg[2]); + utf8_printf(stderr, "Authentication failed for user %s\n", azArg[2]); rc = 1; } }else if( strcmp(azArg[1],"add")==0 ){ if( nArg!=5 ){ - fprintf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n"); + raw_printf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n"); rc = 1; goto meta_command_exit; } @@ -4039,12 +4116,12 @@ static int do_meta_command(char *zLine, ShellState *p){ azArg[3], (int)strlen(azArg[3]), booleanValue(azArg[4])); if( rc ){ - fprintf(stderr, "User-Add failed: %d\n", rc); + raw_printf(stderr, "User-Add failed: %d\n", rc); rc = 1; } }else if( strcmp(azArg[1],"edit")==0 ){ if( nArg!=5 ){ - fprintf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n"); + raw_printf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n"); rc = 1; goto meta_command_exit; } @@ -4052,22 +4129,22 @@ static int do_meta_command(char *zLine, ShellState *p){ azArg[3], (int)strlen(azArg[3]), booleanValue(azArg[4])); if( rc ){ - fprintf(stderr, "User-Edit failed: %d\n", rc); + raw_printf(stderr, "User-Edit failed: %d\n", rc); rc = 1; } }else if( strcmp(azArg[1],"delete")==0 ){ if( nArg!=3 ){ - fprintf(stderr, "Usage: .user delete USER\n"); + raw_printf(stderr, "Usage: .user delete USER\n"); rc = 1; goto meta_command_exit; } rc = sqlite3_user_delete(p->db, azArg[2]); if( rc ){ - fprintf(stderr, "User-Delete failed: %d\n", rc); + raw_printf(stderr, "User-Delete failed: %d\n", rc); rc = 1; } }else{ - fprintf(stderr, "Usage: .user login|add|edit|delete ...\n"); + raw_printf(stderr, "Usage: .user login|add|edit|delete ...\n"); rc = 1; goto meta_command_exit; } @@ -4075,7 +4152,7 @@ static int do_meta_command(char *zLine, ShellState *p){ #endif /* SQLITE_USER_AUTHENTICATION */ if( c=='v' && strncmp(azArg[0], "version", n)==0 ){ - fprintf(p->out, "SQLite %s %s\n" /*extra-version-info*/, + utf8_printf(p->out, "SQLite %s %s\n" /*extra-version-info*/, sqlite3_libversion(), sqlite3_sourceid()); }else @@ -4085,10 +4162,10 @@ static int do_meta_command(char *zLine, ShellState *p){ if( p->db ){ sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFS_POINTER, &pVfs); if( pVfs ){ - fprintf(p->out, "vfs.zName = \"%s\"\n", pVfs->zName); - fprintf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion); - fprintf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile); - fprintf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname); + utf8_printf(p->out, "vfs.zName = \"%s\"\n", pVfs->zName); + raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion); + raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile); + raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname); } } }else @@ -4099,7 +4176,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( p->db ){ sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName); if( zVfsName ){ - fprintf(p->out, "%s\n", zVfsName); + utf8_printf(p->out, "%s\n", zVfsName); sqlite3_free(zVfsName); } } @@ -4121,7 +4198,7 @@ static int do_meta_command(char *zLine, ShellState *p){ }else { - fprintf(stderr, "Error: unknown command or invalid arguments: " + utf8_printf(stderr, "Error: unknown command or invalid arguments: " " \"%s\". Enter \".help\" for help\n", azArg[0]); rc = 1; } @@ -4256,7 +4333,7 @@ static int process_input(ShellState *p, FILE *in){ nAlloc = nSql+nLine+100; zSql = realloc(zSql, nAlloc); if( zSql==0 ){ - fprintf(stderr, "Error: out of memory\n"); + raw_printf(stderr, "Error: out of memory\n"); exit(1); } } @@ -4290,15 +4367,15 @@ static int process_input(ShellState *p, FILE *in){ sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:"); } if( zErrMsg!=0 ){ - fprintf(stderr, "%s %s\n", zPrefix, zErrMsg); + utf8_printf(stderr, "%s %s\n", zPrefix, zErrMsg); sqlite3_free(zErrMsg); zErrMsg = 0; }else{ - fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db)); + utf8_printf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db)); } errCnt++; }else if( p->countChanges ){ - fprintf(p->out, "changes: %3d total_changes: %d\n", + raw_printf(p->out, "changes: %3d total_changes: %d\n", sqlite3_changes(p->db), sqlite3_total_changes(p->db)); } nSql = 0; @@ -4313,7 +4390,7 @@ static int process_input(ShellState *p, FILE *in){ } if( nSql ){ if( !_all_whitespace(zSql) ){ - fprintf(stderr, "Error: incomplete SQL: %s\n", zSql); + utf8_printf(stderr, "Error: incomplete SQL: %s\n", zSql); errCnt++; } } @@ -4404,7 +4481,7 @@ static void process_sqliterc( if (sqliterc == NULL) { home_dir = find_home_dir(); if( home_dir==0 ){ - fprintf(stderr, "-- warning: cannot find home directory;" + raw_printf(stderr, "-- warning: cannot find home directory;" " cannot read ~/.sqliterc\n"); return; } @@ -4415,7 +4492,7 @@ static void process_sqliterc( in = fopen(sqliterc,"rb"); if( in ){ if( stdin_is_interactive ){ - fprintf(stderr,"-- Loading resources from %s\n",sqliterc); + utf8_printf(stderr,"-- Loading resources from %s\n",sqliterc); } process_input(p,in); fclose(in); @@ -4462,14 +4539,14 @@ static const char zOptions[] = #endif ; static void usage(int showDetail){ - fprintf(stderr, + utf8_printf(stderr, "Usage: %s [OPTIONS] FILENAME [SQL]\n" "FILENAME is the name of an SQLite database. A new database is created\n" "if the file does not previously exist.\n", Argv0); if( showDetail ){ - fprintf(stderr, "OPTIONS include:\n%s", zOptions); + utf8_printf(stderr, "OPTIONS include:\n%s", zOptions); }else{ - fprintf(stderr, "Use the -help option for additional information\n"); + raw_printf(stderr, "Use the -help option for additional information\n"); } exit(1); } @@ -4517,7 +4594,7 @@ static void printBold(const char *zText){ */ static char *cmdline_option_value(int argc, char **argv, int i){ if( i==argc ){ - fprintf(stderr, "%s: Error: missing argument to %s\n", + utf8_printf(stderr, "%s: Error: missing argument to %s\n", argv[0], argv[argc-1]); exit(1); } @@ -4537,7 +4614,7 @@ int SQLITE_CDECL main(int argc, char **argv){ #if USE_SYSTEM_SQLITE+0!=1 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){ - fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n", + utf8_printf(stderr, "SQLite header and source version mismatch\n%s\n%s\n", sqlite3_sourceid(), SQLITE_SOURCE_ID); exit(1); } @@ -4547,6 +4624,7 @@ int SQLITE_CDECL main(int argc, char **argv){ Argv0 = argv[0]; main_init(&data); stdin_is_interactive = isatty(0); + stdout_is_console = isatty(1); /* Make sure we have a valid signal handler early, before anything ** else is done. @@ -4585,7 +4663,7 @@ int SQLITE_CDECL main(int argc, char **argv){ nCmd++; azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd); if( azCmd==0 ){ - fprintf(stderr, "out of memory\n"); + raw_printf(stderr, "out of memory\n"); exit(1); } azCmd[nCmd-1] = z; @@ -4667,7 +4745,7 @@ int SQLITE_CDECL main(int argc, char **argv){ if( pVfs ){ sqlite3_vfs_register(pVfs, 1); }else{ - fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]); + utf8_printf(stderr, "no such VFS: \"%s\"\n", argv[i]); exit(1); } } @@ -4677,7 +4755,7 @@ int SQLITE_CDECL main(int argc, char **argv){ data.zDbFilename = ":memory:"; warnInmemoryDb = argc==1; #else - fprintf(stderr,"%s: Error: no database filename specified\n", Argv0); + utf8_printf(stderr,"%s: Error: no database filename specified\n", Argv0); return 1; #endif } @@ -4799,16 +4877,16 @@ int SQLITE_CDECL main(int argc, char **argv){ open_db(&data, 0); rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg); if( zErrMsg!=0 ){ - fprintf(stderr,"Error: %s\n", zErrMsg); + utf8_printf(stderr,"Error: %s\n", zErrMsg); if( bail_on_error ) return rc!=0 ? rc : 1; }else if( rc!=0 ){ - fprintf(stderr,"Error: unable to process SQL \"%s\"\n", z); + utf8_printf(stderr,"Error: unable to process SQL \"%s\"\n", z); if( bail_on_error ) return rc; } } }else{ - fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z); - fprintf(stderr,"Use -help for a list of options.\n"); + utf8_printf(stderr,"%s: Error: unknown option: %s\n", Argv0, z); + raw_printf(stderr,"Use -help for a list of options.\n"); return 1; } } @@ -4826,10 +4904,10 @@ int SQLITE_CDECL main(int argc, char **argv){ open_db(&data, 0); rc = shell_exec(data.db, azCmd[i], shell_callback, &data, &zErrMsg); if( zErrMsg!=0 ){ - fprintf(stderr,"Error: %s\n", zErrMsg); + utf8_printf(stderr,"Error: %s\n", zErrMsg); return rc!=0 ? rc : 1; }else if( rc!=0 ){ - fprintf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]); + utf8_printf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]); return rc; } } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 4249ef768a..c01bbc7869 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -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) @@ -1522,7 +1522,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 */ }; @@ -1932,7 +1932,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 */ @@ -2732,6 +2732,7 @@ struct Parse { int nSet; /* Number of sets used so far */ int nOnce; /* Number of OP_Once instructions so far */ int nOpAlloc; /* Number of slots allocated for Vdbe.aOp[] */ + int szOpAlloc; /* Bytes of memory space allocated for Vdbe.aOp[] */ int iFixedOp; /* Never back out opcodes iFixedOp-1 or earlier */ int ckBase; /* Base register of data during check constraints */ int iSelfTab; /* Table of an index whose exprs are being coded */ @@ -2963,9 +2964,9 @@ struct StrAccum { sqlite3 *db; /* Optional database for lookaside. Can be NULL */ char *zBase; /* A base allocation. Not from malloc. */ char *zText; /* The string collected so far */ - int nChar; /* Length of the string so far */ - int nAlloc; /* Amount of space allocated in zText */ - int mxAlloc; /* Maximum allowed allocation. 0 for no malloc usage */ + u32 nChar; /* Length of the string so far */ + u32 nAlloc; /* Amount of space allocated in zText */ + u32 mxAlloc; /* Maximum allowed allocation. 0 for no malloc usage */ u8 accError; /* STRACCUM_NOMEM or STRACCUM_TOOBIG */ u8 bMalloced; /* zText points to allocated space */ }; @@ -3348,7 +3349,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); @@ -3461,6 +3466,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*); @@ -3698,6 +3704,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[]; diff --git a/src/test_fs.c b/src/test_fs.c index ab6bed8a95..45db0b53b8 100644 --- a/src/test_fs.c +++ b/src/test_fs.c @@ -70,7 +70,7 @@ #include #include -#if SQLITE_OS_UNIX +#if SQLITE_OS_UNIX || defined(__MINGW_H) # include # include # ifndef DIRENT @@ -79,7 +79,9 @@ #endif #if SQLITE_OS_WIN # include -# include "test_windirent.h" +# if !defined(__MINGW_H) +# include "test_windirent.h" +# endif # ifndef S_ISREG # define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) # endif @@ -231,7 +233,14 @@ static int fsdirNext(sqlite3_vtab_cursor *cur){ if( pCsr->pDir ){ struct DIRENT *pRes = 0; +#if defined(__MINGW_H) + pRes = readdir(pCsr->pDir); + if( pRes!=0 ){ + memcpy(&pCsr->entry, pRes, sizeof(struct DIRENT)); + } +#else readdir_r(pCsr->pDir, &pCsr->entry, &pRes); +#endif if( pRes==0 ){ closedir(pCsr->pDir); pCsr->pDir = 0; diff --git a/src/utf.c b/src/utf.c index 25f4dadf0c..ee367c1399 100644 --- a/src/utf.c +++ b/src/utf.c @@ -37,13 +37,13 @@ #include #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 diff --git a/src/vdbe.c b/src/vdbe.c index 894758a01c..5acb3b3137 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1996,21 +1996,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); @@ -2019,15 +2019,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 ){ @@ -2525,7 +2524,7 @@ case OP_Column: { goto op_column_error; } }else{ - VVA_ONLY( t = 0; ) /* Only needed by assert() statements */ + t = 0; } /* If after trying to extract new entries from the header, nHdrParsed is @@ -3403,7 +3402,7 @@ open_cursor_set_hints: assert( OPFLAG_BULKCSR==BTREE_BULKLOAD ); assert( OPFLAG_SEEKEQ==BTREE_SEEK_EQ ); testcase( pOp->p5 & OPFLAG_BULKCSR ); -#ifdef SQLITE_ENABLE_CURSOR_HINT +#ifdef SQLITE_ENABLE_CURSOR_HINTS testcase( pOp->p2 & OPFLAG_SEEKEQ ); #endif sqlite3BtreeCursorHintFlags(pCur->uc.pCursor, diff --git a/src/vdbeaux.c b/src/vdbeaux.c index a266177ac5..dbbb2a6ccb 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -35,6 +35,7 @@ Vdbe *sqlite3VdbeCreate(Parse *pParse){ assert( pParse->aLabel==0 ); assert( pParse->nLabel==0 ); assert( pParse->nOpAlloc==0 ); + assert( pParse->szOpAlloc==0 ); return p; } @@ -124,7 +125,8 @@ static int growOpArray(Vdbe *v, int nOp){ assert( nNew>=(p->nOpAlloc+nOp) ); pNew = sqlite3DbRealloc(p->db, v->aOp, nNew*sizeof(Op)); if( pNew ){ - p->nOpAlloc = sqlite3DbMallocSize(p->db, pNew)/sizeof(Op); + p->szOpAlloc = sqlite3DbMallocSize(p->db, pNew); + p->nOpAlloc = p->szOpAlloc/sizeof(Op); v->aOp = pNew; } return (pNew ? SQLITE_OK : SQLITE_NOMEM); @@ -1846,20 +1848,27 @@ void sqlite3VdbeMakeReady( */ nMem += nCursor; - /* Allocate space for memory registers, SQL variables, VDBE cursors and - ** an array to marshal SQL function arguments in. + /* zCsr will initially point to nFree bytes of unused space at the + ** end of the opcode array, p->aOp. The computation of nFree is + ** conservative - it might be smaller than the true number of free + ** bytes, but never larger. nFree must be a multiple of 8 - it is + ** rounded down if is not. */ - zCsr = (u8*)&p->aOp[p->nOp]; /* Memory avaliable for allocation */ - assert( pParse->nOpAlloc*sizeof(Op) <= 0x7fffff00 ); - nFree = (pParse->nOpAlloc - p->nOp)*sizeof(p->aOp[0]); /* Available space */ + n = ROUND8(sizeof(Op)*p->nOp); /* Bytes of opcode space used */ + zCsr = &((u8*)p->aOp)[n]; /* Unused opcode space */ + assert( EIGHT_BYTE_ALIGNMENT(zCsr) ); + nFree = ROUNDDOWN8(pParse->szOpAlloc - n); /* Bytes of unused space */ + assert( nFree>=0 ); + if( nFree>0 ){ + memset(zCsr, 0, nFree); + assert( EIGHT_BYTE_ALIGNMENT(&zCsr[nFree]) ); + } resolveP2Values(p, &nArg); p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort); if( pParse->explain && nMem<10 ){ nMem = 10; } - memset(zCsr, 0, nFree); - assert( EIGHT_BYTE_ALIGNMENT(&zCsr[nFree]) ); p->expired = 0; /* Memory for registers, parameters, cursor, etc, is allocated in two @@ -3748,7 +3757,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 ); diff --git a/src/where.c b/src/where.c index 7d68664598..e86e26ef1a 100644 --- a/src/where.c +++ b/src/where.c @@ -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; iaiColumn[n] = i; - pIdx->azColl[n] = "BINARY"; + pIdx->azColl[n] = sqlite3StrBINARY; n++; } } if( pSrc->colUsed & MASKBIT(BMS-1) ){ for(i=BMS-1; inCol; 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 ); diff --git a/src/whereInt.h b/src/whereInt.h index 63d2d71cb4..1a189980ef 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -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[] */ diff --git a/test/analyzeF.test b/test/analyzeF.test index 670d178a81..3cbc5f47be 100644 --- a/test/analyzeF.test +++ b/test/analyzeF.test @@ -106,7 +106,7 @@ do_catchsql_test 4.1 { } {1 {error one}} do_catchsql_test 4.2 { - SELECT * FROM t1 WHERE x = zeroblob(2000000000) AND y = 4; + SELECT * FROM t1 WHERE x = zeroblob(2200000000) AND y = 4; } {1 {string or blob too big}} sqlite3_limit db SQLITE_LIMIT_LENGTH 1000000 @@ -122,6 +122,3 @@ do_catchsql_test 4.4 { finish_test - - - diff --git a/test/conflict2.test b/test/conflict2.test index 8419f1a3ff..6496913849 100644 --- a/test/conflict2.test +++ b/test/conflict2.test @@ -289,11 +289,11 @@ do_test conflict2-6.0 { # foreach {i conf1 cmd t0 t1 t2 t3 t4} { 1 {} UPDATE 1 {6 7 8 9} 1 0 1 - 2 REPLACE UPDATE 0 {7 6 9} 1 0 0 - 3 IGNORE UPDATE 0 {6 7 3 9} 1 0 0 - 4 FAIL UPDATE 1 {6 7 3 4} 1 0 0 + 2 REPLACE UPDATE 0 {7 6 9} 1 0 1 + 3 IGNORE UPDATE 0 {6 7 3 9} 1 0 1 + 4 FAIL UPDATE 1 {6 7 3 4} 1 0 1 5 ABORT UPDATE 1 {1 2 3 4} 1 0 1 - 6 ROLLBACK UPDATE 1 {1 2 3 4} 0 0 0 + 6 ROLLBACK UPDATE 1 {1 2 3 4} 0 0 1 7 REPLACE {UPDATE OR IGNORE} 0 {6 7 3 9} 1 0 0 8 IGNORE {UPDATE OR REPLACE} 0 {7 6 9} 1 0 1 9 FAIL {UPDATE OR IGNORE} 0 {6 7 3 9} 1 0 0 diff --git a/test/cursorhint.test b/test/cursorhint.test index 69bc248cd7..ae86120fa8 100644 --- a/test/cursorhint.test +++ b/test/cursorhint.test @@ -46,10 +46,10 @@ proc p4_of_opcode {db opcode sql} { # Run EXPLAIN on $sql. Return a list of P5 values for all $opcode # opcodes that contain regexp $comment in their comment # -proc p5_of_opcode {db opcode comment sql} { +proc p5_of_opcode {db opcode sql} { set res {} $db eval "EXPLAIN $sql" x { - if {$x(opcode)==$opcode && [regexp $comment $x(comment)]} { + if {$x(opcode)==$opcode} { lappend res $x(p5) } } @@ -66,7 +66,7 @@ do_test 1.1 { } } {{EQ(r[1],c0)}} do_test 1.2 { - p5_of_opcode db OpenRead . { + p5_of_opcode db OpenRead { SELECT * FROM t1 CROSS JOIN t2 WHERE a=x } } {00 00} @@ -79,7 +79,7 @@ do_test 2.1 { } } {{EQ(c0,r[1])}} do_test 2.2 { - p5_of_opcode db OpenRead . { + p5_of_opcode db OpenRead { SELECT * FROM t2 CROSS JOIN t1 WHERE a=x } } {00 00} @@ -114,7 +114,7 @@ do_test 4.1desc { } } {GT(c0,11)} do_test 4.2 { - p5_of_opcode db OpenRead . { + p5_of_opcode db OpenRead { SELECT * FROM t1 WHERE b>11; } } {02 00} @@ -129,7 +129,7 @@ do_test 4.3desc { } } {} do_test 4.4 { - p5_of_opcode db OpenRead . { + p5_of_opcode db OpenRead { SELECT c FROM t1 WHERE b<11; } } {00} diff --git a/test/date.test b/test/date.test index b1d1c677c1..2f48b111e6 100644 --- a/test/date.test +++ b/test/date.test @@ -336,6 +336,15 @@ if {$tzoffset_new==4} { datetest 6.8.1 {datetime('2006-04-02 02:00:00','utc')} {2006-04-02 06:00:00} datetest 6.8.2 {datetime('2007-03-11 02:00:00','utc')} {2007-03-11 06:00:00} + # The 'utc' modifier is a no-op if the LHS is known to already be in UTC + datetest 6.9.1 {datetime('2015-12-23 12:00:00','utc')} {2015-12-23 17:00:00} + datetest 6.9.2 {datetime('2015-12-23 12:00:00z','utc')} {2015-12-23 12:00:00} + datetest 6.9.3 {datetime('2015-12-23 12:00:00-03:00','utc')} \ + {2015-12-23 15:00:00} + datetest 6.9.4 {datetime('2015-12-23 12:00:00','utc','utc','utc')} \ + {2015-12-23 17:00:00} + + datetest 6.10 {datetime('2000-01-01 12:00:00','localtime')} \ {2000-01-01 07:00:00} datetest 6.11 {datetime('1969-01-01 12:00:00','localtime')} \ diff --git a/test/fuzzcheck.c b/test/fuzzcheck.c index 6d9c745528..03776f1e70 100644 --- a/test/fuzzcheck.c +++ b/test/fuzzcheck.c @@ -865,8 +865,13 @@ int main(int argc, char **argv){ return 0; }else if( strcmp(z,"limit-mem")==0 ){ +#if !defined(SQLITE_ENABLE_MEMSYS3) && !defined(SQLITE_ENABLE_MEMSYS5) + fatalError("the %s option requires -DSQLITE_ENABLE_MEMSYS5 or _MEMSYS3", + argv[i]); +#else if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]); nMem = integerValue(argv[++i]); +#endif }else if( strcmp(z,"limit-vdbe")==0 ){ vdbeLimitFlag = 1; diff --git a/test/ieee754.test b/test/ieee754.test index c0bf9d7995..bf0676429b 100644 --- a/test/ieee754.test +++ b/test/ieee754.test @@ -43,12 +43,16 @@ foreach {id float rep} { } } -do_execsql_test ieee754-110 { - SELECT ieee754(1,1024), ieee754(4503599627370495,972); -} {Inf 1.79769313486232e+308} -do_execsql_test ieee754-111 { - SELECT ieee754(-1,1024), ieee754(-4503599627370495,972); -} {-Inf -1.79769313486232e+308} +do_test ieee754-110 { + string tolower [ + db eval {SELECT ieee754(1,1024), ieee754(4503599627370495,972);} + ] +} {inf 1.79769313486232e+308} +do_test ieee754-111 { + string tolower [ + db eval {SELECT ieee754(-1,1024), ieee754(-4503599627370495,972);} + ] +} {-inf -1.79769313486232e+308} do_execsql_test ieee754-112 { SELECT ieee754(4503599627370495,973) is null; } {1} diff --git a/test/indexexpr1.test b/test/indexexpr1.test index 89bea1877f..a8a74f259e 100644 --- a/test/indexexpr1.test +++ b/test/indexexpr1.test @@ -307,5 +307,21 @@ do_catchsql_test indexexpr1-910 { INSERT INTO t9(a,b,c,d) VALUES(5,6,7,-8); } {1 {UNIQUE constraint failed: index 't9x1'}} +# Test cases derived from a NEVER() maro failure discovered by +# Jonathan Metzman using AFL +# +do_execsql_test indexexpr1-1000 { + DROP TABLE IF EXISTS t0; + CREATE TABLE t0(a,b,t); + CREATE INDEX i ON t0(a in(0,1)); + INSERT INTO t0 VALUES(0,1,2),(2,3,4),(5,6,7); + UPDATE t0 SET b=99 WHERE (a in(0,1))=0; + SELECT *, '|' FROM t0 ORDER BY +a; +} {0 1 2 | 2 99 4 | 5 99 7 |} +do_execsql_test indexexpr1-1010 { + UPDATE t0 SET b=88 WHERE (a in(0,1))=1; + SELECT *, '|' FROM t0 ORDER BY +a; +} {0 88 2 | 2 99 4 | 5 99 7 |} + finish_test diff --git a/test/json103.test b/test/json103.test new file mode 100644 index 0000000000..0f0241e6fc --- /dev/null +++ b/test/json103.test @@ -0,0 +1,65 @@ +# 2015-12-30 +# +# 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 implements tests for JSON aggregate SQL functions +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +ifcapable !json1 { + finish_test + return +} + +do_execsql_test json103-100 { + CREATE TABLE t1(a,b,c); + WITH RECURSIVE c(x) AS (VALUES(1) UNION SELECT x+1 FROM c WHERE x<100) + INSERT INTO t1(a,b,c) SELECT x, x%3, printf('n%d',x) FROM c; + UPDATE t1 SET a='orange' WHERE rowid=39; + UPDATE t1 SET a=32.5 WHERE rowid=31; + UPDATE t1 SET a=x'303132' WHERE rowid=29; + UPDATE t1 SET a=NULL WHERE rowid=37; + SELECT json_group_array(a) FROM t1 WHERE a<0 AND typeof(a)!='blob'; +} {{[]}} +do_catchsql_test json103-101 { + SELECT json_group_array(a) FROM t1; +} {1 {JSON cannot hold BLOB values}} +do_execsql_test json103-110 { + SELECT json_group_array(a) FROM t1 + WHERE rowid BETWEEN 31 AND 39; +} {{[32.5,32,33,34,35,36,null,38,"orange"]}} +do_execsql_test json103-111 { + SELECT json_array_length(json_group_array(a)) FROM t1 + WHERE rowid BETWEEN 31 AND 39; +} {9} +do_execsql_test json103-120 { + SELECT b, json_group_array(a) FROM t1 WHERE rowid<10 GROUP BY b ORDER BY b; +} {0 {[3,6,9]} 1 {[1,4,7]} 2 {[2,5,8]}} + +do_execsql_test json103-200 { + SELECT json_group_object(c,a) FROM t1 WHERE a<0 AND typeof(a)!='blob'; +} {{{}}} +do_catchsql_test json103-201 { + SELECT json_group_object(c,a) FROM t1; +} {1 {JSON cannot hold BLOB values}} + +do_execsql_test json103-210 { + SELECT json_group_object(c,a) FROM t1 + WHERE rowid BETWEEN 31 AND 39 AND rowid%2==1; +} {{{"n31":32.5,"n33":33,"n35":35,"n37":null,"n39":"orange"}}} +do_execsql_test json103-220 { + SELECT b, json_group_object(c,a) FROM t1 + WHERE rowid<7 GROUP BY b ORDER BY b; +} {0 {{"n3":3,"n6":6}} 1 {{"n1":1,"n4":4}} 2 {{"n2":2,"n5":5}}} + + + +finish_test diff --git a/test/releasetest.tcl b/test/releasetest.tcl index 7f53fd1523..bb902eec3e 100644 --- a/test/releasetest.tcl +++ b/test/releasetest.tcl @@ -86,6 +86,8 @@ array set ::Configs [strip_comments { -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT=1 -DSQLITE_ENABLE_STMT_SCANSTATUS + -DSQLITE_LIKE_DOESNT_MATCH_BLOBS + -DSQLITE_ENABLE_CURSOR_HINTS --enable-json1 } "Check-Symbols" { @@ -830,8 +832,8 @@ proc process_options {argv} { } default { - PUTSERR stderr "" - PUTSERR stderr [string trim $::USAGE_MESSAGE] + PUTSERR "" + PUTSERR [string trim $::USAGE_MESSAGE] exit -1 } } @@ -945,6 +947,8 @@ proc main {argv} { set min [expr {($elapsetime/60)%60}] set sec [expr {$elapsetime%60}] set etime [format (%02d:%02d:%02d) $hr $min $sec] + if {$::JOBS>1} {append etime " $::JOBS cores"} + if {[catch {exec hostname} HNAME]==0} {append etime " on $HNAME"} PUTS [string repeat * 79] incr ::NERRCASE $::NERR PUTS "$::NERRCASE failures out of $::NTESTCASE tests in $etime" diff --git a/test/vtabH.test b/test/vtabH.test index 7973819bd1..7bd542e05b 100644 --- a/test/vtabH.test +++ b/test/vtabH.test @@ -32,12 +32,12 @@ do_execsql_test 1.0 { foreach {tn sql expect} { 1 "SELECT * FROM e6 WHERE b LIKE 'abc'" { - xBestIndex {SELECT rowid, a, b FROM 't6' WHERE b like ?} + xBestIndex {SELECT rowid, a, b FROM 't6' WHERE b like ?} xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} abc } 2 "SELECT * FROM e6 WHERE b GLOB 'abc'" { - xBestIndex {SELECT rowid, a, b FROM 't6' WHERE b glob ?} + xBestIndex {SELECT rowid, a, b FROM 't6' WHERE b glob ?} xFilter {SELECT rowid, a, b FROM 't6' WHERE b glob ?} abc } } { @@ -115,7 +115,7 @@ if {1} { SELECT name FROM fsdir WHERE dir = '.' AND name = 'test.db'; SELECT name FROM fsdir WHERE dir = '.' AND name = '.' } {test.db .} - + proc list_root_files {} { if {$::tcl_platform(platform) eq "windows"} { set res [list] @@ -142,20 +142,6 @@ if {1} { } } - # Read the first 5 entries from the root directory. - # - set res [list] - foreach p [lrange [list_root_files] 0 4] { - if {$::tcl_platform(platform) eq "windows"} { - lappend res $p - } else { - lappend res "/$p" - } - } - do_execsql_test 3.1 { - SELECT path FROM fstree LIMIT 5; - } $res - # Read all entries in the current directory. # proc contents {pattern} { @@ -173,7 +159,7 @@ if {1} { do_execsql_test 3.2 { SELECT path FROM fstree WHERE path GLOB $pwd ORDER BY 1 } [lsort $res] - + # Add some sub-directories and files to the current directory. # do_test 3.3 { @@ -181,7 +167,7 @@ if {1} { foreach {path sz} { subdir/x1.txt 143 subdir/x2.txt 153 - } { + } { set dir [file dirname $path] catch { file mkdir $dir } set fd [open $path w] @@ -189,7 +175,7 @@ if {1} { close $fd } } {} - + set pwd [pwd] do_execsql_test 3.5 { SELECT path, size FROM fstree WHERE path GLOB $pwd || '/subdir/*' ORDER BY 1 diff --git a/test/without_rowid5.test b/test/without_rowid5.test index d163d9c1bc..31a440ad87 100644 --- a/test/without_rowid5.test +++ b/test/without_rowid5.test @@ -132,9 +132,13 @@ do_execsql_test without_rowid5-5.1 { INSERT INTO ipk VALUES('rival','bonus'); -- ok to insert non-integer key SELECT * FROM ipk; } {rival bonus} -do_catchsql_test without_rowid5-5.2 { +do_catchsql_test without_rowid5-5.2a { + BEGIN; INSERT INTO ipk VALUES(NULL,'sample'); -- no automatic generation of keys } {1 {NOT NULL constraint failed: ipk.key}} +do_execsql_test without_rowid5-5.2b { + ROLLBACK; +} {} # EVIDENCE-OF: R-33142-02092 AUTOINCREMENT does not work on WITHOUT # ROWID tables.