Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | The query flattener should not run if the subquery is a compound that contains a RIGHT JOIN in any arm and the subquery is not the first element of the outer query. Otherwise, prior elements of the outer query will not have the JT_LTORJ flag set. Fix for the problem reported in forum post 174afeae5734d42d. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
274e244c85935084b2f0f85176283f01 |
User & Date: | drh 2022-07-13 15:52:15 |
Context
2022-07-13
| ||
21:02 | Add new script test/testrunner.tcl. For running a set of test scripts using multiple processes. (check-in: 0122e93d user: dan tags: trunk) | |
16:06 | The query flattener should not run if the subquery is a compound that contains a RIGHT JOIN in any arm and the subquery is not the first element of the outer query. Otherwise, prior elements of the outer query will not have the JT_LTORJ flag set. Fix for the problem reported in forum post 174afeae5734d42d. (check-in: cf9ed7f2 user: drh tags: branch-3.39) | |
15:52 | The query flattener should not run if the subquery is a compound that contains a RIGHT JOIN in any arm and the subquery is not the first element of the outer query. Otherwise, prior elements of the outer query will not have the JT_LTORJ flag set. Fix for the problem reported in forum post 174afeae5734d42d. (check-in: 274e244c user: drh tags: trunk) | |
2022-07-12
| ||
15:53 | Renamed the SQLITE_SHELL_WASM_WEB_MODE to SQLITE_SHELL_FIDDLE, which seems to be more in line with project convensions and indicates that that flag is only intended for /fiddle mode, as opposed to arbitrary wasm-on-the-web use. (check-in: d1d019bf user: stephan tags: trunk) | |
Changes
Changes to src/select.c.
︙ | ︙ | |||
4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 | ** or DISTINCT, and ** (17c) every term within the subquery compound must have a FROM clause ** (17d) the outer query may not be ** (17d1) aggregate, or ** (17d2) DISTINCT ** (17e) the subquery may not contain window functions, and ** (17f) the subquery must not be the RHS of a LEFT JOIN. ** ** The parent and sub-query may contain WHERE clauses. Subject to ** rules (11), (13) and (14), they may also contain ORDER BY, ** LIMIT and OFFSET clauses. The subquery cannot use any compound ** operator other than UNION ALL because all the other compound ** operators have an implied DISTINCT which is disallowed by ** restriction (4). | > > > | 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 | ** or DISTINCT, and ** (17c) every term within the subquery compound must have a FROM clause ** (17d) the outer query may not be ** (17d1) aggregate, or ** (17d2) DISTINCT ** (17e) the subquery may not contain window functions, and ** (17f) the subquery must not be the RHS of a LEFT JOIN. ** (17g) either the subquery is the first element of the outer ** query or there are no RIGHT or FULL JOINs in any arm ** of the subquery. (This is a duplicate of condition (27b).) ** ** The parent and sub-query may contain WHERE clauses. Subject to ** rules (11), (13) and (14), they may also contain ORDER BY, ** LIMIT and OFFSET clauses. The subquery cannot use any compound ** operator other than UNION ALL because all the other compound ** operators have an implied DISTINCT which is disallowed by ** restriction (4). |
︙ | ︙ | |||
4167 4168 4169 4170 4171 4172 4173 | ** function in the select list or ORDER BY clause, flattening ** is not attempted. ** ** (26) The subquery may not be the right operand of a RIGHT JOIN. ** See also (3) for restrictions on LEFT JOIN. ** ** (27) The subquery may not contain a FULL or RIGHT JOIN unless it | | > > > > | 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 | ** function in the select list or ORDER BY clause, flattening ** is not attempted. ** ** (26) The subquery may not be the right operand of a RIGHT JOIN. ** See also (3) for restrictions on LEFT JOIN. ** ** (27) The subquery may not contain a FULL or RIGHT JOIN unless it ** is the first element of the parent query. This must be the ** the case if: ** (27a) the subquery is not compound query, and ** (27b) the subquery is a compound query and the RIGHT JOIN occurs ** in any arm of the compound query. (See also (17g).) ** ** (28) The subquery is not a MATERIALIZED CTE. ** ** (29) Either the subquery is not the right-hand operand of a join with an ** ON or USING clause nor the right-hand operand of a NATURAL JOIN, or ** the right-most table within the FROM clause of the subquery ** is not part of an outer join. |
︙ | ︙ | |||
4292 4293 4294 4295 4296 4297 4298 | ** opcode. */ isOuterJoin = -1; } #endif assert( pSubSrc->nSrc>0 ); /* True by restriction (7) */ if( iFrom>0 && (pSubSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){ | | | | 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 | ** opcode. */ isOuterJoin = -1; } #endif assert( pSubSrc->nSrc>0 ); /* True by restriction (7) */ if( iFrom>0 && (pSubSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){ return 0; /* Restriction (27a) */ } if( pSubitem->fg.isCte && pSubitem->u2.pCteUse->eM10d==M10d_Yes ){ return 0; /* (28) */ } /* Restriction (29): ** ** We do not want two constraints on the same term of the flattened ** query where one constraint has EP_InnerON and the other is EP_OuterON. ** To prevent this, one or the other of the following conditions must be ** false: ** ** (29a) The right-most entry in the FROM clause of the subquery ** must not be part of an outer join. ** ** (29b) The subquery itself must not be the right operand of a ** NATURAL join or a join that as an ON or USING clause. ** ** These conditions are sufficient to keep an EP_OuterON from being ** flattened into an EP_InnerON. Restrictions (3a) and (27a) prevent ** an EP_InnerON from being flattened into an EP_OuterON. */ if( pSubSrc->nSrc>=2 && (pSubSrc->a[pSubSrc->nSrc-1].fg.jointype & JT_OUTER)!=0 ){ if( (pSubitem->fg.jointype & JT_NATURAL)!=0 || pSubitem->fg.isUsing |
︙ | ︙ | |||
4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 | || (pSub1->pPrior && pSub1->op!=TK_ALL) /* (17a) */ || pSub1->pSrc->nSrc<1 /* (17c) */ #ifndef SQLITE_OMIT_WINDOWFUNC || pSub1->pWin /* (17e) */ #endif ){ return 0; } testcase( pSub1->pSrc->nSrc>1 ); } /* Restriction (18). */ if( p->pOrderBy ){ int ii; | > > > > > > | 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 | || (pSub1->pPrior && pSub1->op!=TK_ALL) /* (17a) */ || pSub1->pSrc->nSrc<1 /* (17c) */ #ifndef SQLITE_OMIT_WINDOWFUNC || pSub1->pWin /* (17e) */ #endif ){ return 0; } if( iFrom>0 && (pSub1->pSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){ /* Without this restriction, the JT_LTORJ flag would end up being ** omitted on left-hand tables of the right join that is being ** flattened. */ return 0; /* Restrictions (17g), (27b) */ } testcase( pSub1->pSrc->nSrc>1 ); } /* Restriction (18). */ if( p->pOrderBy ){ int ii; |
︙ | ︙ |
Changes to test/join8.test.
︙ | ︙ | |||
782 783 784 785 786 787 788 789 | do_execsql_test join8-25010 { SELECT * FROM t1 LEFT JOIN t2 ON true JOIN t3 ON (b2 IN (a1)) FULL JOIN t4 ON true; } {- - - - - x} do_execsql_test join8-25020 { SELECT 1 FROM t1 LEFT JOIN t2 ON true JOIN t3 ON (b2 IN (a1)) FULL JOIN t4 ON true; } {1} finish_test | > > > > > > > > > > > > > > > | 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 | do_execsql_test join8-25010 { SELECT * FROM t1 LEFT JOIN t2 ON true JOIN t3 ON (b2 IN (a1)) FULL JOIN t4 ON true; } {- - - - - x} do_execsql_test join8-25020 { SELECT 1 FROM t1 LEFT JOIN t2 ON true JOIN t3 ON (b2 IN (a1)) FULL JOIN t4 ON true; } {1} # 2022-07-13 # forum/forumpost/174afeae57 # reset_db db null - do_execsql_test join8-26000 { CREATE TABLE t1(a INT); CREATE TABLE t2(b INT, c INT); CREATE VIEW t3(d) AS SELECT NULL FROM t2 FULL OUTER JOIN t1 ON c=a UNION ALL SELECT b FROM t2; INSERT INTO t1(a) VALUES (NULL); INSERT INTO t2(b, c) VALUES (99, NULL); SELECT DISTINCT b, c, d FROM t2, t3 WHERE b<>0 UNION SELECT DISTINCT b, c, d FROM t2, t3 WHERE b ISNULL; } {99 - - 99 - 99} finish_test |