/ Check-in [95037e6d]
Login

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

Overview
Comment:Fix a problem in sqlite3ExprIsInteger() causing failures on select1-4.9.2. Other bug fixes in compound-merge. The compound-merge is still disabled in this check-in using "#if 0" due to additional bugs. (CVS 5295)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 95037e6dbf4ed0ffd38790f3270dcaa4c1ae64ed
User & Date: drh 2008-06-24 12:46:31
Context
2008-06-24
15:39
Add a few extra tests to select9.test. (CVS 5296) check-in: 37b084fd user: danielk1977 tags: trunk
12:46
Fix a problem in sqlite3ExprIsInteger() causing failures on select1-4.9.2. Other bug fixes in compound-merge. The compound-merge is still disabled in this check-in using "#if 0" due to additional bugs. (CVS 5295) check-in: 95037e6d user: drh tags: trunk
12:28
Remove a surplus "breakpoint" from select4.test. (CVS 5294) check-in: 3117238c user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/expr.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
1026
1027
1028
1029
1030
1031
1032

1033
1034
1035
1036
1037
1038
1039
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
** $Id: expr.c,v 1.375 2008/06/24 00:32:35 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Return the 'affinity' of the expression pExpr if any.
**
................................................................................
  switch( p->op ){
    case TK_INTEGER: {
      rc = sqlite3GetInt32((char*)p->token.z, pValue);
      break;
    }
    case TK_UPLUS: {
      rc = sqlite3ExprIsInteger(p->pLeft, pValue);

    }
    case TK_UMINUS: {
      int v;
      if( sqlite3ExprIsInteger(p->pLeft, &v) ){
        *pValue = -v;
        rc = 1;
      }







|







 







>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
** $Id: expr.c,v 1.376 2008/06/24 12:46:31 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Return the 'affinity' of the expression pExpr if any.
**
................................................................................
  switch( p->op ){
    case TK_INTEGER: {
      rc = sqlite3GetInt32((char*)p->token.z, pValue);
      break;
    }
    case TK_UPLUS: {
      rc = sqlite3ExprIsInteger(p->pLeft, pValue);
      break;
    }
    case TK_UMINUS: {
      int v;
      if( sqlite3ExprIsInteger(p->pLeft, &v) ){
        *pValue = -v;
        rc = 1;
      }

Changes to src/insert.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    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 INSERT statements in SQLite.
**
** $Id: insert.c,v 1.242 2008/06/24 00:32:35 drh Exp $
*/
#include "sqliteInt.h"

/*
** Set P4 of the most recently inserted opcode to a column affinity
** string for index pIdx. A column affinity string has one character
** for each column in the table, according to the affinity of the column:







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    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 INSERT statements in SQLite.
**
** $Id: insert.c,v 1.243 2008/06/24 12:46:31 drh Exp $
*/
#include "sqliteInt.h"

/*
** Set P4 of the most recently inserted opcode to a column affinity
** string for index pIdx. A column affinity string has one character
** for each column in the table, according to the affinity of the column:

Changes to src/select.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968

















1969
1970
1971
1972
1973
1974
1975
....
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
....
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
....
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
....
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
**    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.434 2008/06/24 00:32:36 drh Exp $
*/
#include "sqliteInt.h"


/*
** Delete all the content of a Select structure but do not deallocate
** the select structure itself.
................................................................................
  */
  v = sqlite3GetVdbe(pParse);
  if( v==0 ){
    rc = 1;
    goto multi_select_end;
  }

#if 0
  if( p->pOrderBy ){
    return multiSelectOrderBy(pParse, p, pDest, aff);
  }
#endif

  /* Create the destination temporary table if necessary
  */
  dest = *pDest;
  if( dest.eDest==SRT_EphemTab ){
    assert( p->pEList );
    assert( nSetP2<sizeof(aSetP2)/sizeof(aSetP2[0]) );
    aSetP2[nSetP2++] = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iParm, 0);
    dest.eDest = SRT_Table;
  }


















  /* Generate code for the left and right SELECT statements.
  */
  pOrderBy = p->pOrderBy;
  switch( p->op ){
    case TK_ALL: {
      if( pOrderBy==0 ){
................................................................................
      sqlite3VdbeResolveLabel(v, iBreak);
      sqlite3VdbeAddOp2(v, OP_Close, tab2, 0);
      sqlite3VdbeAddOp2(v, OP_Close, tab1, 0);
      break;
    }
  }

  /* Make sure all SELECTs in the statement have the same number of elements
  ** in their result sets.
  */
  assert( p->pEList && pPrior->pEList );
  if( p->pEList->nExpr!=pPrior->pEList->nExpr ){
    sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s"
      " do not have the same number of result columns", selectOpName(p->op));
    rc = 1;
    goto multi_select_end;
  }

  /* Set the number of columns in temporary tables
  */
  nCol = p->pEList->nExpr;
  while( nSetP2 ){
    sqlite3VdbeChangeP2(v, aSetP2[--nSetP2], nCol);
  }

................................................................................
  int savedOffset;      /* Saved value of p->iOffset */
  int labelCmpr;        /* Label for the start of the merge algorithm */
  int labelEnd;         /* Label for the end of the overall SELECT stmt */
  int j1, j2, j3;       /* Jump instructions that get retargetted */
  int op;               /* One of TK_ALL, TK_UNION, TK_EXCEPT, TK_INTERSECT */
  KeyInfo *pKeyInfo;    /* Type data for comparisons */
  int p4type;           /* P4 type used for pKeyInfo */
  u8 NotUsed;           /* Dummy variable */

  assert( p->pOrderBy!=0 );
  v = pParse->pVdbe;
  if( v==0 ) return SQLITE_NOMEM;
  labelEnd = sqlite3VdbeMakeLabel(v);
  labelCmpr = sqlite3VdbeMakeLabel(v);
  pKeyInfo = keyInfoFromExprList(pParse, p->pEList);
................................................................................
  }
  pPrior->pOrderBy = sqlite3ExprListDup(pParse->db, p->pOrderBy);
 
  /* Separate the left and the right query from one another
  */
  p->pPrior = 0;
  pPrior->pRightmost = 0;
  processOrderGroupBy(pParse, p, p->pOrderBy, 1, &NotUsed);
  processOrderGroupBy(pParse, pPrior, pPrior->pOrderBy, 1, &NotUsed);
  
  /* Compute the limit registers */
  computeLimitRegisters(pParse, p, labelEnd);
  if( p->iLimit ){
    regLimitA = ++pParse->nMem;
    regLimitB = ++pParse->nMem;
    sqlite3VdbeAddOp2(v, OP_Copy, p->iOffset ? p->iOffset+1 : p->iLimit,
................................................................................
  }

  /* Free the KeyInfo if unused.
  */
  if( p4type==P4_KEYINFO_HANDOFF ){
    sqlite3_free(pKeyInfo);
  }


  /*** TBD:  Insert subroutine calls to close cursors on incomplete
  **** subqueries ****/
  return SQLITE_OK;
}

#ifndef SQLITE_OMIT_VIEW







|







 







<
<
<
<
<
<





<
|


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







 







<
<
<
<
<
<
<
<
<
<
<







 







<







 







<
<







 







<







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
1947
1948
1949
1950
1951
1952
1953






1954
1955
1956
1957
1958

1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
....
2192
2193
2194
2195
2196
2197
2198











2199
2200
2201
2202
2203
2204
2205
....
2546
2547
2548
2549
2550
2551
2552

2553
2554
2555
2556
2557
2558
2559
....
2569
2570
2571
2572
2573
2574
2575


2576
2577
2578
2579
2580
2581
2582
....
2773
2774
2775
2776
2777
2778
2779

2780
2781
2782
2783
2784
2785
2786
**    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.435 2008/06/24 12:46:31 drh Exp $
*/
#include "sqliteInt.h"


/*
** Delete all the content of a Select structure but do not deallocate
** the select structure itself.
................................................................................
  */
  v = sqlite3GetVdbe(pParse);
  if( v==0 ){
    rc = 1;
    goto multi_select_end;
  }







  /* Create the destination temporary table if necessary
  */
  dest = *pDest;
  if( dest.eDest==SRT_EphemTab ){
    assert( p->pEList );

    sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iParm, p->pEList->nExpr);
    dest.eDest = SRT_Table;
  }

  /* Make sure all SELECTs in the statement have the same number of elements
  ** in their result sets.
  */
  assert( p->pEList && pPrior->pEList );
  if( p->pEList->nExpr!=pPrior->pEList->nExpr ){
    sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s"
      " do not have the same number of result columns", selectOpName(p->op));
    rc = 1;
    goto multi_select_end;
  }

#if 0
  if( p->pOrderBy ){
    return multiSelectOrderBy(pParse, p, pDest, aff);
  }
#endif

  /* Generate code for the left and right SELECT statements.
  */
  pOrderBy = p->pOrderBy;
  switch( p->op ){
    case TK_ALL: {
      if( pOrderBy==0 ){
................................................................................
      sqlite3VdbeResolveLabel(v, iBreak);
      sqlite3VdbeAddOp2(v, OP_Close, tab2, 0);
      sqlite3VdbeAddOp2(v, OP_Close, tab1, 0);
      break;
    }
  }












  /* Set the number of columns in temporary tables
  */
  nCol = p->pEList->nExpr;
  while( nSetP2 ){
    sqlite3VdbeChangeP2(v, aSetP2[--nSetP2], nCol);
  }

................................................................................
  int savedOffset;      /* Saved value of p->iOffset */
  int labelCmpr;        /* Label for the start of the merge algorithm */
  int labelEnd;         /* Label for the end of the overall SELECT stmt */
  int j1, j2, j3;       /* Jump instructions that get retargetted */
  int op;               /* One of TK_ALL, TK_UNION, TK_EXCEPT, TK_INTERSECT */
  KeyInfo *pKeyInfo;    /* Type data for comparisons */
  int p4type;           /* P4 type used for pKeyInfo */


  assert( p->pOrderBy!=0 );
  v = pParse->pVdbe;
  if( v==0 ) return SQLITE_NOMEM;
  labelEnd = sqlite3VdbeMakeLabel(v);
  labelCmpr = sqlite3VdbeMakeLabel(v);
  pKeyInfo = keyInfoFromExprList(pParse, p->pEList);
................................................................................
  }
  pPrior->pOrderBy = sqlite3ExprListDup(pParse->db, p->pOrderBy);
 
  /* Separate the left and the right query from one another
  */
  p->pPrior = 0;
  pPrior->pRightmost = 0;


  
  /* Compute the limit registers */
  computeLimitRegisters(pParse, p, labelEnd);
  if( p->iLimit ){
    regLimitA = ++pParse->nMem;
    regLimitB = ++pParse->nMem;
    sqlite3VdbeAddOp2(v, OP_Copy, p->iOffset ? p->iOffset+1 : p->iLimit,
................................................................................
  }

  /* Free the KeyInfo if unused.
  */
  if( p4type==P4_KEYINFO_HANDOFF ){
    sqlite3_free(pKeyInfo);
  }


  /*** TBD:  Insert subroutine calls to close cursors on incomplete
  **** subqueries ****/
  return SQLITE_OK;
}

#ifndef SQLITE_OMIT_VIEW

Changes to src/sqliteInt.h.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.725 2008/06/24 00:32:36 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** Include the configuration header output by 'configure' if we're using the
** autoconf-based build







|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.726 2008/06/24 12:46:31 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** Include the configuration header output by 'configure' if we're using the
** autoconf-based build

Changes to test/in.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the IN and BETWEEN operator.
#
# $Id: in.test,v 1.19 2008/01/16 18:20:42 danielk1977 Exp $

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

# Generate the test data we will need for the first squences of tests.
#
do_test in-1.0 {
................................................................................
} {1 {only a single result allowed for a SELECT that is part of an expression}}
do_test in-12.6 {
  catchsql {
    SELECT * FROM t2 WHERE a IN (
      SELECT a FROM t3 UNION ALL SELECT a, b FROM t2
    );
  }
} {1 {only a single result allowed for a SELECT that is part of an expression}}
do_test in-12.7 {
  catchsql {
    SELECT * FROM t2 WHERE a IN (
      SELECT a FROM t3 UNION SELECT a, b FROM t2
    );
  }
} {1 {SELECTs to the left and right of UNION do not have the same number of result columns}}







|







 







|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the IN and BETWEEN operator.
#
# $Id: in.test,v 1.20 2008/06/24 12:46:31 drh Exp $

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

# Generate the test data we will need for the first squences of tests.
#
do_test in-1.0 {
................................................................................
} {1 {only a single result allowed for a SELECT that is part of an expression}}
do_test in-12.6 {
  catchsql {
    SELECT * FROM t2 WHERE a IN (
      SELECT a FROM t3 UNION ALL SELECT a, b FROM t2
    );
  }
} {1 {SELECTs to the left and right of UNION ALL do not have the same number of result columns}}
do_test in-12.7 {
  catchsql {
    SELECT * FROM t2 WHERE a IN (
      SELECT a FROM t3 UNION SELECT a, b FROM t2
    );
  }
} {1 {SELECTs to the left and right of UNION do not have the same number of result columns}}

Changes to test/select1.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
928
929
930
931
932
933
934
935
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the SELECT statement.
#
# $Id: select1.test,v 1.60 2008/06/24 12:28:04 drh Exp $

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

# Try to select on a non-existant table.
#
do_test select1-1.1 {
................................................................................
do_test select1-14.2 {
  execsql { 
    SELECT 10 IN (SELECT rowid FROM sqlite_master);
  }
} {0}

finish_test








|







 







<
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
928
929
930
931
932
933
934

#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the SELECT statement.
#
# $Id: select1.test,v 1.61 2008/06/24 12:46:31 drh Exp $

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

# Try to select on a non-existant table.
#
do_test select1-1.1 {
................................................................................
do_test select1-14.2 {
  execsql { 
    SELECT 10 IN (SELECT rowid FROM sqlite_master);
  }
} {0}

finish_test