Fossil SCM

Update to the latest version of SQLite with the sqlite3_stmt_readonly() capability and use that interface for additional security of the user-entered SQL in the ticket report logic.

drh 2010-11-16 23:16 trunk
Commit 115f3ea60ed2e57ffcce69ac8c2e11501a72c006
3 files changed +61 -3 +55 -4 +16 -1
+61 -3
--- src/report.c
+++ src/report.c
@@ -239,10 +239,13 @@
239239
sqlite3_set_authorizer(g.db, report_query_authorizer, (void*)&zErr);
240240
rc = sqlite3_prepare(g.db, zSql, -1, &pStmt, &zTail);
241241
if( rc!=SQLITE_OK ){
242242
zErr = mprintf("Syntax error: %s", sqlite3_errmsg(g.db));
243243
}
244
+ if( !sqlite3_stmt_readonly(pStmt) ){
245
+ zErr = mprintf("SQL must not modify the database");
246
+ }
244247
if( pStmt ){
245248
sqlite3_finalize(pStmt);
246249
}
247250
sqlite3_set_authorizer(g.db, 0, 0);
248251
return zErr;
@@ -815,10 +818,65 @@
815818
@ </tr>
816819
}
817820
@ </table>
818821
}
819822
823
+/*
824
+** Execute a single read-only SQL statement. Invoke xCallback() on each
825
+** row.
826
+*/
827
+int sqlite3_exec_readonly(
828
+ sqlite3 *db, /* The database on which the SQL executes */
829
+ const char *zSql, /* The SQL to be executed */
830
+ sqlite3_callback xCallback, /* Invoke this callback routine */
831
+ void *pArg, /* First argument to xCallback() */
832
+ char **pzErrMsg /* Write error messages here */
833
+){
834
+ int rc = SQLITE_OK; /* Return code */
835
+ const char *zLeftover; /* Tail of unprocessed SQL */
836
+ sqlite3_stmt *pStmt = 0; /* The current SQL statement */
837
+ char **azCols = 0; /* Names of result columns */
838
+ int nCol; /* Number of columns of output */
839
+ char **azVals = 0; /* Text of all output columns */
840
+ int i; /* Loop counter */
841
+
842
+ pStmt = 0;
843
+ rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
844
+ assert( rc==SQLITE_OK || pStmt==0 );
845
+ if( rc!=SQLITE_OK ){
846
+ return rc;
847
+ }
848
+ if( !pStmt ){
849
+ /* this happens for a comment or white-space */
850
+ return SQLITE_OK;
851
+ }
852
+ if( !sqlite3_stmt_readonly(pStmt) ){
853
+ sqlite3_finalize(pStmt);
854
+ return SQLITE_ERROR;
855
+ }
856
+
857
+ nCol = sqlite3_column_count(pStmt);
858
+ azVals = fossil_malloc(2*nCol*sizeof(const char*) + 1);
859
+ while( (rc = sqlite3_step(pStmt))==SQLITE_ROW ){
860
+ if( azCols==0 ){
861
+ azCols = &azVals[nCol];
862
+ for(i=0; i<nCol; i++){
863
+ azCols[i] = (char *)sqlite3_column_name(pStmt, i);
864
+ }
865
+ }
866
+ for(i=0; i<nCol; i++){
867
+ azVals[i] = (char *)sqlite3_column_text(pStmt, i);
868
+ }
869
+ if( xCallback(pArg, nCol, azVals, azCols) ){
870
+ break;
871
+ }
872
+ }
873
+ rc = sqlite3_finalize(pStmt);
874
+ fossil_free(azVals);
875
+ return rc;
876
+}
877
+
820878
821879
/*
822880
** WEBPAGE: /rptview
823881
**
824882
** Generate a report. The rn query parameter is the report number
@@ -897,11 +955,11 @@
897955
"border=\"0\" cellpadding=\"3\" cellspacing=\"0\" class=\"report\"");
898956
@ <table border="1" cellpadding="2" cellspacing="0" class="report">
899957
sState.rn = rn;
900958
sState.nCount = 0;
901959
sqlite3_set_authorizer(g.db, report_query_authorizer, (void*)&zErr1);
902
- sqlite3_exec(g.db, zSql, generate_html, &sState, &zErr2);
960
+ sqlite3_exec_readonly(g.db, zSql, generate_html, &sState, &zErr2);
903961
sqlite3_set_authorizer(g.db, 0, 0);
904962
@ </table>
905963
if( zErr1 ){
906964
@ <p class="reportError">Error: %h(zErr1)</p>
907965
}else if( zErr2 ){
@@ -908,11 +966,11 @@
908966
@ <p class="reportError">Error: %h(zErr2)</p>
909967
}
910968
style_footer();
911969
}else{
912970
sqlite3_set_authorizer(g.db, report_query_authorizer, (void*)&zErr1);
913
- sqlite3_exec(g.db, zSql, output_tab_separated, &count, &zErr2);
971
+ sqlite3_exec_readonly(g.db, zSql, output_tab_separated, &count, &zErr2);
914972
sqlite3_set_authorizer(g.db, 0, 0);
915973
cgi_set_content_type("text/plain");
916974
}
917975
}
918976
@@ -1070,11 +1128,11 @@
10701128
}
10711129
count = 0;
10721130
tktEncode = enc;
10731131
zSep = zSepIn;
10741132
sqlite3_set_authorizer(g.db, report_query_authorizer, (void*)&zErr1);
1075
- sqlite3_exec(g.db, zSql, output_separated_file, &count, &zErr2);
1133
+ sqlite3_exec_readonly(g.db, zSql, output_separated_file, &count, &zErr2);
10761134
sqlite3_set_authorizer(g.db, 0, 0);
10771135
if( zFilter ){
10781136
free(zSql);
10791137
}
10801138
}
10811139
--- src/report.c
+++ src/report.c
@@ -239,10 +239,13 @@
239 sqlite3_set_authorizer(g.db, report_query_authorizer, (void*)&zErr);
240 rc = sqlite3_prepare(g.db, zSql, -1, &pStmt, &zTail);
241 if( rc!=SQLITE_OK ){
242 zErr = mprintf("Syntax error: %s", sqlite3_errmsg(g.db));
243 }
 
 
 
244 if( pStmt ){
245 sqlite3_finalize(pStmt);
246 }
247 sqlite3_set_authorizer(g.db, 0, 0);
248 return zErr;
@@ -815,10 +818,65 @@
815 @ </tr>
816 }
817 @ </table>
818 }
819
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
820
821 /*
822 ** WEBPAGE: /rptview
823 **
824 ** Generate a report. The rn query parameter is the report number
@@ -897,11 +955,11 @@
897 "border=\"0\" cellpadding=\"3\" cellspacing=\"0\" class=\"report\"");
898 @ <table border="1" cellpadding="2" cellspacing="0" class="report">
899 sState.rn = rn;
900 sState.nCount = 0;
901 sqlite3_set_authorizer(g.db, report_query_authorizer, (void*)&zErr1);
902 sqlite3_exec(g.db, zSql, generate_html, &sState, &zErr2);
903 sqlite3_set_authorizer(g.db, 0, 0);
904 @ </table>
905 if( zErr1 ){
906 @ <p class="reportError">Error: %h(zErr1)</p>
907 }else if( zErr2 ){
@@ -908,11 +966,11 @@
908 @ <p class="reportError">Error: %h(zErr2)</p>
909 }
910 style_footer();
911 }else{
912 sqlite3_set_authorizer(g.db, report_query_authorizer, (void*)&zErr1);
913 sqlite3_exec(g.db, zSql, output_tab_separated, &count, &zErr2);
914 sqlite3_set_authorizer(g.db, 0, 0);
915 cgi_set_content_type("text/plain");
916 }
917 }
918
@@ -1070,11 +1128,11 @@
1070 }
1071 count = 0;
1072 tktEncode = enc;
1073 zSep = zSepIn;
1074 sqlite3_set_authorizer(g.db, report_query_authorizer, (void*)&zErr1);
1075 sqlite3_exec(g.db, zSql, output_separated_file, &count, &zErr2);
1076 sqlite3_set_authorizer(g.db, 0, 0);
1077 if( zFilter ){
1078 free(zSql);
1079 }
1080 }
1081
--- src/report.c
+++ src/report.c
@@ -239,10 +239,13 @@
239 sqlite3_set_authorizer(g.db, report_query_authorizer, (void*)&zErr);
240 rc = sqlite3_prepare(g.db, zSql, -1, &pStmt, &zTail);
241 if( rc!=SQLITE_OK ){
242 zErr = mprintf("Syntax error: %s", sqlite3_errmsg(g.db));
243 }
244 if( !sqlite3_stmt_readonly(pStmt) ){
245 zErr = mprintf("SQL must not modify the database");
246 }
247 if( pStmt ){
248 sqlite3_finalize(pStmt);
249 }
250 sqlite3_set_authorizer(g.db, 0, 0);
251 return zErr;
@@ -815,10 +818,65 @@
818 @ </tr>
819 }
820 @ </table>
821 }
822
823 /*
824 ** Execute a single read-only SQL statement. Invoke xCallback() on each
825 ** row.
826 */
827 int sqlite3_exec_readonly(
828 sqlite3 *db, /* The database on which the SQL executes */
829 const char *zSql, /* The SQL to be executed */
830 sqlite3_callback xCallback, /* Invoke this callback routine */
831 void *pArg, /* First argument to xCallback() */
832 char **pzErrMsg /* Write error messages here */
833 ){
834 int rc = SQLITE_OK; /* Return code */
835 const char *zLeftover; /* Tail of unprocessed SQL */
836 sqlite3_stmt *pStmt = 0; /* The current SQL statement */
837 char **azCols = 0; /* Names of result columns */
838 int nCol; /* Number of columns of output */
839 char **azVals = 0; /* Text of all output columns */
840 int i; /* Loop counter */
841
842 pStmt = 0;
843 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
844 assert( rc==SQLITE_OK || pStmt==0 );
845 if( rc!=SQLITE_OK ){
846 return rc;
847 }
848 if( !pStmt ){
849 /* this happens for a comment or white-space */
850 return SQLITE_OK;
851 }
852 if( !sqlite3_stmt_readonly(pStmt) ){
853 sqlite3_finalize(pStmt);
854 return SQLITE_ERROR;
855 }
856
857 nCol = sqlite3_column_count(pStmt);
858 azVals = fossil_malloc(2*nCol*sizeof(const char*) + 1);
859 while( (rc = sqlite3_step(pStmt))==SQLITE_ROW ){
860 if( azCols==0 ){
861 azCols = &azVals[nCol];
862 for(i=0; i<nCol; i++){
863 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
864 }
865 }
866 for(i=0; i<nCol; i++){
867 azVals[i] = (char *)sqlite3_column_text(pStmt, i);
868 }
869 if( xCallback(pArg, nCol, azVals, azCols) ){
870 break;
871 }
872 }
873 rc = sqlite3_finalize(pStmt);
874 fossil_free(azVals);
875 return rc;
876 }
877
878
879 /*
880 ** WEBPAGE: /rptview
881 **
882 ** Generate a report. The rn query parameter is the report number
@@ -897,11 +955,11 @@
955 "border=\"0\" cellpadding=\"3\" cellspacing=\"0\" class=\"report\"");
956 @ <table border="1" cellpadding="2" cellspacing="0" class="report">
957 sState.rn = rn;
958 sState.nCount = 0;
959 sqlite3_set_authorizer(g.db, report_query_authorizer, (void*)&zErr1);
960 sqlite3_exec_readonly(g.db, zSql, generate_html, &sState, &zErr2);
961 sqlite3_set_authorizer(g.db, 0, 0);
962 @ </table>
963 if( zErr1 ){
964 @ <p class="reportError">Error: %h(zErr1)</p>
965 }else if( zErr2 ){
@@ -908,11 +966,11 @@
966 @ <p class="reportError">Error: %h(zErr2)</p>
967 }
968 style_footer();
969 }else{
970 sqlite3_set_authorizer(g.db, report_query_authorizer, (void*)&zErr1);
971 sqlite3_exec_readonly(g.db, zSql, output_tab_separated, &count, &zErr2);
972 sqlite3_set_authorizer(g.db, 0, 0);
973 cgi_set_content_type("text/plain");
974 }
975 }
976
@@ -1070,11 +1128,11 @@
1128 }
1129 count = 0;
1130 tktEncode = enc;
1131 zSep = zSepIn;
1132 sqlite3_set_authorizer(g.db, report_query_authorizer, (void*)&zErr1);
1133 sqlite3_exec_readonly(g.db, zSql, output_separated_file, &count, &zErr2);
1134 sqlite3_set_authorizer(g.db, 0, 0);
1135 if( zFilter ){
1136 free(zSql);
1137 }
1138 }
1139
+55 -4
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -650,11 +650,11 @@
650650
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
651651
** [sqlite_version()] and [sqlite_source_id()].
652652
*/
653653
#define SQLITE_VERSION "3.7.4"
654654
#define SQLITE_VERSION_NUMBER 3007004
655
-#define SQLITE_SOURCE_ID "2010-11-15 16:29:31 136c2ac24ee1663bc0904bce1a619ecef3d11c1c"
655
+#define SQLITE_SOURCE_ID "2010-11-16 23:10:26 fd5b2f23dd5111d2f0934dd828bae36b755024c1"
656656
657657
/*
658658
** CAPI3REF: Run-Time Library Version Numbers
659659
** KEYWORDS: sqlite3_version, sqlite3_sourceid
660660
**
@@ -3174,10 +3174,25 @@
31743174
** SQL text used to create a [prepared statement] if that statement was
31753175
** compiled using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()].
31763176
*/
31773177
SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
31783178
3179
+/*
3180
+** CAPI3REF: Determine If An SQL Statement Writes The Database
3181
+**
3182
+** ^The sqlite3_stmt_readonly(X) interface returns true (non-zero) if
3183
+** the [prepared statement] X is guaranteed to leave the database file
3184
+** unmodified. ^If the sqlite3_stmt_readonly(X) interface returns false (zero)
3185
+** then evaluating the statement might change the database file, but this
3186
+** is not guaranteed as the write operation might be conditional and the
3187
+** condition might not be met. ^If X is a NULL pointer then
3188
+** sqlite3_stmt_readonly(X) returns true. If X is a non-NULL pointer but
3189
+** is not a pointer to a valid, unfinalized prepared statement, then the
3190
+** behavior is undefined and probably harmful.
3191
+*/
3192
+SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
3193
+
31793194
/*
31803195
** CAPI3REF: Dynamically Typed Value Object
31813196
** KEYWORDS: {protected sqlite3_value} {unprotected sqlite3_value}
31823197
**
31833198
** SQLite uses the sqlite3_value object to represent all values
@@ -10050,10 +10065,11 @@
1005010065
int iContinue; /* Jump here to continue with next record */
1005110066
int iBreak; /* Jump here to break out of the loop */
1005210067
int nLevel; /* Number of nested loop */
1005310068
struct WhereClause *pWC; /* Decomposition of the WHERE clause */
1005410069
double savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */
10070
+ double nRowOut; /* Estimated number of output rows */
1005510071
WhereLevel a[1]; /* Information about each nest loop in WHERE */
1005610072
};
1005710073
1005810074
/*
1005910075
** A NameContext defines a context in which to resolve table and column
@@ -10125,10 +10141,11 @@
1012510141
Select *pRightmost; /* Right-most select in a compound select statement */
1012610142
Expr *pLimit; /* LIMIT expression. NULL means not used. */
1012710143
Expr *pOffset; /* OFFSET expression. NULL means not used. */
1012810144
int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */
1012910145
int addrOpenEphm[3]; /* OP_OpenEphem opcodes related to this select */
10146
+ double nSelectRow; /* Estimated number of result rows */
1013010147
};
1013110148
1013210149
/*
1013310150
** Allowed values for Select.selFlags. The "SF" prefix stands for
1013410151
** "Select Flag".
@@ -59476,10 +59493,18 @@
5947659493
** the statement in the first place.
5947759494
*/
5947859495
SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt *pStmt){
5947959496
return pStmt ? ((Vdbe*)pStmt)->db : 0;
5948059497
}
59498
+
59499
+/*
59500
+** Return true if the prepared statement is guaranteed to not modify the
59501
+** database.
59502
+*/
59503
+SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt){
59504
+ return pStmt ? ((Vdbe*)pStmt)->readOnly : 1;
59505
+}
5948159506
5948259507
/*
5948359508
** Return a pointer to the next prepared statement after pStmt associated
5948459509
** with database connection pDb. If pStmt is NULL, return the first
5948559510
** prepared statement for the database connection. Return NULL if there
@@ -88974,10 +88999,12 @@
8897488999
if( sqlite3ExprIsInteger(p->pLimit, &n) ){
8897589000
sqlite3VdbeAddOp2(v, OP_Integer, n, iLimit);
8897689001
VdbeComment((v, "LIMIT counter"));
8897789002
if( n==0 ){
8897889003
sqlite3VdbeAddOp2(v, OP_Goto, 0, iBreak);
89004
+ }else{
89005
+ if( p->nSelectRow > (double)n ) p->nSelectRow = (double)n;
8897989006
}
8898089007
}else{
8898189008
sqlite3ExprCode(pParse, p->pLimit, iLimit);
8898289009
sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit);
8898389010
VdbeComment((v, "LIMIT counter"));
@@ -89135,10 +89162,11 @@
8913589162
/* Generate code for the left and right SELECT statements.
8913689163
*/
8913789164
switch( p->op ){
8913889165
case TK_ALL: {
8913989166
int addr = 0;
89167
+ int nLimit;
8914089168
assert( !pPrior->pLimit );
8914189169
pPrior->pLimit = p->pLimit;
8914289170
pPrior->pOffset = p->pOffset;
8914389171
explainSetInteger(iSub1, pParse->iNextSelectId);
8914489172
rc = sqlite3Select(pParse, pPrior, &dest);
@@ -89157,10 +89185,17 @@
8915789185
explainSetInteger(iSub2, pParse->iNextSelectId);
8915889186
rc = sqlite3Select(pParse, p, &dest);
8915989187
testcase( rc!=SQLITE_OK );
8916089188
pDelete = p->pPrior;
8916189189
p->pPrior = pPrior;
89190
+ p->nSelectRow += pPrior->nSelectRow;
89191
+ if( pPrior->pLimit
89192
+ && sqlite3ExprIsInteger(pPrior->pLimit, &nLimit)
89193
+ && p->nSelectRow > (double)nLimit
89194
+ ){
89195
+ p->nSelectRow = (double)nLimit;
89196
+ }
8916289197
if( addr ){
8916389198
sqlite3VdbeJumpHere(v, addr);
8916489199
}
8916589200
break;
8916689201
}
@@ -89229,10 +89264,11 @@
8922989264
** Be sure to delete p->pOrderBy, therefore, to avoid a memory leak. */
8923089265
sqlite3ExprListDelete(db, p->pOrderBy);
8923189266
pDelete = p->pPrior;
8923289267
p->pPrior = pPrior;
8923389268
p->pOrderBy = 0;
89269
+ if( p->op==TK_UNION ) p->nSelectRow += pPrior->nSelectRow;
8923489270
sqlite3ExprDelete(db, p->pLimit);
8923589271
p->pLimit = pLimit;
8923689272
p->pOffset = pOffset;
8923789273
p->iLimit = 0;
8923889274
p->iOffset = 0;
@@ -89308,10 +89344,11 @@
8930889344
explainSetInteger(iSub2, pParse->iNextSelectId);
8930989345
rc = sqlite3Select(pParse, p, &intersectdest);
8931089346
testcase( rc!=SQLITE_OK );
8931189347
pDelete = p->pPrior;
8931289348
p->pPrior = pPrior;
89349
+ if( p->nSelectRow>pPrior->nSelectRow ) p->nSelectRow = pPrior->nSelectRow;
8931389350
sqlite3ExprDelete(db, p->pLimit);
8931489351
p->pLimit = pLimit;
8931589352
p->pOffset = pOffset;
8931689353
8931789354
/* Generate code to take the intersection of the two temporary
@@ -89894,17 +89931,19 @@
8989489931
}else{
8989589932
addrEofA = sqlite3VdbeAddOp2(v, OP_If, regEofB, labelEnd);
8989689933
sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB);
8989789934
sqlite3VdbeAddOp1(v, OP_Yield, regAddrB);
8989889935
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEofA);
89936
+ p->nSelectRow += pPrior->nSelectRow;
8989989937
}
8990089938
8990189939
/* Generate a subroutine to run when the results from select B
8990289940
** are exhausted and only data in select A remains.
8990389941
*/
8990489942
if( op==TK_INTERSECT ){
8990589943
addrEofB = addrEofA;
89944
+ if( p->nSelectRow > pPrior->nSelectRow ) p->nSelectRow = pPrior->nSelectRow;
8990689945
}else{
8990789946
VdbeNoopComment((v, "eof-B subroutine"));
8990889947
addrEofB = sqlite3VdbeAddOp2(v, OP_If, regEofA, labelEnd);
8990989948
sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA);
8991089949
sqlite3VdbeAddOp1(v, OP_Yield, regAddrA);
@@ -91295,10 +91334,11 @@
9129591334
sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
9129691335
assert( pItem->isPopulated==0 );
9129791336
explainSetInteger(pItem->iSelectId, pParse->iNextSelectId);
9129891337
sqlite3Select(pParse, pSub, &dest);
9129991338
pItem->isPopulated = 1;
91339
+ pItem->pTab->nRowEst = (unsigned)pSub->nSelectRow;
9130091340
}
9130191341
if( /*pParse->nErr ||*/ db->mallocFailed ){
9130291342
goto select_end;
9130391343
}
9130491344
pParse->nHeight -= sqlite3SelectExprHeight(p);
@@ -91387,10 +91427,11 @@
9138791427
}
9138891428
9138991429
/* Set the limiter.
9139091430
*/
9139191431
iEnd = sqlite3VdbeMakeLabel(v);
91432
+ p->nSelectRow = (double)LARGEST_INT64;
9139291433
computeLimitRegisters(pParse, p, iEnd);
9139391434
9139491435
/* Open a virtual index to use for the distinct set.
9139591436
*/
9139691437
if( p->selFlags & SF_Distinct ){
@@ -91410,10 +91451,11 @@
9141091451
/* This case is for non-aggregate queries
9141191452
** Begin the database scan
9141291453
*/
9141391454
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pOrderBy, 0);
9141491455
if( pWInfo==0 ) goto select_end;
91456
+ if( pWInfo->nRowOut < p->nSelectRow ) p->nSelectRow = pWInfo->nRowOut;
9141591457
9141691458
/* If sorting index that was created by a prior OP_OpenEphemeral
9141791459
** instruction ended up not being needed, then change the OP_OpenEphemeral
9141891460
** into an OP_Noop.
9141991461
*/
@@ -91454,10 +91496,13 @@
9145491496
pItem->iAlias = 0;
9145591497
}
9145691498
for(k=pGroupBy->nExpr, pItem=pGroupBy->a; k>0; k--, pItem++){
9145791499
pItem->iAlias = 0;
9145891500
}
91501
+ if( p->nSelectRow>(double)100 ) p->nSelectRow = (double)100;
91502
+ }else{
91503
+ p->nSelectRow = (double)1;
9145991504
}
9146091505
9146191506
9146291507
/* Create a label to jump to when we want to abort the query */
9146391508
addrEnd = sqlite3VdbeMakeLabel(v);
@@ -95437,10 +95482,11 @@
9543795482
#define WHERE_INDEXED 0x000f0000 /* Anything that uses an index */
9543895483
#define WHERE_NOT_FULLSCAN 0x100f3000 /* Does not do a full table scan */
9543995484
#define WHERE_IN_ABLE 0x000f1000 /* Able to support an IN operator */
9544095485
#define WHERE_TOP_LIMIT 0x00100000 /* x<EXPR or x<=EXPR constraint */
9544195486
#define WHERE_BTM_LIMIT 0x00200000 /* x>EXPR or x>=EXPR constraint */
95487
+#define WHERE_BOTH_LIMIT 0x00300000 /* Both x>EXPR and x<EXPR */
9544295488
#define WHERE_IDX_ONLY 0x00800000 /* Use index only - omit table */
9544395489
#define WHERE_ORDERBY 0x01000000 /* Output will appear in correct order */
9544495490
#define WHERE_REVERSE 0x02000000 /* Scan in reverse order */
9544595491
#define WHERE_UNIQUE 0x04000000 /* Selects no more than one row */
9544695492
#define WHERE_VIRTUALTABLE 0x08000000 /* Use virtual-table processing */
@@ -98425,11 +98471,13 @@
9842598471
int iId = pParse->iSelectId; /* Select id (left-most output column) */
9842698472
int isSearch; /* True for a SEARCH. False for SCAN. */
9842798473
9842898474
if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_ONETABLE_ONLY) ) return;
9842998475
98430
- isSearch = (pLevel->plan.nEq>0 || flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT));
98476
+ isSearch = (pLevel->plan.nEq>0)
98477
+ || (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0
98478
+ || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX));
9843198479
9843298480
zMsg = sqlite3MPrintf(db, "%s", isSearch?"SEARCH":"SCAN");
9843398481
if( pItem->pSelect ){
9843498482
zMsg = sqlite3MAppendf(db, zMsg, "%s SUBQUERY %d", zMsg,pItem->iSelectId);
9843598483
}else{
@@ -98452,11 +98500,11 @@
9845298500
}else if( flags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){
9845398501
zMsg = sqlite3MAppendf(db, zMsg, "%s USING INTEGER PRIMARY KEY", zMsg);
9845498502
9845598503
if( flags&WHERE_ROWID_EQ ){
9845698504
zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid=?)", zMsg);
98457
- }else if( flags&WHERE_BTM_LIMIT && flags&WHERE_TOP_LIMIT ){
98505
+ }else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){
9845898506
zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>? AND rowid<?)", zMsg);
9845998507
}else if( flags&WHERE_BTM_LIMIT ){
9846098508
zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>?)", zMsg);
9846198509
}else if( flags&WHERE_TOP_LIMIT ){
9846298510
zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid<?)", zMsg);
@@ -98468,10 +98516,11 @@
9846898516
zMsg = sqlite3MAppendf(db, zMsg, "%s VIRTUAL TABLE INDEX %d:%s", zMsg,
9846998517
pVtabIdx->idxNum, pVtabIdx->idxStr);
9847098518
}
9847198519
#endif
9847298520
if( wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX) ){
98521
+ testcase( wctrlFlags & WHERE_ORDERBY_MIN );
9847398522
nRow = 1;
9847498523
}else{
9847598524
nRow = (sqlite3_int64)pLevel->plan.nRow;
9847698525
}
9847798526
zMsg = sqlite3MAppendf(db, zMsg, "%s (~%lld rows)", zMsg, nRow);
@@ -98888,11 +98937,11 @@
9888898937
** If it is, jump to the next iteration of the loop.
9888998938
*/
9889098939
r1 = sqlite3GetTempReg(pParse);
9889198940
testcase( pLevel->plan.wsFlags & WHERE_BTM_LIMIT );
9889298941
testcase( pLevel->plan.wsFlags & WHERE_TOP_LIMIT );
98893
- if( pLevel->plan.wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT) ){
98942
+ if( (pLevel->plan.wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0 ){
9889498943
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, nEq, r1);
9889598944
sqlite3VdbeAddOp2(v, OP_IsNull, r1, addrCont);
9889698945
}
9889798946
sqlite3ReleaseTempReg(pParse, r1);
9889898947
@@ -99618,17 +99667,19 @@
9961899667
/* Open all tables in the pTabList and any indices selected for
9961999668
** searching those tables.
9962099669
*/
9962199670
sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */
9962299671
notReady = ~(Bitmask)0;
99672
+ pWInfo->nRowOut = (double)1;
9962399673
for(i=0, pLevel=pWInfo->a; i<nTabList; i++, pLevel++){
9962499674
Table *pTab; /* Table to open */
9962599675
int iDb; /* Index of database containing table/index */
9962699676
9962799677
pTabItem = &pTabList->a[pLevel->iFrom];
9962899678
pTab = pTabItem->pTab;
9962999679
pLevel->iTabCur = pTabItem->iCursor;
99680
+ pWInfo->nRowOut *= pLevel->plan.nRow;
9963099681
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
9963199682
if( (pTab->tabFlags & TF_Ephemeral)!=0 || pTab->pSelect ){
9963299683
/* Do nothing */
9963399684
}else
9963499685
#ifndef SQLITE_OMIT_VIRTUALTABLE
9963599686
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -650,11 +650,11 @@
650 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
651 ** [sqlite_version()] and [sqlite_source_id()].
652 */
653 #define SQLITE_VERSION "3.7.4"
654 #define SQLITE_VERSION_NUMBER 3007004
655 #define SQLITE_SOURCE_ID "2010-11-15 16:29:31 136c2ac24ee1663bc0904bce1a619ecef3d11c1c"
656
657 /*
658 ** CAPI3REF: Run-Time Library Version Numbers
659 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
660 **
@@ -3174,10 +3174,25 @@
3174 ** SQL text used to create a [prepared statement] if that statement was
3175 ** compiled using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()].
3176 */
3177 SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
3178
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3179 /*
3180 ** CAPI3REF: Dynamically Typed Value Object
3181 ** KEYWORDS: {protected sqlite3_value} {unprotected sqlite3_value}
3182 **
3183 ** SQLite uses the sqlite3_value object to represent all values
@@ -10050,10 +10065,11 @@
10050 int iContinue; /* Jump here to continue with next record */
10051 int iBreak; /* Jump here to break out of the loop */
10052 int nLevel; /* Number of nested loop */
10053 struct WhereClause *pWC; /* Decomposition of the WHERE clause */
10054 double savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */
 
10055 WhereLevel a[1]; /* Information about each nest loop in WHERE */
10056 };
10057
10058 /*
10059 ** A NameContext defines a context in which to resolve table and column
@@ -10125,10 +10141,11 @@
10125 Select *pRightmost; /* Right-most select in a compound select statement */
10126 Expr *pLimit; /* LIMIT expression. NULL means not used. */
10127 Expr *pOffset; /* OFFSET expression. NULL means not used. */
10128 int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */
10129 int addrOpenEphm[3]; /* OP_OpenEphem opcodes related to this select */
 
10130 };
10131
10132 /*
10133 ** Allowed values for Select.selFlags. The "SF" prefix stands for
10134 ** "Select Flag".
@@ -59476,10 +59493,18 @@
59476 ** the statement in the first place.
59477 */
59478 SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt *pStmt){
59479 return pStmt ? ((Vdbe*)pStmt)->db : 0;
59480 }
 
 
 
 
 
 
 
 
59481
59482 /*
59483 ** Return a pointer to the next prepared statement after pStmt associated
59484 ** with database connection pDb. If pStmt is NULL, return the first
59485 ** prepared statement for the database connection. Return NULL if there
@@ -88974,10 +88999,12 @@
88974 if( sqlite3ExprIsInteger(p->pLimit, &n) ){
88975 sqlite3VdbeAddOp2(v, OP_Integer, n, iLimit);
88976 VdbeComment((v, "LIMIT counter"));
88977 if( n==0 ){
88978 sqlite3VdbeAddOp2(v, OP_Goto, 0, iBreak);
 
 
88979 }
88980 }else{
88981 sqlite3ExprCode(pParse, p->pLimit, iLimit);
88982 sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit);
88983 VdbeComment((v, "LIMIT counter"));
@@ -89135,10 +89162,11 @@
89135 /* Generate code for the left and right SELECT statements.
89136 */
89137 switch( p->op ){
89138 case TK_ALL: {
89139 int addr = 0;
 
89140 assert( !pPrior->pLimit );
89141 pPrior->pLimit = p->pLimit;
89142 pPrior->pOffset = p->pOffset;
89143 explainSetInteger(iSub1, pParse->iNextSelectId);
89144 rc = sqlite3Select(pParse, pPrior, &dest);
@@ -89157,10 +89185,17 @@
89157 explainSetInteger(iSub2, pParse->iNextSelectId);
89158 rc = sqlite3Select(pParse, p, &dest);
89159 testcase( rc!=SQLITE_OK );
89160 pDelete = p->pPrior;
89161 p->pPrior = pPrior;
 
 
 
 
 
 
 
89162 if( addr ){
89163 sqlite3VdbeJumpHere(v, addr);
89164 }
89165 break;
89166 }
@@ -89229,10 +89264,11 @@
89229 ** Be sure to delete p->pOrderBy, therefore, to avoid a memory leak. */
89230 sqlite3ExprListDelete(db, p->pOrderBy);
89231 pDelete = p->pPrior;
89232 p->pPrior = pPrior;
89233 p->pOrderBy = 0;
 
89234 sqlite3ExprDelete(db, p->pLimit);
89235 p->pLimit = pLimit;
89236 p->pOffset = pOffset;
89237 p->iLimit = 0;
89238 p->iOffset = 0;
@@ -89308,10 +89344,11 @@
89308 explainSetInteger(iSub2, pParse->iNextSelectId);
89309 rc = sqlite3Select(pParse, p, &intersectdest);
89310 testcase( rc!=SQLITE_OK );
89311 pDelete = p->pPrior;
89312 p->pPrior = pPrior;
 
89313 sqlite3ExprDelete(db, p->pLimit);
89314 p->pLimit = pLimit;
89315 p->pOffset = pOffset;
89316
89317 /* Generate code to take the intersection of the two temporary
@@ -89894,17 +89931,19 @@
89894 }else{
89895 addrEofA = sqlite3VdbeAddOp2(v, OP_If, regEofB, labelEnd);
89896 sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB);
89897 sqlite3VdbeAddOp1(v, OP_Yield, regAddrB);
89898 sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEofA);
 
89899 }
89900
89901 /* Generate a subroutine to run when the results from select B
89902 ** are exhausted and only data in select A remains.
89903 */
89904 if( op==TK_INTERSECT ){
89905 addrEofB = addrEofA;
 
89906 }else{
89907 VdbeNoopComment((v, "eof-B subroutine"));
89908 addrEofB = sqlite3VdbeAddOp2(v, OP_If, regEofA, labelEnd);
89909 sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA);
89910 sqlite3VdbeAddOp1(v, OP_Yield, regAddrA);
@@ -91295,10 +91334,11 @@
91295 sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
91296 assert( pItem->isPopulated==0 );
91297 explainSetInteger(pItem->iSelectId, pParse->iNextSelectId);
91298 sqlite3Select(pParse, pSub, &dest);
91299 pItem->isPopulated = 1;
 
91300 }
91301 if( /*pParse->nErr ||*/ db->mallocFailed ){
91302 goto select_end;
91303 }
91304 pParse->nHeight -= sqlite3SelectExprHeight(p);
@@ -91387,10 +91427,11 @@
91387 }
91388
91389 /* Set the limiter.
91390 */
91391 iEnd = sqlite3VdbeMakeLabel(v);
 
91392 computeLimitRegisters(pParse, p, iEnd);
91393
91394 /* Open a virtual index to use for the distinct set.
91395 */
91396 if( p->selFlags & SF_Distinct ){
@@ -91410,10 +91451,11 @@
91410 /* This case is for non-aggregate queries
91411 ** Begin the database scan
91412 */
91413 pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pOrderBy, 0);
91414 if( pWInfo==0 ) goto select_end;
 
91415
91416 /* If sorting index that was created by a prior OP_OpenEphemeral
91417 ** instruction ended up not being needed, then change the OP_OpenEphemeral
91418 ** into an OP_Noop.
91419 */
@@ -91454,10 +91496,13 @@
91454 pItem->iAlias = 0;
91455 }
91456 for(k=pGroupBy->nExpr, pItem=pGroupBy->a; k>0; k--, pItem++){
91457 pItem->iAlias = 0;
91458 }
 
 
 
91459 }
91460
91461
91462 /* Create a label to jump to when we want to abort the query */
91463 addrEnd = sqlite3VdbeMakeLabel(v);
@@ -95437,10 +95482,11 @@
95437 #define WHERE_INDEXED 0x000f0000 /* Anything that uses an index */
95438 #define WHERE_NOT_FULLSCAN 0x100f3000 /* Does not do a full table scan */
95439 #define WHERE_IN_ABLE 0x000f1000 /* Able to support an IN operator */
95440 #define WHERE_TOP_LIMIT 0x00100000 /* x<EXPR or x<=EXPR constraint */
95441 #define WHERE_BTM_LIMIT 0x00200000 /* x>EXPR or x>=EXPR constraint */
 
95442 #define WHERE_IDX_ONLY 0x00800000 /* Use index only - omit table */
95443 #define WHERE_ORDERBY 0x01000000 /* Output will appear in correct order */
95444 #define WHERE_REVERSE 0x02000000 /* Scan in reverse order */
95445 #define WHERE_UNIQUE 0x04000000 /* Selects no more than one row */
95446 #define WHERE_VIRTUALTABLE 0x08000000 /* Use virtual-table processing */
@@ -98425,11 +98471,13 @@
98425 int iId = pParse->iSelectId; /* Select id (left-most output column) */
98426 int isSearch; /* True for a SEARCH. False for SCAN. */
98427
98428 if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_ONETABLE_ONLY) ) return;
98429
98430 isSearch = (pLevel->plan.nEq>0 || flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT));
 
 
98431
98432 zMsg = sqlite3MPrintf(db, "%s", isSearch?"SEARCH":"SCAN");
98433 if( pItem->pSelect ){
98434 zMsg = sqlite3MAppendf(db, zMsg, "%s SUBQUERY %d", zMsg,pItem->iSelectId);
98435 }else{
@@ -98452,11 +98500,11 @@
98452 }else if( flags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){
98453 zMsg = sqlite3MAppendf(db, zMsg, "%s USING INTEGER PRIMARY KEY", zMsg);
98454
98455 if( flags&WHERE_ROWID_EQ ){
98456 zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid=?)", zMsg);
98457 }else if( flags&WHERE_BTM_LIMIT && flags&WHERE_TOP_LIMIT ){
98458 zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>? AND rowid<?)", zMsg);
98459 }else if( flags&WHERE_BTM_LIMIT ){
98460 zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>?)", zMsg);
98461 }else if( flags&WHERE_TOP_LIMIT ){
98462 zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid<?)", zMsg);
@@ -98468,10 +98516,11 @@
98468 zMsg = sqlite3MAppendf(db, zMsg, "%s VIRTUAL TABLE INDEX %d:%s", zMsg,
98469 pVtabIdx->idxNum, pVtabIdx->idxStr);
98470 }
98471 #endif
98472 if( wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX) ){
 
98473 nRow = 1;
98474 }else{
98475 nRow = (sqlite3_int64)pLevel->plan.nRow;
98476 }
98477 zMsg = sqlite3MAppendf(db, zMsg, "%s (~%lld rows)", zMsg, nRow);
@@ -98888,11 +98937,11 @@
98888 ** If it is, jump to the next iteration of the loop.
98889 */
98890 r1 = sqlite3GetTempReg(pParse);
98891 testcase( pLevel->plan.wsFlags & WHERE_BTM_LIMIT );
98892 testcase( pLevel->plan.wsFlags & WHERE_TOP_LIMIT );
98893 if( pLevel->plan.wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT) ){
98894 sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, nEq, r1);
98895 sqlite3VdbeAddOp2(v, OP_IsNull, r1, addrCont);
98896 }
98897 sqlite3ReleaseTempReg(pParse, r1);
98898
@@ -99618,17 +99667,19 @@
99618 /* Open all tables in the pTabList and any indices selected for
99619 ** searching those tables.
99620 */
99621 sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */
99622 notReady = ~(Bitmask)0;
 
99623 for(i=0, pLevel=pWInfo->a; i<nTabList; i++, pLevel++){
99624 Table *pTab; /* Table to open */
99625 int iDb; /* Index of database containing table/index */
99626
99627 pTabItem = &pTabList->a[pLevel->iFrom];
99628 pTab = pTabItem->pTab;
99629 pLevel->iTabCur = pTabItem->iCursor;
 
99630 iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
99631 if( (pTab->tabFlags & TF_Ephemeral)!=0 || pTab->pSelect ){
99632 /* Do nothing */
99633 }else
99634 #ifndef SQLITE_OMIT_VIRTUALTABLE
99635
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -650,11 +650,11 @@
650 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
651 ** [sqlite_version()] and [sqlite_source_id()].
652 */
653 #define SQLITE_VERSION "3.7.4"
654 #define SQLITE_VERSION_NUMBER 3007004
655 #define SQLITE_SOURCE_ID "2010-11-16 23:10:26 fd5b2f23dd5111d2f0934dd828bae36b755024c1"
656
657 /*
658 ** CAPI3REF: Run-Time Library Version Numbers
659 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
660 **
@@ -3174,10 +3174,25 @@
3174 ** SQL text used to create a [prepared statement] if that statement was
3175 ** compiled using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()].
3176 */
3177 SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
3178
3179 /*
3180 ** CAPI3REF: Determine If An SQL Statement Writes The Database
3181 **
3182 ** ^The sqlite3_stmt_readonly(X) interface returns true (non-zero) if
3183 ** the [prepared statement] X is guaranteed to leave the database file
3184 ** unmodified. ^If the sqlite3_stmt_readonly(X) interface returns false (zero)
3185 ** then evaluating the statement might change the database file, but this
3186 ** is not guaranteed as the write operation might be conditional and the
3187 ** condition might not be met. ^If X is a NULL pointer then
3188 ** sqlite3_stmt_readonly(X) returns true. If X is a non-NULL pointer but
3189 ** is not a pointer to a valid, unfinalized prepared statement, then the
3190 ** behavior is undefined and probably harmful.
3191 */
3192 SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
3193
3194 /*
3195 ** CAPI3REF: Dynamically Typed Value Object
3196 ** KEYWORDS: {protected sqlite3_value} {unprotected sqlite3_value}
3197 **
3198 ** SQLite uses the sqlite3_value object to represent all values
@@ -10050,10 +10065,11 @@
10065 int iContinue; /* Jump here to continue with next record */
10066 int iBreak; /* Jump here to break out of the loop */
10067 int nLevel; /* Number of nested loop */
10068 struct WhereClause *pWC; /* Decomposition of the WHERE clause */
10069 double savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */
10070 double nRowOut; /* Estimated number of output rows */
10071 WhereLevel a[1]; /* Information about each nest loop in WHERE */
10072 };
10073
10074 /*
10075 ** A NameContext defines a context in which to resolve table and column
@@ -10125,10 +10141,11 @@
10141 Select *pRightmost; /* Right-most select in a compound select statement */
10142 Expr *pLimit; /* LIMIT expression. NULL means not used. */
10143 Expr *pOffset; /* OFFSET expression. NULL means not used. */
10144 int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */
10145 int addrOpenEphm[3]; /* OP_OpenEphem opcodes related to this select */
10146 double nSelectRow; /* Estimated number of result rows */
10147 };
10148
10149 /*
10150 ** Allowed values for Select.selFlags. The "SF" prefix stands for
10151 ** "Select Flag".
@@ -59476,10 +59493,18 @@
59493 ** the statement in the first place.
59494 */
59495 SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt *pStmt){
59496 return pStmt ? ((Vdbe*)pStmt)->db : 0;
59497 }
59498
59499 /*
59500 ** Return true if the prepared statement is guaranteed to not modify the
59501 ** database.
59502 */
59503 SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt){
59504 return pStmt ? ((Vdbe*)pStmt)->readOnly : 1;
59505 }
59506
59507 /*
59508 ** Return a pointer to the next prepared statement after pStmt associated
59509 ** with database connection pDb. If pStmt is NULL, return the first
59510 ** prepared statement for the database connection. Return NULL if there
@@ -88974,10 +88999,12 @@
88999 if( sqlite3ExprIsInteger(p->pLimit, &n) ){
89000 sqlite3VdbeAddOp2(v, OP_Integer, n, iLimit);
89001 VdbeComment((v, "LIMIT counter"));
89002 if( n==0 ){
89003 sqlite3VdbeAddOp2(v, OP_Goto, 0, iBreak);
89004 }else{
89005 if( p->nSelectRow > (double)n ) p->nSelectRow = (double)n;
89006 }
89007 }else{
89008 sqlite3ExprCode(pParse, p->pLimit, iLimit);
89009 sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit);
89010 VdbeComment((v, "LIMIT counter"));
@@ -89135,10 +89162,11 @@
89162 /* Generate code for the left and right SELECT statements.
89163 */
89164 switch( p->op ){
89165 case TK_ALL: {
89166 int addr = 0;
89167 int nLimit;
89168 assert( !pPrior->pLimit );
89169 pPrior->pLimit = p->pLimit;
89170 pPrior->pOffset = p->pOffset;
89171 explainSetInteger(iSub1, pParse->iNextSelectId);
89172 rc = sqlite3Select(pParse, pPrior, &dest);
@@ -89157,10 +89185,17 @@
89185 explainSetInteger(iSub2, pParse->iNextSelectId);
89186 rc = sqlite3Select(pParse, p, &dest);
89187 testcase( rc!=SQLITE_OK );
89188 pDelete = p->pPrior;
89189 p->pPrior = pPrior;
89190 p->nSelectRow += pPrior->nSelectRow;
89191 if( pPrior->pLimit
89192 && sqlite3ExprIsInteger(pPrior->pLimit, &nLimit)
89193 && p->nSelectRow > (double)nLimit
89194 ){
89195 p->nSelectRow = (double)nLimit;
89196 }
89197 if( addr ){
89198 sqlite3VdbeJumpHere(v, addr);
89199 }
89200 break;
89201 }
@@ -89229,10 +89264,11 @@
89264 ** Be sure to delete p->pOrderBy, therefore, to avoid a memory leak. */
89265 sqlite3ExprListDelete(db, p->pOrderBy);
89266 pDelete = p->pPrior;
89267 p->pPrior = pPrior;
89268 p->pOrderBy = 0;
89269 if( p->op==TK_UNION ) p->nSelectRow += pPrior->nSelectRow;
89270 sqlite3ExprDelete(db, p->pLimit);
89271 p->pLimit = pLimit;
89272 p->pOffset = pOffset;
89273 p->iLimit = 0;
89274 p->iOffset = 0;
@@ -89308,10 +89344,11 @@
89344 explainSetInteger(iSub2, pParse->iNextSelectId);
89345 rc = sqlite3Select(pParse, p, &intersectdest);
89346 testcase( rc!=SQLITE_OK );
89347 pDelete = p->pPrior;
89348 p->pPrior = pPrior;
89349 if( p->nSelectRow>pPrior->nSelectRow ) p->nSelectRow = pPrior->nSelectRow;
89350 sqlite3ExprDelete(db, p->pLimit);
89351 p->pLimit = pLimit;
89352 p->pOffset = pOffset;
89353
89354 /* Generate code to take the intersection of the two temporary
@@ -89894,17 +89931,19 @@
89931 }else{
89932 addrEofA = sqlite3VdbeAddOp2(v, OP_If, regEofB, labelEnd);
89933 sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB);
89934 sqlite3VdbeAddOp1(v, OP_Yield, regAddrB);
89935 sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEofA);
89936 p->nSelectRow += pPrior->nSelectRow;
89937 }
89938
89939 /* Generate a subroutine to run when the results from select B
89940 ** are exhausted and only data in select A remains.
89941 */
89942 if( op==TK_INTERSECT ){
89943 addrEofB = addrEofA;
89944 if( p->nSelectRow > pPrior->nSelectRow ) p->nSelectRow = pPrior->nSelectRow;
89945 }else{
89946 VdbeNoopComment((v, "eof-B subroutine"));
89947 addrEofB = sqlite3VdbeAddOp2(v, OP_If, regEofA, labelEnd);
89948 sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA);
89949 sqlite3VdbeAddOp1(v, OP_Yield, regAddrA);
@@ -91295,10 +91334,11 @@
91334 sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
91335 assert( pItem->isPopulated==0 );
91336 explainSetInteger(pItem->iSelectId, pParse->iNextSelectId);
91337 sqlite3Select(pParse, pSub, &dest);
91338 pItem->isPopulated = 1;
91339 pItem->pTab->nRowEst = (unsigned)pSub->nSelectRow;
91340 }
91341 if( /*pParse->nErr ||*/ db->mallocFailed ){
91342 goto select_end;
91343 }
91344 pParse->nHeight -= sqlite3SelectExprHeight(p);
@@ -91387,10 +91427,11 @@
91427 }
91428
91429 /* Set the limiter.
91430 */
91431 iEnd = sqlite3VdbeMakeLabel(v);
91432 p->nSelectRow = (double)LARGEST_INT64;
91433 computeLimitRegisters(pParse, p, iEnd);
91434
91435 /* Open a virtual index to use for the distinct set.
91436 */
91437 if( p->selFlags & SF_Distinct ){
@@ -91410,10 +91451,11 @@
91451 /* This case is for non-aggregate queries
91452 ** Begin the database scan
91453 */
91454 pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pOrderBy, 0);
91455 if( pWInfo==0 ) goto select_end;
91456 if( pWInfo->nRowOut < p->nSelectRow ) p->nSelectRow = pWInfo->nRowOut;
91457
91458 /* If sorting index that was created by a prior OP_OpenEphemeral
91459 ** instruction ended up not being needed, then change the OP_OpenEphemeral
91460 ** into an OP_Noop.
91461 */
@@ -91454,10 +91496,13 @@
91496 pItem->iAlias = 0;
91497 }
91498 for(k=pGroupBy->nExpr, pItem=pGroupBy->a; k>0; k--, pItem++){
91499 pItem->iAlias = 0;
91500 }
91501 if( p->nSelectRow>(double)100 ) p->nSelectRow = (double)100;
91502 }else{
91503 p->nSelectRow = (double)1;
91504 }
91505
91506
91507 /* Create a label to jump to when we want to abort the query */
91508 addrEnd = sqlite3VdbeMakeLabel(v);
@@ -95437,10 +95482,11 @@
95482 #define WHERE_INDEXED 0x000f0000 /* Anything that uses an index */
95483 #define WHERE_NOT_FULLSCAN 0x100f3000 /* Does not do a full table scan */
95484 #define WHERE_IN_ABLE 0x000f1000 /* Able to support an IN operator */
95485 #define WHERE_TOP_LIMIT 0x00100000 /* x<EXPR or x<=EXPR constraint */
95486 #define WHERE_BTM_LIMIT 0x00200000 /* x>EXPR or x>=EXPR constraint */
95487 #define WHERE_BOTH_LIMIT 0x00300000 /* Both x>EXPR and x<EXPR */
95488 #define WHERE_IDX_ONLY 0x00800000 /* Use index only - omit table */
95489 #define WHERE_ORDERBY 0x01000000 /* Output will appear in correct order */
95490 #define WHERE_REVERSE 0x02000000 /* Scan in reverse order */
95491 #define WHERE_UNIQUE 0x04000000 /* Selects no more than one row */
95492 #define WHERE_VIRTUALTABLE 0x08000000 /* Use virtual-table processing */
@@ -98425,11 +98471,13 @@
98471 int iId = pParse->iSelectId; /* Select id (left-most output column) */
98472 int isSearch; /* True for a SEARCH. False for SCAN. */
98473
98474 if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_ONETABLE_ONLY) ) return;
98475
98476 isSearch = (pLevel->plan.nEq>0)
98477 || (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0
98478 || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX));
98479
98480 zMsg = sqlite3MPrintf(db, "%s", isSearch?"SEARCH":"SCAN");
98481 if( pItem->pSelect ){
98482 zMsg = sqlite3MAppendf(db, zMsg, "%s SUBQUERY %d", zMsg,pItem->iSelectId);
98483 }else{
@@ -98452,11 +98500,11 @@
98500 }else if( flags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){
98501 zMsg = sqlite3MAppendf(db, zMsg, "%s USING INTEGER PRIMARY KEY", zMsg);
98502
98503 if( flags&WHERE_ROWID_EQ ){
98504 zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid=?)", zMsg);
98505 }else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){
98506 zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>? AND rowid<?)", zMsg);
98507 }else if( flags&WHERE_BTM_LIMIT ){
98508 zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>?)", zMsg);
98509 }else if( flags&WHERE_TOP_LIMIT ){
98510 zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid<?)", zMsg);
@@ -98468,10 +98516,11 @@
98516 zMsg = sqlite3MAppendf(db, zMsg, "%s VIRTUAL TABLE INDEX %d:%s", zMsg,
98517 pVtabIdx->idxNum, pVtabIdx->idxStr);
98518 }
98519 #endif
98520 if( wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX) ){
98521 testcase( wctrlFlags & WHERE_ORDERBY_MIN );
98522 nRow = 1;
98523 }else{
98524 nRow = (sqlite3_int64)pLevel->plan.nRow;
98525 }
98526 zMsg = sqlite3MAppendf(db, zMsg, "%s (~%lld rows)", zMsg, nRow);
@@ -98888,11 +98937,11 @@
98937 ** If it is, jump to the next iteration of the loop.
98938 */
98939 r1 = sqlite3GetTempReg(pParse);
98940 testcase( pLevel->plan.wsFlags & WHERE_BTM_LIMIT );
98941 testcase( pLevel->plan.wsFlags & WHERE_TOP_LIMIT );
98942 if( (pLevel->plan.wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0 ){
98943 sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, nEq, r1);
98944 sqlite3VdbeAddOp2(v, OP_IsNull, r1, addrCont);
98945 }
98946 sqlite3ReleaseTempReg(pParse, r1);
98947
@@ -99618,17 +99667,19 @@
99667 /* Open all tables in the pTabList and any indices selected for
99668 ** searching those tables.
99669 */
99670 sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */
99671 notReady = ~(Bitmask)0;
99672 pWInfo->nRowOut = (double)1;
99673 for(i=0, pLevel=pWInfo->a; i<nTabList; i++, pLevel++){
99674 Table *pTab; /* Table to open */
99675 int iDb; /* Index of database containing table/index */
99676
99677 pTabItem = &pTabList->a[pLevel->iFrom];
99678 pTab = pTabItem->pTab;
99679 pLevel->iTabCur = pTabItem->iCursor;
99680 pWInfo->nRowOut *= pLevel->plan.nRow;
99681 iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
99682 if( (pTab->tabFlags & TF_Ephemeral)!=0 || pTab->pSelect ){
99683 /* Do nothing */
99684 }else
99685 #ifndef SQLITE_OMIT_VIRTUALTABLE
99686
+16 -1
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -107,11 +107,11 @@
107107
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
108108
** [sqlite_version()] and [sqlite_source_id()].
109109
*/
110110
#define SQLITE_VERSION "3.7.4"
111111
#define SQLITE_VERSION_NUMBER 3007004
112
-#define SQLITE_SOURCE_ID "2010-11-15 16:29:31 136c2ac24ee1663bc0904bce1a619ecef3d11c1c"
112
+#define SQLITE_SOURCE_ID "2010-11-16 23:10:26 fd5b2f23dd5111d2f0934dd828bae36b755024c1"
113113
114114
/*
115115
** CAPI3REF: Run-Time Library Version Numbers
116116
** KEYWORDS: sqlite3_version, sqlite3_sourceid
117117
**
@@ -2631,10 +2631,25 @@
26312631
** SQL text used to create a [prepared statement] if that statement was
26322632
** compiled using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()].
26332633
*/
26342634
SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
26352635
2636
+/*
2637
+** CAPI3REF: Determine If An SQL Statement Writes The Database
2638
+**
2639
+** ^The sqlite3_stmt_readonly(X) interface returns true (non-zero) if
2640
+** the [prepared statement] X is guaranteed to leave the database file
2641
+** unmodified. ^If the sqlite3_stmt_readonly(X) interface returns false (zero)
2642
+** then evaluating the statement might change the database file, but this
2643
+** is not guaranteed as the write operation might be conditional and the
2644
+** condition might not be met. ^If X is a NULL pointer then
2645
+** sqlite3_stmt_readonly(X) returns true. If X is a non-NULL pointer but
2646
+** is not a pointer to a valid, unfinalized prepared statement, then the
2647
+** behavior is undefined and probably harmful.
2648
+*/
2649
+SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
2650
+
26362651
/*
26372652
** CAPI3REF: Dynamically Typed Value Object
26382653
** KEYWORDS: {protected sqlite3_value} {unprotected sqlite3_value}
26392654
**
26402655
** SQLite uses the sqlite3_value object to represent all values
26412656
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -107,11 +107,11 @@
107 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
108 ** [sqlite_version()] and [sqlite_source_id()].
109 */
110 #define SQLITE_VERSION "3.7.4"
111 #define SQLITE_VERSION_NUMBER 3007004
112 #define SQLITE_SOURCE_ID "2010-11-15 16:29:31 136c2ac24ee1663bc0904bce1a619ecef3d11c1c"
113
114 /*
115 ** CAPI3REF: Run-Time Library Version Numbers
116 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
117 **
@@ -2631,10 +2631,25 @@
2631 ** SQL text used to create a [prepared statement] if that statement was
2632 ** compiled using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()].
2633 */
2634 SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
2635
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2636 /*
2637 ** CAPI3REF: Dynamically Typed Value Object
2638 ** KEYWORDS: {protected sqlite3_value} {unprotected sqlite3_value}
2639 **
2640 ** SQLite uses the sqlite3_value object to represent all values
2641
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -107,11 +107,11 @@
107 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
108 ** [sqlite_version()] and [sqlite_source_id()].
109 */
110 #define SQLITE_VERSION "3.7.4"
111 #define SQLITE_VERSION_NUMBER 3007004
112 #define SQLITE_SOURCE_ID "2010-11-16 23:10:26 fd5b2f23dd5111d2f0934dd828bae36b755024c1"
113
114 /*
115 ** CAPI3REF: Run-Time Library Version Numbers
116 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
117 **
@@ -2631,10 +2631,25 @@
2631 ** SQL text used to create a [prepared statement] if that statement was
2632 ** compiled using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()].
2633 */
2634 SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
2635
2636 /*
2637 ** CAPI3REF: Determine If An SQL Statement Writes The Database
2638 **
2639 ** ^The sqlite3_stmt_readonly(X) interface returns true (non-zero) if
2640 ** the [prepared statement] X is guaranteed to leave the database file
2641 ** unmodified. ^If the sqlite3_stmt_readonly(X) interface returns false (zero)
2642 ** then evaluating the statement might change the database file, but this
2643 ** is not guaranteed as the write operation might be conditional and the
2644 ** condition might not be met. ^If X is a NULL pointer then
2645 ** sqlite3_stmt_readonly(X) returns true. If X is a non-NULL pointer but
2646 ** is not a pointer to a valid, unfinalized prepared statement, then the
2647 ** behavior is undefined and probably harmful.
2648 */
2649 SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
2650
2651 /*
2652 ** CAPI3REF: Dynamically Typed Value Object
2653 ** KEYWORDS: {protected sqlite3_value} {unprotected sqlite3_value}
2654 **
2655 ** SQLite uses the sqlite3_value object to represent all values
2656

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button