Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Move the test for an (illegal) scalar sub-query that returns more than one column to earlier in SELECT processing in order to avoid an assert() that can happen later on. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
a55842cfb56b659c88832dce9ce7bafb |
User & Date: | dan 2010-09-02 19:01:16.000 |
Context
2010-09-03
| ||
03:32 | Fix a discrepancy between the documented behavior of SQLITE_DBCONFIG_LOOKASIDE and what it actually does. Also add evidence marks on the DBCONFIG_LOOKASIDE implementation. (check-in: f483be4413 user: drh tags: trunk) | |
2010-09-02
| ||
19:01 | Move the test for an (illegal) scalar sub-query that returns more than one column to earlier in SELECT processing in order to avoid an assert() that can happen later on. (check-in: a55842cfb5 user: dan tags: trunk) | |
18:13 | Fix an off-by-one error in the scratch memory allocator. (check-in: 5a9591607a user: drh tags: trunk) | |
Changes
Changes to src/select.c.
︙ | ︙ | |||
3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 | isAgg = (p->selFlags & SF_Aggregate)!=0; assert( pEList!=0 ); /* Begin generating code. */ v = sqlite3GetVdbe(pParse); if( v==0 ) goto select_end; /* Generate code for all sub-queries in the FROM clause */ #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) for(i=0; !p->pPrior && i<pTabList->nSrc; i++){ struct SrcList_item *pItem = &pTabList->a[i]; SelectDest dest; | > > > > > > > > > | 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 | isAgg = (p->selFlags & SF_Aggregate)!=0; assert( pEList!=0 ); /* Begin generating code. */ v = sqlite3GetVdbe(pParse); if( v==0 ) goto select_end; /* If writing to memory or generating a set ** only a single column may be output. */ #ifndef SQLITE_OMIT_SUBQUERY if( checkForMultiColumnSelectError(pParse, pDest, pEList->nExpr) ){ goto select_end; } #endif /* Generate code for all sub-queries in the FROM clause */ #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) for(i=0; !p->pPrior && i<pTabList->nSrc; i++){ struct SrcList_item *pItem = &pTabList->a[i]; SelectDest dest; |
︙ | ︙ | |||
3693 3694 3695 3696 3697 3698 3699 | if( mxSelect && cnt>mxSelect ){ sqlite3ErrorMsg(pParse, "too many terms in compound SELECT"); return 1; } } return multiSelect(pParse, p, pDest); } | < < < < < < < < < | 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 | if( mxSelect && cnt>mxSelect ){ sqlite3ErrorMsg(pParse, "too many terms in compound SELECT"); return 1; } } return multiSelect(pParse, p, pDest); } #endif /* If possible, rewrite the query to use GROUP BY instead of DISTINCT. ** GROUP BY might use an index, DISTINCT never does. */ assert( p->pGroupBy==0 || (p->selFlags & SF_Aggregate)!=0 ); if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct ){ |
︙ | ︙ |
Changes to test/e_expr.test.
︙ | ︙ | |||
1725 1726 1727 1728 1729 1730 1731 | 2 { EXISTS (SELECT NULL FROM t1) } { EXISTS (SELECT 'bread' FROM t1) } } { set res [db one "SELECT $e1"] do_expr_test e_expr-34.5.${tn}a $e1 integer $res do_expr_test e_expr-34.5.${tn}b $e2 integer $res } | > > | > > > > > > > > > > > | > > > > > > > > > | > > | > > > > > > > > > > > > > > > > > > > > > | 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 | 2 { EXISTS (SELECT NULL FROM t1) } { EXISTS (SELECT 'bread' FROM t1) } } { set res [db one "SELECT $e1"] do_expr_test e_expr-34.5.${tn}a $e1 integer $res do_expr_test e_expr-34.5.${tn}b $e2 integer $res } #------------------------------------------------------------------------- # Test statements related to scalar sub-queries. # catch { db close } file delete -force test.db sqlite3 db test.db do_test e_expr-35.0 { execsql { CREATE TABLE t2(a, b); INSERT INTO t2 VALUES('one', 'two'); INSERT INTO t2 VALUES('three', NULL); INSERT INTO t2 VALUES(4, 5.0); } } {} # EVIDENCE-OF: R-00980-39256 A SELECT statement enclosed in parentheses # may appear as a scalar quantity. # # EVIDENCE-OF: R-56294-03966 All types of SELECT statement, including # aggregate and compound SELECT queries (queries with keywords like # UNION or EXCEPT) are allowed as scalar subqueries. # do_expr_test e_expr-35.1.1 { (SELECT 35) } integer 35 do_expr_test e_expr-35.1.2 { (SELECT NULL) } null {} do_expr_test e_expr-35.1.3 { (SELECT count(*) FROM t2) } integer 3 do_expr_test e_expr-35.1.4 { (SELECT 4 FROM t2) } integer 4 do_expr_test e_expr-35.1.5 { (SELECT b FROM t2 UNION SELECT a+1 FROM t2) } null {} do_expr_test e_expr-35.1.6 { (SELECT a FROM t2 UNION SELECT COALESCE(b, 55) FROM t2 ORDER BY 1) } integer 4 # EVIDENCE-OF: R-46899-53765 A SELECT used as a scalar quantity must # return a result set with a single column. # set M {only a single result allowed for a SELECT that is part of an expression} foreach {tn sql} { 1 { SELECT (SELECT * FROM t2 UNION SELECT a+1, b+1 FROM t2) } 2 { SELECT (SELECT * FROM t2 UNION SELECT a+1, b+1 FROM t2 ORDER BY 1) } 3 { SELECT (SELECT 1, 2) } 4 { SELECT (SELECT NULL, NULL, NULL) } 5 { SELECT (SELECT * FROM t2) } 6 { SELECT (SELECT * FROM (SELECT 1, 2, 3)) } } { do_catchsql_test e_expr-35.2.$tn $sql [list 1 $M] } finish_test |
Changes to test/in.test.
︙ | ︙ | |||
400 401 402 403 404 405 406 | SELECT a, b FROM t3 INTERSECT SELECT a, b FROM t2 ); } } {1 {only a single result allowed for a SELECT that is part of an expression}} do_test in-12.6 { catchsql { SELECT * FROM t2 WHERE a IN ( | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 400 401 402 403 404 405 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 | SELECT a, b FROM t3 INTERSECT SELECT a, b FROM t2 ); } } {1 {only a single result allowed for a SELECT that is part of an expression}} do_test in-12.6 { catchsql { SELECT * FROM t2 WHERE a IN ( SELECT a, b FROM t3 UNION ALL SELECT a FROM t2 ); } } {1 {SELECTs to the left and right of UNION ALL do not have the same number of result columns}} do_test in-12.7 { catchsql { SELECT * FROM t2 WHERE a IN ( SELECT a, b FROM t3 UNION SELECT a FROM t2 ); } } {1 {SELECTs to the left and right of UNION do not have the same number of result columns}} do_test in-12.8 { catchsql { SELECT * FROM t2 WHERE a IN ( SELECT a, b FROM t3 EXCEPT SELECT a FROM t2 ); } } {1 {SELECTs to the left and right of EXCEPT do not have the same number of result columns}} do_test in-12.9 { catchsql { SELECT * FROM t2 WHERE a IN ( SELECT a, b FROM t3 INTERSECT SELECT a FROM t2 ); } } {1 {SELECTs to the left and right of INTERSECT do not have the same number of result columns}} } do_test in-12.10 { catchsql { SELECT * FROM t2 WHERE a IN ( SELECT a FROM t3 UNION ALL SELECT a, b FROM t2 ); } } {1 {only a single result allowed for a SELECT that is part of an expression}} do_test in-12.11 { catchsql { SELECT * FROM t2 WHERE a IN ( SELECT a FROM t3 UNION SELECT a, b FROM t2 ); } } {1 {only a single result allowed for a SELECT that is part of an expression}} do_test in-12.12 { catchsql { SELECT * FROM t2 WHERE a IN ( SELECT a FROM t3 EXCEPT SELECT a, b FROM t2 ); } } {1 {only a single result allowed for a SELECT that is part of an expression}} do_test in-12.13 { catchsql { SELECT * FROM t2 WHERE a IN ( SELECT a FROM t3 INTERSECT SELECT a, b FROM t2 ); } } {1 {only a single result allowed for a SELECT that is part of an expression}} #------------------------------------------------------------------------ # The following tests check that NULL is handled correctly when it # appears as part of a set of values on the right-hand side of an # IN or NOT IN operator. # # When it appears in such a set, NULL is handled as an "unknown value". |
︙ | ︙ |