aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordan <Dan Kennedy>2022-12-05 18:26:37 +0000
committerdan <Dan Kennedy>2022-12-05 18:26:37 +0000
commit77e171e8fa536f47f7a5108d7b8b5d88fc01ae05 (patch)
tree34037f08500bc7bc8f1b5b2879043593096de692 /src
parenta3d0c158a0e5942a2cfbfa05b1c1a629ed230ed0 (diff)
parent49d402684b86e0f49264b5fbbe1d0ca2e7f64b93 (diff)
downloadsqlite-77e171e8fa536f47f7a5108d7b8b5d88fc01ae05.tar.gz
sqlite-77e171e8fa536f47f7a5108d7b8b5d88fc01ae05.zip
Merge latest trunk changes.
FossilOrigin-Name: 1a72777b1279f74f212fb2f675a4594a238e5d28f048879d7f5ad5287673c3c4
Diffstat (limited to 'src')
-rw-r--r--src/malloc.c2
-rw-r--r--src/memdb.c13
-rw-r--r--src/os_kv.c16
-rw-r--r--src/shell.c.in4
-rw-r--r--src/sqlite.h.in23
-rw-r--r--src/where.c65
6 files changed, 76 insertions, 47 deletions
diff --git a/src/malloc.c b/src/malloc.c
index 68d9f5f55..48c460060 100644
--- a/src/malloc.c
+++ b/src/malloc.c
@@ -279,7 +279,7 @@ static void mallocWithAlarm(int n, void **pp){
** The upper bound is slightly less than 2GiB: 0x7ffffeff == 2,147,483,391
** This provides a 256-byte safety margin for defense against 32-bit
** signed integer overflow bugs when computing memory allocation sizes.
-** Parnoid applications might want to reduce the maximum allocation size
+** Paranoid applications might want to reduce the maximum allocation size
** further for an even larger safety margin. 0x3fffffff or 0x0fffffff
** or even smaller would be reasonable upper bounds on the size of a memory
** allocations for most applications.
diff --git a/src/memdb.c b/src/memdb.c
index 0aecb7102..7485f51ff 100644
--- a/src/memdb.c
+++ b/src/memdb.c
@@ -371,9 +371,22 @@ static int memdbLock(sqlite3_file *pFile, int eLock){
if( eLock==pThis->eLock ) return SQLITE_OK;
memdbEnter(p);
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 ){
+ /* Taking an EXCLUSIVE lock. Fail if we only have SHARED and any
+ ** other client has any kind of write-lock. Also fail if any other
+ ** client is holding read-lock. */
+ if( pThis->eLock<=SQLITE_LOCK_SHARED && p->nWrLock ){
+ rc = SQLITE_BUSY;
+ }else if( p->nRdLock>1 ){
+ rc = SQLITE_BUSY;
+ }
+ p->nWrLock = 1;
}else if( 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{
diff --git a/src/os_kv.c b/src/os_kv.c
index 322588be9..45955d18f 100644
--- a/src/os_kv.c
+++ b/src/os_kv.c
@@ -52,7 +52,9 @@ struct KVVfsFile {
char *aJrnl; /* Journal content */
int szPage; /* Last known page size */
sqlite3_int64 szDb; /* Database file size. -1 means unknown */
+ char *aData; /* Buffer to hold page data */
};
+#define SQLITE_KVOS_SZ 133073
/*
** Methods for KVVfsFile
@@ -493,6 +495,7 @@ static int kvvfsClose(sqlite3_file *pProtoFile){
SQLITE_KV_LOG(("xClose %s %s\n", pFile->zClass,
pFile->isJournal ? "journal" : "db"));
sqlite3_free(pFile->aJrnl);
+ sqlite3_free(pFile->aData);
return SQLITE_OK;
}
@@ -541,7 +544,7 @@ static int kvvfsReadDb(
unsigned int pgno;
int got, n;
char zKey[30];
- char aData[133073];
+ char *aData = pFile->aData;
assert( iOfst>=0 );
assert( iAmt>=0 );
SQLITE_KV_LOG(("xRead('%s-db',%d,%lld)\n", pFile->zClass, iAmt, iOfst));
@@ -558,7 +561,8 @@ static int kvvfsReadDb(
pgno = 1;
}
sqlite3_snprintf(sizeof(zKey), zKey, "%u", pgno);
- got = sqlite3KvvfsMethods.xRead(pFile->zClass, zKey, aData, sizeof(aData)-1);
+ got = sqlite3KvvfsMethods.xRead(pFile->zClass, zKey,
+ aData, SQLITE_KVOS_SZ-1);
if( got<0 ){
n = 0;
}else{
@@ -566,7 +570,7 @@ static int kvvfsReadDb(
if( iOfst+iAmt<512 ){
int k = iOfst+iAmt;
aData[k*2] = 0;
- n = kvvfsDecode(aData, &aData[2000], sizeof(aData)-2000);
+ n = kvvfsDecode(aData, &aData[2000], SQLITE_KVOS_SZ-2000);
if( n>=iOfst+iAmt ){
memcpy(zBuf, &aData[2000+iOfst], iAmt);
n = iAmt;
@@ -625,7 +629,7 @@ static int kvvfsWriteDb(
KVVfsFile *pFile = (KVVfsFile*)pProtoFile;
unsigned int pgno;
char zKey[30];
- char aData[131073];
+ char *aData = pFile->aData;
SQLITE_KV_LOG(("xWrite('%s-db',%d,%lld)\n", pFile->zClass, iAmt, iOfst));
assert( iAmt>=512 && iAmt<=65536 );
assert( (iAmt & (iAmt-1))==0 );
@@ -834,6 +838,10 @@ static int kvvfsOpen(
}else{
pFile->zClass = "local";
}
+ pFile->aData = sqlite3_malloc64(SQLITE_KVOS_SZ);
+ if( pFile->aData==0 ){
+ return SQLITE_NOMEM;
+ }
pFile->aJrnl = 0;
pFile->nJrnl = 0;
pFile->szPage = -1;
diff --git a/src/shell.c.in b/src/shell.c.in
index d3ef84e44..7fc777f05 100644
--- a/src/shell.c.in
+++ b/src/shell.c.in
@@ -1880,7 +1880,7 @@ static int safeModeAuth(
"zipfile",
"zipfile_cds",
};
- UNUSED_PARAMETER(zA2);
+ UNUSED_PARAMETER(zA1);
UNUSED_PARAMETER(zA3);
UNUSED_PARAMETER(zA4);
switch( op ){
@@ -1895,7 +1895,7 @@ static int safeModeAuth(
case SQLITE_FUNCTION: {
int i;
for(i=0; i<ArraySize(azProhibitedFunctions); i++){
- if( sqlite3_stricmp(zA1, azProhibitedFunctions[i])==0 ){
+ if( sqlite3_stricmp(zA2, azProhibitedFunctions[i])==0 ){
failIfSafeMode(p, "cannot use the %s() function in safe mode",
azProhibitedFunctions[i]);
}
diff --git a/src/sqlite.h.in b/src/sqlite.h.in
index 91466399b..13eb2e233 100644
--- a/src/sqlite.h.in
+++ b/src/sqlite.h.in
@@ -7015,15 +7015,6 @@ int sqlite3_cancel_auto_extension(void(*xEntryPoint)(void));
void sqlite3_reset_auto_extension(void);
/*
-** The interface to the virtual-table mechanism is currently considered
-** to be experimental. The interface might change in incompatible ways.
-** If this is a problem for you, do not use the interface at this time.
-**
-** When the virtual-table mechanism stabilizes, we will declare the
-** interface fixed, support it indefinitely, and remove this comment.
-*/
-
-/*
** Structures used by the virtual table interface
*/
typedef struct sqlite3_vtab sqlite3_vtab;
@@ -7264,7 +7255,7 @@ struct sqlite3_index_info {
** the [sqlite3_vtab_collation()] interface. For most real-world virtual
** tables, the collating sequence of constraints does not matter (for example
** because the constraints are numeric) and so the sqlite3_vtab_collation()
-** interface is no commonly needed.
+** interface is not commonly needed.
*/
#define SQLITE_INDEX_CONSTRAINT_EQ 2
#define SQLITE_INDEX_CONSTRAINT_GT 4
@@ -7424,16 +7415,6 @@ int sqlite3_declare_vtab(sqlite3*, const char *zSQL);
int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg);
/*
-** The interface to the virtual-table mechanism defined above (back up
-** to a comment remarkably similar to this one) is currently considered
-** to be experimental. The interface might change in incompatible ways.
-** If this is a problem for you, do not use the interface at this time.
-**
-** When the virtual-table mechanism stabilizes, we will declare the
-** interface fixed, support it indefinitely, and remove this comment.
-*/
-
-/*
** CAPI3REF: A Handle To An Open BLOB
** KEYWORDS: {BLOB handle} {BLOB handles}
**
@@ -9636,7 +9617,7 @@ int sqlite3_vtab_nochange(sqlite3_context*);
** <li><p> Otherwise, "BINARY" is returned.
** </ol>
*/
-SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int);
+const char *sqlite3_vtab_collation(sqlite3_index_info*,int);
/*
** CAPI3REF: Determine if a virtual table query is DISTINCT
diff --git a/src/where.c b/src/where.c
index c9eeabe8b..a13379947 100644
--- a/src/where.c
+++ b/src/where.c
@@ -3092,7 +3092,15 @@ static int whereLoopAddBtreeIndex(
** seek only. Then, if this is a non-covering index, add the cost of
** visiting the rows in the main table. */
assert( pSrc->pTab->szTabRow>0 );
- rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow;
+ if( pProbe->idxType==SQLITE_IDXTYPE_IPK ){
+ /* The pProbe->szIdxRow is low for an IPK table since the interior
+ ** pages are small. Thuse szIdxRow gives a good estimate of seek cost.
+ ** But the leaf pages are full-size, so pProbe->szIdxRow would badly
+ ** under-estimate the scanning cost. */
+ rCostIdx = pNew->nOut + 16;
+ }else{
+ rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow;
+ }
pNew->rRun = sqlite3LogEstAdd(rLogSize, rCostIdx);
if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK|WHERE_EXPRIDX))==0 ){
pNew->rRun = sqlite3LogEstAdd(pNew->rRun, pNew->nOut + 16);
@@ -3472,7 +3480,7 @@ static int whereLoopAddBtree(
sPk.aiRowLogEst = aiRowEstPk;
sPk.onError = OE_Replace;
sPk.pTable = pTab;
- sPk.szIdxRow = pTab->szTabRow;
+ sPk.szIdxRow = 3; /* TUNING: Interior rows of IPK table are very small */
sPk.idxType = SQLITE_IDXTYPE_IPK;
aiRowEstPk[0] = pTab->nRowLogEst;
aiRowEstPk[1] = 0;
@@ -4803,37 +4811,56 @@ static const char *wherePathName(WherePath *pPath, int nLoop, WhereLoop *pLast){
** order.
*/
static LogEst whereSortingCost(
- WhereInfo *pWInfo,
- LogEst nRow,
- int nOrderBy,
- int nSorted
+ WhereInfo *pWInfo, /* Query planning context */
+ LogEst nRow, /* Estimated number of rows to sort */
+ int nOrderBy, /* Number of ORDER BY clause terms */
+ int nSorted /* Number of initial ORDER BY terms naturally in order */
){
- /* TUNING: Estimated cost of a full external sort, where N is
+ /* Estimated cost of a full external sort, where N is
** the number of rows to sort is:
**
- ** cost = (3.0 * N * log(N)).
+ ** cost = (K * N * log(N)).
**
** Or, if the order-by clause has X terms but only the last Y
** terms are out of order, then block-sorting will reduce the
** sorting cost to:
**
- ** cost = (3.0 * N * log(N)) * (Y/X)
+ ** cost = (K * N * log(N)) * (Y/X)
**
- ** The (Y/X) term is implemented using stack variable rScale
- ** below.
+ ** The constant K is at least 2.0 but will be larger if there are a
+ ** large number of columns to be sorted, as the sorting time is
+ ** proportional to the amount of content to be sorted. The algorithm
+ ** does not currently distinguish between fat columns (BLOBs and TEXTs)
+ ** and skinny columns (INTs). It just uses the number of columns as
+ ** an approximation for the row width.
+ **
+ ** And extra factor of 2.0 or 3.0 is added to the sorting cost if the sort
+ ** is built using OP_IdxInsert and OP_Sort rather than with OP_SorterInsert.
*/
- LogEst rScale, rSortCost;
- assert( nOrderBy>0 && 66==sqlite3LogEst(100) );
- rScale = sqlite3LogEst((nOrderBy-nSorted)*100/nOrderBy) - 66;
- rSortCost = nRow + rScale + 16;
+ LogEst rSortCost, nCol;
+ assert( pWInfo->pSelect!=0 );
+ assert( pWInfo->pSelect->pEList!=0 );
+ /* TUNING: sorting cost proportional to the number of output columns: */
+ nCol = sqlite3LogEst((pWInfo->pSelect->pEList->nExpr+59)/30);
+ rSortCost = nRow + nCol;
+ if( nSorted>0 ){
+ /* Scale the result by (Y/X) */
+ rSortCost += sqlite3LogEst((nOrderBy-nSorted)*100/nOrderBy) - 66;
+ }
/* Multiple by log(M) where M is the number of output rows.
** Use the LIMIT for M if it is smaller. Or if this sort is for
** a DISTINCT operator, M will be the number of distinct output
** rows, so fudge it downwards a bit.
*/
- if( (pWInfo->wctrlFlags & WHERE_USE_LIMIT)!=0 && pWInfo->iLimit<nRow ){
- nRow = pWInfo->iLimit;
+ if( (pWInfo->wctrlFlags & WHERE_USE_LIMIT)!=0 ){
+ rSortCost += 10; /* TUNING: Extra 2.0x if using LIMIT */
+ if( nSorted!=0 ){
+ rSortCost += 6; /* TUNING: Extra 1.5x if also using partial sort */
+ }
+ if( pWInfo->iLimit<nRow ){
+ nRow = pWInfo->iLimit;
+ }
}else if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT) ){
/* TUNING: In the sort for a DISTINCT operator, assume that the DISTINCT
** reduces the number of output rows by a factor of 2 */
@@ -4985,11 +5012,11 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
pWInfo, nRowEst, nOrderBy, isOrdered
);
}
- /* TUNING: Add a small extra penalty (5) to sorting as an
+ /* TUNING: Add a small extra penalty (3) to sorting as an
** extra encouragment to the query planner to select a plan
** where the rows emerge in the correct order without any sorting
** required. */
- rCost = sqlite3LogEstAdd(rUnsorted, aSortCost[isOrdered]) + 5;
+ rCost = sqlite3LogEstAdd(rUnsorted, aSortCost[isOrdered]) + 3;
WHERETRACE(0x002,
("---- sort cost=%-3d (%d/%d) increases cost %3d to %-3d\n",