mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-05 15:55:57 +03:00
Testing coverage enhancements to sqlite3_get_table() and to the SELECT
code generator. (CVS 4746) FossilOrigin-Name: 45c59802f6d35c7745b96c578ab43d5a336fe822
This commit is contained in:
22
manifest
22
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Improvements\sto\stest\scoverage\sin\sthe\slemon-generated\sparser\sand\sin\sthe\nsqlite3_get_table()\sinterface.\s(CVS\s4745)
|
C Testing\scoverage\senhancements\sto\ssqlite3_get_table()\sand\sto\sthe\sSELECT\ncode\sgenerator.\s(CVS\s4746)
|
||||||
D 2008-01-23T12:52:41
|
D 2008-01-23T14:51:49
|
||||||
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
|
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
|
||||||
F Makefile.in bc2b5df3e3d0d4b801b824b7ef6dec43812b049b
|
F Makefile.in bc2b5df3e3d0d4b801b824b7ef6dec43812b049b
|
||||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||||
@@ -92,7 +92,7 @@ F src/complete.c 4cf68fd75d60257524cbe74f87351b9848399131
|
|||||||
F src/date.c 8ce763c68143b1e8fb6f79dcfc8b801853c97017
|
F src/date.c 8ce763c68143b1e8fb6f79dcfc8b801853c97017
|
||||||
F src/delete.c 739ccbab8fa7478762bded5c9cc67f16a4d09dbe
|
F src/delete.c 739ccbab8fa7478762bded5c9cc67f16a4d09dbe
|
||||||
F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b
|
F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b
|
||||||
F src/expr.c 07318c7e5e3062e2d33314f72819ea420b210dc1
|
F src/expr.c e6fb42c6e55fd9526174b1cb8296b69a60a6688a
|
||||||
F src/fault.c 049b88b8ba0a1db3240aeaf9695cd08b9a3ba9e1
|
F src/fault.c 049b88b8ba0a1db3240aeaf9695cd08b9a3ba9e1
|
||||||
F src/func.c 8e3d0c59961dc403716767308ee764504179054b
|
F src/func.c 8e3d0c59961dc403716767308ee764504179054b
|
||||||
F src/hash.c 2dc6afe7478a0b739499af360c8863c900ea11a8
|
F src/hash.c 2dc6afe7478a0b739499af360c8863c900ea11a8
|
||||||
@@ -132,16 +132,16 @@ F src/pragma.c 2bb8d6882b9a330e041acd05fb6aff5a01bf0a08
|
|||||||
F src/prepare.c 1b0601ca3f97a9d253cc08697484e3045a1678e9
|
F src/prepare.c 1b0601ca3f97a9d253cc08697484e3045a1678e9
|
||||||
F src/printf.c eb27822ba2eec669161409ca31279a24c26ac910
|
F src/printf.c eb27822ba2eec669161409ca31279a24c26ac910
|
||||||
F src/random.c 02ef38b469237482f1ea14a78b2087cfbaec48bd
|
F src/random.c 02ef38b469237482f1ea14a78b2087cfbaec48bd
|
||||||
F src/select.c 9fb094cc0c8acdcbf3581fdfc4490e997b5d1d1e
|
F src/select.c 9c273d069d5051a4413cb55a578f01bd15f90bc8
|
||||||
F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
|
F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
|
||||||
F src/shell.c ca06cb687c40a8bff6307b5fad41a0e86a0f8558
|
F src/shell.c ca06cb687c40a8bff6307b5fad41a0e86a0f8558
|
||||||
F src/sqlite.h.in 2a7e3776534bbe6ff2cdc058f3abebe91e7e429f
|
F src/sqlite.h.in 2a7e3776534bbe6ff2cdc058f3abebe91e7e429f
|
||||||
F src/sqlite3ext.h a93f59cdee3638dc0c9c086f80df743a4e68c3cb
|
F src/sqlite3ext.h a93f59cdee3638dc0c9c086f80df743a4e68c3cb
|
||||||
F src/sqliteInt.h 9d87dc3aa23d78567e8f83c99dd991ea88e303fe
|
F src/sqliteInt.h a26f3d8473f6f91b0902d4f1334ee31f0f910eec
|
||||||
F src/sqliteLimit.h ee4430f88f69bf63527967bb35ca52af7b0ccb1e
|
F src/sqliteLimit.h ee4430f88f69bf63527967bb35ca52af7b0ccb1e
|
||||||
F src/table.c e97099ce0e442930ed9dbfd95072eccd70ab499a
|
F src/table.c 46ccf9b7892a86f57420ae7bac69ecd5e72d26b5
|
||||||
F src/tclsqlite.c 9923abeffc9b3d7dad58e92b319661521f60debf
|
F src/tclsqlite.c 9923abeffc9b3d7dad58e92b319661521f60debf
|
||||||
F src/test1.c 0040e28115047a50dde02383658f6b25ecbbcb42
|
F src/test1.c 5363a117741f26e84b85e30757f0f4414331c46f
|
||||||
F src/test2.c 77b34303883b9d722c65a6879bb0163a400e3789
|
F src/test2.c 77b34303883b9d722c65a6879bb0163a400e3789
|
||||||
F src/test3.c 6b49ddb0946907a07210998810807ace51be00a5
|
F src/test3.c 6b49ddb0946907a07210998810807ace51be00a5
|
||||||
F src/test4.c c2c0f5dc907f1346f5d4b65eb5799f11eb9e4071
|
F src/test4.c c2c0f5dc907f1346f5d4b65eb5799f11eb9e4071
|
||||||
@@ -450,7 +450,7 @@ F test/subselect.test 974e87f8fc91c5f00dd565316d396a5a6c3106c4
|
|||||||
F test/substr.test 4be572ac017143e59b4058dc75c91a0d0dc6d4e0
|
F test/substr.test 4be572ac017143e59b4058dc75c91a0d0dc6d4e0
|
||||||
F test/sync.test ded6b39d8d8ca3c0c5518516c6371b3316d3e3a3
|
F test/sync.test ded6b39d8d8ca3c0c5518516c6371b3316d3e3a3
|
||||||
F test/table.test 13b1c2e2fb4727b35ee1fb7641fc469214fd2455
|
F test/table.test 13b1c2e2fb4727b35ee1fb7641fc469214fd2455
|
||||||
F test/tableapi.test f6d07b9d63c3b0a5d09166d9bbd741e52d4ef309
|
F test/tableapi.test 4546eb710d979db023bfcc16b0c108b1557fcb43
|
||||||
F test/tclsqlite.test 3fac87cb1059c46b8fa8a60b553f4f1adb0fb6d9
|
F test/tclsqlite.test 3fac87cb1059c46b8fa8a60b553f4f1adb0fb6d9
|
||||||
F test/temptable.test 19b851b9e3e64d91e9867619b2a3f5fffee6e125
|
F test/temptable.test 19b851b9e3e64d91e9867619b2a3f5fffee6e125
|
||||||
F test/tester.tcl 6a6600646341b910f2fbfd02db1ef0274479366c
|
F test/tester.tcl 6a6600646341b910f2fbfd02db1ef0274479366c
|
||||||
@@ -614,7 +614,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
|
|||||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||||
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
||||||
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
|
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
|
||||||
P 5375ad6b4b652f388469b0ce4e8e78b3f49169bd
|
P 9f95d79daeb5e7f6fd62f3c896dae4d332121d1c
|
||||||
R cb7fa5e7c3a95c6765c29d29026204b1
|
R 7c8b98078b7046bd6e4e654dd28d4eae
|
||||||
U drh
|
U drh
|
||||||
Z cad27d1b994b4367a16598d68d423c30
|
Z cc9f9cd8eb83f3c51b585ce1808ca1e8
|
||||||
|
@@ -1 +1 @@
|
|||||||
9f95d79daeb5e7f6fd62f3c896dae4d332121d1c
|
45c59802f6d35c7745b96c578ab43d5a336fe822
|
17
src/expr.c
17
src/expr.c
@@ -12,7 +12,7 @@
|
|||||||
** This file contains routines used for analyzing expressions and
|
** This file contains routines used for analyzing expressions and
|
||||||
** for generating VDBE code that evaluates expressions in SQLite.
|
** for generating VDBE code that evaluates expressions in SQLite.
|
||||||
**
|
**
|
||||||
** $Id: expr.c,v 1.351 2008/01/19 23:50:26 drh Exp $
|
** $Id: expr.c,v 1.352 2008/01/23 14:51:49 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@@ -2922,14 +2922,9 @@ static int analyzeAggregate(void *pArg, Expr *pExpr){
|
|||||||
**
|
**
|
||||||
** This routine should only be called after the expression has been
|
** This routine should only be called after the expression has been
|
||||||
** analyzed by sqlite3ExprResolveNames().
|
** analyzed by sqlite3ExprResolveNames().
|
||||||
**
|
|
||||||
** If errors are seen, leave an error message in zErrMsg and return
|
|
||||||
** the number of errors.
|
|
||||||
*/
|
*/
|
||||||
int sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){
|
void sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){
|
||||||
int nErr = pNC->pParse->nErr;
|
|
||||||
walkExprTree(pExpr, analyzeAggregate, pNC);
|
walkExprTree(pExpr, analyzeAggregate, pNC);
|
||||||
return pNC->pParse->nErr - nErr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2938,16 +2933,14 @@ int sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){
|
|||||||
**
|
**
|
||||||
** If an error is found, the analysis is cut short.
|
** If an error is found, the analysis is cut short.
|
||||||
*/
|
*/
|
||||||
int sqlite3ExprAnalyzeAggList(NameContext *pNC, ExprList *pList){
|
void sqlite3ExprAnalyzeAggList(NameContext *pNC, ExprList *pList){
|
||||||
struct ExprList_item *pItem;
|
struct ExprList_item *pItem;
|
||||||
int i;
|
int i;
|
||||||
int nErr = 0;
|
|
||||||
if( pList ){
|
if( pList ){
|
||||||
for(pItem=pList->a, i=0; nErr==0 && i<pList->nExpr; i++, pItem++){
|
for(pItem=pList->a, i=0; i<pList->nExpr; i++, pItem++){
|
||||||
nErr += sqlite3ExprAnalyzeAggregates(pNC, pItem->pExpr);
|
sqlite3ExprAnalyzeAggregates(pNC, pItem->pExpr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nErr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
66
src/select.c
66
src/select.c
@@ -12,7 +12,7 @@
|
|||||||
** This file contains C code routines that are called by the parser
|
** This file contains C code routines that are called by the parser
|
||||||
** to handle SELECT statements in SQLite.
|
** to handle SELECT statements in SQLite.
|
||||||
**
|
**
|
||||||
** $Id: select.c,v 1.406 2008/01/19 03:35:59 drh Exp $
|
** $Id: select.c,v 1.407 2008/01/23 14:51:50 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -502,7 +502,7 @@ static int checkForMultiColumnSelectError(
|
|||||||
** then data is pulled from srcTab and pEList is used only to get the
|
** then data is pulled from srcTab and pEList is used only to get the
|
||||||
** datatypes for each column.
|
** datatypes for each column.
|
||||||
*/
|
*/
|
||||||
static int selectInnerLoop(
|
static void selectInnerLoop(
|
||||||
Parse *pParse, /* The parser context */
|
Parse *pParse, /* The parser context */
|
||||||
Select *p, /* The complete select statement being coded */
|
Select *p, /* The complete select statement being coded */
|
||||||
ExprList *pEList, /* List of values being extracted */
|
ExprList *pEList, /* List of values being extracted */
|
||||||
@@ -524,7 +524,7 @@ static int selectInnerLoop(
|
|||||||
int nResultCol; /* Number of result columns */
|
int nResultCol; /* Number of result columns */
|
||||||
int nToFree; /* Number of result columns to release */
|
int nToFree; /* Number of result columns to release */
|
||||||
|
|
||||||
if( v==0 ) return 0;
|
if( v==0 ) return;
|
||||||
assert( pEList!=0 );
|
assert( pEList!=0 );
|
||||||
|
|
||||||
/* If there was a LIMIT clause on the SELECT statement, then do the check
|
/* If there was a LIMIT clause on the SELECT statement, then do the check
|
||||||
@@ -577,7 +577,7 @@ static int selectInnerLoop(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if( checkForMultiColumnSelectError(pParse, pDest, pEList->nExpr) ){
|
if( checkForMultiColumnSelectError(pParse, pDest, pEList->nExpr) ){
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch( eDest ){
|
switch( eDest ){
|
||||||
@@ -722,7 +722,6 @@ static int selectInnerLoop(
|
|||||||
sqlite3VdbeAddOp2(v, OP_IfZero, p->iLimit, iBreak);
|
sqlite3VdbeAddOp2(v, OP_IfZero, p->iLimit, iBreak);
|
||||||
}
|
}
|
||||||
sqlite3ReleaseTempRange(pParse, regResult, nToFree);
|
sqlite3ReleaseTempRange(pParse, regResult, nToFree);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2057,12 +2056,8 @@ static int multiSelect(
|
|||||||
computeLimitRegisters(pParse, p, iBreak);
|
computeLimitRegisters(pParse, p, iBreak);
|
||||||
sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak);
|
sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak);
|
||||||
iStart = sqlite3VdbeCurrentAddr(v);
|
iStart = sqlite3VdbeCurrentAddr(v);
|
||||||
rc = selectInnerLoop(pParse, p, p->pEList, unionTab, p->pEList->nExpr,
|
selectInnerLoop(pParse, p, p->pEList, unionTab, p->pEList->nExpr,
|
||||||
pOrderBy, -1, &dest, iCont, iBreak, 0);
|
pOrderBy, -1, &dest, iCont, iBreak, 0);
|
||||||
if( rc ){
|
|
||||||
rc = 1;
|
|
||||||
goto multi_select_end;
|
|
||||||
}
|
|
||||||
sqlite3VdbeResolveLabel(v, iCont);
|
sqlite3VdbeResolveLabel(v, iCont);
|
||||||
sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart);
|
sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart);
|
||||||
sqlite3VdbeResolveLabel(v, iBreak);
|
sqlite3VdbeResolveLabel(v, iBreak);
|
||||||
@@ -2141,12 +2136,8 @@ static int multiSelect(
|
|||||||
iStart = sqlite3VdbeAddOp2(v, OP_RowKey, tab1, r1);
|
iStart = sqlite3VdbeAddOp2(v, OP_RowKey, tab1, r1);
|
||||||
sqlite3VdbeAddOp3(v, OP_NotFound, tab2, iCont, r1);
|
sqlite3VdbeAddOp3(v, OP_NotFound, tab2, iCont, r1);
|
||||||
sqlite3ReleaseTempReg(pParse, r1);
|
sqlite3ReleaseTempReg(pParse, r1);
|
||||||
rc = selectInnerLoop(pParse, p, p->pEList, tab1, p->pEList->nExpr,
|
selectInnerLoop(pParse, p, p->pEList, tab1, p->pEList->nExpr,
|
||||||
pOrderBy, -1, &dest, iCont, iBreak, 0);
|
pOrderBy, -1, &dest, iCont, iBreak, 0);
|
||||||
if( rc ){
|
|
||||||
rc = 1;
|
|
||||||
goto multi_select_end;
|
|
||||||
}
|
|
||||||
sqlite3VdbeResolveLabel(v, iCont);
|
sqlite3VdbeResolveLabel(v, iCont);
|
||||||
sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart);
|
sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart);
|
||||||
sqlite3VdbeResolveLabel(v, iBreak);
|
sqlite3VdbeResolveLabel(v, iBreak);
|
||||||
@@ -2919,13 +2910,11 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
|
|||||||
** corresponding bit in argument mask is not set. If mask takes the
|
** corresponding bit in argument mask is not set. If mask takes the
|
||||||
** special value 0xffffffff, then all columns are populated.
|
** special value 0xffffffff, then all columns are populated.
|
||||||
*/
|
*/
|
||||||
int sqlite3SelectMask(Parse *pParse, Select *p, u32 mask){
|
void sqlite3SelectMask(Parse *pParse, Select *p, u32 mask){
|
||||||
if( !p->pPrior && !p->isDistinct && mask!=0xffffffff ){
|
if( !p->pPrior && !p->isDistinct && mask!=0xffffffff ){
|
||||||
ExprList *pEList;
|
ExprList *pEList;
|
||||||
int i;
|
int i;
|
||||||
if( sqlite3SelectResolve(pParse, p, 0) ){
|
sqlite3SelectResolve(pParse, p, 0);
|
||||||
return SQLITE_ERROR;
|
|
||||||
}
|
|
||||||
pEList = p->pEList;
|
pEList = p->pEList;
|
||||||
for(i=0; i<pEList->nExpr && i<32; i++){
|
for(i=0; i<pEList->nExpr && i<32; i++){
|
||||||
if( !(mask&((u32)1<<i)) ){
|
if( !(mask&((u32)1<<i)) ){
|
||||||
@@ -2934,7 +2923,6 @@ int sqlite3SelectMask(Parse *pParse, Select *p, u32 mask){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return SQLITE_OK;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -3201,9 +3189,6 @@ int sqlite3Select(
|
|||||||
*/
|
*/
|
||||||
if( pOrderBy ){
|
if( pOrderBy ){
|
||||||
KeyInfo *pKeyInfo;
|
KeyInfo *pKeyInfo;
|
||||||
if( pParse->nErr ){
|
|
||||||
goto select_end;
|
|
||||||
}
|
|
||||||
pKeyInfo = keyInfoFromExprList(pParse, pOrderBy);
|
pKeyInfo = keyInfoFromExprList(pParse, pOrderBy);
|
||||||
pOrderBy->iECursor = pParse->nTab++;
|
pOrderBy->iECursor = pParse->nTab++;
|
||||||
p->addrOpenEphm[2] = addrSortIndex =
|
p->addrOpenEphm[2] = addrSortIndex =
|
||||||
@@ -3258,10 +3243,8 @@ int sqlite3Select(
|
|||||||
/* Use the standard inner loop
|
/* Use the standard inner loop
|
||||||
*/
|
*/
|
||||||
assert(!isDistinct);
|
assert(!isDistinct);
|
||||||
if( selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, -1, pDest,
|
selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, -1, pDest,
|
||||||
pWInfo->iContinue, pWInfo->iBreak, aff) ){
|
pWInfo->iContinue, pWInfo->iBreak, aff);
|
||||||
goto select_end;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* End the database scan loop.
|
/* End the database scan loop.
|
||||||
*/
|
*/
|
||||||
@@ -3302,20 +3285,14 @@ int sqlite3Select(
|
|||||||
sNC.pAggInfo = &sAggInfo;
|
sNC.pAggInfo = &sAggInfo;
|
||||||
sAggInfo.nSortingColumn = pGroupBy ? pGroupBy->nExpr+1 : 0;
|
sAggInfo.nSortingColumn = pGroupBy ? pGroupBy->nExpr+1 : 0;
|
||||||
sAggInfo.pGroupBy = pGroupBy;
|
sAggInfo.pGroupBy = pGroupBy;
|
||||||
if( sqlite3ExprAnalyzeAggList(&sNC, pEList) ){
|
sqlite3ExprAnalyzeAggList(&sNC, pEList);
|
||||||
goto select_end;
|
sqlite3ExprAnalyzeAggList(&sNC, pOrderBy);
|
||||||
}
|
if( pHaving ){
|
||||||
if( sqlite3ExprAnalyzeAggList(&sNC, pOrderBy) ){
|
sqlite3ExprAnalyzeAggregates(&sNC, pHaving);
|
||||||
goto select_end;
|
|
||||||
}
|
|
||||||
if( pHaving && sqlite3ExprAnalyzeAggregates(&sNC, pHaving) ){
|
|
||||||
goto select_end;
|
|
||||||
}
|
}
|
||||||
sAggInfo.nAccumulator = sAggInfo.nColumn;
|
sAggInfo.nAccumulator = sAggInfo.nColumn;
|
||||||
for(i=0; i<sAggInfo.nFunc; i++){
|
for(i=0; i<sAggInfo.nFunc; i++){
|
||||||
if( sqlite3ExprAnalyzeAggList(&sNC, sAggInfo.aFunc[i].pExpr->pList) ){
|
sqlite3ExprAnalyzeAggList(&sNC, sAggInfo.aFunc[i].pExpr->pList);
|
||||||
goto select_end;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if( db->mallocFailed ) goto select_end;
|
if( db->mallocFailed ) goto select_end;
|
||||||
|
|
||||||
@@ -3377,12 +3354,9 @@ int sqlite3Select(
|
|||||||
if( pHaving ){
|
if( pHaving ){
|
||||||
sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL);
|
sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL);
|
||||||
}
|
}
|
||||||
rc = selectInnerLoop(pParse, p, p->pEList, 0, 0, pOrderBy,
|
selectInnerLoop(pParse, p, p->pEList, 0, 0, pOrderBy,
|
||||||
distinct, pDest,
|
distinct, pDest,
|
||||||
addrOutputRow+1, addrSetAbort, aff);
|
addrOutputRow+1, addrSetAbort, aff);
|
||||||
if( rc ){
|
|
||||||
goto select_end;
|
|
||||||
}
|
|
||||||
sqlite3VdbeAddOp2(v, OP_Return, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Return, 0, 0);
|
||||||
VdbeComment((v, "end groupby result generator"));
|
VdbeComment((v, "end groupby result generator"));
|
||||||
|
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** Internal interface definitions for SQLite.
|
** Internal interface definitions for SQLite.
|
||||||
**
|
**
|
||||||
** @(#) $Id: sqliteInt.h,v 1.654 2008/01/23 03:03:05 drh Exp $
|
** @(#) $Id: sqliteInt.h,v 1.655 2008/01/23 14:51:50 drh Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef _SQLITEINT_H_
|
#ifndef _SQLITEINT_H_
|
||||||
#define _SQLITEINT_H_
|
#define _SQLITEINT_H_
|
||||||
@@ -1760,7 +1760,7 @@ int sqlite3Select(Parse*, Select*, SelectDest*, Select*, int, int*, char *aff);
|
|||||||
Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
|
Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
|
||||||
Expr*,ExprList*,int,Expr*,Expr*);
|
Expr*,ExprList*,int,Expr*,Expr*);
|
||||||
void sqlite3SelectDelete(Select*);
|
void sqlite3SelectDelete(Select*);
|
||||||
int sqlite3SelectMask(Parse *, Select *, u32);
|
void sqlite3SelectMask(Parse *, Select *, u32);
|
||||||
Table *sqlite3SrcListLookup(Parse*, SrcList*);
|
Table *sqlite3SrcListLookup(Parse*, SrcList*);
|
||||||
int sqlite3IsReadOnly(Parse*, Table*, int);
|
int sqlite3IsReadOnly(Parse*, Table*, int);
|
||||||
void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int);
|
void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int);
|
||||||
@@ -1785,8 +1785,8 @@ int sqlite3RunVacuum(char**, sqlite3*);
|
|||||||
char *sqlite3NameFromToken(sqlite3*, Token*);
|
char *sqlite3NameFromToken(sqlite3*, Token*);
|
||||||
int sqlite3ExprCompare(Expr*, Expr*);
|
int sqlite3ExprCompare(Expr*, Expr*);
|
||||||
int sqlite3ExprResolveNames(NameContext *, Expr *);
|
int sqlite3ExprResolveNames(NameContext *, Expr *);
|
||||||
int sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
|
void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
|
||||||
int sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
|
void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
|
||||||
Vdbe *sqlite3GetVdbe(Parse*);
|
Vdbe *sqlite3GetVdbe(Parse*);
|
||||||
Expr *sqlite3CreateIdExpr(Parse *, const char*);
|
Expr *sqlite3CreateIdExpr(Parse *, const char*);
|
||||||
void sqlite3Randomness(int, void*);
|
void sqlite3Randomness(int, void*);
|
||||||
|
16
src/table.c
16
src/table.c
@@ -70,11 +70,7 @@ static int sqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv){
|
|||||||
if( p->nRow==0 ){
|
if( p->nRow==0 ){
|
||||||
p->nColumn = nCol;
|
p->nColumn = nCol;
|
||||||
for(i=0; i<nCol; i++){
|
for(i=0; i<nCol; i++){
|
||||||
if( colv[i]==0 ){
|
z = sqlite3_mprintf("%s", colv[i]);
|
||||||
z = sqlite3_mprintf("");
|
|
||||||
}else{
|
|
||||||
z = sqlite3_mprintf("%s", colv[i]);
|
|
||||||
}
|
|
||||||
if( z==0 ) goto malloc_failed;
|
if( z==0 ) goto malloc_failed;
|
||||||
p->azResult[p->nData++] = z;
|
p->azResult[p->nData++] = z;
|
||||||
}
|
}
|
||||||
@@ -130,7 +126,7 @@ int sqlite3_get_table(
|
|||||||
){
|
){
|
||||||
int rc;
|
int rc;
|
||||||
TabResult res;
|
TabResult res;
|
||||||
if( pazResult==0 ){ return SQLITE_ERROR; }
|
|
||||||
*pazResult = 0;
|
*pazResult = 0;
|
||||||
if( pnColumn ) *pnColumn = 0;
|
if( pnColumn ) *pnColumn = 0;
|
||||||
if( pnRow ) *pnRow = 0;
|
if( pnRow ) *pnRow = 0;
|
||||||
@@ -148,10 +144,8 @@ int sqlite3_get_table(
|
|||||||
}
|
}
|
||||||
res.azResult[0] = 0;
|
res.azResult[0] = 0;
|
||||||
rc = sqlite3_exec(db, zSql, sqlite3_get_table_cb, &res, pzErrMsg);
|
rc = sqlite3_exec(db, zSql, sqlite3_get_table_cb, &res, pzErrMsg);
|
||||||
if( res.azResult ){
|
assert( sizeof(res.azResult[0])>= sizeof(res.nData) );
|
||||||
assert( sizeof(res.azResult[0])>= sizeof(res.nData) );
|
res.azResult[0] = (char*)res.nData;
|
||||||
res.azResult[0] = (char*)res.nData;
|
|
||||||
}
|
|
||||||
if( (rc&0xff)==SQLITE_ABORT ){
|
if( (rc&0xff)==SQLITE_ABORT ){
|
||||||
sqlite3_free_table(&res.azResult[1]);
|
sqlite3_free_table(&res.azResult[1]);
|
||||||
if( res.zErrMsg ){
|
if( res.zErrMsg ){
|
||||||
@@ -195,7 +189,7 @@ void sqlite3_free_table(
|
|||||||
if( azResult ){
|
if( azResult ){
|
||||||
int i, n;
|
int i, n;
|
||||||
azResult--;
|
azResult--;
|
||||||
if( azResult==0 ) return;
|
assert( azResult!=0 );
|
||||||
n = (int)azResult[0];
|
n = (int)azResult[0];
|
||||||
for(i=1; i<n; i++){ if( azResult[i] ) sqlite3_free(azResult[i]); }
|
for(i=1; i<n; i++){ if( azResult[i] ) sqlite3_free(azResult[i]); }
|
||||||
sqlite3_free(azResult);
|
sqlite3_free(azResult);
|
||||||
|
31
src/test1.c
31
src/test1.c
@@ -13,7 +13,7 @@
|
|||||||
** is not included in the SQLite library. It is used for automated
|
** is not included in the SQLite library. It is used for automated
|
||||||
** testing of the SQLite library.
|
** testing of the SQLite library.
|
||||||
**
|
**
|
||||||
** $Id: test1.c,v 1.286 2008/01/22 21:30:53 drh Exp $
|
** $Id: test1.c,v 1.287 2008/01/23 14:51:50 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "tcl.h"
|
#include "tcl.h"
|
||||||
@@ -494,7 +494,7 @@ static int test_snprintf_int(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Usage: sqlite3_get_table_printf DB FORMAT STRING
|
** Usage: sqlite3_get_table_printf DB FORMAT STRING ?--no-counts?
|
||||||
**
|
**
|
||||||
** Invoke the sqlite3_get_table_printf() interface using the open database
|
** Invoke the sqlite3_get_table_printf() interface using the open database
|
||||||
** DB. The SQL is the string FORMAT. The format string should contain
|
** DB. The SQL is the string FORMAT. The format string should contain
|
||||||
@@ -515,24 +515,35 @@ static int test_get_table_printf(
|
|||||||
int i;
|
int i;
|
||||||
char zBuf[30];
|
char zBuf[30];
|
||||||
char *zSql;
|
char *zSql;
|
||||||
if( argc!=4 ){
|
int resCount = -1;
|
||||||
|
if( argc==5 ){
|
||||||
|
if( Tcl_GetInt(interp, argv[4], &resCount) ) return TCL_ERROR;
|
||||||
|
}
|
||||||
|
if( argc!=4 && argc!=5 ){
|
||||||
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
|
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
|
||||||
" DB FORMAT STRING", 0);
|
" DB FORMAT STRING ?COUNT?", 0);
|
||||||
return TCL_ERROR;
|
return TCL_ERROR;
|
||||||
}
|
}
|
||||||
if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
|
if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
|
||||||
Tcl_DStringInit(&str);
|
Tcl_DStringInit(&str);
|
||||||
zSql = sqlite3_mprintf(argv[2],argv[3]);
|
zSql = sqlite3_mprintf(argv[2],argv[3]);
|
||||||
rc = sqlite3_get_table(db, zSql, &aResult, &nRow, &nCol, &zErr);
|
if( argc==5 ){
|
||||||
|
rc = sqlite3_get_table(db, zSql, &aResult, 0, 0, &zErr);
|
||||||
|
}else{
|
||||||
|
rc = sqlite3_get_table(db, zSql, &aResult, &nRow, &nCol, &zErr);
|
||||||
|
resCount = (nRow+1)*nCol;
|
||||||
|
}
|
||||||
sqlite3_free(zSql);
|
sqlite3_free(zSql);
|
||||||
sprintf(zBuf, "%d", rc);
|
sprintf(zBuf, "%d", rc);
|
||||||
Tcl_AppendElement(interp, zBuf);
|
Tcl_AppendElement(interp, zBuf);
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
sprintf(zBuf, "%d", nRow);
|
if( argc==4 ){
|
||||||
Tcl_AppendElement(interp, zBuf);
|
sprintf(zBuf, "%d", nRow);
|
||||||
sprintf(zBuf, "%d", nCol);
|
Tcl_AppendElement(interp, zBuf);
|
||||||
Tcl_AppendElement(interp, zBuf);
|
sprintf(zBuf, "%d", nCol);
|
||||||
for(i=0; i<(nRow+1)*nCol; i++){
|
Tcl_AppendElement(interp, zBuf);
|
||||||
|
}
|
||||||
|
for(i=0; i<resCount; i++){
|
||||||
Tcl_AppendElement(interp, aResult[i] ? aResult[i] : "NULL");
|
Tcl_AppendElement(interp, aResult[i] ? aResult[i] : "NULL");
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
# focus of this file is testing the sqlite_exec_printf() and
|
# focus of this file is testing the sqlite_exec_printf() and
|
||||||
# sqlite_get_table_printf() APIs.
|
# sqlite_get_table_printf() APIs.
|
||||||
#
|
#
|
||||||
# $Id: tableapi.test,v 1.14 2008/01/23 12:52:41 drh Exp $
|
# $Id: tableapi.test,v 1.15 2008/01/23 14:51:50 drh Exp $
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
@@ -66,6 +66,12 @@ do_test tableapi-2.3.3 {
|
|||||||
SELECT * FROM xyz WHERE a>47 ORDER BY a; invalid
|
SELECT * FROM xyz WHERE a>47 ORDER BY a; invalid
|
||||||
} {}
|
} {}
|
||||||
} {1 {near "invalid": syntax error}}
|
} {1 {near "invalid": syntax error}}
|
||||||
|
do_test tableapi-2.3.4 {
|
||||||
|
breakpoint
|
||||||
|
sqlite3_get_table_printf $::dbx {
|
||||||
|
SELECT * FROM xyz WHERE a>47 ORDER BY a
|
||||||
|
} {} 8
|
||||||
|
} {0 a b 48 (48) 49 (49) 50 (50)}
|
||||||
do_test tableapi-2.4 {
|
do_test tableapi-2.4 {
|
||||||
set manyquote ''''''''
|
set manyquote ''''''''
|
||||||
append manyquote $manyquote
|
append manyquote $manyquote
|
||||||
|
Reference in New Issue
Block a user