engine/sqlite/src/select.cpp
author Lars Persson <lars.persson@embeddev.se>
Wed, 31 Mar 2010 18:09:02 +0200
changeset 64 b52f6033af15
parent 2 29cda98b007e
permissions -rw-r--r--
Add so image conversion is done in feedinfo if image already exist. Check in feedengine if image exist from previous database(files might exist, even though the db is corrupt.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     1
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     2
** 2001 September 15
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     3
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     4
** The author disclaims copyright to this source code.  In place of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     5
** a legal notice, here is a blessing:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     6
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     7
**    May you do good and not evil.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     8
**    May you find forgiveness for yourself and forgive others.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     9
**    May you share freely, never taking more than you give.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    10
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    11
*************************************************************************
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    12
** This file contains C code routines that are called by the parser
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    13
** to handle SELECT statements in SQLite.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    14
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    15
** $Id: select.cpp 1282 2008-11-13 09:31:33Z LarsPson $
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    16
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    17
#include "sqliteInt.h"
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    18
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    19
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    20
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    21
** Delete all the content of a Select structure but do not deallocate
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    22
** the select structure itself.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    23
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    24
static void clearSelect(Select *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    25
  sqlite3ExprListDelete(p->pEList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    26
  sqlite3SrcListDelete(p->pSrc);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    27
  sqlite3ExprDelete(p->pWhere);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    28
  sqlite3ExprListDelete(p->pGroupBy);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    29
  sqlite3ExprDelete(p->pHaving);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    30
  sqlite3ExprListDelete(p->pOrderBy);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    31
  sqlite3SelectDelete(p->pPrior);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    32
  sqlite3ExprDelete(p->pLimit);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    33
  sqlite3ExprDelete(p->pOffset);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    34
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    35
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    36
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    37
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    38
** Allocate a new Select structure and return a pointer to that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    39
** structure.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    40
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    41
Select *sqlite3SelectNew(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    42
  Parse *pParse,        /* Parsing context */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    43
  ExprList *pEList,     /* which columns to include in the result */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    44
  SrcList *pSrc,        /* the FROM clause -- which tables to scan */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    45
  Expr *pWhere,         /* the WHERE clause */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    46
  ExprList *pGroupBy,   /* the GROUP BY clause */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    47
  Expr *pHaving,        /* the HAVING clause */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    48
  ExprList *pOrderBy,   /* the ORDER BY clause */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    49
  int isDistinct,       /* true if the DISTINCT keyword is present */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    50
  Expr *pLimit,         /* LIMIT value.  NULL means not used */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    51
  Expr *pOffset         /* OFFSET value.  NULL means no offset */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    52
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    53
  Select *pNew;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    54
  Select standin;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    55
  sqlite3 *db = pParse->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    56
  pNew = (Select*)sqlite3DbMallocZero(db, sizeof(*pNew) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    57
  assert( !pOffset || pLimit );   /* Can't have OFFSET without LIMIT. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    58
  if( pNew==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    59
    pNew = &standin;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    60
    memset(pNew, 0, sizeof(*pNew));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    61
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    62
  if( pEList==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    63
    pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db,TK_ALL,0,0,0), 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    64
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    65
  pNew->pEList = pEList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    66
  pNew->pSrc = pSrc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    67
  pNew->pWhere = pWhere;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    68
  pNew->pGroupBy = pGroupBy;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    69
  pNew->pHaving = pHaving;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    70
  pNew->pOrderBy = pOrderBy;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    71
  pNew->isDistinct = isDistinct;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    72
  pNew->op = TK_SELECT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    73
  assert( pOffset==0 || pLimit!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    74
  pNew->pLimit = pLimit;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    75
  pNew->pOffset = pOffset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    76
  pNew->iLimit = -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    77
  pNew->iOffset = -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    78
  pNew->addrOpenEphm[0] = -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    79
  pNew->addrOpenEphm[1] = -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    80
  pNew->addrOpenEphm[2] = -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    81
  if( pNew==&standin) {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    82
    clearSelect(pNew);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    83
    pNew = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    84
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    85
  return pNew;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    86
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    87
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    88
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    89
** Delete the given Select structure and all of its substructures.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    90
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    91
void sqlite3SelectDelete(Select *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    92
  if( p ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    93
    clearSelect(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    94
    sqlite3_free(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    95
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    96
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    97
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    98
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    99
** Given 1 to 3 identifiers preceeding the JOIN keyword, determine the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   100
** type of join.  Return an integer constant that expresses that type
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   101
** in terms of the following bit values:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   102
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   103
**     JT_INNER
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   104
**     JT_CROSS
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   105
**     JT_OUTER
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   106
**     JT_NATURAL
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   107
**     JT_LEFT
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   108
**     JT_RIGHT
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   109
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   110
** A full outer join is the combination of JT_LEFT and JT_RIGHT.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   111
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   112
** If an illegal or unsupported join type is seen, then still return
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   113
** a join type, but put an error in the pParse structure.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   114
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   115
int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   116
  int jointype = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   117
  Token *apAll[3];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   118
  Token *p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   119
  static const struct {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   120
    const char zKeyword[8];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   121
    u8 nChar;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   122
    u8 code;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   123
  } keywords[] = {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   124
    { "natural", 7, JT_NATURAL },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   125
    { "left",    4, JT_LEFT|JT_OUTER },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   126
    { "right",   5, JT_RIGHT|JT_OUTER },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   127
    { "full",    4, JT_LEFT|JT_RIGHT|JT_OUTER },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   128
    { "outer",   5, JT_OUTER },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   129
    { "inner",   5, JT_INNER },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   130
    { "cross",   5, JT_INNER|JT_CROSS },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   131
  };
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   132
  int i, j;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   133
  apAll[0] = pA;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   134
  apAll[1] = pB;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   135
  apAll[2] = pC;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   136
  for(i=0; i<3 && apAll[i]; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   137
    p = apAll[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   138
    for(j=0; j<sizeof(keywords)/sizeof(keywords[0]); j++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   139
      if( p->n==keywords[j].nChar 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   140
          && sqlite3StrNICmp((char*)p->z, keywords[j].zKeyword, p->n)==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   141
        jointype |= keywords[j].code;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   142
        break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   143
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   144
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   145
    if( j>=sizeof(keywords)/sizeof(keywords[0]) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   146
      jointype |= JT_ERROR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   147
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   148
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   149
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   150
  if(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   151
     (jointype & (JT_INNER|JT_OUTER))==(JT_INNER|JT_OUTER) ||
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   152
     (jointype & JT_ERROR)!=0
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   153
  ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   154
    const char *zSp1 = " ";
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   155
    const char *zSp2 = " ";
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   156
    if( pB==0 ){ zSp1++; }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   157
    if( pC==0 ){ zSp2++; }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   158
    sqlite3ErrorMsg(pParse, "unknown or unsupported join type: "
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   159
       "%T%s%T%s%T", pA, zSp1, pB, zSp2, pC);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   160
    jointype = JT_INNER;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   161
  }else if( jointype & JT_RIGHT ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   162
    sqlite3ErrorMsg(pParse, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   163
      "RIGHT and FULL OUTER JOINs are not currently supported");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   164
    jointype = JT_INNER;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   165
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   166
  return jointype;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   167
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   168
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   169
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   170
** Return the index of a column in a table.  Return -1 if the column
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   171
** is not contained in the table.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   172
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   173
static int columnIndex(Table *pTab, const char *zCol){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   174
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   175
  for(i=0; i<pTab->nCol; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   176
    if( sqlite3StrICmp(pTab->aCol[i].zName, zCol)==0 ) return i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   177
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   178
  return -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   179
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   180
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   181
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   182
** Set the value of a token to a '\000'-terminated string.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   183
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   184
static void setToken(Token *p, const char *z){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   185
  p->z = (u8*)z;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   186
  p->n = z ? strlen(z) : 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   187
  p->dyn = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   188
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   189
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   190
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   191
** Set the token to the double-quoted and escaped version of the string pointed
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   192
** to by z. For example;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   193
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   194
**    {a"bc}  ->  {"a""bc"}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   195
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   196
static void setQuotedToken(Parse *pParse, Token *p, const char *z){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   197
  p->z = (u8 *)sqlite3MPrintf(0, "\"%w\"", z);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   198
  p->dyn = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   199
  if( p->z ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   200
    p->n = strlen((char *)p->z);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   201
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   202
    pParse->db->mallocFailed = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   203
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   204
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   205
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   206
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   207
** Create an expression node for an identifier with the name of zName
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   208
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   209
Expr *sqlite3CreateIdExpr(Parse *pParse, const char *zName){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   210
  Token dummy;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   211
  setToken(&dummy, zName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   212
  return sqlite3PExpr(pParse, TK_ID, 0, 0, &dummy);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   213
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   214
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   215
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   216
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   217
** Add a term to the WHERE expression in *ppExpr that requires the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   218
** zCol column to be equal in the two tables pTab1 and pTab2.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   219
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   220
static void addWhereTerm(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   221
  Parse *pParse,           /* Parsing context */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   222
  const char *zCol,        /* Name of the column */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   223
  const Table *pTab1,      /* First table */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   224
  const char *zAlias1,     /* Alias for first table.  May be NULL */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   225
  const Table *pTab2,      /* Second table */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   226
  const char *zAlias2,     /* Alias for second table.  May be NULL */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   227
  int iRightJoinTable,     /* VDBE cursor for the right table */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   228
  Expr **ppExpr            /* Add the equality term to this expression */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   229
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   230
  Expr *pE1a, *pE1b, *pE1c;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   231
  Expr *pE2a, *pE2b, *pE2c;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   232
  Expr *pE;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   233
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   234
  pE1a = sqlite3CreateIdExpr(pParse, zCol);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   235
  pE2a = sqlite3CreateIdExpr(pParse, zCol);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   236
  if( zAlias1==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   237
    zAlias1 = pTab1->zName;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   238
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   239
  pE1b = sqlite3CreateIdExpr(pParse, zAlias1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   240
  if( zAlias2==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   241
    zAlias2 = pTab2->zName;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   242
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   243
  pE2b = sqlite3CreateIdExpr(pParse, zAlias2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   244
  pE1c = sqlite3PExpr(pParse, TK_DOT, pE1b, pE1a, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   245
  pE2c = sqlite3PExpr(pParse, TK_DOT, pE2b, pE2a, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   246
  pE = sqlite3PExpr(pParse, TK_EQ, pE1c, pE2c, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   247
  if( pE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   248
    ExprSetProperty(pE, EP_FromJoin);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   249
    pE->iRightJoinTable = iRightJoinTable;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   250
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   251
  *ppExpr = sqlite3ExprAnd(pParse->db,*ppExpr, pE);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   252
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   253
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   254
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   255
** Set the EP_FromJoin property on all terms of the given expression.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   256
** And set the Expr.iRightJoinTable to iTable for every term in the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   257
** expression.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   258
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   259
** The EP_FromJoin property is used on terms of an expression to tell
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   260
** the LEFT OUTER JOIN processing logic that this term is part of the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   261
** join restriction specified in the ON or USING clause and not a part
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   262
** of the more general WHERE clause.  These terms are moved over to the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   263
** WHERE clause during join processing but we need to remember that they
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   264
** originated in the ON or USING clause.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   265
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   266
** The Expr.iRightJoinTable tells the WHERE clause processing that the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   267
** expression depends on table iRightJoinTable even if that table is not
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   268
** explicitly mentioned in the expression.  That information is needed
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   269
** for cases like this:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   270
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   271
**    SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.b AND t1.x=5
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   272
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   273
** The where clause needs to defer the handling of the t1.x=5
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   274
** term until after the t2 loop of the join.  In that way, a
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   275
** NULL t2 row will be inserted whenever t1.x!=5.  If we do not
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   276
** defer the handling of t1.x=5, it will be processed immediately
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   277
** after the t1 loop and rows with t1.x!=5 will never appear in
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   278
** the output, which is incorrect.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   279
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   280
static void setJoinExpr(Expr *p, int iTable){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   281
  while( p ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   282
    ExprSetProperty(p, EP_FromJoin);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   283
    p->iRightJoinTable = iTable;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   284
    setJoinExpr(p->pLeft, iTable);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   285
    p = p->pRight;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   286
  } 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   287
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   288
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   289
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   290
** This routine processes the join information for a SELECT statement.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   291
** ON and USING clauses are converted into extra terms of the WHERE clause.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   292
** NATURAL joins also create extra WHERE clause terms.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   293
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   294
** The terms of a FROM clause are contained in the Select.pSrc structure.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   295
** The left most table is the first entry in Select.pSrc.  The right-most
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   296
** table is the last entry.  The join operator is held in the entry to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   297
** the left.  Thus entry 0 contains the join operator for the join between
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   298
** entries 0 and 1.  Any ON or USING clauses associated with the join are
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   299
** also attached to the left entry.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   300
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   301
** This routine returns the number of errors encountered.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   302
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   303
static int sqliteProcessJoin(Parse *pParse, Select *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   304
  SrcList *pSrc;                  /* All tables in the FROM clause */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   305
  int i, j;                       /* Loop counters */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   306
  SrcList::SrcList_item *pLeft;     /* Left table being joined */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   307
  SrcList::SrcList_item *pRight;    /* Right table being joined */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   308
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   309
  pSrc = p->pSrc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   310
  pLeft = &pSrc->a[0];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   311
  pRight = &pLeft[1];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   312
  for(i=0; i<pSrc->nSrc-1; i++, pRight++, pLeft++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   313
    Table *pLeftTab = pLeft->pTab;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   314
    Table *pRightTab = pRight->pTab;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   315
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   316
    if( pLeftTab==0 || pRightTab==0 ) continue;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   317
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   318
    /* When the NATURAL keyword is present, add WHERE clause terms for
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   319
    ** every column that the two tables have in common.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   320
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   321
    if( pRight->jointype & JT_NATURAL ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   322
      if( pRight->pOn || pRight->pUsing ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   323
        sqlite3ErrorMsg(pParse, "a NATURAL join may not have "
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   324
           "an ON or USING clause", 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   325
        return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   326
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   327
      for(j=0; j<pLeftTab->nCol; j++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   328
        char *zName = pLeftTab->aCol[j].zName;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   329
        if( columnIndex(pRightTab, zName)>=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   330
          addWhereTerm(pParse, zName, pLeftTab, pLeft->zAlias, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   331
                              pRightTab, pRight->zAlias,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   332
                              pRight->iCursor, &p->pWhere);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   333
          
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   334
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   335
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   336
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   337
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   338
    /* Disallow both ON and USING clauses in the same join
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   339
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   340
    if( pRight->pOn && pRight->pUsing ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   341
      sqlite3ErrorMsg(pParse, "cannot have both ON and USING "
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   342
        "clauses in the same join");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   343
      return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   344
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   345
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   346
    /* Add the ON clause to the end of the WHERE clause, connected by
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   347
    ** an AND operator.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   348
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   349
    if( pRight->pOn ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   350
      setJoinExpr(pRight->pOn, pRight->iCursor);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   351
      p->pWhere = sqlite3ExprAnd(pParse->db, p->pWhere, pRight->pOn);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   352
      pRight->pOn = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   353
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   354
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   355
    /* Create extra terms on the WHERE clause for each column named
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   356
    ** in the USING clause.  Example: If the two tables to be joined are 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   357
    ** A and B and the USING clause names X, Y, and Z, then add this
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   358
    ** to the WHERE clause:    A.X=B.X AND A.Y=B.Y AND A.Z=B.Z
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   359
    ** Report an error if any column mentioned in the USING clause is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   360
    ** not contained in both tables to be joined.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   361
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   362
    if( pRight->pUsing ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   363
      IdList *pList = pRight->pUsing;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   364
      for(j=0; j<pList->nId; j++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   365
        char *zName = pList->a[j].zName;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   366
        if( columnIndex(pLeftTab, zName)<0 || columnIndex(pRightTab, zName)<0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   367
          sqlite3ErrorMsg(pParse, "cannot join using column %s - column "
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   368
            "not present in both tables", zName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   369
          return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   370
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   371
        addWhereTerm(pParse, zName, pLeftTab, pLeft->zAlias, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   372
                            pRightTab, pRight->zAlias,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   373
                            pRight->iCursor, &p->pWhere);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   374
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   375
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   376
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   377
  return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   378
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   379
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   380
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   381
** Insert code into "v" that will push the record on the top of the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   382
** stack into the sorter.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   383
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   384
static void pushOntoSorter(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   385
  Parse *pParse,         /* Parser context */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   386
  ExprList *pOrderBy,    /* The ORDER BY clause */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   387
  Select *pSelect        /* The whole SELECT statement */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   388
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   389
  Vdbe *v = pParse->pVdbe;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   390
  sqlite3ExprCodeExprList(pParse, pOrderBy);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   391
  sqlite3VdbeAddOp(v, OP_Sequence, pOrderBy->iECursor, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   392
  sqlite3VdbeAddOp(v, OP_Pull, pOrderBy->nExpr + 1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   393
  sqlite3VdbeAddOp(v, OP_MakeRecord, pOrderBy->nExpr + 2, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   394
  sqlite3VdbeAddOp(v, OP_IdxInsert, pOrderBy->iECursor, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   395
  if( pSelect->iLimit>=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   396
    int addr1, addr2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   397
    addr1 = sqlite3VdbeAddOp(v, OP_IfMemZero, pSelect->iLimit+1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   398
    sqlite3VdbeAddOp(v, OP_MemIncr, -1, pSelect->iLimit+1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   399
    addr2 = sqlite3VdbeAddOp(v, OP_Goto, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   400
    sqlite3VdbeJumpHere(v, addr1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   401
    sqlite3VdbeAddOp(v, OP_Last, pOrderBy->iECursor, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   402
    sqlite3VdbeAddOp(v, OP_Delete, pOrderBy->iECursor, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   403
    sqlite3VdbeJumpHere(v, addr2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   404
    pSelect->iLimit = -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   405
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   406
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   407
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   408
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   409
** Add code to implement the OFFSET
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   410
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   411
static void codeOffset(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   412
  Vdbe *v,          /* Generate code into this VM */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   413
  Select *p,        /* The SELECT statement being coded */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   414
  int iContinue,    /* Jump here to skip the current record */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   415
  int nPop          /* Number of times to pop stack when jumping */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   416
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   417
  if( p->iOffset>=0 && iContinue!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   418
    int addr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   419
    sqlite3VdbeAddOp(v, OP_MemIncr, -1, p->iOffset);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   420
    addr = sqlite3VdbeAddOp(v, OP_IfMemNeg, p->iOffset, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   421
    if( nPop>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   422
      sqlite3VdbeAddOp(v, OP_Pop, nPop, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   423
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   424
    sqlite3VdbeAddOp(v, OP_Goto, 0, iContinue);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   425
    VdbeComment((v, "# skip OFFSET records"));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   426
    sqlite3VdbeJumpHere(v, addr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   427
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   428
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   429
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   430
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   431
** Add code that will check to make sure the top N elements of the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   432
** stack are distinct.  iTab is a sorting index that holds previously
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   433
** seen combinations of the N values.  A new entry is made in iTab
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   434
** if the current N values are new.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   435
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   436
** A jump to addrRepeat is made and the N+1 values are popped from the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   437
** stack if the top N elements are not distinct.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   438
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   439
static void codeDistinct(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   440
  Vdbe *v,           /* Generate code into this VM */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   441
  int iTab,          /* A sorting index used to test for distinctness */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   442
  int addrRepeat,    /* Jump to here if not distinct */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   443
  int N              /* The top N elements of the stack must be distinct */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   444
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   445
  sqlite3VdbeAddOp(v, OP_MakeRecord, -N, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   446
  sqlite3VdbeAddOp(v, OP_Distinct, iTab, sqlite3VdbeCurrentAddr(v)+3);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   447
  sqlite3VdbeAddOp(v, OP_Pop, N+1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   448
  sqlite3VdbeAddOp(v, OP_Goto, 0, addrRepeat);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   449
  VdbeComment((v, "# skip indistinct records"));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   450
  sqlite3VdbeAddOp(v, OP_IdxInsert, iTab, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   451
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   452
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   453
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   454
** Generate an error message when a SELECT is used within a subexpression
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   455
** (example:  "a IN (SELECT * FROM table)") but it has more than 1 result
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   456
** column.  We do this in a subroutine because the error occurs in multiple
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   457
** places.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   458
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   459
static int checkForMultiColumnSelectError(Parse *pParse, int eDest, int nExpr){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   460
  if( nExpr>1 && (eDest==SRT_Mem || eDest==SRT_Set) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   461
    sqlite3ErrorMsg(pParse, "only a single result allowed for "
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   462
       "a SELECT that is part of an expression");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   463
    return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   464
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   465
    return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   466
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   467
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   468
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   469
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   470
** This routine generates the code for the inside of the inner loop
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   471
** of a SELECT.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   472
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   473
** If srcTab and nColumn are both zero, then the pEList expressions
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   474
** are evaluated in order to get the data for this row.  If nColumn>0
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   475
** then data is pulled from srcTab and pEList is used only to get the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   476
** datatypes for each column.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   477
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   478
static int selectInnerLoop(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   479
  Parse *pParse,          /* The parser context */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   480
  Select *p,              /* The complete select statement being coded */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   481
  ExprList *pEList,       /* List of values being extracted */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   482
  int srcTab,             /* Pull data from this table */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   483
  int nColumn,            /* Number of columns in the source table */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   484
  ExprList *pOrderBy,     /* If not NULL, sort results using this key */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   485
  int distinct,           /* If >=0, make sure results are distinct */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   486
  int eDest,              /* How to dispose of the results */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   487
  int iParm,              /* An argument to the disposal method */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   488
  int iContinue,          /* Jump here to continue with next row */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   489
  int iBreak,             /* Jump here to break out of the inner loop */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   490
  char *aff               /* affinity string if eDest is SRT_Union */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   491
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   492
  Vdbe *v = pParse->pVdbe;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   493
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   494
  int hasDistinct;        /* True if the DISTINCT keyword is present */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   495
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   496
  if( v==0 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   497
  assert( pEList!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   498
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   499
  /* If there was a LIMIT clause on the SELECT statement, then do the check
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   500
  ** to see if this row should be output.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   501
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   502
  hasDistinct = distinct>=0 && pEList->nExpr>0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   503
  if( pOrderBy==0 && !hasDistinct ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   504
    codeOffset(v, p, iContinue, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   505
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   506
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   507
  /* Pull the requested columns.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   508
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   509
  if( nColumn>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   510
    for(i=0; i<nColumn; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   511
      sqlite3VdbeAddOp(v, OP_Column, srcTab, i);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   512
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   513
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   514
    nColumn = pEList->nExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   515
    sqlite3ExprCodeExprList(pParse, pEList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   516
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   517
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   518
  /* If the DISTINCT keyword was present on the SELECT statement
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   519
  ** and this row has been seen before, then do not make this row
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   520
  ** part of the result.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   521
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   522
  if( hasDistinct ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   523
    assert( pEList!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   524
    assert( pEList->nExpr==nColumn );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   525
    codeDistinct(v, distinct, iContinue, nColumn);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   526
    if( pOrderBy==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   527
      codeOffset(v, p, iContinue, nColumn);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   528
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   529
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   530
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   531
  if( checkForMultiColumnSelectError(pParse, eDest, pEList->nExpr) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   532
    return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   533
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   534
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   535
  switch( eDest ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   536
    /* In this mode, write each query result to the key of the temporary
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   537
    ** table iParm.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   538
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   539
#ifndef SQLITE_OMIT_COMPOUND_SELECT
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   540
    case SRT_Union: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   541
      sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   542
      if( aff ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   543
        sqlite3VdbeChangeP3(v, -1, aff, P3_STATIC);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   544
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   545
      sqlite3VdbeAddOp(v, OP_IdxInsert, iParm, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   546
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   547
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   548
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   549
    /* Construct a record from the query result, but instead of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   550
    ** saving that record, use it as a key to delete elements from
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   551
    ** the temporary table iParm.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   552
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   553
    case SRT_Except: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   554
      int addr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   555
      addr = sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   556
      sqlite3VdbeChangeP3(v, -1, aff, P3_STATIC);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   557
      sqlite3VdbeAddOp(v, OP_NotFound, iParm, addr+3);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   558
      sqlite3VdbeAddOp(v, OP_Delete, iParm, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   559
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   560
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   561
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   562
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   563
    /* Store the result as data using a unique key.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   564
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   565
    case SRT_Table:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   566
    case SRT_EphemTab: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   567
      sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   568
      if( pOrderBy ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   569
        pushOntoSorter(pParse, pOrderBy, p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   570
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   571
        sqlite3VdbeAddOp(v, OP_NewRowid, iParm, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   572
        sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   573
        sqlite3VdbeAddOp(v, OP_Insert, iParm, OPFLAG_APPEND);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   574
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   575
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   576
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   577
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   578
#ifndef SQLITE_OMIT_SUBQUERY
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   579
    /* If we are creating a set for an "expr IN (SELECT ...)" construct,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   580
    ** then there should be a single item on the stack.  Write this
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   581
    ** item into the set table with bogus data.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   582
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   583
    case SRT_Set: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   584
      int addr1 = sqlite3VdbeCurrentAddr(v);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   585
      int addr2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   586
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   587
      assert( nColumn==1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   588
      sqlite3VdbeAddOp(v, OP_NotNull, -1, addr1+3);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   589
      sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   590
      addr2 = sqlite3VdbeAddOp(v, OP_Goto, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   591
      p->affinity = sqlite3CompareAffinity(pEList->a[0].pExpr,(iParm>>16)&0xff);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   592
      if( pOrderBy ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   593
        /* At first glance you would think we could optimize out the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   594
        ** ORDER BY in this case since the order of entries in the set
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   595
        ** does not matter.  But there might be a LIMIT clause, in which
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   596
        ** case the order does matter */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   597
        pushOntoSorter(pParse, pOrderBy, p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   598
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   599
        sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &p->affinity, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   600
        sqlite3VdbeAddOp(v, OP_IdxInsert, (iParm&0x0000FFFF), 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   601
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   602
      sqlite3VdbeJumpHere(v, addr2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   603
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   604
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   605
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   606
    /* If any row exist in the result set, record that fact and abort.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   607
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   608
    case SRT_Exists: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   609
      sqlite3VdbeAddOp(v, OP_MemInt, 1, iParm);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   610
      sqlite3VdbeAddOp(v, OP_Pop, nColumn, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   611
      /* The LIMIT clause will terminate the loop for us */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   612
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   613
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   614
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   615
    /* If this is a scalar select that is part of an expression, then
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   616
    ** store the results in the appropriate memory cell and break out
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   617
    ** of the scan loop.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   618
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   619
    case SRT_Mem: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   620
      assert( nColumn==1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   621
      if( pOrderBy ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   622
        pushOntoSorter(pParse, pOrderBy, p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   623
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   624
        sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   625
        /* The LIMIT clause will jump out of the loop for us */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   626
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   627
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   628
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   629
#endif /* #ifndef SQLITE_OMIT_SUBQUERY */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   630
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   631
    /* Send the data to the callback function or to a subroutine.  In the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   632
    ** case of a subroutine, the subroutine itself is responsible for
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   633
    ** popping the data from the stack.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   634
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   635
    case SRT_Subroutine:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   636
    case SRT_Callback: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   637
      if( pOrderBy ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   638
        sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   639
        pushOntoSorter(pParse, pOrderBy, p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   640
      }else if( eDest==SRT_Subroutine ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   641
        sqlite3VdbeAddOp(v, OP_Gosub, 0, iParm);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   642
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   643
        sqlite3VdbeAddOp(v, OP_Callback, nColumn, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   644
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   645
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   646
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   647
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   648
#if !defined(SQLITE_OMIT_TRIGGER)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   649
    /* Discard the results.  This is used for SELECT statements inside
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   650
    ** the body of a TRIGGER.  The purpose of such selects is to call
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   651
    ** user-defined functions that have side effects.  We do not care
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   652
    ** about the actual results of the select.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   653
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   654
    default: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   655
      assert( eDest==SRT_Discard );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   656
      sqlite3VdbeAddOp(v, OP_Pop, nColumn, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   657
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   658
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   659
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   660
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   661
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   662
  /* Jump to the end of the loop if the LIMIT is reached.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   663
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   664
  if( p->iLimit>=0 && pOrderBy==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   665
    sqlite3VdbeAddOp(v, OP_MemIncr, -1, p->iLimit);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   666
    sqlite3VdbeAddOp(v, OP_IfMemZero, p->iLimit, iBreak);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   667
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   668
  return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   669
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   670
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   671
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   672
** Given an expression list, generate a KeyInfo structure that records
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   673
** the collating sequence for each expression in that expression list.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   674
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   675
** If the ExprList is an ORDER BY or GROUP BY clause then the resulting
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   676
** KeyInfo structure is appropriate for initializing a virtual index to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   677
** implement that clause.  If the ExprList is the result set of a SELECT
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   678
** then the KeyInfo structure is appropriate for initializing a virtual
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   679
** index to implement a DISTINCT test.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   680
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   681
** Space to hold the KeyInfo structure is obtain from malloc.  The calling
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   682
** function is responsible for seeing that this structure is eventually
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   683
** freed.  Add the KeyInfo structure to the P3 field of an opcode using
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   684
** P3_KEYINFO_HANDOFF is the usual way of dealing with this.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   685
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   686
static KeyInfo *keyInfoFromExprList(Parse *pParse, ExprList *pList){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   687
  sqlite3 *db = pParse->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   688
  int nExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   689
  KeyInfo *pInfo;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   690
  ExprList::ExprList_item *pItem;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   691
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   692
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   693
  nExpr = pList->nExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   694
  pInfo = (KeyInfo*)sqlite3DbMallocZero(db, sizeof(*pInfo) + nExpr*(sizeof(CollSeq*)+1) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   695
  if( pInfo ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   696
    pInfo->aSortOrder = (u8*)&pInfo->aColl[nExpr];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   697
    pInfo->nField = nExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   698
    pInfo->enc = ENC(db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   699
    for(i=0, pItem=pList->a; i<nExpr; i++, pItem++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   700
      CollSeq *pColl;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   701
      pColl = sqlite3ExprCollSeq(pParse, pItem->pExpr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   702
      if( !pColl ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   703
        pColl = db->pDfltColl;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   704
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   705
      pInfo->aColl[i] = pColl;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   706
      pInfo->aSortOrder[i] = pItem->sortOrder;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   707
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   708
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   709
  return pInfo;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   710
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   711
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   712
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   713
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   714
** If the inner loop was generated using a non-null pOrderBy argument,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   715
** then the results were placed in a sorter.  After the loop is terminated
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   716
** we need to run the sorter and output the results.  The following
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   717
** routine generates the code needed to do that.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   718
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   719
static void generateSortTail(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   720
  Parse *pParse,   /* Parsing context */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   721
  Select *p,       /* The SELECT statement */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   722
  Vdbe *v,         /* Generate code into this VDBE */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   723
  int nColumn,     /* Number of columns of data */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   724
  int eDest,       /* Write the sorted results here */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   725
  int iParm        /* Optional parameter associated with eDest */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   726
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   727
  int brk = sqlite3VdbeMakeLabel(v);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   728
  int cont = sqlite3VdbeMakeLabel(v);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   729
  int addr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   730
  int iTab;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   731
  int pseudoTab = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   732
  ExprList *pOrderBy = p->pOrderBy;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   733
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   734
  iTab = pOrderBy->iECursor;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   735
  if( eDest==SRT_Callback || eDest==SRT_Subroutine ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   736
    pseudoTab = pParse->nTab++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   737
    sqlite3VdbeAddOp(v, OP_OpenPseudo, pseudoTab, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   738
    sqlite3VdbeAddOp(v, OP_SetNumColumns, pseudoTab, nColumn);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   739
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   740
  addr = 1 + sqlite3VdbeAddOp(v, OP_Sort, iTab, brk);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   741
  codeOffset(v, p, cont, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   742
  if( eDest==SRT_Callback || eDest==SRT_Subroutine ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   743
    sqlite3VdbeAddOp(v, OP_Integer, 1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   744
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   745
  sqlite3VdbeAddOp(v, OP_Column, iTab, pOrderBy->nExpr + 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   746
  switch( eDest ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   747
    case SRT_Table:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   748
    case SRT_EphemTab: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   749
      sqlite3VdbeAddOp(v, OP_NewRowid, iParm, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   750
      sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   751
      sqlite3VdbeAddOp(v, OP_Insert, iParm, OPFLAG_APPEND);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   752
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   753
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   754
#ifndef SQLITE_OMIT_SUBQUERY
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   755
    case SRT_Set: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   756
      assert( nColumn==1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   757
      sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   758
      sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   759
      sqlite3VdbeAddOp(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+3);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   760
      sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &p->affinity, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   761
      sqlite3VdbeAddOp(v, OP_IdxInsert, (iParm&0x0000FFFF), 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   762
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   763
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   764
    case SRT_Mem: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   765
      assert( nColumn==1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   766
      sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   767
      /* The LIMIT clause will terminate the loop for us */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   768
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   769
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   770
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   771
    case SRT_Callback:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   772
    case SRT_Subroutine: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   773
      int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   774
      sqlite3VdbeAddOp(v, OP_Insert, pseudoTab, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   775
      for(i=0; i<nColumn; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   776
        sqlite3VdbeAddOp(v, OP_Column, pseudoTab, i);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   777
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   778
      if( eDest==SRT_Callback ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   779
        sqlite3VdbeAddOp(v, OP_Callback, nColumn, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   780
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   781
        sqlite3VdbeAddOp(v, OP_Gosub, 0, iParm);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   782
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   783
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   784
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   785
    default: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   786
      /* Do nothing */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   787
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   788
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   789
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   790
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   791
  /* Jump to the end of the loop when the LIMIT is reached
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   792
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   793
  if( p->iLimit>=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   794
    sqlite3VdbeAddOp(v, OP_MemIncr, -1, p->iLimit);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   795
    sqlite3VdbeAddOp(v, OP_IfMemZero, p->iLimit, brk);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   796
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   797
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   798
  /* The bottom of the loop
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   799
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   800
  sqlite3VdbeResolveLabel(v, cont);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   801
  sqlite3VdbeAddOp(v, OP_Next, iTab, addr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   802
  sqlite3VdbeResolveLabel(v, brk);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   803
  if( eDest==SRT_Callback || eDest==SRT_Subroutine ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   804
    sqlite3VdbeAddOp(v, OP_Close, pseudoTab, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   805
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   806
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   807
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   808
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   809
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   810
** Return a pointer to a string containing the 'declaration type' of the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   811
** expression pExpr. The string may be treated as static by the caller.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   812
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   813
** The declaration type is the exact datatype definition extracted from the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   814
** original CREATE TABLE statement if the expression is a column. The
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   815
** declaration type for a ROWID field is INTEGER. Exactly when an expression
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   816
** is considered a column can be complex in the presence of subqueries. The
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   817
** result-set expression in all of the following SELECT statements is 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   818
** considered a column by this function.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   819
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   820
**   SELECT col FROM tbl;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   821
**   SELECT (SELECT col FROM tbl;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   822
**   SELECT (SELECT col FROM tbl);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   823
**   SELECT abc FROM (SELECT col AS abc FROM tbl);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   824
** 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   825
** The declaration type for any expression other than a column is NULL.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   826
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   827
static const char *columnType(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   828
  NameContext *pNC, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   829
  Expr *pExpr,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   830
  const char **pzOriginDb,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   831
  const char **pzOriginTab,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   832
  const char **pzOriginCol
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   833
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   834
  char const *zType = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   835
  char const *zOriginDb = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   836
  char const *zOriginTab = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   837
  char const *zOriginCol = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   838
  int j;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   839
  if( pExpr==0 || pNC->pSrcList==0 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   840
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   841
  switch( pExpr->op ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   842
    case TK_AGG_COLUMN:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   843
    case TK_COLUMN: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   844
      /* The expression is a column. Locate the table the column is being
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   845
      ** extracted from in NameContext.pSrcList. This table may be real
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   846
      ** database table or a subquery.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   847
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   848
      Table *pTab = 0;            /* Table structure column is extracted from */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   849
      Select *pS = 0;             /* Select the column is extracted from */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   850
      int iCol = pExpr->iColumn;  /* Index of column in pTab */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   851
      while( pNC && !pTab ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   852
        SrcList *pTabList = pNC->pSrcList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   853
        for(j=0;j<pTabList->nSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   854
        if( j<pTabList->nSrc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   855
          pTab = pTabList->a[j].pTab;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   856
          pS = pTabList->a[j].pSelect;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   857
        }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   858
          pNC = pNC->pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   859
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   860
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   861
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   862
      if( pTab==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   863
        /* FIX ME:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   864
        ** This can occurs if you have something like "SELECT new.x;" inside
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   865
        ** a trigger.  In other words, if you reference the special "new"
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   866
        ** table in the result set of a select.  We do not have a good way
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   867
        ** to find the actual table type, so call it "TEXT".  This is really
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   868
        ** something of a bug, but I do not know how to fix it.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   869
        **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   870
        ** This code does not produce the correct answer - it just prevents
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   871
        ** a segfault.  See ticket #1229.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   872
        */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   873
        zType = "TEXT";
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   874
        break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   875
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   876
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   877
      assert( pTab );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   878
      if( pS ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   879
        /* The "table" is actually a sub-select or a view in the FROM clause
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   880
        ** of the SELECT statement. Return the declaration type and origin
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   881
        ** data for the result-set column of the sub-select.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   882
        */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   883
        if( iCol>=0 && iCol<pS->pEList->nExpr ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   884
          /* If iCol is less than zero, then the expression requests the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   885
          ** rowid of the sub-select or view. This expression is legal (see 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   886
          ** test case misc2.2.2) - it always evaluates to NULL.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   887
          */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   888
          NameContext sNC;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   889
          Expr *p = pS->pEList->a[iCol].pExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   890
          sNC.pSrcList = pS->pSrc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   891
          sNC.pNext = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   892
          sNC.pParse = pNC->pParse;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   893
          zType = columnType(&sNC, p, &zOriginDb, &zOriginTab, &zOriginCol); 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   894
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   895
      }else if( pTab->pSchema ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   896
        /* A real table */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   897
        assert( !pS );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   898
        if( iCol<0 ) iCol = pTab->iPKey;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   899
        assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   900
        if( iCol<0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   901
          zType = "INTEGER";
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   902
          zOriginCol = "rowid";
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   903
        }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   904
          zType = pTab->aCol[iCol].zType;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   905
          zOriginCol = pTab->aCol[iCol].zName;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   906
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   907
        zOriginTab = pTab->zName;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   908
        if( pNC->pParse ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   909
          int iDb = sqlite3SchemaToIndex(pNC->pParse->db, pTab->pSchema);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   910
          zOriginDb = pNC->pParse->db->aDb[iDb].zName;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   911
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   912
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   913
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   914
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   915
#ifndef SQLITE_OMIT_SUBQUERY
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   916
    case TK_SELECT: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   917
      /* The expression is a sub-select. Return the declaration type and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   918
      ** origin info for the single column in the result set of the SELECT
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   919
      ** statement.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   920
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   921
      NameContext sNC;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   922
      Select *pS = pExpr->pSelect;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   923
      Expr *p = pS->pEList->a[0].pExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   924
      sNC.pSrcList = pS->pSrc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   925
      sNC.pNext = pNC;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   926
      sNC.pParse = pNC->pParse;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   927
      zType = columnType(&sNC, p, &zOriginDb, &zOriginTab, &zOriginCol); 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   928
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   929
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   930
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   931
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   932
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   933
  if( pzOriginDb ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   934
    assert( pzOriginTab && pzOriginCol );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   935
    *pzOriginDb = zOriginDb;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   936
    *pzOriginTab = zOriginTab;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   937
    *pzOriginCol = zOriginCol;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   938
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   939
  return zType;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   940
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   941
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   942
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   943
** Generate code that will tell the VDBE the declaration types of columns
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   944
** in the result set.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   945
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   946
static void generateColumnTypes(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   947
  Parse *pParse,      /* Parser context */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   948
  SrcList *pTabList,  /* List of tables */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   949
  ExprList *pEList    /* Expressions defining the result set */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   950
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   951
  Vdbe *v = pParse->pVdbe;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   952
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   953
  NameContext sNC;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   954
  sNC.pSrcList = pTabList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   955
  sNC.pParse = pParse;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   956
  for(i=0; i<pEList->nExpr; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   957
    Expr *p = pEList->a[i].pExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   958
    const char *zOrigDb = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   959
    const char *zOrigTab = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   960
    const char *zOrigCol = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   961
    const char *zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   962
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   963
    /* The vdbe must make its own copy of the column-type and other 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   964
    ** column specific strings, in case the schema is reset before this
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   965
    ** virtual machine is deleted.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   966
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   967
    sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, zType, P3_TRANSIENT);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   968
    sqlite3VdbeSetColName(v, i, COLNAME_DATABASE, zOrigDb, P3_TRANSIENT);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   969
    sqlite3VdbeSetColName(v, i, COLNAME_TABLE, zOrigTab, P3_TRANSIENT);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   970
    sqlite3VdbeSetColName(v, i, COLNAME_COLUMN, zOrigCol, P3_TRANSIENT);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   971
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   972
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   973
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   974
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   975
** Generate code that will tell the VDBE the names of columns
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   976
** in the result set.  This information is used to provide the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   977
** azCol[] values in the callback.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   978
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   979
static void generateColumnNames(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   980
  Parse *pParse,      /* Parser context */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   981
  SrcList *pTabList,  /* List of tables */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   982
  ExprList *pEList    /* Expressions defining the result set */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   983
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   984
  Vdbe *v = pParse->pVdbe;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   985
  int i, j;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   986
  sqlite3 *db = pParse->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   987
  int fullNames, shortNames;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   988
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   989
#ifndef SQLITE_OMIT_EXPLAIN
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   990
  /* If this is an EXPLAIN, skip this step */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   991
  if( pParse->explain ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   992
    return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   993
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   994
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   995
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   996
  assert( v!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   997
  if( pParse->colNamesSet || v==0 || db->mallocFailed ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   998
  pParse->colNamesSet = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   999
  fullNames = (db->flags & SQLITE_FullColNames)!=0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1000
  shortNames = (db->flags & SQLITE_ShortColNames)!=0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1001
  sqlite3VdbeSetNumCols(v, pEList->nExpr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1002
  for(i=0; i<pEList->nExpr; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1003
    Expr *p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1004
    p = pEList->a[i].pExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1005
    if( p==0 ) continue;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1006
    if( pEList->a[i].zName ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1007
      char *zName = pEList->a[i].zName;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1008
      sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, strlen(zName));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1009
      continue;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1010
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1011
    if( p->op==TK_COLUMN && pTabList ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1012
      Table *pTab;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1013
      char *zCol;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1014
      int iCol = p->iColumn;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1015
      for(j=0; j<pTabList->nSrc && pTabList->a[j].iCursor!=p->iTable; j++){}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1016
      assert( j<pTabList->nSrc );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1017
      pTab = pTabList->a[j].pTab;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1018
      if( iCol<0 ) iCol = pTab->iPKey;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1019
      assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1020
      if( iCol<0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1021
        zCol = "rowid";
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1022
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1023
        zCol = pTab->aCol[iCol].zName;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1024
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1025
      if( !shortNames && !fullNames && p->span.z && p->span.z[0] ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1026
        sqlite3VdbeSetColName(v, i, COLNAME_NAME, (char*)p->span.z, p->span.n);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1027
      }else if( fullNames || (!shortNames && pTabList->nSrc>1) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1028
        char *zName = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1029
        char *zTab;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1030
 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1031
        zTab = pTabList->a[j].zAlias;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1032
        if( fullNames || zTab==0 ) zTab = pTab->zName;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1033
        sqlite3SetString(&zName, zTab, ".", zCol, (char*)0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1034
        sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, P3_DYNAMIC);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1035
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1036
        sqlite3VdbeSetColName(v, i, COLNAME_NAME, zCol, strlen(zCol));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1037
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1038
    }else if( p->span.z && p->span.z[0] ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1039
      sqlite3VdbeSetColName(v, i, COLNAME_NAME, (char*)p->span.z, p->span.n);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1040
      /* sqlite3VdbeCompressSpace(v, addr); */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1041
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1042
      char zName[30];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1043
      assert( p->op!=TK_COLUMN || pTabList==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1044
      sqlite3_snprintf(sizeof(zName), zName, "column%d", i+1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1045
      sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1046
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1047
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1048
  generateColumnTypes(pParse, pTabList, pEList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1049
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1050
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1051
#ifndef SQLITE_OMIT_COMPOUND_SELECT
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1052
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1053
** Name of the connection operator, used for error messages.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1054
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1055
static const char *selectOpName(int id){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1056
  char *z;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1057
  switch( id ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1058
    case TK_ALL:       z = "UNION ALL";   break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1059
    case TK_INTERSECT: z = "INTERSECT";   break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1060
    case TK_EXCEPT:    z = "EXCEPT";      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1061
    default:           z = "UNION";       break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1062
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1063
  return z;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1064
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1065
#endif /* SQLITE_OMIT_COMPOUND_SELECT */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1066
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1067
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1068
** Forward declaration
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1069
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1070
static int prepSelectStmt(Parse*, Select*);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1071
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1072
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1073
** Given a SELECT statement, generate a Table structure that describes
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1074
** the result set of that SELECT.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1075
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1076
Table *sqlite3ResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1077
  Table *pTab;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1078
  int i, j;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1079
  ExprList *pEList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1080
  Column *aCol, *pCol;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1081
  sqlite3 *db = pParse->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1082
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1083
  while( pSelect->pPrior ) pSelect = pSelect->pPrior;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1084
  if( prepSelectStmt(pParse, pSelect) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1085
    return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1086
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1087
  if( sqlite3SelectResolve(pParse, pSelect, 0) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1088
    return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1089
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1090
  pTab = (Table*)sqlite3DbMallocZero(db, sizeof(Table) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1091
  if( pTab==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1092
    return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1093
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1094
  pTab->nRef = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1095
  pTab->zName = zTabName ? sqlite3DbStrDup(db, zTabName) : 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1096
  pEList = pSelect->pEList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1097
  pTab->nCol = pEList->nExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1098
  assert( pTab->nCol>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1099
  pTab->aCol = aCol = (Column*)sqlite3DbMallocZero(db, sizeof(pTab->aCol[0])*pTab->nCol);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1100
  for(i=0, pCol=aCol; i<pTab->nCol; i++, pCol++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1101
    Expr *p, *pR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1102
    char *zType;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1103
    char *zName;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1104
    int nName;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1105
    CollSeq *pColl;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1106
    int cnt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1107
    NameContext sNC;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1108
    
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1109
    /* Get an appropriate name for the column
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1110
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1111
    p = pEList->a[i].pExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1112
    assert( p->pRight==0 || p->pRight->token.z==0 || p->pRight->token.z[0]!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1113
    if( (zName = pEList->a[i].zName)!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1114
      /* If the column contains an "AS <name>" phrase, use <name> as the name */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1115
      zName = sqlite3DbStrDup(db, zName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1116
    }else if( p->op==TK_DOT 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1117
              && (pR=p->pRight)!=0 && pR->token.z && pR->token.z[0] ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1118
      /* For columns of the from A.B use B as the name */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1119
      zName = sqlite3MPrintf(db, "%T", &pR->token);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1120
    }else if( p->span.z && p->span.z[0] ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1121
      /* Use the original text of the column expression as its name */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1122
      zName = sqlite3MPrintf(db, "%T", &p->span);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1123
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1124
      /* If all else fails, make up a name */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1125
      zName = sqlite3MPrintf(db, "column%d", i+1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1126
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1127
    if( !zName || db->mallocFailed ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1128
      db->mallocFailed = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1129
      sqlite3_free(zName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1130
      sqlite3DeleteTable(pTab);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1131
      return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1132
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1133
    sqlite3Dequote(zName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1134
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1135
    /* Make sure the column name is unique.  If the name is not unique,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1136
    ** append a integer to the name so that it becomes unique.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1137
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1138
    nName = strlen(zName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1139
    for(j=cnt=0; j<i; j++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1140
      if( sqlite3StrICmp(aCol[j].zName, zName)==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1141
        zName[nName] = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1142
        zName = sqlite3MPrintf(db, "%z:%d", zName, ++cnt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1143
        j = -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1144
        if( zName==0 ) break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1145
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1146
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1147
    pCol->zName = zName;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1148
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1149
    /* Get the typename, type affinity, and collating sequence for the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1150
    ** column.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1151
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1152
    memset(&sNC, 0, sizeof(sNC));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1153
    sNC.pSrcList = pSelect->pSrc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1154
    zType = sqlite3DbStrDup(db, columnType(&sNC, p, 0, 0, 0));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1155
    pCol->zType = zType;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1156
    pCol->affinity = sqlite3ExprAffinity(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1157
    pColl = sqlite3ExprCollSeq(pParse, p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1158
    if( pColl ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1159
      pCol->zColl = sqlite3DbStrDup(db, pColl->zName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1160
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1161
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1162
  pTab->iPKey = -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1163
  return pTab;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1164
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1165
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1166
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1167
** Prepare a SELECT statement for processing by doing the following
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1168
** things:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1169
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1170
**    (1)  Make sure VDBE cursor numbers have been assigned to every
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1171
**         element of the FROM clause.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1172
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1173
**    (2)  Fill in the pTabList->a[].pTab fields in the SrcList that 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1174
**         defines FROM clause.  When views appear in the FROM clause,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1175
**         fill pTabList->a[].pSelect with a copy of the SELECT statement
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1176
**         that implements the view.  A copy is made of the view's SELECT
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1177
**         statement so that we can freely modify or delete that statement
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1178
**         without worrying about messing up the presistent representation
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1179
**         of the view.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1180
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1181
**    (3)  Add terms to the WHERE clause to accomodate the NATURAL keyword
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1182
**         on joins and the ON and USING clause of joins.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1183
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1184
**    (4)  Scan the list of columns in the result set (pEList) looking
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1185
**         for instances of the "*" operator or the TABLE.* operator.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1186
**         If found, expand each "*" to be every column in every table
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1187
**         and TABLE.* to be every column in TABLE.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1188
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1189
** Return 0 on success.  If there are problems, leave an error message
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1190
** in pParse and return non-zero.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1191
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1192
static int prepSelectStmt(Parse *pParse, Select *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1193
  int i, j, k, rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1194
  SrcList *pTabList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1195
  ExprList *pEList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1196
  SrcList::SrcList_item *pFrom;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1197
  sqlite3 *db = pParse->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1198
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1199
  if( p==0 || p->pSrc==0 || db->mallocFailed ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1200
    return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1201
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1202
  pTabList = p->pSrc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1203
  pEList = p->pEList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1204
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1205
  /* Make sure cursor numbers have been assigned to all entries in
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1206
  ** the FROM clause of the SELECT statement.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1207
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1208
  sqlite3SrcListAssignCursors(pParse, p->pSrc);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1209
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1210
  /* Look up every table named in the FROM clause of the select.  If
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1211
  ** an entry of the FROM clause is a subquery instead of a table or view,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1212
  ** then create a transient table structure to describe the subquery.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1213
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1214
     Table *pTab;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1215
 for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1216
    if( pFrom->pTab!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1217
      /* This statement has already been prepared.  There is no need
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1218
      ** to go further. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1219
      assert( i==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1220
      return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1221
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1222
    if( pFrom->zName==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1223
#ifndef SQLITE_OMIT_SUBQUERY
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1224
      /* A sub-query in the FROM clause of a SELECT */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1225
      assert( pFrom->pSelect!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1226
      if( pFrom->zAlias==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1227
        pFrom->zAlias =
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1228
          sqlite3MPrintf(db, "sqlite_subquery_%p_", (void*)pFrom->pSelect);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1229
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1230
      assert( pFrom->pTab==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1231
      pFrom->pTab = pTab = 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1232
        sqlite3ResultSetOfSelect(pParse, pFrom->zAlias, pFrom->pSelect);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1233
      if( pTab==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1234
        return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1235
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1236
      /* The isEphem flag indicates that the Table structure has been
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1237
      ** dynamically allocated and may be freed at any time.  In other words,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1238
      ** pTab is not pointing to a persistent table structure that defines
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1239
      ** part of the schema. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1240
      pTab->isEphem = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1241
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1242
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1243
      /* An ordinary table or view name in the FROM clause */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1244
      assert( pFrom->pTab==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1245
      pFrom->pTab = pTab = 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1246
        sqlite3LocateTable(pParse,pFrom->zName,pFrom->zDatabase);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1247
      if( pTab==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1248
        return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1249
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1250
      pTab->nRef++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1251
#if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1252
      if( pTab->pSelect || IsVirtual(pTab) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1253
        /* We reach here if the named table is a really a view */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1254
        if( sqlite3ViewGetColumnNames(pParse, pTab) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1255
          return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1256
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1257
        /* If pFrom->pSelect!=0 it means we are dealing with a
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1258
        ** view within a view.  The SELECT structure has already been
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1259
        ** copied by the outer view so we can skip the copy step here
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1260
        ** in the inner view.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1261
        */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1262
        if( pFrom->pSelect==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1263
          pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1264
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1265
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1266
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1267
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1268
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1269
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1270
  /* Process NATURAL keywords, and ON and USING clauses of joins.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1271
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1272
  if( sqliteProcessJoin(pParse, p) ) return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1273
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1274
  /* For every "*" that occurs in the column list, insert the names of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1275
  ** all columns in all tables.  And for every TABLE.* insert the names
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1276
  ** of all columns in TABLE.  The parser inserted a special expression
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1277
  ** with the TK_ALL operator for each "*" that it found in the column list.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1278
  ** The following code just has to locate the TK_ALL expressions and expand
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1279
  ** each one to the list of all columns in all tables.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1280
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1281
  ** The first loop just checks to see if there are any "*" operators
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1282
  ** that need expanding.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1283
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1284
  for(k=0; k<pEList->nExpr; k++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1285
    Expr *pE = pEList->a[k].pExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1286
    if( pE->op==TK_ALL ) break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1287
    if( pE->op==TK_DOT && pE->pRight && pE->pRight->op==TK_ALL
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1288
         && pE->pLeft && pE->pLeft->op==TK_ID ) break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1289
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1290
  rc = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1291
  if( k<pEList->nExpr ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1292
    /*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1293
    ** If we get here it means the result set contains one or more "*"
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1294
    ** operators that need to be expanded.  Loop through each expression
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1295
    ** in the result set and expand them one by one.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1296
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1297
	  ExprList::ExprList_item *a = pEList->a;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1298
    ExprList *pNew = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1299
    int flags = pParse->db->flags;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1300
    int longNames = (flags & SQLITE_FullColNames)!=0 &&
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1301
                      (flags & SQLITE_ShortColNames)==0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1302
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1303
    for(k=0; k<pEList->nExpr; k++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1304
      Expr *pE = a[k].pExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1305
      if( pE->op!=TK_ALL &&
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1306
           (pE->op!=TK_DOT || pE->pRight==0 || pE->pRight->op!=TK_ALL) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1307
        /* This particular expression does not need to be expanded.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1308
        */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1309
        pNew = sqlite3ExprListAppend(pParse, pNew, a[k].pExpr, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1310
        if( pNew ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1311
          pNew->a[pNew->nExpr-1].zName = a[k].zName;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1312
        }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1313
          rc = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1314
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1315
        a[k].pExpr = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1316
        a[k].zName = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1317
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1318
        /* This expression is a "*" or a "TABLE.*" and needs to be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1319
        ** expanded. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1320
        int tableSeen = 0;      /* Set to 1 when TABLE matches */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1321
        char *zTName;            /* text of name of TABLE */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1322
        if( pE->op==TK_DOT && pE->pLeft ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1323
          zTName = sqlite3NameFromToken(db, &pE->pLeft->token);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1324
        }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1325
          zTName = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1326
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1327
        for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1328
          Table *pTab = pFrom->pTab;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1329
          char *zTabName = pFrom->zAlias;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1330
          if( zTabName==0 || zTabName[0]==0 ){ 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1331
            zTabName = pTab->zName;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1332
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1333
          if( zTName && (zTabName==0 || zTabName[0]==0 || 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1334
                 sqlite3StrICmp(zTName, zTabName)!=0) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1335
            continue;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1336
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1337
          tableSeen = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1338
          for(j=0; j<pTab->nCol; j++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1339
            Expr *pExpr, *pRight;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1340
            char *zName = pTab->aCol[j].zName;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1341
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1342
            /* If a column is marked as 'hidden' (currently only possible
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1343
            ** for virtual tables), do not include it in the expanded
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1344
            ** result-set list.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1345
            */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1346
            if( IsHiddenColumn(&pTab->aCol[j]) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1347
              assert(IsVirtual(pTab));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1348
              continue;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1349
            }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1350
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1351
            if( i>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1352
				SrcList::SrcList_item *pLeft = &pTabList->a[i-1];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1353
              if( (pLeft[1].jointype & JT_NATURAL)!=0 &&
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1354
                        columnIndex(pLeft->pTab, zName)>=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1355
                /* In a NATURAL join, omit the join columns from the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1356
                ** table on the right */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1357
                continue;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1358
              }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1359
              if( sqlite3IdListIndex(pLeft[1].pUsing, zName)>=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1360
                /* In a join with a USING clause, omit columns in the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1361
                ** using clause from the table on the right. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1362
                continue;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1363
              }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1364
            }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1365
            pRight = sqlite3PExpr(pParse, TK_ID, 0, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1366
            if( pRight==0 ) break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1367
            setQuotedToken(pParse, &pRight->token, zName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1368
            if( zTabName && (longNames || pTabList->nSrc>1) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1369
              Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1370
              pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1371
              if( pExpr==0 ) break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1372
              setQuotedToken(pParse, &pLeft->token, zTabName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1373
              setToken(&pExpr->span, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1374
                  sqlite3MPrintf(db, "%s.%s", zTabName, zName));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1375
              pExpr->span.dyn = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1376
              pExpr->token.z = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1377
              pExpr->token.n = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1378
              pExpr->token.dyn = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1379
            }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1380
              pExpr = pRight;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1381
              pExpr->span = pExpr->token;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1382
              pExpr->span.dyn = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1383
            }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1384
            if( longNames ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1385
              pNew = sqlite3ExprListAppend(pParse, pNew, pExpr, &pExpr->span);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1386
            }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1387
              pNew = sqlite3ExprListAppend(pParse, pNew, pExpr, &pRight->token);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1388
            }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1389
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1390
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1391
        if( !tableSeen ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1392
          if( zTName ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1393
            sqlite3ErrorMsg(pParse, "no such table: %s", zTName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1394
          }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1395
            sqlite3ErrorMsg(pParse, "no tables specified");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1396
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1397
          rc = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1398
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1399
        sqlite3_free(zTName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1400
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1401
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1402
    sqlite3ExprListDelete(pEList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1403
    p->pEList = pNew;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1404
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1405
  if( p->pEList && p->pEList->nExpr>SQLITE_MAX_COLUMN ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1406
    sqlite3ErrorMsg(pParse, "too many columns in result set");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1407
    rc = SQLITE_ERROR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1408
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1409
  if( db->mallocFailed ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1410
    rc = SQLITE_NOMEM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1411
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1412
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1413
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1414
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1415
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1416
** pE is a pointer to an expression which is a single term in
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1417
** ORDER BY or GROUP BY clause.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1418
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1419
** If pE evaluates to an integer constant i, then return i.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1420
** This is an indication to the caller that it should sort
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1421
** by the i-th column of the result set.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1422
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1423
** If pE is a well-formed expression and the SELECT statement
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1424
** is not compound, then return 0.  This indicates to the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1425
** caller that it should sort by the value of the ORDER BY
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1426
** expression.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1427
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1428
** If the SELECT is compound, then attempt to match pE against
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1429
** result set columns in the left-most SELECT statement.  Return
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1430
** the index i of the matching column, as an indication to the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1431
** caller that it should sort by the i-th column.  If there is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1432
** no match, return -1 and leave an error message in pParse.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1433
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1434
static int matchOrderByTermToExprList(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1435
  Parse *pParse,     /* Parsing context for error messages */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1436
  Select *pSelect,   /* The SELECT statement with the ORDER BY clause */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1437
  Expr *pE,          /* The specific ORDER BY term */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1438
  int idx,           /* When ORDER BY term is this */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1439
  int isCompound,    /* True if this is a compound SELECT */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1440
  u8 *pHasAgg        /* True if expression contains aggregate functions */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1441
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1442
  int i;             /* Loop counter */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1443
  ExprList *pEList;  /* The columns of the result set */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1444
  NameContext nc;    /* Name context for resolving pE */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1445
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1446
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1447
  /* If the term is an integer constant, return the value of that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1448
  ** constant */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1449
  pEList = pSelect->pEList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1450
  if( sqlite3ExprIsInteger(pE, &i) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1451
    if( i<=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1452
      /* If i is too small, make it too big.  That way the calling
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1453
      ** function still sees a value that is out of range, but does
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1454
      ** not confuse the column number with 0 or -1 result code.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1455
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1456
      i = pEList->nExpr+1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1457
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1458
    return i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1459
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1460
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1461
  /* If the term is a simple identifier that try to match that identifier
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1462
  ** against a column name in the result set.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1463
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1464
  if( pE->op==TK_ID || (pE->op==TK_STRING && pE->token.z[0]!='\'') ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1465
    sqlite3 *db = pParse->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1466
    char *zCol = sqlite3NameFromToken(db, &pE->token);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1467
    if( zCol==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1468
      return -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1469
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1470
    for(i=0; i<pEList->nExpr; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1471
      char *zAs = pEList->a[i].zName;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1472
      if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1473
        sqlite3_free(zCol);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1474
        return i+1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1475
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1476
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1477
    sqlite3_free(zCol);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1478
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1479
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1480
  /* Resolve all names in the ORDER BY term expression
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1481
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1482
  memset(&nc, 0, sizeof(nc));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1483
  nc.pParse = pParse;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1484
  nc.pSrcList = pSelect->pSrc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1485
  nc.pEList = pEList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1486
  nc.allowAgg = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1487
  nc.nErr = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1488
  if( sqlite3ExprResolveNames(&nc, pE) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1489
    if( isCompound ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1490
      sqlite3ErrorClear(pParse);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1491
      return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1492
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1493
      return -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1494
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1495
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1496
  if( nc.hasAgg && pHasAgg ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1497
    *pHasAgg = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1498
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1499
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1500
  /* For a compound SELECT, we need to try to match the ORDER BY
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1501
  ** expression against an expression in the result set
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1502
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1503
  if( isCompound ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1504
    for(i=0; i<pEList->nExpr; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1505
      if( sqlite3ExprCompare(pEList->a[i].pExpr, pE) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1506
        return i+1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1507
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1508
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1509
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1510
  return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1511
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1512
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1513
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1514
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1515
** Analyze and ORDER BY or GROUP BY clause in a simple SELECT statement.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1516
** Return the number of errors seen.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1517
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1518
** Every term of the ORDER BY or GROUP BY clause needs to be an
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1519
** expression.  If any expression is an integer constant, then
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1520
** that expression is replaced by the corresponding 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1521
** expression from the result set.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1522
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1523
static int processOrderGroupBy(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1524
  Parse *pParse,        /* Parsing context.  Leave error messages here */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1525
  Select *pSelect,      /* The SELECT statement containing the clause */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1526
  ExprList *pOrderBy,   /* The ORDER BY or GROUP BY clause to be processed */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1527
  int isOrder,          /* 1 for ORDER BY.  0 for GROUP BY */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1528
  u8 *pHasAgg           /* Set to TRUE if any term contains an aggregate */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1529
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1530
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1531
  sqlite3 *db = pParse->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1532
  ExprList *pEList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1533
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1534
  if( pOrderBy==0 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1535
  if( pOrderBy->nExpr>SQLITE_MAX_COLUMN ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1536
    const char *zType = isOrder ? "ORDER" : "GROUP";
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1537
    sqlite3ErrorMsg(pParse, "too many terms in %s BY clause", zType);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1538
    return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1539
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1540
  pEList = pSelect->pEList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1541
  if( pEList==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1542
    return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1543
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1544
  for(i=0; i<pOrderBy->nExpr; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1545
    int iCol;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1546
    Expr *pE = pOrderBy->a[i].pExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1547
    iCol = matchOrderByTermToExprList(pParse, pSelect, pE, i+1, 0, pHasAgg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1548
    if( iCol<0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1549
      return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1550
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1551
    if( iCol>pEList->nExpr ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1552
      const char *zType = isOrder ? "ORDER" : "GROUP";
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1553
      sqlite3ErrorMsg(pParse, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1554
         "%r %s BY term out of range - should be "
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1555
         "between 1 and %d", i+1, zType, pEList->nExpr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1556
      return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1557
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1558
    if( iCol>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1559
      CollSeq *pColl = pE->pColl;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1560
      int flags = pE->flags & EP_ExpCollate;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1561
      sqlite3ExprDelete(pE);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1562
      pE = sqlite3ExprDup(db, pEList->a[iCol-1].pExpr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1563
      pOrderBy->a[i].pExpr = pE;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1564
      if( pColl && flags ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1565
        pE->pColl = pColl;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1566
        pE->flags |= flags;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1567
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1568
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1569
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1570
  return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1571
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1572
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1573
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1574
** Analyze and ORDER BY or GROUP BY clause in a SELECT statement.  Return
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1575
** the number of errors seen.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1576
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1577
** The processing depends on whether the SELECT is simple or compound.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1578
** For a simple SELECT statement, evry term of the ORDER BY or GROUP BY
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1579
** clause needs to be an expression.  If any expression is an integer
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1580
** constant, then that expression is replaced by the corresponding 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1581
** expression from the result set.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1582
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1583
** For compound SELECT statements, every expression needs to be of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1584
** type TK_COLUMN with a iTable value as given in the 4th parameter.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1585
** If any expression is an integer, that becomes the column number.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1586
** Otherwise, match the expression against result set columns from
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1587
** the left-most SELECT.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1588
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1589
static int processCompoundOrderBy(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1590
  Parse *pParse,        /* Parsing context.  Leave error messages here */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1591
  Select *pSelect,      /* The SELECT statement containing the ORDER BY */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1592
  int iTable            /* Output table for compound SELECT statements */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1593
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1594
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1595
  ExprList *pOrderBy;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1596
  ExprList *pEList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1597
  sqlite3 *db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1598
  int moreToDo = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1599
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1600
  pOrderBy = pSelect->pOrderBy;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1601
  if( pOrderBy==0 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1602
  if( pOrderBy->nExpr>SQLITE_MAX_COLUMN ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1603
    sqlite3ErrorMsg(pParse, "too many terms in ORDER BY clause");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1604
    return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1605
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1606
  db = pParse->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1607
  for(i=0; i<pOrderBy->nExpr; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1608
    pOrderBy->a[i].done = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1609
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1610
  while( pSelect->pPrior ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1611
    pSelect = pSelect->pPrior;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1612
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1613
  while( pSelect && moreToDo ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1614
    moreToDo = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1615
    for(i=0; i<pOrderBy->nExpr; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1616
      int iCol;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1617
      Expr *pE, *pDup;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1618
      if( pOrderBy->a[i].done ) continue;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1619
      pE = pOrderBy->a[i].pExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1620
      pDup = sqlite3ExprDup(db, pE);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1621
      if( pDup==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1622
        return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1623
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1624
      iCol = matchOrderByTermToExprList(pParse, pSelect, pDup, i+1, 1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1625
      sqlite3ExprDelete(pDup);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1626
      if( iCol<0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1627
        return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1628
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1629
      pEList = pSelect->pEList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1630
      if( pEList==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1631
        return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1632
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1633
      if( iCol>pEList->nExpr ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1634
        sqlite3ErrorMsg(pParse, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1635
           "%r ORDER BY term out of range - should be "
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1636
           "between 1 and %d", i+1, pEList->nExpr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1637
        return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1638
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1639
      if( iCol>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1640
        pE->op = TK_COLUMN;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1641
        pE->iTable = iTable;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1642
        pE->iAgg = -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1643
        pE->iColumn = iCol-1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1644
        pE->pTab = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1645
        pOrderBy->a[i].done = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1646
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1647
        moreToDo = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1648
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1649
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1650
    pSelect = pSelect->pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1651
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1652
  for(i=0; i<pOrderBy->nExpr; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1653
    if( pOrderBy->a[i].done==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1654
      sqlite3ErrorMsg(pParse, "%r ORDER BY term does not match any "
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1655
            "column in the result set", i+1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1656
      return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1657
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1658
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1659
  return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1660
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1661
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1662
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1663
** Get a VDBE for the given parser context.  Create a new one if necessary.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1664
** If an error occurs, return NULL and leave a message in pParse.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1665
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1666
Vdbe *sqlite3GetVdbe(Parse *pParse){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1667
  Vdbe *v = pParse->pVdbe;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1668
  if( v==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1669
    v = pParse->pVdbe = sqlite3VdbeCreate(pParse->db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1670
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1671
  return v;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1672
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1673
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1674
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1675
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1676
** Compute the iLimit and iOffset fields of the SELECT based on the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1677
** pLimit and pOffset expressions.  pLimit and pOffset hold the expressions
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1678
** that appear in the original SQL statement after the LIMIT and OFFSET
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1679
** keywords.  Or NULL if those keywords are omitted. iLimit and iOffset 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1680
** are the integer memory register numbers for counters used to compute 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1681
** the limit and offset.  If there is no limit and/or offset, then 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1682
** iLimit and iOffset are negative.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1683
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1684
** This routine changes the values of iLimit and iOffset only if
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1685
** a limit or offset is defined by pLimit and pOffset.  iLimit and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1686
** iOffset should have been preset to appropriate default values
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1687
** (usually but not always -1) prior to calling this routine.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1688
** Only if pLimit!=0 or pOffset!=0 do the limit registers get
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1689
** redefined.  The UNION ALL operator uses this property to force
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1690
** the reuse of the same limit and offset registers across multiple
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1691
** SELECT statements.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1692
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1693
static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1694
  Vdbe *v = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1695
  int iLimit = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1696
  int iOffset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1697
  int addr1, addr2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1698
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1699
  /* 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1700
  ** "LIMIT -1" always shows all rows.  There is some
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1701
  ** contraversy about what the correct behavior should be.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1702
  ** The current implementation interprets "LIMIT 0" to mean
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1703
  ** no rows.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1704
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1705
  if( p->pLimit ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1706
    p->iLimit = iLimit = pParse->nMem;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1707
    pParse->nMem += 2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1708
    v = sqlite3GetVdbe(pParse);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1709
    if( v==0 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1710
    sqlite3ExprCode(pParse, p->pLimit);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1711
    sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1712
    sqlite3VdbeAddOp(v, OP_MemStore, iLimit, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1713
    VdbeComment((v, "# LIMIT counter"));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1714
    sqlite3VdbeAddOp(v, OP_IfMemZero, iLimit, iBreak);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1715
    sqlite3VdbeAddOp(v, OP_MemLoad, iLimit, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1716
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1717
  if( p->pOffset ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1718
    p->iOffset = iOffset = pParse->nMem++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1719
    v = sqlite3GetVdbe(pParse);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1720
    if( v==0 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1721
    sqlite3ExprCode(pParse, p->pOffset);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1722
    sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1723
    sqlite3VdbeAddOp(v, OP_MemStore, iOffset, p->pLimit==0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1724
    VdbeComment((v, "# OFFSET counter"));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1725
    addr1 = sqlite3VdbeAddOp(v, OP_IfMemPos, iOffset, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1726
    sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1727
    sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1728
    sqlite3VdbeJumpHere(v, addr1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1729
    if( p->pLimit ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1730
      sqlite3VdbeAddOp(v, OP_Add, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1731
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1732
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1733
  if( p->pLimit ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1734
    addr1 = sqlite3VdbeAddOp(v, OP_IfMemPos, iLimit, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1735
    sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1736
    sqlite3VdbeAddOp(v, OP_MemInt, -1, iLimit+1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1737
    addr2 = sqlite3VdbeAddOp(v, OP_Goto, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1738
    sqlite3VdbeJumpHere(v, addr1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1739
    sqlite3VdbeAddOp(v, OP_MemStore, iLimit+1, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1740
    VdbeComment((v, "# LIMIT+OFFSET"));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1741
    sqlite3VdbeJumpHere(v, addr2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1742
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1743
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1744
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1745
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1746
** Allocate a virtual index to use for sorting.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1747
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1748
static void createSortingIndex(Parse *pParse, Select *p, ExprList *pOrderBy){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1749
  if( pOrderBy ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1750
    int addr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1751
    assert( pOrderBy->iECursor==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1752
    pOrderBy->iECursor = pParse->nTab++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1753
    addr = sqlite3VdbeAddOp(pParse->pVdbe, OP_OpenEphemeral,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1754
                            pOrderBy->iECursor, pOrderBy->nExpr+1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1755
    assert( p->addrOpenEphm[2] == -1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1756
    p->addrOpenEphm[2] = addr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1757
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1758
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1759
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1760
#ifndef SQLITE_OMIT_COMPOUND_SELECT
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1761
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1762
** Return the appropriate collating sequence for the iCol-th column of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1763
** the result set for the compound-select statement "p".  Return NULL if
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1764
** the column has no default collating sequence.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1765
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1766
** The collating sequence for the compound select is taken from the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1767
** left-most term of the select that has a collating sequence.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1768
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1769
static CollSeq *multiSelectCollSeq(Parse *pParse, Select *p, int iCol){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1770
  CollSeq *pRet;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1771
  if( p->pPrior ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1772
    pRet = multiSelectCollSeq(pParse, p->pPrior, iCol);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1773
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1774
    pRet = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1775
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1776
  if( pRet==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1777
    pRet = sqlite3ExprCollSeq(pParse, p->pEList->a[iCol].pExpr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1778
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1779
  return pRet;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1780
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1781
#endif /* SQLITE_OMIT_COMPOUND_SELECT */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1782
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1783
#ifndef SQLITE_OMIT_COMPOUND_SELECT
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1784
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1785
** This routine is called to process a query that is really the union
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1786
** or intersection of two or more separate queries.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1787
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1788
** "p" points to the right-most of the two queries.  the query on the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1789
** left is p->pPrior.  The left query could also be a compound query
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1790
** in which case this routine will be called recursively. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1791
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1792
** The results of the total query are to be written into a destination
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1793
** of type eDest with parameter iParm.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1794
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1795
** Example 1:  Consider a three-way compound SQL statement.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1796
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1797
**     SELECT a FROM t1 UNION SELECT b FROM t2 UNION SELECT c FROM t3
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1798
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1799
** This statement is parsed up as follows:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1800
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1801
**     SELECT c FROM t3
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1802
**      |
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1803
**      `----->  SELECT b FROM t2
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1804
**                |
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1805
**                `------>  SELECT a FROM t1
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1806
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1807
** The arrows in the diagram above represent the Select.pPrior pointer.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1808
** So if this routine is called with p equal to the t3 query, then
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1809
** pPrior will be the t2 query.  p->op will be TK_UNION in this case.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1810
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1811
** Notice that because of the way SQLite parses compound SELECTs, the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1812
** individual selects always group from left to right.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1813
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1814
static int multiSelect(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1815
  Parse *pParse,        /* Parsing context */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1816
  Select *p,            /* The right-most of SELECTs to be coded */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1817
  int eDest,            /* \___  Store query results as specified */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1818
  int iParm,            /* /     by these two parameters.         */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1819
  char *aff             /* If eDest is SRT_Union, the affinity string */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1820
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1821
  int rc = SQLITE_OK;   /* Success code from a subroutine */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1822
  Select *pPrior;       /* Another SELECT immediately to our left */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1823
  Vdbe *v;              /* Generate code to this VDBE */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1824
  int nCol;             /* Number of columns in the result set */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1825
  ExprList *pOrderBy;   /* The ORDER BY clause on p */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1826
  int aSetP2[2];        /* Set P2 value of these op to number of columns */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1827
  int nSetP2 = 0;       /* Number of slots in aSetP2[] used */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1828
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1829
  /* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs.  Only
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1830
  ** the last (right-most) SELECT in the series may have an ORDER BY or LIMIT.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1831
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1832
  if( p==0 || p->pPrior==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1833
    rc = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1834
    goto multi_select_end;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1835
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1836
  pPrior = p->pPrior;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1837
  assert( pPrior->pRightmost!=pPrior );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1838
  assert( pPrior->pRightmost==p->pRightmost );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1839
  if( pPrior->pOrderBy ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1840
    sqlite3ErrorMsg(pParse,"ORDER BY clause should come after %s not before",
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1841
      selectOpName(p->op));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1842
    rc = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1843
    goto multi_select_end;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1844
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1845
  if( pPrior->pLimit ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1846
    sqlite3ErrorMsg(pParse,"LIMIT clause should come after %s not before",
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1847
      selectOpName(p->op));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1848
    rc = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1849
    goto multi_select_end;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1850
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1851
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1852
  /* Make sure we have a valid query engine.  If not, create a new one.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1853
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1854
  v = sqlite3GetVdbe(pParse);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1855
  if( v==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1856
    rc = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1857
    goto multi_select_end;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1858
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1859
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1860
  /* Create the destination temporary table if necessary
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1861
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1862
  if( eDest==SRT_EphemTab ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1863
    assert( p->pEList );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1864
    assert( nSetP2<sizeof(aSetP2)/sizeof(aSetP2[0]) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1865
    aSetP2[nSetP2++] = sqlite3VdbeAddOp(v, OP_OpenEphemeral, iParm, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1866
    eDest = SRT_Table;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1867
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1868
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1869
  /* Generate code for the left and right SELECT statements.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1870
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1871
  pOrderBy = p->pOrderBy;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1872
  switch( p->op ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1873
    case TK_ALL: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1874
      if( pOrderBy==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1875
        int addr = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1876
        assert( !pPrior->pLimit );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1877
        pPrior->pLimit = p->pLimit;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1878
        pPrior->pOffset = p->pOffset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1879
        rc = sqlite3Select(pParse, pPrior, eDest, iParm, 0, 0, 0, aff);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1880
        p->pLimit = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1881
        p->pOffset = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1882
        if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1883
          goto multi_select_end;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1884
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1885
        p->pPrior = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1886
        p->iLimit = pPrior->iLimit;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1887
        p->iOffset = pPrior->iOffset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1888
        if( p->iLimit>=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1889
          addr = sqlite3VdbeAddOp(v, OP_IfMemZero, p->iLimit, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1890
          VdbeComment((v, "# Jump ahead if LIMIT reached"));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1891
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1892
        rc = sqlite3Select(pParse, p, eDest, iParm, 0, 0, 0, aff);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1893
        p->pPrior = pPrior;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1894
        if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1895
          goto multi_select_end;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1896
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1897
        if( addr ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1898
          sqlite3VdbeJumpHere(v, addr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1899
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1900
        break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1901
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1902
      /* For UNION ALL ... ORDER BY fall through to the next case */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1903
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1904
    case TK_EXCEPT:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1905
    case TK_UNION: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1906
      int unionTab;    /* Cursor number of the temporary table holding result */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1907
      int op = 0;      /* One of the SRT_ operations to apply to self */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1908
      int priorOp;     /* The SRT_ operation to apply to prior selects */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1909
      Expr *pLimit, *pOffset; /* Saved values of p->nLimit and p->nOffset */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1910
      int addr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1911
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1912
      priorOp = p->op==TK_ALL ? SRT_Table : SRT_Union;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1913
      if( eDest==priorOp && pOrderBy==0 && !p->pLimit && !p->pOffset ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1914
        /* We can reuse a temporary table generated by a SELECT to our
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1915
        ** right.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1916
        */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1917
        unionTab = iParm;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1918
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1919
        /* We will need to create our own temporary table to hold the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1920
        ** intermediate results.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1921
        */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1922
        unionTab = pParse->nTab++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1923
        if( processCompoundOrderBy(pParse, p, unionTab) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1924
          rc = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1925
          goto multi_select_end;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1926
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1927
        addr = sqlite3VdbeAddOp(v, OP_OpenEphemeral, unionTab, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1928
        if( priorOp==SRT_Table ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1929
          assert( nSetP2<sizeof(aSetP2)/sizeof(aSetP2[0]) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1930
          aSetP2[nSetP2++] = addr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1931
        }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1932
          assert( p->addrOpenEphm[0] == -1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1933
          p->addrOpenEphm[0] = addr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1934
          p->pRightmost->usesEphm = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1935
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1936
        createSortingIndex(pParse, p, pOrderBy);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1937
        assert( p->pEList );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1938
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1939
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1940
      /* Code the SELECT statements to our left
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1941
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1942
      assert( !pPrior->pOrderBy );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1943
      rc = sqlite3Select(pParse, pPrior, priorOp, unionTab, 0, 0, 0, aff);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1944
      if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1945
        goto multi_select_end;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1946
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1947
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1948
      /* Code the current SELECT statement
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1949
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1950
      switch( p->op ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1951
         case TK_EXCEPT:  op = SRT_Except;   break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1952
         case TK_UNION:   op = SRT_Union;    break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1953
         case TK_ALL:     op = SRT_Table;    break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1954
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1955
      p->pPrior = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1956
      p->pOrderBy = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1957
      p->disallowOrderBy = pOrderBy!=0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1958
      pLimit = p->pLimit;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1959
      p->pLimit = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1960
      pOffset = p->pOffset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1961
      p->pOffset = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1962
      rc = sqlite3Select(pParse, p, op, unionTab, 0, 0, 0, aff);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1963
      /* Query flattening in sqlite3Select() might refill p->pOrderBy.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1964
      ** Be sure to delete p->pOrderBy, therefore, to avoid a memory leak. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1965
      sqlite3ExprListDelete(p->pOrderBy);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1966
      p->pPrior = pPrior;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1967
      p->pOrderBy = pOrderBy;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1968
      sqlite3ExprDelete(p->pLimit);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1969
      p->pLimit = pLimit;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1970
      p->pOffset = pOffset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1971
      p->iLimit = -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1972
      p->iOffset = -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1973
      if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1974
        goto multi_select_end;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1975
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1976
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1977
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1978
      /* Convert the data in the temporary table into whatever form
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1979
      ** it is that we currently need.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1980
      */      
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1981
      if( eDest!=priorOp || unionTab!=iParm ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1982
        int iCont, iBreak, iStart;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1983
        assert( p->pEList );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1984
        if( eDest==SRT_Callback ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1985
          Select *pFirst = p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1986
          while( pFirst->pPrior ) pFirst = pFirst->pPrior;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1987
          generateColumnNames(pParse, 0, pFirst->pEList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1988
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1989
        iBreak = sqlite3VdbeMakeLabel(v);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1990
        iCont = sqlite3VdbeMakeLabel(v);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1991
        computeLimitRegisters(pParse, p, iBreak);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1992
        sqlite3VdbeAddOp(v, OP_Rewind, unionTab, iBreak);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1993
        iStart = sqlite3VdbeCurrentAddr(v);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1994
        rc = selectInnerLoop(pParse, p, p->pEList, unionTab, p->pEList->nExpr,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1995
                             pOrderBy, -1, eDest, iParm, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1996
                             iCont, iBreak, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1997
        if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1998
          rc = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1999
          goto multi_select_end;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2000
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2001
        sqlite3VdbeResolveLabel(v, iCont);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2002
        sqlite3VdbeAddOp(v, OP_Next, unionTab, iStart);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2003
        sqlite3VdbeResolveLabel(v, iBreak);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2004
        sqlite3VdbeAddOp(v, OP_Close, unionTab, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2005
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2006
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2007
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2008
    case TK_INTERSECT: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2009
      int tab1, tab2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2010
      int iCont, iBreak, iStart;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2011
      Expr *pLimit, *pOffset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2012
      int addr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2013
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2014
      /* INTERSECT is different from the others since it requires
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2015
      ** two temporary tables.  Hence it has its own case.  Begin
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2016
      ** by allocating the tables we will need.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2017
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2018
      tab1 = pParse->nTab++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2019
      tab2 = pParse->nTab++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2020
      if( processCompoundOrderBy(pParse, p, tab1) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2021
        rc = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2022
        goto multi_select_end;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2023
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2024
      createSortingIndex(pParse, p, pOrderBy);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2025
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2026
      addr = sqlite3VdbeAddOp(v, OP_OpenEphemeral, tab1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2027
      assert( p->addrOpenEphm[0] == -1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2028
      p->addrOpenEphm[0] = addr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2029
      p->pRightmost->usesEphm = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2030
      assert( p->pEList );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2031
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2032
      /* Code the SELECTs to our left into temporary table "tab1".
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2033
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2034
      rc = sqlite3Select(pParse, pPrior, SRT_Union, tab1, 0, 0, 0, aff);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2035
      if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2036
        goto multi_select_end;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2037
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2038
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2039
      /* Code the current SELECT into temporary table "tab2"
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2040
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2041
      addr = sqlite3VdbeAddOp(v, OP_OpenEphemeral, tab2, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2042
      assert( p->addrOpenEphm[1] == -1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2043
      p->addrOpenEphm[1] = addr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2044
      p->pPrior = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2045
      pLimit = p->pLimit;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2046
      p->pLimit = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2047
      pOffset = p->pOffset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2048
      p->pOffset = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2049
      rc = sqlite3Select(pParse, p, SRT_Union, tab2, 0, 0, 0, aff);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2050
      p->pPrior = pPrior;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2051
      sqlite3ExprDelete(p->pLimit);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2052
      p->pLimit = pLimit;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2053
      p->pOffset = pOffset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2054
      if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2055
        goto multi_select_end;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2056
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2057
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2058
      /* Generate code to take the intersection of the two temporary
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2059
      ** tables.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2060
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2061
      assert( p->pEList );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2062
      if( eDest==SRT_Callback ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2063
        Select *pFirst = p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2064
        while( pFirst->pPrior ) pFirst = pFirst->pPrior;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2065
        generateColumnNames(pParse, 0, pFirst->pEList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2066
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2067
      iBreak = sqlite3VdbeMakeLabel(v);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2068
      iCont = sqlite3VdbeMakeLabel(v);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2069
      computeLimitRegisters(pParse, p, iBreak);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2070
      sqlite3VdbeAddOp(v, OP_Rewind, tab1, iBreak);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2071
      iStart = sqlite3VdbeAddOp(v, OP_RowKey, tab1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2072
      sqlite3VdbeAddOp(v, OP_NotFound, tab2, iCont);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2073
      rc = selectInnerLoop(pParse, p, p->pEList, tab1, p->pEList->nExpr,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2074
                             pOrderBy, -1, eDest, iParm, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2075
                             iCont, iBreak, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2076
      if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2077
        rc = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2078
        goto multi_select_end;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2079
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2080
      sqlite3VdbeResolveLabel(v, iCont);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2081
      sqlite3VdbeAddOp(v, OP_Next, tab1, iStart);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2082
      sqlite3VdbeResolveLabel(v, iBreak);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2083
      sqlite3VdbeAddOp(v, OP_Close, tab2, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2084
      sqlite3VdbeAddOp(v, OP_Close, tab1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2085
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2086
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2087
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2088
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2089
  /* Make sure all SELECTs in the statement have the same number of elements
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2090
  ** in their result sets.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2091
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2092
  assert( p->pEList && pPrior->pEList );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2093
  if( p->pEList->nExpr!=pPrior->pEList->nExpr ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2094
    sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s"
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2095
      " do not have the same number of result columns", selectOpName(p->op));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2096
    rc = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2097
    goto multi_select_end;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2098
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2099
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2100
  /* Set the number of columns in temporary tables
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2101
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2102
  nCol = p->pEList->nExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2103
  while( nSetP2 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2104
    sqlite3VdbeChangeP2(v, aSetP2[--nSetP2], nCol);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2105
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2106
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2107
  /* Compute collating sequences used by either the ORDER BY clause or
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2108
  ** by any temporary tables needed to implement the compound select.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2109
  ** Attach the KeyInfo structure to all temporary tables.  Invoke the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2110
  ** ORDER BY processing if there is an ORDER BY clause.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2111
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2112
  ** This section is run by the right-most SELECT statement only.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2113
  ** SELECT statements to the left always skip this part.  The right-most
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2114
  ** SELECT might also skip this part if it has no ORDER BY clause and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2115
  ** no temp tables are required.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2116
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2117
  if( pOrderBy || p->usesEphm ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2118
    int i;                        /* Loop counter */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2119
    KeyInfo *pKeyInfo;            /* Collating sequence for the result set */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2120
    Select *pLoop;                /* For looping through SELECT statements */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2121
    int nKeyCol;                  /* Number of entries in pKeyInfo->aCol[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2122
    CollSeq **apColl;             /* For looping through pKeyInfo->aColl[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2123
    CollSeq **aCopy;              /* A copy of pKeyInfo->aColl[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2124
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2125
    assert( p->pRightmost==p );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2126
    nKeyCol = nCol + (pOrderBy ? pOrderBy->nExpr : 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2127
    pKeyInfo = (KeyInfo*)sqlite3DbMallocZero(pParse->db,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2128
                       sizeof(*pKeyInfo)+nKeyCol*(sizeof(CollSeq*) + 1));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2129
    if( !pKeyInfo ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2130
      rc = SQLITE_NOMEM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2131
      goto multi_select_end;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2132
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2133
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2134
    pKeyInfo->enc = ENC(pParse->db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2135
    pKeyInfo->nField = nCol;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2136
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2137
    for(i=0, apColl=pKeyInfo->aColl; i<nCol; i++, apColl++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2138
      *apColl = multiSelectCollSeq(pParse, p, i);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2139
      if( 0==*apColl ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2140
        *apColl = pParse->db->pDfltColl;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2141
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2142
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2143
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2144
    for(pLoop=p; pLoop; pLoop=pLoop->pPrior){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2145
      for(i=0; i<2; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2146
        int addr = pLoop->addrOpenEphm[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2147
        if( addr<0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2148
          /* If [0] is unused then [1] is also unused.  So we can
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2149
          ** always safely abort as soon as the first unused slot is found */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2150
          assert( pLoop->addrOpenEphm[1]<0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2151
          break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2152
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2153
        sqlite3VdbeChangeP2(v, addr, nCol);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2154
        sqlite3VdbeChangeP3(v, addr, (char*)pKeyInfo, P3_KEYINFO);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2155
        pLoop->addrOpenEphm[i] = -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2156
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2157
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2158
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2159
    if( pOrderBy ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2160
		ExprList::ExprList_item *pOTerm = pOrderBy->a;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2161
      int nOrderByExpr = pOrderBy->nExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2162
      int addr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2163
      u8 *pSortOrder;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2164
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2165
      /* Reuse the same pKeyInfo for the ORDER BY as was used above for
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2166
      ** the compound select statements.  Except we have to change out the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2167
      ** pKeyInfo->aColl[] values.  Some of the aColl[] values will be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2168
      ** reused when constructing the pKeyInfo for the ORDER BY, so make
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2169
      ** a copy.  Sufficient space to hold both the nCol entries for
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2170
      ** the compound select and the nOrderbyExpr entries for the ORDER BY
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2171
      ** was allocated above.  But we need to move the compound select
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2172
      ** entries out of the way before constructing the ORDER BY entries.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2173
      ** Move the compound select entries into aCopy[] where they can be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2174
      ** accessed and reused when constructing the ORDER BY entries.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2175
      ** Because nCol might be greater than or less than nOrderByExpr
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2176
      ** we have to use memmove() when doing the copy.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2177
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2178
      aCopy = &pKeyInfo->aColl[nOrderByExpr];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2179
      pSortOrder = pKeyInfo->aSortOrder = (u8*)&aCopy[nCol];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2180
      memmove(aCopy, pKeyInfo->aColl, nCol*sizeof(CollSeq*));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2181
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2182
      apColl = pKeyInfo->aColl;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2183
      for(i=0; i<nOrderByExpr; i++, pOTerm++, apColl++, pSortOrder++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2184
        Expr *pExpr = pOTerm->pExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2185
        if( (pExpr->flags & EP_ExpCollate) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2186
          assert( pExpr->pColl!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2187
          *apColl = pExpr->pColl;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2188
        }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2189
          *apColl = aCopy[pExpr->iColumn];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2190
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2191
        *pSortOrder = pOTerm->sortOrder;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2192
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2193
      assert( p->pRightmost==p );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2194
      assert( p->addrOpenEphm[2]>=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2195
      addr = p->addrOpenEphm[2];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2196
      sqlite3VdbeChangeP2(v, addr, p->pOrderBy->nExpr+2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2197
      pKeyInfo->nField = nOrderByExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2198
      sqlite3VdbeChangeP3(v, addr, (char*)pKeyInfo, P3_KEYINFO_HANDOFF);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2199
      pKeyInfo = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2200
      generateSortTail(pParse, p, v, p->pEList->nExpr, eDest, iParm);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2201
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2202
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2203
    sqlite3_free(pKeyInfo);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2204
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2205
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2206
multi_select_end:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2207
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2208
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2209
#endif /* SQLITE_OMIT_COMPOUND_SELECT */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2210
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2211
#ifndef SQLITE_OMIT_VIEW
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2212
/* Forward Declarations */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2213
static void substExprList(sqlite3*, ExprList*, int, ExprList*);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2214
static void substSelect(sqlite3*, Select *, int, ExprList *);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2215
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2216
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2217
** Scan through the expression pExpr.  Replace every reference to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2218
** a column in table number iTable with a copy of the iColumn-th
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2219
** entry in pEList.  (But leave references to the ROWID column 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2220
** unchanged.)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2221
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2222
** This routine is part of the flattening procedure.  A subquery
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2223
** whose result set is defined by pEList appears as entry in the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2224
** FROM clause of a SELECT such that the VDBE cursor assigned to that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2225
** FORM clause entry is iTable.  This routine make the necessary 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2226
** changes to pExpr so that it refers directly to the source table
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2227
** of the subquery rather the result set of the subquery.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2228
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2229
static void substExpr(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2230
  sqlite3 *db,        /* Report malloc errors to this connection */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2231
  Expr *pExpr,        /* Expr in which substitution occurs */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2232
  int iTable,         /* Table to be substituted */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2233
  ExprList *pEList    /* Substitute expressions */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2234
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2235
  if( pExpr==0 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2236
  if( pExpr->op==TK_COLUMN && pExpr->iTable==iTable ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2237
    if( pExpr->iColumn<0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2238
      pExpr->op = TK_NULL;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2239
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2240
      Expr *pNew;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2241
      assert( pEList!=0 && pExpr->iColumn<pEList->nExpr );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2242
      assert( pExpr->pLeft==0 && pExpr->pRight==0 && pExpr->pList==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2243
      pNew = pEList->a[pExpr->iColumn].pExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2244
      assert( pNew!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2245
      pExpr->op = pNew->op;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2246
      assert( pExpr->pLeft==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2247
      pExpr->pLeft = sqlite3ExprDup(db, pNew->pLeft);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2248
      assert( pExpr->pRight==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2249
      pExpr->pRight = sqlite3ExprDup(db, pNew->pRight);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2250
      assert( pExpr->pList==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2251
      pExpr->pList = sqlite3ExprListDup(db, pNew->pList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2252
      pExpr->iTable = pNew->iTable;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2253
      pExpr->pTab = pNew->pTab;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2254
      pExpr->iColumn = pNew->iColumn;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2255
      pExpr->iAgg = pNew->iAgg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2256
      sqlite3TokenCopy(db, &pExpr->token, &pNew->token);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2257
      sqlite3TokenCopy(db, &pExpr->span, &pNew->span);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2258
      pExpr->pSelect = sqlite3SelectDup(db, pNew->pSelect);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2259
      pExpr->flags = pNew->flags;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2260
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2261
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2262
    substExpr(db, pExpr->pLeft, iTable, pEList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2263
    substExpr(db, pExpr->pRight, iTable, pEList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2264
    substSelect(db, pExpr->pSelect, iTable, pEList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2265
    substExprList(db, pExpr->pList, iTable, pEList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2266
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2267
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2268
static void substExprList(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2269
  sqlite3 *db,         /* Report malloc errors here */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2270
  ExprList *pList,     /* List to scan and in which to make substitutes */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2271
  int iTable,          /* Table to be substituted */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2272
  ExprList *pEList     /* Substitute values */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2273
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2274
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2275
  if( pList==0 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2276
  for(i=0; i<pList->nExpr; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2277
    substExpr(db, pList->a[i].pExpr, iTable, pEList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2278
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2279
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2280
static void substSelect(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2281
  sqlite3 *db,         /* Report malloc errors here */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2282
  Select *p,           /* SELECT statement in which to make substitutions */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2283
  int iTable,          /* Table to be replaced */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2284
  ExprList *pEList     /* Substitute values */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2285
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2286
  if( !p ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2287
  substExprList(db, p->pEList, iTable, pEList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2288
  substExprList(db, p->pGroupBy, iTable, pEList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2289
  substExprList(db, p->pOrderBy, iTable, pEList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2290
  substExpr(db, p->pHaving, iTable, pEList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2291
  substExpr(db, p->pWhere, iTable, pEList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2292
  substSelect(db, p->pPrior, iTable, pEList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2293
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2294
#endif /* !defined(SQLITE_OMIT_VIEW) */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2295
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2296
#ifndef SQLITE_OMIT_VIEW
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2297
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2298
** This routine attempts to flatten subqueries in order to speed
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2299
** execution.  It returns 1 if it makes changes and 0 if no flattening
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2300
** occurs.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2301
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2302
** To understand the concept of flattening, consider the following
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2303
** query:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2304
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2305
**     SELECT a FROM (SELECT x+y AS a FROM t1 WHERE z<100) WHERE a>5
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2306
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2307
** The default way of implementing this query is to execute the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2308
** subquery first and store the results in a temporary table, then
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2309
** run the outer query on that temporary table.  This requires two
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2310
** passes over the data.  Furthermore, because the temporary table
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2311
** has no indices, the WHERE clause on the outer query cannot be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2312
** optimized.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2313
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2314
** This routine attempts to rewrite queries such as the above into
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2315
** a single flat select, like this:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2316
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2317
**     SELECT x+y AS a FROM t1 WHERE z<100 AND a>5
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2318
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2319
** The code generated for this simpification gives the same result
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2320
** but only has to scan the data once.  And because indices might 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2321
** exist on the table t1, a complete scan of the data might be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2322
** avoided.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2323
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2324
** Flattening is only attempted if all of the following are true:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2325
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2326
**   (1)  The subquery and the outer query do not both use aggregates.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2327
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2328
**   (2)  The subquery is not an aggregate or the outer query is not a join.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2329
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2330
**   (3)  The subquery is not the right operand of a left outer join, or
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2331
**        the subquery is not itself a join.  (Ticket #306)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2332
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2333
**   (4)  The subquery is not DISTINCT or the outer query is not a join.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2334
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2335
**   (5)  The subquery is not DISTINCT or the outer query does not use
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2336
**        aggregates.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2337
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2338
**   (6)  The subquery does not use aggregates or the outer query is not
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2339
**        DISTINCT.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2340
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2341
**   (7)  The subquery has a FROM clause.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2342
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2343
**   (8)  The subquery does not use LIMIT or the outer query is not a join.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2344
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2345
**   (9)  The subquery does not use LIMIT or the outer query does not use
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2346
**        aggregates.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2347
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2348
**  (10)  The subquery does not use aggregates or the outer query does not
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2349
**        use LIMIT.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2350
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2351
**  (11)  The subquery and the outer query do not both have ORDER BY clauses.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2352
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2353
**  (12)  The subquery is not the right term of a LEFT OUTER JOIN or the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2354
**        subquery has no WHERE clause.  (added by ticket #350)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2355
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2356
**  (13)  The subquery and outer query do not both use LIMIT
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2357
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2358
**  (14)  The subquery does not use OFFSET
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2359
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2360
**  (15)  The outer query is not part of a compound select or the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2361
**        subquery does not have both an ORDER BY and a LIMIT clause.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2362
**        (See ticket #2339)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2363
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2364
** In this routine, the "p" parameter is a pointer to the outer query.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2365
** The subquery is p->pSrc->a[iFrom].  isAgg is true if the outer query
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2366
** uses aggregates and subqueryIsAgg is true if the subquery uses aggregates.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2367
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2368
** If flattening is not attempted, this routine is a no-op and returns 0.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2369
** If flattening is attempted this routine returns 1.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2370
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2371
** All of the expression analysis must occur on both the outer query and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2372
** the subquery before this routine runs.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2373
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2374
static int flattenSubquery(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2375
  sqlite3 *db,         /* Database connection */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2376
  Select *p,           /* The parent or outer SELECT statement */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2377
  int iFrom,           /* Index in p->pSrc->a[] of the inner subquery */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2378
  int isAgg,           /* True if outer SELECT uses aggregate functions */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2379
  int subqueryIsAgg    /* True if the subquery uses aggregate functions */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2380
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2381
  Select *pSub;       /* The inner query or "subquery" */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2382
  SrcList *pSrc;      /* The FROM clause of the outer query */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2383
  SrcList *pSubSrc;   /* The FROM clause of the subquery */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2384
  ExprList *pList;    /* The result set of the outer query */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2385
  int iParent;        /* VDBE cursor number of the pSub result set temp table */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2386
  int i;              /* Loop counter */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2387
  Expr *pWhere;                    /* The WHERE clause */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2388
  SrcList::SrcList_item *pSubitem;   /* The subquery */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2389
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2390
  /* Check to see if flattening is permitted.  Return 0 if not.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2391
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2392
  if( p==0 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2393
  pSrc = p->pSrc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2394
  assert( pSrc && iFrom>=0 && iFrom<pSrc->nSrc );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2395
  pSubitem = &pSrc->a[iFrom];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2396
  pSub = pSubitem->pSelect;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2397
  assert( pSub!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2398
  if( isAgg && subqueryIsAgg ) return 0;                 /* Restriction (1)  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2399
  if( subqueryIsAgg && pSrc->nSrc>1 ) return 0;          /* Restriction (2)  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2400
  pSubSrc = pSub->pSrc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2401
  assert( pSubSrc );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2402
  /* Prior to version 3.1.2, when LIMIT and OFFSET had to be simple constants,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2403
  ** not arbitrary expresssions, we allowed some combining of LIMIT and OFFSET
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2404
  ** because they could be computed at compile-time.  But when LIMIT and OFFSET
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2405
  ** became arbitrary expressions, we were forced to add restrictions (13)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2406
  ** and (14). */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2407
  if( pSub->pLimit && p->pLimit ) return 0;              /* Restriction (13) */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2408
  if( pSub->pOffset ) return 0;                          /* Restriction (14) */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2409
  if( p->pRightmost && pSub->pLimit && pSub->pOrderBy ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2410
    return 0;                                            /* Restriction (15) */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2411
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2412
  if( pSubSrc->nSrc==0 ) return 0;                       /* Restriction (7)  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2413
  if( (pSub->isDistinct || pSub->pLimit) 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2414
         && (pSrc->nSrc>1 || isAgg) ){          /* Restrictions (4)(5)(8)(9) */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2415
     return 0;       
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2416
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2417
  if( p->isDistinct && subqueryIsAgg ) return 0;         /* Restriction (6)  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2418
  if( (p->disallowOrderBy || p->pOrderBy) && pSub->pOrderBy ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2419
     return 0;                                           /* Restriction (11) */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2420
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2421
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2422
  /* Restriction 3:  If the subquery is a join, make sure the subquery is 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2423
  ** not used as the right operand of an outer join.  Examples of why this
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2424
  ** is not allowed:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2425
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2426
  **         t1 LEFT OUTER JOIN (t2 JOIN t3)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2427
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2428
  ** If we flatten the above, we would get
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2429
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2430
  **         (t1 LEFT OUTER JOIN t2) JOIN t3
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2431
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2432
  ** which is not at all the same thing.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2433
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2434
  if( pSubSrc->nSrc>1 && (pSubitem->jointype & JT_OUTER)!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2435
    return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2436
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2437
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2438
  /* Restriction 12:  If the subquery is the right operand of a left outer
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2439
  ** join, make sure the subquery has no WHERE clause.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2440
  ** An examples of why this is not allowed:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2441
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2442
  **         t1 LEFT OUTER JOIN (SELECT * FROM t2 WHERE t2.x>0)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2443
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2444
  ** If we flatten the above, we would get
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2445
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2446
  **         (t1 LEFT OUTER JOIN t2) WHERE t2.x>0
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2447
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2448
  ** But the t2.x>0 test will always fail on a NULL row of t2, which
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2449
  ** effectively converts the OUTER JOIN into an INNER JOIN.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2450
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2451
  if( (pSubitem->jointype & JT_OUTER)!=0 && pSub->pWhere!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2452
    return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2453
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2454
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2455
  /* If we reach this point, it means flattening is permitted for the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2456
  ** iFrom-th entry of the FROM clause in the outer query.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2457
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2458
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2459
  /* Move all of the FROM elements of the subquery into the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2460
  ** the FROM clause of the outer query.  Before doing this, remember
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2461
  ** the cursor number for the original outer query FROM element in
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2462
  ** iParent.  The iParent cursor will never be used.  Subsequent code
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2463
  ** will scan expressions looking for iParent references and replace
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2464
  ** those references with expressions that resolve to the subquery FROM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2465
  ** elements we are now copying in.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2466
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2467
  iParent = pSubitem->iCursor;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2468
  {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2469
    int nSubSrc = pSubSrc->nSrc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2470
    int jointype = pSubitem->jointype;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2471
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2472
    sqlite3DeleteTable(pSubitem->pTab);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2473
    sqlite3_free(pSubitem->zDatabase);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2474
    sqlite3_free(pSubitem->zName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2475
    sqlite3_free(pSubitem->zAlias);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2476
    pSubitem->pTab = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2477
    pSubitem->zDatabase = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2478
    pSubitem->zName = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2479
    pSubitem->zAlias = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2480
    if( nSubSrc>1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2481
      int extra = nSubSrc - 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2482
      for(i=1; i<nSubSrc; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2483
        pSrc = sqlite3SrcListAppend(db, pSrc, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2484
        if( pSrc==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2485
          p->pSrc = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2486
          return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2487
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2488
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2489
      p->pSrc = pSrc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2490
      for(i=pSrc->nSrc-1; i-extra>=iFrom; i--){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2491
        pSrc->a[i] = pSrc->a[i-extra];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2492
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2493
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2494
    for(i=0; i<nSubSrc; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2495
      pSrc->a[i+iFrom] = pSubSrc->a[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2496
      memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i]));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2497
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2498
    pSrc->a[iFrom].jointype = jointype;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2499
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2500
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2501
  /* Now begin substituting subquery result set expressions for 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2502
  ** references to the iParent in the outer query.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2503
  ** 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2504
  ** Example:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2505
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2506
  **   SELECT a+5, b*10 FROM (SELECT x*3 AS a, y+10 AS b FROM t1) WHERE a>b;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2507
  **   \                     \_____________ subquery __________/          /
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2508
  **    \_____________________ outer query ______________________________/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2509
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2510
  ** We look at every expression in the outer query and every place we see
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2511
  ** "a" we substitute "x*3" and every place we see "b" we substitute "y+10".
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2512
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2513
  pList = p->pEList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2514
  for(i=0; i<pList->nExpr; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2515
    Expr *pExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2516
    if( pList->a[i].zName==0 && (pExpr = pList->a[i].pExpr)->span.z!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2517
      pList->a[i].zName = 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2518
             sqlite3DbStrNDup(db, (char*)pExpr->span.z, pExpr->span.n);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2519
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2520
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2521
  substExprList(db, p->pEList, iParent, pSub->pEList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2522
  if( isAgg ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2523
    substExprList(db, p->pGroupBy, iParent, pSub->pEList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2524
    substExpr(db, p->pHaving, iParent, pSub->pEList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2525
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2526
  if( pSub->pOrderBy ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2527
    assert( p->pOrderBy==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2528
    p->pOrderBy = pSub->pOrderBy;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2529
    pSub->pOrderBy = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2530
  }else if( p->pOrderBy ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2531
    substExprList(db, p->pOrderBy, iParent, pSub->pEList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2532
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2533
  if( pSub->pWhere ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2534
    pWhere = sqlite3ExprDup(db, pSub->pWhere);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2535
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2536
    pWhere = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2537
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2538
  if( subqueryIsAgg ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2539
    assert( p->pHaving==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2540
    p->pHaving = p->pWhere;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2541
    p->pWhere = pWhere;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2542
    substExpr(db, p->pHaving, iParent, pSub->pEList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2543
    p->pHaving = sqlite3ExprAnd(db, p->pHaving, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2544
                                sqlite3ExprDup(db, pSub->pHaving));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2545
    assert( p->pGroupBy==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2546
    p->pGroupBy = sqlite3ExprListDup(db, pSub->pGroupBy);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2547
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2548
    substExpr(db, p->pWhere, iParent, pSub->pEList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2549
    p->pWhere = sqlite3ExprAnd(db, p->pWhere, pWhere);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2550
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2551
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2552
  /* The flattened query is distinct if either the inner or the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2553
  ** outer query is distinct. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2554
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2555
  p->isDistinct = p->isDistinct || pSub->isDistinct;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2556
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2557
  /*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2558
  ** SELECT ... FROM (SELECT ... LIMIT a OFFSET b) LIMIT x OFFSET y;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2559
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2560
  ** One is tempted to try to add a and b to combine the limits.  But this
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2561
  ** does not work if either limit is negative.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2562
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2563
  if( pSub->pLimit ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2564
    p->pLimit = pSub->pLimit;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2565
    pSub->pLimit = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2566
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2567
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2568
  /* Finially, delete what is left of the subquery and return
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2569
  ** success.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2570
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2571
  sqlite3SelectDelete(pSub);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2572
  return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2573
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2574
#endif /* SQLITE_OMIT_VIEW */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2575
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2576
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2577
** Analyze the SELECT statement passed in as an argument to see if it
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2578
** is a simple min() or max() query.  If it is and this query can be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2579
** satisfied using a single seek to the beginning or end of an index,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2580
** then generate the code for this SELECT and return 1.  If this is not a 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2581
** simple min() or max() query, then return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2582
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2583
** A simply min() or max() query looks like this:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2584
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2585
**    SELECT min(a) FROM table;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2586
**    SELECT max(a) FROM table;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2587
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2588
** The query may have only a single table in its FROM argument.  There
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2589
** can be no GROUP BY or HAVING or WHERE clauses.  The result set must
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2590
** be the min() or max() of a single column of the table.  The column
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2591
** in the min() or max() function must be indexed.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2592
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2593
** The parameters to this routine are the same as for sqlite3Select().
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2594
** See the header comment on that routine for additional information.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2595
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2596
static int simpleMinMaxQuery(Parse *pParse, Select *p, int eDest, int iParm){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2597
  Expr *pExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2598
  int iCol;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2599
  Table *pTab;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2600
  Index *pIdx;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2601
  int base;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2602
  Vdbe *v;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2603
  int seekOp;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2604
  ExprList *pEList, *pList, eList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2605
  ExprList::ExprList_item eListItem;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2606
  SrcList *pSrc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2607
  int brk;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2608
  int iDb;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2609
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2610
  /* Check to see if this query is a simple min() or max() query.  Return
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2611
  ** zero if it is  not.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2612
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2613
  if( p->pGroupBy || p->pHaving || p->pWhere ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2614
  pSrc = p->pSrc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2615
  if( pSrc->nSrc!=1 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2616
  pEList = p->pEList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2617
  if( pEList->nExpr!=1 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2618
  pExpr = pEList->a[0].pExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2619
  if( pExpr->op!=TK_AGG_FUNCTION ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2620
  pList = pExpr->pList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2621
  if( pList==0 || pList->nExpr!=1 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2622
  if( pExpr->token.n!=3 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2623
  if( sqlite3StrNICmp((char*)pExpr->token.z,"min",3)==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2624
    seekOp = OP_Rewind;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2625
  }else if( sqlite3StrNICmp((char*)pExpr->token.z,"max",3)==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2626
    seekOp = OP_Last;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2627
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2628
    return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2629
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2630
  pExpr = pList->a[0].pExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2631
  if( pExpr->op!=TK_COLUMN ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2632
  iCol = pExpr->iColumn;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2633
  pTab = pSrc->a[0].pTab;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2634
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2635
  /* This optimization cannot be used with virtual tables. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2636
  if( IsVirtual(pTab) ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2637
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2638
  /* If we get to here, it means the query is of the correct form.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2639
  ** Check to make sure we have an index and make pIdx point to the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2640
  ** appropriate index.  If the min() or max() is on an INTEGER PRIMARY
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2641
  ** key column, no index is necessary so set pIdx to NULL.  If no
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2642
  ** usable index is found, return 0.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2643
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2644
  if( iCol<0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2645
    pIdx = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2646
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2647
    CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2648
    if( pColl==0 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2649
    for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2650
      assert( pIdx->nColumn>=1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2651
      if( pIdx->aiColumn[0]==iCol && 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2652
          0==sqlite3StrICmp(pIdx->azColl[0], pColl->zName) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2653
        break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2654
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2655
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2656
    if( pIdx==0 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2657
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2658
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2659
  /* Identify column types if we will be using the callback.  This
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2660
  ** step is skipped if the output is going to a table or a memory cell.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2661
  ** The column names have already been generated in the calling function.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2662
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2663
  v = sqlite3GetVdbe(pParse);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2664
  if( v==0 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2665
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2666
  /* If the output is destined for a temporary table, open that table.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2667
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2668
  if( eDest==SRT_EphemTab ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2669
    sqlite3VdbeAddOp(v, OP_OpenEphemeral, iParm, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2670
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2671
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2672
  /* Generating code to find the min or the max.  Basically all we have
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2673
  ** to do is find the first or the last entry in the chosen index.  If
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2674
  ** the min() or max() is on the INTEGER PRIMARY KEY, then find the first
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2675
  ** or last entry in the main table.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2676
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2677
  iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2678
  assert( iDb>=0 || pTab->isEphem );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2679
  sqlite3CodeVerifySchema(pParse, iDb);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2680
  sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2681
  base = pSrc->a[0].iCursor;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2682
  brk = sqlite3VdbeMakeLabel(v);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2683
  computeLimitRegisters(pParse, p, brk);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2684
  if( pSrc->a[0].pSelect==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2685
    sqlite3OpenTable(pParse, base, iDb, pTab, OP_OpenRead);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2686
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2687
  if( pIdx==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2688
    sqlite3VdbeAddOp(v, seekOp, base, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2689
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2690
    /* Even though the cursor used to open the index here is closed
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2691
    ** as soon as a single value has been read from it, allocate it
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2692
    ** using (pParse->nTab++) to prevent the cursor id from being 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2693
    ** reused. This is important for statements of the form 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2694
    ** "INSERT INTO x SELECT max() FROM x".
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2695
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2696
    int iIdx;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2697
    KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2698
    iIdx = pParse->nTab++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2699
    assert( pIdx->pSchema==pTab->pSchema );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2700
    sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2701
    sqlite3VdbeOp3(v, OP_OpenRead, iIdx, pIdx->tnum, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2702
        (char*)pKey, P3_KEYINFO_HANDOFF);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2703
    if( seekOp==OP_Rewind ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2704
      sqlite3VdbeAddOp(v, OP_Null, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2705
      sqlite3VdbeAddOp(v, OP_MakeRecord, 1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2706
      seekOp = OP_MoveGt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2707
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2708
    if( pIdx->aSortOrder[0]==SQLITE_SO_DESC ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2709
      /* Ticket #2514: invert the seek operator if we are using
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2710
      ** a descending index. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2711
      if( seekOp==OP_Last ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2712
        seekOp = OP_Rewind;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2713
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2714
        assert( seekOp==OP_MoveGt );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2715
        seekOp = OP_MoveLt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2716
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2717
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2718
    sqlite3VdbeAddOp(v, seekOp, iIdx, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2719
    sqlite3VdbeAddOp(v, OP_IdxRowid, iIdx, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2720
    sqlite3VdbeAddOp(v, OP_Close, iIdx, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2721
    sqlite3VdbeAddOp(v, OP_MoveGe, base, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2722
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2723
  eList.nExpr = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2724
  memset(&eListItem, 0, sizeof(eListItem));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2725
  eList.a = &eListItem;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2726
  eList.a[0].pExpr = pExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2727
  selectInnerLoop(pParse, p, &eList, 0, 0, 0, -1, eDest, iParm, brk, brk, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2728
  sqlite3VdbeResolveLabel(v, brk);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2729
  sqlite3VdbeAddOp(v, OP_Close, base, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2730
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2731
  return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2732
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2733
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2734
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2735
** This routine resolves any names used in the result set of the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2736
** supplied SELECT statement. If the SELECT statement being resolved
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2737
** is a sub-select, then pOuterNC is a pointer to the NameContext 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2738
** of the parent SELECT.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2739
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2740
int sqlite3SelectResolve(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2741
  Parse *pParse,         /* The parser context */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2742
  Select *p,             /* The SELECT statement being coded. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2743
  NameContext *pOuterNC  /* The outer name context. May be NULL. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2744
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2745
  ExprList *pEList;          /* Result set. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2746
  int i;                     /* For-loop variable used in multiple places */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2747
  NameContext sNC;           /* Local name-context */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2748
  ExprList *pGroupBy;        /* The group by clause */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2749
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2750
  /* If this routine has run before, return immediately. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2751
  if( p->isResolved ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2752
    assert( !pOuterNC );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2753
    return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2754
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2755
  p->isResolved = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2756
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2757
  /* If there have already been errors, do nothing. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2758
  if( pParse->nErr>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2759
    return SQLITE_ERROR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2760
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2761
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2762
  /* Prepare the select statement. This call will allocate all cursors
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2763
  ** required to handle the tables and subqueries in the FROM clause.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2764
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2765
  if( prepSelectStmt(pParse, p) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2766
    return SQLITE_ERROR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2767
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2768
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2769
  /* Resolve the expressions in the LIMIT and OFFSET clauses. These
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2770
  ** are not allowed to refer to any names, so pass an empty NameContext.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2771
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2772
  memset(&sNC, 0, sizeof(sNC));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2773
  sNC.pParse = pParse;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2774
  if( sqlite3ExprResolveNames(&sNC, p->pLimit) ||
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2775
      sqlite3ExprResolveNames(&sNC, p->pOffset) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2776
    return SQLITE_ERROR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2777
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2778
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2779
  /* Set up the local name-context to pass to ExprResolveNames() to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2780
  ** resolve the expression-list.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2781
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2782
  sNC.allowAgg = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2783
  sNC.pSrcList = p->pSrc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2784
  sNC.pNext = pOuterNC;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2785
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2786
  /* Resolve names in the result set. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2787
  pEList = p->pEList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2788
  if( !pEList ) return SQLITE_ERROR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2789
  for(i=0; i<pEList->nExpr; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2790
    Expr *pX = pEList->a[i].pExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2791
    if( sqlite3ExprResolveNames(&sNC, pX) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2792
      return SQLITE_ERROR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2793
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2794
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2795
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2796
  /* If there are no aggregate functions in the result-set, and no GROUP BY 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2797
  ** expression, do not allow aggregates in any of the other expressions.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2798
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2799
  assert( !p->isAgg );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2800
  pGroupBy = p->pGroupBy;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2801
  if( pGroupBy || sNC.hasAgg ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2802
    p->isAgg = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2803
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2804
    sNC.allowAgg = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2805
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2806
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2807
  /* If a HAVING clause is present, then there must be a GROUP BY clause.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2808
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2809
  if( p->pHaving && !pGroupBy ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2810
    sqlite3ErrorMsg(pParse, "a GROUP BY clause is required before HAVING");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2811
    return SQLITE_ERROR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2812
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2813
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2814
  /* Add the expression list to the name-context before parsing the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2815
  ** other expressions in the SELECT statement. This is so that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2816
  ** expressions in the WHERE clause (etc.) can refer to expressions by
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2817
  ** aliases in the result set.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2818
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2819
  ** Minor point: If this is the case, then the expression will be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2820
  ** re-evaluated for each reference to it.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2821
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2822
  sNC.pEList = p->pEList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2823
  if( sqlite3ExprResolveNames(&sNC, p->pWhere) ||
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2824
     sqlite3ExprResolveNames(&sNC, p->pHaving) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2825
    return SQLITE_ERROR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2826
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2827
  if( p->pPrior==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2828
    if( processOrderGroupBy(pParse, p, p->pOrderBy, 1, &sNC.hasAgg) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2829
      return SQLITE_ERROR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2830
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2831
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2832
  if( processOrderGroupBy(pParse, p, pGroupBy, 0, &sNC.hasAgg) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2833
    return SQLITE_ERROR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2834
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2835
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2836
  if( pParse->db->mallocFailed ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2837
    return SQLITE_NOMEM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2838
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2839
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2840
  /* Make sure the GROUP BY clause does not contain aggregate functions.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2841
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2842
  if( pGroupBy ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2843
	  ExprList::ExprList_item *pItem;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2844
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2845
    for(i=0, pItem=pGroupBy->a; i<pGroupBy->nExpr; i++, pItem++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2846
      if( ExprHasProperty(pItem->pExpr, EP_Agg) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2847
        sqlite3ErrorMsg(pParse, "aggregate functions are not allowed in "
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2848
            "the GROUP BY clause");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2849
        return SQLITE_ERROR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2850
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2851
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2852
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2853
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2854
  /* If this is one SELECT of a compound, be sure to resolve names
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2855
  ** in the other SELECTs.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2856
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2857
  if( p->pPrior ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2858
    return sqlite3SelectResolve(pParse, p->pPrior, pOuterNC);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2859
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2860
    return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2861
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2862
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2863
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2864
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2865
** Reset the aggregate accumulator.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2866
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2867
** The aggregate accumulator is a set of memory cells that hold
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2868
** intermediate results while calculating an aggregate.  This
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2869
** routine simply stores NULLs in all of those memory cells.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2870
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2871
static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2872
  Vdbe *v = pParse->pVdbe;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2873
  int i=0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2874
  AggInfo::AggInfo_func *pFunc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2875
  if( pAggInfo->nFunc+pAggInfo->nColumn==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2876
    return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2877
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2878
  for(i=0; i<pAggInfo->nColumn; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2879
    sqlite3VdbeAddOp(v, OP_MemNull, pAggInfo->aCol[i].iMem, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2880
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2881
  for(pFunc=pAggInfo->aFunc, i=0; i<pAggInfo->nFunc; i++, pFunc++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2882
    sqlite3VdbeAddOp(v, OP_MemNull, pFunc->iMem, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2883
    if( pFunc->iDistinct>=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2884
      Expr *pE = pFunc->pExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2885
      if( pE->pList==0 || pE->pList->nExpr!=1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2886
        sqlite3ErrorMsg(pParse, "DISTINCT in aggregate must be followed "
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2887
           "by an expression");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2888
        pFunc->iDistinct = -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2889
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2890
        KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pE->pList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2891
        sqlite3VdbeOp3(v, OP_OpenEphemeral, pFunc->iDistinct, 0, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2892
                          (char*)pKeyInfo, P3_KEYINFO_HANDOFF);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2893
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2894
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2895
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2896
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2897
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2898
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2899
** Invoke the OP_AggFinalize opcode for every aggregate function
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2900
** in the AggInfo structure.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2901
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2902
static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2903
  Vdbe *v = pParse->pVdbe;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2904
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2905
  AggInfo::AggInfo_func *pF;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2906
  for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2907
    ExprList *pList = pF->pExpr->pList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2908
    sqlite3VdbeOp3(v, OP_AggFinal, pF->iMem, pList ? pList->nExpr : 0,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2909
                      (const char*)pF->pFunc, P3_FUNCDEF);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2910
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2911
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2912
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2913
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2914
** Update the accumulator memory cells for an aggregate based on
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2915
** the current cursor position.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2916
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2917
static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2918
  Vdbe *v = pParse->pVdbe;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2919
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2920
  AggInfo::AggInfo_func *pF;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2921
  AggInfo::AggInfo_col *pC;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2922
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2923
  pAggInfo->directMode = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2924
  for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2925
    int nArg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2926
    int addrNext = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2927
    ExprList *pList = pF->pExpr->pList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2928
    if( pList ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2929
      nArg = pList->nExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2930
      sqlite3ExprCodeExprList(pParse, pList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2931
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2932
      nArg = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2933
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2934
    if( pF->iDistinct>=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2935
      addrNext = sqlite3VdbeMakeLabel(v);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2936
      assert( nArg==1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2937
      codeDistinct(v, pF->iDistinct, addrNext, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2938
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2939
    if( pF->pFunc->needCollSeq ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2940
      CollSeq *pColl = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2941
	  ExprList::ExprList_item *pItem;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2942
      int j;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2943
      assert( pList!=0 );  /* pList!=0 if pF->pFunc->needCollSeq is true */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2944
      for(j=0, pItem=pList->a; !pColl && j<nArg; j++, pItem++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2945
        pColl = sqlite3ExprCollSeq(pParse, pItem->pExpr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2946
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2947
      if( !pColl ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2948
        pColl = pParse->db->pDfltColl;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2949
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2950
      sqlite3VdbeOp3(v, OP_CollSeq, 0, 0, (char *)pColl, P3_COLLSEQ);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2951
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2952
    sqlite3VdbeOp3(v, OP_AggStep, pF->iMem, nArg, (const char*)pF->pFunc, P3_FUNCDEF);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2953
    if( addrNext ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2954
      sqlite3VdbeResolveLabel(v, addrNext);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2955
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2956
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2957
  for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2958
    sqlite3ExprCode(pParse, pC->pExpr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2959
    sqlite3VdbeAddOp(v, OP_MemStore, pC->iMem, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2960
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2961
  pAggInfo->directMode = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2962
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2963
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2964
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2965
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2966
** Generate code for the given SELECT statement.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2967
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2968
** The results are distributed in various ways depending on the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2969
** value of eDest and iParm.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2970
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2971
**     eDest Value       Result
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2972
**     ------------    -------------------------------------------
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2973
**     SRT_Callback    Invoke the callback for each row of the result.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2974
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2975
**     SRT_Mem         Store first result in memory cell iParm
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2976
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2977
**     SRT_Set         Store results as keys of table iParm.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2978
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2979
**     SRT_Union       Store results as a key in a temporary table iParm
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2980
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2981
**     SRT_Except      Remove results from the temporary table iParm.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2982
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2983
**     SRT_Table       Store results in temporary table iParm
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2984
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2985
** The table above is incomplete.  Additional eDist value have be added
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2986
** since this comment was written.  See the selectInnerLoop() function for
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2987
** a complete listing of the allowed values of eDest and their meanings.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2988
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2989
** This routine returns the number of errors.  If any errors are
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2990
** encountered, then an appropriate error message is left in
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2991
** pParse->zErrMsg.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2992
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2993
** This routine does NOT free the Select structure passed in.  The
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2994
** calling function needs to do that.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2995
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2996
** The pParent, parentTab, and *pParentAgg fields are filled in if this
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2997
** SELECT is a subquery.  This routine may try to combine this SELECT
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2998
** with its parent to form a single flat query.  In so doing, it might
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2999
** change the parent query from a non-aggregate to an aggregate query.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3000
** For that reason, the pParentAgg flag is passed as a pointer, so it
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3001
** can be changed.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3002
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3003
** Example 1:   The meaning of the pParent parameter.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3004
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3005
**    SELECT * FROM t1 JOIN (SELECT x, count(*) FROM t2) JOIN t3;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3006
**    \                      \_______ subquery _______/        /
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3007
**     \                                                      /
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3008
**      \____________________ outer query ___________________/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3009
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3010
** This routine is called for the outer query first.   For that call,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3011
** pParent will be NULL.  During the processing of the outer query, this 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3012
** routine is called recursively to handle the subquery.  For the recursive
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3013
** call, pParent will point to the outer query.  Because the subquery is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3014
** the second element in a three-way join, the parentTab parameter will
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3015
** be 1 (the 2nd value of a 0-indexed array.)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3016
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3017
int sqlite3Select(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3018
  Parse *pParse,         /* The parser context */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3019
  Select *p,             /* The SELECT statement being coded. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3020
  int eDest,             /* How to dispose of the results */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3021
  int iParm,             /* A parameter used by the eDest disposal method */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3022
  Select *pParent,       /* Another SELECT for which this is a sub-query */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3023
  int parentTab,         /* Index in pParent->pSrc of this query */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3024
  int *pParentAgg,       /* True if pParent uses aggregate functions */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3025
  char *aff              /* If eDest is SRT_Union, the affinity string */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3026
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3027
  int i, j;              /* Loop counters */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3028
  WhereInfo *pWInfo;     /* Return from sqlite3WhereBegin() */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3029
  Vdbe *v;               /* The virtual machine under construction */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3030
  int isAgg;             /* True for select lists like "count(*)" */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3031
  ExprList *pEList;      /* List of columns to extract. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3032
  SrcList *pTabList;     /* List of tables to select from */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3033
  Expr *pWhere;          /* The WHERE clause.  May be NULL */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3034
  ExprList *pOrderBy;    /* The ORDER BY clause.  May be NULL */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3035
  ExprList *pGroupBy;    /* The GROUP BY clause.  May be NULL */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3036
  Expr *pHaving;         /* The HAVING clause.  May be NULL */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3037
  int isDistinct;        /* True if the DISTINCT keyword is present */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3038
  int distinct;          /* Table to use for the distinct set */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3039
  int rc = 1;            /* Value to return from this function */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3040
  int addrSortIndex;     /* Address of an OP_OpenEphemeral instruction */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3041
  AggInfo sAggInfo;      /* Information used by aggregate queries */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3042
  int iEnd;              /* Address of the end of the query */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3043
  sqlite3 *db;           /* The database connection */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3044
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3045
  db = pParse->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3046
  if( p==0 || db->mallocFailed || pParse->nErr ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3047
    return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3048
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3049
  if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3050
  memset(&sAggInfo, 0, sizeof(sAggInfo));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3051
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3052
  pOrderBy = p->pOrderBy;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3053
  if( IgnorableOrderby(eDest) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3054
    p->pOrderBy = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3055
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3056
  if( sqlite3SelectResolve(pParse, p, 0) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3057
    goto select_end;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3058
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3059
  p->pOrderBy = pOrderBy;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3060
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3061
#ifndef SQLITE_OMIT_COMPOUND_SELECT
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3062
  /* If there is are a sequence of queries, do the earlier ones first.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3063
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3064
  if( p->pPrior ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3065
    if( p->pRightmost==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3066
      Select *pLoop, *pRight = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3067
      int cnt = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3068
      for(pLoop=p; pLoop; pLoop=pLoop->pPrior, cnt++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3069
        pLoop->pRightmost = p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3070
        pLoop->pNext = pRight;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3071
        pRight = pLoop;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3072
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3073
      if( SQLITE_MAX_COMPOUND_SELECT>0 && cnt>SQLITE_MAX_COMPOUND_SELECT ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3074
        sqlite3ErrorMsg(pParse, "too many terms in compound SELECT");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3075
        return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3076
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3077
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3078
    return multiSelect(pParse, p, eDest, iParm, aff);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3079
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3080
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3081
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3082
  /* Make local copies of the parameters for this query.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3083
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3084
  pTabList = p->pSrc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3085
  pWhere = p->pWhere;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3086
  pGroupBy = p->pGroupBy;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3087
  pHaving = p->pHaving;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3088
  isAgg = p->isAgg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3089
  isDistinct = p->isDistinct;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3090
  pEList = p->pEList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3091
  if( pEList==0 ) goto select_end;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3092
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3093
  /* 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3094
  ** Do not even attempt to generate any code if we have already seen
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3095
  ** errors before this routine starts.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3096
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3097
  if( pParse->nErr>0 ) goto select_end;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3098
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3099
  /* If writing to memory or generating a set
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3100
  ** only a single column may be output.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3101
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3102
#ifndef SQLITE_OMIT_SUBQUERY
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3103
  if( checkForMultiColumnSelectError(pParse, eDest, pEList->nExpr) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3104
    goto select_end;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3105
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3106
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3107
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3108
  /* ORDER BY is ignored for some destinations.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3109
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3110
  if( IgnorableOrderby(eDest) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3111
    pOrderBy = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3112
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3113
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3114
  /* Begin generating code.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3115
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3116
  v = sqlite3GetVdbe(pParse);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3117
  if( v==0 ) goto select_end;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3118
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3119
  /* Generate code for all sub-queries in the FROM clause
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3120
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3121
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3122
  for(i=0; i<pTabList->nSrc; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3123
    const char *zSavedAuthContext = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3124
    int needRestoreContext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3125
	SrcList::SrcList_item *pItem = &pTabList->a[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3126
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3127
    if( pItem->pSelect==0 || pItem->isPopulated ) continue;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3128
    if( pItem->zName!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3129
      zSavedAuthContext = pParse->zAuthContext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3130
      pParse->zAuthContext = pItem->zName;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3131
      needRestoreContext = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3132
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3133
      needRestoreContext = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3134
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3135
#if defined(SQLITE_TEST) || SQLITE_MAX_EXPR_DEPTH>0
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3136
    /* Increment Parse.nHeight by the height of the largest expression
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3137
    ** tree refered to by this, the parent select. The child select
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3138
    ** may contain expression trees of at most
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3139
    ** (SQLITE_MAX_EXPR_DEPTH-Parse.nHeight) height. This is a bit
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3140
    ** more conservative than necessary, but much easier than enforcing
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3141
    ** an exact limit.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3142
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3143
    pParse->nHeight += sqlite3SelectExprHeight(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3144
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3145
    sqlite3Select(pParse, pItem->pSelect, SRT_EphemTab, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3146
                 pItem->iCursor, p, i, &isAgg, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3147
    if( db->mallocFailed ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3148
      goto select_end;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3149
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3150
#if defined(SQLITE_TEST) || SQLITE_MAX_EXPR_DEPTH>0
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3151
    pParse->nHeight -= sqlite3SelectExprHeight(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3152
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3153
    if( needRestoreContext ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3154
      pParse->zAuthContext = zSavedAuthContext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3155
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3156
    pTabList = p->pSrc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3157
    pWhere = p->pWhere;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3158
    if( !IgnorableOrderby(eDest) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3159
      pOrderBy = p->pOrderBy;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3160
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3161
    pGroupBy = p->pGroupBy;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3162
    pHaving = p->pHaving;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3163
    isDistinct = p->isDistinct;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3164
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3165
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3166
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3167
  /* Check for the special case of a min() or max() function by itself
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3168
  ** in the result set.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3169
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3170
  if( simpleMinMaxQuery(pParse, p, eDest, iParm) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3171
    rc = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3172
    goto select_end;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3173
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3174
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3175
  /* Check to see if this is a subquery that can be "flattened" into its parent.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3176
  ** If flattening is a possiblity, do so and return immediately.  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3177
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3178
#ifndef SQLITE_OMIT_VIEW
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3179
  if( pParent && pParentAgg &&
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3180
      flattenSubquery(db, pParent, parentTab, *pParentAgg, isAgg) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3181
    if( isAgg ) *pParentAgg = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3182
    goto select_end;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3183
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3184
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3185
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3186
  /* If possible, rewrite the query to use GROUP BY instead of DISTINCT.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3187
  ** GROUP BY may use an index, DISTINCT never does.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3188
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3189
  if( p->isDistinct && !p->isAgg && !p->pGroupBy ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3190
    p->pGroupBy = sqlite3ExprListDup(db, p->pEList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3191
    pGroupBy = p->pGroupBy;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3192
    p->isDistinct = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3193
    isDistinct = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3194
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3195
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3196
  /* If there is an ORDER BY clause, then this sorting
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3197
  ** index might end up being unused if the data can be 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3198
  ** extracted in pre-sorted order.  If that is the case, then the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3199
  ** OP_OpenEphemeral instruction will be changed to an OP_Noop once
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3200
  ** we figure out that the sorting index is not needed.  The addrSortIndex
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3201
  ** variable is used to facilitate that change.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3202
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3203
  if( pOrderBy ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3204
    KeyInfo *pKeyInfo;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3205
    if( pParse->nErr ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3206
      goto select_end;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3207
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3208
    pKeyInfo = keyInfoFromExprList(pParse, pOrderBy);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3209
    pOrderBy->iECursor = pParse->nTab++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3210
    p->addrOpenEphm[2] = addrSortIndex =
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3211
      sqlite3VdbeOp3(v, OP_OpenEphemeral, pOrderBy->iECursor, pOrderBy->nExpr+2,                     (char*)pKeyInfo, P3_KEYINFO_HANDOFF);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3212
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3213
    addrSortIndex = -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3214
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3215
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3216
  /* If the output is destined for a temporary table, open that table.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3217
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3218
  if( eDest==SRT_EphemTab ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3219
    sqlite3VdbeAddOp(v, OP_OpenEphemeral, iParm, pEList->nExpr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3220
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3221
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3222
  /* Set the limiter.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3223
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3224
  iEnd = sqlite3VdbeMakeLabel(v);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3225
  computeLimitRegisters(pParse, p, iEnd);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3226
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3227
  /* Open a virtual index to use for the distinct set.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3228
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3229
  if( isDistinct ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3230
    KeyInfo *pKeyInfo;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3231
    assert( isAgg || pGroupBy );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3232
    distinct = pParse->nTab++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3233
    pKeyInfo = keyInfoFromExprList(pParse, p->pEList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3234
    sqlite3VdbeOp3(v, OP_OpenEphemeral, distinct, 0, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3235
                        (char*)pKeyInfo, P3_KEYINFO_HANDOFF);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3236
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3237
    distinct = -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3238
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3239
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3240
  /* Aggregate and non-aggregate queries are handled differently */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3241
  if( !isAgg && pGroupBy==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3242
    /* This case is for non-aggregate queries
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3243
    ** Begin the database scan
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3244
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3245
    pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pOrderBy);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3246
    if( pWInfo==0 ) goto select_end;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3247
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3248
    /* If sorting index that was created by a prior OP_OpenEphemeral 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3249
    ** instruction ended up not being needed, then change the OP_OpenEphemeral
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3250
    ** into an OP_Noop.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3251
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3252
    if( addrSortIndex>=0 && pOrderBy==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3253
      sqlite3VdbeChangeToNoop(v, addrSortIndex, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3254
      p->addrOpenEphm[2] = -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3255
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3256
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3257
    /* Use the standard inner loop
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3258
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3259
    assert(!isDistinct);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3260
    if( selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, -1, eDest,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3261
                    iParm, pWInfo->iContinue, pWInfo->iBreak, aff) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3262
       goto select_end;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3263
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3264
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3265
    /* End the database scan loop.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3266
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3267
    sqlite3WhereEnd(pWInfo);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3268
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3269
    /* This is the processing for aggregate queries */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3270
    NameContext sNC;    /* Name context for processing aggregate information */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3271
    int iAMem;          /* First Mem address for storing current GROUP BY */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3272
    int iBMem;          /* First Mem address for previous GROUP BY */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3273
    int iUseFlag;       /* Mem address holding flag indicating that at least
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3274
                        ** one row of the input to the aggregator has been
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3275
                        ** processed */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3276
    int iAbortFlag;     /* Mem address which causes query abort if positive */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3277
    int groupBySort;    /* Rows come from source in GROUP BY order */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3278
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3279
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3280
    /* The following variables hold addresses or labels for parts of the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3281
    ** virtual machine program we are putting together */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3282
    int addrOutputRow;      /* Start of subroutine that outputs a result row */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3283
    int addrSetAbort;       /* Set the abort flag and return */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3284
    int addrInitializeLoop; /* Start of code that initializes the input loop */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3285
    int addrTopOfLoop;      /* Top of the input loop */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3286
    int addrGroupByChange;  /* Code that runs when any GROUP BY term changes */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3287
    int addrProcessRow;     /* Code to process a single input row */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3288
    int addrEnd;            /* End of all processing */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3289
    int addrSortingIdx;     /* The OP_OpenEphemeral for the sorting index */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3290
    int addrReset;          /* Subroutine for resetting the accumulator */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3291
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3292
    addrEnd = sqlite3VdbeMakeLabel(v);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3293
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3294
    /* Convert TK_COLUMN nodes into TK_AGG_COLUMN and make entries in
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3295
    ** sAggInfo for all TK_AGG_FUNCTION nodes in expressions of the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3296
    ** SELECT statement.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3297
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3298
    memset(&sNC, 0, sizeof(sNC));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3299
    sNC.pParse = pParse;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3300
    sNC.pSrcList = pTabList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3301
    sNC.pAggInfo = &sAggInfo;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3302
    sAggInfo.nSortingColumn = pGroupBy ? pGroupBy->nExpr+1 : 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3303
    sAggInfo.pGroupBy = pGroupBy;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3304
    if( sqlite3ExprAnalyzeAggList(&sNC, pEList) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3305
      goto select_end;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3306
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3307
    if( sqlite3ExprAnalyzeAggList(&sNC, pOrderBy) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3308
      goto select_end;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3309
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3310
    if( pHaving && sqlite3ExprAnalyzeAggregates(&sNC, pHaving) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3311
      goto select_end;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3312
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3313
    sAggInfo.nAccumulator = sAggInfo.nColumn;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3314
    for(i=0; i<sAggInfo.nFunc; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3315
      if( sqlite3ExprAnalyzeAggList(&sNC, sAggInfo.aFunc[i].pExpr->pList) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3316
        goto select_end;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3317
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3318
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3319
    if( db->mallocFailed ) goto select_end;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3320
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3321
    /* Processing for aggregates with GROUP BY is very different and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3322
    ** much more complex than aggregates without a GROUP BY.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3323
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3324
    if( pGroupBy ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3325
      KeyInfo *pKeyInfo;  /* Keying information for the group by clause */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3326
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3327
      /* Create labels that we will be needing
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3328
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3329
     
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3330
      addrInitializeLoop = sqlite3VdbeMakeLabel(v);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3331
      addrGroupByChange = sqlite3VdbeMakeLabel(v);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3332
      addrProcessRow = sqlite3VdbeMakeLabel(v);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3333
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3334
      /* If there is a GROUP BY clause we might need a sorting index to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3335
      ** implement it.  Allocate that sorting index now.  If it turns out
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3336
      ** that we do not need it after all, the OpenEphemeral instruction
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3337
      ** will be converted into a Noop.  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3338
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3339
      sAggInfo.sortingIdx = pParse->nTab++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3340
      pKeyInfo = keyInfoFromExprList(pParse, pGroupBy);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3341
      addrSortingIdx =
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3342
          sqlite3VdbeOp3(v, OP_OpenEphemeral, sAggInfo.sortingIdx,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3343
                         sAggInfo.nSortingColumn,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3344
                         (char*)pKeyInfo, P3_KEYINFO_HANDOFF);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3345
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3346
      /* Initialize memory locations used by GROUP BY aggregate processing
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3347
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3348
      iUseFlag = pParse->nMem++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3349
      iAbortFlag = pParse->nMem++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3350
      iAMem = pParse->nMem;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3351
      pParse->nMem += pGroupBy->nExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3352
      iBMem = pParse->nMem;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3353
      pParse->nMem += pGroupBy->nExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3354
      sqlite3VdbeAddOp(v, OP_MemInt, 0, iAbortFlag);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3355
      VdbeComment((v, "# clear abort flag"));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3356
      sqlite3VdbeAddOp(v, OP_MemInt, 0, iUseFlag);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3357
      VdbeComment((v, "# indicate accumulator empty"));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3358
      sqlite3VdbeAddOp(v, OP_Goto, 0, addrInitializeLoop);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3359
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3360
      /* Generate a subroutine that outputs a single row of the result
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3361
      ** set.  This subroutine first looks at the iUseFlag.  If iUseFlag
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3362
      ** is less than or equal to zero, the subroutine is a no-op.  If
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3363
      ** the processing calls for the query to abort, this subroutine
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3364
      ** increments the iAbortFlag memory location before returning in
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3365
      ** order to signal the caller to abort.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3366
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3367
      addrSetAbort = sqlite3VdbeCurrentAddr(v);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3368
      sqlite3VdbeAddOp(v, OP_MemInt, 1, iAbortFlag);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3369
      VdbeComment((v, "# set abort flag"));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3370
      sqlite3VdbeAddOp(v, OP_Return, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3371
      addrOutputRow = sqlite3VdbeCurrentAddr(v);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3372
      sqlite3VdbeAddOp(v, OP_IfMemPos, iUseFlag, addrOutputRow+2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3373
      VdbeComment((v, "# Groupby result generator entry point"));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3374
      sqlite3VdbeAddOp(v, OP_Return, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3375
      finalizeAggFunctions(pParse, &sAggInfo);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3376
      if( pHaving ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3377
        sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3378
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3379
      rc = selectInnerLoop(pParse, p, p->pEList, 0, 0, pOrderBy,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3380
                           distinct, eDest, iParm, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3381
                           addrOutputRow+1, addrSetAbort, aff);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3382
      if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3383
        goto select_end;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3384
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3385
      sqlite3VdbeAddOp(v, OP_Return, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3386
      VdbeComment((v, "# end groupby result generator"));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3387
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3388
      /* Generate a subroutine that will reset the group-by accumulator
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3389
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3390
      addrReset = sqlite3VdbeCurrentAddr(v);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3391
      resetAccumulator(pParse, &sAggInfo);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3392
      sqlite3VdbeAddOp(v, OP_Return, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3393
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3394
      /* Begin a loop that will extract all source rows in GROUP BY order.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3395
      ** This might involve two separate loops with an OP_Sort in between, or
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3396
      ** it might be a single loop that uses an index to extract information
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3397
      ** in the right order to begin with.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3398
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3399
      sqlite3VdbeResolveLabel(v, addrInitializeLoop);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3400
      sqlite3VdbeAddOp(v, OP_Gosub, 0, addrReset);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3401
      pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pGroupBy);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3402
      if( pWInfo==0 ) goto select_end;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3403
      if( pGroupBy==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3404
        /* The optimizer is able to deliver rows in group by order so
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3405
        ** we do not have to sort.  The OP_OpenEphemeral table will be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3406
        ** cancelled later because we still need to use the pKeyInfo
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3407
        */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3408
        pGroupBy = p->pGroupBy;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3409
        groupBySort = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3410
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3411
        /* Rows are coming out in undetermined order.  We have to push
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3412
        ** each row into a sorting index, terminate the first loop,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3413
        ** then loop over the sorting index in order to get the output
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3414
        ** in sorted order
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3415
        */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3416
        groupBySort = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3417
        sqlite3ExprCodeExprList(pParse, pGroupBy);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3418
        sqlite3VdbeAddOp(v, OP_Sequence, sAggInfo.sortingIdx, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3419
        j = pGroupBy->nExpr+1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3420
        for(i=0; i<sAggInfo.nColumn; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3421
			AggInfo::AggInfo_col *pCol = &sAggInfo.aCol[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3422
          if( pCol->iSorterColumn<j ) continue;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3423
          sqlite3ExprCodeGetColumn(v, pCol->pTab, pCol->iColumn, pCol->iTable);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3424
          j++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3425
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3426
        sqlite3VdbeAddOp(v, OP_MakeRecord, j, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3427
        sqlite3VdbeAddOp(v, OP_IdxInsert, sAggInfo.sortingIdx, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3428
        sqlite3WhereEnd(pWInfo);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3429
        sqlite3VdbeAddOp(v, OP_Sort, sAggInfo.sortingIdx, addrEnd);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3430
        VdbeComment((v, "# GROUP BY sort"));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3431
        sAggInfo.useSortingIdx = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3432
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3433
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3434
      /* Evaluate the current GROUP BY terms and store in b0, b1, b2...
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3435
      ** (b0 is memory location iBMem+0, b1 is iBMem+1, and so forth)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3436
      ** Then compare the current GROUP BY terms against the GROUP BY terms
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3437
      ** from the previous row currently stored in a0, a1, a2...
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3438
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3439
      addrTopOfLoop = sqlite3VdbeCurrentAddr(v);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3440
      for(j=0; j<pGroupBy->nExpr; j++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3441
        if( groupBySort ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3442
          sqlite3VdbeAddOp(v, OP_Column, sAggInfo.sortingIdx, j);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3443
        }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3444
          sAggInfo.directMode = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3445
          sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3446
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3447
        sqlite3VdbeAddOp(v, OP_MemStore, iBMem+j, j<pGroupBy->nExpr-1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3448
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3449
      for(j=pGroupBy->nExpr-1; j>=0; j--){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3450
        if( j<pGroupBy->nExpr-1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3451
          sqlite3VdbeAddOp(v, OP_MemLoad, iBMem+j, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3452
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3453
        sqlite3VdbeAddOp(v, OP_MemLoad, iAMem+j, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3454
        if( j==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3455
          sqlite3VdbeAddOp(v, OP_Eq, 0x200, addrProcessRow);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3456
        }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3457
          sqlite3VdbeAddOp(v, OP_Ne, 0x200, addrGroupByChange);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3458
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3459
        sqlite3VdbeChangeP3(v, -1, (const char*)pKeyInfo->aColl[j], P3_COLLSEQ);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3460
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3461
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3462
      /* Generate code that runs whenever the GROUP BY changes.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3463
      ** Change in the GROUP BY are detected by the previous code
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3464
      ** block.  If there were no changes, this block is skipped.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3465
      **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3466
      ** This code copies current group by terms in b0,b1,b2,...
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3467
      ** over to a0,a1,a2.  It then calls the output subroutine
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3468
      ** and resets the aggregate accumulator registers in preparation
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3469
      ** for the next GROUP BY batch.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3470
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3471
      sqlite3VdbeResolveLabel(v, addrGroupByChange);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3472
      for(j=0; j<pGroupBy->nExpr; j++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3473
        sqlite3VdbeAddOp(v, OP_MemMove, iAMem+j, iBMem+j);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3474
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3475
      sqlite3VdbeAddOp(v, OP_Gosub, 0, addrOutputRow);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3476
      VdbeComment((v, "# output one row"));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3477
      sqlite3VdbeAddOp(v, OP_IfMemPos, iAbortFlag, addrEnd);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3478
      VdbeComment((v, "# check abort flag"));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3479
      sqlite3VdbeAddOp(v, OP_Gosub, 0, addrReset);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3480
      VdbeComment((v, "# reset accumulator"));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3481
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3482
      /* Update the aggregate accumulators based on the content of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3483
      ** the current row
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3484
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3485
      sqlite3VdbeResolveLabel(v, addrProcessRow);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3486
      updateAccumulator(pParse, &sAggInfo);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3487
      sqlite3VdbeAddOp(v, OP_MemInt, 1, iUseFlag);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3488
      VdbeComment((v, "# indicate data in accumulator"));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3489
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3490
      /* End of the loop
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3491
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3492
      if( groupBySort ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3493
        sqlite3VdbeAddOp(v, OP_Next, sAggInfo.sortingIdx, addrTopOfLoop);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3494
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3495
        sqlite3WhereEnd(pWInfo);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3496
        sqlite3VdbeChangeToNoop(v, addrSortingIdx, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3497
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3498
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3499
      /* Output the final row of result
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3500
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3501
      sqlite3VdbeAddOp(v, OP_Gosub, 0, addrOutputRow);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3502
      VdbeComment((v, "# output final row"));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3503
      
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3504
    } /* endif pGroupBy */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3505
    else {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3506
      /* This case runs if the aggregate has no GROUP BY clause.  The
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3507
      ** processing is much simpler since there is only a single row
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3508
      ** of output.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3509
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3510
      resetAccumulator(pParse, &sAggInfo);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3511
      pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3512
      if( pWInfo==0 ) goto select_end;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3513
      updateAccumulator(pParse, &sAggInfo);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3514
      sqlite3WhereEnd(pWInfo);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3515
      finalizeAggFunctions(pParse, &sAggInfo);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3516
      pOrderBy = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3517
      if( pHaving ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3518
        sqlite3ExprIfFalse(pParse, pHaving, addrEnd, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3519
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3520
      selectInnerLoop(pParse, p, p->pEList, 0, 0, 0, -1, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3521
                      eDest, iParm, addrEnd, addrEnd, aff);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3522
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3523
    sqlite3VdbeResolveLabel(v, addrEnd);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3524
    
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3525
  } /* endif aggregate query */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3526
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3527
  /* If there is an ORDER BY clause, then we need to sort the results
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3528
  ** and send them to the callback one by one.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3529
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3530
  if( pOrderBy ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3531
    generateSortTail(pParse, p, v, pEList->nExpr, eDest, iParm);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3532
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3533
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3534
#ifndef SQLITE_OMIT_SUBQUERY
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3535
  /* If this was a subquery, we have now converted the subquery into a
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3536
  ** temporary table.  So set the SrcList_item.isPopulated flag to prevent
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3537
  ** this subquery from being evaluated again and to force the use of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3538
  ** the temporary table.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3539
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3540
  if( pParent ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3541
    assert( pParent->pSrc->nSrc>parentTab );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3542
    assert( pParent->pSrc->a[parentTab].pSelect==p );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3543
    pParent->pSrc->a[parentTab].isPopulated = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3544
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3545
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3546
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3547
  /* Jump here to skip this query
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3548
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3549
  sqlite3VdbeResolveLabel(v, iEnd);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3550
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3551
  /* The SELECT was successfully coded.   Set the return code to 0
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3552
  ** to indicate no errors.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3553
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3554
  rc = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3555
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3556
  /* Control jumps to here if an error is encountered above, or upon
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3557
  ** successful coding of the SELECT.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3558
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3559
select_end:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3560
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3561
  /* Identify column names if we will be using them in a callback.  This
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3562
  ** step is skipped if the output is going to some other destination.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3563
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3564
  if( rc==SQLITE_OK && eDest==SRT_Callback ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3565
    generateColumnNames(pParse, pTabList, pEList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3566
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3567
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3568
  sqlite3_free(sAggInfo.aCol);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3569
  sqlite3_free(sAggInfo.aFunc);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3570
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3571
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3572
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3573
#if defined(SQLITE_DEBUG)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3574
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3575
*******************************************************************************
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3576
** The following code is used for testing and debugging only.  The code
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3577
** that follows does not appear in normal builds.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3578
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3579
** These routines are used to print out the content of all or part of a 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3580
** parse structures such as Select or Expr.  Such printouts are useful
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3581
** for helping to understand what is happening inside the code generator
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3582
** during the execution of complex SELECT statements.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3583
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3584
** These routine are not called anywhere from within the normal
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3585
** code base.  Then are intended to be called from within the debugger
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3586
** or from temporary "printf" statements inserted for debugging.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3587
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3588
void sqlite3PrintExpr(Expr *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3589
  if( p->token.z && p->token.n>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3590
    sqlite3DebugPrintf("(%.*s", p->token.n, p->token.z);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3591
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3592
    sqlite3DebugPrintf("(%d", p->op);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3593
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3594
  if( p->pLeft ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3595
    sqlite3DebugPrintf(" ");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3596
    sqlite3PrintExpr(p->pLeft);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3597
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3598
  if( p->pRight ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3599
    sqlite3DebugPrintf(" ");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3600
    sqlite3PrintExpr(p->pRight);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3601
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3602
  sqlite3DebugPrintf(")");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3603
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3604
void sqlite3PrintExprList(ExprList *pList){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3605
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3606
  for(i=0; i<pList->nExpr; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3607
    sqlite3PrintExpr(pList->a[i].pExpr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3608
    if( i<pList->nExpr-1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3609
      sqlite3DebugPrintf(", ");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3610
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3611
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3612
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3613
void sqlite3PrintSelect(Select *p, int indent){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3614
  sqlite3DebugPrintf("%*sSELECT(%p) ", indent, "", p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3615
  sqlite3PrintExprList(p->pEList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3616
  sqlite3DebugPrintf("\n");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3617
  if( p->pSrc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3618
    char *zPrefix;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3619
    int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3620
    zPrefix = "FROM";
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3621
    for(i=0; i<p->pSrc->nSrc; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3622
      struct SrcList_item *pItem = &p->pSrc->a[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3623
      sqlite3DebugPrintf("%*s ", indent+6, zPrefix);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3624
      zPrefix = "";
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3625
      if( pItem->pSelect ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3626
        sqlite3DebugPrintf("(\n");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3627
        sqlite3PrintSelect(pItem->pSelect, indent+10);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3628
        sqlite3DebugPrintf("%*s)", indent+8, "");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3629
      }else if( pItem->zName ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3630
        sqlite3DebugPrintf("%s", pItem->zName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3631
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3632
      if( pItem->pTab ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3633
        sqlite3DebugPrintf("(table: %s)", pItem->pTab->zName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3634
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3635
      if( pItem->zAlias ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3636
        sqlite3DebugPrintf(" AS %s", pItem->zAlias);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3637
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3638
      if( i<p->pSrc->nSrc-1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3639
        sqlite3DebugPrintf(",");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3640
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3641
      sqlite3DebugPrintf("\n");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3642
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3643
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3644
  if( p->pWhere ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3645
    sqlite3DebugPrintf("%*s WHERE ", indent, "");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3646
    sqlite3PrintExpr(p->pWhere);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3647
    sqlite3DebugPrintf("\n");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3648
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3649
  if( p->pGroupBy ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3650
    sqlite3DebugPrintf("%*s GROUP BY ", indent, "");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3651
    sqlite3PrintExprList(p->pGroupBy);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3652
    sqlite3DebugPrintf("\n");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3653
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3654
  if( p->pHaving ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3655
    sqlite3DebugPrintf("%*s HAVING ", indent, "");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3656
    sqlite3PrintExpr(p->pHaving);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3657
    sqlite3DebugPrintf("\n");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3658
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3659
  if( p->pOrderBy ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3660
    sqlite3DebugPrintf("%*s ORDER BY ", indent, "");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3661
    sqlite3PrintExprList(p->pOrderBy);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3662
    sqlite3DebugPrintf("\n");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3663
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3664
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3665
/* End of the structure debug printing code
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3666
*****************************************************************************/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3667
#endif /* defined(SQLITE_TEST) || defined(SQLITE_DEBUG) */