/ Check-in [f22d0f64]
Login

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

Overview
Comment:Cleanup the implementation and the documentation of the new 0x200 P1 flag on the VDBE comparison operands. (CVS 2729)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: f22d0f64a0b9100e16746fb800efa508d286e40e
User & Date: drh 2005-09-20 13:55:18
Context
2005-09-20
17:42
Code cleanup and simplification. Three new Mem opcodes added. The sqlite3VdbeJumpHere function added. (CVS 2730) check-in: 2471957f user: drh tags: trunk
13:55
Cleanup the implementation and the documentation of the new 0x200 P1 flag on the VDBE comparison operands. (CVS 2729) check-in: f22d0f64 user: drh tags: trunk
13:12
NULLs compare equal to each other when computing GROUP BY categories. (CVS 2728) check-in: d9b0c970 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/select.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.273 2005/09/20 13:12:00 drh Exp $
*/
#include "sqliteInt.h"


/*
** Allocate a new Select structure and return a pointer to that
** structure.
................................................................................
        if( j<pGroupBy->nExpr-1 ){
          sqlite3VdbeAddOp(v, OP_MemLoad, iBMem+j, 0);
        }
        sqlite3VdbeAddOp(v, OP_MemLoad, iAMem+j, 0);
        if( j==0 ){
          sqlite3VdbeAddOp(v, OP_Eq, 0x200, addrProcessRow);
        }else{
          sqlite3VdbeAddOp(v, OP_Ne, 0x300, addrGroupByChange);
        }
        sqlite3VdbeChangeP3(v, -1, (void*)pKeyInfo->aColl[j], P3_COLLSEQ);
      }

      /* Generate code that runs whenever the GROUP BY changes.
      ** Change in the GROUP BY are detected by the previous code
      ** block.  If there were no changes, this block is skipped.







|







 







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.274 2005/09/20 13:55:18 drh Exp $
*/
#include "sqliteInt.h"


/*
** Allocate a new Select structure and return a pointer to that
** structure.
................................................................................
        if( j<pGroupBy->nExpr-1 ){
          sqlite3VdbeAddOp(v, OP_MemLoad, iBMem+j, 0);
        }
        sqlite3VdbeAddOp(v, OP_MemLoad, iAMem+j, 0);
        if( j==0 ){
          sqlite3VdbeAddOp(v, OP_Eq, 0x200, addrProcessRow);
        }else{
          sqlite3VdbeAddOp(v, OP_Ne, 0x200, addrGroupByChange);
        }
        sqlite3VdbeChangeP3(v, -1, (void*)pKeyInfo->aColl[j], P3_COLLSEQ);
      }

      /* Generate code that runs whenever the GROUP BY changes.
      ** Change in the GROUP BY are detected by the previous code
      ** block.  If there were no changes, this block is skipped.

Changes to src/vdbe.c.

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
....
1408
1409
1410
1411
1412
1413
1414


1415
1416





1417
1418
1419
1420
1421
1422
1423
....
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488







1489
1490
1491


1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.489 2005/09/20 13:12:00 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
................................................................................
/* Opcode: Eq P1 P2 P3
**
** Pop the top two elements from the stack.  If they are equal, then
** jump to instruction P2.  Otherwise, continue to the next instruction.
**
** If the 0x100 bit of P1 is true and either operand is NULL then take the
** jump.  If the 0x100 bit of P1 is clear then fall thru if either operand


** is NULL.  If the 0x200 bit of P1 is set and both operands are NULL, then
** return true or take the jump - treat NULL values as just another number.





**
** The least significant byte of P1 (mask 0xff) must be an affinity character -
** 'n', 't', 'i' or 'o' - or 0x00. An attempt is made to coerce both values
** according to the affinity before the comparison is made. If the byte is
** 0x00, then numeric affinity is used.
**
** Once any conversions have taken place, and neither value is NULL, 
................................................................................
  flags = pTos->flags|pNos->flags;

  /* If either value is a NULL P2 is not zero, take the jump if the least
  ** significant byte of P1 is true. If P2 is zero, then push a NULL onto
  ** the stack.
  */
  if( flags&MEM_Null ){
    if( (pOp->p1 & 0x200)!=0 && (pTos->flags & pNos->flags & MEM_Null)!=0 ){
      /* If the 0x200 bit of P1 is set and *both* operands are NULL, then
      ** pretend that both operands are integer 0.  This will cause the the
      ** various comparison operators to threat NULL just like any other value.







      */
      pTos->flags = pNos->flags = MEM_Int;
      pTos->i = pNos->i = 0;


    }else{
      /* If the 0x200 bit of P1 is clear or only one of the operands is NULL,
      ** then the result is always NULL.  The jump is taken if the 0x100 bit
      ** of P1 is set.
      */
      popStack(&pTos, 2);
      if( pOp->p2 ){
        if( pOp->p1 & 0x100 ){
          pc = pOp->p2-1;
        }







|







 







>
>
|
<
>
>
>
>
>







 







|
|
|
|
>
>
>
>
>
>
>

<
<
>
>

|
|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
....
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417

1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
....
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502


1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.490 2005/09/20 13:55:18 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
................................................................................
/* Opcode: Eq P1 P2 P3
**
** Pop the top two elements from the stack.  If they are equal, then
** jump to instruction P2.  Otherwise, continue to the next instruction.
**
** If the 0x100 bit of P1 is true and either operand is NULL then take the
** jump.  If the 0x100 bit of P1 is clear then fall thru if either operand
** is NULL.
**
** If the 0x200 bit of P1 is set and either operand is NULL then

** both operands are converted to integers prior to comparison.
** NULL operands are converted to zero and non-NULL operands are
** converted to 1.  Thus, for example, with 0x200 set,  NULL==NULL is true
** whereas it would normally be NULL.  Similarly,  NULL==123 is false when
** 0x200 is set but is NULL when the 0x200 bit of P1 is clear.
**
** The least significant byte of P1 (mask 0xff) must be an affinity character -
** 'n', 't', 'i' or 'o' - or 0x00. An attempt is made to coerce both values
** according to the affinity before the comparison is made. If the byte is
** 0x00, then numeric affinity is used.
**
** Once any conversions have taken place, and neither value is NULL, 
................................................................................
  flags = pTos->flags|pNos->flags;

  /* If either value is a NULL P2 is not zero, take the jump if the least
  ** significant byte of P1 is true. If P2 is zero, then push a NULL onto
  ** the stack.
  */
  if( flags&MEM_Null ){
    if( (pOp->p1 & 0x200)!=0 ){
      /* The 0x200 bit of P1 means, roughly "do not treat NULL as the
      ** magic SQL value it normally is - treat it as if it were another
      ** integer".
      **
      ** With 0x200 set, if either operand is NULL then both operands
      ** are converted to integers prior to being passed down into the
      ** normal comparison logic below.  NULL operands are converted to
      ** zero and non-NULL operands are converted to 1.  Thus, for example,
      ** with 0x200 set,  NULL==NULL is true whereas it would normally
      ** be NULL.  Similarly,  NULL!=123 is true.
      */


      sqlite3VdbeMemSetInt64(pTos, (pTos->flags & MEM_Null)==0);
      sqlite3VdbeMemSetInt64(pNos, (pNos->flags & MEM_Null)==0);
    }else{
      /* If the 0x200 bit of P1 is clear and either operand is NULL then
      ** the result is always NULL.  The jump is taken if the 0x100 bit
      ** of P1 is set.
      */
      popStack(&pTos, 2);
      if( pOp->p2 ){
        if( pOp->p1 & 0x100 ){
          pc = pOp->p2-1;
        }