Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Continuation of the fix at [8c0f69e0e4ae0a44]: If a viaCoroutine FROM clause term is participating in a RIGHT or FULL JOIN, we have to create an always-NULL pseudo-cursor for that term when processing the RIGHT join. dbsqlfuzz 6fd1ff3a64bef4a6c092e8d757548e95698b0df5. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
e1040e51ebd04f2a076f477b6f240f84 |
User & Date: | drh 2024-04-22 00:42:47 |
Context
2024-04-22
| ||
11:48 | For sqlite3.oo1.DB JavaScript classes, bypass execution of any on-open() SQL in SEE-capable builds because it would necessarily run before the client has an opportunity to provide their decryption key, which would leave the db handle in an unusable state and cause the ctor to throw. This currently affects only the OPFS VFSes. We may want to consider extending the ctor options object to optionally accept an SEE key and apply it when opening the db. (check-in: 5c505ee8 user: stephan tags: trunk) | |
00:42 | Continuation of the fix at [8c0f69e0e4ae0a44]: If a viaCoroutine FROM clause term is participating in a RIGHT or FULL JOIN, we have to create an always-NULL pseudo-cursor for that term when processing the RIGHT join. dbsqlfuzz 6fd1ff3a64bef4a6c092e8d757548e95698b0df5. (check-in: e1040e51 user: drh tags: trunk) | |
2024-04-21
| ||
23:35 | Fix an indentation problem in debugging routine sqlite3ShowSrcList(). No changes to production code. (check-in: 5560df27 user: drh tags: trunk) | |
Changes
Changes to src/vdbe.c.
︙ | ︙ | |||
4580 4581 4582 4583 4584 4585 4586 | ** ** A pseudo-table created by this opcode is used to hold a single ** row output from the sorter so that the row can be decomposed into ** individual columns using the OP_Column opcode. The OP_Column opcode ** is the only cursor opcode that works with a pseudo-table. ** ** P3 is the number of fields in the records that will be stored by | | > | 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 | ** ** A pseudo-table created by this opcode is used to hold a single ** row output from the sorter so that the row can be decomposed into ** individual columns using the OP_Column opcode. The OP_Column opcode ** is the only cursor opcode that works with a pseudo-table. ** ** P3 is the number of fields in the records that will be stored by ** the pseudo-table. If P2 is 0 or negative then the pseudo-cursor ** will return NULL for every column. */ case OP_OpenPseudo: { VdbeCursor *pCx; assert( pOp->p1>=0 ); assert( pOp->p3>=0 ); pCx = allocateCursor(p, pOp->p1, pOp->p3, CURTYPE_PSEUDO); |
︙ | ︙ |
Changes to src/wherecode.c.
︙ | ︙ | |||
2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 | pRight = &pWInfo->pTabList->a[pWInfo->a[k].iFrom]; mAll |= pWInfo->a[k].pWLoop->maskSelf; if( pRight->fg.viaCoroutine ){ sqlite3VdbeAddOp3( v, OP_Null, 0, pRight->regResult, pRight->regResult + pRight->pSelect->pEList->nExpr-1 ); }else{ sqlite3VdbeAddOp1(v, OP_NullRow, pWInfo->a[k].iTabCur); iIdxCur = pWInfo->a[k].iIdxCur; if( iIdxCur ){ sqlite3VdbeAddOp1(v, OP_NullRow, iIdxCur); } } | > | 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 | pRight = &pWInfo->pTabList->a[pWInfo->a[k].iFrom]; mAll |= pWInfo->a[k].pWLoop->maskSelf; if( pRight->fg.viaCoroutine ){ sqlite3VdbeAddOp3( v, OP_Null, 0, pRight->regResult, pRight->regResult + pRight->pSelect->pEList->nExpr-1 ); sqlite3VdbeAddOp1(v, OP_OpenPseudo, pWInfo->a[k].iTabCur); }else{ sqlite3VdbeAddOp1(v, OP_NullRow, pWInfo->a[k].iTabCur); iIdxCur = pWInfo->a[k].iIdxCur; if( iIdxCur ){ sqlite3VdbeAddOp1(v, OP_NullRow, iIdxCur); } } |
︙ | ︙ |
Changes to test/values.test.
︙ | ︙ | |||
666 667 668 669 670 671 672 673 674 | SELECT *, '|' FROM t1 FULL JOIN (VALUES(33,44),(55,66)) AS t2 ON a=b ORDER BY +column1 } {11 22 NULL NULL | NULL NULL 33 44 | NULL NULL 55 66 |} do_execsql_test 19.4 { SELECT *, '|' FROM (VALUES(33,44),(55,66)) AS t2 FULL JOIN t1 ON a=b ORDER BY +column1 } {NULL NULL 11 22 | 33 44 NULL NULL | 55 66 NULL NULL |} finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 | SELECT *, '|' FROM t1 FULL JOIN (VALUES(33,44),(55,66)) AS t2 ON a=b ORDER BY +column1 } {11 22 NULL NULL | NULL NULL 33 44 | NULL NULL 55 66 |} do_execsql_test 19.4 { SELECT *, '|' FROM (VALUES(33,44),(55,66)) AS t2 FULL JOIN t1 ON a=b ORDER BY +column1 } {NULL NULL 11 22 | 33 44 NULL NULL | 55 66 NULL NULL |} # 2024-04-21 dbsqlfuzz 6fd1ff3a64bef4a6c092e8d757548e95698b0df5 # A continuation of the 2024-04-18 problem above. We have to create # Pseudo-cursor that is always NULL on the viaCoroutine loop in case # there are OP_Columns generated against it by the sub-WHERE clause. # db null N do_execsql_test 19.5 { DROP TABLE IF EXISTS t1; DROP TABLE IF EXISTS t2; DROP TABLE IF EXISTS t3; CREATE TABLE t1(a,b); INSERT INTO t1 VALUES(1,2); CREATE TABLE t2(column1,column2); INSERT INTO t2 VALUES(11,22),(33,44); CREATE TABLE t3(d,e); INSERT INTO t3 VALUES(3,4); } do_execsql_test 19.6 { -- output verify using PG 14.2 SELECT * FROM t1 CROSS JOIN t2 FULL JOIN t3 ON a=d ORDER BY +d, +column1; } {1 2 11 22 N N 1 2 33 44 N N N N N N 3 4} do_execsql_test 19.7 { SELECT * FROM t1 CROSS JOIN (VALUES(11,22),(33,44)) FULL JOIN t3 ON a=d ORDER BY +d, +column1; } {1 2 11 22 N N 1 2 33 44 N N N N N N 3 4} do_execsql_test 19.8 { -- output verified using PG 14.2 SELECT * FROM t1 CROSS JOIN t2 FULL JOIN t3 ON a=d WHERE column1 IS NULL; } {N N N N 3 4} do_execsql_test 19.9 { SELECT * FROM t1 CROSS JOIN (VALUES(11,22),(33,44)) FULL JOIN t3 ON a=d WHERE column1 IS NULL; } {N N N N 3 4} finish_test |