Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | In the query flattener, defer deleting content until after associated Parse object is destroyed, in case some of the deleted expressions have been collected for use by sAggInfo. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | early-winfunc-rewrite-dev |
Files: | files | file ages | folders |
SHA3-256: |
03b32be44d9d278397d50c9a8d7aad7c |
User & Date: | drh 2020-06-06 18:34:12 |
Context
2020-06-06
| ||
20:48 | Merge multiple changes from trunk to address concerns with window-function parse-tree rewriting. (check-in: 05418b2a user: drh tags: branch-3.32-early-winfunc-rewrite) | |
18:45 | Clearly distinguish between window functions and scalar functions in the debugging TreeView output. (check-in: 15babdcb user: drh tags: early-winfunc-rewrite-dev) | |
18:34 | In the query flattener, defer deleting content until after associated Parse object is destroyed, in case some of the deleted expressions have been collected for use by sAggInfo. (check-in: 03b32be4 user: drh tags: early-winfunc-rewrite-dev) | |
14:58 | Remove an incorrect assert() added earlier today. (check-in: 3926ff17 user: drh tags: early-winfunc-rewrite-dev) | |
Changes
Changes to src/build.c.
︙ | ︙ | |||
208 209 210 211 212 213 214 | sqlite3AutoincrementBegin(pParse); /* Code constant expressions that where factored out of inner loops */ if( pParse->pConstExpr ){ ExprList *pEL = pParse->pConstExpr; pParse->okConstFactor = 0; for(i=0; i<pEL->nExpr; i++){ | > > | > | 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 | sqlite3AutoincrementBegin(pParse); /* Code constant expressions that where factored out of inner loops */ if( pParse->pConstExpr ){ ExprList *pEL = pParse->pConstExpr; pParse->okConstFactor = 0; for(i=0; i<pEL->nExpr; i++){ int iReg = pEL->a[i].u.iConstExprReg; if( iReg>0 ){ sqlite3ExprCode(pParse, pEL->a[i].pExpr, iReg); } } } /* Finally, jump back to the beginning of the executable code. */ sqlite3VdbeGoto(v, 1); } } |
︙ | ︙ |
Changes to src/select.c.
︙ | ︙ | |||
163 164 165 166 167 168 169 | pAllocated = 0; }else{ assert( pNew->pSrc!=0 || pParse->nErr>0 ); } return pAllocated; } | < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 | pAllocated = 0; }else{ assert( pNew->pSrc!=0 || pParse->nErr>0 ); } return pAllocated; } /* ** Delete the given Select structure and all of its substructures. */ void sqlite3SelectDelete(sqlite3 *db, Select *p){ if( OK_IF_ALWAYS_TRUE(p) ) clearSelect(db, p, 1); } /* ** Make arrangements to delete a subquery when the Parse object is ** destroyed. ** ** This works by adding the subquery to the Parse.pConstExpr list, but ** with a register number of zero. The pConstExpr list is destroyed ** when the Parse object is destroyed. And the zero register means ** that the expression is not coded. */ void sqlite3SelectDeferredDelete(Parse *pParse, Select *p){ Expr *pNew = sqlite3PExpr(pParse, TK_SELECT, 0, 0); if( pNew==0 ){ clearSelect(pParse->db, p, 1); }else{ sqlite3PExprAddSelect(pParse, pNew, p); pParse->pConstExpr = sqlite3ExprListAppend(pParse, pParse->pConstExpr, pNew); testcase( pParse->pConstExpr==0 ); /* Only true following OOM */ #ifdef SQLITE_DEBUG if( pParse->pConstExpr ){ ExprList *p = pParse->pConstExpr; struct ExprList_item *pItem = &p->a[p->nExpr-1]; assert( pItem->reusable==0 ); assert( pItem->u.iConstExprReg==0 ); } #endif } } /* ** Delete all the substructure for p, but keep p allocated. Redefine ** p to be a single SELECT where every column of the result set has a ** value of NULL. */ void sqlite3SelectReset(Parse *pParse, Select *p){ |
︙ | ︙ | |||
4147 4148 4149 4150 4151 4152 4153 | recomputeColumnsUsed(pParent, &pSrc->a[i+iFrom]); } } /* Finially, delete what is left of the subquery and return ** success. */ | | | 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 | recomputeColumnsUsed(pParent, &pSrc->a[i+iFrom]); } } /* Finially, delete what is left of the subquery and return ** success. */ sqlite3SelectDeferredDelete(pParse, pSub1); #if SELECTTRACE_ENABLED if( sqlite3SelectTrace & 0x100 ){ SELECTTRACE(0x100,pParse,p,("After flattening:\n")); sqlite3TreeViewSelect(0, p, 0); } #endif |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 | void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*, Expr*, int, int, u8); void sqlite3DropIndex(Parse*, SrcList*, int); int sqlite3Select(Parse*, Select*, SelectDest*); Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*, Expr*,ExprList*,u32,Expr*); void sqlite3SelectDelete(sqlite3*, Select*); void sqlite3SelectReset(Parse*, Select*); Table *sqlite3SrcListLookup(Parse*, SrcList*); int sqlite3IsReadOnly(Parse*, Table*, int); void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int); #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,char*); #endif | > | 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 | void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*, Expr*, int, int, u8); void sqlite3DropIndex(Parse*, SrcList*, int); int sqlite3Select(Parse*, Select*, SelectDest*); Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*, Expr*,ExprList*,u32,Expr*); void sqlite3SelectDelete(sqlite3*, Select*); void sqlite3SelectDeferredDelete(Parse*, Select*); void sqlite3SelectReset(Parse*, Select*); Table *sqlite3SrcListLookup(Parse*, SrcList*); int sqlite3IsReadOnly(Parse*, Table*, int); void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int); #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,char*); #endif |
︙ | ︙ |
Changes to test/window1.test.
︙ | ︙ | |||
1832 1833 1834 1835 1836 1837 1838 1839 1840 | FROM t1; } {{} {} 0} do_execsql_test 57.2 { CREATE TABLE v0 ( v1 INTEGER PRIMARY KEY ) ; INSERT INTO v0 VALUES ( 10 ) ; SELECT DISTINCT v1, lead(v1) OVER() FROM v0 GROUP BY v1 ORDER BY 2; } {10 {}} finish_test | > > > > > > > > > > > | 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 | FROM t1; } {{} {} 0} do_execsql_test 57.2 { CREATE TABLE v0 ( v1 INTEGER PRIMARY KEY ) ; INSERT INTO v0 VALUES ( 10 ) ; SELECT DISTINCT v1, lead(v1) OVER() FROM v0 GROUP BY v1 ORDER BY 2; } {10 {}} do_execsql_test 57.3 { DROP TABLE t1; CREATE TABLE t1(a); INSERT INTO t1(a) VALUES(22); CREATE TABLE t3(y); INSERT INTO t3(y) VALUES(5),(11),(-9); SELECT ( SELECT max(y) OVER( ORDER BY (SELECT x FROM (SELECT sum(y) AS x FROM t1))) ) FROM t3; } {5} finish_test |