Skip to content
File

Blob: patches/sqlite/0001-row-counts-plain.patch

9.3 KB
1diff -u5 -r sqlite-src-pristine/src/shell.c.in sqlite-src-modified/src/shell.c.in
2--- sqlite-src-pristine/src/shell.c.in 2024-10-21 11:47:53
3+++ sqlite-src-modified/src/shell.c.in 2024-11-05 08:16:15
4@@ -3411,10 +3411,15 @@
5 sqlite3_fprintf(out,
6 "Number of times run: %d\n", iCur);
7 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_MEMUSED, bReset);
8 sqlite3_fprintf(out,
9 "Memory used by prepared stmt: %d\n", iCur);
10+
11+ iCur = sqlite3_stmt_status(pArg->pStmt, LIBSQL_STMTSTATUS_ROWS_READ, bReset);
12+ sqlite3_fprintf(pArg->out, "Rows read: %d\n", iCur);
13+ iCur = sqlite3_stmt_status(pArg->pStmt, LIBSQL_STMTSTATUS_ROWS_WRITTEN, bReset);
14+ sqlite3_fprintf(pArg->out, "Rows written: %d\n", iCur);
15 }
16
17 #ifdef __linux__
18 displayLinuxIoStats(pArg->out);
19 #endif
20diff -u5 -r sqlite-src-pristine/src/sqlite.h.in sqlite-src-modified/src/sqlite.h.in
21--- sqlite-src-pristine/src/sqlite.h.in 2024-10-21 11:47:53
22+++ sqlite-src-modified/src/sqlite.h.in 2024-11-05 08:13:50
23@@ -8907,20 +8907,32 @@
24 ** used to store the prepared statement. ^This value is not actually
25 ** a counter, and so the resetFlg parameter to sqlite3_stmt_status()
26 ** is ignored when the opcode is SQLITE_STMTSTATUS_MEMUSED.
27 ** </dd>
28 ** </dl>
29+**
30+** [[LIBSQL_STMTSTATUS_ROWS_READ]]
31+** [[LIBSQL_STMTSTATUS_ROWS_WRITTEN]]
32+** <dt>LIBSQL_STMTSTATUS_ROWS_READ<br>
33+** LIBSQL_STMTSTATUS_ROWS_WRITTEN</dt>
34+** <dd>^LIBSQL_STMTSTATUS_ROWS_READ is the number of rows read when executing
35+** this statement. LIBSQL_STMTSTATUS_ROWS_WRITTEN value is the number of
36+** rows written.
37 */
38 #define SQLITE_STMTSTATUS_FULLSCAN_STEP 1
39 #define SQLITE_STMTSTATUS_SORT 2
40 #define SQLITE_STMTSTATUS_AUTOINDEX 3
41 #define SQLITE_STMTSTATUS_VM_STEP 4
42 #define SQLITE_STMTSTATUS_REPREPARE 5
43 #define SQLITE_STMTSTATUS_RUN 6
44 #define SQLITE_STMTSTATUS_FILTER_MISS 7
45 #define SQLITE_STMTSTATUS_FILTER_HIT 8
46 #define SQLITE_STMTSTATUS_MEMUSED 99
47+
48+#define LIBSQL_STMTSTATUS_BASE 1024
49+#define LIBSQL_STMTSTATUS_ROWS_READ LIBSQL_STMTSTATUS_BASE + 1
50+#define LIBSQL_STMTSTATUS_ROWS_WRITTEN LIBSQL_STMTSTATUS_BASE + 2
51
52 /*
53 ** CAPI3REF: Custom Page Cache Object
54 **
55 ** The sqlite3_pcache type is opaque. It is implemented by
56diff -u5 -r sqlite-src-pristine/src/vdbe.c sqlite-src-modified/src/vdbe.c
57--- sqlite-src-pristine/src/vdbe.c 2024-10-21 11:47:53
58+++ sqlite-src-modified/src/vdbe.c 2024-11-05 08:13:50
59@@ -3737,10 +3737,11 @@
60 if( pOp->p3 ){
61 nEntry = sqlite3BtreeRowCountEst(pCrsr);
62 }else{
63 nEntry = 0; /* Not needed. Only used to silence a warning. */
64 rc = sqlite3BtreeCount(db, pCrsr, &nEntry);
65+ p->aLibsqlCounter[LIBSQL_STMTSTATUS_ROWS_READ - LIBSQL_STMTSTATUS_BASE] += nEntry;
66 if( rc ) goto abort_due_to_error;
67 }
68 pOut = out2Prerelease(p, pOp);
69 pOut->u.i = nEntry;
70 goto check_for_interrupt;
71@@ -4900,10 +4901,11 @@
72 if( eqOnly && r.eqSeen==0 ){
73 assert( res!=0 );
74 goto seek_not_found;
75 }
76 }
77+ p->aLibsqlCounter[LIBSQL_STMTSTATUS_ROWS_READ - LIBSQL_STMTSTATUS_BASE]++;
78 #ifdef SQLITE_TEST
79 sqlite3_search_count++;
80 #endif
81 if( oc>=OP_SeekGE ){ assert( oc==OP_SeekGE || oc==OP_SeekGT );
82 if( res<0 || (res==0 && oc==OP_SeekGT) ){
83@@ -5470,10 +5472,11 @@
84 pC->nullRow = 0;
85 pC->cacheStatus = CACHE_STALE;
86 pC->deferredMoveto = 0;
87 VdbeBranchTaken(res!=0,2);
88 pC->seekResult = res;
89+ p->aLibsqlCounter[LIBSQL_STMTSTATUS_ROWS_READ - LIBSQL_STMTSTATUS_BASE]++;
90 if( res!=0 ){
91 assert( rc==SQLITE_OK );
92 if( pOp->p2==0 ){
93 rc = SQLITE_CORRUPT_BKPT;
94 }else{
95@@ -5727,10 +5730,11 @@
96 }
97 if( pOp->p5 & OPFLAG_ISNOOP ) break;
98 #endif
99
100 assert( (pOp->p5 & OPFLAG_LASTROWID)==0 || (pOp->p5 & OPFLAG_NCHANGE)!=0 );
101+ if (!pC->isEphemeral) p->aLibsqlCounter[LIBSQL_STMTSTATUS_ROWS_WRITTEN - LIBSQL_STMTSTATUS_BASE]++;
102 if( pOp->p5 & OPFLAG_NCHANGE ){
103 p->nChange++;
104 if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = x.nKey;
105 }
106 assert( (pData->flags & (MEM_Blob|MEM_Str))!=0 || pData->n==0 );
107@@ -5920,10 +5924,11 @@
108 pC->seekResult = 0;
109 if( rc ) goto abort_due_to_error;
110
111 /* Invoke the update-hook if required. */
112 if( opflags & OPFLAG_NCHANGE ){
113+ if (!pC->isEphemeral) p->aLibsqlCounter[LIBSQL_STMTSTATUS_ROWS_WRITTEN - LIBSQL_STMTSTATUS_BASE]++;
114 p->nChange++;
115 if( db->xUpdateCallback && ALWAYS(pTab!=0) && HasRowid(pTab) ){
116 db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, pTab->zName,
117 pC->movetoTarget);
118 assert( pC->iDb>=0 );
119@@ -6207,10 +6212,11 @@
120 rc = sqlite3BtreeLast(pCrsr, &res);
121 pC->nullRow = (u8)res;
122 pC->deferredMoveto = 0;
123 pC->cacheStatus = CACHE_STALE;
124 if( rc ) goto abort_due_to_error;
125+ p->aLibsqlCounter[LIBSQL_STMTSTATUS_ROWS_READ - LIBSQL_STMTSTATUS_BASE]++;
126 if( pOp->p2>0 ){
127 VdbeBranchTaken(res!=0,2);
128 if( res ) goto jump_to_p2;
129 }
130 break;
131@@ -6326,10 +6332,11 @@
132 pC->deferredMoveto = 0;
133 pC->cacheStatus = CACHE_STALE;
134 }
135 if( rc ) goto abort_due_to_error;
136 pC->nullRow = (u8)res;
137+ p->aLibsqlCounter[LIBSQL_STMTSTATUS_ROWS_READ - LIBSQL_STMTSTATUS_BASE]++;
138 if( pOp->p2>0 ){
139 VdbeBranchTaken(res!=0,2);
140 if( res ) goto jump_to_p2;
141 }
142 break;
143@@ -6431,10 +6438,11 @@
144 pC->cacheStatus = CACHE_STALE;
145 VdbeBranchTaken(rc==SQLITE_OK,2);
146 if( rc==SQLITE_OK ){
147 pC->nullRow = 0;
148 p->aCounter[pOp->p5]++;
149+ p->aLibsqlCounter[LIBSQL_STMTSTATUS_ROWS_READ - LIBSQL_STMTSTATUS_BASE]++;
150 #ifdef SQLITE_TEST
151 sqlite3_search_count++;
152 #endif
153 goto jump_to_p2_and_check_for_interrupt;
154 }
155@@ -6482,10 +6490,11 @@
156 assert( pC!=0 );
157 assert( !isSorter(pC) );
158 pIn2 = &aMem[pOp->p2];
159 assert( (pIn2->flags & MEM_Blob) || (pOp->p5 & OPFLAG_PREFORMAT) );
160 if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
161+ if (!pC->isEphemeral) p->aLibsqlCounter[LIBSQL_STMTSTATUS_ROWS_WRITTEN - LIBSQL_STMTSTATUS_BASE]++;
162 assert( pC->eCurType==CURTYPE_BTREE );
163 assert( pC->isTable==0 );
164 rc = ExpandBlob(pIn2);
165 if( rc ) goto abort_due_to_error;
166 x.nKey = pIn2->n;
167@@ -6882,10 +6891,11 @@
168 assert( p->readOnly==0 );
169 assert( DbMaskTest(p->btreeMask, pOp->p2) );
170 rc = sqlite3BtreeClearTable(db->aDb[pOp->p2].pBt, (u32)pOp->p1, &nChange);
171 if( pOp->p3 ){
172 p->nChange += nChange;
173+ p->aLibsqlCounter[LIBSQL_STMTSTATUS_ROWS_WRITTEN - LIBSQL_STMTSTATUS_BASE] += nChange;
174 if( pOp->p3>0 ){
175 assert( memIsValid(&aMem[pOp->p3]) );
176 memAboutToChange(p, &aMem[pOp->p3]);
177 aMem[pOp->p3].u.i += nChange;
178 }
179@@ -8466,10 +8476,11 @@
180 ** some other method is next invoked on the save virtual table cursor.
181 */
182 rc = pModule->xNext(pCur->uc.pVCur);
183 sqlite3VtabImportErrmsg(p, pVtab);
184 if( rc ) goto abort_due_to_error;
185+ p->aLibsqlCounter[LIBSQL_STMTSTATUS_ROWS_READ - LIBSQL_STMTSTATUS_BASE]++;
186 res = pModule->xEof(pCur->uc.pVCur);
187 VdbeBranchTaken(!res,2);
188 if( !res ){
189 /* If there is data, jump to P2 */
190 goto jump_to_p2_and_check_for_interrupt;
191@@ -8587,10 +8598,11 @@
192 rc = SQLITE_OK;
193 }else{
194 p->errorAction = ((pOp->p5==OE_Replace) ? OE_Abort : pOp->p5);
195 }
196 }else{
197+ p->aLibsqlCounter[LIBSQL_STMTSTATUS_ROWS_WRITTEN - LIBSQL_STMTSTATUS_BASE]++;
198 p->nChange++;
199 }
200 if( rc ) goto abort_due_to_error;
201 }
202 break;
203diff -u5 -r sqlite-src-pristine/src/vdbeInt.h sqlite-src-modified/src/vdbeInt.h
204--- sqlite-src-pristine/src/vdbeInt.h 2024-10-21 11:47:53
205+++ sqlite-src-modified/src/vdbeInt.h 2024-11-05 08:13:50
206@@ -496,10 +496,11 @@
207 bft bIsReader:1; /* True for statements that read */
208 bft haveEqpOps:1; /* Bytecode supports EXPLAIN QUERY PLAN */
209 yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */
210 yDbMask lockMask; /* Subset of btreeMask that requires a lock */
211 u32 aCounter[9]; /* Counters used by sqlite3_stmt_status() */
212+ u32 aLibsqlCounter[3]; /* libSQL extension: Counters used by sqlite3_stmt_status()*/
213 char *zSql; /* Text of the SQL statement that generated this */
214 #ifdef SQLITE_ENABLE_NORMALIZE
215 char *zNormSql; /* Normalization of the associated SQL statement */
216 DblquoteStr *pDblStr; /* List of double-quoted string literals */
217 #endif
218diff -u5 -r sqlite-src-pristine/src/vdbeapi.c sqlite-src-modified/src/vdbeapi.c
219--- sqlite-src-pristine/src/vdbeapi.c 2024-10-21 11:47:53
220+++ sqlite-src-modified/src/vdbeapi.c 2024-11-05 08:13:50
221@@ -2072,11 +2072,11 @@
222 int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){
223 Vdbe *pVdbe = (Vdbe*)pStmt;
224 u32 v;
225 #ifdef SQLITE_ENABLE_API_ARMOR
226 if( !pStmt
227- || (op!=SQLITE_STMTSTATUS_MEMUSED && (op<0||op>=ArraySize(pVdbe->aCounter)))
228+ || (op!=SQLITE_STMTSTATUS_MEMUSED && (op<0||(op>=ArraySize(pVdbe->aCounter)&&op<LIBSQL_STMTSTATUS_BASE)))
229 ){
230 (void)SQLITE_MISUSE_BKPT;
231 return 0;
232 }
233 #endif
234@@ -2089,10 +2089,13 @@
235 db->lookaside.pEnd = db->lookaside.pStart;
236 sqlite3VdbeDelete(pVdbe);
237 db->pnBytesFreed = 0;
238 db->lookaside.pEnd = db->lookaside.pTrueEnd;
239 sqlite3_mutex_leave(db->mutex);
240+ }else if( op>=LIBSQL_STMTSTATUS_BASE ){
241+ v = pVdbe->aLibsqlCounter[op - LIBSQL_STMTSTATUS_BASE];
242+ if( resetFlag ) pVdbe->aLibsqlCounter[op - LIBSQL_STMTSTATUS_BASE] = 0;
243 }else{
244 v = pVdbe->aCounter[op];
245 if( resetFlag ) pVdbe->aCounter[op] = 0;
246 }
247 return (int)v;