mirror of
https://github.com/sqlite/sqlite.git
synced 2025-04-26 11:28:58 +03:00
A list of arguments following a table name translates into equality
constraints against hidden columns in that table. FossilOrigin-Name: 40e12cfe4c29475417ba89fb637b4c763cf74016
This commit is contained in:
parent
8a48b9c0b1
commit
01d230ce05
30
manifest
30
manifest
@ -1,5 +1,5 @@
|
||||
C Minor\srefactor\sof\sthe\sSrcList\sobject\sso\sthat\sit\sis\sable\sto\shold\sthe\sargument\nlist\sto\sa\stable-valued-function\sin\sthe\sFROM\sclause.
|
||||
D 2015-08-19T15:20:00.817
|
||||
C A\slist\sof\sarguments\sfollowing\sa\stable\sname\stranslates\sinto\sequality\nconstraints\sagainst\shidden\scolumns\sin\sthat\stable.
|
||||
D 2015-08-19T17:11:37.512
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in 4f663b6b4954b9b1eb0e6f08387688a93b57542d
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
@ -281,7 +281,7 @@ F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79
|
||||
F src/btree.c f48b3ef91676c06a90a8832987ecef6b94c931ee
|
||||
F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1
|
||||
F src/btreeInt.h 8177c9ab90d772d6d2c6c517e05bed774b7c92c0
|
||||
F src/build.c 909416959d8948a436d86461ffacdb3b19ec8286
|
||||
F src/build.c 16051071cd855c23e47b087b49ac99c65b1d8c39
|
||||
F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0
|
||||
F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f
|
||||
F src/ctime.c 5a0b735dc95604766f5dac73973658eef782ee8b
|
||||
@ -325,7 +325,7 @@ F src/os_win.c 40b3af7a47eb1107d0d69e592bec345a3b7b798a
|
||||
F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
|
||||
F src/pager.c aa916ca28606ccf4b6877dfc2b643ccbca86589f
|
||||
F src/pager.h 6d435f563b3f7fcae4b84433b76a6ac2730036e2
|
||||
F src/parse.y 2ed6efe32ec400c765fec5f3253c650ffdfeb65b
|
||||
F src/parse.y ad9af8552f6f340bd646577ca63356a6f82b6a7e
|
||||
F src/pcache.c cde06aa50962595e412d497e22fd2e07878ba1f0
|
||||
F src/pcache.h 9968603796240cdf83da7e7bef76edf90619cea9
|
||||
F src/pcache1.c d08939800abf3031bd0affd5a13fbc4d7ba3fb68
|
||||
@ -334,14 +334,14 @@ F src/pragma.h 631a91c8b0e6ca8f051a1d8a4a0da4150e04620a
|
||||
F src/prepare.c 82e5db1013846a819f198336fed72c44c974e7b1
|
||||
F src/printf.c 2bc439ff20a4aad0e0ad50a37a67b5eae7d20edc
|
||||
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
|
||||
F src/resolve.c cd1c44c853c3560b3fa85637f732a9b7fc0e9295
|
||||
F src/resolve.c bbb4874decae6e60eee0395a31205d3b55cd2c00
|
||||
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
|
||||
F src/select.c c46de38c1b66355f02a839bb72eb13f277e6d19c
|
||||
F src/shell.c b1f91e60918df3a68efad1e3a11696b9a7e23d23
|
||||
F src/sqlite.h.in 447ead0a6b3293206f04a0896553955d07cfb4b9
|
||||
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
|
||||
F src/sqlite3ext.h a0b948ebc89bac13941254641326a6aa248c2cc4
|
||||
F src/sqliteInt.h 9fae37f6bcc2f9ed71fe0362972c263642326914
|
||||
F src/sqliteInt.h 89e68539d645db597366a91411468b51e73c21a0
|
||||
F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
|
||||
F src/status.c f266ad8a2892d659b74f0f50cb6a88b6e7c12179
|
||||
F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e
|
||||
@ -393,7 +393,7 @@ F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698
|
||||
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
||||
F src/threads.c 6bbcc9fe50c917864d48287b4792d46d6e873481
|
||||
F src/tokenize.c 57cb3720f53f84d811def2069c2b169b6be539a5
|
||||
F src/treeview.c fda5cfc4635d4a436214c4593f3032d07688a0e2
|
||||
F src/treeview.c c15df00728034549ff92d78ae851b44952736d3b
|
||||
F src/trigger.c 322f23aad694e8f31d384dcfa386d52a48d3c52f
|
||||
F src/update.c 487747b328b7216bb7f6af0695d6937d5c9e605f
|
||||
F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c
|
||||
@ -412,11 +412,11 @@ F src/vtab.c 1e3405f78e9f248bdee6ef7a8903fadaa7222f9c
|
||||
F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb
|
||||
F src/wal.c 6fb6b68969e4692593c2552c4e7bff5882de2cb8
|
||||
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
||||
F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804
|
||||
F src/where.c a572b23993febb7bb72ee997c55da3b03d870be8
|
||||
F src/whereInt.h 5f87e3c4b0551747d119730dfebddd3c54f04047
|
||||
F src/walker.c 2e14d17f592d176b6dc879c33fbdec4fbccaa2ba
|
||||
F src/where.c 66518a14a1238611aa0744d6980b6b7f544f4816
|
||||
F src/whereInt.h 880a8599226ac1c00203490d934f3ed79b292572
|
||||
F src/wherecode.c 69f19535a6de0cceb10e16b31a3a03463e31bc24
|
||||
F src/whereexpr.c 9ce1c9cfedbf80c93c7d899497025ec8256ce652
|
||||
F src/whereexpr.c 6332ade8f72beebb6438734e92757da4631176e0
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
|
||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||
@ -1031,7 +1031,7 @@ F test/superlock.test 1cde669f68d2dd37d6c9bd35eee1d95491ae3fc2
|
||||
F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85
|
||||
F test/syscall.test d2fdaad713f103ac611fe7ef9b724c7b69f8149c
|
||||
F test/sysfault.test fa776e60bf46bdd3ae69f0b73e46ee3977a58ae6
|
||||
F test/tabfunc01.test 0c1fb6ee8eba49c13b8a4c35b8f0726397debb33
|
||||
F test/tabfunc01.test ca013d7012764f85185d0d1b77f158a7b1b3ad6d
|
||||
F test/table.test 33bf0d1fd07f304582695184b8e6feb017303816
|
||||
F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126
|
||||
F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930
|
||||
@ -1376,7 +1376,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P c58426dbd5ea8b8440ebcc1214f79fa63d658216
|
||||
R 8f19410a9a93222f2a2f5ce9faa04ea9
|
||||
P b919376147597c4b73421abe5788f893baf1560b
|
||||
R 03d0a3c413d15fc0179aae3fc23d1837
|
||||
U drh
|
||||
Z 28752308589cee1f3c6d24275593910d
|
||||
Z 86fabb010e68498602162c53cf0d6cc5
|
||||
|
@ -1 +1 @@
|
||||
b919376147597c4b73421abe5788f893baf1560b
|
||||
40e12cfe4c29475417ba89fb637b4c763cf74016
|
15
src/build.c
15
src/build.c
@ -3797,6 +3797,21 @@ void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pIndexedBy){
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Add the list of function arguments to the SrcList entry for a
|
||||
** table-valued-function.
|
||||
*/
|
||||
void sqlite3SrcListFuncArgs(Parse *pParse, SrcList *p, ExprList *pList){
|
||||
if( p && ALWAYS(p->nSrc>0) ){
|
||||
struct SrcList_item *pItem = &p->a[p->nSrc-1];
|
||||
assert( pItem->fg.notIndexed==0 );
|
||||
assert( pItem->fg.isIndexedBy==0 );
|
||||
assert( pItem->fg.isTabFunc==0 );
|
||||
pItem->u1.pFuncArg = pList;
|
||||
pItem->fg.isTabFunc = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** When building up a FROM clause in the parser, the join operator
|
||||
** is initially attached to the left operand. But the code generator
|
||||
|
@ -594,6 +594,11 @@ seltablist(A) ::= stl_prefix(X) nm(Y) dbnm(D) as(Z) indexed_opt(I)
|
||||
A = sqlite3SrcListAppendFromTerm(pParse,X,&Y,&D,&Z,0,N,U);
|
||||
sqlite3SrcListIndexedBy(pParse, A, &I);
|
||||
}
|
||||
seltablist(A) ::= stl_prefix(X) nm(Y) dbnm(D) LP exprlist(E) RP as(Z)
|
||||
on_opt(N) using_opt(U). {
|
||||
A = sqlite3SrcListAppendFromTerm(pParse,X,&Y,&D,&Z,0,N,U);
|
||||
sqlite3SrcListFuncArgs(pParse, A, E);
|
||||
}
|
||||
%ifndef SQLITE_OMIT_SUBQUERY
|
||||
seltablist(A) ::= stl_prefix(X) LP select(S) RP
|
||||
as(Z) on_opt(N) using_opt(U). {
|
||||
|
@ -1142,7 +1142,6 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
|
||||
int isCompound; /* True if p is a compound select */
|
||||
int nCompound; /* Number of compound terms processed so far */
|
||||
Parse *pParse; /* Parsing context */
|
||||
ExprList *pEList; /* Result set expression list */
|
||||
int i; /* Loop counter */
|
||||
ExprList *pGroupBy; /* The GROUP BY clause */
|
||||
Select *pLeftmost; /* Left-most of SELECT of a compound */
|
||||
@ -1237,14 +1236,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
|
||||
sNC.pNext = pOuterNC;
|
||||
|
||||
/* Resolve names in the result set. */
|
||||
pEList = p->pEList;
|
||||
assert( pEList!=0 );
|
||||
for(i=0; i<pEList->nExpr; i++){
|
||||
Expr *pX = pEList->a[i].pExpr;
|
||||
if( sqlite3ResolveExprNames(&sNC, pX) ){
|
||||
return WRC_Abort;
|
||||
}
|
||||
}
|
||||
if( sqlite3ResolveExprListNames(&sNC, p->pEList) ) return WRC_Abort;
|
||||
|
||||
/* If there are no aggregate functions in the result-set, and no GROUP BY
|
||||
** expression, do not allow aggregates in any of the other expressions.
|
||||
@ -1277,6 +1269,16 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
|
||||
if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort;
|
||||
if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort;
|
||||
|
||||
/* Resolve names in table-valued-function arguments */
|
||||
for(i=0; i<p->pSrc->nSrc; i++){
|
||||
struct SrcList_item *pItem = &p->pSrc->a[i];
|
||||
if( pItem->fg.isTabFunc
|
||||
&& sqlite3ResolveExprListNames(&sNC, pItem->u1.pFuncArg)
|
||||
){
|
||||
return WRC_Abort;
|
||||
}
|
||||
}
|
||||
|
||||
/* The ORDER BY and GROUP BY clauses may not refer to terms in
|
||||
** outer queries
|
||||
*/
|
||||
@ -1440,6 +1442,21 @@ int sqlite3ResolveExprNames(
|
||||
return ExprHasProperty(pExpr, EP_Error);
|
||||
}
|
||||
|
||||
/*
|
||||
** Resolve all names for all expression in an expression list. This is
|
||||
** just like sqlite3ResolveExprNames() except that it works for an expression
|
||||
** list rather than a single expression.
|
||||
*/
|
||||
int sqlite3ResolveExprListNames(
|
||||
NameContext *pNC, /* Namespace to resolve expressions in. */
|
||||
ExprList *pList /* The expression list to be analyzed. */
|
||||
){
|
||||
int i;
|
||||
for(i=0; i<pList->nExpr; i++){
|
||||
if( sqlite3ResolveExprNames(pNC, pList->a[i].pExpr) ) return WRC_Abort;
|
||||
}
|
||||
return WRC_Continue;
|
||||
}
|
||||
|
||||
/*
|
||||
** Resolve all names in all expressions of a SELECT and in all
|
||||
|
@ -3328,6 +3328,7 @@ SrcList *sqlite3SrcListAppend(sqlite3*, SrcList*, Token*, Token*);
|
||||
SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*,
|
||||
Token*, Select*, Expr*, IdList*);
|
||||
void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *);
|
||||
void sqlite3SrcListFuncArgs(Parse*, SrcList*, ExprList*);
|
||||
int sqlite3IndexedByLookup(Parse *, struct SrcList_item *);
|
||||
void sqlite3SrcListShiftJoinType(SrcList*);
|
||||
void sqlite3SrcListAssignCursors(Parse*, SrcList*);
|
||||
@ -3619,6 +3620,7 @@ void sqlite3SelectPrep(Parse*, Select*, NameContext*);
|
||||
void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p);
|
||||
int sqlite3MatchSpanName(const char*, const char*, const char*, const char*);
|
||||
int sqlite3ResolveExprNames(NameContext*, Expr*);
|
||||
int sqlite3ResolveExprListNames(NameContext*, ExprList*);
|
||||
void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
|
||||
void sqlite3ResolveSelfReference(Parse*,Table*,int,Expr*,ExprList*);
|
||||
int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
|
||||
|
@ -128,6 +128,9 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
|
||||
if( pItem->pSelect ){
|
||||
sqlite3TreeViewSelect(pView, pItem->pSelect, 0);
|
||||
}
|
||||
if( pItem->fg.isTabFunc ){
|
||||
sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:");
|
||||
}
|
||||
sqlite3TreeViewPop(pView);
|
||||
}
|
||||
sqlite3TreeViewPop(pView);
|
||||
|
@ -105,6 +105,11 @@ int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){
|
||||
if( sqlite3WalkSelect(pWalker, pItem->pSelect) ){
|
||||
return WRC_Abort;
|
||||
}
|
||||
if( pItem->fg.isTabFunc
|
||||
&& sqlite3WalkExprList(pWalker, pItem->u1.pFuncArg)
|
||||
){
|
||||
return WRC_Abort;
|
||||
}
|
||||
}
|
||||
}
|
||||
return WRC_Continue;
|
||||
|
@ -4030,6 +4030,7 @@ WhereInfo *sqlite3WhereBegin(
|
||||
*/
|
||||
for(ii=0; ii<pTabList->nSrc; ii++){
|
||||
createMask(pMaskSet, pTabList->a[ii].iCursor);
|
||||
sqlite3WhereTabFuncArgs(pParse, &pTabList->a[ii], &pWInfo->sWC);
|
||||
}
|
||||
#ifndef NDEBUG
|
||||
{
|
||||
|
@ -475,6 +475,7 @@ void sqlite3WhereSplit(WhereClause*,Expr*,u8);
|
||||
Bitmask sqlite3WhereExprUsage(WhereMaskSet*, Expr*);
|
||||
Bitmask sqlite3WhereExprListUsage(WhereMaskSet*, ExprList*);
|
||||
void sqlite3WhereExprAnalyze(SrcList*, WhereClause*);
|
||||
void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereClause*);
|
||||
|
||||
|
||||
|
||||
|
@ -1247,3 +1247,42 @@ void sqlite3WhereExprAnalyze(
|
||||
exprAnalyze(pTabList, pWC, i);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** For table-valued-functions, transform the function arguments into
|
||||
** new WHERE clause terms.
|
||||
**
|
||||
** Each function argument translates into an equality constraint against
|
||||
** a HIDDEN column in the table.
|
||||
*/
|
||||
void sqlite3WhereTabFuncArgs(
|
||||
Parse *pParse, /* Parsing context */
|
||||
struct SrcList_item *pItem, /* The FROM clause term to process */
|
||||
WhereClause *pWC /* Xfer function arguments to here */
|
||||
){
|
||||
Table *pTab;
|
||||
int j, k;
|
||||
ExprList *pArgs;
|
||||
Expr *pColRef;
|
||||
Expr *pTerm;
|
||||
if( pItem->fg.isTabFunc==0 ) return;
|
||||
pTab = pItem->pTab;
|
||||
assert( pTab!=0 );
|
||||
pArgs = pItem->u1.pFuncArg;
|
||||
assert( pArgs!=0 );
|
||||
for(j=k=0; j<pArgs->nExpr; j++){
|
||||
while( k<pTab->nCol && (pTab->aCol[k].colFlags & COLFLAG_HIDDEN)==0 ){ k++; }
|
||||
if( k>=pTab->nCol ){
|
||||
sqlite3ErrorMsg(pParse, "too many arguments on %s - max %d",
|
||||
pTab->zName, j);
|
||||
return;
|
||||
}
|
||||
pColRef = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0);
|
||||
if( pColRef==0 ) return;
|
||||
pColRef->iTable = pItem->iCursor;
|
||||
pColRef->iColumn = k++;
|
||||
pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef,
|
||||
sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0);
|
||||
whereClauseInsert(pWC, pTerm, TERM_DYNAMIC);
|
||||
}
|
||||
}
|
||||
|
@ -32,5 +32,24 @@ do_execsql_test tabfunc01-1.2 {
|
||||
do_catchsql_test tabfunc01-1.3 {
|
||||
CREATE VIRTUAL TABLE t1 USING generate_series;
|
||||
} {1 {no such module: generate_series}}
|
||||
do_execsql_test tabfunc01-1.4 {
|
||||
SELECT * FROM generate_series(1,9,2);
|
||||
} {1 3 5 7 9}
|
||||
do_execsql_test tabfunc01-1.5 {
|
||||
SELECT * FROM generate_series(1,9);
|
||||
} {1 2 3 4 5 6 7 8 9}
|
||||
do_execsql_test tabfunc01-1.6 {
|
||||
SELECT * FROM generate_series(1,10) WHERE step=3;
|
||||
} {1 4 7 10}
|
||||
do_catchsql_test tabfunc01-1.7 {
|
||||
SELECT * FROM generate_series(1,9,2,11);
|
||||
} {1 {too many arguments on generate_series - max 3}}
|
||||
|
||||
do_execsql_test tabfunc01-2.1 {
|
||||
CREATE TABLE t1(x);
|
||||
INSERT INTO t1(x) VALUES(2),(3);
|
||||
SELECT *, '|' FROM t1, generate_series(1,x) ORDER BY 1, 2
|
||||
|
||||
} {2 1 | 2 2 | 3 1 | 3 2 | 3 3 |}
|
||||
|
||||
finish_test
|
||||
|
Loading…
x
Reference in New Issue
Block a user