mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Incorporate recent trunk changes.
FossilOrigin-Name: 62b8269ba2ff71e2daaa86688698896badd6f6e34ab42fbf92dda7fcda73a230
This commit is contained in:
@@ -161,6 +161,7 @@ struct SqliteDb {
|
||||
int nStmt; /* Number of statements in stmtList */
|
||||
IncrblobChannel *pIncrblob;/* Linked list of open incrblob channels */
|
||||
int nStep, nSort, nIndex; /* Statistics for most recent operation */
|
||||
int nVMStep; /* Another statistic for most recent operation */
|
||||
int nTransaction; /* Number of nested [transaction] methods */
|
||||
int openFlags; /* Flags used to open. (SQLITE_OPEN_URI) */
|
||||
#ifdef SQLITE_TEST
|
||||
@@ -1456,10 +1457,13 @@ struct DbEvalContext {
|
||||
const char *zSql; /* Remaining SQL to execute */
|
||||
SqlPreparedStmt *pPreStmt; /* Current statement */
|
||||
int nCol; /* Number of columns returned by pStmt */
|
||||
int evalFlags; /* Flags used */
|
||||
Tcl_Obj *pArray; /* Name of array variable */
|
||||
Tcl_Obj **apColName; /* Array of column names */
|
||||
};
|
||||
|
||||
#define SQLITE_EVAL_WITHOUTNULLS 0x00001 /* Unset array(*) for NULL */
|
||||
|
||||
/*
|
||||
** Release any cache of column names currently held as part of
|
||||
** the DbEvalContext structure passed as the first argument.
|
||||
@@ -1492,7 +1496,8 @@ static void dbEvalInit(
|
||||
DbEvalContext *p, /* Pointer to structure to initialize */
|
||||
SqliteDb *pDb, /* Database handle */
|
||||
Tcl_Obj *pSql, /* Object containing SQL script */
|
||||
Tcl_Obj *pArray /* Name of Tcl array to set (*) element of */
|
||||
Tcl_Obj *pArray, /* Name of Tcl array to set (*) element of */
|
||||
int evalFlags /* Flags controlling evaluation */
|
||||
){
|
||||
memset(p, 0, sizeof(DbEvalContext));
|
||||
p->pDb = pDb;
|
||||
@@ -1503,6 +1508,7 @@ static void dbEvalInit(
|
||||
p->pArray = pArray;
|
||||
Tcl_IncrRefCount(pArray);
|
||||
}
|
||||
p->evalFlags = evalFlags;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1594,6 +1600,7 @@ static int dbEvalStep(DbEvalContext *p){
|
||||
pDb->nStep = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_FULLSCAN_STEP,1);
|
||||
pDb->nSort = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_SORT,1);
|
||||
pDb->nIndex = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_AUTOINDEX,1);
|
||||
pDb->nVMStep = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_VM_STEP,1);
|
||||
dbReleaseColumnNames(p);
|
||||
p->pPreStmt = 0;
|
||||
|
||||
@@ -1734,11 +1741,15 @@ static int SQLITE_TCLAPI DbEvalNextCmd(
|
||||
Tcl_Obj **apColName;
|
||||
dbEvalRowInfo(p, &nCol, &apColName);
|
||||
for(i=0; i<nCol; i++){
|
||||
Tcl_Obj *pVal = dbEvalColumnValue(p, i);
|
||||
if( pArray==0 ){
|
||||
Tcl_ObjSetVar2(interp, apColName[i], 0, pVal, 0);
|
||||
Tcl_ObjSetVar2(interp, apColName[i], 0, dbEvalColumnValue(p,i), 0);
|
||||
}else if( (p->evalFlags & SQLITE_EVAL_WITHOUTNULLS)!=0
|
||||
&& sqlite3_column_type(p->pPreStmt->pStmt, i)==SQLITE_NULL
|
||||
){
|
||||
Tcl_UnsetVar2(interp, Tcl_GetString(pArray),
|
||||
Tcl_GetString(apColName[i]), 0);
|
||||
}else{
|
||||
Tcl_ObjSetVar2(interp, pArray, apColName[i], pVal, 0);
|
||||
Tcl_ObjSetVar2(interp, pArray, apColName[i], dbEvalColumnValue(p,i), 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2451,7 +2462,7 @@ static int SQLITE_TCLAPI DbObjCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
dbEvalInit(&sEval, pDb, objv[2], 0);
|
||||
dbEvalInit(&sEval, pDb, objv[2], 0, 0);
|
||||
rc = dbEvalStep(&sEval);
|
||||
if( choice==DB_ONECOLUMN ){
|
||||
if( rc==TCL_OK ){
|
||||
@@ -2472,7 +2483,7 @@ static int SQLITE_TCLAPI DbObjCmd(
|
||||
}
|
||||
|
||||
/*
|
||||
** $db eval $sql ?array? ?{ ...code... }?
|
||||
** $db eval ?options? $sql ?array? ?{ ...code... }?
|
||||
**
|
||||
** The SQL statement in $sql is evaluated. For each row, the values are
|
||||
** placed in elements of the array named "array" and ...code... is executed.
|
||||
@@ -2481,8 +2492,22 @@ static int SQLITE_TCLAPI DbObjCmd(
|
||||
** that have the same name as the fields extracted by the query.
|
||||
*/
|
||||
case DB_EVAL: {
|
||||
int evalFlags = 0;
|
||||
const char *zOpt;
|
||||
while( objc>3 && (zOpt = Tcl_GetString(objv[2]))!=0 && zOpt[0]=='-' ){
|
||||
if( strcmp(zOpt, "-withoutnulls")==0 ){
|
||||
evalFlags |= SQLITE_EVAL_WITHOUTNULLS;
|
||||
}
|
||||
else{
|
||||
Tcl_AppendResult(interp, "unknown option: \"", zOpt, "\"", (void*)0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
objc--;
|
||||
objv++;
|
||||
}
|
||||
if( objc<3 || objc>5 ){
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "SQL ?ARRAY-NAME? ?SCRIPT?");
|
||||
Tcl_WrongNumArgs(interp, 2, objv,
|
||||
"?OPTIONS? SQL ?ARRAY-NAME? ?SCRIPT?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -2490,7 +2515,7 @@ static int SQLITE_TCLAPI DbObjCmd(
|
||||
DbEvalContext sEval;
|
||||
Tcl_Obj *pRet = Tcl_NewObj();
|
||||
Tcl_IncrRefCount(pRet);
|
||||
dbEvalInit(&sEval, pDb, objv[2], 0);
|
||||
dbEvalInit(&sEval, pDb, objv[2], 0, 0);
|
||||
while( TCL_OK==(rc = dbEvalStep(&sEval)) ){
|
||||
int i;
|
||||
int nCol;
|
||||
@@ -2511,14 +2536,14 @@ static int SQLITE_TCLAPI DbObjCmd(
|
||||
Tcl_Obj *pArray = 0;
|
||||
Tcl_Obj *pScript;
|
||||
|
||||
if( objc==5 && *(char *)Tcl_GetString(objv[3]) ){
|
||||
if( objc>=5 && *(char *)Tcl_GetString(objv[3]) ){
|
||||
pArray = objv[3];
|
||||
}
|
||||
pScript = objv[objc-1];
|
||||
Tcl_IncrRefCount(pScript);
|
||||
|
||||
p = (DbEvalContext *)Tcl_Alloc(sizeof(DbEvalContext));
|
||||
dbEvalInit(p, pDb, objv[2], pArray);
|
||||
dbEvalInit(p, pDb, objv[2], pArray, evalFlags);
|
||||
|
||||
cd2[0] = (void *)p;
|
||||
cd2[1] = (void *)pScript;
|
||||
@@ -2861,7 +2886,7 @@ static int SQLITE_TCLAPI DbObjCmd(
|
||||
}
|
||||
|
||||
/*
|
||||
** $db status (step|sort|autoindex)
|
||||
** $db status (step|sort|autoindex|vmstep)
|
||||
**
|
||||
** Display SQLITE_STMTSTATUS_FULLSCAN_STEP or
|
||||
** SQLITE_STMTSTATUS_SORT for the most recent eval.
|
||||
@@ -2880,9 +2905,11 @@ static int SQLITE_TCLAPI DbObjCmd(
|
||||
v = pDb->nSort;
|
||||
}else if( strcmp(zOp, "autoindex")==0 ){
|
||||
v = pDb->nIndex;
|
||||
}else if( strcmp(zOp, "vmstep")==0 ){
|
||||
v = pDb->nVMStep;
|
||||
}else{
|
||||
Tcl_AppendResult(interp,
|
||||
"bad argument: should be autoindex, step, or sort",
|
||||
"bad argument: should be autoindex, step, sort or vmstep",
|
||||
(char*)0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
Reference in New Issue
Block a user