SQLite

Check-in [e1040e51]
Login

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: e1040e51ebd04f2a076f477b6f240f849afb10f543ebe518e09d6842cc3cb38e
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
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/vdbe.c.

4580
4581
4582
4583
4584
4585
4586
4587

4588
4589
4590
4591
4592
4593
4594
**
** 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.

*/
case OP_OpenPseudo: {
  VdbeCursor *pCx;

  assert( pOp->p1>=0 );
  assert( pOp->p3>=0 );
  pCx = allocateCursor(p, pOp->p1, pOp->p3, CURTYPE_PSEUDO);







|
>







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