mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
Add the -withoutnulls option to the "db eval" method in the TCL interface.
FossilOrigin-Name: 18f0616e15684ca327fb10a1d133331af1d3b75f609498982290f6ad69fcaced
This commit is contained in:
14
manifest
14
manifest
@@ -1,5 +1,5 @@
|
|||||||
C The\s".import"\scommand\sof\sthe\sshell,\sand\sthe\scsv\svirtual\stable\sextension\sboth\nignore\sa\ssingle\sUTF-8\sBOM\sat\sthe\sbeginning\sof\stheir\sinput.
|
C Add\sthe\s-withoutnulls\soption\sto\sthe\s"db\seval"\smethod\sin\sthe\sTCL\sinterface.
|
||||||
D 2017-06-26T18:42:23.729
|
D 2017-06-26T21:08:32.812
|
||||||
F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb
|
F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb
|
||||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||||
F Makefile.msc 8eeb80162074004e906b53d7340a12a14c471a83743aab975947e95ce061efcc
|
F Makefile.msc 8eeb80162074004e906b53d7340a12a14c471a83743aab975947e95ce061efcc
|
||||||
@@ -414,7 +414,7 @@ F src/sqliteInt.h 34a54fb47de2da1465f3d3ba1cd373db880bd5d588b0fe862a073ecacd6dda
|
|||||||
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
|
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
|
||||||
F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1
|
F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1
|
||||||
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
|
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
|
||||||
F src/tclsqlite.c 1ac29f18b1b3787a30b45dbbdf6fdc4aa4f1a2f8c7c8fe586beba1b177eba97d
|
F src/tclsqlite.c cbf6313f86400acdf7dbf55fcd218cd28d43110a1210967efbc4f250646f81c0
|
||||||
F src/test1.c c99f0442918a7a5d5b68a95d6024c211989e6c782c15ced5a558994baaf76a5e
|
F src/test1.c c99f0442918a7a5d5b68a95d6024c211989e6c782c15ced5a558994baaf76a5e
|
||||||
F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5
|
F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5
|
||||||
F src/test3.c b8434949dfb8aff8dfa082c8b592109e77844c2135ed3c492113839b6956255b
|
F src/test3.c b8434949dfb8aff8dfa082c8b592109e77844c2135ed3c492113839b6956255b
|
||||||
@@ -1187,7 +1187,7 @@ F test/tabfunc01.test 699251cb99651415218a891384510a685c7ab012
|
|||||||
F test/table.test b708f3e5fa2542fa51dfab21fc07b36ea445cb2f
|
F test/table.test b708f3e5fa2542fa51dfab21fc07b36ea445cb2f
|
||||||
F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126
|
F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126
|
||||||
F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930
|
F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930
|
||||||
F test/tclsqlite.test 1d73b9203b1ca8798d7d7310742b8d3febc0d56e
|
F test/tclsqlite.test c3d7ac9449634b9f17fd048a3c0212e88a7448be810a9c5bd051acc1ffa00d2f
|
||||||
F test/tempdb.test bd92eba8f20e16a9136e434e20b280794de3cdb6
|
F test/tempdb.test bd92eba8f20e16a9136e434e20b280794de3cdb6
|
||||||
F test/tempdb2.test 27e41ed540b2f9b056c2e77e9bddc1b875358507
|
F test/tempdb2.test 27e41ed540b2f9b056c2e77e9bddc1b875358507
|
||||||
F test/tempfault.test 0c0d349c9a99bf5f374655742577f8712c647900
|
F test/tempfault.test 0c0d349c9a99bf5f374655742577f8712c647900
|
||||||
@@ -1583,7 +1583,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
|||||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||||
P c8186874b3fec737445ad5c4ba3eaecd922af664b387d89dc31eea60476a0294
|
P 7c15d762d99c2e3e534cd35dfe25ddcd317637eb1f2655fd24c2dd5f9d5a7613
|
||||||
R ab3f395a40974200838735f2b7274cd8
|
R 444ece00921d566093c338ff4adc8e5d
|
||||||
U drh
|
U drh
|
||||||
Z 910f6f462fbe04fd9eb737726ef5f52f
|
Z eb4d6ea47810159e5e12ebef5223a855
|
||||||
|
@@ -1 +1 @@
|
|||||||
7c15d762d99c2e3e534cd35dfe25ddcd317637eb1f2655fd24c2dd5f9d5a7613
|
18f0616e15684ca327fb10a1d133331af1d3b75f609498982290f6ad69fcaced
|
@@ -1451,10 +1451,13 @@ struct DbEvalContext {
|
|||||||
const char *zSql; /* Remaining SQL to execute */
|
const char *zSql; /* Remaining SQL to execute */
|
||||||
SqlPreparedStmt *pPreStmt; /* Current statement */
|
SqlPreparedStmt *pPreStmt; /* Current statement */
|
||||||
int nCol; /* Number of columns returned by pStmt */
|
int nCol; /* Number of columns returned by pStmt */
|
||||||
|
int evalFlags; /* Flags used */
|
||||||
Tcl_Obj *pArray; /* Name of array variable */
|
Tcl_Obj *pArray; /* Name of array variable */
|
||||||
Tcl_Obj **apColName; /* Array of column names */
|
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
|
** Release any cache of column names currently held as part of
|
||||||
** the DbEvalContext structure passed as the first argument.
|
** the DbEvalContext structure passed as the first argument.
|
||||||
@@ -1487,7 +1490,8 @@ static void dbEvalInit(
|
|||||||
DbEvalContext *p, /* Pointer to structure to initialize */
|
DbEvalContext *p, /* Pointer to structure to initialize */
|
||||||
SqliteDb *pDb, /* Database handle */
|
SqliteDb *pDb, /* Database handle */
|
||||||
Tcl_Obj *pSql, /* Object containing SQL script */
|
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));
|
memset(p, 0, sizeof(DbEvalContext));
|
||||||
p->pDb = pDb;
|
p->pDb = pDb;
|
||||||
@@ -1498,6 +1502,7 @@ static void dbEvalInit(
|
|||||||
p->pArray = pArray;
|
p->pArray = pArray;
|
||||||
Tcl_IncrRefCount(pArray);
|
Tcl_IncrRefCount(pArray);
|
||||||
}
|
}
|
||||||
|
p->evalFlags = evalFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1730,11 +1735,15 @@ static int SQLITE_TCLAPI DbEvalNextCmd(
|
|||||||
Tcl_Obj **apColName;
|
Tcl_Obj **apColName;
|
||||||
dbEvalRowInfo(p, &nCol, &apColName);
|
dbEvalRowInfo(p, &nCol, &apColName);
|
||||||
for(i=0; i<nCol; i++){
|
for(i=0; i<nCol; i++){
|
||||||
Tcl_Obj *pVal = dbEvalColumnValue(p, i);
|
|
||||||
if( pArray==0 ){
|
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{
|
}else{
|
||||||
Tcl_ObjSetVar2(interp, pArray, apColName[i], pVal, 0);
|
Tcl_ObjSetVar2(interp, pArray, apColName[i], dbEvalColumnValue(p,i), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2447,7 +2456,7 @@ static int SQLITE_TCLAPI DbObjCmd(
|
|||||||
return TCL_ERROR;
|
return TCL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
dbEvalInit(&sEval, pDb, objv[2], 0);
|
dbEvalInit(&sEval, pDb, objv[2], 0, 0);
|
||||||
rc = dbEvalStep(&sEval);
|
rc = dbEvalStep(&sEval);
|
||||||
if( choice==DB_ONECOLUMN ){
|
if( choice==DB_ONECOLUMN ){
|
||||||
if( rc==TCL_OK ){
|
if( rc==TCL_OK ){
|
||||||
@@ -2468,7 +2477,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
|
** 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.
|
** placed in elements of the array named "array" and ...code... is executed.
|
||||||
@@ -2477,8 +2486,22 @@ static int SQLITE_TCLAPI DbObjCmd(
|
|||||||
** that have the same name as the fields extracted by the query.
|
** that have the same name as the fields extracted by the query.
|
||||||
*/
|
*/
|
||||||
case DB_EVAL: {
|
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 ){
|
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;
|
return TCL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2486,7 +2509,7 @@ static int SQLITE_TCLAPI DbObjCmd(
|
|||||||
DbEvalContext sEval;
|
DbEvalContext sEval;
|
||||||
Tcl_Obj *pRet = Tcl_NewObj();
|
Tcl_Obj *pRet = Tcl_NewObj();
|
||||||
Tcl_IncrRefCount(pRet);
|
Tcl_IncrRefCount(pRet);
|
||||||
dbEvalInit(&sEval, pDb, objv[2], 0);
|
dbEvalInit(&sEval, pDb, objv[2], 0, 0);
|
||||||
while( TCL_OK==(rc = dbEvalStep(&sEval)) ){
|
while( TCL_OK==(rc = dbEvalStep(&sEval)) ){
|
||||||
int i;
|
int i;
|
||||||
int nCol;
|
int nCol;
|
||||||
@@ -2507,14 +2530,14 @@ static int SQLITE_TCLAPI DbObjCmd(
|
|||||||
Tcl_Obj *pArray = 0;
|
Tcl_Obj *pArray = 0;
|
||||||
Tcl_Obj *pScript;
|
Tcl_Obj *pScript;
|
||||||
|
|
||||||
if( objc==5 && *(char *)Tcl_GetString(objv[3]) ){
|
if( objc>=5 && *(char *)Tcl_GetString(objv[3]) ){
|
||||||
pArray = objv[3];
|
pArray = objv[3];
|
||||||
}
|
}
|
||||||
pScript = objv[objc-1];
|
pScript = objv[objc-1];
|
||||||
Tcl_IncrRefCount(pScript);
|
Tcl_IncrRefCount(pScript);
|
||||||
|
|
||||||
p = (DbEvalContext *)Tcl_Alloc(sizeof(DbEvalContext));
|
p = (DbEvalContext *)Tcl_Alloc(sizeof(DbEvalContext));
|
||||||
dbEvalInit(p, pDb, objv[2], pArray);
|
dbEvalInit(p, pDb, objv[2], pArray, evalFlags);
|
||||||
|
|
||||||
cd2[0] = (void *)p;
|
cd2[0] = (void *)p;
|
||||||
cd2[1] = (void *)pScript;
|
cd2[1] = (void *)pScript;
|
||||||
|
@@ -113,7 +113,7 @@ ifcapable {complete} {
|
|||||||
do_test tcl-1.14 {
|
do_test tcl-1.14 {
|
||||||
set v [catch {db eval} msg]
|
set v [catch {db eval} msg]
|
||||||
lappend v $msg
|
lappend v $msg
|
||||||
} {1 {wrong # args: should be "db eval SQL ?ARRAY-NAME? ?SCRIPT?"}}
|
} {1 {wrong # args: should be "db eval ?OPTIONS? SQL ?ARRAY-NAME? ?SCRIPT?"}}
|
||||||
do_test tcl-1.15 {
|
do_test tcl-1.15 {
|
||||||
set v [catch {db function} msg]
|
set v [catch {db function} msg]
|
||||||
lappend v $msg
|
lappend v $msg
|
||||||
@@ -665,6 +665,44 @@ do_test tcl-15.5 {
|
|||||||
} {0}
|
} {0}
|
||||||
|
|
||||||
|
|
||||||
|
# 2017-06-26: The --withoutnulls flag to "db eval".
|
||||||
|
#
|
||||||
|
# In the "db eval --withoutnulls SQL ARRAY" form, NULL results cause the
|
||||||
|
# corresponding array entry to be unset. The default behavior (without
|
||||||
|
# the -withoutnulls flags) is for the corresponding array value to get
|
||||||
|
# the [db nullvalue] string.
|
||||||
|
#
|
||||||
|
catch {db close}
|
||||||
|
forcedelete test.db
|
||||||
|
sqlite3 db test.db
|
||||||
|
do_execsql_test tcl-16.100 {
|
||||||
|
CREATE TABLE t1(a,b);
|
||||||
|
INSERT INTO t1 VALUES(1,2),(2,NULL),(3,'xyz');
|
||||||
|
}
|
||||||
|
do_test tcl-16.101 {
|
||||||
|
set res {}
|
||||||
|
unset -nocomplain x
|
||||||
|
db eval {SELECT * FROM t1} x {
|
||||||
|
lappend res $x(a) [array names x]
|
||||||
|
}
|
||||||
|
set res
|
||||||
|
} {1 {a b *} 2 {a b *} 3 {a b *}}
|
||||||
|
do_test tcl-16.102 {
|
||||||
|
set res [catch {
|
||||||
|
db eval -unknown {SELECT * FROM t1} x {
|
||||||
|
lappend res $x(a) [array names x]
|
||||||
|
}
|
||||||
|
} rc]
|
||||||
|
lappend res $rc
|
||||||
|
} {1 {unknown option: "-unknown"}}
|
||||||
|
do_test tcl-16.103 {
|
||||||
|
set res {}
|
||||||
|
unset -nocomplain x
|
||||||
|
db eval -withoutnulls {SELECT * FROM t1} x {
|
||||||
|
lappend res $x(a) [array names x]
|
||||||
|
}
|
||||||
|
set res
|
||||||
|
} {1 {a b *} 2 {a *} 3 {a b *}}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user