Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ http_archive(
strip_prefix = "sqlite-amalgamation-3400100",
type = "zip",
url = "https://sqlite.org/2022/sqlite-amalgamation-3400100.zip",
patches = [
"//:patches/sqlite/0001-row-counts-amalgamation.patch",
],
patch_args = ["-p1"],
)

http_archive(
Expand Down
302 changes: 302 additions & 0 deletions patches/sqlite/0001-row-counts-amalgamation.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,302 @@
diff -u5 -r sqlite-amalgamation-pristine/shell.c sqlite-amalgamation-modified/shell.c
--- sqlite-amalgamation-pristine/shell.c 2022-12-28 06:26:39.000000000 -0800
+++ sqlite-amalgamation-modified/shell.c 2023-08-04 14:53:19.663535828 -0700
@@ -17356,10 +17356,15 @@
raw_printf(pArg->out, "Reprepare operations: %d\n", iCur);
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_RUN, bReset);
raw_printf(pArg->out, "Number of times run: %d\n", iCur);
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_MEMUSED, bReset);
raw_printf(pArg->out, "Memory used by prepared stmt: %d\n", iCur);
+
+ iCur = sqlite3_stmt_status(pArg->pStmt, LIBSQL_STMTSTATUS_ROWS_READ, bReset);
+ raw_printf(pArg->out, "Rows read: %d\n", iCur);
+ iCur = sqlite3_stmt_status(pArg->pStmt, LIBSQL_STMTSTATUS_ROWS_WRITTEN, bReset);
+ raw_printf(pArg->out, "Rows written: %d\n", iCur);
}

#ifdef __linux__
displayLinuxIoStats(pArg->out);
#endif
diff -u5 -r sqlite-amalgamation-pristine/sqlite3.c sqlite-amalgamation-modified/sqlite3.c
--- sqlite-amalgamation-pristine/sqlite3.c 2022-12-28 06:26:39.000000000 -0800
+++ sqlite-amalgamation-modified/sqlite3.c 2023-08-04 14:53:19.667535836 -0700
@@ -452,11 +452,11 @@
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION "3.40.1"
#define SQLITE_VERSION_NUMBER 3040001
-#define SQLITE_SOURCE_ID "2022-12-28 14:03:47 df5c253c0b3dd24916e4ec7cf77d3db5294cc9fd45ae7b9c5e82ad8197f38a24"
+#define SQLITE_SOURCE_ID "2022-12-28 14:03:47 df5c253c0b3dd24916e4ec7cf77d3db5294cc9fd45ae7b9c5e82ad8197f3alt1"

/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version sqlite3_sourceid
**
@@ -8921,10 +8921,18 @@
** used to store the prepared statement. ^This value is not actually
** a counter, and so the resetFlg parameter to sqlite3_stmt_status()
** is ignored when the opcode is SQLITE_STMTSTATUS_MEMUSED.
** </dd>
** </dl>
+**
+** [[LIBSQL_STMTSTATUS_ROWS_READ]]
+** [[LIBSQL_STMTSTATUS_ROWS_WRITTEN]]
+** <dt>LIBSQL_STMTSTATUS_ROWS_READ<br>
+** LIBSQL_STMTSTATUS_ROWS_WRITTEN</dt>
+** <dd>^LIBSQL_STMTSTATUS_ROWS_READ is the number of rows read when executing
+** this statement. LIBSQL_STMTSTATUS_ROWS_WRITTEN value is the number of
+** rows written.
*/
#define SQLITE_STMTSTATUS_FULLSCAN_STEP 1
#define SQLITE_STMTSTATUS_SORT 2
#define SQLITE_STMTSTATUS_AUTOINDEX 3
#define SQLITE_STMTSTATUS_VM_STEP 4
@@ -8932,10 +8940,14 @@
#define SQLITE_STMTSTATUS_RUN 6
#define SQLITE_STMTSTATUS_FILTER_MISS 7
#define SQLITE_STMTSTATUS_FILTER_HIT 8
#define SQLITE_STMTSTATUS_MEMUSED 99

+#define LIBSQL_STMTSTATUS_BASE 1024
+#define LIBSQL_STMTSTATUS_ROWS_READ LIBSQL_STMTSTATUS_BASE + 1
+#define LIBSQL_STMTSTATUS_ROWS_WRITTEN LIBSQL_STMTSTATUS_BASE + 2
+
/*
** CAPI3REF: Custom Page Cache Object
**
** The sqlite3_pcache type is opaque. It is implemented by
** the pluggable module. The SQLite core has no knowledge of
@@ -22778,10 +22790,11 @@
bft readOnly:1; /* True for statements that do not write */
bft bIsReader:1; /* True for statements that read */
yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */
yDbMask lockMask; /* Subset of btreeMask that requires a lock */
u32 aCounter[9]; /* Counters used by sqlite3_stmt_status() */
+ u32 aLibsqlCounter[3]; /* libSQL extension: Counters used by sqlite3_stmt_status()*/
char *zSql; /* Text of the SQL statement that generated this */
#ifdef SQLITE_ENABLE_NORMALIZE
char *zNormSql; /* Normalization of the associated SQL statement */
DblquoteStr *pDblStr; /* List of double-quoted string literals */
#endif
@@ -89160,11 +89173,11 @@
SQLITE_API int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){
Vdbe *pVdbe = (Vdbe*)pStmt;
u32 v;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !pStmt
- || (op!=SQLITE_STMTSTATUS_MEMUSED && (op<0||op>=ArraySize(pVdbe->aCounter)))
+ || (op!=SQLITE_STMTSTATUS_MEMUSED && (op<0||(op>=ArraySize(pVdbe->aCounter)&&op<LIBSQL_STMTSTATUS_BASE)))
){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
@@ -89177,10 +89190,13 @@
db->lookaside.pEnd = db->lookaside.pStart;
sqlite3VdbeDelete(pVdbe);
db->pnBytesFreed = 0;
db->lookaside.pEnd = db->lookaside.pTrueEnd;
sqlite3_mutex_leave(db->mutex);
+ }else if( op>=LIBSQL_STMTSTATUS_BASE ){
+ v = pVdbe->aLibsqlCounter[op - LIBSQL_STMTSTATUS_BASE];
+ if( resetFlag ) pVdbe->aLibsqlCounter[op - LIBSQL_STMTSTATUS_BASE] = 0;
}else{
v = pVdbe->aCounter[op];
if( resetFlag ) pVdbe->aCounter[op] = 0;
}
return (int)v;
@@ -93285,10 +93301,11 @@
if( pOp->p3 ){
nEntry = sqlite3BtreeRowCountEst(pCrsr);
}else{
nEntry = 0; /* Not needed. Only used to silence a warning. */
rc = sqlite3BtreeCount(db, pCrsr, &nEntry);
+ p->aLibsqlCounter[LIBSQL_STMTSTATUS_ROWS_READ - LIBSQL_STMTSTATUS_BASE] += nEntry;
if( rc ) goto abort_due_to_error;
}
pOut = out2Prerelease(p, pOp);
pOut->u.i = nEntry;
goto check_for_interrupt;
@@ -94444,10 +94461,11 @@
if( eqOnly && r.eqSeen==0 ){
assert( res!=0 );
goto seek_not_found;
}
}
+ p->aLibsqlCounter[LIBSQL_STMTSTATUS_ROWS_READ - LIBSQL_STMTSTATUS_BASE]++;
#ifdef SQLITE_TEST
sqlite3_search_count++;
#endif
if( oc>=OP_SeekGE ){ assert( oc==OP_SeekGE || oc==OP_SeekGT );
if( res<0 || (res==0 && oc==OP_SeekGT) ){
@@ -95012,10 +95030,11 @@
pC->nullRow = 0;
pC->cacheStatus = CACHE_STALE;
pC->deferredMoveto = 0;
VdbeBranchTaken(res!=0,2);
pC->seekResult = res;
+ p->aLibsqlCounter[LIBSQL_STMTSTATUS_ROWS_READ - LIBSQL_STMTSTATUS_BASE]++;
if( res!=0 ){
assert( rc==SQLITE_OK );
if( pOp->p2==0 ){
rc = SQLITE_CORRUPT_BKPT;
}else{
@@ -95268,10 +95287,11 @@
}
}
if( pOp->p5 & OPFLAG_ISNOOP ) break;
#endif

+ p->aLibsqlCounter[LIBSQL_STMTSTATUS_ROWS_WRITTEN - LIBSQL_STMTSTATUS_BASE]++;
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;
@@ -95451,10 +95471,11 @@
pC->seekResult = 0;
if( rc ) goto abort_due_to_error;

/* Invoke the update-hook if required. */
if( opflags & OPFLAG_NCHANGE ){
+ p->aLibsqlCounter[LIBSQL_STMTSTATUS_ROWS_WRITTEN - LIBSQL_STMTSTATUS_BASE]++;
p->nChange++;
if( db->xUpdateCallback && ALWAYS(pTab!=0) && HasRowid(pTab) ){
db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, pTab->zName,
pC->movetoTarget);
assert( pC->iDb>=0 );
@@ -95738,10 +95759,11 @@
rc = sqlite3BtreeLast(pCrsr, &res);
pC->nullRow = (u8)res;
pC->deferredMoveto = 0;
pC->cacheStatus = CACHE_STALE;
if( rc ) goto abort_due_to_error;
+ p->aLibsqlCounter[LIBSQL_STMTSTATUS_ROWS_READ - LIBSQL_STMTSTATUS_BASE]++;
if( pOp->p2>0 ){
VdbeBranchTaken(res!=0,2);
if( res ) goto jump_to_p2;
}
break;
@@ -95842,10 +95864,11 @@
pC->deferredMoveto = 0;
pC->cacheStatus = CACHE_STALE;
}
if( rc ) goto abort_due_to_error;
pC->nullRow = (u8)res;
+ p->aLibsqlCounter[LIBSQL_STMTSTATUS_ROWS_READ - LIBSQL_STMTSTATUS_BASE]++;
assert( pOp->p2>0 && pOp->p2<p->nOp );
VdbeBranchTaken(res!=0,2);
if( res ) goto jump_to_p2;
break;
}
@@ -95946,10 +95969,11 @@
pC->cacheStatus = CACHE_STALE;
VdbeBranchTaken(rc==SQLITE_OK,2);
if( rc==SQLITE_OK ){
pC->nullRow = 0;
p->aCounter[pOp->p5]++;
+ p->aLibsqlCounter[LIBSQL_STMTSTATUS_ROWS_READ - LIBSQL_STMTSTATUS_BASE]++;
#ifdef SQLITE_TEST
sqlite3_search_count++;
#endif
goto jump_to_p2_and_check_for_interrupt;
}
@@ -95997,10 +96021,11 @@
assert( pC!=0 );
assert( !isSorter(pC) );
pIn2 = &aMem[pOp->p2];
assert( (pIn2->flags & MEM_Blob) || (pOp->p5 & OPFLAG_PREFORMAT) );
if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
+ p->aLibsqlCounter[LIBSQL_STMTSTATUS_ROWS_WRITTEN - LIBSQL_STMTSTATUS_BASE]++;
assert( pC->eCurType==CURTYPE_BTREE );
assert( pC->isTable==0 );
rc = ExpandBlob(pIn2);
if( rc ) goto abort_due_to_error;
x.nKey = pIn2->n;
@@ -96397,10 +96422,11 @@
assert( p->readOnly==0 );
assert( DbMaskTest(p->btreeMask, pOp->p2) );
rc = sqlite3BtreeClearTable(db->aDb[pOp->p2].pBt, (u32)pOp->p1, &nChange);
if( pOp->p3 ){
p->nChange += nChange;
+ p->aLibsqlCounter[LIBSQL_STMTSTATUS_ROWS_WRITTEN - LIBSQL_STMTSTATUS_BASE] += nChange;
if( pOp->p3>0 ){
assert( memIsValid(&aMem[pOp->p3]) );
memAboutToChange(p, &aMem[pOp->p3]);
aMem[pOp->p3].u.i += nChange;
}
@@ -97879,10 +97905,11 @@
** some other method is next invoked on the save virtual table cursor.
*/
rc = pModule->xNext(pCur->uc.pVCur);
sqlite3VtabImportErrmsg(p, pVtab);
if( rc ) goto abort_due_to_error;
+ p->aLibsqlCounter[LIBSQL_STMTSTATUS_ROWS_READ - LIBSQL_STMTSTATUS_BASE]++;
res = pModule->xEof(pCur->uc.pVCur);
VdbeBranchTaken(!res,2);
if( !res ){
/* If there is data, jump to P2 */
goto jump_to_p2_and_check_for_interrupt;
@@ -98000,10 +98027,11 @@
rc = SQLITE_OK;
}else{
p->errorAction = ((pOp->p5==OE_Replace) ? OE_Abort : pOp->p5);
}
}else{
+ p->aLibsqlCounter[LIBSQL_STMTSTATUS_ROWS_WRITTEN - LIBSQL_STMTSTATUS_BASE]++;
p->nChange++;
}
if( rc ) goto abort_due_to_error;
}
break;
diff -u5 -r sqlite-amalgamation-pristine/sqlite3.h sqlite-amalgamation-modified/sqlite3.h
--- sqlite-amalgamation-pristine/sqlite3.h 2022-12-28 06:26:39.000000000 -0800
+++ sqlite-amalgamation-modified/sqlite3.h 2023-08-04 14:53:19.667535836 -0700
@@ -146,11 +146,11 @@
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION "3.40.1"
#define SQLITE_VERSION_NUMBER 3040001
-#define SQLITE_SOURCE_ID "2022-12-28 14:03:47 df5c253c0b3dd24916e4ec7cf77d3db5294cc9fd45ae7b9c5e82ad8197f38a24"
+#define SQLITE_SOURCE_ID "2022-12-28 14:03:47 df5c253c0b3dd24916e4ec7cf77d3db5294cc9fd45ae7b9c5e82ad8197f3alt1"

/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version sqlite3_sourceid
**
@@ -8615,10 +8615,18 @@
** used to store the prepared statement. ^This value is not actually
** a counter, and so the resetFlg parameter to sqlite3_stmt_status()
** is ignored when the opcode is SQLITE_STMTSTATUS_MEMUSED.
** </dd>
** </dl>
+**
+** [[LIBSQL_STMTSTATUS_ROWS_READ]]
+** [[LIBSQL_STMTSTATUS_ROWS_WRITTEN]]
+** <dt>LIBSQL_STMTSTATUS_ROWS_READ<br>
+** LIBSQL_STMTSTATUS_ROWS_WRITTEN</dt>
+** <dd>^LIBSQL_STMTSTATUS_ROWS_READ is the number of rows read when executing
+** this statement. LIBSQL_STMTSTATUS_ROWS_WRITTEN value is the number of
+** rows written.
*/
#define SQLITE_STMTSTATUS_FULLSCAN_STEP 1
#define SQLITE_STMTSTATUS_SORT 2
#define SQLITE_STMTSTATUS_AUTOINDEX 3
#define SQLITE_STMTSTATUS_VM_STEP 4
@@ -8626,10 +8634,14 @@
#define SQLITE_STMTSTATUS_RUN 6
#define SQLITE_STMTSTATUS_FILTER_MISS 7
#define SQLITE_STMTSTATUS_FILTER_HIT 8
#define SQLITE_STMTSTATUS_MEMUSED 99

+#define LIBSQL_STMTSTATUS_BASE 1024
+#define LIBSQL_STMTSTATUS_ROWS_READ LIBSQL_STMTSTATUS_BASE + 1
+#define LIBSQL_STMTSTATUS_ROWS_WRITTEN LIBSQL_STMTSTATUS_BASE + 2
+
/*
** CAPI3REF: Custom Page Cache Object
**
** The sqlite3_pcache type is opaque. It is implemented by
** the pluggable module. The SQLite core has no knowledge of
Loading