/ Check-in [6c0f44bd]
Login

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

Overview
Comment:Fix a bug in the left outer join logic. (CVS 758)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:6c0f44bd6374010f7a4a091e585eb36e0665f96f
User & Date: drh 2002-09-30 12:36:26
Context
2002-10-12
13:44
Remove the call to srand() and add better comments to the sqliteOsRandomSeed() routine. Ticket #163. (CVS 759) check-in: d87a886d user: drh tags: trunk
2002-09-30
12:36
Fix a bug in the left outer join logic. (CVS 758) check-in: 6c0f44bd user: drh tags: trunk
01:31
Fix an uninitialized variable that could cause problems when comparing two NULLs. (CVS 757) check-in: 01542500 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/where.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
421
422
423
424
425
426
427

428
429
430
431
432
433
434
...
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This module contains C code that generates VDBE code used to process
** the WHERE clause of SQL statements.  Also found here are subroutines
** to generate VDBE code to evaluate expressions.
**
** $Id: where.c,v 1.64 2002/08/28 03:01:01 drh Exp $
*/
#include "sqliteInt.h"

/*
** The query generator uses an array of instances of this structure to
** help it analyze the subexpressions of the WHERE clause.  Each WHERE
** clause subexpression is separated from the others by an AND operator.
................................................................................

    /* Check to see if there is an expression that uses only the
    ** ROWID field of this table.  For terms of the form ROWID==expr
    ** set iDirectEq[i] to the index of the term.  For terms of the
    ** form ROWID<expr or ROWID<=expr set iDirectLt[i] to the term index.
    ** For terms like ROWID>expr or ROWID>=expr set iDirectGt[i].
    */

    iDirectEq[i] = -1;
    iDirectLt[i] = -1;
    iDirectGt[i] = -1;
    for(j=0; j<nExpr; j++){
      if( aExpr[j].idxLeft==idx && aExpr[j].p->pLeft->iColumn<0
            && (aExpr[j].prereqRight & loopMask)==aExpr[j].prereqRight ){
        switch( aExpr[j].p->op ){
................................................................................
    }
    pWInfo->a[i].pIdx = pBestIdx;
    pWInfo->a[i].score = bestScore;
    loopMask |= 1<<idx;
    if( pBestIdx ){
      pWInfo->a[i].iCur = pParse->nTab++;
      pWInfo->peakNTab = pParse->nTab;
    }else{
      pWInfo->a[i].iCur = -1;
    }
  }

  /* Check to see if the ORDER BY clause is or can be satisfied by the
  ** use of an index on the first table.
  */
  if( ppOrderBy && *ppOrderBy && pTabList->nSrc>0 ){







|







 







>







 







<
<







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
...
574
575
576
577
578
579
580


581
582
583
584
585
586
587
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This module contains C code that generates VDBE code used to process
** the WHERE clause of SQL statements.  Also found here are subroutines
** to generate VDBE code to evaluate expressions.
**
** $Id: where.c,v 1.65 2002/09/30 12:36:26 drh Exp $
*/
#include "sqliteInt.h"

/*
** The query generator uses an array of instances of this structure to
** help it analyze the subexpressions of the WHERE clause.  Each WHERE
** clause subexpression is separated from the others by an AND operator.
................................................................................

    /* Check to see if there is an expression that uses only the
    ** ROWID field of this table.  For terms of the form ROWID==expr
    ** set iDirectEq[i] to the index of the term.  For terms of the
    ** form ROWID<expr or ROWID<=expr set iDirectLt[i] to the term index.
    ** For terms like ROWID>expr or ROWID>=expr set iDirectGt[i].
    */
    pWInfo->a[i].iCur = -1;
    iDirectEq[i] = -1;
    iDirectLt[i] = -1;
    iDirectGt[i] = -1;
    for(j=0; j<nExpr; j++){
      if( aExpr[j].idxLeft==idx && aExpr[j].p->pLeft->iColumn<0
            && (aExpr[j].prereqRight & loopMask)==aExpr[j].prereqRight ){
        switch( aExpr[j].p->op ){
................................................................................
    }
    pWInfo->a[i].pIdx = pBestIdx;
    pWInfo->a[i].score = bestScore;
    loopMask |= 1<<idx;
    if( pBestIdx ){
      pWInfo->a[i].iCur = pParse->nTab++;
      pWInfo->peakNTab = pParse->nTab;


    }
  }

  /* Check to see if the ORDER BY clause is or can be satisfied by the
  ** use of an index on the first table.
  */
  if( ppOrderBy && *ppOrderBy && pTabList->nSrc>0 ){

Changes to test/join.test.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
279
280
281
282
283
284
285














286


287
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for joins, including outer joins.
#
# $Id: join.test,v 1.5 2002/07/31 19:50:28 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

do_test join-1.1 {
  execsql {
    CREATE TABLE t1(a,b,c);
................................................................................
} {}
do_test join-4.10 {
  execsql {
    SELECT * FROM t6, t5 WHERE t6.a>t5.a;
  }
} {}


















finish_test







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for joins, including outer joins.
#
# $Id: join.test,v 1.6 2002/09/30 12:36:26 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

do_test join-1.1 {
  execsql {
    CREATE TABLE t1(a,b,c);
................................................................................
} {}
do_test join-4.10 {
  execsql {
    SELECT * FROM t6, t5 WHERE t6.a>t5.a;
  }
} {}

do_test join-5.1 {
  execsql {
    BEGIN;
    create table centros (id integer primary key, centro);
    INSERT INTO centros VALUES(1,'xxx');
    create table usuarios (id integer primary key, nombre, apellidos,
    idcentro integer);
    INSERT INTO usuarios VALUES(1,'a','aa',1);
    INSERT INTO usuarios VALUES(2,'b','bb',1);
    INSERT INTO usuarios VALUES(3,'c','cc',NULL);
    create index idcentro on usuarios (idcentro);
    END;
    select usuarios.id, usuarios.nombre, centros.centro from
    usuarios left outer join centros on usuarios.idcentro = centros.id;
  }
} {1 a xxx 2 b xxx 3 c {}}

finish_test