/ Check-in [d30fdf0f]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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 | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: d30fdf0f2c24cb74b48fab9b83fba4e4b2fe878a
User & Date: drh 2005-01-20 13:36:20
Context
2005-01-20
22:48
Bug fixes and enhancements entered while on jury recess. (CVS 2246) check-in: 38401dfb 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: d30fdf0f user: drh tags: trunk
13:03
Remove a few more lines of code when SQLITE_OMIT_** macros are defined. (CVS 2244) check-in: 417bbba9 user: danielk1977 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
....
1172
1173
1174
1175
1176
1177
1178

1179
1180
1181
1182
1183
1184
1185
....
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
....
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
**    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.
**
................................................................................
** 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;
................................................................................
          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. */
................................................................................
        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.
*/







|







 







>







 







>









>
>







|
>
>
>
>
>
>
>
>
>
>







 







>










>




>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
....
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
....
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
**    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.
**
................................................................................
** 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;
................................................................................
          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. */
................................................................................
        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
...
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
...
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
...
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
**
*************************************************************************
** 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 ){
................................................................................
    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($$);}
................................................................................
  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);
................................................................................
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);
}







|







 







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







 







<
<
<
<
<







 







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







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
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
...
690
691
692
693
694
695
696





697
698
699
700
701
702
703
...
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
**
*************************************************************************
** 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 ){
................................................................................
    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($$);}
................................................................................
  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);
................................................................................
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
...
500
501
502
503
504
505
506

507
508
509
510
511
512
513
...
613
614
615
616
617
618
619

620
621
622
623
624
625
626
....
2369
2370
2371
2372
2373
2374
2375

2376
2377
2378
2379
2380
2381
2382
....
2456
2457
2458
2459
2460
2461
2462

2463
2464
2465
2466
2467
2468
2469
....
2482
2483
2484
2485
2486
2487
2488

2489
2490
2491
2492
2493
2494
2495
....
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
**    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.
................................................................................
      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);
................................................................................
      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:
................................................................................
  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.
................................................................................
  */
  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;
................................................................................
    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;
................................................................................
          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++;







|







 







>







 







>







 







>







 







>







 







>







 







|

|
|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
...
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
....
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
....
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
....
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
....
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
**    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.
................................................................................
      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);
................................................................................
      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:
................................................................................
  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.
................................................................................
  */
  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;
................................................................................
    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;
................................................................................
          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.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
828
829
830
831
832
833
834

835
836
837
838
839
840
841
....
1012
1013
1014
1015
1016
1017
1018

1019
1020
1021
1022
1023
1024
1025
**    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.
................................................................................
/*
** 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)
................................................................................
#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







|







 







>







 







>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
....
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
**    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.
................................................................................
/*
** 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)
................................................................................
#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
...
142
143
144
145
146
147
148

149
150
151
152
153
154
155
#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[] = {
................................................................................
  { "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                 },







>
>
>
>
>




|




|




|







 







>







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
...
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#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[] = {
................................................................................
  { "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                 },