Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix the sqlite3ExprDup() routine so that it makes complete duplications of subqueries containing window functions. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | ticket-f09fcd17810f |
Files: | files | file ages | folders |
SHA3-256: |
940174543e87184a0278fcd02e8a096a |
User & Date: | drh 2018-12-06 22:04:19.327 |
Context
2018-12-06
| ||
22:12 | Performance improvement: Avoid using sqlite3WalkerSelectExpr() and sqlite3WalkerSelectFrom() twice, so that the compiler will in-line their implementation. (Closed-Leaf check-in: 2b9258b8b0 user: drh tags: ticket-f09fcd17810f) | |
22:04 | Fix the sqlite3ExprDup() routine so that it makes complete duplications of subqueries containing window functions. (check-in: 940174543e user: drh tags: ticket-f09fcd17810f) | |
19:56 | New test case that still hits an assertion fault, just to prove that the previous checkin merely made the problem more obscure and did not completely fix it. (check-in: a9a3b53264 user: drh tags: ticket-f09fcd17810f) | |
Changes
Changes to src/expr.c.
︙ | ︙ | |||
1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 | } } return pRet; } #else # define withDup(x,y) 0 #endif /* ** The following group of routines make deep copies of expressions, ** expression lists, ID lists, and select statements. The copies can ** be deleted (by being passed to their respective ...Delete() routines) ** without effecting the originals. ** | > > > > > > > > > > > > > > > > > > > > > > > > > > | 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 | } } return pRet; } #else # define withDup(x,y) 0 #endif #ifndef SQLITE_OMIT_WINDOWFUNC /* ** The gatherSelectWindows() procedure and its helper routine ** gatherSelectWindowsCallback() are used to scan all the expressions ** an a newly duplicated SELECT statement and gather all of the Window ** objects found there, assembling them onto the linked list at Select->pWin. */ static int gatherSelectWindowsCallback(Walker *pWalker, Expr *pExpr){ if( pExpr->op==TK_FUNCTION && pExpr->y.pWin!=0 ){ assert( ExprHasProperty(pExpr, EP_WinFunc) ); pExpr->y.pWin->pNextWin = pWalker->u.pSelect->pWin; pWalker->u.pSelect->pWin = pExpr->y.pWin; } return WRC_Continue; } static void gatherSelectWindows(Select *p){ Walker w; w.xExprCallback = gatherSelectWindowsCallback; w.xSelectCallback = 0; w.u.pSelect = p; sqlite3WalkSelectExpr(&w, p); sqlite3WalkSelectFrom(&w, p); } #endif /* ** The following group of routines make deep copies of expressions, ** expression lists, ID lists, and select statements. The copies can ** be deleted (by being passed to their respective ...Delete() routines) ** without effecting the originals. ** |
︙ | ︙ | |||
1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 | pNew->addrOpenEphm[0] = -1; pNew->addrOpenEphm[1] = -1; pNew->nSelectRow = p->nSelectRow; pNew->pWith = withDup(db, p->pWith); #ifndef SQLITE_OMIT_WINDOWFUNC pNew->pWin = 0; pNew->pWinDefn = sqlite3WindowListDup(db, p->pWinDefn); #endif pNew->selId = p->selId; *pp = pNew; pp = &pNew->pPrior; pNext = pNew; } | > | 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 | pNew->addrOpenEphm[0] = -1; pNew->addrOpenEphm[1] = -1; pNew->nSelectRow = p->nSelectRow; pNew->pWith = withDup(db, p->pWith); #ifndef SQLITE_OMIT_WINDOWFUNC pNew->pWin = 0; pNew->pWinDefn = sqlite3WindowListDup(db, p->pWinDefn); if( p->pWin ) gatherSelectWindows(pNew); #endif pNew->selId = p->selId; *pp = pNew; pp = &pNew->pPrior; pNext = pNew; } |
︙ | ︙ |
Changes to src/window.c.
︙ | ︙ | |||
2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 | Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){ Window *pNew = 0; if( ALWAYS(p) ){ pNew = sqlite3DbMallocZero(db, sizeof(Window)); if( pNew ){ pNew->zName = sqlite3DbStrDup(db, p->zName); pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0); pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0); pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0); pNew->eType = p->eType; pNew->eEnd = p->eEnd; pNew->eStart = p->eStart; pNew->pStart = sqlite3ExprDup(db, p->pStart, 0); pNew->pEnd = sqlite3ExprDup(db, p->pEnd, 0); | > | 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 | Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){ Window *pNew = 0; if( ALWAYS(p) ){ pNew = sqlite3DbMallocZero(db, sizeof(Window)); if( pNew ){ pNew->zName = sqlite3DbStrDup(db, p->zName); pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0); pNew->pFunc = p->pFunc; pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0); pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0); pNew->eType = p->eType; pNew->eEnd = p->eEnd; pNew->eStart = p->eStart; pNew->pStart = sqlite3ExprDup(db, p->pStart, 0); pNew->pEnd = sqlite3ExprDup(db, p->pEnd, 0); |
︙ | ︙ |