/ Check-in [77fc2301]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:The TK_IF_NULL_ROW expression node must be treated as a variable that references the table Expr.iTable. Proposed fix for ticket [7fde638e94287d2c].
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256:77fc23013cebc7797985864b91d78db5d0e2469511732044ebfaf02b891c979a
User & Date: drh 2017-05-25 00:08:48
Context
2017-05-25
17:27
Merge the LEFT JOIN query flattener fixes from 3.19.2. check-in: 6513e4a1 user: drh tags: trunk
00:28
The TK_IF_NULL_ROW expression node must be treated as a variable that references the table Expr.iTable. Proposed fix for ticket [7fde638e94287d2c]. check-in: b30a364a user: drh tags: branch-3.19
00:08
The TK_IF_NULL_ROW expression node must be treated as a variable that references the table Expr.iTable. Proposed fix for ticket [7fde638e94287d2c]. check-in: 77fc2301 user: drh tags: trunk
2017-05-24
15:32
Fix harmless compiler warnings in FTS5. check-in: 57a60e95 user: mistachkin tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/expr.c.

1736
1737
1738
1739
1740
1741
1742
1743




1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
    case TK_AGG_COLUMN:
      testcase( pExpr->op==TK_ID );
      testcase( pExpr->op==TK_COLUMN );
      testcase( pExpr->op==TK_AGG_FUNCTION );
      testcase( pExpr->op==TK_AGG_COLUMN );
      if( pWalker->eCode==3 && pExpr->iTable==pWalker->u.iCur ){
        return WRC_Continue;
      }else{




        pWalker->eCode = 0;
        return WRC_Abort;
      }
    case TK_VARIABLE:
      if( pWalker->eCode==5 ){
        /* Silently convert bound parameters that appear inside of CREATE
        ** statements into a NULL when parsing the CREATE statement text out
        ** of the sqlite_master table */
        pExpr->op = TK_NULL;
      }else if( pWalker->eCode==4 ){







<
>
>
>
>
|
|
<







1736
1737
1738
1739
1740
1741
1742

1743
1744
1745
1746
1747
1748

1749
1750
1751
1752
1753
1754
1755
    case TK_AGG_COLUMN:
      testcase( pExpr->op==TK_ID );
      testcase( pExpr->op==TK_COLUMN );
      testcase( pExpr->op==TK_AGG_FUNCTION );
      testcase( pExpr->op==TK_AGG_COLUMN );
      if( pWalker->eCode==3 && pExpr->iTable==pWalker->u.iCur ){
        return WRC_Continue;

      }
      /* Fall through */
    case TK_IF_NULL_ROW:
      testcase( pExpr->op==TK_IF_NULL_ROW );
      pWalker->eCode = 0;
      return WRC_Abort;

    case TK_VARIABLE:
      if( pWalker->eCode==5 ){
        /* Silently convert bound parameters that appear inside of CREATE
        ** statements into a NULL when parsing the CREATE statement text out
        ** of the sqlite_master table */
        pExpr->op = TK_NULL;
      }else if( pWalker->eCode==4 ){

Changes to src/whereexpr.c.

1371
1372
1373
1374
1375
1376
1377
1378
1379
1380

1381
1382
1383
1384
1385
1386
1387
1388
1389
** a bitmask indicating which tables are used in that expression
** tree.
*/
Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){
  Bitmask mask;
  if( p==0 ) return 0;
  if( p->op==TK_COLUMN ){
    mask = sqlite3WhereGetMask(pMaskSet, p->iTable);
    return mask;
  }

  assert( !ExprHasProperty(p, EP_TokenOnly) );
  mask = p->pRight ? sqlite3WhereExprUsage(pMaskSet, p->pRight) : 0;
  if( p->pLeft ) mask |= sqlite3WhereExprUsage(pMaskSet, p->pLeft);
  if( ExprHasProperty(p, EP_xIsSelect) ){
    mask |= exprSelectUsage(pMaskSet, p->x.pSelect);
  }else if( p->x.pList ){
    mask |= sqlite3WhereExprListUsage(pMaskSet, p->x.pList);
  }
  return mask;







|
<

>

|







1371
1372
1373
1374
1375
1376
1377
1378

1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
** a bitmask indicating which tables are used in that expression
** tree.
*/
Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){
  Bitmask mask;
  if( p==0 ) return 0;
  if( p->op==TK_COLUMN ){
    return sqlite3WhereGetMask(pMaskSet, p->iTable);

  }
  mask = (p->op==TK_IF_NULL_ROW) ? sqlite3WhereGetMask(pMaskSet, p->iTable) : 0;
  assert( !ExprHasProperty(p, EP_TokenOnly) );
  if( p->pRight ) mask |= sqlite3WhereExprUsage(pMaskSet, p->pRight);
  if( p->pLeft ) mask |= sqlite3WhereExprUsage(pMaskSet, p->pLeft);
  if( ExprHasProperty(p, EP_xIsSelect) ){
    mask |= exprSelectUsage(pMaskSet, p->x.pSelect);
  }else if( p->x.pList ){
    mask |= sqlite3WhereExprListUsage(pMaskSet, p->x.pList);
  }
  return mask;

Changes to test/join.test.

738
739
740
741
742
743
744
745




















746
  SELECT * FROM (SELECT 111) LEFT JOIN (SELECT c+222 FROM t1) GROUP BY 1;
} {111 {}}
do_execsql_test join-14.5 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(c PRIMARY KEY) WITHOUT ROWID;
  SELECT * FROM (SELECT 111) LEFT JOIN (SELECT c+222 FROM t1) GROUP BY 1;
} {111 {}}





















finish_test








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
  SELECT * FROM (SELECT 111) LEFT JOIN (SELECT c+222 FROM t1) GROUP BY 1;
} {111 {}}
do_execsql_test join-14.5 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(c PRIMARY KEY) WITHOUT ROWID;
  SELECT * FROM (SELECT 111) LEFT JOIN (SELECT c+222 FROM t1) GROUP BY 1;
} {111 {}}

# Verify the fix to ticket 
# https://www.sqlite.org/src/tktview/7fde638e94287d2c948cd9389
#
db close
sqlite3 db :memory:
do_execsql_test join-14.10 {
  CREATE TABLE t1(a);
  INSERT INTO t1 VALUES(1),(2),(3);
  CREATE VIEW v2 AS SELECT a, 1 AS b FROM t1;
  CREATE TABLE t3(x);
  INSERT INTO t3 VALUES(2),(4);
  SELECT *, '|' FROM t3 LEFT JOIN v2 ON a=x WHERE b=1;
} {2 2 1 |}
do_execsql_test join-14.11 {
  SELECT *, '|' FROM t3 LEFT JOIN v2 ON a=x WHERE b+1=x;
} {2 2 1 |}
do_execsql_test join-14.12 {
  SELECT *, '|' FROM t3 LEFT JOIN v2 ON a=x ORDER BY b;
} {4 {} {} | 2 2 1 |}

finish_test