SQLite

Check-in [d30fdf0f2c]
Login

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

Overview
Comment:Added the SQLITE_OMIT_SUBQUERY compile-time option and the EXISTS operator. Regression tests are currently failing with an assertion fault. (CVS 2245)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: d30fdf0f2c24cb74b48fab9b83fba4e4b2fe878a
User & Date: drh 2005-01-20 13:36:20.000
Context
2005-01-20
22:48
Bug fixes and enhancements entered while on jury recess. (CVS 2246) (check-in: 38401dfbd5 user: drh tags: trunk)
13:36
Added the SQLITE_OMIT_SUBQUERY compile-time option and the EXISTS operator. Regression tests are currently failing with an assertion fault. (CVS 2245) (check-in: d30fdf0f2c user: drh tags: trunk)
13:03
Remove a few more lines of code when SQLITE_OMIT_** macros are defined. (CVS 2244) (check-in: 417bbba93a user: danielk1977 tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/expr.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 routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
** $Id: expr.c,v 1.184 2005/01/20 13:03:10 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Return the 'affinity' of the expression pExpr if any.
**







|







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 routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
** $Id: expr.c,v 1.185 2005/01/20 13:36:20 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Return the 'affinity' of the expression pExpr if any.
**
1172
1173
1174
1175
1176
1177
1178

1179
1180
1181
1182
1183
1184
1185
** If it finds any, it generates code to write the value of that select
** into a memory cell.
**
** This routine is a callback for wallExprTree() used to implement
** sqlite3ExprCodeSubquery().  See comments on those routines for
** additional information.
*/

static int codeSubqueryStep(void *pArg, Expr *pExpr){
  QueryCoder *pCoder = (QueryCoder*)pArg;
  Parse *pParse = pCoder->pParse;

  switch( pExpr->op ){
    case TK_IN: {
      char affinity;







>







1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
** If it finds any, it generates code to write the value of that select
** into a memory cell.
**
** This routine is a callback for wallExprTree() used to implement
** sqlite3ExprCodeSubquery().  See comments on those routines for
** additional information.
*/
#ifndef SQLITE_OMIT_SUBQUERY
static int codeSubqueryStep(void *pArg, Expr *pExpr){
  QueryCoder *pCoder = (QueryCoder*)pArg;
  Parse *pParse = pCoder->pParse;

  switch( pExpr->op ){
    case TK_IN: {
      char affinity;
1259
1260
1261
1262
1263
1264
1265

1266
1267
1268
1269
1270
1271
1272
1273
1274


1275
1276
1277
1278
1279
1280
1281










1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297

1298
1299
1300
1301
1302
1303
1304
1305
1306
1307

1308
1309
1310
1311

1312
1313
1314
1315
1316
1317
1318
          sqlite3VdbeAddOp(v, OP_PutStrKey, pExpr->iTable, 0);
        }
      }
      sqlite3VdbeChangeP3(v, addr, (void *)&keyInfo, P3_KEYINFO);
      return 1;
    }


    case TK_SELECT: {
      /* This has to be a scalar SELECT.  Generate code to put the
      ** value of this select in a memory cell and record the number
      ** of the memory cell in iColumn.
      */
      NameContext *pNC;
      int nRef;
      Vdbe *v;
      int addr;



      pNC = pCoder->pNC;
      if( pNC ) nRef = pNC->nRef;
      sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */
      v = sqlite3GetVdbe(pParse);
      addr = sqlite3VdbeAddOp(v, OP_Goto, 0, 0);
      pExpr->iColumn = pParse->nMem++;










      sqlite3Select(pParse, pExpr->pSelect, SRT_Mem,pExpr->iColumn,0,0,0,0,pNC);
      if( pNC && pNC->nRef>nRef ){
        /* Subquery value changes.  Evaluate at each use */
        pExpr->iTable = addr+1;
        sqlite3VdbeAddOp(v, OP_Return, 0, 0);
        sqlite3VdbeChangeP2(v, addr, sqlite3VdbeCurrentAddr(v));
      }else{
        /* Subquery value is constant.  evaluate only once. */
        pExpr->iTable = -1;
        sqlite3VdbeChangeP2(v, addr, addr+1);
      }
      return 1;
    }
  }
  return 0;
}


/*
** Generate code to evaluate subqueries and IN operators contained
** in expression pExpr.
*/
static int sqlite3ExprCodeSubquery(
  Parse *pParse,       /* Parser */
  NameContext *pNC,    /* First enclosing namespace.  Often NULL */
  Expr *pExpr          /* Subquery to be coded */
){

  QueryCoder sCoder;
  sCoder.pParse = pParse;
  sCoder.pNC = pNC;
  walkExprTree(pExpr, codeSubqueryStep, &sCoder);

  return 0;
}

/*
** Generate an instruction that will put the integer describe by
** text z[0..n-1] on the stack.
*/







>









>
>







>
>
>
>
>
>
>
>
>
>
|















>










>




>







1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
          sqlite3VdbeAddOp(v, OP_PutStrKey, pExpr->iTable, 0);
        }
      }
      sqlite3VdbeChangeP3(v, addr, (void *)&keyInfo, P3_KEYINFO);
      return 1;
    }

    case TK_EXISTS:
    case TK_SELECT: {
      /* This has to be a scalar SELECT.  Generate code to put the
      ** value of this select in a memory cell and record the number
      ** of the memory cell in iColumn.
      */
      NameContext *pNC;
      int nRef;
      Vdbe *v;
      int addr;
      int sop;
      Select *pSel;

      pNC = pCoder->pNC;
      if( pNC ) nRef = pNC->nRef;
      sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */
      v = sqlite3GetVdbe(pParse);
      addr = sqlite3VdbeAddOp(v, OP_Goto, 0, 0);
      pExpr->iColumn = pParse->nMem++;
      pSel = pExpr->pSelect;
      if( pExpr->op==TK_SELECT ){
        sop = SRT_Mem;
      }else{
        static const Token one = { "1", 0, 1 };
        sop = SRT_Exists;
        sqlite3ExprListDelete(pSel->pEList);
        pSel->pEList = sqlite3ExprListAppend(0, 
                          sqlite3Expr(TK_INTEGER, 0, 0, &one), 0);
      }
      sqlite3Select(pParse, pSel, sop, pExpr->iColumn, 0, 0, 0, 0, pNC);
      if( pNC && pNC->nRef>nRef ){
        /* Subquery value changes.  Evaluate at each use */
        pExpr->iTable = addr+1;
        sqlite3VdbeAddOp(v, OP_Return, 0, 0);
        sqlite3VdbeChangeP2(v, addr, sqlite3VdbeCurrentAddr(v));
      }else{
        /* Subquery value is constant.  evaluate only once. */
        pExpr->iTable = -1;
        sqlite3VdbeChangeP2(v, addr, addr+1);
      }
      return 1;
    }
  }
  return 0;
}
#endif /* SQLITE_OMIT_SUBQUERY */

/*
** Generate code to evaluate subqueries and IN operators contained
** in expression pExpr.
*/
static int sqlite3ExprCodeSubquery(
  Parse *pParse,       /* Parser */
  NameContext *pNC,    /* First enclosing namespace.  Often NULL */
  Expr *pExpr          /* Subquery to be coded */
){
#ifndef SQLITE_OMIT_SUBQUERY
  QueryCoder sCoder;
  sCoder.pParse = pParse;
  sCoder.pNC = pNC;
  walkExprTree(pExpr, codeSubqueryStep, &sCoder);
#endif
  return 0;
}

/*
** Generate an instruction that will put the integer describe by
** text z[0..n-1] on the stack.
*/
Changes to src/parse.y.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
**
*************************************************************************
** This file contains SQLite's grammar for SQL.  Process this file
** using the lemon parser generator to generate C code that runs
** the parser.  Lemon will also generate a header file containing
** numeric codes for all of the tokens.
**
** @(#) $Id: parse.y,v 1.160 2005/01/20 02:14:31 drh Exp $
*/
%token_prefix TK_
%token_type {Token}
%default_type {Token}
%extra_argument {Parse *pParse}
%syntax_error {
  if( pParse->zErrMsg==0 ){







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
**
*************************************************************************
** This file contains SQLite's grammar for SQL.  Process this file
** using the lemon parser generator to generate C code that runs
** the parser.  Lemon will also generate a header file containing
** numeric codes for all of the tokens.
**
** @(#) $Id: parse.y,v 1.161 2005/01/20 13:36:20 drh Exp $
*/
%token_prefix TK_
%token_type {Token}
%default_type {Token}
%extra_argument {Parse *pParse}
%syntax_error {
  if( pParse->zErrMsg==0 ){
414
415
416
417
418
419
420

421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445

446
447
448
449
450
451
452
    else { sqlite3ExprDelete(N); }
  }
  if( U ){
    if( A && A->nSrc>1 ){ A->a[A->nSrc-2].pUsing = U; }
    else { sqlite3IdListDelete(U); }
  }
}

seltablist(A) ::= stl_prefix(X) LP seltablist_paren(S) RP
                  as(Z) on_opt(N) using_opt(U). {
  A = sqlite3SrcListAppend(X,0,0);
  A->a[A->nSrc-1].pSelect = S;
  if( Z.n ) sqlite3SrcListAddAlias(A,&Z);
  if( N ){
    if( A && A->nSrc>1 ){ A->a[A->nSrc-2].pOn = N; }
    else { sqlite3ExprDelete(N); }
  }
  if( U ){
    if( A && A->nSrc>1 ){ A->a[A->nSrc-2].pUsing = U; }
    else { sqlite3IdListDelete(U); }
  }
}

// A seltablist_paren nonterminal represents anything in a FROM that
// is contained inside parentheses.  This can be either a subquery or
// a grouping of table and subqueries.
//
%type seltablist_paren {Select*}
%destructor seltablist_paren {sqlite3SelectDelete($$);}
seltablist_paren(A) ::= select(S).      {A = S;}
seltablist_paren(A) ::= seltablist(F).  {
   A = sqlite3SelectNew(0,F,0,0,0,0,0,-1,0);
}


%type dbnm {Token}
dbnm(A) ::= .          {A.z=0; A.n=0;}
dbnm(A) ::= DOT nm(X). {A = X;}

%type fullname {SrcList*}
%destructor fullname {sqlite3SrcListDelete($$);}







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







414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
    else { sqlite3ExprDelete(N); }
  }
  if( U ){
    if( A && A->nSrc>1 ){ A->a[A->nSrc-2].pUsing = U; }
    else { sqlite3IdListDelete(U); }
  }
}
%ifndef SQLITE_OMIT_SUBQUERY
  seltablist(A) ::= stl_prefix(X) LP seltablist_paren(S) RP
                    as(Z) on_opt(N) using_opt(U). {
    A = sqlite3SrcListAppend(X,0,0);
    A->a[A->nSrc-1].pSelect = S;
    if( Z.n ) sqlite3SrcListAddAlias(A,&Z);
    if( N ){
      if( A && A->nSrc>1 ){ A->a[A->nSrc-2].pOn = N; }
      else { sqlite3ExprDelete(N); }
    }
    if( U ){
      if( A && A->nSrc>1 ){ A->a[A->nSrc-2].pUsing = U; }
      else { sqlite3IdListDelete(U); }
    }
  }
  
 // A seltablist_paren nonterminal represents anything in a FROM that
  // is contained inside parentheses.  This can be either a subquery or
  // a grouping of table and subqueries.
  //
  %type seltablist_paren {Select*}
  %destructor seltablist_paren {sqlite3SelectDelete($$);}
  seltablist_paren(A) ::= select(S).      {A = S;}
  seltablist_paren(A) ::= seltablist(F).  {
     A = sqlite3SelectNew(0,F,0,0,0,0,0,-1,0);
  }
%endif // SQLITE_OMIT_SUBQUERY

%type dbnm {Token}
dbnm(A) ::= .          {A.z=0; A.n=0;}
dbnm(A) ::= DOT nm(X). {A = X;}

%type fullname {SrcList*}
%destructor fullname {sqlite3SrcListDelete($$);}
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
716
717
718
719






720
721
722
723
724
725
726
727
728
729
730
731
732





733


734
735
736
737
738
739
740
  A = sqlite3Expr(TK_UMINUS, X, 0, 0);
  sqlite3ExprSpan(A,&B,&X->span);
}
expr(A) ::= PLUS(B) expr(X). [UPLUS] {
  A = sqlite3Expr(TK_UPLUS, X, 0, 0);
  sqlite3ExprSpan(A,&B,&X->span);
}
expr(A) ::= LP(B) select(X) RP(E). {
  A = sqlite3Expr(TK_SELECT, 0, 0, 0);
  if( A ) A->pSelect = X;
  sqlite3ExprSpan(A,&B,&E);
}
%type between_op {int}
between_op(A) ::= BETWEEN.     {A = 0;}
between_op(A) ::= NOT BETWEEN. {A = 1;}
expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
  ExprList *pList = sqlite3ExprListAppend(0, X, 0);
  pList = sqlite3ExprListAppend(pList, Y, 0);
  A = sqlite3Expr(TK_BETWEEN, W, 0, 0);
  if( A ) A->pList = pList;
  if( N ) A = sqlite3Expr(TK_NOT, A, 0, 0);
  sqlite3ExprSpan(A,&W->span,&Y->span);
}
%type in_op {int}
in_op(A) ::= IN.      {A = 0;}
in_op(A) ::= NOT IN.  {A = 1;}
expr(A) ::= expr(X) in_op(N) LP exprlist(Y) RP(E). [IN] {
  A = sqlite3Expr(TK_IN, X, 0, 0);
  if( A ) A->pList = Y;
  if( N ) A = sqlite3Expr(TK_NOT, A, 0, 0);
  sqlite3ExprSpan(A,&X->span,&E);
}






expr(A) ::= expr(X) in_op(N) LP select(Y) RP(E).  [IN] {
  A = sqlite3Expr(TK_IN, X, 0, 0);
  if( A ) A->pSelect = Y;
  if( N ) A = sqlite3Expr(TK_NOT, A, 0, 0);
  sqlite3ExprSpan(A,&X->span,&E);
}
expr(A) ::= expr(X) in_op(N) nm(Y) dbnm(Z). [IN] {
  SrcList *pSrc = sqlite3SrcListAppend(0,&Y,&Z);
  A = sqlite3Expr(TK_IN, X, 0, 0);
  if( A ) A->pSelect = sqlite3SelectNew(0,pSrc,0,0,0,0,0,-1,0);
  if( N ) A = sqlite3Expr(TK_NOT, A, 0, 0);
  sqlite3ExprSpan(A,&X->span,Z.z?&Z:&Y);
}









/* CASE expressions */
expr(A) ::= CASE(C) case_operand(X) case_exprlist(Y) case_else(Z) END(E). {
  A = sqlite3Expr(TK_CASE, X, Z, 0);
  if( A ) A->pList = Y;
  sqlite3ExprSpan(A, &C, &E);
}







<
<
<
<
<




















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







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
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
  A = sqlite3Expr(TK_UMINUS, X, 0, 0);
  sqlite3ExprSpan(A,&B,&X->span);
}
expr(A) ::= PLUS(B) expr(X). [UPLUS] {
  A = sqlite3Expr(TK_UPLUS, X, 0, 0);
  sqlite3ExprSpan(A,&B,&X->span);
}





%type between_op {int}
between_op(A) ::= BETWEEN.     {A = 0;}
between_op(A) ::= NOT BETWEEN. {A = 1;}
expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
  ExprList *pList = sqlite3ExprListAppend(0, X, 0);
  pList = sqlite3ExprListAppend(pList, Y, 0);
  A = sqlite3Expr(TK_BETWEEN, W, 0, 0);
  if( A ) A->pList = pList;
  if( N ) A = sqlite3Expr(TK_NOT, A, 0, 0);
  sqlite3ExprSpan(A,&W->span,&Y->span);
}
%type in_op {int}
in_op(A) ::= IN.      {A = 0;}
in_op(A) ::= NOT IN.  {A = 1;}
expr(A) ::= expr(X) in_op(N) LP exprlist(Y) RP(E). [IN] {
  A = sqlite3Expr(TK_IN, X, 0, 0);
  if( A ) A->pList = Y;
  if( N ) A = sqlite3Expr(TK_NOT, A, 0, 0);
  sqlite3ExprSpan(A,&X->span,&E);
}
%ifndef SQLITE_OMIT_SUBQUERY
  expr(A) ::= LP(B) select(X) RP(E). {
    A = sqlite3Expr(TK_SELECT, 0, 0, 0);
    if( A ) A->pSelect = X;
    sqlite3ExprSpan(A,&B,&E);
  }
  expr(A) ::= expr(X) in_op(N) LP select(Y) RP(E).  [IN] {
    A = sqlite3Expr(TK_IN, X, 0, 0);
    if( A ) A->pSelect = Y;
    if( N ) A = sqlite3Expr(TK_NOT, A, 0, 0);
    sqlite3ExprSpan(A,&X->span,&E);
  }
  expr(A) ::= expr(X) in_op(N) nm(Y) dbnm(Z). [IN] {
    SrcList *pSrc = sqlite3SrcListAppend(0,&Y,&Z);
    A = sqlite3Expr(TK_IN, X, 0, 0);
    if( A ) A->pSelect = sqlite3SelectNew(0,pSrc,0,0,0,0,0,-1,0);
    if( N ) A = sqlite3Expr(TK_NOT, A, 0, 0);
    sqlite3ExprSpan(A,&X->span,Z.z?&Z:&Y);
  }
  expr(A) ::= EXISTS(B) LP select(Y) RP(E). {
    Expr *p = A = sqlite3Expr(TK_EXISTS, 0, 0, 0);
    if( p ){
      p->pSelect = Y;
      sqlite3ExprSpan(p,&B,&E);
    }
  }
%endif // SQLITE_OMIT_SUBQUERY

/* CASE expressions */
expr(A) ::= CASE(C) case_operand(X) case_exprlist(Y) case_else(Z) END(E). {
  A = sqlite3Expr(TK_CASE, X, Z, 0);
  if( A ) A->pList = Y;
  sqlite3ExprSpan(A, &C, &E);
}
Changes to src/select.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 SELECT statements in SQLite.
**
** $Id: select.c,v 1.230 2005/01/20 13:03:10 danielk1977 Exp $
*/
#include "sqliteInt.h"


/*
** Allocate a new Select structure and return a pointer to that
** structure.







|







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 SELECT statements in SQLite.
**
** $Id: select.c,v 1.231 2005/01/20 13:36:20 drh Exp $
*/
#include "sqliteInt.h"


/*
** Allocate a new Select structure and return a pointer to that
** structure.
500
501
502
503
504
505
506

507
508
509
510
511
512
513
      break;
    }

    /* If this is a scalar select that is part of an expression, then
    ** store the results in the appropriate memory cell and break out
    ** of the scan loop.
    */

    case SRT_Mem: {
      assert( nColumn==1 );
      if( pOrderBy ){
        pushOntoSorter(pParse, v, pOrderBy);
      }else{
        sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1);
        sqlite3VdbeAddOp(v, OP_Goto, 0, iBreak);







>







500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
      break;
    }

    /* If this is a scalar select that is part of an expression, then
    ** store the results in the appropriate memory cell and break out
    ** of the scan loop.
    */
    case SRT_Exists:
    case SRT_Mem: {
      assert( nColumn==1 );
      if( pOrderBy ){
        pushOntoSorter(pParse, v, pOrderBy);
      }else{
        sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1);
        sqlite3VdbeAddOp(v, OP_Goto, 0, iBreak);
613
614
615
616
617
618
619

620
621
622
623
624
625
626
      sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
      sqlite3VdbeAddOp(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+3);
      sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, "n", P3_STATIC);
      sqlite3VdbeAddOp(v, OP_String8, 0, 0);
      sqlite3VdbeAddOp(v, OP_PutStrKey, (iParm&0x0000FFFF), 0);
      break;
    }

    case SRT_Mem: {
      assert( nColumn==1 );
      sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1);
      sqlite3VdbeAddOp(v, OP_Goto, 0, end1);
      break;
    }
    case SRT_Callback:







>







614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
      sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
      sqlite3VdbeAddOp(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+3);
      sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, "n", P3_STATIC);
      sqlite3VdbeAddOp(v, OP_String8, 0, 0);
      sqlite3VdbeAddOp(v, OP_PutStrKey, (iParm&0x0000FFFF), 0);
      break;
    }
    case SRT_Exists:
    case SRT_Mem: {
      assert( nColumn==1 );
      sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1);
      sqlite3VdbeAddOp(v, OP_Goto, 0, end1);
      break;
    }
    case SRT_Callback:
2369
2370
2371
2372
2373
2374
2375

2376
2377
2378
2379
2380
2381
2382
  pWhere = p->pWhere;
  pEList = p->pEList;
  if( pEList==0 ) goto select_end;

  /* If writing to memory or generating a set
  ** only a single column may be output.
  */

  if( (eDest==SRT_Mem || eDest==SRT_Set) && pEList->nExpr>1 ){
    sqlite3ErrorMsg(pParse, "only a single result allowed for "
       "a SELECT that is part of an expression");
    goto select_end;
  }

  /* ORDER BY is ignored for some destinations.







>







2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
  pWhere = p->pWhere;
  pEList = p->pEList;
  if( pEList==0 ) goto select_end;

  /* If writing to memory or generating a set
  ** only a single column may be output.
  */
  assert( eDest!=SRT_Exists || pEList->nExpr==1 );
  if( (eDest==SRT_Mem || eDest==SRT_Set) && pEList->nExpr>1 ){
    sqlite3ErrorMsg(pParse, "only a single result allowed for "
       "a SELECT that is part of an expression");
    goto select_end;
  }

  /* ORDER BY is ignored for some destinations.
2456
2457
2458
2459
2460
2461
2462

2463
2464
2465
2466
2467
2468
2469
  */
  if( eDest==SRT_Callback ){
    generateColumnNames(pParse, pTabList, pEList);
  }

  /* Generate code for all sub-queries in the FROM clause
  */

  for(i=0; i<pTabList->nSrc; i++){
    const char *zSavedAuthContext = 0;
    int needRestoreContext;

    if( pTabList->a[i].pSelect==0 ) continue;
    if( pTabList->a[i].zName!=0 ){
      zSavedAuthContext = pParse->zAuthContext;







>







2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
  */
  if( eDest==SRT_Callback ){
    generateColumnNames(pParse, pTabList, pEList);
  }

  /* Generate code for all sub-queries in the FROM clause
  */
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
  for(i=0; i<pTabList->nSrc; i++){
    const char *zSavedAuthContext = 0;
    int needRestoreContext;

    if( pTabList->a[i].pSelect==0 ) continue;
    if( pTabList->a[i].zName!=0 ){
      zSavedAuthContext = pParse->zAuthContext;
2482
2483
2484
2485
2486
2487
2488

2489
2490
2491
2492
2493
2494
2495
    if( eDest!=SRT_Union && eDest!=SRT_Except && eDest!=SRT_Discard ){
      pOrderBy = p->pOrderBy;
    }
    pGroupBy = p->pGroupBy;
    pHaving = p->pHaving;
    isDistinct = p->isDistinct;
  }


  /* Check for the special case of a min() or max() function by itself
  ** in the result set.
  */
  if( simpleMinMaxQuery(pParse, p, eDest, iParm) ){
    rc = 0;
    goto select_end;







>







2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
    if( eDest!=SRT_Union && eDest!=SRT_Except && eDest!=SRT_Discard ){
      pOrderBy = p->pOrderBy;
    }
    pGroupBy = p->pGroupBy;
    pHaving = p->pHaving;
    isDistinct = p->isDistinct;
  }
#endif

  /* Check for the special case of a min() or max() function by itself
  ** in the result set.
  */
  if( simpleMinMaxQuery(pParse, p, eDest, iParm) ){
    rc = 0;
    goto select_end;
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
          pKey->aColl[i] = pParse->db->pDfltColl;
        }
      }
      sqlite3VdbeChangeP3(v, addr, (char *)pKey, P3_KEYINFO_HANDOFF);
    }
  }

  /* Initialize the memory cell to NULL
  */
  if( eDest==SRT_Mem ){
    sqlite3VdbeAddOp(v, OP_String8, 0, 0);
    sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1);
  }

  /* Open a temporary table to use for the distinct set.
  */
  if( isDistinct ){
    distinct = pParse->nTab++;







|

|
|







2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
          pKey->aColl[i] = pParse->db->pDfltColl;
        }
      }
      sqlite3VdbeChangeP3(v, addr, (char *)pKey, P3_KEYINFO_HANDOFF);
    }
  }

  /* Initialize the memory cell to NULL for SRT_Mem or 0 for SRT_Exists
  */
  if( eDest==SRT_Mem || eDest==SRT_Exists ){
    sqlite3VdbeAddOp(v, eDest==SRT_Mem ? OP_String8 : OP_Integer, 0, 0);
    sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1);
  }

  /* Open a temporary table to use for the distinct set.
  */
  if( isDistinct ){
    distinct = pParse->nTab++;
Changes to src/sqliteInt.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
** 2001 September 15
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    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.358 2005/01/20 02:14:31 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** Cursor support is turned off unless the SQLITE_ENABLE_CURSOR option
** is defined.













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
** 2001 September 15
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    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.359 2005/01/20 13:36:20 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** Cursor support is turned off unless the SQLITE_ENABLE_CURSOR option
** is defined.
828
829
830
831
832
833
834

835
836
837
838
839
840
841
/*
** The following are the meanings of bits in the Expr.flags field.
*/
#define EP_FromJoin     0x0001  /* Originated in ON or USING clause of a join */
#define EP_Agg          0x0002  /* Contains one or more aggregate functions */
#define EP_Resolved     0x0004  /* IDs have been resolved to COLUMNs */
#define EP_Error        0x0008  /* Expression contains one or more errors */


/*
** These macros can be used to test, set, or clear bits in the 
** Expr.flags field.
*/
#define ExprHasProperty(E,P)     (((E)->flags&(P))==(P))
#define ExprHasAnyProperty(E,P)  (((E)->flags&(P))!=0)







>







828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
/*
** The following are the meanings of bits in the Expr.flags field.
*/
#define EP_FromJoin     0x0001  /* Originated in ON or USING clause of a join */
#define EP_Agg          0x0002  /* Contains one or more aggregate functions */
#define EP_Resolved     0x0004  /* IDs have been resolved to COLUMNs */
#define EP_Error        0x0008  /* Expression contains one or more errors */
#define EP_Not          0x0010  /* Operator preceeded by NOT */

/*
** These macros can be used to test, set, or clear bits in the 
** Expr.flags field.
*/
#define ExprHasProperty(E,P)     (((E)->flags&(P))==(P))
#define ExprHasAnyProperty(E,P)  (((E)->flags&(P))!=0)
1012
1013
1014
1015
1016
1017
1018

1019
1020
1021
1022
1023
1024
1025
#define SRT_Union        5  /* Store result as keys in a table */
#define SRT_Except       6  /* Remove result from a UNION table */
#define SRT_Table        7  /* Store result as data with a unique key */
#define SRT_TempTable    8  /* Store result in a trasient table */
#define SRT_Discard      9  /* Do not save the results anywhere */
#define SRT_Sorter      10  /* Store results in the sorter */
#define SRT_Subroutine  11  /* Call a subroutine to handle results */


/*
** When a SELECT uses aggregate functions (like "count(*)" or "avg(f1)")
** we have to do some additional analysis of expressions.  An instance
** of the following structure holds information about a single subexpression
** somewhere in the SELECT statement.  An array of these structures holds
** all the information we need to generate code for aggregate







>







1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
#define SRT_Union        5  /* Store result as keys in a table */
#define SRT_Except       6  /* Remove result from a UNION table */
#define SRT_Table        7  /* Store result as data with a unique key */
#define SRT_TempTable    8  /* Store result in a trasient table */
#define SRT_Discard      9  /* Do not save the results anywhere */
#define SRT_Sorter      10  /* Store results in the sorter */
#define SRT_Subroutine  11  /* Call a subroutine to handle results */
#define SRT_Exists      12  /* Put 0 or 1 in a memory cell */

/*
** When a SELECT uses aggregate functions (like "count(*)" or "avg(f1)")
** we have to do some additional analysis of expressions.  An instance
** of the following structure holds information about a single subexpression
** somewhere in the SELECT statement.  An array of these structures holds
** all the information we need to generate code for aggregate
Changes to tool/mkkeywordhash.c.
75
76
77
78
79
80
81





82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#else
#  define PRAGMA     512
#endif
#ifdef SQLITE_OMIT_REINDEX
#  define REINDEX    0
#else
#  define REINDEX    1024





#endif
#ifdef SQLITE_OMIT_TRIGGER
#  define TRIGGER    0
#else
#  define TRIGGER    2048
#endif
#ifdef SQLITE_OMIT_VACUUM
#  define VACUUM     0
#else
#  define VACUUM     4096
#endif
#ifdef SQLITE_OMIT_VIEW
#  define VIEW       0
#else
#  define VIEW       8192
#endif


/*
** These are the keywords
*/
static Keyword aKeywordTable[] = {







>
>
>
>
>




|




|




|







75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#else
#  define PRAGMA     512
#endif
#ifdef SQLITE_OMIT_REINDEX
#  define REINDEX    0
#else
#  define REINDEX    1024
#endif
#ifdef SQLITE_OMIT_SUBQUERY
#  define SUBQUERY   0
#else
#  define SUBQUERY   2048
#endif
#ifdef SQLITE_OMIT_TRIGGER
#  define TRIGGER    0
#else
#  define TRIGGER    4096
#endif
#ifdef SQLITE_OMIT_VACUUM
#  define VACUUM     0
#else
#  define VACUUM     8192
#endif
#ifdef SQLITE_OMIT_VIEW
#  define VIEW       0
#else
#  define VIEW       16384
#endif


/*
** These are the keywords
*/
static Keyword aKeywordTable[] = {
142
143
144
145
146
147
148

149
150
151
152
153
154
155
  { "DROP",             "TK_DROP",         ALWAYS                 },
  { "END",              "TK_END",          ALWAYS                 },
  { "EACH",             "TK_EACH",         TRIGGER                },
  { "ELSE",             "TK_ELSE",         ALWAYS                 },
  { "ESCAPE",           "TK_ESCAPE",       ALWAYS                 },
  { "EXCEPT",           "TK_EXCEPT",       COMPOUND               },
  { "EXCLUSIVE",        "TK_EXCLUSIVE",    ALWAYS                 },

  { "EXPLAIN",          "TK_EXPLAIN",      EXPLAIN                },
  { "FAIL",             "TK_FAIL",         CONFLICT|TRIGGER       },
  { "FETCH",            "TK_FETCH",        CURSOR                 },
  { "FIRST",            "TK_FIRST",        CURSOR                 },
  { "FOR",              "TK_FOR",          TRIGGER|CURSOR         },
  { "FOREIGN",          "TK_FOREIGN",      FKEY                   },
  { "FROM",             "TK_FROM",         ALWAYS                 },







>







147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
  { "DROP",             "TK_DROP",         ALWAYS                 },
  { "END",              "TK_END",          ALWAYS                 },
  { "EACH",             "TK_EACH",         TRIGGER                },
  { "ELSE",             "TK_ELSE",         ALWAYS                 },
  { "ESCAPE",           "TK_ESCAPE",       ALWAYS                 },
  { "EXCEPT",           "TK_EXCEPT",       COMPOUND               },
  { "EXCLUSIVE",        "TK_EXCLUSIVE",    ALWAYS                 },
  { "EXISTS",           "TK_EXISTS",       SUBQUERY               },
  { "EXPLAIN",          "TK_EXPLAIN",      EXPLAIN                },
  { "FAIL",             "TK_FAIL",         CONFLICT|TRIGGER       },
  { "FETCH",            "TK_FETCH",        CURSOR                 },
  { "FIRST",            "TK_FIRST",        CURSOR                 },
  { "FOR",              "TK_FOR",          TRIGGER|CURSOR         },
  { "FOREIGN",          "TK_FOREIGN",      FKEY                   },
  { "FROM",             "TK_FROM",         ALWAYS                 },