Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Ensure that the window function rewrite does not leave the parse tree in an invalid state that might cause problems downstream before the error is recognized and unwinds the stack. Also take steps such that an invalid parse tree does not cause problems even if it goes unrecognized. Forum post 398e9d5aa9. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
0f9fc6b6073365d5159cd71e7fe08f8d |
User & Date: | drh 2021-11-07 23:33:01 |
Context
2021-11-08
| ||
16:38 | Add assert()s that verify that cursor numbers on subqueries are always greater than outer cursor numbers. Except, this is not always true in the presence of query flattening. We might need to relax that constraint. This branch will probably become a dead-end. For now it is saved for reference. (Closed-Leaf check-in: 6f436966 user: drh tags: well-ordered-cursors) | |
15:46 | Fix an assert() in memdbTruncate() that could fail when processing a corrupt database. (check-in: b1e29298 user: dan tags: trunk) | |
2021-11-07
| ||
23:33 | Ensure that the window function rewrite does not leave the parse tree in an invalid state that might cause problems downstream before the error is recognized and unwinds the stack. Also take steps such that an invalid parse tree does not cause problems even if it goes unrecognized. Forum post 398e9d5aa9. (check-in: 0f9fc6b6 user: drh tags: trunk) | |
2021-11-06
| ||
20:25 | Add ALWAYS() to a branch made unreachable by the previous check-in. (check-in: 0dc963f6 user: drh tags: trunk) | |
Changes
Changes to src/expr.c.
︙ | ︙ | |||
18 19 20 21 22 23 24 | static void exprCodeBetween(Parse*,Expr*,int,void(*)(Parse*,Expr*,int,int),int); static int exprCodeVector(Parse *pParse, Expr *p, int *piToFree); /* ** Return the affinity character for a single column of a table. */ char sqlite3TableColumnAffinity(const Table *pTab, int iCol){ | | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | static void exprCodeBetween(Parse*,Expr*,int,void(*)(Parse*,Expr*,int,int),int); static int exprCodeVector(Parse *pParse, Expr *p, int *piToFree); /* ** Return the affinity character for a single column of a table. */ char sqlite3TableColumnAffinity(const Table *pTab, int iCol){ if( iCol<0 || NEVER(iCol>=pTab->nCol) ) return SQLITE_AFF_INTEGER; return pTab->aCol[iCol].affinity; } /* ** Return the 'affinity' of the expression pExpr if any. ** ** If pExpr is a column, a reference to a column via an 'AS' alias, ** or a sub-select with a column as the return value, then the |
︙ | ︙ |
Changes to src/where.c.
︙ | ︙ | |||
5361 5362 5363 5364 5365 5366 5367 5368 5369 5370 5371 5372 5373 5374 | /* Generate the code to do the search. Each iteration of the for ** loop below generates code for a single nested loop of the VM ** program. */ for(ii=0; ii<nTabList; ii++){ int addrExplain; int wsFlags; pLevel = &pWInfo->a[ii]; wsFlags = pLevel->pWLoop->wsFlags; #ifndef SQLITE_OMIT_AUTOMATIC_INDEX if( (pLevel->pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 ){ constructAutomaticIndex(pParse, &pWInfo->sWC, &pTabList->a[pLevel->iFrom], notReady, pLevel); if( db->mallocFailed ) goto whereBeginError; | > | 5361 5362 5363 5364 5365 5366 5367 5368 5369 5370 5371 5372 5373 5374 5375 | /* Generate the code to do the search. Each iteration of the for ** loop below generates code for a single nested loop of the VM ** program. */ for(ii=0; ii<nTabList; ii++){ int addrExplain; int wsFlags; if( pParse->nErr ) goto whereBeginError; pLevel = &pWInfo->a[ii]; wsFlags = pLevel->pWLoop->wsFlags; #ifndef SQLITE_OMIT_AUTOMATIC_INDEX if( (pLevel->pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 ){ constructAutomaticIndex(pParse, &pWInfo->sWC, &pTabList->a[pLevel->iFrom], notReady, pLevel); if( db->mallocFailed ) goto whereBeginError; |
︙ | ︙ |
Changes to src/window.c.
︙ | ︙ | |||
1095 1096 1097 1098 1099 1100 1101 | w.xSelectCallback2 = sqlite3WalkerDepthDecrease; sqlite3WalkSelect(&w, pSub); } }else{ sqlite3SelectDelete(db, pSub); } if( db->mallocFailed ) rc = SQLITE_NOMEM; | | > > > > | 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 | w.xSelectCallback2 = sqlite3WalkerDepthDecrease; sqlite3WalkSelect(&w, pSub); } }else{ sqlite3SelectDelete(db, pSub); } if( db->mallocFailed ) rc = SQLITE_NOMEM; /* Defer deleting the temporary table pTab because if an error occurred, ** there could still be references to that table embedded in the ** result-set or ORDER BY clause of the SELECT statement p. */ sqlite3ParserAddCleanup(pParse, sqlite3DbFree, pTab); } if( rc ){ if( pParse->nErr==0 ){ assert( pParse->db->mallocFailed ); sqlite3ErrorToParser(pParse->db, SQLITE_NOMEM); } |
︙ | ︙ |
Changes to test/window1.test.
︙ | ︙ | |||
2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 | } do_execsql_test 70.1 { SELECT substr(a,4,lag(a,7) OVER(PARTITION BY 'cf23' ORDER BY 2)) AS ca0 FROM t1 ORDER BY ca0; } do_execsql_test 70.2 { SELECT substr(a,4,lag(a,7) OVER(PARTITION BY 'cf23' ORDER BY likely(2))) AS ca0 FROM t1 ORDER BY ca0; } finish_test | > > > > > > > > > > > > | 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 | } do_execsql_test 70.1 { SELECT substr(a,4,lag(a,7) OVER(PARTITION BY 'cf23' ORDER BY 2)) AS ca0 FROM t1 ORDER BY ca0; } do_execsql_test 70.2 { SELECT substr(a,4,lag(a,7) OVER(PARTITION BY 'cf23' ORDER BY likely(2))) AS ca0 FROM t1 ORDER BY ca0; } # 2021-11-07 # Bug report from Wang Ke # https://sqlite.org/forum/forumpost/9ba4f60ff8 reset_db do_catchsql_test 71.0 { CREATE TABLE t0(a); SELECT a FROM t0, (SELECT a AS b FROM t0) WHERE (a,1)=(SELECT 2,2 UNION SELECT sum(b),max(b) OVER(ORDER BY b) ORDER BY 2) AND b=4 ORDER BY b; } {/1 {.*}/} finish_test |