Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 13977eda16 | |||
| fda3dd5e67 | |||
| 27de99df79 | |||
| 3041bf593b | |||
| cc6408ffa3 | |||
| 8e8c2f1498 |
@@ -1,5 +1,5 @@
|
||||
C Recompute\sthe\sset\sof\scolumns\sused\sfor\seach\stable\swhen\sthe\stable\sis\ninvolved\sin\squery\sflattening.
|
||||
D 2020-03-21T00:05:53.338
|
||||
C Merge\supdates\sfrom\strunk.
|
||||
D 2020-03-21T14:05:56.197
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@@ -529,14 +529,14 @@ F src/pragma.h 9473160d220416456b40f27323bb4b316d4e4e08ffbf8bf88c5f7045d49c38e5
|
||||
F src/prepare.c 8d4d6c8aa6afefc48027c54b41cdf134b4d6bc2fc4badbe483ad7fd9e1728a28
|
||||
F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4
|
||||
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
|
||||
F src/resolve.c 38e3a5636f5bdc92e3683e4cafbba6418c0aa15e0d89ca5b28bd0b621dbb80bf
|
||||
F src/resolve.c ad43b2ed4bea58abca3092993382aa2ac91b89144d2066faae4ac924b39396f9
|
||||
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
|
||||
F src/select.c cb7588bfe9e1a900801e5ca345296b32b85ded0d57b2f277a9962294eb4c7aa2
|
||||
F src/select.c ba6d286edbf0dcb0c9b90ad6b8020d7f2e0b21fb2f19d33d5972db831756b2c1
|
||||
F src/shell.c.in f76590931c0cbbfef347f44f81ade6b335f80c46bc6e59b8b6114383a8df30e0
|
||||
F src/sqlite.h.in 802957feeb249ede54f8dfe99b72aa19e70a0b7737969c46e625dc2f9f2d42b0
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h 9c5269260409eb3275324ccace6a13a96f4ad330c708415f70ca6097901ff4ee
|
||||
F src/sqliteInt.h 3ccd2aedc57f61009285c4fa7ca1d75b380a48b5168f9605c10c86a7be62156c
|
||||
F src/sqliteInt.h 84e11419a13b8d20b9dd91eb5c5547cdb905f0c0b658f70669dae07843c35356
|
||||
F src/sqliteLimit.h 95cb8479ca459496d9c1c6a9f76b38aee12203a56ce1092fe13e50ae2454c032
|
||||
F src/status.c 9ff2210207c6c3b4d9631a8241a7d45ab1b26a0e9c84cb07a9b5ce2de9a3b278
|
||||
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
|
||||
@@ -603,11 +603,11 @@ F src/upsert.c 2920de71b20f04fe25eb00b655d086f0ba60ea133c59d7fa3325c49838818e78
|
||||
F src/utf.c 95fb6e03a5ca679045c5adccd05380f0addccabef5911abddcb06af069500ab7
|
||||
F src/util.c a285c1e026907b69fa2592bd05047a565a1d8a1aef2b73c924b6a8ffe772871a
|
||||
F src/vacuum.c 813b510ba887fee6492bcb11f2bf77d7eb58b232b83649136372e0a2fc17f4b9
|
||||
F src/vdbe.c c1c123c6248fa88940b932a00bcc75056921b6d046d45a82566cb97415d2299c
|
||||
F src/vdbe.c b7b9ec1d604a12f4cafedf796027a297bc306f0d3afb340948898256cb4473b9
|
||||
F src/vdbe.h 51282fbe819ee0e8eeeaab176240860d334c20a12b14f3b363e7f1a4e05d60b9
|
||||
F src/vdbeInt.h a17146053a1aa438474012998fe07e314f3df274a61491ad838ad85d848ac051
|
||||
F src/vdbeapi.c 1252d80c548711e47a6d84dae88ed4e95d3fbb4e7bd0eaa1347299af7efddf02
|
||||
F src/vdbeaux.c e8baf66528e36474f4071e3171b660a454606eb5b54459a729982c939ad7a5bb
|
||||
F src/vdbeInt.h 37a1cb667c80b4cbceb80a7b3947e3b15892cc84bff0cde788ec1781cfab5bde
|
||||
F src/vdbeapi.c d7540ad79510d3baa30a09db93f305e3d12f069dbd7bd49ebed51b14a3024681
|
||||
F src/vdbeaux.c 99703bb60f4f7f7700f801510cb9732e50abfcf5ba65958121c017dcd595d78e
|
||||
F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b1
|
||||
F src/vdbemem.c 39b942ecca179f4f30a32b54579a85d74ccaefa5af2a0ad2700abe5ef0768b22
|
||||
F src/vdbesort.c 2be76d26998ce2b3324cdcc9f6443728e54b6c7677c553ad909c7d7cfab587df
|
||||
@@ -619,7 +619,7 @@ F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a
|
||||
F src/walker.c 7c429c694abd12413a5c17aec9f47cfe9eba6807e6b0a32df883e8e3a14835ed
|
||||
F src/where.c 9546c82056e8cdb27291f98cf1adca5d271240b399bb97b32f77fc2bea6146c9
|
||||
F src/whereInt.h 6b874aa15f94e43a2cec1080be64d955b04deeafeac90ffb5d6975c0d511be3c
|
||||
F src/wherecode.c 7b939de85d65cc4b4bfa197513136b9e0ae03167e3b82842ca5a0ba1055ba65d
|
||||
F src/wherecode.c 9e931b9d01c3c6ffa9b150f4535dacea0dd38360fa740b6f525cf27c17415ba0
|
||||
F src/whereexpr.c 264d58971eaf8256eb5b0917bcd7fc7a1f1109fdda183a8382308a1b18a2dce7
|
||||
F src/window.c ba1ffb78d73c5831433681aab7ee634230ee32f14ad508efa585044662141d5a
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
@@ -1860,7 +1860,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 86e98ddc19470410ccc6d2cf4ad56ef0bc5a23b7fbe6331b8cae374689f54529
|
||||
R ee0c3203501becfb0c0fab4a61c04589
|
||||
P 62aece66774587590bf7f88883cca1c1e76866e9df93bb1a17c4d9db894f06aa a9bb71ba708ba72255ba8d18c9856e38ddf53eae2d61c8435149354fb2b2459e
|
||||
R d7e5eecaf46db6237774ccab2e4497bb
|
||||
U drh
|
||||
Z 54b4f622fc0ff39925380e9e68d902eb
|
||||
Z d68a3bb48f89136a3b7a1e13c312fa0b
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
a9bb71ba708ba72255ba8d18c9856e38ddf53eae2d61c8435149354fb2b2459e
|
||||
2383aa2cb864734cccca6c98605df6026c732cbfb9a173660d2993dc63970f63
|
||||
+1
-1
@@ -934,7 +934,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
#endif
|
||||
else if( no_such_func && pParse->db->init.busy==0
|
||||
#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
|
||||
&& pParse->explain==0
|
||||
&& pParse->explain==SQLITE_STMTMODE_RUN
|
||||
#endif
|
||||
){
|
||||
sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId);
|
||||
|
||||
+1
-1
@@ -5546,7 +5546,7 @@ static void explainSimpleCount(
|
||||
Table *pTab, /* Table being queried */
|
||||
Index *pIdx /* Index used to optimize scan, or NULL */
|
||||
){
|
||||
if( pParse->explain==2 ){
|
||||
if( pParse->explain==SQLITE_STMTMODE_EQP ){
|
||||
int bCover = (pIdx!=0 && (HasRowid(pTab) || !IsPrimaryKeyIndex(pIdx)));
|
||||
sqlite3VdbeExplain(pParse, 0, "SCAN TABLE %s%s%s",
|
||||
pTab->zName,
|
||||
|
||||
@@ -3370,6 +3370,13 @@ struct Parse {
|
||||
#define PARSE_MODE_RENAME 2
|
||||
#define PARSE_MODE_UNMAP 3
|
||||
|
||||
/*
|
||||
** Allowed values for Vdbe.explain and Parse.explain
|
||||
*/
|
||||
#define SQLITE_STMTMODE_RUN 0
|
||||
#define SQLITE_STMTMODE_EXPLAIN 1
|
||||
#define SQLITE_STMTMODE_EQP 2
|
||||
|
||||
/*
|
||||
** Sizes and pointers of various parts of the Parse object.
|
||||
*/
|
||||
|
||||
+17
-5
@@ -539,9 +539,10 @@ void sqlite3VdbeMemPrettyPrint(Mem *pMem, StrAccum *pStr){
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
/*
|
||||
** Print the value of a register for tracing purposes:
|
||||
** Print the value of a Mem object on standard output.
|
||||
** Used for tracing and for interactive debugging only.
|
||||
*/
|
||||
static void memTracePrint(Mem *p){
|
||||
static void memPrint(Mem *p){
|
||||
if( p->flags & MEM_Undefined ){
|
||||
printf(" undefined");
|
||||
}else if( p->flags & MEM_Null ){
|
||||
@@ -567,9 +568,19 @@ static void memTracePrint(Mem *p){
|
||||
}
|
||||
if( p->flags & MEM_Subtype ) printf(" subtype=0x%02x", p->eSubtype);
|
||||
}
|
||||
/* Print N Mem objects beginning with p. Used for interactive debugging */
|
||||
void sqlite3MemPrint(Mem *p, int N){
|
||||
int i;
|
||||
for(i=0; i<N; i++){
|
||||
if( N>1 ) printf("%3d:", i);
|
||||
memPrint(p+i);
|
||||
printf("\n");
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
||||
static void registerTrace(int iReg, Mem *p){
|
||||
printf("R[%d] = ", iReg);
|
||||
memTracePrint(p);
|
||||
memPrint(p);
|
||||
if( p->pScopyFrom ){
|
||||
printf(" <== R[%d]", (int)(p->pScopyFrom - &p[-iReg]));
|
||||
}
|
||||
@@ -704,8 +715,8 @@ int sqlite3VdbeExec(
|
||||
assert( p->rc==SQLITE_OK || (p->rc&0xff)==SQLITE_BUSY );
|
||||
assert( p->bIsReader || p->readOnly!=0 );
|
||||
p->iCurrentTime = 0;
|
||||
assert( p->explain==0 );
|
||||
p->pResultSet = 0;
|
||||
assert( p->explain==SQLITE_STMTMODE_RUN );
|
||||
p->nRes = 0;
|
||||
db->busyHandler.nBusy = 0;
|
||||
if( db->u1.isInterrupted ) goto abort_due_to_interrupt;
|
||||
sqlite3VdbeIOTraceSql(p);
|
||||
@@ -1493,6 +1504,7 @@ case OP_ResultRow: {
|
||||
** a side effect.
|
||||
*/
|
||||
pMem = p->pResultSet = &aMem[pOp->p1];
|
||||
p->nRes = pOp->p2;
|
||||
for(i=0; i<pOp->p2; i++){
|
||||
assert( memIsValid(&pMem[i]) );
|
||||
Deephemeralize(&pMem[i]);
|
||||
|
||||
+24
-14
@@ -26,6 +26,11 @@
|
||||
# define SQLITE_MAX_SCHEMA_RETRY 50
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Maximum number of columns in any "EXPLAIN" output
|
||||
*/
|
||||
#define VDBE_EXPLAIN_COLS 9
|
||||
|
||||
/*
|
||||
** VDBE_DISPLAY_P4 is true or false depending on whether or not the
|
||||
** "explain" P4 display logic is enabled.
|
||||
@@ -337,11 +342,6 @@ struct sqlite3_context {
|
||||
sqlite3_value *argv[1]; /* Argument set */
|
||||
};
|
||||
|
||||
/* A bitfield type for use inside of structures. Always follow with :N where
|
||||
** N is the number of bits.
|
||||
*/
|
||||
typedef unsigned bft; /* Bit Field Type */
|
||||
|
||||
/* The ScanStatus object holds a single value for the
|
||||
** sqlite3_stmt_scanstatus() interface.
|
||||
*/
|
||||
@@ -414,21 +414,23 @@ struct Vdbe {
|
||||
int rcApp; /* errcode set by sqlite3_result_error_code() */
|
||||
u32 nWrite; /* Number of write operations that have occurred */
|
||||
#endif
|
||||
u16 nResColumn; /* Number of columns in one row of the result set */
|
||||
u16 nResColumn; /* Columns in one row of a normal result set */
|
||||
u16 nRes; /* Columns in the current actual result set */
|
||||
u8 errorAction; /* Recovery action to do in case of an error */
|
||||
u8 minWriteFileFormat; /* Minimum file format for writable database files */
|
||||
u8 prepFlags; /* SQLITE_PREPARE_* flags */
|
||||
bft expired:2; /* 1: recompile VM immediately 2: when convenient */
|
||||
bft explain:2; /* True if EXPLAIN present on SQL command */
|
||||
bft doingRerun:1; /* True if rerunning after an auto-reprepare */
|
||||
bft changeCntOn:1; /* True to update the change-counter */
|
||||
bft runOnlyOnce:1; /* Automatically expire on reset */
|
||||
bft usesStmtJournal:1; /* True if uses a statement journal */
|
||||
bft readOnly:1; /* True for statements that do not write */
|
||||
bft bIsReader:1; /* True for statements that read */
|
||||
u8 explain:2; /* True if EXPLAIN present on SQL command */
|
||||
u8 expired:2; /* 1: recompile VM immediately 2: when convenient */
|
||||
u8 doingRerun:1; /* True if rerunning after an auto-reprepare */
|
||||
u8 changeCntOn:1; /* True to update the change-counter */
|
||||
u8 runOnlyOnce:1; /* Automatically expire on reset */
|
||||
u8 usesStmtJournal:1; /* True if uses a statement journal */
|
||||
u8 readOnly:1; /* True for statements that do not write */
|
||||
u8 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[7]; /* Counters used by sqlite3_stmt_status() */
|
||||
u32 nColName; /* Number of slots allocated to aColName[] above */
|
||||
char *zSql; /* Text of the SQL statement that generated this */
|
||||
#ifdef SQLITE_ENABLE_NORMALIZE
|
||||
char *zNormSql; /* Normalization of the associated SQL statement */
|
||||
@@ -457,6 +459,13 @@ struct Vdbe {
|
||||
#define VDBE_MAGIC_RESET 0x48fa9f76 /* Reset and ready to run again */
|
||||
#define VDBE_MAGIC_DEAD 0x5606c3c8 /* The VDBE has been deallocated */
|
||||
|
||||
/*
|
||||
** Values for Vdbe.explain
|
||||
*/
|
||||
#define SQLITE_STMTMODE_RUN 0
|
||||
#define SQLITE_STMTMODE_EXPLAIN 1
|
||||
#define SQLITE_STMTMODE_EQP 2
|
||||
|
||||
/*
|
||||
** Structure used to store the context required by the
|
||||
** sqlite3_preupdate_*() API functions.
|
||||
@@ -497,6 +506,7 @@ int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*);
|
||||
int sqlite3VdbeIdxRowid(sqlite3*, BtCursor*, i64*);
|
||||
int sqlite3VdbeExec(Vdbe*);
|
||||
#ifndef SQLITE_OMIT_EXPLAIN
|
||||
Mem *sqlite3VdbeSetExplainColumnNames(Vdbe*);
|
||||
int sqlite3VdbeList(Vdbe*);
|
||||
#endif
|
||||
int sqlite3VdbeHalt(Vdbe*);
|
||||
|
||||
+13
-4
@@ -996,8 +996,16 @@ int sqlite3_aggregate_count(sqlite3_context *p){
|
||||
** Return the number of columns in the result set for the statement pStmt.
|
||||
*/
|
||||
int sqlite3_column_count(sqlite3_stmt *pStmt){
|
||||
static const u8 anColumn[] = {
|
||||
0, /* SQLITE_STMTMODE_RUN (Use pVm->nResColumn instead) */
|
||||
8, /* SQLITE_STMTMODE_EXPLAIN */
|
||||
4 /* SQLITE_STMTMODE_EQP */
|
||||
};
|
||||
Vdbe *pVm = (Vdbe *)pStmt;
|
||||
return pVm ? pVm->nResColumn : 0;
|
||||
if( pVm==0 ) return 0;
|
||||
assert( pVm->explain>=0 && pVm->explain<=2 );
|
||||
if( pVm->explain==0 ) return pVm->nResColumn;
|
||||
return (int)anColumn[pVm->explain];
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1006,8 +1014,8 @@ int sqlite3_column_count(sqlite3_stmt *pStmt){
|
||||
*/
|
||||
int sqlite3_data_count(sqlite3_stmt *pStmt){
|
||||
Vdbe *pVm = (Vdbe *)pStmt;
|
||||
if( pVm==0 || pVm->pResultSet==0 ) return 0;
|
||||
return pVm->nResColumn;
|
||||
if( pVm==0 || pVm->nRes==0 ) return 0;
|
||||
return sqlite3_column_count(pStmt);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1061,7 +1069,7 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){
|
||||
if( pVm==0 ) return (Mem*)columnNullValue();
|
||||
assert( pVm->db );
|
||||
sqlite3_mutex_enter(pVm->db->mutex);
|
||||
if( pVm->pResultSet!=0 && i<pVm->nResColumn && i>=0 ){
|
||||
if( i<pVm->nRes && i>=0 ){
|
||||
pOut = &pVm->pResultSet[i];
|
||||
}else{
|
||||
sqlite3Error(pVm->db, SQLITE_RANGE);
|
||||
@@ -1211,6 +1219,7 @@ static const void *columnName(
|
||||
N += useType*n;
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
assert( db->mallocFailed==0 );
|
||||
assert( N>=0 && N<p->nColName );
|
||||
#ifndef SQLITE_OMIT_UTF16
|
||||
if( useUtf16 ){
|
||||
ret = sqlite3_value_text16((sqlite3_value*)&p->aColName[N]);
|
||||
|
||||
+102
-83
@@ -1872,7 +1872,11 @@ static void initMemArray(Mem *p, int N, sqlite3 *db, u16 flags){
|
||||
}
|
||||
|
||||
/*
|
||||
** Release an array of N Mem elements
|
||||
** Release all content from an array of N Mem elements. All elements
|
||||
** are left in a state of "MEM_Undefined".
|
||||
**
|
||||
** This routine does not free the array itself. It just frees the
|
||||
** content held by the Mem elements in the array.
|
||||
*/
|
||||
static void releaseMemArray(Mem *p, int N){
|
||||
if( p && N ){
|
||||
@@ -1961,24 +1965,62 @@ void sqlite3VdbeFrameDelete(VdbeFrame *p){
|
||||
sqlite3DbFree(p->v->db, p);
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_EXPLAIN
|
||||
/*
|
||||
** There should are VDBE_EXPLAIN_COLS*2+1 extra registers on the end of the
|
||||
** Vdbe.aColName array for statements that are in one of the
|
||||
** "explain" modes.
|
||||
**
|
||||
** * VDBE_EXPLAIN_COLS registers for the column names
|
||||
** * 1 register to keep track of subprograms
|
||||
** * VDBE_EXPLAIN_COLS registers to hold row output
|
||||
**
|
||||
** This routine makes sure those extra register exist and returns
|
||||
** a pointer to the first of them. If the extra registers do
|
||||
** not exist, then the are allocated.
|
||||
**
|
||||
** NULL is returned if there is a memory allocation error.
|
||||
*/
|
||||
Mem *sqlite3VdbeSetExplainColumnNames(Vdbe *p){
|
||||
int n = p->nResColumn*COLNAME_N;
|
||||
if( p->nColName<=n ){
|
||||
static const char * const azColName[] = {
|
||||
"addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment",
|
||||
"id", "parent", "notused", "detail"
|
||||
};
|
||||
int iFirst, cnt, i;
|
||||
Mem *pNew = sqlite3DbRealloc(p->db, p->aColName,
|
||||
(n+VDBE_EXPLAIN_COLS*2+1)*sizeof(Mem));
|
||||
if( pNew==0 ){
|
||||
return 0;
|
||||
}
|
||||
p->aColName = pNew;
|
||||
p->nColName = n+VDBE_EXPLAIN_COLS*2+1;
|
||||
initMemArray(p->aColName+n, VDBE_EXPLAIN_COLS*2+1, p->db, MEM_Null);
|
||||
if( p->explain==SQLITE_STMTMODE_EXPLAIN ){
|
||||
iFirst = 0;
|
||||
cnt = 8;
|
||||
}else{
|
||||
iFirst = 8;
|
||||
cnt = 4;
|
||||
}
|
||||
assert( cnt<=VDBE_EXPLAIN_COLS );
|
||||
for(i=0; i<cnt; i++){
|
||||
sqlite3VdbeMemSetStr(pNew+n+i, azColName[i+iFirst], -1,
|
||||
SQLITE_UTF8, SQLITE_STATIC);
|
||||
}
|
||||
}
|
||||
return p->aColName + n;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SQLITE_OMIT_EXPLAIN
|
||||
/*
|
||||
** Give a listing of the program in the virtual machine.
|
||||
**
|
||||
** The interface is the same as sqlite3VdbeExec(). But instead of
|
||||
** running the code, it invokes the callback once for each instruction.
|
||||
** This feature is used to implement "EXPLAIN".
|
||||
**
|
||||
** When p->explain==1, each instruction is listed. When
|
||||
** p->explain==2, only OP_Explain instructions are listed and these
|
||||
** are shown in a different format. p->explain==2 is used to implement
|
||||
** EXPLAIN QUERY PLAN.
|
||||
** 2018-04-24: In p->explain==2 mode, the OP_Init opcodes of triggers
|
||||
** are also shown, so that the boundaries between the main program and
|
||||
** each trigger are clear.
|
||||
**
|
||||
** When p->explain==1, first the main program is listed, then each of
|
||||
** the trigger subprograms are listed one by one.
|
||||
** running the code, it returns rows based on the bytecode content,
|
||||
** rather than on actually running the bytecode.
|
||||
*/
|
||||
int sqlite3VdbeList(
|
||||
Vdbe *p /* The VDBE */
|
||||
@@ -1990,11 +2032,12 @@ int sqlite3VdbeList(
|
||||
sqlite3 *db = p->db; /* The database connection */
|
||||
int i; /* Loop counter */
|
||||
int rc = SQLITE_OK; /* Return code */
|
||||
Mem *pMem = &p->aMem[1]; /* First Mem of result set */
|
||||
int bListSubprogs = (p->explain==1 || (db->flags & SQLITE_TriggerEQP)!=0);
|
||||
Mem *pMem; /* First Mem of result set */
|
||||
int bListSubprogs; /* Also show subprograms */
|
||||
Op *pOp = 0;
|
||||
|
||||
assert( p->explain );
|
||||
assert( p->explain==SQLITE_STMTMODE_EXPLAIN
|
||||
|| p->explain==SQLITE_STMTMODE_EQP );
|
||||
assert( p->magic==VDBE_MAGIC_RUN );
|
||||
assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY || p->rc==SQLITE_NOMEM );
|
||||
|
||||
@@ -2002,8 +2045,13 @@ int sqlite3VdbeList(
|
||||
** the result, result columns may become dynamic if the user calls
|
||||
** sqlite3_column_text16(), causing a translation to UTF-16 encoding.
|
||||
*/
|
||||
releaseMemArray(pMem, 8);
|
||||
p->pResultSet = 0;
|
||||
pMem = sqlite3VdbeSetExplainColumnNames(p);
|
||||
if( pMem==0 ){
|
||||
p->rc = SQLITE_NOMEM;
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
pMem += VDBE_EXPLAIN_COLS;
|
||||
p->nRes = 0;
|
||||
|
||||
if( p->rc==SQLITE_NOMEM ){
|
||||
/* This happens if a malloc() inside a call to sqlite3_column_text() or
|
||||
@@ -2020,13 +2068,10 @@ int sqlite3VdbeList(
|
||||
** encountered, but p->pc will eventually catch up to nRow.
|
||||
*/
|
||||
nRow = p->nOp;
|
||||
bListSubprogs = p->explain!=SQLITE_STMTMODE_EQP
|
||||
|| (db->flags & SQLITE_TriggerEQP)!=0;
|
||||
if( bListSubprogs ){
|
||||
/* The first 8 memory cells are used for the result set. So we will
|
||||
** commandeer the 9th cell to use as storage for an array of pointers
|
||||
** to trigger subprograms. The VDBE is guaranteed to have at least 9
|
||||
** cells. */
|
||||
assert( p->nMem>9 );
|
||||
pSub = &p->aMem[9];
|
||||
pSub = pMem++;
|
||||
if( pSub->flags&MEM_Blob ){
|
||||
/* On the first call to sqlite3_step(), pSub will hold a NULL. It is
|
||||
** initialized to a BLOB by the P4_SUBPROGRAM processing logic below */
|
||||
@@ -2037,6 +2082,7 @@ int sqlite3VdbeList(
|
||||
nRow += apSub[i]->nOp;
|
||||
}
|
||||
}
|
||||
p->pResultSet = pMem;
|
||||
|
||||
while(1){ /* Loop exits via break */
|
||||
i = p->pc++;
|
||||
@@ -2065,7 +2111,7 @@ int sqlite3VdbeList(
|
||||
|
||||
/* When an OP_Program opcode is encounter (the only opcode that has
|
||||
** a P4_SUBPROGRAM argument), expand the size of the array of subprograms
|
||||
** kept in p->aMem[9].z to hold the new program - assuming this subprogram
|
||||
** to hold the new program - assuming this subprogram
|
||||
** has not already been seen.
|
||||
*/
|
||||
if( bListSubprogs && pOp->p4type==P4_SUBPROGRAM ){
|
||||
@@ -2082,14 +2128,18 @@ int sqlite3VdbeList(
|
||||
}
|
||||
apSub = (SubProgram **)pSub->z;
|
||||
apSub[nSub++] = pOp->p4.pProgram;
|
||||
pSub->flags |= MEM_Blob;
|
||||
MemSetTypeFlag(pSub, MEM_Blob);
|
||||
pSub->n = nSub*sizeof(SubProgram*);
|
||||
nRow += pOp->p4.pProgram->nOp;
|
||||
}
|
||||
}
|
||||
if( p->explain<2 ) break;
|
||||
if( pOp->opcode==OP_Explain ) break;
|
||||
if( pOp->opcode==OP_Init && p->pc>1 ) break;
|
||||
if( p->explain==SQLITE_STMTMODE_EXPLAIN ){
|
||||
break; /* Show every bytecode line for SQLITE_STMTMODE_EXPLAIN */
|
||||
}else{
|
||||
/* Only OP_Init and OP_Explain opcodes are significant for EQP */
|
||||
if( pOp->opcode==OP_Explain ) break;
|
||||
if( pOp->opcode==OP_Init && p->pc>1 ) break;
|
||||
}
|
||||
}
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
@@ -2099,30 +2149,14 @@ int sqlite3VdbeList(
|
||||
sqlite3VdbeError(p, sqlite3ErrStr(p->rc));
|
||||
}else{
|
||||
char *zP4;
|
||||
if( p->explain==1 ){
|
||||
pMem->flags = MEM_Int;
|
||||
pMem->u.i = i; /* Program counter */
|
||||
pMem++;
|
||||
|
||||
pMem->flags = MEM_Static|MEM_Str|MEM_Term;
|
||||
pMem->z = (char*)sqlite3OpcodeName(pOp->opcode); /* Opcode */
|
||||
assert( pMem->z!=0 );
|
||||
pMem->n = sqlite3Strlen30(pMem->z);
|
||||
pMem->enc = SQLITE_UTF8;
|
||||
pMem++;
|
||||
if( p->explain==SQLITE_STMTMODE_EXPLAIN ){
|
||||
sqlite3VdbeMemSetInt64(pMem++, i); /* Program counter */
|
||||
sqlite3VdbeMemSetStr(pMem++, (char*)sqlite3OpcodeName(pOp->opcode),
|
||||
-1, SQLITE_UTF8, SQLITE_STATIC);
|
||||
}
|
||||
|
||||
pMem->flags = MEM_Int;
|
||||
pMem->u.i = pOp->p1; /* P1 */
|
||||
pMem++;
|
||||
|
||||
pMem->flags = MEM_Int;
|
||||
pMem->u.i = pOp->p2; /* P2 */
|
||||
pMem++;
|
||||
|
||||
pMem->flags = MEM_Int;
|
||||
pMem->u.i = pOp->p3; /* P3 */
|
||||
pMem++;
|
||||
sqlite3VdbeMemSetInt64(pMem++, pOp->p1); /* P1 */
|
||||
sqlite3VdbeMemSetInt64(pMem++, pOp->p2); /* P2 */
|
||||
sqlite3VdbeMemSetInt64(pMem++, pOp->p3); /* P3 */
|
||||
|
||||
if( sqlite3VdbeMemClearAndResize(pMem, 100) ){ /* P4 */
|
||||
assert( p->db->mallocFailed );
|
||||
@@ -2140,7 +2174,7 @@ int sqlite3VdbeList(
|
||||
}
|
||||
pMem++;
|
||||
|
||||
if( p->explain==1 ){
|
||||
if( p->explain==SQLITE_STMTMODE_EXPLAIN ){
|
||||
if( sqlite3VdbeMemClearAndResize(pMem, 4) ){
|
||||
assert( p->db->mallocFailed );
|
||||
return SQLITE_ERROR;
|
||||
@@ -2162,10 +2196,11 @@ int sqlite3VdbeList(
|
||||
#else
|
||||
pMem->flags = MEM_Null; /* Comment */
|
||||
#endif
|
||||
pMem++;
|
||||
}
|
||||
|
||||
p->nResColumn = 8 - 4*(p->explain-1);
|
||||
p->pResultSet = &p->aMem[1];
|
||||
p->nRes = (int)(pMem - p->pResultSet);
|
||||
assert( p->nRes<=VDBE_EXPLAIN_COLS );
|
||||
p->rc = SQLITE_OK;
|
||||
rc = SQLITE_ROW;
|
||||
}
|
||||
@@ -2369,25 +2404,7 @@ void sqlite3VdbeMakeReady(
|
||||
resolveP2Values(p, &nArg);
|
||||
p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort);
|
||||
if( pParse->explain ){
|
||||
static const char * const azColName[] = {
|
||||
"addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment",
|
||||
"id", "parent", "notused", "detail"
|
||||
};
|
||||
int iFirst, mx, i;
|
||||
if( nMem<10 ) nMem = 10;
|
||||
if( pParse->explain==2 ){
|
||||
sqlite3VdbeSetNumCols(p, 4);
|
||||
iFirst = 8;
|
||||
mx = 12;
|
||||
}else{
|
||||
sqlite3VdbeSetNumCols(p, 8);
|
||||
iFirst = 0;
|
||||
mx = 8;
|
||||
}
|
||||
for(i=iFirst; i<mx; i++){
|
||||
sqlite3VdbeSetColName(p, i-iFirst, COLNAME_NAME,
|
||||
azColName[i], SQLITE_STATIC);
|
||||
}
|
||||
p->explain = pParse->explain;
|
||||
}
|
||||
p->expired = 0;
|
||||
|
||||
@@ -2425,7 +2442,6 @@ void sqlite3VdbeMakeReady(
|
||||
|
||||
p->pVList = pParse->pVList;
|
||||
pParse->pVList = 0;
|
||||
p->explain = pParse->explain;
|
||||
if( db->mallocFailed ){
|
||||
p->nVar = 0;
|
||||
p->nCursor = 0;
|
||||
@@ -2563,17 +2579,20 @@ static void closeAllCursors(Vdbe *p){
|
||||
** be called on an SQL statement before sqlite3_step().
|
||||
*/
|
||||
void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){
|
||||
int n;
|
||||
sqlite3 *db = p->db;
|
||||
u32 n;
|
||||
|
||||
if( p->nResColumn ){
|
||||
releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
|
||||
if( p->nColName ){
|
||||
releaseMemArray(p->aColName, p->nColName);
|
||||
sqlite3DbFree(db, p->aColName);
|
||||
}
|
||||
n = nResColumn*COLNAME_N;
|
||||
p->nResColumn = (u16)nResColumn;
|
||||
n = p->nColName = (u32)nResColumn*COLNAME_N;
|
||||
p->aColName = (Mem*)sqlite3DbMallocRawNN(db, sizeof(Mem)*n );
|
||||
if( p->aColName==0 ) return;
|
||||
if( p->aColName==0 ){
|
||||
p->nColName = 0;
|
||||
return;
|
||||
}
|
||||
initMemArray(p->aColName, n, db, MEM_Null);
|
||||
}
|
||||
|
||||
@@ -3307,7 +3326,7 @@ int sqlite3VdbeReset(Vdbe *p){
|
||||
#endif
|
||||
sqlite3DbFree(db, p->zErrMsg);
|
||||
p->zErrMsg = 0;
|
||||
p->pResultSet = 0;
|
||||
p->nRes = 0;
|
||||
#ifdef SQLITE_DEBUG
|
||||
p->nWrite = 0;
|
||||
#endif
|
||||
@@ -3412,7 +3431,7 @@ void sqlite3VdbeDeleteAuxData(sqlite3 *db, AuxData **pp, int iOp, int mask){
|
||||
void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
|
||||
SubProgram *pSub, *pNext;
|
||||
assert( p->db==0 || p->db==db );
|
||||
releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
|
||||
releaseMemArray(p->aColName, p->nColName);
|
||||
for(pSub=p->pProgram; pSub; pSub=pNext){
|
||||
pNext = pSub->pNext;
|
||||
vdbeFreeOpArray(db, pSub->aOp, pSub->nOp);
|
||||
|
||||
+1
-1
@@ -126,7 +126,7 @@ int sqlite3WhereExplainOneScan(
|
||||
){
|
||||
int ret = 0;
|
||||
#if !defined(SQLITE_DEBUG) && !defined(SQLITE_ENABLE_STMT_SCANSTATUS)
|
||||
if( sqlite3ParseToplevel(pParse)->explain==2 )
|
||||
if( sqlite3ParseToplevel(pParse)->explain==SQLITE_STMTMODE_EQP )
|
||||
#endif
|
||||
{
|
||||
struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom];
|
||||
|
||||
Reference in New Issue
Block a user