Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix an assert() failure that could occur in ALTER TABLE code when the schema contains a view that uses a CTE. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
75b04a4b0d2e65bfcd02cf4e0b6d8f19 |
User & Date: | dan 2019-12-04 14:26:38.017 |
Context
2019-12-04
| ||
15:08 | Ensure that an ALWAYS() in the rename logic really is always true, even for faulty inputs. (check-in: 54410f0e77 user: drh tags: trunk) | |
14:26 | Fix an assert() failure that could occur in ALTER TABLE code when the schema contains a view that uses a CTE. (check-in: 75b04a4b0d user: dan tags: trunk) | |
03:46 | Fix a buffer overread that could occur in fts3 with corrupt %_stat records. (check-in: e01fdbf9f7 user: dan tags: trunk) | |
Changes
Changes to src/alter.c.
︙ | ︙ | |||
728 729 730 731 732 733 734 735 736 737 738 739 740 741 | ** Walker callback used by sqlite3RenameExprUnmap(). */ static int renameUnmapExprCb(Walker *pWalker, Expr *pExpr){ Parse *pParse = pWalker->pParse; sqlite3RenameTokenRemap(pParse, 0, (void*)pExpr); return WRC_Continue; } /* ** Walker callback used by sqlite3RenameExprUnmap(). */ static int renameUnmapSelectCb(Walker *pWalker, Select *p){ Parse *pParse = pWalker->pParse; int i; | > > > > > > > > > > > > > > > > > > | 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 | ** Walker callback used by sqlite3RenameExprUnmap(). */ static int renameUnmapExprCb(Walker *pWalker, Expr *pExpr){ Parse *pParse = pWalker->pParse; sqlite3RenameTokenRemap(pParse, 0, (void*)pExpr); return WRC_Continue; } /* ** Iterate through the Select objects that are part of WITH clauses attached ** to select statement pSelect. */ static void renameWalkWith(Walker *pWalker, Select *pSelect){ if( pSelect->pWith ){ int i; for(i=0; i<pSelect->pWith->nCte; i++){ Select *p = pSelect->pWith->a[i].pSelect; NameContext sNC; memset(&sNC, 0, sizeof(sNC)); sNC.pParse = pWalker->pParse; sqlite3SelectPrep(sNC.pParse, p, &sNC); sqlite3WalkSelect(pWalker, p); } } } /* ** Walker callback used by sqlite3RenameExprUnmap(). */ static int renameUnmapSelectCb(Walker *pWalker, Select *p){ Parse *pParse = pWalker->pParse; int i; |
︙ | ︙ | |||
749 750 751 752 753 754 755 756 757 758 759 760 761 762 | } if( ALWAYS(p->pSrc) ){ /* Every Select as a SrcList, even if it is empty */ SrcList *pSrc = p->pSrc; for(i=0; i<pSrc->nSrc; i++){ sqlite3RenameTokenRemap(pParse, 0, (void*)pSrc->a[i].zName); } } return WRC_Continue; } /* ** Remove all nodes that are part of expression pExpr from the rename list. */ void sqlite3RenameExprUnmap(Parse *pParse, Expr *pExpr){ | > > | 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 | } if( ALWAYS(p->pSrc) ){ /* Every Select as a SrcList, even if it is empty */ SrcList *pSrc = p->pSrc; for(i=0; i<pSrc->nSrc; i++){ sqlite3RenameTokenRemap(pParse, 0, (void*)pSrc->a[i].zName); } } renameWalkWith(pWalker, p); return WRC_Continue; } /* ** Remove all nodes that are part of expression pExpr from the rename list. */ void sqlite3RenameExprUnmap(Parse *pParse, Expr *pExpr){ |
︙ | ︙ | |||
815 816 817 818 819 820 821 | pCtx->pList = pToken; pCtx->nList++; break; } } } | < < < < < < < < < < < < < < < < < < | 835 836 837 838 839 840 841 842 843 844 845 846 847 848 | pCtx->pList = pToken; pCtx->nList++; break; } } } /* ** This is a Walker select callback. It does nothing. It is only required ** because without a dummy callback, sqlite3WalkExpr() and similar do not ** descend into sub-select statements. */ static int renameColumnSelectCb(Walker *pWalker, Select *p){ renameWalkWith(pWalker, p); |
︙ | ︙ |
Changes to test/altertab3.test.
︙ | ︙ | |||
406 407 408 409 410 411 412 413 414 415 | ORDER BY b COLLATE nocase ); } {1 {1st ORDER BY term does not match any column in the result set}} do_catchsql_test 18.3 { ALTER TABLE t1 RENAME TO t1x; } {1 {error in trigger r1: 1st ORDER BY term does not match any column in the result set}} finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 | ORDER BY b COLLATE nocase ); } {1 {1st ORDER BY term does not match any column in the result set}} do_catchsql_test 18.3 { ALTER TABLE t1 RENAME TO t1x; } {1 {error in trigger r1: 1st ORDER BY term does not match any column in the result set}} #------------------------------------------------------------------------- reset_db do_execsql_test 19.0 { CREATE TABLE a(a,h CONSTRAINT a UNIQUE ON CONFLICT FAIL,CONSTRAINT a); } foreach {tn v res} { 1 { CREATE VIEW q AS SELECT 123 WINDOW x AS ( RANGE BETWEEN UNBOUNDED PRECEDING AND INDEXED() OVER( PARTITION BY ( WITH x AS(VALUES(col1)) VALUES(453) ) ) FOLLOWING ) } {1 {error in view q: no such column: col1}} 2 { CREATE VIEW q AS SELECT CAST(CAST(CAST(CAST(CAST(CAST(CAST(CAST(CAST(CAST(CAST(RIGHT AS)AS)AS)AS)AS)AS)AS)AS)AS)AS)AS)WINDOW x AS(RANGE BETWEEN UNBOUNDED PRECEDING AND INDEXED(*)OVER(PARTITION BY CROSS,CROSS,NATURAL,sqlite_master(*)OVER a,(WITH a AS(VALUES(LEFT)UNION VALUES(LEFT)UNION VALUES(LEFT)UNION VALUES(LEFT)UNION VALUES(LEFT)UNION VALUES(LEFT)UNION VALUES(LEFT))VALUES(LEFT))IN STORED,LEFT,LEFT,LEFT,LEFT,LEFT,LEFT)*LEFT FOLLOWING)ORDER BY LEFT,LEFT,LEFT,LEFT,LEFT,LEFT,LEFT,LEFT,LEFT,LEFT,LEFT LIMIT LEFT,INDEXED(*)OVER(PARTITION BY CROSS,CROSS,CROSS,LEFT,INDEXED(*)OVER(PARTITION BY CROSS,CROSS,CROSS),INDEXED(*)OVER(PARTITION BY LEFT,LEFT,LEFT,LEFT,LEFT,LEFT,LEFT,LEFT,LEFT,LEFT,LEFT), LEFT,LEFT,INNER,CROSS,CROSS,CROSS,INNER,NATURAL ORDER BY OUTER,NATURAL,NATURAL,NATURAL,NATURAL,NATURAL,NATURAL,NATURAL,INNER, INNER,INNER NULLS LAST GROUPS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING); } {1 {error in view q: no such column: LEFT}} 3 { CREATE VIEW q AS SELECT 99 WINDOW x AS (RANGE BETWEEN UNBOUNDED PRECEDING AND count(*)OVER(PARTITION BY (WITH a AS(VALUES(2),(x3))VALUES(0))) FOLLOWING)ORDER BY x2,sum(1)OVER(PARTITION BY avg(5)OVER(PARTITION BY x1)); } {1 {error in view q: no such column: x3}} } { do_execsql_test 19.$tn.1 " DROP VIEW IF EXISTS q; $v " {} do_catchsql_test 19.$tn.2 { ALTER TABLE a RENAME TO g; } $res } finish_test |