aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/os_win.c19
-rw-r--r--src/printf.c1
-rw-r--r--src/shell.c8
-rw-r--r--src/sqlite.h.in7
-rw-r--r--src/test1.c50
-rw-r--r--src/where.c6
-rw-r--r--src/whereInt.h1
7 files changed, 84 insertions, 8 deletions
diff --git a/src/os_win.c b/src/os_win.c
index 36fb9f690..5c246a858 100644
--- a/src/os_win.c
+++ b/src/os_win.c
@@ -2927,8 +2927,16 @@ static int winLock(sqlite3_file *id, int locktype){
** If you are using this code as a model for alternative VFSes, do not
** copy this retry logic. It is a hack intended for Windows only.
*/
+ lastErrno = osGetLastError();
OSTRACE(("LOCK-PENDING-FAIL file=%p, count=%d, result=%d\n",
pFile->h, cnt, res));
+ if( lastErrno==ERROR_INVALID_HANDLE ){
+ pFile->lastErrno = lastErrno;
+ rc = SQLITE_IOERR_LOCK;
+ OSTRACE(("LOCK-FAIL file=%p, count=%d, rc=%s\n",
+ pFile->h, cnt, sqlite3ErrName(rc)));
+ return rc;
+ }
if( cnt ) sqlite3_win32_sleep(1);
}
gotPendingLock = res;
@@ -3172,6 +3180,17 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){
OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
return SQLITE_OK;
}
+#ifdef SQLITE_TEST
+ case SQLITE_FCNTL_WIN32_SET_HANDLE: {
+ LPHANDLE phFile = (LPHANDLE)pArg;
+ HANDLE hOldFile = pFile->h;
+ pFile->h = *phFile;
+ *phFile = hOldFile;
+ OSTRACE(("FCNTL oldFile=%p, newFile=%p, rc=SQLITE_OK\n",
+ hOldFile, pFile->h));
+ return SQLITE_OK;
+ }
+#endif
case SQLITE_FCNTL_TEMPFILENAME: {
char *zTFile = 0;
int rc = winGetTempname(pFile->pVfs, &zTFile);
diff --git a/src/printf.c b/src/printf.c
index 01209c042..37910804d 100644
--- a/src/printf.c
+++ b/src/printf.c
@@ -756,6 +756,7 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
zNew = sqlite3_realloc(zOld, p->nAlloc);
}
if( zNew ){
+ assert( p->zText!=0 || p->nChar==0 );
if( zOld==0 && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
p->zText = zNew;
}else{
diff --git a/src/shell.c b/src/shell.c
index 5daadbeaf..63517fdd1 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -2425,8 +2425,8 @@ static int do_meta_command(char *zLine, struct callback_data *p){
}else
if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
- char *zTable = azArg[2]; /* Insert data into this table */
- char *zFile = azArg[1]; /* Name of file to extra content from */
+ char *zTable; /* Insert data into this table */
+ char *zFile; /* Name of file to extra content from */
sqlite3_stmt *pStmt = NULL; /* A statement */
int nCol; /* Number of columns in the table */
int nByte; /* Number of bytes in an SQL string */
@@ -2441,6 +2441,8 @@ static int do_meta_command(char *zLine, struct callback_data *p){
fprintf(stderr, "Usage: .import FILE TABLE\n");
goto meta_command_exit;
}
+ zFile = azArg[1];
+ zTable = azArg[2];
seenInterrupt = 0;
memset(&sCsv, 0, sizeof(sCsv));
open_db(p, 0);
@@ -2998,7 +3000,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"",
zCmd, azArg[i]);
}
- system(zCmd);
+ (void)system(zCmd);
sqlite3_free(zCmd);
}else
diff --git a/src/sqlite.h.in b/src/sqlite.h.in
index dc45899cf..47b81d198 100644
--- a/src/sqlite.h.in
+++ b/src/sqlite.h.in
@@ -942,6 +942,12 @@ struct sqlite3_io_methods {
** on whether or not the file has been renamed, moved, or deleted since it
** was first opened.
**
+** <li>[[SQLITE_FCNTL_WIN32_SET_HANDLE]]
+** The [SQLITE_FCNTL_WIN32_SET_HANDLE] opcode is used for debugging. This
+** opcode causes the xFileControl method to swap the file handle with the one
+** pointed to by the pArg argument. This capability is used during testing
+** and only needs to be supported when SQLITE_TEST is defined.
+**
** </ul>
*/
#define SQLITE_FCNTL_LOCKSTATE 1
@@ -965,6 +971,7 @@ struct sqlite3_io_methods {
#define SQLITE_FCNTL_HAS_MOVED 20
#define SQLITE_FCNTL_SYNC 21
#define SQLITE_FCNTL_COMMIT_PHASETWO 22
+#define SQLITE_FCNTL_WIN32_SET_HANDLE 23
/*
** CAPI3REF: Mutex Handle
diff --git a/src/test1.c b/src/test1.c
index ab51ddafa..3872207cb 100644
--- a/src/test1.c
+++ b/src/test1.c
@@ -117,6 +117,16 @@ int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb){
return TCL_OK;
}
+#if SQLITE_OS_WIN
+/*
+** Decode a Win32 HANDLE object.
+*/
+int getWin32Handle(Tcl_Interp *interp, const char *zA, LPHANDLE phFile){
+ *phFile = (HANDLE)sqlite3TestTextToPtr(zA);
+ return TCL_OK;
+}
+#endif
+
extern const char *sqlite3ErrName(int);
#define t1ErrorName sqlite3ErrName
@@ -5250,6 +5260,7 @@ static int file_control_lockproxy_test(
return TCL_OK;
}
+#if SQLITE_OS_WIN
/*
** tclcmd: file_control_win32_av_retry DB NRETRY DELAY
**
@@ -5284,6 +5295,42 @@ static int file_control_win32_av_retry(
}
/*
+** tclcmd: file_control_win32_set_handle DB HANDLE
+**
+** This TCL command runs the sqlite3_file_control interface with
+** the SQLITE_FCNTL_WIN32_SET_HANDLE opcode.
+*/
+static int file_control_win32_set_handle(
+ ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
+ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
+ int objc, /* Number of arguments */
+ Tcl_Obj *CONST objv[] /* Command arguments */
+){
+ sqlite3 *db;
+ int rc;
+ HANDLE hFile = NULL;
+ char z[100];
+
+ if( objc!=3 ){
+ Tcl_AppendResult(interp, "wrong # args: should be \"",
+ Tcl_GetStringFromObj(objv[0], 0), " DB HANDLE", 0);
+ return TCL_ERROR;
+ }
+ if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
+ return TCL_ERROR;
+ }
+ if( getWin32Handle(interp, Tcl_GetString(objv[2]), &hFile) ){
+ return TCL_ERROR;
+ }
+ rc = sqlite3_file_control(db, NULL, SQLITE_FCNTL_WIN32_SET_HANDLE,
+ (void*)&hFile);
+ sqlite3_snprintf(sizeof(z), z, "%d %p", rc, (void*)hFile);
+ Tcl_AppendResult(interp, z, (char*)0);
+ return TCL_OK;
+}
+#endif
+
+/*
** tclcmd: file_control_persist_wal DB PERSIST-FLAG
**
** This TCL command runs the sqlite3_file_control interface with
@@ -6633,7 +6680,10 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
{ "file_control_lockproxy_test", file_control_lockproxy_test, 0 },
{ "file_control_chunksize_test", file_control_chunksize_test, 0 },
{ "file_control_sizehint_test", file_control_sizehint_test, 0 },
+#if SQLITE_OS_WIN
{ "file_control_win32_av_retry", file_control_win32_av_retry, 0 },
+ { "file_control_win32_set_handle", file_control_win32_set_handle, 0 },
+#endif
{ "file_control_persist_wal", file_control_persist_wal, 0 },
{ "file_control_powersafe_overwrite",file_control_powersafe_overwrite,0},
{ "file_control_vfsname", file_control_vfsname, 0 },
diff --git a/src/where.c b/src/where.c
index 25c1c0414..f914004b2 100644
--- a/src/where.c
+++ b/src/where.c
@@ -4286,7 +4286,6 @@ static int whereLoopAddBtreeIndex(
testcase( eOp & WO_IN );
pNew->nOut += pTerm->truthProb;
pNew->nOut -= nIn;
- pNew->wsFlags |= WHERE_LIKELIHOOD;
}else{
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
tRowcnt nOut = 0;
@@ -4295,7 +4294,6 @@ static int whereLoopAddBtreeIndex(
&& pNew->u.btree.nEq<=pProbe->nSampleCol
&& OptimizationEnabled(db, SQLITE_Stat3)
&& ((eOp & WO_IN)==0 || !ExprHasProperty(pTerm->pExpr, EP_xIsSelect))
- && (pNew->wsFlags & WHERE_LIKELIHOOD)==0
){
Expr *pExpr = pTerm->pExpr;
if( (eOp & (WO_EQ|WO_ISNULL))!=0 ){
@@ -5297,7 +5295,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
/* TUNING: For simple queries, only the best path is tracked.
** For 2-way joins, the 5 best paths are followed.
** For joins of 3 or more tables, track the 10 best paths */
- mxChoice = (nLoop==1) ? 1 : (nLoop==2 ? 5 : 10);
+ mxChoice = (nLoop<=1) ? 1 : (nLoop==2 ? 5 : 10);
assert( nLoop<=pWInfo->pTabList->nSrc );
WHERETRACE(0x002, ("---- begin solver\n"));
@@ -5327,7 +5325,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
aFrom[0].isOrdered = 0;
nOrderBy = 0;
}else{
- aFrom[0].isOrdered = -1;
+ aFrom[0].isOrdered = nLoop>0 ? -1 : 1;
nOrderBy = pWInfo->pOrderBy->nExpr;
}
diff --git a/src/whereInt.h b/src/whereInt.h
index 010cd6e8a..72e7530db 100644
--- a/src/whereInt.h
+++ b/src/whereInt.h
@@ -458,4 +458,3 @@ struct WhereInfo {
#define WHERE_AUTO_INDEX 0x00004000 /* Uses an ephemeral index */
#define WHERE_SKIPSCAN 0x00008000 /* Uses the skip-scan algorithm */
#define WHERE_UNQ_WANTED 0x00010000 /* WHERE_ONEROW would have been helpful*/
-#define WHERE_LIKELIHOOD 0x00020000 /* A likelihood() is affecting nOut */