engine/sqlite/src/expr.cpp
author Sebastian Brannstrom <sebastianb@symbian.org>
Sat, 16 Oct 2010 15:36:19 +0100
branch3rded
changeset 275 e2c3225833c3
parent 2 29cda98b007e
permissions -rw-r--r--
Fix for bug 2818
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 routines used for analyzing expressions and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    13
** for generating VDBE code that evaluates expressions 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: expr.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
#include <ctype.h>
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
** Return the 'affinity' of the expression pExpr if any.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    22
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    23
** If pExpr is a column, a reference to a column via an 'AS' alias,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    24
** or a sub-select with a column as the return value, then the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    25
** affinity of that column is returned. Otherwise, 0x00 is returned,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    26
** indicating no affinity for the expression.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    27
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    28
** i.e. the WHERE clause expresssions in the following statements all
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    29
** have an affinity:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    30
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    31
** CREATE TABLE t1(a);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    32
** SELECT * FROM t1 WHERE a;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    33
** SELECT a AS b FROM t1 WHERE b;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    34
** SELECT * FROM t1 WHERE (select a from t1);
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
char sqlite3ExprAffinity(Expr *pExpr){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    37
  int op = pExpr->op;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    38
  if( op==TK_SELECT ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    39
    return sqlite3ExprAffinity(pExpr->pSelect->pEList->a[0].pExpr);
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
#ifndef SQLITE_OMIT_CAST
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    42
  if( op==TK_CAST ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    43
    return sqlite3AffinityType(&pExpr->token);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    44
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    45
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    46
  return pExpr->affinity;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    47
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    48
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    49
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    50
** Set the collating sequence for expression pExpr to be the collating
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    51
** sequence named by pToken.   Return a pointer to the revised expression.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    52
** The collating sequence is marked as "explicit" using the EP_ExpCollate
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    53
** flag.  An explicit collating sequence will override implicit
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    54
** collating sequences.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    55
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    56
Expr *sqlite3ExprSetColl(Parse *pParse, Expr *pExpr, Token *pName){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    57
  char *zColl = 0;            /* Dequoted name of collation sequence */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    58
  CollSeq *pColl;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    59
  zColl = sqlite3NameFromToken(pParse->db, pName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    60
  if( pExpr && zColl ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    61
    pColl = sqlite3LocateCollSeq(pParse, zColl, -1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    62
    if( pColl ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    63
      pExpr->pColl = pColl;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    64
      pExpr->flags |= EP_ExpCollate;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    65
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    66
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    67
  sqlite3_free(zColl);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    68
  return pExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    69
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    70
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    71
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    72
** Return the default collation sequence for the expression pExpr. If
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    73
** there is no default collation type, return 0.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    74
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    75
CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    76
  CollSeq *pColl = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    77
  if( pExpr ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    78
    int op;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    79
    pColl = pExpr->pColl;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    80
    op = pExpr->op;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    81
    if( (op==TK_CAST || op==TK_UPLUS) && !pColl ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    82
      return sqlite3ExprCollSeq(pParse, pExpr->pLeft);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    83
    }
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
  if( sqlite3CheckCollSeq(pParse, pColl) ){ 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    86
    pColl = 0;
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
  return pColl;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    89
}
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
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    92
** pExpr is an operand of a comparison operator.  aff2 is the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    93
** type affinity of the other operand.  This routine returns the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    94
** type affinity that should be used for the comparison operator.
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
char sqlite3CompareAffinity(Expr *pExpr, char aff2){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    97
  char aff1 = sqlite3ExprAffinity(pExpr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    98
  if( aff1 && aff2 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    99
    /* Both sides of the comparison are columns. If one has numeric
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   100
    ** affinity, use that. Otherwise use no affinity.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   101
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   102
    if( sqlite3IsNumericAffinity(aff1) || sqlite3IsNumericAffinity(aff2) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   103
      return SQLITE_AFF_NUMERIC;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   104
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   105
      return SQLITE_AFF_NONE;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   106
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   107
  }else if( !aff1 && !aff2 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   108
    /* Neither side of the comparison is a column.  Compare the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   109
    ** results directly.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   110
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   111
    return SQLITE_AFF_NONE;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   112
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   113
    /* One side is a column, the other is not. Use the columns affinity. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   114
    assert( aff1==0 || aff2==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   115
    return (aff1 + aff2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   116
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   117
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   118
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   119
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   120
** pExpr is a comparison operator.  Return the type affinity that should
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   121
** be applied to both operands prior to doing the comparison.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   122
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   123
static char comparisonAffinity(Expr *pExpr){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   124
  char aff;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   125
  assert( pExpr->op==TK_EQ || pExpr->op==TK_IN || pExpr->op==TK_LT ||
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   126
          pExpr->op==TK_GT || pExpr->op==TK_GE || pExpr->op==TK_LE ||
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   127
          pExpr->op==TK_NE );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   128
  assert( pExpr->pLeft );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   129
  aff = sqlite3ExprAffinity(pExpr->pLeft);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   130
  if( pExpr->pRight ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   131
    aff = sqlite3CompareAffinity(pExpr->pRight, aff);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   132
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   133
  else if( pExpr->pSelect ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   134
    aff = sqlite3CompareAffinity(pExpr->pSelect->pEList->a[0].pExpr, aff);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   135
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   136
  else if( !aff ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   137
    aff = SQLITE_AFF_NONE;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   138
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   139
  return aff;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   140
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   141
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   142
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   143
** pExpr is a comparison expression, eg. '=', '<', IN(...) etc.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   144
** idx_affinity is the affinity of an indexed column. Return true
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   145
** if the index with affinity idx_affinity may be used to implement
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   146
** the comparison in pExpr.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   147
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   148
int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   149
  char aff = comparisonAffinity(pExpr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   150
  switch( aff ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   151
    case SQLITE_AFF_NONE:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   152
      return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   153
    case SQLITE_AFF_TEXT:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   154
      return idx_affinity==SQLITE_AFF_TEXT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   155
    default:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   156
      return sqlite3IsNumericAffinity(idx_affinity);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   157
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   158
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   159
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   160
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   161
** Return the P1 value that should be used for a binary comparison
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   162
** opcode (OP_Eq, OP_Ge etc.) used to compare pExpr1 and pExpr2.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   163
** If jumpIfNull is true, then set the low byte of the returned
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   164
** P1 value to tell the opcode to jump if either expression
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   165
** evaluates to NULL.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   166
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   167
static int binaryCompareP1(Expr *pExpr1, Expr *pExpr2, int jumpIfNull){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   168
  char aff = sqlite3ExprAffinity(pExpr2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   169
  return ((int)sqlite3CompareAffinity(pExpr1, aff))+(jumpIfNull?0x100:0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   170
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   171
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
** Return a pointer to the collation sequence that should be used by
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   174
** a binary comparison operator comparing pLeft and pRight.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   175
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   176
** If the left hand expression has a collating sequence type, then it is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   177
** used. Otherwise the collation sequence for the right hand expression
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   178
** is used, or the default (BINARY) if neither expression has a collating
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   179
** type.
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
** Argument pRight (but not pLeft) may be a null pointer. In this case,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   182
** it is not considered.
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
CollSeq *sqlite3BinaryCompareCollSeq(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   185
  Parse *pParse, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   186
  Expr *pLeft, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   187
  Expr *pRight
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
  CollSeq *pColl;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   190
  assert( pLeft );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   191
  if( pLeft->flags & EP_ExpCollate ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   192
    assert( pLeft->pColl );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   193
    pColl = pLeft->pColl;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   194
  }else if( pRight && pRight->flags & EP_ExpCollate ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   195
    assert( pRight->pColl );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   196
    pColl = pRight->pColl;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   197
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   198
    pColl = sqlite3ExprCollSeq(pParse, pLeft);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   199
    if( !pColl ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   200
      pColl = sqlite3ExprCollSeq(pParse, pRight);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   201
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   202
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   203
  return pColl;
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
** Generate code for a comparison operator.
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
static int codeCompare(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   210
  Parse *pParse,    /* The parsing (and code generating) context */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   211
  Expr *pLeft,      /* The left operand */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   212
  Expr *pRight,     /* The right operand */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   213
  int opcode,       /* The comparison opcode */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   214
  int dest,         /* Jump here if true.  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   215
  int jumpIfNull    /* If true, jump if either operand is NULL */
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
  int p1 = binaryCompareP1(pLeft, pRight, jumpIfNull);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   218
  CollSeq *p3 = sqlite3BinaryCompareCollSeq(pParse, pLeft, pRight);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   219
  return sqlite3VdbeOp3(pParse->pVdbe, opcode, p1, dest, (const char*)p3, P3_COLLSEQ);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   220
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   221
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   222
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   223
** Construct a new expression node and return a pointer to it.  Memory
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   224
** for this node is obtained from sqlite3_malloc().  The calling function
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   225
** is responsible for making sure the node eventually gets freed.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   226
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   227
Expr *sqlite3Expr(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   228
  sqlite3 *db,            /* Handle for sqlite3DbMallocZero() (may be null) */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   229
  int op,                 /* Expression opcode */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   230
  Expr *pLeft,            /* Left operand */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   231
  Expr *pRight,           /* Right operand */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   232
  const Token *pToken     /* Argument token */
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
  Expr *pNew;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   235
  pNew = (Expr*)sqlite3DbMallocZero(db, sizeof(Expr));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   236
  if( pNew==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   237
    /* When malloc fails, delete pLeft and pRight. Expressions passed to 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   238
    ** this function must always be allocated with sqlite3Expr() for this 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   239
    ** reason. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   240
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   241
    sqlite3ExprDelete(pLeft);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   242
    sqlite3ExprDelete(pRight);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   243
    return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   244
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   245
  pNew->op = op;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   246
  pNew->pLeft = pLeft;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   247
  pNew->pRight = pRight;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   248
  pNew->iAgg = -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   249
  if( pToken ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   250
    assert( pToken->dyn==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   251
    pNew->span = pNew->token = *pToken;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   252
  }else if( pLeft ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   253
    if( pRight ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   254
      sqlite3ExprSpan(pNew, &pLeft->span, &pRight->span);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   255
      if( pRight->flags & EP_ExpCollate ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   256
        pNew->flags |= EP_ExpCollate;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   257
        pNew->pColl = pRight->pColl;
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
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   260
    if( pLeft->flags & EP_ExpCollate ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   261
      pNew->flags |= EP_ExpCollate;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   262
      pNew->pColl = pLeft->pColl;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   263
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   264
  }
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
  sqlite3ExprSetHeight(pNew);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   267
  return pNew;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   268
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   269
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
** Works like sqlite3Expr() except that it takes an extra Parse*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   272
** argument and notifies the associated connection object if malloc fails.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   273
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   274
Expr *sqlite3PExpr(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   275
  Parse *pParse,          /* Parsing context */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   276
  int op,                 /* Expression opcode */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   277
  Expr *pLeft,            /* Left operand */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   278
  Expr *pRight,           /* Right operand */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   279
  const Token *pToken     /* Argument token */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   280
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   281
  return sqlite3Expr(pParse->db, op, pLeft, pRight, pToken);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   282
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   283
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   284
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   285
** When doing a nested parse, you can include terms in an expression
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   286
** that look like this:   #0 #1 #2 ...  These terms refer to elements
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   287
** on the stack.  "#0" means the top of the stack.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   288
** "#1" means the next down on the stack.  And so forth.
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 is called by the parser to deal with on of those terms.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   291
** It immediately generates code to store the value in a memory location.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   292
** The returns an expression that will code to extract the value from
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   293
** that memory location as needed.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   294
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   295
Expr *sqlite3RegisterExpr(Parse *pParse, Token *pToken){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   296
  Vdbe *v = pParse->pVdbe;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   297
  Expr *p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   298
  int depth;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   299
  if( pParse->nested==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   300
    sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", pToken);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   301
    return sqlite3PExpr(pParse, TK_NULL, 0, 0, 0);
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
  if( v==0 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   304
  p = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, pToken);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   305
  if( p==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   306
    return 0;  /* Malloc failed */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   307
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   308
  depth = atoi((char*)&pToken->z[1]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   309
  p->iTable = pParse->nMem++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   310
  sqlite3VdbeAddOp(v, OP_Dup, depth, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   311
  sqlite3VdbeAddOp(v, OP_MemStore, p->iTable, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   312
  return p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   313
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   314
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
** Join two expressions using an AND operator.  If either expression is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   317
** NULL, then just return the other expression.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   318
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   319
Expr *sqlite3ExprAnd(sqlite3 *db, Expr *pLeft, Expr *pRight){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   320
  if( pLeft==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   321
    return pRight;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   322
  }else if( pRight==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   323
    return pLeft;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   324
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   325
    return sqlite3Expr(db, TK_AND, pLeft, pRight, 0);
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
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   328
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   329
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   330
** Set the Expr.span field of the given expression to span all
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   331
** text between the two given tokens.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   332
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   333
void sqlite3ExprSpan(Expr *pExpr, Token *pLeft, Token *pRight){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   334
  assert( pRight!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   335
  assert( pLeft!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   336
  if( pExpr && pRight->z && pLeft->z ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   337
    assert( pLeft->dyn==0 || pLeft->z[pLeft->n]==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   338
    if( pLeft->dyn==0 && pRight->dyn==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   339
      pExpr->span.z = pLeft->z;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   340
      pExpr->span.n = pRight->n + (pRight->z - pLeft->z);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   341
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   342
      pExpr->span.z = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   343
    }
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   347
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   348
** Construct a new expression node for a function with multiple
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   349
** arguments.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   350
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   351
Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *pToken){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   352
  Expr *pNew;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   353
  assert( pToken );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   354
  pNew = (Expr*)sqlite3DbMallocZero(pParse->db, sizeof(Expr) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   355
  if( pNew==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   356
    sqlite3ExprListDelete(pList); /* Avoid leaking memory when malloc fails */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   357
    return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   358
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   359
  pNew->op = TK_FUNCTION;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   360
  pNew->pList = pList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   361
  assert( pToken->dyn==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   362
  pNew->token = *pToken;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   363
  pNew->span = pNew->token;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   364
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   365
  sqlite3ExprSetHeight(pNew);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   366
  return pNew;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   367
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   368
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   369
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   370
** Assign a variable number to an expression that encodes a wildcard
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   371
** in the original SQL statement.  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   372
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   373
** Wildcards consisting of a single "?" are assigned the next sequential
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   374
** variable number.
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
** Wildcards of the form "?nnn" are assigned the number "nnn".  We make
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   377
** sure "nnn" is not too be to avoid a denial of service attack when
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   378
** the SQL statement comes from an external source.
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
** Wildcards of the form ":aaa" or "$aaa" are assigned the same number
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   381
** as the previous instance of the same wildcard.  Or if this is the first
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   382
** instance of the wildcard, the next sequenial variable number is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   383
** assigned.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   384
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   385
void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   386
  Token *pToken;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   387
  sqlite3 *db = pParse->db;
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
  if( pExpr==0 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   390
  pToken = &pExpr->token;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   391
  assert( pToken->n>=1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   392
  assert( pToken->z!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   393
  assert( pToken->z[0]!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   394
  if( pToken->n==1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   395
    /* Wildcard of the form "?".  Assign the next variable number */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   396
    pExpr->iTable = ++pParse->nVar;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   397
  }else if( pToken->z[0]=='?' ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   398
    /* Wildcard of the form "?nnn".  Convert "nnn" to an integer and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   399
    ** use it as the variable number */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   400
    int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   401
    pExpr->iTable = i = atoi((char*)&pToken->z[1]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   402
    if( i<1 || i>SQLITE_MAX_VARIABLE_NUMBER ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   403
      sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d",
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   404
          SQLITE_MAX_VARIABLE_NUMBER);
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
    if( i>pParse->nVar ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   407
      pParse->nVar = i;
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
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   410
    /* Wildcards of the form ":aaa" or "$aaa".  Reuse the same variable
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   411
    ** number as the prior appearance of the same name, or if the name
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   412
    ** has never appeared before, reuse the same variable number
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   413
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   414
    int i, n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   415
    n = pToken->n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   416
    for(i=0; i<pParse->nVarExpr; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   417
      Expr *pE;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   418
      if( (pE = pParse->apVarExpr[i])!=0
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   419
          && pE->token.n==n
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   420
          && memcmp(pE->token.z, pToken->z, n)==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   421
        pExpr->iTable = pE->iTable;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   422
        break;
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
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   425
    if( i>=pParse->nVarExpr ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   426
      pExpr->iTable = ++pParse->nVar;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   427
      if( pParse->nVarExpr>=pParse->nVarExprAlloc-1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   428
        pParse->nVarExprAlloc += pParse->nVarExprAlloc + 10;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   429
        pParse->apVarExpr =
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   430
            (Expr**)sqlite3DbReallocOrFree(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   431
              db,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   432
              pParse->apVarExpr,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   433
              pParse->nVarExprAlloc*sizeof(pParse->apVarExpr[0])
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   434
            );
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
      if( !db->mallocFailed ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   437
        assert( pParse->apVarExpr!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   438
        pParse->apVarExpr[pParse->nVarExpr++] = pExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   439
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   440
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   441
  } 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   442
  if( !pParse->nErr && pParse->nVar>SQLITE_MAX_VARIABLE_NUMBER ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   443
    sqlite3ErrorMsg(pParse, "too many SQL variables");
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
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   446
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   447
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   448
** Recursively delete an expression tree.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   449
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   450
void sqlite3ExprDelete(Expr *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   451
  if( p==0 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   452
  if( p->span.dyn ) sqlite3_free((char*)p->span.z);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   453
  if( p->token.dyn ) sqlite3_free((char*)p->token.z);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   454
  sqlite3ExprDelete(p->pLeft);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   455
  sqlite3ExprDelete(p->pRight);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   456
  sqlite3ExprListDelete(p->pList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   457
  sqlite3SelectDelete(p->pSelect);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   458
  sqlite3_free(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   459
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   460
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   461
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   462
** The Expr.token field might be a string literal that is quoted.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   463
** If so, remove the quotation marks.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   464
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   465
void sqlite3DequoteExpr(sqlite3 *db, Expr *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   466
  if( ExprHasAnyProperty(p, EP_Dequoted) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   467
    return;
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
  ExprSetProperty(p, EP_Dequoted);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   470
  if( p->token.dyn==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   471
    sqlite3TokenCopy(db, &p->token, &p->token);
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
  sqlite3Dequote((char*)p->token.z);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   474
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   475
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   476
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
** The following group of routines make deep copies of expressions,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   479
** expression lists, ID lists, and select statements.  The copies can
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   480
** be deleted (by being passed to their respective ...Delete() routines)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   481
** without effecting the originals.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   482
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   483
** The expression list, ID, and source lists return by sqlite3ExprListDup(),
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   484
** sqlite3IdListDup(), and sqlite3SrcListDup() can not be further expanded 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   485
** by subsequent calls to sqlite*ListAppend() routines.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   486
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   487
** Any tables that the SrcList might point to are not duplicated.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   488
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   489
Expr *sqlite3ExprDup(sqlite3 *db, Expr *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   490
  Expr *pNew;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   491
  if( p==0 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   492
  pNew = (Expr*)sqlite3DbMallocRaw(db, sizeof(*p) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   493
  if( pNew==0 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   494
  memcpy(pNew, p, sizeof(*pNew));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   495
  if( p->token.z!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   496
    pNew->token.z = (u8*)sqlite3DbStrNDup(db, (char*)p->token.z, p->token.n);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   497
    pNew->token.dyn = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   498
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   499
    assert( pNew->token.z==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   500
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   501
  pNew->span.z = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   502
  pNew->pLeft = sqlite3ExprDup(db, p->pLeft);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   503
  pNew->pRight = sqlite3ExprDup(db, p->pRight);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   504
  pNew->pList = sqlite3ExprListDup(db, p->pList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   505
  pNew->pSelect = sqlite3SelectDup(db, p->pSelect);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   506
  return pNew;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   507
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   508
void sqlite3TokenCopy(sqlite3 *db, Token *pTo, Token *pFrom){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   509
  if( pTo->dyn ) sqlite3_free((char*)pTo->z);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   510
  if( pFrom->z ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   511
    pTo->n = pFrom->n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   512
    pTo->z = (u8*)sqlite3DbStrNDup(db, (char*)pFrom->z, pFrom->n);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   513
    pTo->dyn = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   514
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   515
    pTo->z = 0;
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
ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   519
  ExprList *pNew;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   520
  ExprList::ExprList_item *pItem, *pOldItem;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   521
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   522
  if( p==0 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   523
  pNew = (ExprList*)sqlite3DbMallocRaw(db, sizeof(*pNew) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   524
  if( pNew==0 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   525
  pNew->iECursor = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   526
  pNew->nExpr = pNew->nAlloc = p->nExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   527
  pNew->a = pItem = (ExprList::ExprList_item*)sqlite3DbMallocRaw(db,  p->nExpr*sizeof(p->a[0]) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   528
  if( pItem==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   529
    sqlite3_free(pNew);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   530
    return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   531
  } 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   532
  pOldItem = p->a;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   533
  for(i=0; i<p->nExpr; i++, pItem++, pOldItem++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   534
    Expr *pNewExpr, *pOldExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   535
    pItem->pExpr = pNewExpr = sqlite3ExprDup(db, pOldExpr = pOldItem->pExpr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   536
    if( pOldExpr->span.z!=0 && pNewExpr ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   537
      /* Always make a copy of the span for top-level expressions in the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   538
      ** expression list.  The logic in SELECT processing that determines
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   539
      ** the names of columns in the result set needs this information */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   540
      sqlite3TokenCopy(db, &pNewExpr->span, &pOldExpr->span);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   541
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   542
    assert( pNewExpr==0 || pNewExpr->span.z!=0 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   543
            || pOldExpr->span.z==0
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   544
            || db->mallocFailed );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   545
    pItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   546
    pItem->sortOrder = pOldItem->sortOrder;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   547
    pItem->isAgg = pOldItem->isAgg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   548
    pItem->done = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   549
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   550
  return pNew;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   551
}
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
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   554
** If cursors, triggers, views and subqueries are all omitted from
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   555
** the build, then none of the following routines, except for 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   556
** sqlite3SelectDup(), can be called. sqlite3SelectDup() is sometimes
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   557
** called with a NULL argument.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   558
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   559
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) \
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   560
 || !defined(SQLITE_OMIT_SUBQUERY)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   561
SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   562
  SrcList *pNew;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   563
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   564
  int nByte;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   565
  if( p==0 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   566
  nByte = sizeof(*p) + (p->nSrc>0 ? sizeof(p->a[0]) * (p->nSrc-1) : 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   567
  pNew = (SrcList*)sqlite3DbMallocRaw(db, nByte );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   568
  if( pNew==0 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   569
  pNew->nSrc = pNew->nAlloc = p->nSrc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   570
  for(i=0; i<p->nSrc; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   571
	  SrcList::SrcList_item *pNewItem = &pNew->a[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   572
	  SrcList::SrcList_item *pOldItem = &p->a[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   573
    Table *pTab;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   574
    pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   575
    pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   576
    pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   577
    pNewItem->jointype = pOldItem->jointype;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   578
    pNewItem->iCursor = pOldItem->iCursor;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   579
    pNewItem->isPopulated = pOldItem->isPopulated;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   580
    pTab = pNewItem->pTab = pOldItem->pTab;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   581
    if( pTab ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   582
      pTab->nRef++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   583
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   584
    pNewItem->pSelect = sqlite3SelectDup(db, pOldItem->pSelect);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   585
    pNewItem->pOn = sqlite3ExprDup(db, pOldItem->pOn);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   586
    pNewItem->pUsing = sqlite3IdListDup(db, pOldItem->pUsing);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   587
    pNewItem->colUsed = pOldItem->colUsed;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   588
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   589
  return pNew;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   590
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   591
IdList *sqlite3IdListDup(sqlite3 *db, IdList *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   592
  IdList *pNew;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   593
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   594
  if( p==0 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   595
  pNew = (IdList*)sqlite3DbMallocRaw(db, sizeof(*pNew) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   596
  if( pNew==0 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   597
  pNew->nId = pNew->nAlloc = p->nId;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   598
  pNew->a = (IdList::IdList_item*)sqlite3DbMallocRaw(db, p->nId*sizeof(p->a[0]) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   599
  if( pNew->a==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   600
    sqlite3_free(pNew);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   601
    return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   602
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   603
  for(i=0; i<p->nId; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   604
	  IdList::IdList_item *pNewItem = &pNew->a[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   605
	  IdList::IdList_item *pOldItem = &p->a[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   606
    pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   607
    pNewItem->idx = pOldItem->idx;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   608
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   609
  return pNew;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   610
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   611
Select *sqlite3SelectDup(sqlite3 *db, Select *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   612
  Select *pNew;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   613
  if( p==0 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   614
  pNew = (Select*)sqlite3DbMallocRaw(db, sizeof(*p) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   615
  if( pNew==0 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   616
  pNew->isDistinct = p->isDistinct;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   617
  pNew->pEList = sqlite3ExprListDup(db, p->pEList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   618
  pNew->pSrc = sqlite3SrcListDup(db, p->pSrc);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   619
  pNew->pWhere = sqlite3ExprDup(db, p->pWhere);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   620
  pNew->pGroupBy = sqlite3ExprListDup(db, p->pGroupBy);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   621
  pNew->pHaving = sqlite3ExprDup(db, p->pHaving);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   622
  pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   623
  pNew->op = p->op;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   624
  pNew->pPrior = sqlite3SelectDup(db, p->pPrior);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   625
  pNew->pLimit = sqlite3ExprDup(db, p->pLimit);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   626
  pNew->pOffset = sqlite3ExprDup(db, p->pOffset);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   627
  pNew->iLimit = -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   628
  pNew->iOffset = -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   629
  pNew->isResolved = p->isResolved;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   630
  pNew->isAgg = p->isAgg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   631
  pNew->usesEphm = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   632
  pNew->disallowOrderBy = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   633
  pNew->pRightmost = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   634
  pNew->addrOpenEphm[0] = -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   635
  pNew->addrOpenEphm[1] = -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   636
  pNew->addrOpenEphm[2] = -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   637
  return pNew;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   638
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   639
#else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   640
Select *sqlite3SelectDup(sqlite3 *db, Select *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   641
  assert( p==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   642
  return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   643
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   644
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   645
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
** Add a new element to the end of an expression list.  If pList is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   649
** initially NULL, then create a new expression list.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   650
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   651
ExprList *sqlite3ExprListAppend(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   652
  Parse *pParse,          /* Parsing context */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   653
  ExprList *pList,        /* List to which to append. Might be NULL */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   654
  Expr *pExpr,            /* Expression to be appended */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   655
  Token *pName            /* AS keyword for the expression */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   656
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   657
  sqlite3 *db = pParse->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   658
  if( pList==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   659
    pList = (ExprList*)sqlite3DbMallocZero(db, sizeof(ExprList) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   660
    if( pList==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   661
      goto no_mem;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   662
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   663
    assert( pList->nAlloc==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   664
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   665
  if( pList->nAlloc<=pList->nExpr ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   666
	  ExprList::ExprList_item *a;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   667
    int n = pList->nAlloc*2 + 4;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   668
	a = (ExprList::ExprList_item*)sqlite3DbRealloc(db, pList->a, n*sizeof(pList->a[0]));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   669
    if( a==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   670
      goto no_mem;
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
    pList->a = a;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   673
    pList->nAlloc = n;
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
  assert( pList->a!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   676
  if( pExpr || pName ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   677
	  ExprList::ExprList_item *pItem = &pList->a[pList->nExpr++];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   678
    memset(pItem, 0, sizeof(*pItem));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   679
    pItem->zName = sqlite3NameFromToken(db, pName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   680
    pItem->pExpr = pExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   681
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   682
  return pList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   683
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   684
no_mem:     
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   685
  /* Avoid leaking memory if malloc has failed. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   686
  sqlite3ExprDelete(pExpr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   687
  sqlite3ExprListDelete(pList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   688
  return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   689
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   690
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   691
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   692
** If the expression list pEList contains more than iLimit elements,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   693
** leave an error message in pParse.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   694
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   695
void sqlite3ExprListCheckLength(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   696
  Parse *pParse,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   697
  ExprList *pEList,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   698
  int iLimit,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   699
  const char *zObject
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   700
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   701
  if( pEList && pEList->nExpr>iLimit ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   702
    sqlite3ErrorMsg(pParse, "too many columns in %s", zObject);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   703
  }
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   706
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   707
#if defined(SQLITE_TEST) || SQLITE_MAX_EXPR_DEPTH>0
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   708
/* The following three functions, heightOfExpr(), heightOfExprList()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   709
** and heightOfSelect(), are used to determine the maximum height
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   710
** of any expression tree referenced by the structure passed as the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   711
** first argument.
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
** If this maximum height is greater than the current value pointed
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   714
** to by pnHeight, the second parameter, then set *pnHeight to that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   715
** value.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   716
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   717
static void heightOfExpr(Expr *p, int *pnHeight){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   718
  if( p ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   719
    if( p->nHeight>*pnHeight ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   720
      *pnHeight = p->nHeight;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   721
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   722
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   723
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   724
static void heightOfExprList(ExprList *p, int *pnHeight){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   725
  if( p ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   726
    int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   727
    for(i=0; i<p->nExpr; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   728
      heightOfExpr(p->a[i].pExpr, pnHeight);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   729
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   730
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   731
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   732
static void heightOfSelect(Select *p, int *pnHeight){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   733
  if( p ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   734
    heightOfExpr(p->pWhere, pnHeight);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   735
    heightOfExpr(p->pHaving, pnHeight);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   736
    heightOfExpr(p->pLimit, pnHeight);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   737
    heightOfExpr(p->pOffset, pnHeight);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   738
    heightOfExprList(p->pEList, pnHeight);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   739
    heightOfExprList(p->pGroupBy, pnHeight);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   740
    heightOfExprList(p->pOrderBy, pnHeight);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   741
    heightOfSelect(p->pPrior, pnHeight);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   742
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   743
}
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
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   746
** Set the Expr.nHeight variable in the structure passed as an 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   747
** argument. An expression with no children, Expr.pList or 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   748
** Expr.pSelect member has a height of 1. Any other expression
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   749
** has a height equal to the maximum height of any other 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   750
** referenced Expr plus one.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   751
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   752
void sqlite3ExprSetHeight(Expr *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   753
  int nHeight = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   754
  heightOfExpr(p->pLeft, &nHeight);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   755
  heightOfExpr(p->pRight, &nHeight);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   756
  heightOfExprList(p->pList, &nHeight);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   757
  heightOfSelect(p->pSelect, &nHeight);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   758
  p->nHeight = nHeight + 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   759
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   760
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   761
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   762
** Return the maximum height of any expression tree referenced
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   763
** by the select statement passed as an argument.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   764
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   765
int sqlite3SelectExprHeight(Select *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   766
  int nHeight = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   767
  heightOfSelect(p, &nHeight);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   768
  return nHeight;
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   772
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   773
** Delete an entire expression list.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   774
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   775
void sqlite3ExprListDelete(ExprList *pList){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   776
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   777
  ExprList::ExprList_item *pItem;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   778
  if( pList==0 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   779
  assert( pList->a!=0 || (pList->nExpr==0 && pList->nAlloc==0) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   780
  assert( pList->nExpr<=pList->nAlloc );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   781
  for(pItem=pList->a, i=0; i<pList->nExpr; i++, pItem++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   782
    sqlite3ExprDelete(pItem->pExpr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   783
    sqlite3_free(pItem->zName);
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
  sqlite3_free(pList->a);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   786
  sqlite3_free(pList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   787
}
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
** Walk an expression tree.  Call xFunc for each node visited.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   791
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   792
** The return value from xFunc determines whether the tree walk continues.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   793
** 0 means continue walking the tree.  1 means do not walk children
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   794
** of the current node but continue with siblings.  2 means abandon
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   795
** the tree walk completely.
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
** The return value from this routine is 1 to abandon the tree walk
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   798
** and 0 to continue.
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
** NOTICE:  This routine does *not* descend into subqueries.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   801
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   802
static int walkExprList(ExprList *, int (*)(void *, Expr*), void *);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   803
static int walkExprTree(Expr *pExpr, int (*xFunc)(void*,Expr*), void *pArg){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   804
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   805
  if( pExpr==0 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   806
  rc = (*xFunc)(pArg, pExpr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   807
  if( rc==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   808
    if( walkExprTree(pExpr->pLeft, xFunc, pArg) ) return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   809
    if( walkExprTree(pExpr->pRight, xFunc, pArg) ) return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   810
    if( walkExprList(pExpr->pList, xFunc, pArg) ) return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   811
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   812
  return rc>1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   813
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   814
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   815
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   816
** Call walkExprTree() for every expression in list p.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   817
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   818
static int walkExprList(ExprList *p, int (*xFunc)(void *, Expr*), void *pArg){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   819
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   820
  ExprList::ExprList_item *pItem;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   821
  if( !p ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   822
  for(i=p->nExpr, pItem=p->a; i>0; i--, pItem++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   823
    if( walkExprTree(pItem->pExpr, xFunc, pArg) ) return 1;
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
  return 0;
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   828
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   829
** Call walkExprTree() for every expression in Select p, not including
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   830
** expressions that are part of sub-selects in any FROM clause or the LIMIT
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   831
** or OFFSET expressions..
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   832
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   833
static int walkSelectExpr(Select *p, int (*xFunc)(void *, Expr*), void *pArg){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   834
  walkExprList(p->pEList, xFunc, pArg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   835
  walkExprTree(p->pWhere, xFunc, pArg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   836
  walkExprList(p->pGroupBy, xFunc, pArg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   837
  walkExprTree(p->pHaving, xFunc, pArg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   838
  walkExprList(p->pOrderBy, xFunc, pArg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   839
  if( p->pPrior ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   840
    walkSelectExpr(p->pPrior, xFunc, pArg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   841
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   842
  return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   843
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   844
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   845
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   846
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   847
** This routine is designed as an xFunc for walkExprTree().
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   848
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   849
** pArg is really a pointer to an integer.  If we can tell by looking
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   850
** at pExpr that the expression that contains pExpr is not a constant
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   851
** expression, then set *pArg to 0 and return 2 to abandon the tree walk.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   852
** If pExpr does does not disqualify the expression from being a constant
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   853
** then do nothing.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   854
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   855
** After walking the whole tree, if no nodes are found that disqualify
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   856
** the expression as constant, then we assume the whole expression
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   857
** is constant.  See sqlite3ExprIsConstant() for additional information.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   858
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   859
static int exprNodeIsConstant(void *pArg, Expr *pExpr){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   860
  int *pN = (int*)pArg;
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 *pArg is 3 then any term of the expression that comes from
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   863
  ** the ON or USING clauses of a join disqualifies the expression
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   864
  ** from being considered constant. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   865
  if( (*pN)==3 && ExprHasAnyProperty(pExpr, EP_FromJoin) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   866
    *pN = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   867
    return 2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   868
  }
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
  switch( pExpr->op ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   871
    /* Consider functions to be constant if all their arguments are constant
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   872
    ** and *pArg==2 */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   873
    case TK_FUNCTION:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   874
      if( (*pN)==2 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   875
      /* Fall through */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   876
    case TK_ID:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   877
    case TK_COLUMN:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   878
    case TK_DOT:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   879
    case TK_AGG_FUNCTION:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   880
    case TK_AGG_COLUMN:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   881
#ifndef SQLITE_OMIT_SUBQUERY
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   882
    case TK_SELECT:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   883
    case TK_EXISTS:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   884
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   885
      *pN = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   886
      return 2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   887
    case TK_IN:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   888
      if( pExpr->pSelect ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   889
        *pN = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   890
        return 2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   891
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   892
    default:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   893
      return 0;
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
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   896
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   897
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   898
** Walk an expression tree.  Return 1 if the expression is constant
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   899
** and 0 if it involves variables or function calls.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   900
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   901
** For the purposes of this function, a double-quoted string (ex: "abc")
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   902
** is considered a variable but a single-quoted string (ex: 'abc') is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   903
** a constant.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   904
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   905
int sqlite3ExprIsConstant(Expr *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   906
  int isConst = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   907
  walkExprTree(p, exprNodeIsConstant, &isConst);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   908
  return isConst;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   909
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   910
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
** Walk an expression tree.  Return 1 if the expression is constant
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   913
** that does no originate from the ON or USING clauses of a join.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   914
** Return 0 if it involves variables or function calls or terms from
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   915
** an ON or USING clause.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   916
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   917
int sqlite3ExprIsConstantNotJoin(Expr *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   918
  int isConst = 3;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   919
  walkExprTree(p, exprNodeIsConstant, &isConst);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   920
  return isConst!=0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   921
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   922
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   923
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   924
** Walk an expression tree.  Return 1 if the expression is constant
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   925
** or a function call with constant arguments.  Return and 0 if there
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   926
** are any variables.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   927
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   928
** For the purposes of this function, a double-quoted string (ex: "abc")
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   929
** is considered a variable but a single-quoted string (ex: 'abc') is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   930
** a constant.
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
int sqlite3ExprIsConstantOrFunction(Expr *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   933
  int isConst = 2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   934
  walkExprTree(p, exprNodeIsConstant, &isConst);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   935
  return isConst!=0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   936
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   937
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
** If the expression p codes a constant integer that is small enough
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   940
** to fit in a 32-bit integer, return 1 and put the value of the integer
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   941
** in *pValue.  If the expression is not an integer or if it is too big
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   942
** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   943
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   944
int sqlite3ExprIsInteger(Expr *p, int *pValue){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   945
  switch( p->op ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   946
    case TK_INTEGER: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   947
      if( sqlite3GetInt32((char*)p->token.z, pValue) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   948
        return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   949
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   950
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   951
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   952
    case TK_UPLUS: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   953
      return sqlite3ExprIsInteger(p->pLeft, pValue);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   954
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   955
    case TK_UMINUS: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   956
      int v;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   957
      if( sqlite3ExprIsInteger(p->pLeft, &v) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   958
        *pValue = -v;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   959
        return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   960
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   961
      break;
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
    default: break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   964
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   965
  return 0;
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   968
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   969
** Return TRUE if the given string is a row-id column name.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   970
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   971
int sqlite3IsRowid(const char *z){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   972
  if( sqlite3StrICmp(z, "_ROWID_")==0 ) return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   973
  if( sqlite3StrICmp(z, "ROWID")==0 ) return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   974
  if( sqlite3StrICmp(z, "OID")==0 ) return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   975
  return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   976
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   977
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
** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   980
** that name in the set of source tables in pSrcList and make the pExpr 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   981
** expression node refer back to that source column.  The following changes
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   982
** are made to pExpr:
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
**    pExpr->iDb           Set the index in db->aDb[] of the database holding
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   985
**                         the table.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   986
**    pExpr->iTable        Set to the cursor number for the table obtained
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   987
**                         from pSrcList.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   988
**    pExpr->iColumn       Set to the column number within the table.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   989
**    pExpr->op            Set to TK_COLUMN.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   990
**    pExpr->pLeft         Any expression this points to is deleted
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   991
**    pExpr->pRight        Any expression this points to is deleted.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   992
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   993
** The pDbToken is the name of the database (the "X").  This value may be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   994
** NULL meaning that name is of the form Y.Z or Z.  Any available database
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   995
** can be used.  The pTableToken is the name of the table (the "Y").  This
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   996
** value can be NULL if pDbToken is also NULL.  If pTableToken is NULL it
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   997
** means that the form of the name is Z and that columns from any table
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   998
** can be used.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   999
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1000
** If the name cannot be resolved unambiguously, leave an error message
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1001
** in pParse and return non-zero.  Return zero on success.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1002
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1003
static int lookupName(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1004
  Parse *pParse,       /* The parsing context */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1005
  Token *pDbToken,     /* Name of the database containing table, or NULL */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1006
  Token *pTableToken,  /* Name of table containing column, or NULL */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1007
  Token *pColumnToken, /* Name of the column. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1008
  NameContext *pNC,    /* The name context used to resolve the name */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1009
  Expr *pExpr          /* Make this EXPR node point to the selected column */
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
  char *zDb = 0;       /* Name of the database.  The "X" in X.Y.Z */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1012
  char *zTab = 0;      /* Name of the table.  The "Y" in X.Y.Z or Y.Z */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1013
  char *zCol = 0;      /* Name of the column.  The "Z" */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1014
  int i, j;            /* Loop counters */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1015
  int cnt = 0;         /* Number of matching column names */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1016
  int cntTab = 0;      /* Number of matching table names */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1017
  sqlite3 *db = pParse->db;  /* The database */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1018
  SrcList::SrcList_item *pItem;       /* Use for looping over pSrcList items */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1019
  SrcList::SrcList_item *pMatch = 0;  /* The matching pSrcList item */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1020
  NameContext *pTopNC = pNC;        /* First namecontext in the list */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1021
  Schema *pSchema = 0;              /* Schema of the expression */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1022
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1023
  assert( pColumnToken && pColumnToken->z ); /* The Z in X.Y.Z cannot be NULL */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1024
  zDb = sqlite3NameFromToken(db, pDbToken);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1025
  zTab = sqlite3NameFromToken(db, pTableToken);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1026
  zCol = sqlite3NameFromToken(db, pColumnToken);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1027
  if( db->mallocFailed ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1028
    goto lookupname_end;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1029
  }
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
  pExpr->iTable = -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1032
  while( pNC && cnt==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1033
    ExprList *pEList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1034
    SrcList *pSrcList = pNC->pSrcList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1035
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1036
    if( pSrcList ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1037
      for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1038
        Table *pTab;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1039
        int iDb;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1040
        Column *pCol;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1041
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1042
        pTab = pItem->pTab;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1043
        assert( pTab!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1044
        iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1045
        assert( pTab->nCol>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1046
        if( zTab ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1047
          if( pItem->zAlias ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1048
            char *zTabName = pItem->zAlias;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1049
            if( sqlite3StrICmp(zTabName, zTab)!=0 ) continue;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1050
          }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1051
            char *zTabName = pTab->zName;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1052
            if( zTabName==0 || sqlite3StrICmp(zTabName, zTab)!=0 ) continue;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1053
            if( zDb!=0 && sqlite3StrICmp(db->aDb[iDb].zName, zDb)!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1054
              continue;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1055
            }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1056
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1057
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1058
        if( 0==(cntTab++) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1059
          pExpr->iTable = pItem->iCursor;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1060
          pSchema = pTab->pSchema;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1061
          pMatch = pItem;
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
        for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1064
          if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1065
            const char *zColl = pTab->aCol[j].zColl;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1066
            IdList *pUsing;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1067
            cnt++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1068
            pExpr->iTable = pItem->iCursor;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1069
            pMatch = pItem;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1070
            pSchema = pTab->pSchema;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1071
            /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1072
            pExpr->iColumn = j==pTab->iPKey ? -1 : j;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1073
            pExpr->affinity = pTab->aCol[j].affinity;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1074
            if( (pExpr->flags & EP_ExpCollate)==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1075
              pExpr->pColl = sqlite3FindCollSeq(db, ENC(db), zColl,-1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1076
            }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1077
            if( i<pSrcList->nSrc-1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1078
              if( pItem[1].jointype & JT_NATURAL ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1079
                /* If this match occurred in the left table of a natural join,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1080
                ** then skip the right table to avoid a duplicate match */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1081
                pItem++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1082
                i++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1083
              }else if( (pUsing = pItem[1].pUsing)!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1084
                /* If this match occurs on a column that is in the USING clause
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1085
                ** of a join, skip the search of the right table of the join
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1086
                ** to avoid a duplicate match there. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1087
                int k;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1088
                for(k=0; k<pUsing->nId; k++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1089
                  if( sqlite3StrICmp(pUsing->a[k].zName, zCol)==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1090
                    pItem++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1091
                    i++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1092
                    break;
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
                }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1095
              }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1096
            }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1097
            break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1098
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1099
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1100
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1101
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1102
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1103
#ifndef SQLITE_OMIT_TRIGGER
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1104
    /* If we have not already resolved the name, then maybe 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1105
    ** it is a new.* or old.* trigger argument reference
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1106
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1107
    if( zDb==0 && zTab!=0 && cnt==0 && pParse->trigStack!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1108
      TriggerStack *pTriggerStack = pParse->trigStack;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1109
      Table *pTab = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1110
      if( pTriggerStack->newIdx != -1 && sqlite3StrICmp("new", zTab) == 0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1111
        pExpr->iTable = pTriggerStack->newIdx;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1112
        assert( pTriggerStack->pTab );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1113
        pTab = pTriggerStack->pTab;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1114
      }else if( pTriggerStack->oldIdx != -1 && sqlite3StrICmp("old", zTab)==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1115
        pExpr->iTable = pTriggerStack->oldIdx;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1116
        assert( pTriggerStack->pTab );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1117
        pTab = pTriggerStack->pTab;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1118
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1119
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1120
      if( pTab ){ 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1121
        int iCol;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1122
        Column *pCol = pTab->aCol;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1123
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1124
        pSchema = pTab->pSchema;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1125
        cntTab++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1126
        for(iCol=0; iCol < pTab->nCol; iCol++, pCol++) {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1127
          if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1128
            const char *zColl = pTab->aCol[iCol].zColl;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1129
            cnt++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1130
            pExpr->iColumn = iCol==pTab->iPKey ? -1 : iCol;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1131
            pExpr->affinity = pTab->aCol[iCol].affinity;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1132
            if( (pExpr->flags & EP_ExpCollate)==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1133
              pExpr->pColl = sqlite3FindCollSeq(db, ENC(db), zColl,-1, 0);
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
            pExpr->pTab = pTab;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1136
            break;
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
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1139
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1140
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1141
#endif /* !defined(SQLITE_OMIT_TRIGGER) */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1142
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1143
    /*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1144
    ** Perhaps the name is a reference to the ROWID
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
    if( cnt==0 && cntTab==1 && sqlite3IsRowid(zCol) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1147
      cnt = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1148
      pExpr->iColumn = -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1149
      pExpr->affinity = SQLITE_AFF_INTEGER;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1150
    }
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
    /*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1153
    ** If the input is of the form Z (not Y.Z or X.Y.Z) then the name Z
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1154
    ** might refer to an result-set alias.  This happens, for example, when
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1155
    ** we are resolving names in the WHERE clause of the following command:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1156
    **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1157
    **     SELECT a+b AS x FROM table WHERE x<10;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1158
    **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1159
    ** In cases like this, replace pExpr with a copy of the expression that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1160
    ** forms the result set entry ("a+b" in the example) and return immediately.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1161
    ** Note that the expression in the result set should have already been
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1162
    ** resolved by the time the WHERE clause is resolved.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1163
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1164
    if( cnt==0 && (pEList = pNC->pEList)!=0 && zTab==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1165
      for(j=0; j<pEList->nExpr; j++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1166
        char *zAs = pEList->a[j].zName;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1167
        if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1168
          Expr *pDup, *pOrig;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1169
          assert( pExpr->pLeft==0 && pExpr->pRight==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1170
          assert( pExpr->pList==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1171
          assert( pExpr->pSelect==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1172
          pOrig = pEList->a[j].pExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1173
          if( !pNC->allowAgg && ExprHasProperty(pOrig, EP_Agg) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1174
            sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1175
            sqlite3_free(zCol);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1176
            return 2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1177
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1178
          pDup = sqlite3ExprDup(db, pOrig);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1179
          if( pExpr->flags & EP_ExpCollate ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1180
            pDup->pColl = pExpr->pColl;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1181
            pDup->flags |= EP_ExpCollate;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1182
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1183
          if( pExpr->span.dyn ) sqlite3_free((char*)pExpr->span.z);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1184
          if( pExpr->token.dyn ) sqlite3_free((char*)pExpr->token.z);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1185
          memcpy(pExpr, pDup, sizeof(*pExpr));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1186
          sqlite3_free(pDup);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1187
          cnt = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1188
          pMatch = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1189
          assert( zTab==0 && zDb==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1190
          goto lookupname_end_2;
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
      } 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1193
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1194
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1195
    /* Advance to the next name context.  The loop will exit when either
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1196
    ** we have a match (cnt>0) or when we run out of name contexts.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1197
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1198
    if( cnt==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1199
      pNC = pNC->pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1200
    }
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1203
  /*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1204
  ** If X and Y are NULL (in other words if only the column name Z is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1205
  ** supplied) and the value of Z is enclosed in double-quotes, then
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1206
  ** Z is a string literal if it doesn't match any column names.  In that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1207
  ** case, we need to return right away and not make any changes to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1208
  ** pExpr.
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
  ** Because no reference was made to outer contexts, the pNC->nRef
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1211
  ** fields are not changed in any context.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1212
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1213
  if( cnt==0 && zTab==0 && pColumnToken->z[0]=='"' ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1214
    sqlite3_free(zCol);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1215
    return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1216
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1217
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1218
  /*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1219
  ** cnt==0 means there was not match.  cnt>1 means there were two or
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1220
  ** more matches.  Either way, we have an error.
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( cnt!=1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1223
    char *z = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1224
    char *zErr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1225
    zErr = (char*)(cnt==0 ? "no such column: %s" : "ambiguous column name: %s");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1226
    if( zDb ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1227
      sqlite3SetString(&z, zDb, ".", zTab, ".", zCol, (char*)0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1228
    }else if( zTab ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1229
      sqlite3SetString(&z, zTab, ".", zCol, (char*)0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1230
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1231
      z = sqlite3StrDup(zCol);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1232
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1233
    if( z ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1234
      sqlite3ErrorMsg(pParse, zErr, z);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1235
      sqlite3_free(z);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1236
      pTopNC->nErr++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1237
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1238
      db->mallocFailed = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1239
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1240
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1241
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1242
  /* If a column from a table in pSrcList is referenced, then record
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1243
  ** this fact in the pSrcList.a[].colUsed bitmask.  Column 0 causes
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1244
  ** bit 0 to be set.  Column 1 sets bit 1.  And so forth.  If the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1245
  ** column number is greater than the number of bits in the bitmask
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1246
  ** then set the high-order bit of the bitmask.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1247
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1248
  if( pExpr->iColumn>=0 && pMatch!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1249
    int n = pExpr->iColumn;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1250
    if( n>=sizeof(Bitmask)*8 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1251
      n = sizeof(Bitmask)*8-1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1252
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1253
    assert( pMatch->iCursor==pExpr->iTable );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1254
    pMatch->colUsed |= ((Bitmask)1)<<n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1255
  }
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
lookupname_end:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1258
  /* Clean up and return
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1259
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1260
  sqlite3_free(zDb);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1261
  sqlite3_free(zTab);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1262
  sqlite3ExprDelete(pExpr->pLeft);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1263
  pExpr->pLeft = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1264
  sqlite3ExprDelete(pExpr->pRight);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1265
  pExpr->pRight = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1266
  pExpr->op = TK_COLUMN;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1267
lookupname_end_2:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1268
  sqlite3_free(zCol);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1269
  if( cnt==1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1270
    assert( pNC!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1271
    sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1272
    if( pMatch && !pMatch->pSelect ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1273
      pExpr->pTab = pMatch->pTab;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1274
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1275
    /* Increment the nRef value on all name contexts from TopNC up to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1276
    ** the point where the name matched. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1277
    for(;;){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1278
      assert( pTopNC!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1279
      pTopNC->nRef++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1280
      if( pTopNC==pNC ) break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1281
      pTopNC = pTopNC->pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1282
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1283
    return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1284
  } else {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1285
    return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1286
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1287
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1288
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
** This routine is designed as an xFunc for walkExprTree().
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1291
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1292
** Resolve symbolic names into TK_COLUMN operators for the current
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1293
** node in the expression tree.  Return 0 to continue the search down
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1294
** the tree or 2 to abort the tree walk.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1295
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1296
** This routine also does error checking and name resolution for
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1297
** function names.  The operator for aggregate functions is changed
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1298
** to TK_AGG_FUNCTION.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1299
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1300
static int nameResolverStep(void *pArg, Expr *pExpr){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1301
  NameContext *pNC = (NameContext*)pArg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1302
  Parse *pParse;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1303
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1304
  if( pExpr==0 ) return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1305
  assert( pNC!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1306
  pParse = pNC->pParse;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1307
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1308
  if( ExprHasAnyProperty(pExpr, EP_Resolved) ) return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1309
  ExprSetProperty(pExpr, EP_Resolved);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1310
#ifndef NDEBUG
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1311
  if( pNC->pSrcList && pNC->pSrcList->nAlloc>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1312
    SrcList *pSrcList = pNC->pSrcList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1313
    int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1314
    for(i=0; i<pNC->pSrcList->nSrc; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1315
      assert( pSrcList->a[i].iCursor>=0 && pSrcList->a[i].iCursor<pParse->nTab);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1316
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1317
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1318
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1319
  switch( pExpr->op ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1320
    /* Double-quoted strings (ex: "abc") are used as identifiers if
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1321
    ** possible.  Otherwise they remain as strings.  Single-quoted
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1322
    ** strings (ex: 'abc') are always string literals.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1323
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1324
    case TK_STRING: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1325
      if( pExpr->token.z[0]=='\'' ) break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1326
      /* Fall thru into the TK_ID case if this is a double-quoted string */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1327
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1328
    /* A lone identifier is the name of a column.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1329
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1330
    case TK_ID: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1331
      lookupName(pParse, 0, 0, &pExpr->token, pNC, pExpr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1332
      return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1333
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1334
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1335
    /* A table name and column name:     ID.ID
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1336
    ** Or a database, table and column:  ID.ID.ID
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1337
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1338
    case TK_DOT: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1339
      Token *pColumn;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1340
      Token *pTable;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1341
      Token *pDb;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1342
      Expr *pRight;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1343
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1344
      /* if( pSrcList==0 ) break; */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1345
      pRight = pExpr->pRight;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1346
      if( pRight->op==TK_ID ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1347
        pDb = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1348
        pTable = &pExpr->pLeft->token;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1349
        pColumn = &pRight->token;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1350
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1351
        assert( pRight->op==TK_DOT );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1352
        pDb = &pExpr->pLeft->token;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1353
        pTable = &pRight->pLeft->token;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1354
        pColumn = &pRight->pRight->token;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1355
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1356
      lookupName(pParse, pDb, pTable, pColumn, pNC, pExpr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1357
      return 1;
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1360
    /* Resolve function names
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1361
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1362
    case TK_CONST_FUNC:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1363
    case TK_FUNCTION: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1364
      ExprList *pList = pExpr->pList;    /* The argument list */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1365
      int n = pList ? pList->nExpr : 0;  /* Number of arguments */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1366
      int no_such_func = 0;       /* True if no such function exists */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1367
      int wrong_num_args = 0;     /* True if wrong number of arguments */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1368
      int is_agg = 0;             /* True if is an aggregate function */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1369
      int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1370
      int auth;                   /* Authorization to use the function */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1371
      int nId;                    /* Number of characters in function name */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1372
      const char *zId;            /* The function name. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1373
      FuncDef *pDef;              /* Information about the function */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1374
      int enc = ENC(pParse->db);  /* The database encoding */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1375
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1376
      zId = (char*)pExpr->token.z;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1377
      nId = pExpr->token.n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1378
      pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1379
      if( pDef==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1380
        pDef = sqlite3FindFunction(pParse->db, zId, nId, -1, enc, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1381
        if( pDef==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1382
          no_such_func = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1383
        }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1384
          wrong_num_args = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1385
        }
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
        is_agg = pDef->xFunc==0;
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
#ifndef SQLITE_OMIT_AUTHORIZATION
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1390
      if( pDef ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1391
        auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0, pDef->zName, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1392
        if( auth!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1393
          if( auth==SQLITE_DENY ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1394
            sqlite3ErrorMsg(pParse, "not authorized to use function: %s",
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1395
                                    pDef->zName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1396
            pNC->nErr++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1397
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1398
          pExpr->op = TK_NULL;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1399
          return 1;
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
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1403
      if( is_agg && !pNC->allowAgg ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1404
        sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1405
        pNC->nErr++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1406
        is_agg = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1407
      }else if( no_such_func ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1408
        sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1409
        pNC->nErr++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1410
      }else if( wrong_num_args ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1411
        sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()",
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1412
             nId, zId);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1413
        pNC->nErr++;
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
      if( is_agg ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1416
        pExpr->op = TK_AGG_FUNCTION;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1417
        pNC->hasAgg = 1;
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( is_agg ) pNC->allowAgg = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1420
      for(i=0; pNC->nErr==0 && i<n; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1421
        walkExprTree(pList->a[i].pExpr, nameResolverStep, pNC);
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( is_agg ) pNC->allowAgg = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1424
      /* FIX ME:  Compute pExpr->affinity based on the expected return
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1425
      ** type of the function 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1426
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1427
      return is_agg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1428
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1429
#ifndef SQLITE_OMIT_SUBQUERY
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1430
    case TK_SELECT:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1431
    case TK_EXISTS:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1432
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1433
    case TK_IN: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1434
      if( pExpr->pSelect ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1435
        int nRef = pNC->nRef;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1436
#ifndef SQLITE_OMIT_CHECK
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1437
        if( pNC->isCheck ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1438
          sqlite3ErrorMsg(pParse,"subqueries prohibited in CHECK constraints");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1439
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1440
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1441
        sqlite3SelectResolve(pParse, pExpr->pSelect, pNC);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1442
        assert( pNC->nRef>=nRef );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1443
        if( nRef!=pNC->nRef ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1444
          ExprSetProperty(pExpr, EP_VarSelect);
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
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1448
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1449
#ifndef SQLITE_OMIT_CHECK
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1450
    case TK_VARIABLE: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1451
      if( pNC->isCheck ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1452
        sqlite3ErrorMsg(pParse,"parameters prohibited in CHECK constraints");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1453
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1454
      break;
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
#endif
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 0;
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
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1462
** This routine walks an expression tree and resolves references to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1463
** table columns.  Nodes of the form ID.ID or ID resolve into an
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1464
** index to the table in the table list and a column offset.  The 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1465
** Expr.opcode for such nodes is changed to TK_COLUMN.  The Expr.iTable
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1466
** value is changed to the index of the referenced table in pTabList
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1467
** plus the "base" value.  The base value will ultimately become the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1468
** VDBE cursor number for a cursor that is pointing into the referenced
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1469
** table.  The Expr.iColumn value is changed to the index of the column 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1470
** of the referenced table.  The Expr.iColumn value for the special
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1471
** ROWID column is -1.  Any INTEGER PRIMARY KEY column is tried as an
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1472
** alias for ROWID.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1473
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1474
** Also resolve function names and check the functions for proper
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1475
** usage.  Make sure all function names are recognized and all functions
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1476
** have the correct number of arguments.  Leave an error message
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1477
** in pParse->zErrMsg if anything is amiss.  Return the number of errors.
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
** If the expression contains aggregate functions then set the EP_Agg
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1480
** property on the 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
int sqlite3ExprResolveNames( 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1483
  NameContext *pNC,       /* Namespace to resolve expressions in. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1484
  Expr *pExpr             /* The expression to be analyzed. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1485
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1486
  int savedHasAgg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1487
  if( pExpr==0 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1488
#if defined(SQLITE_TEST) || SQLITE_MAX_EXPR_DEPTH>0
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1489
  if( (pExpr->nHeight+pNC->pParse->nHeight)>SQLITE_MAX_EXPR_DEPTH ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1490
    sqlite3ErrorMsg(pNC->pParse, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1491
       "Expression tree is too large (maximum depth %d)",
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1492
       SQLITE_MAX_EXPR_DEPTH
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1493
    );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1494
    return 1;
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
  pNC->pParse->nHeight += pExpr->nHeight;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1497
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1498
  savedHasAgg = pNC->hasAgg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1499
  pNC->hasAgg = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1500
  walkExprTree(pExpr, nameResolverStep, pNC);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1501
#if defined(SQLITE_TEST) || SQLITE_MAX_EXPR_DEPTH>0
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1502
  pNC->pParse->nHeight -= pExpr->nHeight;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1503
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1504
  if( pNC->nErr>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1505
    ExprSetProperty(pExpr, EP_Error);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1506
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1507
  if( pNC->hasAgg ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1508
    ExprSetProperty(pExpr, EP_Agg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1509
  }else if( savedHasAgg ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1510
    pNC->hasAgg = 1;
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
  return ExprHasProperty(pExpr, EP_Error);
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
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1516
** A pointer instance of this structure is used to pass information
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1517
** through walkExprTree into codeSubqueryStep().
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1518
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1519
typedef struct QueryCoder QueryCoder;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1520
struct QueryCoder {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1521
  Parse *pParse;       /* The parsing context */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1522
  NameContext *pNC;    /* Namespace of first enclosing query */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1523
};
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1524
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1525
#ifdef SQLITE_TEST
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1526
  int sqlite3_enable_in_opt = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1527
#else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1528
  #define sqlite3_enable_in_opt 1
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1529
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1530
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1531
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1532
** This function is used by the implementation of the IN (...) operator.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1533
** It's job is to find or create a b-tree structure that may be used
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1534
** either to test for membership of the (...) set or to iterate through
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1535
** its members, skipping duplicates.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1536
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1537
** The cursor opened on the structure (database table, database index 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1538
** or ephermal table) is stored in pX->iTable before this function returns.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1539
** The returned value indicates the structure type, as follows:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1540
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1541
**   IN_INDEX_ROWID - The cursor was opened on a database table.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1542
**   IN_INDEX_INDEX - The cursor was opened on a database indec.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1543
**   IN_INDEX_EPH -   The cursor was opened on a specially created and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1544
**                    populated epheremal table.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1545
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1546
** An existing structure may only be used if the SELECT is of the simple
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1547
** form:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1548
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1549
**     SELECT <column> FROM <table>
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 the mustBeUnique parameter is false, the structure will be used 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1552
** for fast set membership tests. In this case an epheremal table must 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1553
** be used unless <column> is an INTEGER PRIMARY KEY or an index can 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1554
** be found with <column> as its left-most column.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1555
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1556
** If mustBeUnique is true, then the structure will be used to iterate
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1557
** through the set members, skipping any duplicates. In this case an
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1558
** epheremal table must be used unless the selected <column> is guaranteed
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1559
** to be unique - either because it is an INTEGER PRIMARY KEY or it
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1560
** is unique by virtue of a constraint or implicit index.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1561
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1562
#ifndef SQLITE_OMIT_SUBQUERY
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1563
int sqlite3FindInIndex(Parse *pParse, Expr *pX, int mustBeUnique){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1564
  Select *p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1565
  int eType = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1566
  int iTab = pParse->nTab++;
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
  /* The follwing if(...) expression is true if the SELECT is of the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1569
  ** simple form:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1570
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1571
  **     SELECT <column> FROM <table>
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
  ** If this is the case, it may be possible to use an existing table
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1574
  ** or index instead of generating an epheremal table.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1575
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1576
  if( sqlite3_enable_in_opt
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1577
   && (p=pX->pSelect) && !p->pPrior
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1578
   && !p->isDistinct && !p->isAgg && !p->pGroupBy
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1579
   && p->pSrc && p->pSrc->nSrc==1 && !p->pSrc->a[0].pSelect
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1580
   && !p->pSrc->a[0].pTab->pSelect                                  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1581
   && p->pEList->nExpr==1 && p->pEList->a[0].pExpr->op==TK_COLUMN
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1582
   && !p->pLimit && !p->pOffset && !p->pWhere
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1583
  ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1584
    sqlite3 *db = pParse->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1585
    Index *pIdx;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1586
    Expr *pExpr = p->pEList->a[0].pExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1587
    int iCol = pExpr->iColumn;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1588
    Vdbe *v = sqlite3GetVdbe(pParse);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1589
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1590
    /* This function is only called from two places. In both cases the vdbe
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1591
    ** has already been allocated. So assume sqlite3GetVdbe() is always
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1592
    ** successful here.
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
    assert(v);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1595
    if( iCol<0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1596
      int iMem = pParse->nMem++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1597
      int iAddr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1598
      Table *pTab = p->pSrc->a[0].pTab;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1599
      int iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1600
      sqlite3VdbeUsesBtree(v, iDb);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1601
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1602
      sqlite3VdbeAddOp(v, OP_MemLoad, iMem, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1603
      iAddr = sqlite3VdbeAddOp(v, OP_If, 0, iMem);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1604
      sqlite3VdbeAddOp(v, OP_MemInt, 1, iMem);
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
      sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1607
      eType = IN_INDEX_ROWID;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1608
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1609
      sqlite3VdbeJumpHere(v, iAddr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1610
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1611
      /* The collation sequence used by the comparison. If an index is to 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1612
      ** be used in place of a temp-table, it must be ordered according
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1613
      ** to this collation sequence.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1614
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1615
      CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pExpr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1616
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1617
      /* Check that the affinity that will be used to perform the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1618
      ** comparison is the same as the affinity of the column. If
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1619
      ** it is not, it is not possible to use any index.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1620
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1621
      Table *pTab = p->pSrc->a[0].pTab;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1622
      char aff = comparisonAffinity(pX);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1623
      int affinity_ok = (pTab->aCol[iCol].affinity==aff||aff==SQLITE_AFF_NONE);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1624
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1625
      for(pIdx=pTab->pIndex; pIdx && eType==0 && affinity_ok; pIdx=pIdx->pNext){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1626
        if( (pIdx->aiColumn[0]==iCol)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1627
         && (pReq==sqlite3FindCollSeq(db, ENC(db), pIdx->azColl[0], -1, 0))
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1628
         && (!mustBeUnique || (pIdx->nColumn==1 && pIdx->onError!=OE_None))
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1629
        ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1630
          int iDb;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1631
          int iMem = pParse->nMem++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1632
          int iAddr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1633
          char *pKey;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1634
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1635
          pKey = (char *)sqlite3IndexKeyinfo(pParse, pIdx);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1636
          iDb = sqlite3SchemaToIndex(db, pIdx->pSchema);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1637
          sqlite3VdbeUsesBtree(v, iDb);
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
          sqlite3VdbeAddOp(v, OP_MemLoad, iMem, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1640
          iAddr = sqlite3VdbeAddOp(v, OP_If, 0, iMem);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1641
          sqlite3VdbeAddOp(v, OP_MemInt, 1, iMem);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1642
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1643
          sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1644
          VdbeComment((v, "# %s", pIdx->zName));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1645
          sqlite3VdbeOp3(v,OP_OpenRead,iTab,pIdx->tnum,pKey,P3_KEYINFO_HANDOFF);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1646
          eType = IN_INDEX_INDEX;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1647
          sqlite3VdbeAddOp(v, OP_SetNumColumns, iTab, pIdx->nColumn);
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
          sqlite3VdbeJumpHere(v, iAddr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1650
        }
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
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1653
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1654
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1655
  if( eType==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1656
    sqlite3CodeSubselect(pParse, pX);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1657
    eType = IN_INDEX_EPH;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1658
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1659
    pX->iTable = iTab;
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
  return eType;
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
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1664
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
** Generate code for scalar subqueries used as an expression
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1667
** and IN operators.  Examples:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1668
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1669
**     (SELECT a FROM b)          -- subquery
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1670
**     EXISTS (SELECT a FROM b)   -- EXISTS subquery
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1671
**     x IN (4,5,11)              -- IN operator with list on right-hand side
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1672
**     x IN (SELECT a FROM b)     -- IN operator with subquery on the right
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
** The pExpr parameter describes the expression that contains the IN
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1675
** operator or subquery.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1676
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1677
#ifndef SQLITE_OMIT_SUBQUERY
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1678
void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1679
  int testAddr = 0;                       /* One-time test address */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1680
  Vdbe *v = sqlite3GetVdbe(pParse);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1681
  if( v==0 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1682
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 code must be run in its entirety every time it is encountered
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1685
  ** if any of the following is true:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1686
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1687
  **    *  The right-hand side is a correlated subquery
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1688
  **    *  The right-hand side is an expression list containing variables
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1689
  **    *  We are inside a trigger
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1690
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1691
  ** If all of the above are false, then we can run this code just once
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1692
  ** save the results, and reuse the same result on subsequent invocations.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1693
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1694
  if( !ExprHasAnyProperty(pExpr, EP_VarSelect) && !pParse->trigStack ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1695
    int mem = pParse->nMem++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1696
    sqlite3VdbeAddOp(v, OP_MemLoad, mem, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1697
    testAddr = sqlite3VdbeAddOp(v, OP_If, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1698
    assert( testAddr>0 || pParse->db->mallocFailed );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1699
    sqlite3VdbeAddOp(v, OP_MemInt, 1, mem);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1700
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1701
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1702
  switch( pExpr->op ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1703
    case TK_IN: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1704
      char affinity;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1705
      KeyInfo keyInfo;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1706
      int addr;        /* Address of OP_OpenEphemeral instruction */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1707
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1708
      affinity = sqlite3ExprAffinity(pExpr->pLeft);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1709
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1710
      /* Whether this is an 'x IN(SELECT...)' or an 'x IN(<exprlist>)'
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1711
      ** expression it is handled the same way. A virtual table is 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1712
      ** filled with single-field index keys representing the results
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1713
      ** from the SELECT or the <exprlist>.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1714
      **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1715
      ** If the 'x' expression is a column value, or the SELECT...
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1716
      ** statement returns a column value, then the affinity of that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1717
      ** column is used to build the index keys. If both 'x' and the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1718
      ** SELECT... statement are columns, then numeric affinity is used
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1719
      ** if either column has NUMERIC or INTEGER affinity. If neither
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1720
      ** 'x' nor the SELECT... statement are columns, then numeric affinity
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1721
      ** is used.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1722
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1723
      pExpr->iTable = pParse->nTab++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1724
      addr = sqlite3VdbeAddOp(v, OP_OpenEphemeral, pExpr->iTable, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1725
      memset(&keyInfo, 0, sizeof(keyInfo));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1726
      keyInfo.nField = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1727
      sqlite3VdbeAddOp(v, OP_SetNumColumns, pExpr->iTable, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1728
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1729
      if( pExpr->pSelect ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1730
        /* Case 1:     expr IN (SELECT ...)
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
        ** Generate code to write the results of the select into the temporary
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1733
        ** table allocated and opened above.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1734
        */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1735
        int iParm = pExpr->iTable +  (((int)affinity)<<16);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1736
        ExprList *pEList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1737
        assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1738
        if( sqlite3Select(pParse, pExpr->pSelect, SRT_Set, iParm, 0, 0, 0, 0) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1739
          return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1740
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1741
        pEList = pExpr->pSelect->pEList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1742
        if( pEList && pEList->nExpr>0 ){ 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1743
          keyInfo.aColl[0] = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1744
              pEList->a[0].pExpr);
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
      }else if( pExpr->pList ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1747
        /* Case 2:     expr IN (exprlist)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1748
        **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1749
        ** For each expression, build an index key from the evaluation and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1750
        ** store it in the temporary table. If <expr> is a column, then use
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1751
        ** that columns affinity when building index keys. If <expr> is not
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1752
        ** a column, use numeric affinity.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1753
        */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1754
        int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1755
        ExprList *pList = pExpr->pList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1756
		ExprList::ExprList_item *pItem;
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
        if( !affinity ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1759
          affinity = SQLITE_AFF_NONE;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1760
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1761
        keyInfo.aColl[0] = pExpr->pLeft->pColl;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1762
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1763
        /* Loop through each expression in <exprlist>. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1764
        for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1765
          Expr *pE2 = pItem->pExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1766
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1767
          /* If the expression is not constant then we will need to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1768
          ** disable the test that was generated above that makes sure
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1769
          ** this code only executes once.  Because for a non-constant
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1770
          ** expression we need to rerun this code each time.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1771
          */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1772
          if( testAddr>0 && !sqlite3ExprIsConstant(pE2) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1773
            sqlite3VdbeChangeToNoop(v, testAddr-1, 3);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1774
            testAddr = 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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1777
          /* Evaluate the expression and insert it into the temp table */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1778
          sqlite3ExprCode(pParse, pE2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1779
          sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &affinity, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1780
          sqlite3VdbeAddOp(v, OP_IdxInsert, pExpr->iTable, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1781
        }
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
      sqlite3VdbeChangeP3(v, addr, (const char *)&keyInfo, P3_KEYINFO);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1784
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1785
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1786
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1787
    case TK_EXISTS:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1788
    case TK_SELECT: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1789
      /* This has to be a scalar SELECT.  Generate code to put the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1790
      ** value of this select in a memory cell and record the number
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1791
      ** of the memory cell in iColumn.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1792
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1793
      static const Token one = { (u8*)"1", 0, 1 };
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1794
      Select *pSel;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1795
      int iMem;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1796
      int sop;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1797
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1798
      pExpr->iColumn = iMem = pParse->nMem++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1799
      pSel = pExpr->pSelect;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1800
      if( pExpr->op==TK_SELECT ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1801
        sop = SRT_Mem;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1802
        sqlite3VdbeAddOp(v, OP_MemNull, iMem, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1803
        VdbeComment((v, "# Init subquery result"));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1804
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1805
        sop = SRT_Exists;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1806
        sqlite3VdbeAddOp(v, OP_MemInt, 0, iMem);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1807
        VdbeComment((v, "# Init EXISTS result"));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1808
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1809
      sqlite3ExprDelete(pSel->pLimit);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1810
      pSel->pLimit = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, &one);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1811
      if( sqlite3Select(pParse, pSel, sop, iMem, 0, 0, 0, 0) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1812
        return;
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
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1815
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1816
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1817
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1818
  if( testAddr ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1819
    sqlite3VdbeJumpHere(v, testAddr);
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1822
  return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1823
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1824
#endif /* SQLITE_OMIT_SUBQUERY */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1825
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1826
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1827
** Duplicate an 8-byte value
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
static char *dup8bytes(Vdbe *v, const char *in){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1830
  char *out = (char*)sqlite3DbMallocRaw(sqlite3VdbeDb(v), 8);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1831
  if( out ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1832
    memcpy(out, in, 8);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1833
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1834
  return out;
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1837
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1838
** Generate an instruction that will put the floating point
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1839
** value described by z[0..n-1] on the stack.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1840
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1841
** The z[] string will probably not be zero-terminated.  But the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1842
** z[n] character is guaranteed to be something that does not look
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1843
** like the continuation of the number.
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
static void codeReal(Vdbe *v, const char *z, int n, int negateFlag){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1846
  assert( z || v==0 || sqlite3VdbeDb(v)->mallocFailed );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1847
  if( z ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1848
    double value;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1849
    char *zV;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1850
    assert( !isdigit(z[n]) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1851
    sqlite3AtoF(z, &value);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1852
    if( negateFlag ) value = -value;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1853
    zV = dup8bytes(v, (char*)&value);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1854
    sqlite3VdbeOp3(v, OP_Real, 0, 0, zV, P3_REAL);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1855
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1856
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1857
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
** Generate an instruction that will put the integer describe by
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1861
** text z[0..n-1] on the stack.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1862
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1863
** The z[] string will probably not be zero-terminated.  But the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1864
** z[n] character is guaranteed to be something that does not look
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1865
** like the continuation of the number.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1866
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1867
static void codeInteger(Vdbe *v, const char *z, int n, int negateFlag){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1868
  assert( z || v==0 || sqlite3VdbeDb(v)->mallocFailed );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1869
  if( z ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1870
    int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1871
    assert( !isdigit(z[n]) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1872
    if( sqlite3GetInt32(z, &i) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1873
      if( negateFlag ) i = -i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1874
      sqlite3VdbeAddOp(v, OP_Integer, i, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1875
    }else if( sqlite3FitsIn64Bits(z, negateFlag) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1876
      i64 value;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1877
      char *zV;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1878
      sqlite3Atoi64(z, &value);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1879
      if( negateFlag ) value = -value;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1880
      zV = dup8bytes(v, (char*)&value);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1881
      sqlite3VdbeOp3(v, OP_Int64, 0, 0, zV, P3_INT64);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1882
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1883
      codeReal(v, z, n, negateFlag);
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
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1886
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1887
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1888
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1889
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1890
** Generate code that will extract the iColumn-th column from
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1891
** table pTab and push that column value on the stack.  There
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1892
** is an open cursor to pTab in iTable.  If iColumn<0 then
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1893
** code is generated that extracts the rowid.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1894
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1895
void sqlite3ExprCodeGetColumn(Vdbe *v, Table *pTab, int iColumn, int iTable){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1896
  if( iColumn<0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1897
    int op = (pTab && IsVirtual(pTab)) ? OP_VRowid : OP_Rowid;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1898
    sqlite3VdbeAddOp(v, op, iTable, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1899
  }else if( pTab==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1900
    sqlite3VdbeAddOp(v, OP_Column, iTable, iColumn);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1901
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1902
    int op = IsVirtual(pTab) ? OP_VColumn : OP_Column;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1903
    sqlite3VdbeAddOp(v, op, iTable, iColumn);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1904
    sqlite3ColumnDefault(v, pTab, iColumn);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1905
#ifndef SQLITE_OMIT_FLOATING_POINT
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1906
    if( pTab->aCol[iColumn].affinity==SQLITE_AFF_REAL ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1907
      sqlite3VdbeAddOp(v, OP_RealAffinity, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1908
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1909
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1910
  }
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1913
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1914
** Generate code into the current Vdbe to evaluate the given
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1915
** expression and leave the result on the top of stack.
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
** This code depends on the fact that certain token values (ex: TK_EQ)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1918
** are the same as opcode values (ex: OP_Eq) that implement the corresponding
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1919
** operation.  Special comments in vdbe.c and the mkopcodeh.awk script in
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1920
** the make process cause these values to align.  Assert()s in the code
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1921
** below verify that the numbers are aligned correctly.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1922
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1923
void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1924
  Vdbe *v = pParse->pVdbe;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1925
  int op;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1926
  int stackChng = 1;    /* Amount of change to stack depth */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1927
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1928
  if( v==0 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1929
  if( pExpr==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1930
    sqlite3VdbeAddOp(v, OP_Null, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1931
    return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1932
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1933
  op = pExpr->op;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1934
  switch( op ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1935
    case TK_AGG_COLUMN: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1936
      AggInfo *pAggInfo = pExpr->pAggInfo;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1937
	  AggInfo::AggInfo_col *pCol = &pAggInfo->aCol[pExpr->iAgg];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1938
      if( !pAggInfo->directMode ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1939
        sqlite3VdbeAddOp(v, OP_MemLoad, pCol->iMem, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1940
        break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1941
      }else if( pAggInfo->useSortingIdx ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1942
        sqlite3VdbeAddOp(v, OP_Column, pAggInfo->sortingIdx,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1943
                              pCol->iSorterColumn);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1944
        break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1945
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1946
      /* Otherwise, fall thru into the TK_COLUMN case */
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
    case TK_COLUMN: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1949
      if( pExpr->iTable<0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1950
        /* This only happens when coding check constraints */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1951
        assert( pParse->ckOffset>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1952
        sqlite3VdbeAddOp(v, OP_Dup, pParse->ckOffset-pExpr->iColumn-1, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1953
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1954
        sqlite3ExprCodeGetColumn(v, pExpr->pTab, pExpr->iColumn, pExpr->iTable);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1955
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1956
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1957
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1958
    case TK_INTEGER: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1959
      codeInteger(v, (char*)pExpr->token.z, pExpr->token.n, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1960
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1961
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1962
    case TK_FLOAT: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1963
      codeReal(v, (char*)pExpr->token.z, pExpr->token.n, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1964
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1965
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1966
    case TK_STRING: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1967
      sqlite3DequoteExpr(pParse->db, pExpr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1968
      sqlite3VdbeOp3(v,OP_String8, 0, 0, (char*)pExpr->token.z, pExpr->token.n);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1969
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1970
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1971
    case TK_NULL: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1972
      sqlite3VdbeAddOp(v, OP_Null, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1973
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1974
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1975
#ifndef SQLITE_OMIT_BLOB_LITERAL
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1976
    case TK_BLOB: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1977
      int n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1978
      const char *z;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1979
      assert( TK_BLOB==OP_HexBlob );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1980
      n = pExpr->token.n - 3;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1981
      z = (char*)pExpr->token.z + 2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1982
      assert( n>=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1983
      if( n==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1984
        z = "";
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1985
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1986
      sqlite3VdbeOp3(v, op, 0, 0, z, n);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1987
      break;
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
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1990
    case TK_VARIABLE: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1991
      sqlite3VdbeAddOp(v, OP_Variable, pExpr->iTable, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1992
      if( pExpr->token.n>1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1993
        sqlite3VdbeChangeP3(v, -1, (char*)pExpr->token.z, pExpr->token.n);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1994
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1995
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1996
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1997
    case TK_REGISTER: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1998
      sqlite3VdbeAddOp(v, OP_MemLoad, pExpr->iTable, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1999
      break;
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
#ifndef SQLITE_OMIT_CAST
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2002
    case TK_CAST: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2003
      /* Expressions of the form:   CAST(pLeft AS token) */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2004
      int aff, to_op;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2005
      sqlite3ExprCode(pParse, pExpr->pLeft);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2006
      aff = sqlite3AffinityType(&pExpr->token);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2007
      to_op = aff - SQLITE_AFF_TEXT + OP_ToText;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2008
      assert( to_op==OP_ToText    || aff!=SQLITE_AFF_TEXT    );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2009
      assert( to_op==OP_ToBlob    || aff!=SQLITE_AFF_NONE    );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2010
      assert( to_op==OP_ToNumeric || aff!=SQLITE_AFF_NUMERIC );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2011
      assert( to_op==OP_ToInt     || aff!=SQLITE_AFF_INTEGER );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2012
      assert( to_op==OP_ToReal    || aff!=SQLITE_AFF_REAL    );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2013
      sqlite3VdbeAddOp(v, to_op, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2014
      stackChng = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2015
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2016
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2017
#endif /* SQLITE_OMIT_CAST */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2018
    case TK_LT:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2019
    case TK_LE:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2020
    case TK_GT:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2021
    case TK_GE:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2022
    case TK_NE:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2023
    case TK_EQ: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2024
      assert( TK_LT==OP_Lt );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2025
      assert( TK_LE==OP_Le );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2026
      assert( TK_GT==OP_Gt );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2027
      assert( TK_GE==OP_Ge );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2028
      assert( TK_EQ==OP_Eq );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2029
      assert( TK_NE==OP_Ne );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2030
      sqlite3ExprCode(pParse, pExpr->pLeft);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2031
      sqlite3ExprCode(pParse, pExpr->pRight);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2032
      codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2033
      stackChng = -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2034
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2035
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2036
    case TK_AND:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2037
    case TK_OR:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2038
    case TK_PLUS:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2039
    case TK_STAR:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2040
    case TK_MINUS:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2041
    case TK_REM:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2042
    case TK_BITAND:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2043
    case TK_BITOR:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2044
    case TK_SLASH:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2045
    case TK_LSHIFT:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2046
    case TK_RSHIFT: 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2047
    case TK_CONCAT: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2048
      assert( TK_AND==OP_And );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2049
      assert( TK_OR==OP_Or );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2050
      assert( TK_PLUS==OP_Add );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2051
      assert( TK_MINUS==OP_Subtract );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2052
      assert( TK_REM==OP_Remainder );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2053
      assert( TK_BITAND==OP_BitAnd );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2054
      assert( TK_BITOR==OP_BitOr );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2055
      assert( TK_SLASH==OP_Divide );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2056
      assert( TK_LSHIFT==OP_ShiftLeft );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2057
      assert( TK_RSHIFT==OP_ShiftRight );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2058
      assert( TK_CONCAT==OP_Concat );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2059
      sqlite3ExprCode(pParse, pExpr->pLeft);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2060
      sqlite3ExprCode(pParse, pExpr->pRight);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2061
      sqlite3VdbeAddOp(v, op, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2062
      stackChng = -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2063
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2064
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2065
    case TK_UMINUS: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2066
      Expr *pLeft = pExpr->pLeft;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2067
      assert( pLeft );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2068
      if( pLeft->op==TK_FLOAT || pLeft->op==TK_INTEGER ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2069
        Token *p = &pLeft->token;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2070
        if( pLeft->op==TK_FLOAT ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2071
          codeReal(v, (char*)p->z, p->n, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2072
        }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2073
          codeInteger(v, (char*)p->z, p->n, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2074
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2075
        break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2076
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2077
      /* Fall through into TK_NOT */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2078
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2079
    case TK_BITNOT:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2080
    case TK_NOT: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2081
      assert( TK_BITNOT==OP_BitNot );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2082
      assert( TK_NOT==OP_Not );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2083
      sqlite3ExprCode(pParse, pExpr->pLeft);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2084
      sqlite3VdbeAddOp(v, op, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2085
      stackChng = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2086
      break;
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
    case TK_ISNULL:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2089
    case TK_NOTNULL: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2090
      int dest;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2091
      assert( TK_ISNULL==OP_IsNull );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2092
      assert( TK_NOTNULL==OP_NotNull );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2093
      sqlite3VdbeAddOp(v, OP_Integer, 1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2094
      sqlite3ExprCode(pParse, pExpr->pLeft);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2095
      dest = sqlite3VdbeCurrentAddr(v) + 2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2096
      sqlite3VdbeAddOp(v, op, 1, dest);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2097
      sqlite3VdbeAddOp(v, OP_AddImm, -1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2098
      stackChng = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2099
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2100
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2101
    case TK_AGG_FUNCTION: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2102
      AggInfo *pInfo = pExpr->pAggInfo;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2103
      if( pInfo==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2104
        sqlite3ErrorMsg(pParse, "misuse of aggregate: %T",
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2105
            &pExpr->span);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2106
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2107
        sqlite3VdbeAddOp(v, OP_MemLoad, pInfo->aFunc[pExpr->iAgg].iMem, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2108
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2109
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2110
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2111
    case TK_CONST_FUNC:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2112
    case TK_FUNCTION: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2113
      ExprList *pList = pExpr->pList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2114
      int nExpr = pList ? pList->nExpr : 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2115
      FuncDef *pDef;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2116
      int nId;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2117
      const char *zId;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2118
      int constMask = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2119
      int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2120
      sqlite3 *db = pParse->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2121
      u8 enc = ENC(db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2122
      CollSeq *pColl = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2123
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2124
      zId = (char*)pExpr->token.z;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2125
      nId = pExpr->token.n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2126
      pDef = sqlite3FindFunction(pParse->db, zId, nId, nExpr, enc, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2127
      assert( pDef!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2128
      nExpr = sqlite3ExprCodeExprList(pParse, pList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2129
#ifndef SQLITE_OMIT_VIRTUALTABLE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2130
      /* Possibly overload the function if the first argument is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2131
      ** a virtual table column.
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
      ** For infix functions (LIKE, GLOB, REGEXP, and MATCH) use the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2134
      ** second argument, not the first, as the argument to test to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2135
      ** see if it is a column in a virtual table.  This is done because
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2136
      ** the left operand of infix functions (the operand we want to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2137
      ** control overloading) ends up as the second argument to the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2138
      ** function.  The expression "A glob B" is equivalent to 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2139
      ** "glob(B,A).  We want to use the A in "A glob B" to test
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2140
      ** for function overloading.  But we use the B term in "glob(B,A)".
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
      if( nExpr>=2 && (pExpr->flags & EP_InfixFunc) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2143
        pDef = sqlite3VtabOverloadFunction(db, pDef, nExpr, pList->a[1].pExpr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2144
      }else if( nExpr>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2145
        pDef = sqlite3VtabOverloadFunction(db, pDef, nExpr, pList->a[0].pExpr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2146
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2147
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2148
      for(i=0; i<nExpr && i<32; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2149
        if( sqlite3ExprIsConstant(pList->a[i].pExpr) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2150
          constMask |= (1<<i);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2151
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2152
        if( pDef->needCollSeq && !pColl ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2153
          pColl = sqlite3ExprCollSeq(pParse, pList->a[i].pExpr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2154
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2155
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2156
      if( pDef->needCollSeq ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2157
        if( !pColl ) pColl = pParse->db->pDfltColl; 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2158
        sqlite3VdbeOp3(v, OP_CollSeq, 0, 0, (char *)pColl, P3_COLLSEQ);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2159
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2160
      sqlite3VdbeOp3(v, OP_Function, constMask, nExpr, (char*)pDef, P3_FUNCDEF);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2161
      stackChng = 1-nExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2162
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2163
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2164
#ifndef SQLITE_OMIT_SUBQUERY
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2165
    case TK_EXISTS:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2166
    case TK_SELECT: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2167
      if( pExpr->iColumn==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2168
        sqlite3CodeSubselect(pParse, pExpr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2169
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2170
      sqlite3VdbeAddOp(v, OP_MemLoad, pExpr->iColumn, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2171
      VdbeComment((v, "# load subquery result"));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2172
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2173
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2174
    case TK_IN: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2175
      int addr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2176
      char affinity;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2177
      int ckOffset = pParse->ckOffset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2178
      int eType;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2179
      int iLabel = sqlite3VdbeMakeLabel(v);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2180
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2181
      eType = sqlite3FindInIndex(pParse, pExpr, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2182
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2183
      /* Figure out the affinity to use to create a key from the results
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2184
      ** of the expression. affinityStr stores a static string suitable for
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2185
      ** P3 of OP_MakeRecord.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2186
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2187
      affinity = comparisonAffinity(pExpr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2188
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2189
      sqlite3VdbeAddOp(v, OP_Integer, 1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2190
      pParse->ckOffset = (ckOffset ? (ckOffset+1) : 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2191
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2192
      /* Code the <expr> from "<expr> IN (...)". The temporary table
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2193
      ** pExpr->iTable contains the values that make up the (...) set.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2194
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2195
      sqlite3ExprCode(pParse, pExpr->pLeft);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2196
      addr = sqlite3VdbeCurrentAddr(v);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2197
      sqlite3VdbeAddOp(v, OP_NotNull, -1, addr+4);            /* addr + 0 */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2198
      sqlite3VdbeAddOp(v, OP_Pop, 2, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2199
      sqlite3VdbeAddOp(v, OP_Null, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2200
      sqlite3VdbeAddOp(v, OP_Goto, 0, iLabel);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2201
      if( eType==IN_INDEX_ROWID ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2202
        int iAddr = sqlite3VdbeCurrentAddr(v)+3;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2203
        sqlite3VdbeAddOp(v, OP_MustBeInt, 1, iAddr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2204
        sqlite3VdbeAddOp(v, OP_NotExists, pExpr->iTable, iAddr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2205
        sqlite3VdbeAddOp(v, OP_Goto, pExpr->iTable, iLabel);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2206
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2207
        sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &affinity, 1);   /* addr + 4 */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2208
        sqlite3VdbeAddOp(v, OP_Found, pExpr->iTable, iLabel);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2209
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2210
      sqlite3VdbeAddOp(v, OP_AddImm, -1, 0);                  /* addr + 6 */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2211
      sqlite3VdbeResolveLabel(v, iLabel);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2212
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2213
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2214
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2215
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2216
    case TK_BETWEEN: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2217
      Expr *pLeft = pExpr->pLeft;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2218
	  ExprList::ExprList_item *pLItem = pExpr->pList->a;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2219
      Expr *pRight = pLItem->pExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2220
      sqlite3ExprCode(pParse, pLeft);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2221
      sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2222
      sqlite3ExprCode(pParse, pRight);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2223
      codeCompare(pParse, pLeft, pRight, OP_Ge, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2224
      sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2225
      pLItem++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2226
      pRight = pLItem->pExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2227
      sqlite3ExprCode(pParse, pRight);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2228
      codeCompare(pParse, pLeft, pRight, OP_Le, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2229
      sqlite3VdbeAddOp(v, OP_And, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2230
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2231
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2232
    case TK_UPLUS: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2233
      sqlite3ExprCode(pParse, pExpr->pLeft);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2234
      stackChng = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2235
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2236
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2237
    case TK_CASE: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2238
      int expr_end_label;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2239
      int jumpInst;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2240
      int nExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2241
      int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2242
      ExprList *pEList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2243
	  ExprList::ExprList_item *aListelem;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2244
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2245
      assert(pExpr->pList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2246
      assert((pExpr->pList->nExpr % 2) == 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2247
      assert(pExpr->pList->nExpr > 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2248
      pEList = pExpr->pList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2249
      aListelem = pEList->a;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2250
      nExpr = pEList->nExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2251
      expr_end_label = sqlite3VdbeMakeLabel(v);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2252
      if( pExpr->pLeft ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2253
        sqlite3ExprCode(pParse, pExpr->pLeft);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2254
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2255
      for(i=0; i<nExpr; i=i+2){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2256
        sqlite3ExprCode(pParse, aListelem[i].pExpr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2257
        if( pExpr->pLeft ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2258
          sqlite3VdbeAddOp(v, OP_Dup, 1, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2259
          jumpInst = codeCompare(pParse, pExpr->pLeft, aListelem[i].pExpr,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2260
                                 OP_Ne, 0, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2261
          sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2262
        }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2263
          jumpInst = sqlite3VdbeAddOp(v, OP_IfNot, 1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2264
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2265
        sqlite3ExprCode(pParse, aListelem[i+1].pExpr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2266
        sqlite3VdbeAddOp(v, OP_Goto, 0, expr_end_label);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2267
        sqlite3VdbeJumpHere(v, jumpInst);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2268
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2269
      if( pExpr->pLeft ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2270
        sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2271
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2272
      if( pExpr->pRight ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2273
        sqlite3ExprCode(pParse, pExpr->pRight);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2274
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2275
        sqlite3VdbeAddOp(v, OP_Null, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2276
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2277
      sqlite3VdbeResolveLabel(v, expr_end_label);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2278
      break;
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
#ifndef SQLITE_OMIT_TRIGGER
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2281
    case TK_RAISE: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2282
      if( !pParse->trigStack ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2283
        sqlite3ErrorMsg(pParse,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2284
                       "RAISE() may only be used within a trigger-program");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2285
        return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2286
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2287
      if( pExpr->iColumn!=OE_Ignore ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2288
         assert( pExpr->iColumn==OE_Rollback ||
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2289
                 pExpr->iColumn == OE_Abort ||
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2290
                 pExpr->iColumn == OE_Fail );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2291
         sqlite3DequoteExpr(pParse->db, pExpr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2292
         sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, pExpr->iColumn,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2293
                        (char*)pExpr->token.z, pExpr->token.n);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2294
      } else {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2295
         assert( pExpr->iColumn == OE_Ignore );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2296
         sqlite3VdbeAddOp(v, OP_ContextPop, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2297
         sqlite3VdbeAddOp(v, OP_Goto, 0, pParse->trigStack->ignoreJump);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2298
         VdbeComment((v, "# raise(IGNORE)"));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2299
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2300
      stackChng = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2301
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2302
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2303
#endif
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2306
  if( pParse->ckOffset ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2307
    pParse->ckOffset += stackChng;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2308
    assert( pParse->ckOffset );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2309
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2310
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2311
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2312
#ifndef SQLITE_OMIT_TRIGGER
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
** Generate code that evalutes the given expression and leaves the result
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2315
** on the stack.  See also sqlite3ExprCode().
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
** This routine might also cache the result and modify the pExpr tree
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2318
** so that it will make use of the cached result on subsequent evaluations
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2319
** rather than evaluate the whole expression again.  Trivial expressions are
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2320
** not cached.  If the expression is cached, its result is stored in a 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2321
** memory location.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2322
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2323
void sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2324
  Vdbe *v = pParse->pVdbe;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2325
  VdbeOp *pOp;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2326
  int iMem;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2327
  int addr1, addr2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2328
  if( v==0 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2329
  addr1 = sqlite3VdbeCurrentAddr(v);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2330
  sqlite3ExprCode(pParse, pExpr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2331
  addr2 = sqlite3VdbeCurrentAddr(v);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2332
  if( addr2>addr1+1
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2333
   || ((pOp = sqlite3VdbeGetOp(v, addr1))!=0 && pOp->opcode==OP_Function) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2334
    iMem = pExpr->iTable = pParse->nMem++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2335
    sqlite3VdbeAddOp(v, OP_MemStore, iMem, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2336
    pExpr->op = TK_REGISTER;
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
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2339
#endif
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
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2342
** Generate code that pushes the value of every element of the given
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2343
** expression list onto the stack.
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
** Return the number of elements pushed onto the stack.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2346
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2347
int sqlite3ExprCodeExprList(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2348
  Parse *pParse,     /* Parsing context */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2349
  ExprList *pList    /* The expression list to be coded */
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
	ExprList::ExprList_item *pItem;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2352
  int i, n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2353
  if( pList==0 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2354
  n = pList->nExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2355
  for(pItem=pList->a, i=n; i>0; i--, pItem++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2356
    sqlite3ExprCode(pParse, pItem->pExpr);
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
  return n;
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2361
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2362
** Generate code for a boolean expression such that a jump is made
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2363
** to the label "dest" if the expression is true but execution
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2364
** continues straight thru if the expression is false.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2365
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2366
** If the expression evaluates to NULL (neither true nor false), then
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2367
** take the jump if the jumpIfNull flag is true.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2368
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2369
** This code depends on the fact that certain token values (ex: TK_EQ)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2370
** are the same as opcode values (ex: OP_Eq) that implement the corresponding
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2371
** operation.  Special comments in vdbe.c and the mkopcodeh.awk script in
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2372
** the make process cause these values to align.  Assert()s in the code
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2373
** below verify that the numbers are aligned correctly.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2374
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2375
void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2376
  Vdbe *v = pParse->pVdbe;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2377
  int op = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2378
  int ckOffset = pParse->ckOffset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2379
  if( v==0 || pExpr==0 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2380
  op = pExpr->op;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2381
  switch( op ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2382
    case TK_AND: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2383
      int d2 = sqlite3VdbeMakeLabel(v);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2384
      sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2, !jumpIfNull);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2385
      sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2386
      sqlite3VdbeResolveLabel(v, d2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2387
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2388
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2389
    case TK_OR: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2390
      sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2391
      sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2392
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2393
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2394
    case TK_NOT: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2395
      sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2396
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2397
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2398
    case TK_LT:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2399
    case TK_LE:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2400
    case TK_GT:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2401
    case TK_GE:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2402
    case TK_NE:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2403
    case TK_EQ: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2404
      assert( TK_LT==OP_Lt );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2405
      assert( TK_LE==OP_Le );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2406
      assert( TK_GT==OP_Gt );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2407
      assert( TK_GE==OP_Ge );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2408
      assert( TK_EQ==OP_Eq );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2409
      assert( TK_NE==OP_Ne );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2410
      sqlite3ExprCode(pParse, pExpr->pLeft);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2411
      sqlite3ExprCode(pParse, pExpr->pRight);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2412
      codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, dest, jumpIfNull);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2413
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2414
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2415
    case TK_ISNULL:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2416
    case TK_NOTNULL: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2417
      assert( TK_ISNULL==OP_IsNull );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2418
      assert( TK_NOTNULL==OP_NotNull );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2419
      sqlite3ExprCode(pParse, pExpr->pLeft);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2420
      sqlite3VdbeAddOp(v, op, 1, dest);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2421
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2422
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2423
    case TK_BETWEEN: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2424
      /* The expression "x BETWEEN y AND z" is implemented as:
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
      ** 1 IF (x < y) GOTO 3
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2427
      ** 2 IF (x <= z) GOTO <dest>
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2428
      ** 3 ...
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
      int addr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2431
      Expr *pLeft = pExpr->pLeft;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2432
      Expr *pRight = pExpr->pList->a[0].pExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2433
      sqlite3ExprCode(pParse, pLeft);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2434
      sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2435
      sqlite3ExprCode(pParse, pRight);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2436
      addr = codeCompare(pParse, pLeft, pRight, OP_Lt, 0, !jumpIfNull);
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
      pRight = pExpr->pList->a[1].pExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2439
      sqlite3ExprCode(pParse, pRight);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2440
      codeCompare(pParse, pLeft, pRight, OP_Le, dest, jumpIfNull);
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
      sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2443
      sqlite3VdbeJumpHere(v, addr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2444
      sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2445
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2446
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2447
    default: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2448
      sqlite3ExprCode(pParse, pExpr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2449
      sqlite3VdbeAddOp(v, OP_If, jumpIfNull, dest);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2450
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2451
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2452
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2453
  pParse->ckOffset = ckOffset;
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2456
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2457
** Generate code for a boolean expression such that a jump is made
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2458
** to the label "dest" if the expression is false but execution
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2459
** continues straight thru if the expression is true.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2460
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2461
** If the expression evaluates to NULL (neither true nor false) then
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2462
** jump if jumpIfNull is true or fall through if jumpIfNull is false.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2463
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2464
void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2465
  Vdbe *v = pParse->pVdbe;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2466
  int op = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2467
  int ckOffset = pParse->ckOffset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2468
  if( v==0 || pExpr==0 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2469
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2470
  /* The value of pExpr->op and op are related as follows:
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
  **       pExpr->op            op
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2473
  **       ---------          ----------
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2474
  **       TK_ISNULL          OP_NotNull
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2475
  **       TK_NOTNULL         OP_IsNull
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2476
  **       TK_NE              OP_Eq
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2477
  **       TK_EQ              OP_Ne
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2478
  **       TK_GT              OP_Le
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2479
  **       TK_LE              OP_Gt
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2480
  **       TK_GE              OP_Lt
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2481
  **       TK_LT              OP_Ge
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2482
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2483
  ** For other values of pExpr->op, op is undefined and unused.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2484
  ** The value of TK_ and OP_ constants are arranged such that we
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2485
  ** can compute the mapping above using the following expression.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2486
  ** Assert()s verify that the computation is correct.
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
  op = ((pExpr->op+(TK_ISNULL&1))^1)-(TK_ISNULL&1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2489
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2490
  /* Verify correct alignment of TK_ and OP_ constants
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2491
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2492
  assert( pExpr->op!=TK_ISNULL || op==OP_NotNull );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2493
  assert( pExpr->op!=TK_NOTNULL || op==OP_IsNull );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2494
  assert( pExpr->op!=TK_NE || op==OP_Eq );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2495
  assert( pExpr->op!=TK_EQ || op==OP_Ne );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2496
  assert( pExpr->op!=TK_LT || op==OP_Ge );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2497
  assert( pExpr->op!=TK_LE || op==OP_Gt );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2498
  assert( pExpr->op!=TK_GT || op==OP_Le );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2499
  assert( pExpr->op!=TK_GE || op==OP_Lt );
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
  switch( pExpr->op ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2502
    case TK_AND: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2503
      sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2504
      sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2505
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2506
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2507
    case TK_OR: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2508
      int d2 = sqlite3VdbeMakeLabel(v);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2509
      sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, !jumpIfNull);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2510
      sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2511
      sqlite3VdbeResolveLabel(v, d2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2512
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2513
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2514
    case TK_NOT: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2515
      sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2516
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2517
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2518
    case TK_LT:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2519
    case TK_LE:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2520
    case TK_GT:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2521
    case TK_GE:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2522
    case TK_NE:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2523
    case TK_EQ: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2524
      sqlite3ExprCode(pParse, pExpr->pLeft);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2525
      sqlite3ExprCode(pParse, pExpr->pRight);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2526
      codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, dest, jumpIfNull);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2527
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2528
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2529
    case TK_ISNULL:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2530
    case TK_NOTNULL: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2531
      sqlite3ExprCode(pParse, pExpr->pLeft);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2532
      sqlite3VdbeAddOp(v, op, 1, dest);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2533
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2534
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2535
    case TK_BETWEEN: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2536
      /* The expression is "x BETWEEN y AND z". It is implemented as:
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
      ** 1 IF (x >= y) GOTO 3
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2539
      ** 2 GOTO <dest>
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2540
      ** 3 IF (x > z) GOTO <dest>
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2541
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2542
      int addr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2543
      Expr *pLeft = pExpr->pLeft;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2544
      Expr *pRight = pExpr->pList->a[0].pExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2545
      sqlite3ExprCode(pParse, pLeft);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2546
      sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2547
      sqlite3ExprCode(pParse, pRight);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2548
      addr = sqlite3VdbeCurrentAddr(v);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2549
      codeCompare(pParse, pLeft, pRight, OP_Ge, addr+3, !jumpIfNull);
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
      sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2552
      sqlite3VdbeAddOp(v, OP_Goto, 0, dest);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2553
      pRight = pExpr->pList->a[1].pExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2554
      sqlite3ExprCode(pParse, pRight);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2555
      codeCompare(pParse, pLeft, pRight, OP_Gt, dest, jumpIfNull);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2556
      break;
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
    default: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2559
      sqlite3ExprCode(pParse, pExpr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2560
      sqlite3VdbeAddOp(v, OP_IfNot, jumpIfNull, dest);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2561
      break;
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
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2564
  pParse->ckOffset = ckOffset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2565
}
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
** Do a deep comparison of two expression trees.  Return TRUE (non-zero)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2569
** if they are identical and return FALSE if they differ in any way.
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
** Sometimes this routine will return FALSE even if the two expressions
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2572
** really are equivalent.  If we cannot prove that the expressions are
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2573
** identical, we return FALSE just to be safe.  So if this routine
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2574
** returns false, then you do not really know for certain if the two
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2575
** expressions are the same.  But if you get a TRUE return, then you
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2576
** can be sure the expressions are the same.  In the places where
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2577
** this routine is used, it does not hurt to get an extra FALSE - that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2578
** just might result in some slightly slower code.  But returning
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2579
** an incorrect TRUE could lead to a malfunction.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2580
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2581
int sqlite3ExprCompare(Expr *pA, Expr *pB){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2582
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2583
  if( pA==0||pB==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2584
    return pB==pA;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2585
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2586
  if( pA->op!=pB->op ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2587
  if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2588
  if( !sqlite3ExprCompare(pA->pLeft, pB->pLeft) ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2589
  if( !sqlite3ExprCompare(pA->pRight, pB->pRight) ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2590
  if( pA->pList ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2591
    if( pB->pList==0 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2592
    if( pA->pList->nExpr!=pB->pList->nExpr ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2593
    for(i=0; i<pA->pList->nExpr; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2594
      if( !sqlite3ExprCompare(pA->pList->a[i].pExpr, pB->pList->a[i].pExpr) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2595
        return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2596
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2597
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2598
  }else if( pB->pList ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2599
    return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2600
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2601
  if( pA->pSelect || pB->pSelect ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2602
  if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2603
  if( pA->op!=TK_COLUMN && pA->token.z ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2604
    if( pB->token.z==0 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2605
    if( pB->token.n!=pA->token.n ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2606
    if( sqlite3StrNICmp((char*)pA->token.z,(char*)pB->token.z,pB->token.n)!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2607
      return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2608
    }
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
  return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2611
}
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2614
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2615
** Add a new element to the pAggInfo->aCol[] array.  Return the index of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2616
** the new element.  Return a negative number if malloc fails.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2617
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2618
static int addAggInfoColumn(sqlite3 *db, AggInfo *pInfo){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2619
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2620
  pInfo->aCol = (AggInfo::AggInfo_col*)sqlite3ArrayAllocate(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2621
       db,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2622
       pInfo->aCol,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2623
       sizeof(pInfo->aCol[0]),
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2624
       3,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2625
       &pInfo->nColumn,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2626
       &pInfo->nColumnAlloc,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2627
       &i
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2628
  );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2629
  return i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2630
}    
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2631
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2632
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2633
** Add a new element to the pAggInfo->aFunc[] array.  Return the index of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2634
** the new element.  Return a negative number if malloc fails.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2635
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2636
static int addAggInfoFunc(sqlite3 *db, AggInfo *pInfo){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2637
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2638
  pInfo->aFunc = (AggInfo::AggInfo_func*)sqlite3ArrayAllocate(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2639
       db, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2640
       pInfo->aFunc,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2641
       sizeof(pInfo->aFunc[0]),
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2642
       3,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2643
       &pInfo->nFunc,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2644
       &pInfo->nFuncAlloc,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2645
       &i
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2646
  );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2647
  return i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2648
}    
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2649
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2650
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2651
** This is an xFunc for walkExprTree() used to implement 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2652
** sqlite3ExprAnalyzeAggregates().  See sqlite3ExprAnalyzeAggregates
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2653
** for additional information.
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
** This routine analyzes the aggregate function at pExpr.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2656
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2657
static int analyzeAggregate(void *pArg, Expr *pExpr){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2658
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2659
  NameContext *pNC = (NameContext *)pArg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2660
  Parse *pParse = pNC->pParse;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2661
  SrcList *pSrcList = pNC->pSrcList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2662
  AggInfo *pAggInfo = pNC->pAggInfo;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2663
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2664
  switch( pExpr->op ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2665
    case TK_AGG_COLUMN:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2666
    case TK_COLUMN: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2667
      /* Check to see if the column is in one of the tables in the FROM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2668
      ** clause of the aggregate query */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2669
      if( pSrcList ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2670
		  SrcList::SrcList_item *pItem = pSrcList->a;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2671
        for(i=0; i<pSrcList->nSrc; i++, pItem++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2672
			AggInfo::AggInfo_col *pCol;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2673
          if( pExpr->iTable==pItem->iCursor ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2674
            /* If we reach this point, it means that pExpr refers to a table
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2675
            ** that is in the FROM clause of the aggregate query.  
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
            ** Make an entry for the column in pAggInfo->aCol[] if there
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2678
            ** is not an entry there already.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2679
            */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2680
			  int k=0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2681
            pCol = pAggInfo->aCol;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2682
            for(k=0; k<pAggInfo->nColumn; k++, pCol++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2683
              if( pCol->iTable==pExpr->iTable &&
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2684
                  pCol->iColumn==pExpr->iColumn ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2685
                break;
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
            }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2688
            if( (k>=pAggInfo->nColumn)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2689
             && (k = addAggInfoColumn(pParse->db, pAggInfo))>=0 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2690
            ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2691
              pCol = &pAggInfo->aCol[k];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2692
              pCol->pTab = pExpr->pTab;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2693
              pCol->iTable = pExpr->iTable;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2694
              pCol->iColumn = pExpr->iColumn;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2695
              pCol->iMem = pParse->nMem++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2696
              pCol->iSorterColumn = -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2697
              pCol->pExpr = pExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2698
              if( pAggInfo->pGroupBy ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2699
                int j, n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2700
                ExprList *pGB = pAggInfo->pGroupBy;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2701
				ExprList::ExprList_item *pTerm = pGB->a;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2702
                n = pGB->nExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2703
                for(j=0; j<n; j++, pTerm++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2704
                  Expr *pE = pTerm->pExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2705
                  if( pE->op==TK_COLUMN && pE->iTable==pExpr->iTable &&
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2706
                      pE->iColumn==pExpr->iColumn ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2707
                    pCol->iSorterColumn = j;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2708
                    break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2709
                  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2710
                }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2711
              }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2712
              if( pCol->iSorterColumn<0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2713
                pCol->iSorterColumn = pAggInfo->nSortingColumn++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2714
              }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2715
            }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2716
            /* There is now an entry for pExpr in pAggInfo->aCol[] (either
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2717
            ** because it was there before or because we just created it).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2718
            ** Convert the pExpr to be a TK_AGG_COLUMN referring to that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2719
            ** pAggInfo->aCol[] entry.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2720
            */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2721
            pExpr->pAggInfo = pAggInfo;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2722
            pExpr->op = TK_AGG_COLUMN;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2723
            pExpr->iAgg = k;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2724
            break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2725
          } /* endif pExpr->iTable==pItem->iCursor */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2726
        } /* end loop over pSrcList */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2727
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2728
      return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2729
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2730
    case TK_AGG_FUNCTION: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2731
      /* The pNC->nDepth==0 test causes aggregate functions in subqueries
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2732
      ** to be ignored */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2733
      if( pNC->nDepth==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2734
        /* Check to see if pExpr is a duplicate of another aggregate 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2735
        ** function that is already in the pAggInfo structure
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2736
        */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2737
		  AggInfo::AggInfo_func *pItem = pAggInfo->aFunc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2738
        for(i=0; i<pAggInfo->nFunc; i++, pItem++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2739
          if( sqlite3ExprCompare(pItem->pExpr, pExpr) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2740
            break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2741
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2742
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2743
        if( i>=pAggInfo->nFunc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2744
          /* pExpr is original.  Make a new entry in pAggInfo->aFunc[]
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2745
          */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2746
          u8 enc = ENC(pParse->db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2747
          i = addAggInfoFunc(pParse->db, pAggInfo);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2748
          if( i>=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2749
            pItem = &pAggInfo->aFunc[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2750
            pItem->pExpr = pExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2751
            pItem->iMem = pParse->nMem++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2752
            pItem->pFunc = sqlite3FindFunction(pParse->db,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2753
                   (char*)pExpr->token.z, pExpr->token.n,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2754
                   pExpr->pList ? pExpr->pList->nExpr : 0, enc, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2755
            if( pExpr->flags & EP_Distinct ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2756
              pItem->iDistinct = pParse->nTab++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2757
            }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2758
              pItem->iDistinct = -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2759
            }
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
        /* Make pExpr point to the appropriate pAggInfo->aFunc[] entry
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2763
        */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2764
        pExpr->iAgg = i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2765
        pExpr->pAggInfo = pAggInfo;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2766
        return 1;
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
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2770
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2771
  /* Recursively walk subqueries looking for TK_COLUMN nodes that need
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2772
  ** to be changed to TK_AGG_COLUMN.  But increment nDepth so that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2773
  ** TK_AGG_FUNCTION nodes in subqueries will be unchanged.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2774
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2775
  if( pExpr->pSelect ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2776
    pNC->nDepth++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2777
    walkSelectExpr(pExpr->pSelect, analyzeAggregate, pNC);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2778
    pNC->nDepth--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2779
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2780
  return 0;
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2783
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2784
** Analyze the given expression looking for aggregate functions and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2785
** for variables that need to be added to the pParse->aAgg[] array.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2786
** Make additional entries to the pParse->aAgg[] array as necessary.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2787
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2788
** This routine should only be called after the expression has been
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2789
** analyzed by sqlite3ExprResolveNames().
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2790
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2791
** If errors are seen, leave an error message in zErrMsg and return
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2792
** the number of errors.
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
int sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2795
  int nErr = pNC->pParse->nErr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2796
  walkExprTree(pExpr, analyzeAggregate, pNC);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2797
  return pNC->pParse->nErr - nErr;
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2800
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2801
** Call sqlite3ExprAnalyzeAggregates() for every expression in an
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2802
** expression list.  Return the number of errors.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2803
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2804
** If an error is found, the analysis is cut short.
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
int sqlite3ExprAnalyzeAggList(NameContext *pNC, ExprList *pList){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2807
	ExprList::ExprList_item *pItem;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2808
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2809
  int nErr = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2810
  if( pList ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2811
    for(pItem=pList->a, i=0; nErr==0 && i<pList->nExpr; i++, pItem++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2812
      nErr += sqlite3ExprAnalyzeAggregates(pNC, pItem->pExpr);
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
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2815
  return nErr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2816
}