aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/alter.c5
-rw-r--r--src/build.c18
-rw-r--r--src/dbpage.c8
-rw-r--r--src/dbstat.c4
-rw-r--r--src/expr.c154
-rw-r--r--src/func.c6
-rw-r--r--src/main.c3
-rw-r--r--src/memdb.c118
-rw-r--r--src/printf.c27
-rw-r--r--src/select.c208
-rw-r--r--src/shell.c.in293
-rw-r--r--src/sqlite.h.in1
-rw-r--r--src/sqliteInt.h25
-rw-r--r--src/update.c3
-rw-r--r--src/vdbe.c45
-rw-r--r--src/vdbeInt.h2
-rw-r--r--src/vdbeapi.c8
-rw-r--r--src/vdbeaux.c7
-rw-r--r--src/vdbevtab.c4
-rw-r--r--src/where.c31
20 files changed, 618 insertions, 352 deletions
diff --git a/src/alter.c b/src/alter.c
index d8a998287..cebeec385 100644
--- a/src/alter.c
+++ b/src/alter.c
@@ -741,13 +741,14 @@ static void renameTokenCheckAll(Parse *pParse, const void *pPtr){
assert( pParse->db->mallocFailed==0 || pParse->nErr!=0 );
if( pParse->nErr==0 ){
const RenameToken *p;
- u8 i = 0;
+ u32 i = 1;
for(p=pParse->pRename; p; p=p->pNext){
if( p->p ){
assert( p->p!=pPtr );
- i += *(u8*)(p->p);
+ i += *(u8*)(p->p) | 1;
}
}
+ assert( i>0 );
}
}
#else
diff --git a/src/build.c b/src/build.c
index effaeb733..60d59c0c4 100644
--- a/src/build.c
+++ b/src/build.c
@@ -2004,6 +2004,13 @@ void sqlite3AddGenerated(Parse *pParse, Expr *pExpr, Token *pType){
if( pCol->colFlags & COLFLAG_PRIMKEY ){
makeColumnPartOfPrimaryKey(pParse, pCol); /* For the error message */
}
+ if( ALWAYS(pExpr) && pExpr->op==TK_ID ){
+ /* The value of a generated column needs to be a real expression, not
+ ** just a reference to another column, in order for covering index
+ ** optimizations to work correctly. So if the value is not an expression,
+ ** turn it into one by adding a unary "+" operator. */
+ pExpr = sqlite3PExpr(pParse, TK_UPLUS, pExpr, 0);
+ }
sqlite3ColumnSetExpr(pParse, pTab, pCol, pExpr);
pExpr = 0;
goto generated_done;
@@ -2140,7 +2147,8 @@ static char *createTableStmt(sqlite3 *db, Table *p){
/* SQLITE_AFF_TEXT */ " TEXT",
/* SQLITE_AFF_NUMERIC */ " NUM",
/* SQLITE_AFF_INTEGER */ " INT",
- /* SQLITE_AFF_REAL */ " REAL"
+ /* SQLITE_AFF_REAL */ " REAL",
+ /* SQLITE_AFF_FLEXNUM */ " NUM",
};
int len;
const char *zType;
@@ -2156,10 +2164,12 @@ static char *createTableStmt(sqlite3 *db, Table *p){
testcase( pCol->affinity==SQLITE_AFF_NUMERIC );
testcase( pCol->affinity==SQLITE_AFF_INTEGER );
testcase( pCol->affinity==SQLITE_AFF_REAL );
+ testcase( pCol->affinity==SQLITE_AFF_FLEXNUM );
zType = azType[pCol->affinity - SQLITE_AFF_BLOB];
len = sqlite3Strlen30(zType);
- assert( pCol->affinity==SQLITE_AFF_BLOB
+ assert( pCol->affinity==SQLITE_AFF_BLOB
+ || pCol->affinity==SQLITE_AFF_FLEXNUM
|| pCol->affinity==sqlite3AffinityType(zType, 0) );
memcpy(&zStmt[k], zType, len);
k += len;
@@ -2574,6 +2584,7 @@ int sqlite3ShadowTableName(sqlite3 *db, const char *zName){
** not pass them into code generator routines by mistake.
*/
static int markImmutableExprStep(Walker *pWalker, Expr *pExpr){
+ (void)pWalker;
ExprSetVVAProperty(pExpr, EP_Immutable);
return WRC_Continue;
}
@@ -3140,8 +3151,7 @@ static SQLITE_NOINLINE int viewGetColumnNames(Parse *pParse, Table *pTable){
&& pTable->nCol==pSel->pEList->nExpr
){
assert( db->mallocFailed==0 );
- sqlite3SelectAddColumnTypeAndCollation(pParse, pTable, pSel,
- SQLITE_AFF_NONE);
+ sqlite3SubqueryColumnTypes(pParse, pTable, pSel, SQLITE_AFF_NONE);
}
}else{
/* CREATE VIEW name AS... without an argument list. Construct
diff --git a/src/dbpage.c b/src/dbpage.c
index 458f2bd50..9378dd4fc 100644
--- a/src/dbpage.c
+++ b/src/dbpage.c
@@ -72,6 +72,10 @@ static int dbpageConnect(
){
DbpageTable *pTab = 0;
int rc = SQLITE_OK;
+ (void)pAux;
+ (void)argc;
+ (void)argv;
+ (void)pzErr;
sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY);
rc = sqlite3_declare_vtab(db,
@@ -110,6 +114,7 @@ static int dbpageDisconnect(sqlite3_vtab *pVtab){
static int dbpageBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
int i;
int iPlan = 0;
+ (void)tab;
/* If there is a schema= constraint, it must be honored. Report a
** ridiculously large estimated cost if the schema= constraint is
@@ -225,6 +230,8 @@ static int dbpageFilter(
sqlite3 *db = pTab->db;
Btree *pBt;
+ (void)idxStr;
+
/* Default setting is no rows of result */
pCsr->pgno = 1;
pCsr->mxPgno = 0;
@@ -320,6 +327,7 @@ static int dbpageUpdate(
Pager *pPager;
int szPage;
+ (void)pRowid;
if( pTab->db->flags & SQLITE_Defensive ){
zErr = "read-only";
goto update_fail;
diff --git a/src/dbstat.c b/src/dbstat.c
index fdef913f8..0a89d0524 100644
--- a/src/dbstat.c
+++ b/src/dbstat.c
@@ -163,6 +163,7 @@ static int statConnect(
StatTable *pTab = 0;
int rc = SQLITE_OK;
int iDb;
+ (void)pAux;
if( argc>=4 ){
Token nm;
@@ -216,6 +217,7 @@ static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
int iSchema = -1;
int iName = -1;
int iAgg = -1;
+ (void)tab;
/* Look for a valid schema=? constraint. If found, change the idxNum to
** 1 and request the value of that constraint be sent to xFilter. And
@@ -741,6 +743,8 @@ static int statFilter(
int iArg = 0; /* Count of argv[] parameters used so far */
int rc = SQLITE_OK; /* Result of this operation */
const char *zName = 0; /* Only provide analysis of this table */
+ (void)argc;
+ (void)idxStr;
statResetCsr(pCsr);
sqlite3_finalize(pCsr->pStmt);
diff --git a/src/expr.c b/src/expr.c
index 592e9dd25..271d9dea8 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -44,49 +44,122 @@ char sqlite3TableColumnAffinity(const Table *pTab, int iCol){
*/
char sqlite3ExprAffinity(const Expr *pExpr){
int op;
- while( ExprHasProperty(pExpr, EP_Skip|EP_IfNullRow) ){
- assert( pExpr->op==TK_COLLATE
- || pExpr->op==TK_IF_NULL_ROW
- || (pExpr->op==TK_REGISTER && pExpr->op2==TK_IF_NULL_ROW) );
- pExpr = pExpr->pLeft;
- assert( pExpr!=0 );
- }
op = pExpr->op;
- if( op==TK_REGISTER ) op = pExpr->op2;
- if( op==TK_COLUMN || (op==TK_AGG_COLUMN && pExpr->y.pTab!=0) ){
- assert( ExprUseYTab(pExpr) );
- assert( pExpr->y.pTab!=0 );
- return sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
- }
- if( op==TK_SELECT ){
- assert( ExprUseXSelect(pExpr) );
- assert( pExpr->x.pSelect!=0 );
- assert( pExpr->x.pSelect->pEList!=0 );
- assert( pExpr->x.pSelect->pEList->a[0].pExpr!=0 );
- return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr);
- }
+ while( 1 /* exit-by-break */ ){
+ if( op==TK_COLUMN || (op==TK_AGG_COLUMN && pExpr->y.pTab!=0) ){
+ assert( ExprUseYTab(pExpr) );
+ assert( pExpr->y.pTab!=0 );
+ return sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
+ }
+ if( op==TK_SELECT ){
+ assert( ExprUseXSelect(pExpr) );
+ assert( pExpr->x.pSelect!=0 );
+ assert( pExpr->x.pSelect->pEList!=0 );
+ assert( pExpr->x.pSelect->pEList->a[0].pExpr!=0 );
+ return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr);
+ }
#ifndef SQLITE_OMIT_CAST
- if( op==TK_CAST ){
- assert( !ExprHasProperty(pExpr, EP_IntValue) );
- return sqlite3AffinityType(pExpr->u.zToken, 0);
- }
+ if( op==TK_CAST ){
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
+ return sqlite3AffinityType(pExpr->u.zToken, 0);
+ }
#endif
- if( op==TK_SELECT_COLUMN ){
- assert( pExpr->pLeft!=0 && ExprUseXSelect(pExpr->pLeft) );
- assert( pExpr->iColumn < pExpr->iTable );
- assert( pExpr->iTable==pExpr->pLeft->x.pSelect->pEList->nExpr );
- return sqlite3ExprAffinity(
- pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr
- );
- }
- if( op==TK_VECTOR ){
- assert( ExprUseXList(pExpr) );
- return sqlite3ExprAffinity(pExpr->x.pList->a[0].pExpr);
+ if( op==TK_SELECT_COLUMN ){
+ assert( pExpr->pLeft!=0 && ExprUseXSelect(pExpr->pLeft) );
+ assert( pExpr->iColumn < pExpr->iTable );
+ assert( pExpr->iTable==pExpr->pLeft->x.pSelect->pEList->nExpr );
+ return sqlite3ExprAffinity(
+ pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr
+ );
+ }
+ if( op==TK_VECTOR ){
+ assert( ExprUseXList(pExpr) );
+ return sqlite3ExprAffinity(pExpr->x.pList->a[0].pExpr);
+ }
+ if( ExprHasProperty(pExpr, EP_Skip|EP_IfNullRow) ){
+ assert( pExpr->op==TK_COLLATE
+ || pExpr->op==TK_IF_NULL_ROW
+ || (pExpr->op==TK_REGISTER && pExpr->op2==TK_IF_NULL_ROW) );
+ pExpr = pExpr->pLeft;
+ op = pExpr->op;
+ continue;
+ }
+ if( op!=TK_REGISTER || (op = pExpr->op2)==TK_REGISTER ) break;
}
return pExpr->affExpr;
}
/*
+** Make a guess at all the possible datatypes of the result that could
+** be returned by an expression. Return a bitmask indicating the answer:
+**
+** 0x01 Numeric
+** 0x02 Text
+** 0x04 Blob
+**
+** If the expression must return NULL, then 0x00 is returned.
+*/
+int sqlite3ExprDataType(const Expr *pExpr){
+ while( pExpr ){
+ switch( pExpr->op ){
+ case TK_COLLATE:
+ case TK_IF_NULL_ROW:
+ case TK_UPLUS: {
+ pExpr = pExpr->pLeft;
+ break;
+ }
+ case TK_NULL: {
+ pExpr = 0;
+ break;
+ }
+ case TK_STRING: {
+ return 0x02;
+ }
+ case TK_BLOB: {
+ return 0x04;
+ }
+ case TK_CONCAT: {
+ return 0x06;
+ }
+ case TK_VARIABLE:
+ case TK_AGG_FUNCTION:
+ case TK_FUNCTION: {
+ return 0x07;
+ }
+ case TK_COLUMN:
+ case TK_AGG_COLUMN:
+ case TK_SELECT:
+ case TK_CAST:
+ case TK_SELECT_COLUMN:
+ case TK_VECTOR: {
+ int aff = sqlite3ExprAffinity(pExpr);
+ if( aff>=SQLITE_AFF_NUMERIC ) return 0x05;
+ if( aff==SQLITE_AFF_TEXT ) return 0x06;
+ return 0x07;
+ }
+ case TK_CASE: {
+ int res = 0;
+ int ii;
+ ExprList *pList = pExpr->x.pList;
+ assert( ExprUseXList(pExpr) && pList!=0 );
+ assert( pList->nExpr > 0);
+ for(ii=1; ii<pList->nExpr; ii+=2){
+ res |= sqlite3ExprDataType(pList->a[ii].pExpr);
+ }
+ if( pList->nExpr % 2 ){
+ res |= sqlite3ExprDataType(pList->a[pList->nExpr-1].pExpr);
+ }
+ return res;
+ }
+ default: {
+ return 0x01;
+ }
+ } /* End of switch(op) */
+ } /* End of while(pExpr) */
+ return 0x00;
+}
+
+/*
** Set the collating sequence for expression pExpr to be the collating
** sequence named by pToken. Return a pointer to a new Expr node that
** implements the COLLATE operator.
@@ -4177,7 +4250,7 @@ expr_code_doover:
assert( pExpr->y.pTab!=0 );
aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
if( aff>SQLITE_AFF_BLOB ){
- static const char zAff[] = "B\000C\000D\000E";
+ static const char zAff[] = "B\000C\000D\000E\000F";
assert( SQLITE_AFF_BLOB=='A' );
assert( SQLITE_AFF_TEXT=='B' );
sqlite3VdbeAddOp4(v, OP_Affinity, iReg, 1, 0,
@@ -6174,10 +6247,8 @@ int sqlite3ReferencesSrcList(Parse *pParse, Expr *pExpr, SrcList *pSrcList){
** it does, make a copy. This is done because the pExpr argument is
** subject to change.
**
-** The copy is stored on pParse->pConstExpr with a register number of 0.
-** This will cause the expression to be deleted automatically when the
-** Parse object is destroyed, but the zero register number means that it
-** will not generate any code in the preamble.
+** The copy is scheduled for deletion using the sqlite3ExprDeferredDelete()
+** which builds on the sqlite3ParserAddCleanup() mechanism.
*/
static int agginfoPersistExprCb(Walker *pWalker, Expr *pExpr){
if( ALWAYS(!ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced))
@@ -6188,7 +6259,6 @@ static int agginfoPersistExprCb(Walker *pWalker, Expr *pExpr){
Parse *pParse = pWalker->pParse;
sqlite3 *db = pParse->db;
if( pExpr->op!=TK_AGG_FUNCTION ){
- assert( pExpr->op==TK_AGG_COLUMN || pExpr->op==TK_IF_NULL_ROW );
assert( iAgg>=0 && iAgg<pAggInfo->nColumn );
if( pAggInfo->aCol[iAgg].pCExpr==pExpr ){
pExpr = sqlite3ExprDup(db, pExpr, 0);
@@ -6314,6 +6384,7 @@ static void findOrCreateAggInfoColumn(
}
fix_up_expr:
ExprSetVVAProperty(pExpr, EP_NoReduce);
+ assert( pExpr->pAggInfo==0 || pExpr->pAggInfo==pAggInfo );
pExpr->pAggInfo = pAggInfo;
if( pExpr->op==TK_COLUMN ){
pExpr->op = TK_AGG_COLUMN;
@@ -6349,6 +6420,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
}
if( pIEpr==0 ) break;
if( NEVER(!ExprUseYTab(pExpr)) ) break;
+ if( pExpr->pAggInfo!=0 ) break; /* Already resolved by outer context */
/* If we reach this point, it means that expression pExpr can be
** translated into a reference to an index column as described by
diff --git a/src/func.c b/src/func.c
index 3c5a85230..9a62470a0 100644
--- a/src/func.c
+++ b/src/func.c
@@ -1082,7 +1082,7 @@ void sqlite3QuoteValue(StrAccum *pStr, sqlite3_value *pValue){
}
case SQLITE_BLOB: {
char const *zBlob = sqlite3_value_blob(pValue);
- int nBlob = sqlite3_value_bytes(pValue);
+ i64 nBlob = sqlite3_value_bytes(pValue);
assert( zBlob==sqlite3_value_blob(pValue) ); /* No encoding change */
sqlite3StrAccumEnlarge(pStr, nBlob*2 + 4);
if( pStr->accError==0 ){
@@ -1440,6 +1440,9 @@ static void unknownFunc(
sqlite3_value **argv
){
/* no-op */
+ (void)context;
+ (void)argc;
+ (void)argv;
}
#endif /*SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION*/
@@ -2183,6 +2186,7 @@ static void piFunc(
sqlite3_value **argv
){
assert( argc==0 );
+ (void)argv;
sqlite3_result_double(context, M_PI);
}
diff --git a/src/main.c b/src/main.c
index 67dd60ae7..a2d96ad28 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1566,6 +1566,7 @@ const char *sqlite3ErrName(int rc){
case SQLITE_NOTICE_RECOVER_WAL: zName = "SQLITE_NOTICE_RECOVER_WAL";break;
case SQLITE_NOTICE_RECOVER_ROLLBACK:
zName = "SQLITE_NOTICE_RECOVER_ROLLBACK"; break;
+ case SQLITE_NOTICE_RBU: zName = "SQLITE_NOTICE_RBU"; break;
case SQLITE_WARNING: zName = "SQLITE_WARNING"; break;
case SQLITE_WARNING_AUTOINDEX: zName = "SQLITE_WARNING_AUTOINDEX"; break;
case SQLITE_DONE: zName = "SQLITE_DONE"; break;
@@ -2118,7 +2119,7 @@ int sqlite3_overload_function(
rc = sqlite3FindFunction(db, zName, nArg, SQLITE_UTF8, 0)!=0;
sqlite3_mutex_leave(db->mutex);
if( rc ) return SQLITE_OK;
- zCopy = sqlite3_mprintf(zName);
+ zCopy = sqlite3_mprintf("%s", zName);
if( zCopy==0 ) return SQLITE_NOMEM;
return sqlite3_create_function_v2(db, zName, nArg, SQLITE_UTF8,
zCopy, sqlite3InvalidFunction, 0, 0, sqlite3_free);
diff --git a/src/memdb.c b/src/memdb.c
index 4ea3cffde..657cb9ca6 100644
--- a/src/memdb.c
+++ b/src/memdb.c
@@ -109,6 +109,7 @@ static int memdbTruncate(sqlite3_file*, sqlite3_int64 size);
static int memdbSync(sqlite3_file*, int flags);
static int memdbFileSize(sqlite3_file*, sqlite3_int64 *pSize);
static int memdbLock(sqlite3_file*, int);
+static int memdbUnlock(sqlite3_file*, int);
/* static int memdbCheckReservedLock(sqlite3_file*, int *pResOut);// not used */
static int memdbFileControl(sqlite3_file*, int op, void *pArg);
/* static int memdbSectorSize(sqlite3_file*); // not used */
@@ -167,7 +168,7 @@ static const sqlite3_io_methods memdb_io_methods = {
memdbSync, /* xSync */
memdbFileSize, /* xFileSize */
memdbLock, /* xLock */
- memdbLock, /* xUnlock - same as xLock in this case */
+ memdbUnlock, /* xUnlock */
0, /* memdbCheckReservedLock, */ /* xCheckReservedLock */
memdbFileControl, /* xFileControl */
0, /* memdbSectorSize,*/ /* xSectorSize */
@@ -368,64 +369,81 @@ static int memdbLock(sqlite3_file *pFile, int eLock){
MemFile *pThis = (MemFile*)pFile;
MemStore *p = pThis->pStore;
int rc = SQLITE_OK;
- if( eLock==pThis->eLock ) return SQLITE_OK;
+ if( eLock<=pThis->eLock ) return SQLITE_OK;
memdbEnter(p);
- assert( p->nWrLock==0 || p->nWrLock==1 ); /* No more than 1 write lock */
- if( eLock>SQLITE_LOCK_SHARED ){
- assert( pThis->eLock>=SQLITE_LOCK_SHARED );
- if( p->mFlags & SQLITE_DESERIALIZE_READONLY ){
- rc = SQLITE_READONLY;
- }else if( eLock==SQLITE_LOCK_EXCLUSIVE ){
- /* We never go for an EXCLUSIVE lock unless we already hold SHARED or
- ** higher */
- assert( pThis->eLock>=SQLITE_LOCK_SHARED );
- testcase( pThis->eLock==SQLITE_LOCK_SHARED );
-
- /* Because we are holding SHARED or more, there must be at least
- ** one read lock */
- assert( p->nRdLock>0 );
-
- /* The only way that there can be an existing write lock is if we
- ** currently hold it. Otherwise, we would have never been able to
- ** promote from NONE to SHARED. */
- assert( p->nWrLock==0 || pThis->eLock>SQLITE_LOCK_SHARED );
-
- if( p->nRdLock>1 ){
- /* Cannot take EXCLUSIVE if somebody else is holding SHARED */
- rc = SQLITE_BUSY;
- }else{
- p->nWrLock = 1;
+
+ assert( p->nWrLock==0 || p->nWrLock==1 );
+ assert( pThis->eLock<=SQLITE_LOCK_SHARED || p->nWrLock==1 );
+ assert( pThis->eLock==SQLITE_LOCK_NONE || p->nRdLock>=1 );
+
+ if( eLock>SQLITE_LOCK_SHARED && (p->mFlags & SQLITE_DESERIALIZE_READONLY) ){
+ rc = SQLITE_READONLY;
+ }else{
+ switch( eLock ){
+ case SQLITE_LOCK_SHARED: {
+ assert( pThis->eLock==SQLITE_LOCK_NONE );
+ if( p->nWrLock>0 ){
+ rc = SQLITE_BUSY;
+ }else{
+ p->nRdLock++;
+ }
+ break;
+ };
+
+ case SQLITE_LOCK_RESERVED:
+ case SQLITE_LOCK_PENDING: {
+ assert( pThis->eLock>=SQLITE_LOCK_SHARED );
+ if( ALWAYS(pThis->eLock==SQLITE_LOCK_SHARED) ){
+ if( p->nWrLock>0 ){
+ rc = SQLITE_BUSY;
+ }else{
+ p->nWrLock = 1;
+ }
+ }
+ break;
}
- }else if( ALWAYS(pThis->eLock<=SQLITE_LOCK_SHARED) ){
- /* Upgrading to RESERVED or PENDING from SHARED. Fail if any other
- ** client has a write-lock of any kind. */
- if( p->nWrLock ){
- rc = SQLITE_BUSY;
- }else{
- p->nWrLock = 1;
+
+ default: {
+ assert( eLock==SQLITE_LOCK_EXCLUSIVE );
+ assert( pThis->eLock>=SQLITE_LOCK_SHARED );
+ if( p->nRdLock>1 ){
+ rc = SQLITE_BUSY;
+ }else if( pThis->eLock==SQLITE_LOCK_SHARED ){
+ p->nWrLock = 1;
+ }
+ break;
}
}
- }else if( eLock==SQLITE_LOCK_SHARED ){
- if( pThis->eLock > SQLITE_LOCK_SHARED ){
- assert( p->nWrLock==1 );
- p->nWrLock = 0;
- }else if( p->nWrLock ){
- rc = SQLITE_BUSY;
- }else{
- p->nRdLock++;
+ }
+ if( rc==SQLITE_OK ) pThis->eLock = eLock;
+ memdbLeave(p);
+ return rc;
+}
+
+/*
+** Unlock an memdb-file.
+*/
+static int memdbUnlock(sqlite3_file *pFile, int eLock){
+ MemFile *pThis = (MemFile*)pFile;
+ MemStore *p = pThis->pStore;
+ if( eLock>=pThis->eLock ) return SQLITE_OK;
+ memdbEnter(p);
+
+ assert( eLock==SQLITE_LOCK_SHARED || eLock==SQLITE_LOCK_NONE );
+ if( eLock==SQLITE_LOCK_SHARED ){
+ if( ALWAYS(pThis->eLock>SQLITE_LOCK_SHARED) ){
+ p->nWrLock--;
}
}else{
- assert( eLock==SQLITE_LOCK_NONE );
- if( pThis->eLock>SQLITE_LOCK_SHARED ){
- assert( p->nWrLock==1 );
- p->nWrLock = 0;
+ if( pThis->eLock>SQLITE_LOCK_SHARED ){
+ p->nWrLock--;
}
- assert( p->nRdLock>0 );
p->nRdLock--;
}
- if( rc==SQLITE_OK ) pThis->eLock = eLock;
+
+ pThis->eLock = eLock;
memdbLeave(p);
- return rc;
+ return SQLITE_OK;
}
#if 0
@@ -535,7 +553,7 @@ static int memdbOpen(
memset(pFile, 0, sizeof(*pFile));
szName = sqlite3Strlen30(zName);
- if( szName>1 && zName[0]=='/' ){
+ if( szName>1 && (zName[0]=='/' || zName[0]=='\\') ){
int i;
#ifndef SQLITE_MUTEX_OMIT
sqlite3_mutex *pVfsMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1);
diff --git a/src/printf.c b/src/printf.c
index 3602e1fcb..335ad0684 100644
--- a/src/printf.c
+++ b/src/printf.c
@@ -736,13 +736,26 @@ void sqlite3_str_vappendf(
}
}
if( precision>1 ){
+ i64 nPrior = 1;
width -= precision-1;
if( width>1 && !flag_leftjustify ){
sqlite3_str_appendchar(pAccum, width-1, ' ');
width = 0;
}
- while( precision-- > 1 ){
- sqlite3_str_append(pAccum, buf, length);
+ sqlite3_str_append(pAccum, buf, length);
+ precision--;
+ while( precision > 1 ){
+ i64 nCopyBytes;
+ if( nPrior > precision-1 ) nPrior = precision - 1;
+ nCopyBytes = length*nPrior;
+ if( nCopyBytes + pAccum->nChar >= pAccum->nAlloc ){
+ sqlite3StrAccumEnlarge(pAccum, nCopyBytes);
+ }
+ if( pAccum->accError ) break;
+ sqlite3_str_append(pAccum,
+ &pAccum->zText[pAccum->nChar-nCopyBytes], nCopyBytes);
+ precision -= nPrior;
+ nPrior *= 2;
}
}
bufpt = buf;
@@ -970,9 +983,9 @@ void sqlite3RecordErrorOffsetOfExpr(sqlite3 *db, const Expr *pExpr){
** Return the number of bytes of text that StrAccum is able to accept
** after the attempted enlargement. The value returned might be zero.
*/
-int sqlite3StrAccumEnlarge(StrAccum *p, int N){
+int sqlite3StrAccumEnlarge(StrAccum *p, i64 N){
char *zNew;
- assert( p->nChar+(i64)N >= p->nAlloc ); /* Only called if really needed */
+ assert( p->nChar+N >= p->nAlloc ); /* Only called if really needed */
if( p->accError ){
testcase(p->accError==SQLITE_TOOBIG);
testcase(p->accError==SQLITE_NOMEM);
@@ -983,8 +996,7 @@ int sqlite3StrAccumEnlarge(StrAccum *p, int N){
return p->nAlloc - p->nChar - 1;
}else{
char *zOld = isMalloced(p) ? p->zText : 0;
- i64 szNew = p->nChar;
- szNew += (sqlite3_int64)N + 1;
+ i64 szNew = p->nChar + N + 1;
if( szNew+p->nChar<=p->mxAlloc ){
/* Force exponential buffer size growth as long as it does not overflow,
** to avoid having to call this routine too often */
@@ -1014,7 +1026,8 @@ int sqlite3StrAccumEnlarge(StrAccum *p, int N){
return 0;
}
}
- return N;
+ assert( N>=0 && N<=0x7fffffff );
+ return (int)N;
}
/*
diff --git a/src/select.c b/src/select.c
index 886ac336f..eee9e29bb 100644
--- a/src/select.c
+++ b/src/select.c
@@ -1298,9 +1298,6 @@ static void selectInnerLoop(
testcase( eDest==SRT_Fifo );
testcase( eDest==SRT_DistFifo );
sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1+nPrefixReg);
- if( pDest->zAffSdst ){
- sqlite3VdbeChangeP4(v, -1, pDest->zAffSdst, nResultCol);
- }
#ifndef SQLITE_OMIT_CTE
if( eDest==SRT_DistFifo ){
/* If the destination is DistFifo, then cursor (iParm+1) is open
@@ -1873,6 +1870,7 @@ static void generateSortTail(
#else /* if !defined(SQLITE_ENABLE_COLUMN_METADATA) */
# define columnType(A,B,C,D,E) columnTypeImpl(A,B)
#endif
+#ifndef SQLITE_OMIT_DECLTYPE
static const char *columnTypeImpl(
NameContext *pNC,
#ifndef SQLITE_ENABLE_COLUMN_METADATA
@@ -1903,7 +1901,7 @@ static const char *columnTypeImpl(
Table *pTab = 0; /* Table structure column is extracted from */
Select *pS = 0; /* Select the column is extracted from */
int iCol = pExpr->iColumn; /* Index of column in pTab */
- while( pNC && !pTab ){
+ while( ALWAYS(pNC) && !pTab ){
SrcList *pTabList = pNC->pSrcList;
for(j=0;j<pTabList->nSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++);
if( j<pTabList->nSrc ){
@@ -1914,7 +1912,7 @@ static const char *columnTypeImpl(
}
}
- if( pTab==0 ){
+ if( NEVER(pTab==0) ){
/* At one time, code such as "SELECT new.x" within a trigger would
** cause this condition to run. Since then, we have restructured how
** trigger code is generated and so this condition is no longer
@@ -2019,6 +2017,7 @@ static const char *columnTypeImpl(
#endif
return zType;
}
+#endif /* !defined(SQLITE_OMIT_DECLTYPE) */
/*
** Generate code that will tell the VDBE the declaration types of columns
@@ -2290,47 +2289,76 @@ int sqlite3ColumnsFromExprList(
}
/*
-** Add type and collation information to a column list based on
-** a SELECT statement.
-**
-** The column list presumably came from selectColumnNamesFromExprList().
-** The column list has only names, not types or collations. This
-** routine goes through and adds the types and collations.
-**
-** This routine requires that all identifiers in the SELECT
-** statement be resolved.
+** pTab is a transient Table object that represents a subquery of some
+** kind (maybe a parenthesized subquery in the FROM clause of a larger
+** query, or a VIEW, or a CTE). This routine computes type information
+** for that Table object based on the Select object that implements the
+** subquery. For the purposes of this routine, "type infomation" means:
+**
+** * The datatype name, as it might appear in a CREATE TABLE statement
+** * Which collating sequence to use for the column
+** * The affinity of the column
*/
-void sqlite3SelectAddColumnTypeAndCollation(
- Parse *pParse, /* Parsing contexts */
- Table *pTab, /* Add column type information to this table */
- Select *pSelect, /* SELECT used to determine types and collations */
- char aff /* Default affinity for columns */
+void sqlite3SubqueryColumnTypes(
+ Parse *pParse, /* Parsing contexts */
+ Table *pTab, /* Add column type information to this table */
+ Select *pSelect, /* SELECT used to determine types and collations */
+ char aff /* Default affinity. */
){
sqlite3 *db = pParse->db;
- NameContext sNC;
Column *pCol;
CollSeq *pColl;
- int i;
+ int i,j;
Expr *p;
struct ExprList_item *a;
assert( pSelect!=0 );
assert( (pSelect->selFlags & SF_Resolved)!=0 );
assert( pTab->nCol==pSelect->pEList->nExpr || db->mallocFailed );
+ assert( aff==SQLITE_AFF_NONE || aff==SQLITE_AFF_BLOB );
if( db->mallocFailed ) return;
- memset(&sNC, 0, sizeof(sNC));
- sNC.pSrcList = pSelect->pSrc;
+ while( pSelect->pPrior ) pSelect = pSelect->pPrior;
a = pSelect->pEList->a;
for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
const char *zType;
- i64 n, m;
+ i64 n;
pTab->tabFlags |= (pCol->colFlags & COLFLAG_NOINSERT);
p = a[i].pExpr;
- zType = columnType(&sNC, p, 0, 0, 0);
/* pCol->szEst = ... // Column size est for SELECT tables never used */
pCol->affinity = sqlite3ExprAffinity(p);
+ if( pCol->affinity<=SQLITE_AFF_NONE ){
+ pCol->affinity = aff;
+ }else if( pCol->affinity>=SQLITE_AFF_NUMERIC && p->op==TK_CAST ){
+ pCol->affinity = SQLITE_AFF_FLEXNUM;
+ }
+ if( pCol->affinity>=SQLITE_AFF_TEXT && pSelect->pNext ){
+ int m = 0;
+ Select *pS2;
+ for(m=0, pS2=pSelect->pNext; pS2; pS2=pS2->pNext){
+ m |= sqlite3ExprDataType(pS2->pEList->a[i].pExpr);
+ }
+ if( pCol->affinity==SQLITE_AFF_TEXT && (m&0x01)!=0 ){
+ pCol->affinity = SQLITE_AFF_BLOB;
+ }else
+ if( pCol->affinity>=SQLITE_AFF_NUMERIC && (m&0x02)!=0 ){
+ pCol->affinity = SQLITE_AFF_BLOB;
+ }
+ }
+ if( pCol->affinity==SQLITE_AFF_NUMERIC
+ || pCol->affinity==SQLITE_AFF_FLEXNUM
+ ){
+ zType = "NUM";
+ }else{
+ zType = 0;
+ for(j=1; j<SQLITE_N_STDTYPE; j++){
+ if( sqlite3StdTypeAffinity[j]==pCol->affinity ){
+ zType = sqlite3StdType[j];
+ break;
+ }
+ }
+ }
if( zType ){
- m = sqlite3Strlen30(zType);
+ i64 m = sqlite3Strlen30(zType);
n = sqlite3Strlen30(pCol->zCnName);
pCol->zCnName = sqlite3DbReallocOrFree(db, pCol->zCnName, n+m+2);
if( pCol->zCnName ){
@@ -2341,7 +2369,6 @@ void sqlite3SelectAddColumnTypeAndCollation(
pCol->colFlags &= ~(COLFLAG_HASTYPE|COLFLAG_HASCOLL);
}
}
- if( pCol->affinity<=SQLITE_AFF_NONE ) pCol->affinity = aff;
pColl = sqlite3ExprCollSeq(pParse, p);
if( pColl ){
assert( pTab->pIndex==0 );
@@ -2375,7 +2402,7 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect, char aff){
pTab->zName = 0;
pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
sqlite3ColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol);
- sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSelect, aff);
+ sqlite3SubqueryColumnTypes(pParse, pTab, pSelect, aff);
pTab->iPKey = -1;
if( db->mallocFailed ){
sqlite3DeleteTable(db, pTab);
@@ -6186,14 +6213,14 @@ static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){
** This is a Walker.xSelectCallback callback for the sqlite3SelectTypeInfo()
** interface.
**
-** For each FROM-clause subquery, add Column.zType and Column.zColl
-** information to the Table structure that represents the result set
-** of that subquery.
+** For each FROM-clause subquery, add Column.zType, Column.zColl, and
+** Column.affinity information to the Table structure that represents
+** the result set of that subquery.
**
** The Table structure that represents the result set was constructed
-** by selectExpander() but the type and collation information was omitted
-** at that point because identifiers had not yet been resolved. This
-** routine is called after identifier resolution.
+** by selectExpander() but the type and collation and affinity information
+** was omitted at that point because identifiers had not yet been resolved.
+** This routine is called after identifier resolution.
*/
static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){
Parse *pParse;
@@ -6213,9 +6240,7 @@ static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){
/* A sub-query in the FROM clause of a SELECT */
Select *pSel = pFrom->pSelect;
if( pSel ){
- while( pSel->pPrior ) pSel = pSel->pPrior;
- sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSel,
- SQLITE_AFF_NONE);
+ sqlite3SubqueryColumnTypes(pParse, pTab, pSel, SQLITE_AFF_NONE);
}
}
}
@@ -6289,7 +6314,7 @@ static void printAggInfo(AggInfo *pAggInfo){
}
for(ii=0; ii<pAggInfo->nFunc; ii++){
sqlite3DebugPrintf("agg-func[%d]: iMem=%d\n",
- ii, AggInfoFuncReg(pAggInfo,ii));
+ ii, pAggInfo->iFirstReg+pAggInfo->nColumn+ii);
sqlite3TreeViewExpr(0, pAggInfo->aFunc[ii].pFExpr, 0);
}
}
@@ -6697,19 +6722,24 @@ static void havingToWhere(Parse *pParse, Select *p){
}
/*
-** Check to see if the pThis entry of pTabList is a self-join of a prior view.
-** If it is, then return the SrcItem for the prior view. If it is not,
-** then return 0.
+** Check to see if the pThis entry of pTabList is a self-join of another view.
+** Search FROM-clause entries in the range of iFirst..iEnd, including iFirst
+** but stopping before iEnd.
+**
+** If pThis is a self-join, then return the SrcItem for the first other
+** instance of that view found. If pThis is not a self-join then return 0.
*/
static SrcItem *isSelfJoinView(
SrcList *pTabList, /* Search for self-joins in this FROM clause */
- SrcItem *pThis /* Search for prior reference to this subquery */
+ SrcItem *pThis, /* Search for prior reference to this subquery */
+ int iFirst, int iEnd /* Range of FROM-clause entries to search. */
){
SrcItem *pItem;
assert( pThis->pSelect!=0 );
if( pThis->pSelect->selFlags & SF_PushDown ) return 0;
- for(pItem = pTabList->a; pItem<pThis; pItem++){
+ while( iFirst<iEnd ){
Select *pS1;
+ pItem = &pTabList->a[iFirst++];
if( pItem->pSelect==0 ) continue;
if( pItem->fg.viaCoroutine ) continue;
if( pItem->zName==0 ) continue;
@@ -6855,6 +6885,62 @@ static int sameSrcAlias(SrcItem *p0, SrcList *pSrc){
}
/*
+** Return TRUE (non-zero) if the i-th entry in the pTabList SrcList can
+** be implemented as a co-routine. The i-th entry is guaranteed to be
+** a subquery.
+**
+** The subquery is implemented as a co-routine if all of the following are
+** true:
+**
+** (1) The subquery will likely be implemented in the outer loop of
+** the query. This will be the case if any one of the following
+** conditions hold:
+** (a) The subquery is the only term in the FROM clause
+** (b) The subquery is the left-most term and a CROSS JOIN or similar
+** requires it to be the outer loop
+** (c) All of the following are true:
+** (i) The subquery is the left-most subquery in the FROM clause
+** (ii) There is nothing that would prevent the subquery from
+** being used as the outer loop if the sqlite3WhereBegin()
+** routine nominates it to that position.
+** (iii) The query is not a UPDATE ... FROM
+** (2) The subquery is not a CTE that should be materialized because of
+** the AS MATERIALIZED keywords
+** (3) The subquery is not part of a left operand for a RIGHT JOIN
+** (4) The SQLITE_Coroutine optimization disable flag is not set
+** (5) The subquery is not self-joined
+*/
+static int fromClauseTermCanBeCoroutine(
+ Parse *pParse, /* Parsing context */
+ SrcList *pTabList, /* FROM clause */
+ int i, /* Which term of the FROM clause holds the subquery */
+ int selFlags /* Flags on the SELECT statement */
+){
+ SrcItem *pItem = &pTabList->a[i];
+ if( pItem->fg.isCte && pItem->u2.pCteUse->eM10d==M10d_Yes ) return 0;/* (2) */
+ if( pTabList->a[0].fg.jointype & JT_LTORJ ) return 0; /* (3) */
+ if( OptimizationDisabled(pParse->db, SQLITE_Coroutines) ) return 0; /* (4) */
+ if( isSelfJoinView(pTabList, pItem, i+1, pTabList->nSrc)!=0 ){
+ return 0; /* (5) */
+ }
+ if( i==0 ){
+ if( pTabList->nSrc==1 ) return 1; /* (1a) */
+ if( pTabList->a[1].fg.jointype & JT_CROSS ) return 1; /* (1b) */
+ if( selFlags & SF_UpdateFrom ) return 0; /* (1c-iii) */
+ return 1;
+ }
+ if( selFlags & SF_UpdateFrom ) return 0; /* (1c-iii) */
+ while( 1 /*exit-by-break*/ ){
+ if( pItem->fg.jointype & (JT_OUTER|JT_CROSS) ) return 0; /* (1c-ii) */
+ if( i==0 ) break;
+ i--;
+ pItem--;
+ if( pItem->pSelect!=0 ) return 0; /* (1c-i) */
+ }
+ return 1;
+}
+
+/*
** Generate code for the SELECT statement given in the p argument.
**
** The results are returned according to the SelectDest structure.
@@ -7241,35 +7327,19 @@ int sqlite3Select(
pParse->zAuthContext = pItem->zName;
/* Generate code to implement the subquery
- **
- ** The subquery is implemented as a co-routine if all of the following are
- ** true:
- **
- ** (1) the subquery is guaranteed to be the outer loop (so that
- ** it does not need to be computed more than once), and
- ** (2) the subquery is not a CTE that should be materialized
- ** (3) the subquery is not part of a left operand for a RIGHT JOIN
*/
- if( i==0
- && (pTabList->nSrc==1
- || (pTabList->a[1].fg.jointype&(JT_OUTER|JT_CROSS))!=0) /* (1) */
- && (pItem->fg.isCte==0 || pItem->u2.pCteUse->eM10d!=M10d_Yes) /* (2) */
- && (pTabList->a[0].fg.jointype & JT_LTORJ)==0 /* (3) */
- ){
+ if( fromClauseTermCanBeCoroutine(pParse, pTabList, i, p->selFlags) ){
/* Implement a co-routine that will return a single row of the result
** set on each invocation.
*/
int addrTop = sqlite3VdbeCurrentAddr(v)+1;
-#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
- int addrExplain;
-#endif
pItem->regReturn = ++pParse->nMem;
sqlite3VdbeAddOp3(v, OP_InitCoroutine, pItem->regReturn, 0, addrTop);
VdbeComment((v, "%!S", pItem));
pItem->addrFillSub = addrTop;
sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn);
- ExplainQueryPlan2(addrExplain, (pParse, 1, "CO-ROUTINE %!S", pItem));
+ ExplainQueryPlan((pParse, 1, "CO-ROUTINE %!S", pItem));
sqlite3Select(pParse, pSub, &dest);
pItem->pTab->nRowLogEst = pSub->nSelectRow;
pItem->fg.viaCoroutine = 1;
@@ -7277,10 +7347,6 @@ int sqlite3Select(
sqlite3VdbeEndCoroutine(v, pItem->regReturn);
sqlite3VdbeJumpHere(v, addrTop-1);
sqlite3ClearTempRegCache(pParse);
- /* For SQLITE_SCANSTAT_NCYCLE, all instructions from the
- ** OP_InitCoroutine coded above until this point are attributed to
- ** the CO-ROUTINE query element. */
- sqlite3VdbeScanStatusRange(v, addrExplain, addrExplain-1, -1);
}else if( pItem->fg.isCte && pItem->u2.pCteUse->addrM9e>0 ){
/* This is a CTE for which materialization code has already been
** generated. Invoke the subroutine to compute the materialization,
@@ -7293,7 +7359,7 @@ int sqlite3Select(
VdbeComment((v, "%!S", pItem));
}
pSub->nSelectRow = pCteUse->nRowEst;
- }else if( (pPrior = isSelfJoinView(pTabList, pItem))!=0 ){
+ }else if( (pPrior = isSelfJoinView(pTabList, pItem, 0, i))!=0 ){
/* This view has already been materialized by a prior entry in
** this same FROM clause. Reuse it. */
if( pPrior->addrFillSub ){
@@ -7327,14 +7393,12 @@ int sqlite3Select(
sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
ExplainQueryPlan2(addrExplain, (pParse, 1, "MATERIALIZE %!S", pItem));
- dest.zAffSdst = sqlite3TableAffinityStr(db, pItem->pTab);
sqlite3Select(pParse, pSub, &dest);
- sqlite3DbFree(db, dest.zAffSdst);
- dest.zAffSdst = 0;
pItem->pTab->nRowLogEst = pSub->nSelectRow;
if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr);
sqlite3VdbeAddOp2(v, OP_Return, pItem->regReturn, topAddr+1);
VdbeComment((v, "end %!S", pItem));
+ sqlite3VdbeScanStatusRange(v, addrExplain, addrExplain, -1);
sqlite3VdbeJumpHere(v, topAddr);
sqlite3ClearTempRegCache(pParse);
if( pItem->fg.isCte && pItem->fg.isCorrelated==0 ){
@@ -7344,9 +7408,6 @@ int sqlite3Select(
pCteUse->iCur = pItem->iCursor;
pCteUse->nRowEst = pSub->nSelectRow;
}
- /* For SQLITE_SCANSTAT_NCYCLE, all instructions from the
- ** OP_Explain to here are attibuted to the MATERIALIZE element. */
- sqlite3VdbeScanStatusRange(v, addrExplain, addrExplain, -1);
}
if( db->mallocFailed ) goto select_end;
pParse->nHeight -= sqlite3SelectExprHeight(p);
@@ -7624,6 +7685,9 @@ int sqlite3Select(
goto select_end;
}
pAggInfo->selId = p->selId;
+#ifdef SQLITE_DEBUG
+ pAggInfo->pSelect = p;
+#endif
memset(&sNC, 0, sizeof(sNC));
sNC.pParse = pParse;
sNC.pSrcList = pTabList;
diff --git a/src/shell.c.in b/src/shell.c.in
index bb17d1c73..ae9215fda 100644
--- a/src/shell.c.in
+++ b/src/shell.c.in
@@ -21,7 +21,7 @@ typedef unsigned short int u16;
/*
** Optionally #include a user-defined header, whereby compilation options
-** may be set prior to where they take effect, but after platform setup.
+** may be set prior to where they take effect, but after platform setup.
** If SQLITE_CUSTOM_INCLUDE=? is defined, its value names the #include
** file. Note that this macro has a like effect on sqlite3.c compilation.
*/
@@ -535,20 +535,21 @@ static char *dynamicContinuePrompt(void){
return continuePrompt;
}else{
if( dynPrompt.zScannerAwaits ){
- int ncp = strlen(continuePrompt), ndp = strlen(dynPrompt.zScannerAwaits);
+ size_t ncp = strlen(continuePrompt);
+ size_t ndp = strlen(dynPrompt.zScannerAwaits);
if( ndp > ncp-3 ) return continuePrompt;
strcpy(dynPrompt.dynamicPrompt, dynPrompt.zScannerAwaits);
while( ndp<3 ) dynPrompt.dynamicPrompt[ndp++] = ' ';
strncpy(dynPrompt.dynamicPrompt+3, continuePrompt+3,
- PROMPT_LEN_MAX-4);
+ PROMPT_LEN_MAX-4);
}else{
if( dynPrompt.inParenLevel>9 ){
- strncpy(dynPrompt.dynamicPrompt, "(..", 4);
+ strncpy(dynPrompt.dynamicPrompt, "(..", 4);
}else if( dynPrompt.inParenLevel<0 ){
- strncpy(dynPrompt.dynamicPrompt, ")x!", 4);
+ strncpy(dynPrompt.dynamicPrompt, ")x!", 4);
}else{
- strncpy(dynPrompt.dynamicPrompt, "(x.", 4);
- dynPrompt.dynamicPrompt[2] = (char)('0'+dynPrompt.inParenLevel);
+ strncpy(dynPrompt.dynamicPrompt, "(x.", 4);
+ dynPrompt.dynamicPrompt[2] = (char)('0'+dynPrompt.inParenLevel);
}
strncpy(dynPrompt.dynamicPrompt+3, continuePrompt+3, PROMPT_LEN_MAX-4);
}
@@ -1033,7 +1034,7 @@ static void shellModuleSchema(
char *zFake;
UNUSED_PARAMETER(nVal);
zName = (const char*)sqlite3_value_text(apVal[0]);
- zFake = zName ? shellFakeSchema(sqlite3_context_db_handle(pCtx), 0, zName) : 0;
+ zFake = zName? shellFakeSchema(sqlite3_context_db_handle(pCtx), 0, zName) : 0;
if( zFake ){
sqlite3_result_text(pCtx, sqlite3_mprintf("/* %s */", zFake),
-1, sqlite3_free);
@@ -1132,6 +1133,13 @@ INCLUDE ../ext/misc/memtrace.c
INCLUDE ../ext/misc/shathree.c
INCLUDE ../ext/misc/uint.c
INCLUDE ../ext/misc/decimal.c
+#undef sqlite3_base_init
+#define sqlite3_base_init sqlite3_base64_init
+INCLUDE ../ext/misc/base64.c
+#undef sqlite3_base_init
+#define sqlite3_base_init sqlite3_base85_init
+#define OMIT_BASE85_CHECKER
+INCLUDE ../ext/misc/base85.c
INCLUDE ../ext/misc/ieee754.c
INCLUDE ../ext/misc/series.c
INCLUDE ../ext/misc/regexp.c
@@ -1588,7 +1596,7 @@ static void editFunc(
}
sz = j;
p[sz] = 0;
- }
+ }
sqlite3_result_text64(context, (const char*)p, sz,
sqlite3_free, SQLITE_UTF8);
}
@@ -2763,9 +2771,9 @@ static char *shell_error_context(const char *zSql, sqlite3 *db){
shell_check_oom(zCode);
for(i=0; zCode[i]; i++){ if( IsSpace(zSql[i]) ) zCode[i] = ' '; }
if( iOffset<25 ){
- zMsg = sqlite3_mprintf("\n %z\n %*s^--- error here", zCode, iOffset, "");
+ zMsg = sqlite3_mprintf("\n %z\n %*s^--- error here", zCode,iOffset,"");
}else{
- zMsg = sqlite3_mprintf("\n %z\n %*serror here ---^", zCode, iOffset-14, "");
+ zMsg = sqlite3_mprintf("\n %z\n %*serror here ---^", zCode,iOffset-14,"");
}
return zMsg;
}
@@ -2953,7 +2961,7 @@ static int display_stats(
if( pArg->statsOn==3 ){
if( pArg->pStmt ){
- iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
+ iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP,bReset);
raw_printf(pArg->out, "VM-steps: %d\n", iCur);
}
return 0;
@@ -3034,8 +3042,10 @@ static int display_stats(
raw_printf(pArg->out, "Sort Operations: %d\n", iCur);
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
raw_printf(pArg->out, "Autoindex Inserts: %d\n", iCur);
- iHit = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FILTER_HIT, bReset);
- iMiss = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FILTER_MISS, bReset);
+ iHit = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FILTER_HIT,
+ bReset);
+ iMiss = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FILTER_MISS,
+ bReset);
if( iHit || iMiss ){
raw_printf(pArg->out, "Bloom filter bypass taken: %d/%d\n",
iHit, iHit+iMiss);
@@ -3064,7 +3074,7 @@ static int display_stats(
static int scanStatsHeight(sqlite3_stmt *p, int iEntry){
int iPid = 0;
int ret = 1;
- sqlite3_stmt_scanstatus_v2(p, iEntry,
+ sqlite3_stmt_scanstatus_v2(p, iEntry,
SQLITE_SCANSTAT_SELECTID, SQLITE_SCANSTAT_COMPLEX, (void*)&iPid
);
while( iPid!=0 ){
@@ -3072,12 +3082,12 @@ static int scanStatsHeight(sqlite3_stmt *p, int iEntry){
for(ii=0; 1; ii++){
int iId;
int res;
- res = sqlite3_stmt_scanstatus_v2(p, ii,
+ res = sqlite3_stmt_scanstatus_v2(p, ii,
SQLITE_SCANSTAT_SELECTID, SQLITE_SCANSTAT_COMPLEX, (void*)&iId
);
if( res ) break;
if( iId==iPid ){
- sqlite3_stmt_scanstatus_v2(p, ii,
+ sqlite3_stmt_scanstatus_v2(p, ii,
SQLITE_SCANSTAT_PARENTID, SQLITE_SCANSTAT_COMPLEX, (void*)&iPid
);
}
@@ -3409,7 +3419,7 @@ static void bind_prepared_stmt(ShellState *pArg, sqlite3_stmt *pStmt){
** characters
*/
static void print_box_line(FILE *out, int N){
- const char zDash[] =
+ const char zDash[] =
BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24
BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24;
const int nDash = sizeof(zDash) - 1;
@@ -3538,7 +3548,7 @@ static char *translateForDisplayAndDup(
break;
}
zOut[j] = 0;
- return (char*)zOut;
+ return (char*)zOut;
}
/* Extract the value of the i-th current column for pStmt as an SQL literal
@@ -3899,8 +3909,8 @@ static void exec_prepared_stmt(
** caller to eventually free this buffer using sqlite3_free().
*/
static int expertHandleSQL(
- ShellState *pState,
- const char *zSql,
+ ShellState *pState,
+ const char *zSql,
char **pzErr
){
assert( pState->expert.pExpert );
@@ -3910,7 +3920,7 @@ static int expertHandleSQL(
/*
** This function is called either to silently clean up the object
-** created by the ".expert" command (if bCancel==1), or to generate a
+** created by the ".expert" command (if bCancel==1), or to generate a
** report from it and then clean it up (if bCancel==0).
**
** If successful, SQLITE_OK is returned. Otherwise, an SQLite error
@@ -4005,7 +4015,8 @@ static int expertDotCommand(
if( rc==SQLITE_OK ){
pState->expert.pExpert = sqlite3_expert_new(pState->db, &zErr);
if( pState->expert.pExpert==0 ){
- raw_printf(stderr, "sqlite3_expert_new: %s\n", zErr ? zErr : "out of memory");
+ raw_printf(stderr, "sqlite3_expert_new: %s\n",
+ zErr ? zErr : "out of memory");
rc = SQLITE_ERROR;
}else{
sqlite3_expert_config(
@@ -4966,7 +4977,7 @@ int deduceDatabaseType(const char *zName, int dfltZip){
}
}
fclose(f);
- return rc;
+ return rc;
}
#ifndef SQLITE_OMIT_DESERIALIZE
@@ -5065,8 +5076,8 @@ readHexDb_error:
** offset (4*<arg2>) of the blob.
*/
static void shellInt32(
- sqlite3_context *context,
- int argc,
+ sqlite3_context *context,
+ int argc,
sqlite3_value **argv
){
const unsigned char *pBlob;
@@ -5093,8 +5104,8 @@ static void shellInt32(
** using "..." with internal double-quote characters doubled.
*/
static void shellIdQuote(
- sqlite3_context *context,
- int argc,
+ sqlite3_context *context,
+ int argc,
sqlite3_value **argv
){
const char *zName = (const char*)sqlite3_value_text(argv[0]);
@@ -5109,8 +5120,8 @@ static void shellIdQuote(
** Scalar function "usleep(X)" invokes sqlite3_sleep(X) and returns X.
*/
static void shellUSleepFunc(
- sqlite3_context *context,
- int argcUnused,
+ sqlite3_context *context,
+ int argcUnused,
sqlite3_value **argv
){
int sleep = sqlite3_value_int(argv[0]);
@@ -5122,7 +5133,7 @@ static void shellUSleepFunc(
/*
** Scalar function "shell_escape_crnl" used by the .recover command.
** The argument passed to this function is the output of built-in
-** function quote(). If the first character of the input is "'",
+** function quote(). If the first character of the input is "'",
** indicating that the value passed to quote() was a text value,
** then this function searches the input for "\n" and "\r" characters
** and adds a wrapper similar to the following:
@@ -5133,8 +5144,8 @@ static void shellUSleepFunc(
** of the input is returned.
*/
static void shellEscapeCrnl(
- sqlite3_context *context,
- int argc,
+ sqlite3_context *context,
+ int argc,
sqlite3_value **argv
){
const char *zText = (const char*)sqlite3_value_text(argv[0]);
@@ -5234,13 +5245,13 @@ static void open_db(ShellState *p, int openFlags){
if( zDbFilename==0 || zDbFilename[0]==0 ){
p->openMode = SHELL_OPEN_NORMAL;
}else{
- p->openMode = (u8)deduceDatabaseType(zDbFilename,
+ p->openMode = (u8)deduceDatabaseType(zDbFilename,
(openFlags & OPEN_DB_ZIPFILE)!=0);
}
}
switch( p->openMode ){
case SHELL_OPEN_APPENDVFS: {
- sqlite3_open_v2(zDbFilename, &p->db,
+ sqlite3_open_v2(zDbFilename, &p->db,
SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|p->openFlags, "apndvfs");
break;
}
@@ -5282,6 +5293,8 @@ static void open_db(ShellState *p, int openFlags){
sqlite3_shathree_init(p->db, 0, 0);
sqlite3_uint_init(p->db, 0, 0);
sqlite3_decimal_init(p->db, 0, 0);
+ sqlite3_base64_init(p->db, 0, 0);
+ sqlite3_base85_init(p->db, 0, 0);
sqlite3_regexp_init(p->db, 0, 0);
sqlite3_ieee_init(p->db, 0, 0);
sqlite3_series_init(p->db, 0, 0);
@@ -5393,7 +5406,7 @@ void close_db(sqlite3 *db){
if( rc ){
utf8_printf(stderr, "Error: sqlite3_close() returns %d: %s\n",
rc, sqlite3_errmsg(db));
- }
+ }
}
#if HAVE_READLINE || HAVE_EDITLINE
@@ -5423,6 +5436,8 @@ static char *readline_completion_generator(const char *text, int state){
return zRet;
}
static char **readline_completion(const char *zText, int iStart, int iEnd){
+ (void)iStart;
+ (void)iEnd;
rl_attempted_completion_over = 1;
return rl_completion_matches(zText, readline_completion_generator);
}
@@ -6634,16 +6649,16 @@ static int lintDotCommand(
#if !defined SQLITE_OMIT_VIRTUALTABLE
static void shellPrepare(
- sqlite3 *db,
- int *pRc,
- const char *zSql,
+ sqlite3 *db,
+ int *pRc,
+ const char *zSql,
sqlite3_stmt **ppStmt
){
*ppStmt = 0;
if( *pRc==SQLITE_OK ){
int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0);
if( rc!=SQLITE_OK ){
- raw_printf(stderr, "sql error: %s (%d)\n",
+ raw_printf(stderr, "sql error: %s (%d)\n",
sqlite3_errmsg(db), sqlite3_errcode(db)
);
*pRc = rc;
@@ -6659,10 +6674,10 @@ static void shellPrepare(
** nuisance compiler warnings about "defined but not used".
*/
void shellPreparePrintf(
- sqlite3 *db,
- int *pRc,
+ sqlite3 *db,
+ int *pRc,
sqlite3_stmt **ppStmt,
- const char *zFmt,
+ const char *zFmt,
...
){
*ppStmt = 0;
@@ -6688,7 +6703,7 @@ void shellPreparePrintf(
** nuisance compiler warnings about "defined but not used".
*/
void shellFinalize(
- int *pRc,
+ int *pRc,
sqlite3_stmt *pStmt
){
if( pStmt ){
@@ -6710,7 +6725,7 @@ void shellFinalize(
** nuisance compiler warnings about "defined but not used".
*/
void shellReset(
- int *pRc,
+ int *pRc,
sqlite3_stmt *pStmt
){
int rc = sqlite3_reset(pStmt);
@@ -6758,7 +6773,7 @@ static int arUsage(FILE *f){
}
/*
-** Print an error message for the .ar command to stderr and return
+** Print an error message for the .ar command to stderr and return
** SQLITE_ERROR.
*/
static int arErrorMsg(ArCommand *pAr, const char *zFmt, ...){
@@ -6839,7 +6854,7 @@ static int arProcessSwitch(ArCommand *pAr, int eSwitch, const char *zArg){
/*
** Parse the command line for an ".ar" command. The results are written into
** structure (*pAr). SQLITE_OK is returned if the command line is parsed
-** successfully, otherwise an error message is written to stderr and
+** successfully, otherwise an error message is written to stderr and
** SQLITE_ERROR returned.
*/
static int arParseCommand(
@@ -7035,7 +7050,7 @@ static int arCheckEntries(ArCommand *pAr){
** when pAr->bGlob is false and GLOB match when pAr->bGlob is true.
*/
static void arWhereClause(
- int *pRc,
+ int *pRc,
ArCommand *pAr,
char **pzWhere /* OUT: New WHERE clause */
){
@@ -7050,7 +7065,7 @@ static void arWhereClause(
for(i=0; i<pAr->nArg; i++){
const char *z = pAr->azArg[i];
zWhere = sqlite3_mprintf(
- "%z%s name %s '%q' OR substr(name,1,%d) %s '%q/'",
+ "%z%s name %s '%q' OR substr(name,1,%d) %s '%q/'",
zWhere, zSep, zSameOp, z, strlen30(z)+1, zSameOp, z
);
if( zWhere==0 ){
@@ -7065,10 +7080,10 @@ static void arWhereClause(
}
/*
-** Implementation of .ar "lisT" command.
+** Implementation of .ar "lisT" command.
*/
static int arListCommand(ArCommand *pAr){
- const char *zSql = "SELECT %s FROM %s WHERE %s";
+ const char *zSql = "SELECT %s FROM %s WHERE %s";
const char *azCols[] = {
"name",
"lsmode(mode), sz, datetime(mtime, 'unixepoch'), name"
@@ -7090,7 +7105,7 @@ static int arListCommand(ArCommand *pAr){
if( pAr->bVerbose ){
utf8_printf(pAr->p->out, "%s % 10d %s %s\n",
sqlite3_column_text(pSql, 0),
- sqlite3_column_int(pSql, 1),
+ sqlite3_column_int(pSql, 1),
sqlite3_column_text(pSql, 2),
sqlite3_column_text(pSql, 3)
);
@@ -7147,17 +7162,17 @@ static int arRemoveCommand(ArCommand *pAr){
}
/*
-** Implementation of .ar "eXtract" command.
+** Implementation of .ar "eXtract" command.
*/
static int arExtractCommand(ArCommand *pAr){
- const char *zSql1 =
+ const char *zSql1 =
"SELECT "
" ($dir || name),"
" writefile(($dir || name), %s, mode, mtime) "
"FROM %s WHERE (%s) AND (data IS NULL OR $dirOnly = 0)"
" AND name NOT GLOB '*..[/\\]*'";
- const char *azExtraArg[] = {
+ const char *azExtraArg[] = {
"sqlar_uncompress(data, sz)",
"data"
};
@@ -7183,7 +7198,7 @@ static int arExtractCommand(ArCommand *pAr){
if( zDir==0 ) rc = SQLITE_NOMEM;
}
- shellPreparePrintf(pAr->db, &rc, &pSql, zSql1,
+ shellPreparePrintf(pAr->db, &rc, &pSql, zSql1,
azExtraArg[pAr->bZip], pAr->zSrcTable, zWhere
);
@@ -7261,7 +7276,7 @@ static int arCreateOrUpdateCommand(
int bUpdate, /* true for a --create. */
int bOnlyIfChanged /* Only update if file has changed */
){
- const char *zCreate =
+ const char *zCreate =
"CREATE TABLE IF NOT EXISTS sqlar(\n"
" name TEXT PRIMARY KEY, -- name of the file\n"
" mode INT, -- access permissions\n"
@@ -7303,7 +7318,7 @@ static int arCreateOrUpdateCommand(
arExecSql(pAr, "PRAGMA page_size=512");
rc = arExecSql(pAr, "SAVEPOINT ar;");
if( rc!=SQLITE_OK ) return rc;
- zTemp[0] = 0;
+ zTemp[0] = 0;
if( pAr->bZip ){
/* Initialize the zipfile virtual table, if necessary */
if( pAr->zFile ){
@@ -7397,7 +7412,7 @@ static int arDotCommand(
}else if( cmd.zFile ){
int flags;
if( cmd.bAppend ) eDbType = SHELL_OPEN_APPENDVFS;
- if( cmd.eCmd==AR_CMD_CREATE || cmd.eCmd==AR_CMD_INSERT
+ if( cmd.eCmd==AR_CMD_CREATE || cmd.eCmd==AR_CMD_INSERT
|| cmd.eCmd==AR_CMD_REMOVE || cmd.eCmd==AR_CMD_UPDATE ){
flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE;
}else{
@@ -7408,10 +7423,10 @@ static int arDotCommand(
utf8_printf(pState->out, "-- open database '%s'%s\n", cmd.zFile,
eDbType==SHELL_OPEN_APPENDVFS ? " using 'apndvfs'" : "");
}
- rc = sqlite3_open_v2(cmd.zFile, &cmd.db, flags,
+ rc = sqlite3_open_v2(cmd.zFile, &cmd.db, flags,
eDbType==SHELL_OPEN_APPENDVFS ? "apndvfs" : 0);
if( rc!=SQLITE_OK ){
- utf8_printf(stderr, "cannot open file: %s (%s)\n",
+ utf8_printf(stderr, "cannot open file: %s (%s)\n",
cmd.zFile, sqlite3_errmsg(cmd.db)
);
goto end_ar_command;
@@ -7527,7 +7542,7 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){
bRowids = 0;
}
else{
- utf8_printf(stderr, "unexpected option: %s\n", azArg[i]);
+ utf8_printf(stderr, "unexpected option: %s\n", azArg[i]);
showHelp(pState->out, azArg[0]);
return 1;
}
@@ -7890,7 +7905,7 @@ static int do_meta_command(char *zLine, ShellState *p){
return 1;
}
if( zDb==0 ) zDb = "main";
- rc = sqlite3_open_v2(zDestFile, &pDest,
+ rc = sqlite3_open_v2(zDestFile, &pDest,
SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, zVfs);
if( rc!=SQLITE_OK ){
utf8_printf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
@@ -8140,7 +8155,7 @@ static int do_meta_command(char *zLine, ShellState *p){
if( nArg>1 && ii==ArraySize(aDbConfig) ){
utf8_printf(stderr, "Error: unknown dbconfig \"%s\"\n", azArg[1]);
utf8_printf(stderr, "Enter \".dbconfig\" with no arguments for a list\n");
- }
+ }
}else
#if SQLITE_SHELL_HAVE_RECOVER
@@ -8207,7 +8222,7 @@ static int do_meta_command(char *zLine, ShellState *p){
" substr(o.name, 1, length(name)+1) == (name||'_')"
")", azArg[i], azArg[i]
);
-
+
if( zLike ){
zLike = sqlite3_mprintf("%z OR %z", zLike, zExpr);
}else{
@@ -8340,7 +8355,7 @@ static int do_meta_command(char *zLine, ShellState *p){
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( c=='e' && cli_strncmp(azArg[0], "expert", n)==0 ){
if( p->bSafeMode ){
- raw_printf(stderr,
+ raw_printf(stderr,
"Cannot run experimental commands such as \"%s\" in safe mode\n",
azArg[0]);
rc = 1;
@@ -8359,7 +8374,7 @@ static int do_meta_command(char *zLine, ShellState *p){
} aCtrl[] = {
{ "chunk_size", SQLITE_FCNTL_CHUNK_SIZE, "SIZE" },
{ "data_version", SQLITE_FCNTL_DATA_VERSION, "" },
- { "has_moved", SQLITE_FCNTL_HAS_MOVED, "" },
+ { "has_moved", SQLITE_FCNTL_HAS_MOVED, "" },
{ "lock_timeout", SQLITE_FCNTL_LOCK_TIMEOUT, "MILLISEC" },
{ "persist_wal", SQLITE_FCNTL_PERSIST_WAL, "[BOOLEAN]" },
/* { "pragma", SQLITE_FCNTL_PRAGMA, "NAME ARG" },*/
@@ -8380,7 +8395,7 @@ static int do_meta_command(char *zLine, ShellState *p){
open_db(p, 0);
zCmd = nArg>=2 ? azArg[1] : "help";
- if( zCmd[0]=='-'
+ if( zCmd[0]=='-'
&& (cli_strcmp(zCmd,"--schema")==0 || cli_strcmp(zCmd,"-schema")==0)
&& nArg>=4
){
@@ -9758,7 +9773,8 @@ static int do_meta_command(char *zLine, ShellState *p){
}else if( zName==0 ){
zName = azArg[ii];
}else{
- raw_printf(stderr, "Usage: .schema ?--indent? ?--nosys? ?LIKE-PATTERN?\n");
+ raw_printf(stderr,
+ "Usage: .schema ?--indent? ?--nosys? ?LIKE-PATTERN?\n");
rc = 1;
goto meta_command_exit;
}
@@ -9874,7 +9890,7 @@ static int do_meta_command(char *zLine, ShellState *p){
if( (c=='s' && n==11 && cli_strncmp(azArg[0], "selecttrace", n)==0)
|| (c=='t' && n==9 && cli_strncmp(azArg[0], "treetrace", n)==0)
){
- unsigned int x = nArg>=2 ? (unsigned int)integerValue(azArg[1]) : 0xffffffff;
+ unsigned int x = nArg>=2? (unsigned int)integerValue(azArg[1]) : 0xffffffff;
sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, &x);
}else
@@ -10059,7 +10075,8 @@ static int do_meta_command(char *zLine, ShellState *p){
}
}
if( pAuxDb->nSession>=ArraySize(pAuxDb->aSession) ){
- raw_printf(stderr, "Maximum of %d sessions\n", ArraySize(pAuxDb->aSession));
+ raw_printf(stderr,
+ "Maximum of %d sessions\n", ArraySize(pAuxDb->aSession));
goto meta_command_exit;
}
pSession = &pAuxDb->aSession[pAuxDb->nSession];
@@ -10343,26 +10360,26 @@ static int do_meta_command(char *zLine, ShellState *p){
{
int lrc;
char *zRevText = /* Query for reversible to-blob-to-text check */
- "SELECT lower(name) as tname FROM sqlite_schema\n"
- "WHERE type='table' AND coalesce(rootpage,0)>1\n"
- "AND name NOT LIKE 'sqlite_%%'%s\n"
- "ORDER BY 1 collate nocase";
+ "SELECT lower(name) as tname FROM sqlite_schema\n"
+ "WHERE type='table' AND coalesce(rootpage,0)>1\n"
+ "AND name NOT LIKE 'sqlite_%%'%s\n"
+ "ORDER BY 1 collate nocase";
zRevText = sqlite3_mprintf(zRevText, zLike? " AND name LIKE $tspec" : "");
zRevText = sqlite3_mprintf(
- /* lower-case query is first run, producing upper-case query. */
- "with tabcols as materialized(\n"
- "select tname, cname\n"
- "from ("
- " select ss.tname as tname, ti.name as cname\n"
- " from (%z) ss\n inner join pragma_table_info(tname) ti))\n"
- "select 'SELECT total(bad_text_count) AS bad_text_count\n"
- "FROM ('||group_concat(query, ' UNION ALL ')||')' as btc_query\n"
- " from (select 'SELECT COUNT(*) AS bad_text_count\n"
- "FROM '||tname||' WHERE '\n"
- "||group_concat('CAST(CAST('||cname||' AS BLOB) AS TEXT)<>'||cname\n"
- "|| ' AND typeof('||cname||')=''text'' ',\n"
- "' OR ') as query, tname from tabcols group by tname)"
- , zRevText);
+ /* lower-case query is first run, producing upper-case query. */
+ "with tabcols as materialized(\n"
+ "select tname, cname\n"
+ "from ("
+ " select ss.tname as tname, ti.name as cname\n"
+ " from (%z) ss\n inner join pragma_table_info(tname) ti))\n"
+ "select 'SELECT total(bad_text_count) AS bad_text_count\n"
+ "FROM ('||group_concat(query, ' UNION ALL ')||')' as btc_query\n"
+ " from (select 'SELECT COUNT(*) AS bad_text_count\n"
+ "FROM '||tname||' WHERE '\n"
+ "||group_concat('CAST(CAST('||cname||' AS BLOB) AS TEXT)<>'||cname\n"
+ "|| ' AND typeof('||cname||')=''text'' ',\n"
+ "' OR ') as query, tname from tabcols group by tname)"
+ , zRevText);
shell_check_oom(zRevText);
if( bDebug ) utf8_printf(p->out, "%s\n", zRevText);
lrc = sqlite3_prepare_v2(p->db, zRevText, -1, &pStmt, 0);
@@ -10375,16 +10392,16 @@ static int do_meta_command(char *zLine, ShellState *p){
lrc = sqlite3_prepare_v2(p->db, zGenQuery, -1, &pCheckStmt, 0);
if( bDebug ) utf8_printf(p->out, "%s\n", zGenQuery);
if( SQLITE_OK==lrc ){
- if( SQLITE_ROW==sqlite3_step(pCheckStmt) ){
- double countIrreversible = sqlite3_column_double(pCheckStmt, 0);
- if( countIrreversible>0 ){
- int n = (int)(countIrreversible + 0.5);
- utf8_printf(stderr,
- "Digest includes %d invalidly encoded text field%s.\n",
- n, (n>1)? "s": "");
- }
- }
- sqlite3_finalize(pCheckStmt);
+ if( SQLITE_ROW==sqlite3_step(pCheckStmt) ){
+ double countIrreversible = sqlite3_column_double(pCheckStmt, 0);
+ if( countIrreversible>0 ){
+ int sz = (int)(countIrreversible + 0.5);
+ utf8_printf(stderr,
+ "Digest includes %d invalidly encoded text field%s.\n",
+ sz, (sz>1)? "s": "");
+ }
+ }
+ sqlite3_finalize(pCheckStmt);
}
sqlite3_finalize(pStmt);
}
@@ -10620,28 +10637,28 @@ static int do_meta_command(char *zLine, ShellState *p){
int unSafe; /* Not valid for --safe mode */
const char *zUsage; /* Usage notes */
} aCtrl[] = {
- { "always", SQLITE_TESTCTRL_ALWAYS, 1, "BOOLEAN" },
- { "assert", SQLITE_TESTCTRL_ASSERT, 1, "BOOLEAN" },
- /*{ "benign_malloc_hooks",SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS,1, "" },*/
- /*{ "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST, 1, "" },*/
- { "byteorder", SQLITE_TESTCTRL_BYTEORDER, 0, "" },
- { "extra_schema_checks",SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS,0,"BOOLEAN" },
- /*{ "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, 1,"" },*/
- { "imposter", SQLITE_TESTCTRL_IMPOSTER,1,"SCHEMA ON/OFF ROOTPAGE"},
- { "internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS,0,"" },
- { "localtime_fault", SQLITE_TESTCTRL_LOCALTIME_FAULT,0,"BOOLEAN" },
- { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT,1, "BOOLEAN" },
- { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS,0,"DISABLE-MASK" },
+ {"always", SQLITE_TESTCTRL_ALWAYS, 1, "BOOLEAN" },
+ {"assert", SQLITE_TESTCTRL_ASSERT, 1, "BOOLEAN" },
+ /*{"benign_malloc_hooks",SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS,1, "" },*/
+ /*{"bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST, 1, "" },*/
+ {"byteorder", SQLITE_TESTCTRL_BYTEORDER, 0, "" },
+ {"extra_schema_checks",SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS,0,"BOOLEAN" },
+ /*{"fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, 1,"" },*/
+ {"imposter", SQLITE_TESTCTRL_IMPOSTER,1,"SCHEMA ON/OFF ROOTPAGE"},
+ {"internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS,0,"" },
+ {"localtime_fault", SQLITE_TESTCTRL_LOCALTIME_FAULT,0,"BOOLEAN" },
+ {"never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT,1, "BOOLEAN" },
+ {"optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS,0,"DISABLE-MASK" },
#ifdef YYCOVERAGE
- { "parser_coverage", SQLITE_TESTCTRL_PARSER_COVERAGE,0,"" },
-#endif
- { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE,0, "OFFSET " },
- { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE,0, "" },
- { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE, 0, "" },
- { "prng_seed", SQLITE_TESTCTRL_PRNG_SEED, 0, "SEED ?db?" },
- { "seek_count", SQLITE_TESTCTRL_SEEK_COUNT, 0, "" },
- { "sorter_mmap", SQLITE_TESTCTRL_SORTER_MMAP, 0, "NMAX" },
- { "tune", SQLITE_TESTCTRL_TUNE, 1, "ID VALUE" },
+ {"parser_coverage", SQLITE_TESTCTRL_PARSER_COVERAGE,0,"" },
+#endif
+ {"pending_byte", SQLITE_TESTCTRL_PENDING_BYTE,0, "OFFSET " },
+ {"prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE,0, "" },
+ {"prng_save", SQLITE_TESTCTRL_PRNG_SAVE, 0, "" },
+ {"prng_seed", SQLITE_TESTCTRL_PRNG_SEED, 0, "SEED ?db?" },
+ {"seek_count", SQLITE_TESTCTRL_SEEK_COUNT, 0, "" },
+ {"sorter_mmap", SQLITE_TESTCTRL_SORTER_MMAP, 0, "NMAX" },
+ {"tune", SQLITE_TESTCTRL_TUNE, 1, "ID VALUE" },
};
int testctrl = -1;
int iCtrl = -1;
@@ -11066,7 +11083,7 @@ static int do_meta_command(char *zLine, ShellState *p){
}else
if( c=='w' && cli_strncmp(azArg[0], "wheretrace", n)==0 ){
- unsigned int x = nArg>=2 ? (unsigned int)integerValue(azArg[1]) : 0xffffffff;
+ unsigned int x = nArg>=2? (unsigned int)integerValue(azArg[1]) : 0xffffffff;
sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 3, &x);
}else
@@ -11119,7 +11136,7 @@ typedef enum {
** return values are passed as the 2nd argument.
*/
static QuickScanState quickscan(char *zLine, QuickScanState qss,
- SCAN_TRACKER_REFTYPE pst){
+ SCAN_TRACKER_REFTYPE pst){
char cin;
char cWait = (char)qss; /* intentional narrowing loss */
if( cWait==0 ){
@@ -11143,7 +11160,7 @@ static QuickScanState quickscan(char *zLine, QuickScanState qss,
if( *zLine=='*' ){
++zLine;
cWait = '*';
- CONTINUE_PROMPT_AWAITS(pst, "/*");
+ CONTINUE_PROMPT_AWAITS(pst, "/*");
qss = QSS_SETV(qss, cWait);
goto TermScan;
}
@@ -11154,14 +11171,14 @@ static QuickScanState quickscan(char *zLine, QuickScanState qss,
case '`': case '\'': case '"':
cWait = cin;
qss = QSS_HasDark | cWait;
- CONTINUE_PROMPT_AWAITC(pst, cin);
+ CONTINUE_PROMPT_AWAITC(pst, cin);
goto TermScan;
case '(':
- CONTINUE_PAREN_INCR(pst, 1);
- break;
+ CONTINUE_PAREN_INCR(pst, 1);
+ break;
case ')':
- CONTINUE_PAREN_INCR(pst, -1);
- break;
+ CONTINUE_PAREN_INCR(pst, -1);
+ break;
default:
break;
}
@@ -11177,19 +11194,19 @@ static QuickScanState quickscan(char *zLine, QuickScanState qss,
continue;
++zLine;
cWait = 0;
- CONTINUE_PROMPT_AWAITC(pst, 0);
+ CONTINUE_PROMPT_AWAITC(pst, 0);
qss = QSS_SETV(qss, 0);
goto PlainScan;
case '`': case '\'': case '"':
if(*zLine==cWait){
- /* Swallow doubled end-delimiter.*/
+ /* Swallow doubled end-delimiter.*/
++zLine;
continue;
}
/* fall thru */
case ']':
cWait = 0;
- CONTINUE_PROMPT_AWAITC(pst, 0);
+ CONTINUE_PROMPT_AWAITC(pst, 0);
qss = QSS_SETV(qss, 0);
goto PlainScan;
default: assert(0);
@@ -11294,9 +11311,9 @@ static void echo_group_input(ShellState *p, const char *zDo){
#ifdef SQLITE_SHELL_FIDDLE
/*
-** Alternate one_input_line() impl for wasm mode. This is not in the primary impl
-** because we need the global shellState and cannot access it from that function
-** without moving lots of code around (creating a larger/messier diff).
+** Alternate one_input_line() impl for wasm mode. This is not in the primary
+** impl because we need the global shellState and cannot access it from that
+** function without moving lots of code around (creating a larger/messier diff).
*/
static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
/* Parse the next line from shellState.wasm.zInput. */
@@ -12115,12 +12132,12 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
data.openFlags |= SQLITE_OPEN_NOFOLLOW;
}else if( cli_strcmp(z,"-ascii")==0 ){
data.mode = MODE_Ascii;
- sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, SEP_Unit);
- sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator, SEP_Record);
+ sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,SEP_Unit);
+ sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,SEP_Record);
}else if( cli_strcmp(z,"-tabs")==0 ){
data.mode = MODE_List;
- sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, SEP_Tab);
- sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator, SEP_Row);
+ sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,SEP_Tab);
+ sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,SEP_Row);
}else if( cli_strcmp(z,"-separator")==0 ){
sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
"%s",cmdline_option_value(argc,argv,++i));
diff --git a/src/sqlite.h.in b/src/sqlite.h.in
index 355e4f9b7..210a728c5 100644
--- a/src/sqlite.h.in
+++ b/src/sqlite.h.in
@@ -563,6 +563,7 @@ int sqlite3_exec(
#define SQLITE_CONSTRAINT_DATATYPE (SQLITE_CONSTRAINT |(12<<8))
#define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8))
#define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
+#define SQLITE_NOTICE_RBU (SQLITE_NOTICE | (3<<8))
#define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8))
#define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8))
#define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8))
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 5a19058bd..838c6e7b5 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -973,9 +973,9 @@ typedef INT16_TYPE LogEst;
** pointers. In that case, only verify 4-byte alignment.
*/
#ifdef SQLITE_4_BYTE_ALIGNED_MALLOC
-# define EIGHT_BYTE_ALIGNMENT(X) ((((char*)(X) - (char*)0)&3)==0)
+# define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&3)==0)
#else
-# define EIGHT_BYTE_ALIGNMENT(X) ((((char*)(X) - (char*)0)&7)==0)
+# define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&7)==0)
#endif
/*
@@ -1844,6 +1844,7 @@ struct sqlite3 {
#define SQLITE_FlttnUnionAll 0x00800000 /* Disable the UNION ALL flattener */
/* TH3 expects this value ^^^^^^^^^^ See flatten04.test */
#define SQLITE_IndexedExpr 0x01000000 /* Pull exprs from index when able */
+#define SQLITE_Coroutines 0x02000000 /* Co-routines for subqueries */
#define SQLITE_AllOpts 0xffffffff /* All optimizations */
/*
@@ -2238,6 +2239,7 @@ struct CollSeq {
#define SQLITE_AFF_NUMERIC 0x43 /* 'C' */
#define SQLITE_AFF_INTEGER 0x44 /* 'D' */
#define SQLITE_AFF_REAL 0x45 /* 'E' */
+#define SQLITE_AFF_FLEXNUM 0x46 /* 'F' */
#define sqlite3IsNumericAffinity(X) ((X)>=SQLITE_AFF_NUMERIC)
@@ -2793,6 +2795,9 @@ struct AggInfo {
} *aFunc;
int nFunc; /* Number of entries in aFunc[] */
u32 selId; /* Select to which this AggInfo belongs */
+#ifdef SQLITE_DEBUG
+ Select *pSelect; /* SELECT statement that this AggInfo supports */
+#endif
};
/*
@@ -3465,6 +3470,7 @@ struct Select {
#define SF_MultiPart 0x2000000 /* Has multiple incompatible PARTITIONs */
#define SF_CopyCte 0x4000000 /* SELECT statement is a copy of a CTE */
#define SF_OrderByReqd 0x8000000 /* The ORDER BY clause may not be omitted */
+#define SF_UpdateFrom 0x10000000 /* Query originates with UPDATE FROM */
/* True if S exists and has SF_NestedFrom */
#define IsNestedFrom(S) ((S)!=0 && ((S)->selFlags&SF_NestedFrom)!=0)
@@ -3573,7 +3579,7 @@ struct SelectDest {
int iSDParm2; /* A second parameter for the eDest disposal method */
int iSdst; /* Base register where results are written */
int nSdst; /* Number of registers allocated */
- char *zAffSdst; /* Affinity used for SRT_Set, SRT_Table, and similar */
+ char *zAffSdst; /* Affinity used for SRT_Set */
ExprList *pOrderBy; /* Key columns for SRT_Queue and SRT_DistQueue */
};
@@ -3632,10 +3638,10 @@ struct TriggerPrg {
#else
typedef unsigned int yDbMask;
# define DbMaskTest(M,I) (((M)&(((yDbMask)1)<<(I)))!=0)
-# define DbMaskZero(M) (M)=0
-# define DbMaskSet(M,I) (M)|=(((yDbMask)1)<<(I))
-# define DbMaskAllZero(M) (M)==0
-# define DbMaskNonZero(M) (M)!=0
+# define DbMaskZero(M) ((M)=0)
+# define DbMaskSet(M,I) ((M)|=(((yDbMask)1)<<(I)))
+# define DbMaskAllZero(M) ((M)==0)
+# define DbMaskNonZero(M) ((M)!=0)
#endif
/*
@@ -4678,7 +4684,7 @@ const char *sqlite3ColumnColl(Column*);
void sqlite3DeleteColumnNames(sqlite3*,Table*);
void sqlite3GenerateColumnNames(Parse *pParse, Select *pSelect);
int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**);
-void sqlite3SelectAddColumnTypeAndCollation(Parse*,Table*,Select*,char);
+void sqlite3SubqueryColumnTypes(Parse*,Table*,Select*,char);
Table *sqlite3ResultSetOfSelect(Parse*,Select*,char);
void sqlite3OpenSchemaTable(Parse *, int);
Index *sqlite3PrimaryKeyIndex(Table*);
@@ -5049,6 +5055,7 @@ char sqlite3CompareAffinity(const Expr *pExpr, char aff2);
int sqlite3IndexAffinityOk(const Expr *pExpr, char idx_affinity);
char sqlite3TableColumnAffinity(const Table*,int);
char sqlite3ExprAffinity(const Expr *pExpr);
+int sqlite3ExprDataType(const Expr *pExpr);
int sqlite3Atoi64(const char*, i64*, int, u8);
int sqlite3DecOrHexToI64(const char*, i64*);
void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...);
@@ -5207,7 +5214,7 @@ int sqlite3ApiExit(sqlite3 *db, int);
int sqlite3OpenTempDatabase(Parse *);
void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int);
-int sqlite3StrAccumEnlarge(StrAccum*, int);
+int sqlite3StrAccumEnlarge(StrAccum*, i64);
char *sqlite3StrAccumFinish(StrAccum*);
void sqlite3StrAccumSetError(StrAccum*, u8);
void sqlite3ResultStrAccum(sqlite3_context*,StrAccum*);
diff --git a/src/update.c b/src/update.c
index 809b30653..a4e57d1d4 100644
--- a/src/update.c
+++ b/src/update.c
@@ -263,7 +263,8 @@ static void updateFromSelect(
}
}
pSelect = sqlite3SelectNew(pParse, pList,
- pSrc, pWhere2, pGrp, 0, pOrderBy2, SF_UFSrcCheck|SF_IncludeHidden, pLimit2
+ pSrc, pWhere2, pGrp, 0, pOrderBy2,
+ SF_UFSrcCheck|SF_IncludeHidden|SF_UpdateFrom, pLimit2
);
if( pSelect ) pSelect->selFlags |= SF_OrderByReqd;
sqlite3SelectDestInit(&dest, eDest, iEph);
diff --git a/src/vdbe.c b/src/vdbe.c
index 12b22992b..7705b68ec 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -133,6 +133,9 @@ int sqlite3_found_count = 0;
*/
static void test_trace_breakpoint(int pc, Op *pOp, Vdbe *v){
static int n = 0;
+ (void)pc;
+ (void)pOp;
+ (void)v;
n++;
}
#endif
@@ -371,6 +374,10 @@ static void applyNumericAffinity(Mem *pRec, int bTryForInt){
** always preferred, even if the affinity is REAL, because
** an integer representation is more space efficient on disk.
**
+** SQLITE_AFF_FLEXNUM:
+** If the value is text, then try to convert it into a number of
+** some kind (integer or real) but do not make any other changes.
+**
** SQLITE_AFF_TEXT:
** Convert pRec to a text representation.
**
@@ -385,11 +392,11 @@ static void applyAffinity(
){
if( affinity>=SQLITE_AFF_NUMERIC ){
assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL
- || affinity==SQLITE_AFF_NUMERIC );
+ || affinity==SQLITE_AFF_NUMERIC || affinity==SQLITE_AFF_FLEXNUM );
if( (pRec->flags & MEM_Int)==0 ){ /*OPTIMIZATION-IF-FALSE*/
if( (pRec->flags & MEM_Real)==0 ){
if( pRec->flags & MEM_Str ) applyNumericAffinity(pRec,1);
- }else{
+ }else if( affinity<=SQLITE_AFF_REAL ){
sqlite3VdbeIntegerAffinity(pRec);
}
}
@@ -709,6 +716,7 @@ int sqlite3VdbeExec(
#ifdef SQLITE_DEBUG
Op *pOrigOp; /* Value of pOp at the top of the loop */
int nExtraDelete = 0; /* Verifies FORDELETE and AUXDELETE flags */
+ u8 iCompareIsInit = 0; /* iCompare is initialized */
#endif
int rc = SQLITE_OK; /* Value to return */
sqlite3 *db = p->db; /* The database */
@@ -730,7 +738,9 @@ int sqlite3VdbeExec(
/*** INSERT STACK UNION HERE ***/
assert( p->eVdbeState==VDBE_RUN_STATE ); /* sqlite3_step() verifies this */
- sqlite3VdbeEnter(p);
+ if( DbMaskNonZero(p->lockMask) ){
+ sqlite3VdbeEnter(p);
+ }
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
if( db->xProgress ){
u32 iPrior = p->aCounter[SQLITE_STMTSTATUS_VM_STEP];
@@ -751,7 +761,6 @@ int sqlite3VdbeExec(
assert( p->bIsReader || p->readOnly!=0 );
p->iCurrentTime = 0;
assert( p->explain==0 );
- p->pResultSet = 0;
db->busyHandler.nBusy = 0;
if( AtomicLoad(&db->u1.isInterrupted) ) goto abort_due_to_interrupt;
sqlite3VdbeIOTraceSql(p);
@@ -1582,10 +1591,10 @@ case OP_ResultRow: {
assert( pOp->p1+pOp->p2<=(p->nMem+1 - p->nCursor)+1 );
p->cacheCtr = (p->cacheCtr + 2)|1;
- p->pResultSet = &aMem[pOp->p1];
+ p->pResultRow = &aMem[pOp->p1];
#ifdef SQLITE_DEBUG
{
- Mem *pMem = p->pResultSet;
+ Mem *pMem = p->pResultRow;
int i;
for(i=0; i<pOp->p2; i++){
assert( memIsValid(&pMem[i]) );
@@ -2115,7 +2124,6 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
flags1 = pIn1->flags;
flags3 = pIn3->flags;
if( (flags1 & flags3 & MEM_Int)!=0 ){
- assert( (pOp->p5 & SQLITE_AFF_MASK)!=SQLITE_AFF_TEXT || CORRUPT_DB );
/* Common case of comparison of two integers */
if( pIn3->u.i > pIn1->u.i ){
if( sqlite3aGTb[pOp->opcode] ){
@@ -2123,18 +2131,21 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
goto jump_to_p2;
}
iCompare = +1;
+ VVA_ONLY( iCompareIsInit = 1; )
}else if( pIn3->u.i < pIn1->u.i ){
if( sqlite3aLTb[pOp->opcode] ){
VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3);
goto jump_to_p2;
}
iCompare = -1;
+ VVA_ONLY( iCompareIsInit = 1; )
}else{
if( sqlite3aEQb[pOp->opcode] ){
VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3);
goto jump_to_p2;
}
iCompare = 0;
+ VVA_ONLY( iCompareIsInit = 1; )
}
VdbeBranchTaken(0, (pOp->p5 & SQLITE_NULLEQ)?2:3);
break;
@@ -2166,6 +2177,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
goto jump_to_p2;
}
iCompare = 1; /* Operands are not equal */
+ VVA_ONLY( iCompareIsInit = 1; )
break;
}
}else{
@@ -2183,7 +2195,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
applyNumericAffinity(pIn3,0);
}
}
- }else if( affinity==SQLITE_AFF_TEXT ){
+ }else if( affinity==SQLITE_AFF_TEXT && ((flags1 | flags3) & MEM_Str)!=0 ){
if( (flags1 & MEM_Str)==0 && (flags1&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){
testcase( pIn1->flags & MEM_Int );
testcase( pIn1->flags & MEM_Real );
@@ -2191,7 +2203,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
sqlite3VdbeMemStringify(pIn1, encoding, 1);
testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) );
flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask);
- if( pIn1==pIn3 ) flags3 = flags1 | MEM_Str;
+ if( NEVER(pIn1==pIn3) ) flags3 = flags1 | MEM_Str;
}
if( (flags3 & MEM_Str)==0 && (flags3&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){
testcase( pIn3->flags & MEM_Int );
@@ -2222,6 +2234,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
res2 = sqlite3aGTb[pOp->opcode];
}
iCompare = res;
+ VVA_ONLY( iCompareIsInit = 1; )
/* Undo any changes made by applyAffinity() to the input registers. */
assert( (pIn3->flags & MEM_Dyn) == (flags3 & MEM_Dyn) );
@@ -2260,6 +2273,7 @@ case OP_ElseEq: { /* same as TK_ESCAPE, jump */
break;
}
#endif /* SQLITE_DEBUG */
+ assert( iCompareIsInit );
VdbeBranchTaken(iCompare==0, 2);
if( iCompare==0 ) goto jump_to_p2;
break;
@@ -2354,6 +2368,7 @@ case OP_Compare: {
pColl = pKeyInfo->aColl[i];
bRev = (pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_DESC);
iCompare = sqlite3MemCompare(&aMem[p1+idx], &aMem[p2+idx], pColl);
+ VVA_ONLY( iCompareIsInit = 1; )
if( iCompare ){
if( (pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_BIGNULL)
&& ((aMem[p1+idx].flags & MEM_Null) || (aMem[p2+idx].flags & MEM_Null))
@@ -2378,6 +2393,7 @@ case OP_Compare: {
*/
case OP_Jump: { /* jump */
assert( pOp>aOp && pOp[-1].opcode==OP_Compare );
+ assert( iCompareIsInit );
if( iCompare<0 ){
VdbeBranchTaken(0,4); pOp = &aOp[pOp->p1 - 1];
}else if( iCompare==0 ){
@@ -5556,8 +5572,11 @@ case OP_Insert: {
if( pOp->p5 & OPFLAG_ISNOOP ) break;
#endif
- if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
- if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = x.nKey;
+ assert( (pOp->p5 & OPFLAG_LASTROWID)==0 || (pOp->p5 & OPFLAG_NCHANGE)!=0 );
+ if( pOp->p5 & OPFLAG_NCHANGE ){
+ p->nChange++;
+ if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = x.nKey;
+ }
assert( (pData->flags & (MEM_Blob|MEM_Str))!=0 || pData->n==0 );
x.pData = pData->z;
x.nData = pData->n;
@@ -8824,7 +8843,9 @@ vdbe_return:
}
#endif
p->aCounter[SQLITE_STMTSTATUS_VM_STEP] += (int)nVmStep;
- sqlite3VdbeLeave(p);
+ if( DbMaskNonZero(p->lockMask) ){
+ sqlite3VdbeLeave(p);
+ }
assert( rc!=SQLITE_OK || nExtraDelete==0
|| sqlite3_strlike("DELETE%",p->zSql,0)!=0
);
diff --git a/src/vdbeInt.h b/src/vdbeInt.h
index cd112e9c4..03f4ec542 100644
--- a/src/vdbeInt.h
+++ b/src/vdbeInt.h
@@ -454,7 +454,7 @@ struct Vdbe {
int nOp; /* Number of instructions in the program */
int nOpAlloc; /* Slots allocated for aOp[] */
Mem *aColName; /* Column names to return */
- Mem *pResultSet; /* Pointer to an array of results */
+ Mem *pResultRow; /* Current output row */
char *zErrMsg; /* Error message written here */
VList *pVList; /* Name of variables */
#ifndef SQLITE_OMIT_TRACE
diff --git a/src/vdbeapi.c b/src/vdbeapi.c
index 414745e8b..e080449c5 100644
--- a/src/vdbeapi.c
+++ b/src/vdbeapi.c
@@ -753,7 +753,7 @@ static int sqlite3Step(Vdbe *p){
/* If the statement completed successfully, invoke the profile callback */
checkProfileCallback(db, p);
#endif
-
+ p->pResultRow = 0;
if( rc==SQLITE_DONE && db->autoCommit ){
assert( p->rc==SQLITE_OK );
p->rc = doWalCallbacks(db);
@@ -1117,7 +1117,7 @@ int sqlite3_column_count(sqlite3_stmt *pStmt){
*/
int sqlite3_data_count(sqlite3_stmt *pStmt){
Vdbe *pVm = (Vdbe *)pStmt;
- if( pVm==0 || pVm->pResultSet==0 ) return 0;
+ if( pVm==0 || pVm->pResultRow==0 ) return 0;
return pVm->nResColumn;
}
@@ -1172,8 +1172,8 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){
if( pVm==0 ) return (Mem*)columnNullValue();
assert( pVm->db );
sqlite3_mutex_enter(pVm->db->mutex);
- if( pVm->pResultSet!=0 && i<pVm->nResColumn && i>=0 ){
- pOut = &pVm->pResultSet[i];
+ if( pVm->pResultRow!=0 && i<pVm->nResColumn && i>=0 ){
+ pOut = &pVm->pResultRow[i];
}else{
sqlite3Error(pVm->db, SQLITE_RANGE);
pOut = (Mem*)columnNullValue();
diff --git a/src/vdbeaux.c b/src/vdbeaux.c
index 8d284746f..ca9e5112a 100644
--- a/src/vdbeaux.c
+++ b/src/vdbeaux.c
@@ -212,6 +212,8 @@ static int growOpArray(Vdbe *v, int nOp){
*/
static void test_addop_breakpoint(int pc, Op *pOp){
static int n = 0;
+ (void)pc;
+ (void)pOp;
n++;
}
#endif
@@ -2316,7 +2318,6 @@ int sqlite3VdbeList(
** sqlite3_column_text16(), causing a translation to UTF-16 encoding.
*/
releaseMemArray(pMem, 8);
- p->pResultSet = 0;
if( p->rc==SQLITE_NOMEM ){
/* This happens if a malloc() inside a call to sqlite3_column_text() or
@@ -2373,7 +2374,7 @@ int sqlite3VdbeList(
sqlite3VdbeMemSetStr(pMem+5, zP4, -1, SQLITE_UTF8, sqlite3_free);
p->nResColumn = 8;
}
- p->pResultSet = pMem;
+ p->pResultRow = pMem;
if( db->mallocFailed ){
p->rc = SQLITE_NOMEM;
rc = SQLITE_ERROR;
@@ -3505,7 +3506,7 @@ int sqlite3VdbeReset(Vdbe *p){
sqlite3DbFree(db, p->zErrMsg);
p->zErrMsg = 0;
}
- p->pResultSet = 0;
+ p->pResultRow = 0;
#ifdef SQLITE_DEBUG
p->nWrite = 0;
#endif
diff --git a/src/vdbevtab.c b/src/vdbevtab.c
index e9bafd450..6557d8cb0 100644
--- a/src/vdbevtab.c
+++ b/src/vdbevtab.c
@@ -83,6 +83,9 @@ static int bytecodevtabConnect(
");"
};
+ (void)argc;
+ (void)argv;
+ (void)pzErr;
rc = sqlite3_declare_vtab(db, azSchema[isTabUsed]);
if( rc==SQLITE_OK ){
pNew = sqlite3_malloc( sizeof(*pNew) );
@@ -318,6 +321,7 @@ static int bytecodevtabFilter(
bytecodevtab_cursor *pCur = (bytecodevtab_cursor *)pVtabCursor;
bytecodevtab *pVTab = (bytecodevtab *)pVtabCursor->pVtab;
int rc = SQLITE_OK;
+ (void)idxStr;
bytecodevtabCursorClear(pCur);
pCur->iRowid = 0;
diff --git a/src/where.c b/src/where.c
index 25ad18b28..890c3bf52 100644
--- a/src/where.c
+++ b/src/where.c
@@ -836,7 +836,8 @@ static void explainAutomaticIndex(
const char *zSep = "";
char *zText = 0;
int ii = 0;
- zText = sqlite3_mprintf("CREATE AUTOMATIC INDEX ON %s(", pTab->zName);
+ sqlite3_str *pStr = sqlite3_str_new(pParse->db);
+ sqlite3_str_appendf(pStr,"CREATE AUTOMATIC INDEX ON %s(", pTab->zName);
assert( pIdx->nColumn>1 );
assert( pIdx->aiColumn[pIdx->nColumn-1]==XN_ROWID );
for(ii=0; ii<(pIdx->nColumn-1); ii++){
@@ -844,13 +845,18 @@ static void explainAutomaticIndex(
int iCol = pIdx->aiColumn[ii];
zName = pTab->aCol[iCol].zCnName;
- zText = sqlite3_mprintf("%z%s%s", zText, zSep, zName);
+ sqlite3_str_appendf(pStr, "%s%s", zSep, zName);
zSep = ", ";
}
- *pAddrExplain = sqlite3VdbeExplain(
- pParse, 0, "%s)%s", zText, (bPartial ? " WHERE <expr>" : "")
- );
- sqlite3_free(zText);
+ zText = sqlite3_str_finish(pStr);
+ if( zText==0 ){
+ sqlite3OomFault(pParse->db);
+ }else{
+ *pAddrExplain = sqlite3VdbeExplain(
+ pParse, 0, "%s)%s", zText, (bPartial ? " WHERE <expr>" : "")
+ );
+ sqlite3_free(zText);
+ }
}
}
#else
@@ -5672,6 +5678,12 @@ static SQLITE_NOINLINE void whereAddIndexedExpr(
p = sqlite3DbMallocRaw(pParse->db, sizeof(IndexedExpr));
if( p==0 ) break;
p->pIENext = pParse->pIdxEpr;
+#ifdef WHERETRACE_ENABLED
+ if( sqlite3WhereTrace & 0x200 ){
+ sqlite3DebugPrintf("New pParse->pIdxEpr term {%d,%d}\n", iIdxCur, i);
+ if( sqlite3WhereTrace & 0x5000 ) sqlite3ShowExpr(pExpr);
+ }
+#endif
p->pExpr = sqlite3ExprDup(pParse->db, pExpr, 0);
p->iDataCur = pTabItem->iCursor;
p->iIdxCur = iIdxCur;
@@ -6634,6 +6646,13 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
IndexedExpr *p = pParse->pIdxEpr;
while( p ){
if( p->iIdxCur==pLevel->iIdxCur ){
+#ifdef WHERETRACE_ENABLED
+ if( sqlite3WhereTrace & 0x200 ){
+ sqlite3DebugPrintf("Disable pParse->pIdxEpr term {%d,%d}\n",
+ p->iIdxCur, p->iIdxCol);
+ if( sqlite3WhereTrace & 0x5000 ) sqlite3ShowExpr(p->pExpr);
+ }
+#endif
p->iDataCur = -1;
p->iIdxCur = -1;
}