aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/build.c10
-rw-r--r--src/main.c29
-rw-r--r--src/pcache1.c2
-rw-r--r--src/select.c3
-rw-r--r--src/sqlite.h.in8
-rw-r--r--src/test_devsym.c1
-rw-r--r--src/vdbe.c114
-rw-r--r--src/vdbeInt.h2
-rw-r--r--src/vdbeaux.c7
-rw-r--r--src/vdbemem.c2
-rw-r--r--src/window.c29
11 files changed, 175 insertions, 32 deletions
diff --git a/src/build.c b/src/build.c
index 380af8379..53314593b 100644
--- a/src/build.c
+++ b/src/build.c
@@ -618,10 +618,14 @@ static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){
#ifdef SQLITE_DEBUG
/* Record the number of outstanding lookaside allocations in schema Tables
- ** prior to doing any free() operations. Since schema Tables do not use
- ** lookaside, this number should not change. */
+ ** prior to doing any free() operations. Since schema Tables do not use
+ ** lookaside, this number should not change.
+ **
+ ** If malloc has already failed, it may be that it failed while allocating
+ ** a Table object that was going to be marked ephemeral. So do not check
+ ** that no lookaside memory is used in this case either. */
int nLookaside = 0;
- if( db && (pTable->tabFlags & TF_Ephemeral)==0 ){
+ if( db && !db->mallocFailed && (pTable->tabFlags & TF_Ephemeral)==0 ){
nLookaside = sqlite3LookasideUsed(db, 0);
}
#endif
diff --git a/src/main.c b/src/main.c
index a70271162..612700627 100644
--- a/src/main.c
+++ b/src/main.c
@@ -3073,8 +3073,35 @@ static int openDatabase(
db->szMmap = sqlite3GlobalConfig.szMmap;
db->nextPagesize = 0;
db->nMaxSorterMmap = 0x7FFFFFFF;
- db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger | SQLITE_CacheSpill
+ db->flags |= SQLITE_ShortColNames
+ | SQLITE_EnableTrigger
+ | SQLITE_CacheSpill
+
+/* The SQLITE_DQS compile-time option determines the default settings
+** for SQLITE_DBCONFIG_DQS_DDL and SQLITE_DBCONFIG_DQS_DML.
+**
+** SQLITE_DQS SQLITE_DBCONFIG_DQS_DDL SQLITE_DBCONFIG_DQS_DML
+** ---------- ----------------------- -----------------------
+** undefined on on
+** 3 on on
+** 2 on off
+** 1 off on
+** 0 off off
+**
+** Legacy behavior is 3 (double-quoted string literals are allowed anywhere)
+** and so that is the default. But developers are encouranged to use
+** -DSQLITE_DQS=0 (best) or -DSQLITE_DQS=1 (second choice) if possible.
+*/
+#if !defined(SQLITE_DQS)
+# define SQLITE_DQS 3
+#endif
+#if (SQLITE_DQS&1)==1
| SQLITE_DqsDML
+#endif
+#if (SQLITE_DQS&2)==2
+ | SQLITE_DqsDDL
+#endif
+
#if !defined(SQLITE_DEFAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX
| SQLITE_AutoIndex
#endif
diff --git a/src/pcache1.c b/src/pcache1.c
index ff01ae311..c9d55866e 100644
--- a/src/pcache1.c
+++ b/src/pcache1.c
@@ -778,6 +778,7 @@ static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){
}else{
pGroup = &pcache1.grp;
}
+ pcache1EnterMutex(pGroup);
if( pGroup->lru.isAnchor==0 ){
pGroup->lru.isAnchor = 1;
pGroup->lru.pLruPrev = pGroup->lru.pLruNext = &pGroup->lru;
@@ -787,7 +788,6 @@ static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){
pCache->szExtra = szExtra;
pCache->szAlloc = szPage + szExtra + ROUND8(sizeof(PgHdr1));
pCache->bPurgeable = (bPurgeable ? 1 : 0);
- pcache1EnterMutex(pGroup);
pcache1ResizeHash(pCache);
if( bPurgeable ){
pCache->nMin = 10;
diff --git a/src/select.c b/src/select.c
index e6471fb84..8b18e20d0 100644
--- a/src/select.c
+++ b/src/select.c
@@ -2096,9 +2096,6 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){
if( pTab==0 ){
return 0;
}
- /* The sqlite3ResultSetOfSelect() is only used n contexts where lookaside
- ** is disabled */
- assert( db->lookaside.bDisable );
pTab->nTabRef = 1;
pTab->zName = 0;
pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
diff --git a/src/sqlite.h.in b/src/sqlite.h.in
index 6b0704f12..4dd14ac17 100644
--- a/src/sqlite.h.in
+++ b/src/sqlite.h.in
@@ -2235,14 +2235,18 @@ struct sqlite3_mem_methods {
** <dt>SQLITE_DBCONFIG_DQS_DML</td>
** <dd>The SQLITE_DBCONFIG_DQS_DML option activates or deactivates
** the legacy [double-quoted string literal] misfeature for DML statement
-** only, that is DELETE, INSERT, SELECT, and UPDATE statements.
+** only, that is DELETE, INSERT, SELECT, and UPDATE statements. The
+** default value of this setting is determined by the [-DSQLITE_DQS]
+** compile-time option.
** </dd>
**
** [[SQLITE_DBCONFIG_DQS_DDL]]
** <dt>SQLITE_DBCONFIG_DQS_DDL</td>
** <dd>The SQLITE_DBCONFIG_DQS option activates or deactivates
** the legacy [double-quoted string literal] misfeature for DDL statements,
-** such as CREATE TABLE and CREATE INDEX.
+** such as CREATE TABLE and CREATE INDEX. The
+** default value of this setting is determined by the [-DSQLITE_DQS]
+** compile-time option.
** </dd>
** </dl>
*/
diff --git a/src/test_devsym.c b/src/test_devsym.c
index 0da6671cf..23354312c 100644
--- a/src/test_devsym.c
+++ b/src/test_devsym.c
@@ -505,6 +505,7 @@ void devsym_register(int iDeviceChar, int iSectorSize){
void devsym_unregister(){
sqlite3_vfs_unregister(&devsym_vfs);
+ sqlite3_vfs_unregister(&writecrash_vfs);
g.pVfs = 0;
g.iDeviceChar = 0;
g.iSectorSize = 0;
diff --git a/src/vdbe.c b/src/vdbe.c
index d697d6b1e..018ba97d3 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -2927,14 +2927,36 @@ case OP_MakeRecord: {
#endif
/* Loop through the elements that will make up the record to figure
- ** out how much space is required for the new record.
+ ** out how much space is required for the new record. After this loop,
+ ** the Mem.uTemp field of each term should hold the serial-type that will
+ ** be used for that term in the generated record:
+ **
+ ** Mem.uTemp value type
+ ** --------------- ---------------
+ ** 0 NULL
+ ** 1 1-byte signed integer
+ ** 2 2-byte signed integer
+ ** 3 3-byte signed integer
+ ** 4 4-byte signed integer
+ ** 5 6-byte signed integer
+ ** 6 8-byte signed integer
+ ** 7 IEEE float
+ ** 8 Integer constant 0
+ ** 9 Integer constant 1
+ ** 10,11 reserved for expansion
+ ** N>=12 and even BLOB
+ ** N>=13 and odd text
+ **
+ ** The following additional values are computed:
+ ** nHdr Number of bytes needed for the record header
+ ** nData Number of bytes of data space needed for the record
+ ** nZero Zero bytes at the end of the record
*/
pRec = pLast;
do{
assert( memIsValid(pRec) );
- serial_type = sqlite3VdbeSerialType(pRec, file_format, &len);
- if( pRec->flags & MEM_Zero ){
- if( serial_type==0 ){
+ if( pRec->flags & MEM_Null ){
+ if( pRec->flags & MEM_Zero ){
/* Values with MEM_Null and MEM_Zero are created by xColumn virtual
** table methods that never invoke sqlite3_result_xxxxx() while
** computing an unchanging column value in an UPDATE statement.
@@ -2942,19 +2964,83 @@ case OP_MakeRecord: {
** so that they can be passed through to xUpdate and have
** a true sqlite3_value_nochange(). */
assert( pOp->p5==OPFLAG_NOCHNG_MAGIC || CORRUPT_DB );
- serial_type = 10;
- }else if( nData ){
- if( sqlite3VdbeMemExpandBlob(pRec) ) goto no_mem;
+ pRec->uTemp = 10;
+ }else{
+ pRec->uTemp = 0;
+ }
+ nHdr++;
+ }else if( pRec->flags & (MEM_Int|MEM_IntReal) ){
+ /* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */
+ i64 i = pRec->u.i;
+ u64 u;
+ testcase( pRec->flags & MEM_Int );
+ testcase( pRec->flags & MEM_IntReal );
+ if( i<0 ){
+ u = ~i;
+ }else{
+ u = i;
+ }
+ nHdr++;
+ testcase( u==127 ); testcase( u==128 );
+ testcase( u==32767 ); testcase( u==32768 );
+ testcase( u==8388607 ); testcase( u==8388608 );
+ testcase( u==2147483647 ); testcase( u==2147483648 );
+ testcase( u==140737488355327LL ); testcase( u==140737488355328LL );
+ if( u<=127 ){
+ if( (i&1)==i && file_format>=4 ){
+ pRec->uTemp = 8+(u32)u;
+ }else{
+ nData++;
+ pRec->uTemp = 1;
+ }
+ }else if( u<=32767 ){
+ nData += 2;
+ pRec->uTemp = 2;
+ }else if( u<=8388607 ){
+ nData += 3;
+ pRec->uTemp = 3;
+ }else if( u<=2147483647 ){
+ nData += 4;
+ pRec->uTemp = 4;
+ }else if( u<=140737488355327LL ){
+ nData += 6;
+ pRec->uTemp = 5;
}else{
- nZero += pRec->u.nZero;
- len -= pRec->u.nZero;
+ nData += 8;
+ if( pRec->flags & MEM_IntReal ){
+ /* If the value is IntReal and is going to take up 8 bytes to store
+ ** as an integer, then we might as well make it an 8-byte floating
+ ** point value */
+ pRec->u.r = (double)pRec->u.i;
+ pRec->flags &= ~MEM_IntReal;
+ pRec->flags |= MEM_Real;
+ pRec->uTemp = 7;
+ }else{
+ pRec->uTemp = 6;
+ }
+ }
+ }else if( pRec->flags & MEM_Real ){
+ nHdr++;
+ nData += 8;
+ pRec->uTemp = 7;
+ }else{
+ assert( db->mallocFailed || pRec->flags&(MEM_Str|MEM_Blob) );
+ assert( pRec->n>=0 );
+ len = (u32)pRec->n;
+ serial_type = (len*2) + 12 + ((pRec->flags & MEM_Str)!=0);
+ if( pRec->flags & MEM_Zero ){
+ serial_type += pRec->u.nZero*2;
+ if( nData ){
+ if( sqlite3VdbeMemExpandBlob(pRec) ) goto no_mem;
+ len += pRec->u.nZero;
+ }else{
+ nZero += pRec->u.nZero;
+ }
}
+ nData += len;
+ nHdr += sqlite3VarintLen(serial_type);
+ pRec->uTemp = serial_type;
}
- nData += len;
- testcase( serial_type==127 );
- testcase( serial_type==128 );
- nHdr += serial_type<=127 ? 1 : sqlite3VarintLen(serial_type);
- pRec->uTemp = serial_type;
if( pRec==pData0 ) break;
pRec--;
}while(1);
diff --git a/src/vdbeInt.h b/src/vdbeInt.h
index 17e057b18..3332b4838 100644
--- a/src/vdbeInt.h
+++ b/src/vdbeInt.h
@@ -486,7 +486,9 @@ int sqlite3VdbeCursorMoveto(VdbeCursor**, int*);
int sqlite3VdbeCursorRestore(VdbeCursor*);
u32 sqlite3VdbeSerialTypeLen(u32);
u8 sqlite3VdbeOneByteSerialTypeLen(u8);
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
u32 sqlite3VdbeSerialType(Mem*, int, u32*);
+#endif
u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32);
u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
void sqlite3VdbeDeleteAuxData(sqlite3*, AuxData**, int, int);
diff --git a/src/vdbeaux.c b/src/vdbeaux.c
index 70f56c3a5..5781d8f21 100644
--- a/src/vdbeaux.c
+++ b/src/vdbeaux.c
@@ -3430,10 +3430,16 @@ int sqlite3VdbeCursorMoveto(VdbeCursor **pp, int *piCol){
** of SQLite will not understand those serial types.
*/
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/*
** Return the serial-type for the value stored in pMem.
**
** This routine might convert a large MEM_IntReal value into MEM_Real.
+**
+** 2019-07-11: The primary user of this subroutine was the OP_MakeRecord
+** opcode in the byte-code engine. But by moving this routine in-line, we
+** can omit some redundant tests and make that opcode a lot faster. So
+** this routine is now only used by the STAT3/4 logic.
*/
u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){
int flags = pMem->flags;
@@ -3494,6 +3500,7 @@ u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){
*pLen = n;
return ((n*2) + 12 + ((flags&MEM_Str)!=0));
}
+#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
/*
** The sizes for serial types less than 128
diff --git a/src/vdbemem.c b/src/vdbemem.c
index c0e386ef6..af6d41a38 100644
--- a/src/vdbemem.c
+++ b/src/vdbemem.c
@@ -703,7 +703,7 @@ int sqlite3RealSameAsInt(double r1, sqlite3_int64 i){
double r2 = (double)i;
return r1==0.0
|| (memcmp(&r1, &r2, sizeof(r1))==0
- && i >= -2251799813685248 && i < 2251799813685248);
+ && i >= -2251799813685248LL && i < 2251799813685248LL);
}
/*
diff --git a/src/window.c b/src/window.c
index 4d7ebf608..b91b0f050 100644
--- a/src/window.c
+++ b/src/window.c
@@ -736,6 +736,7 @@ struct WindowRewrite {
Window *pWin;
SrcList *pSrc;
ExprList *pSub;
+ Table *pTab;
Select *pSubSelect; /* Current sub-select, if any */
};
@@ -796,6 +797,7 @@ static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){
pExpr->op = TK_COLUMN;
pExpr->iColumn = p->pSub->nExpr-1;
pExpr->iTable = p->pWin->iEphCsr;
+ pExpr->y.pTab = p->pTab;
}
break;
@@ -839,6 +841,7 @@ static void selectWindowRewriteEList(
Window *pWin,
SrcList *pSrc,
ExprList *pEList, /* Rewrite expressions in this list */
+ Table *pTab,
ExprList **ppSub /* IN/OUT: Sub-select expression-list */
){
Walker sWalker;
@@ -850,6 +853,7 @@ static void selectWindowRewriteEList(
sRewrite.pSub = *ppSub;
sRewrite.pWin = pWin;
sRewrite.pSrc = pSrc;
+ sRewrite.pTab = pTab;
sWalker.pParse = pParse;
sWalker.xExprCallback = selectWindowRewriteExprCb;
@@ -909,11 +913,18 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
ExprList *pSublist = 0; /* Expression list for sub-query */
Window *pMWin = p->pWin; /* Master window object */
Window *pWin; /* Window object iterator */
+ Table *pTab;
+
+ pTab = sqlite3DbMallocZero(db, sizeof(Table));
+ if( pTab==0 ){
+ return SQLITE_NOMEM;
+ }
p->pSrc = 0;
p->pWhere = 0;
p->pGroupBy = 0;
p->pHaving = 0;
+ p->selFlags &= ~SF_Aggregate;
/* Create the ORDER BY clause for the sub-select. This is the concatenation
** of the window PARTITION and ORDER BY clauses. Then, if this makes it
@@ -933,8 +944,8 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
pMWin->iEphCsr = pParse->nTab++;
pParse->nTab += 3;
- selectWindowRewriteEList(pParse, pMWin, pSrc, p->pEList, &pSublist);
- selectWindowRewriteEList(pParse, pMWin, pSrc, p->pOrderBy, &pSublist);
+ selectWindowRewriteEList(pParse, pMWin, pSrc, p->pEList, pTab, &pSublist);
+ selectWindowRewriteEList(pParse, pMWin, pSrc, p->pOrderBy, pTab, &pSublist);
pMWin->nBufferCol = (pSublist ? pSublist->nExpr : 0);
/* Append the PARTITION BY and ORDER BY expressions to the to the
@@ -976,16 +987,19 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
);
p->pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);
if( p->pSrc ){
+ Table *pTab2;
p->pSrc->a[0].pSelect = pSub;
sqlite3SrcListAssignCursors(pParse, p->pSrc);
- if( sqlite3ExpandSubquery(pParse, &p->pSrc->a[0]) ){
+ pSub->selFlags |= SF_Expanded;
+ pTab2 = sqlite3ResultSetOfSelect(pParse, pSub);
+ if( pTab2==0 ){
rc = SQLITE_NOMEM;
}else{
- pSub->selFlags |= SF_Expanded;
- p->selFlags &= ~SF_Aggregate;
- sqlite3SelectPrep(pParse, pSub, 0);
+ memcpy(pTab, pTab2, sizeof(Table));
+ pTab->tabFlags |= TF_Ephemeral;
+ p->pSrc->a[0].pTab = pTab;
+ pTab = pTab2;
}
-
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pMWin->iEphCsr, pSublist->nExpr);
sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+1, pMWin->iEphCsr);
sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+2, pMWin->iEphCsr);
@@ -994,6 +1008,7 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
sqlite3SelectDelete(db, pSub);
}
if( db->mallocFailed ) rc = SQLITE_NOMEM;
+ sqlite3DbFree(db, pTab);
}
return rc;