/ Check-in [1d3fc977]
Login

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

Overview
Comment:Add the sqliteErrorMsg() function and use it to generate error message text during parsing and code generation. This simplifies the code somewhat and makes it easier to handle names with a database prefix. (CVS 891)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 1d3fc977211abdc7ba3fd51d661863e8ce5aef69
User & Date: drh 2003-03-31 02:12:47
Context
2003-03-31
13:36
Minor follow-on changes to the recent ATTACH patch. (CVS 892) check-in: e80afe75 user: drh tags: trunk
02:12
Add the sqliteErrorMsg() function and use it to generate error message text during parsing and code generation. This simplifies the code somewhat and makes it easier to handle names with a database prefix. (CVS 891) check-in: 1d3fc977 user: drh tags: trunk
00:30
The ATTACH and DETACH statements are now coded but are still mostly untested. (CVS 890) check-in: c7c5e927 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/build.c.

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
....
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
....
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
....
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
....
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
....
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
....
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
**     COPY
**     VACUUM
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**     PRAGMA
**
** $Id: build.c,v 1.137 2003/03/31 00:30:48 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Check to see if the schema for the database needs
................................................................................
  Vdbe *v;
  sqlite *db = pParse->db;

  if( pParse->nErr || sqlite_malloc_failed ) return;
  assert( pName->nSrc==1 );
  pIndex = sqliteFindIndex(db, pName->a[0].zName, pName->a[0].zDatabase);
  if( pIndex==0 ){
    sqliteSetString(&pParse->zErrMsg, "no such index: ", pName->a[0].zName, 0);
    pParse->nErr++;
    goto exit_drop_index;
  }
  if( pIndex->autoIndex ){
    sqliteSetString(&pParse->zErrMsg, "index associated with UNIQUE "
      "or PRIMARY KEY constraint cannot be dropped", 0);
    pParse->nErr++;
    goto exit_drop_index;
  }
  if( pIndex->iDb>1 ){
    sqliteSetString(&pParse->zErrMsg, "cannot alter schema of attached "
       "databases", 0);
    pParse->nErr++;
    goto exit_drop_index;
  }
#ifndef SQLITE_OMIT_AUTHORIZATION
  {
    int code = SQLITE_DROP_INDEX;
    Table *pTab = pIndex->pTable;
    if( sqliteAuthCheck(pParse, SQLITE_DELETE, SCHEMA_TABLE(pIndex->iDb), 0) ){
................................................................................
void sqliteBeginTransaction(Parse *pParse, int onError){
  sqlite *db;

  if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
  if( pParse->nErr || sqlite_malloc_failed ) return;
  if( sqliteAuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0) ) return;
  if( db->flags & SQLITE_InTrans ){
    pParse->nErr++;
    sqliteSetString(&pParse->zErrMsg, "cannot start a transaction "
       "within a transaction", 0);
    return;
  }
  sqliteBeginWriteOperation(pParse, 0, 0);
  db->flags |= SQLITE_InTrans;
  db->onError = onError;
}

................................................................................
void sqliteCommitTransaction(Parse *pParse){
  sqlite *db;

  if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
  if( pParse->nErr || sqlite_malloc_failed ) return;
  if( sqliteAuthCheck(pParse, SQLITE_TRANSACTION, "COMMIT", 0) ) return;
  if( (db->flags & SQLITE_InTrans)==0 ){
    pParse->nErr++;
    sqliteSetString(&pParse->zErrMsg, 
       "cannot commit - no transaction is active", 0);
    return;
  }
  db->flags &= ~SQLITE_InTrans;
  sqliteEndWriteOperation(pParse);
  db->onError = OE_Default;
}

................................................................................
  sqlite *db;
  Vdbe *v;

  if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
  if( pParse->nErr || sqlite_malloc_failed ) return;
  if( sqliteAuthCheck(pParse, SQLITE_TRANSACTION, "ROLLBACK", 0) ) return;
  if( (db->flags & SQLITE_InTrans)==0 ){
    pParse->nErr++;
    sqliteSetString(&pParse->zErrMsg,
       "cannot rollback - no transaction is active", 0);
    return; 
  }
  v = sqliteGetVdbe(pParse);
  if( v ){
    sqliteVdbeAddOp(v, OP_Rollback, 0, 0);
  }
  db->flags &= ~SQLITE_InTrans;
................................................................................
  
  zName = 0;
  sqliteSetNString(&zName, pDbname->z, pDbname->n, 0);
  if( zName==0 ) return;
  sqliteDequote(zName);
  for(i=0; i<db->nDb; i++){
    if( db->aDb[i].zName && sqliteStrICmp(db->aDb[i].zName, zName)==0 ){
      sqliteSetString(&pParse->zErrMsg, "database \"", zName, 
         "\" already in use", 0);
      sqliteFree(zName);
      pParse->nErr++;
      return;
    }
  }
  aNew->zName = zName;
  zFile = 0;
  sqliteSetNString(&zFile, pFilename->z, pFilename->n, 0);
  if( zFile==0 ) return;
  sqliteDequote(zFile);
  rc = sqliteBtreeOpen(zFile, 0, MAX_PAGES, &aNew->pBt);
  if( rc ){
    sqliteSetString(&pParse->zErrMsg, "unable to open database: ", zFile, 0);
    pParse->nErr++;
  }
  sqliteFree(zFile);
  db->flags &= ~SQLITE_Initialized;
  if( pParse->nErr ) return;
  rc = sqliteInit(pParse->db, &pParse->zErrMsg);
  if( rc ){
    pParse->nErr++;
................................................................................
  db = pParse->db;
  for(i=0; i<db->nDb; i++){
    if( db->aDb[i].pBt==0 || db->aDb[i].zName==0 ) continue;
    if( strlen(db->aDb[i].zName)!=pDbname->n ) continue;
    if( sqliteStrNICmp(db->aDb[i].zName, pDbname->z, pDbname->n)==0 ) break;
  }
  if( i>=db->nDb ){
    sqliteSetNString(&pParse->zErrMsg, "no such database: ", -1,
        pDbname->z, pDbname->n, 0);
    pParse->nErr++;
    return;
  }
  if( i<2 ){
    sqliteSetString(&pParse->zErrMsg, "cannot detached \"main\" or \"temp\"",0);
    pParse->nErr++;
    return;
  }
  sqliteBtreeClose(db->aDb[i].pBt);
  db->aDb[i].pBt = 0;
  sqliteResetInternalSchema(db, 0);
}







|







 







|
<



|

<



|

<







 







<
|
<







 







<
<
|







 







<
<
|







 







<
|
<
<










|
<







 







|
<
<



|
<






21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
....
1746
1747
1748
1749
1750
1751
1752
1753

1754
1755
1756
1757
1758

1759
1760
1761
1762
1763

1764
1765
1766
1767
1768
1769
1770
....
2101
2102
2103
2104
2105
2106
2107

2108

2109
2110
2111
2112
2113
2114
2115
....
2119
2120
2121
2122
2123
2124
2125


2126
2127
2128
2129
2130
2131
2132
2133
....
2138
2139
2140
2141
2142
2143
2144


2145
2146
2147
2148
2149
2150
2151
2152
....
2688
2689
2690
2691
2692
2693
2694

2695


2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706

2707
2708
2709
2710
2711
2712
2713
....
2729
2730
2731
2732
2733
2734
2735
2736


2737
2738
2739
2740

2741
2742
2743
2744
2745
2746
**     COPY
**     VACUUM
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**     PRAGMA
**
** $Id: build.c,v 1.138 2003/03/31 02:12:47 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Check to see if the schema for the database needs
................................................................................
  Vdbe *v;
  sqlite *db = pParse->db;

  if( pParse->nErr || sqlite_malloc_failed ) return;
  assert( pName->nSrc==1 );
  pIndex = sqliteFindIndex(db, pName->a[0].zName, pName->a[0].zDatabase);
  if( pIndex==0 ){
    sqliteErrorMsg(pParse, "no such index: %S", pName, 0);

    goto exit_drop_index;
  }
  if( pIndex->autoIndex ){
    sqliteErrorMsg(pParse, "index associated with UNIQUE "
      "or PRIMARY KEY constraint cannot be dropped", 0);

    goto exit_drop_index;
  }
  if( pIndex->iDb>1 ){
    sqliteErrorMsg(pParse, "cannot alter schema of attached "
       "databases", 0);

    goto exit_drop_index;
  }
#ifndef SQLITE_OMIT_AUTHORIZATION
  {
    int code = SQLITE_DROP_INDEX;
    Table *pTab = pIndex->pTable;
    if( sqliteAuthCheck(pParse, SQLITE_DELETE, SCHEMA_TABLE(pIndex->iDb), 0) ){
................................................................................
void sqliteBeginTransaction(Parse *pParse, int onError){
  sqlite *db;

  if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
  if( pParse->nErr || sqlite_malloc_failed ) return;
  if( sqliteAuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0) ) return;
  if( db->flags & SQLITE_InTrans ){

    sqliteErrorMsg(pParse, "cannot start a transaction within a transaction");

    return;
  }
  sqliteBeginWriteOperation(pParse, 0, 0);
  db->flags |= SQLITE_InTrans;
  db->onError = onError;
}

................................................................................
void sqliteCommitTransaction(Parse *pParse){
  sqlite *db;

  if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
  if( pParse->nErr || sqlite_malloc_failed ) return;
  if( sqliteAuthCheck(pParse, SQLITE_TRANSACTION, "COMMIT", 0) ) return;
  if( (db->flags & SQLITE_InTrans)==0 ){


    sqliteErrorMsg(pParse, "cannot commit - no transaction is active");
    return;
  }
  db->flags &= ~SQLITE_InTrans;
  sqliteEndWriteOperation(pParse);
  db->onError = OE_Default;
}

................................................................................
  sqlite *db;
  Vdbe *v;

  if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
  if( pParse->nErr || sqlite_malloc_failed ) return;
  if( sqliteAuthCheck(pParse, SQLITE_TRANSACTION, "ROLLBACK", 0) ) return;
  if( (db->flags & SQLITE_InTrans)==0 ){


    sqliteErrorMsg(pParse, "cannot rollback - no transaction is active");
    return; 
  }
  v = sqliteGetVdbe(pParse);
  if( v ){
    sqliteVdbeAddOp(v, OP_Rollback, 0, 0);
  }
  db->flags &= ~SQLITE_InTrans;
................................................................................
  
  zName = 0;
  sqliteSetNString(&zName, pDbname->z, pDbname->n, 0);
  if( zName==0 ) return;
  sqliteDequote(zName);
  for(i=0; i<db->nDb; i++){
    if( db->aDb[i].zName && sqliteStrICmp(db->aDb[i].zName, zName)==0 ){

      sqliteErrorMsg(pParse, "database %z is already in use", zName);


      return;
    }
  }
  aNew->zName = zName;
  zFile = 0;
  sqliteSetNString(&zFile, pFilename->z, pFilename->n, 0);
  if( zFile==0 ) return;
  sqliteDequote(zFile);
  rc = sqliteBtreeOpen(zFile, 0, MAX_PAGES, &aNew->pBt);
  if( rc ){
    sqliteErrorMsg(pParse, "unable to open database: %s", zFile);

  }
  sqliteFree(zFile);
  db->flags &= ~SQLITE_Initialized;
  if( pParse->nErr ) return;
  rc = sqliteInit(pParse->db, &pParse->zErrMsg);
  if( rc ){
    pParse->nErr++;
................................................................................
  db = pParse->db;
  for(i=0; i<db->nDb; i++){
    if( db->aDb[i].pBt==0 || db->aDb[i].zName==0 ) continue;
    if( strlen(db->aDb[i].zName)!=pDbname->n ) continue;
    if( sqliteStrNICmp(db->aDb[i].zName, pDbname->z, pDbname->n)==0 ) break;
  }
  if( i>=db->nDb ){
    sqliteErrorMsg(pParse, "no such database: %T", pDbname);


    return;
  }
  if( i<2 ){
    sqliteErrorMsg(pParse, "cannot detached database %T", pDbname);

    return;
  }
  sqliteBtreeClose(db->aDb[i].pBt);
  db->aDb[i].pBt = 0;
  sqliteResetInternalSchema(db, 0);
}

Changes to src/delete.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
..
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle DELETE FROM statements.
**
** $Id: delete.c,v 1.49 2003/03/27 13:50:00 drh Exp $
*/
#include "sqliteInt.h"

/*
** Look up every table that is named in pSrc.  If any table is not found,
** add an error message to pParse->zErrMsg and return NULL.  If all tables
** are found, return a pointer to the last table.
................................................................................
  Table *pTab = 0;
  int i;
  for(i=0; i<pSrc->nSrc; i++){
    const char *zTab = pSrc->a[i].zName;
    const char *zDb = pSrc->a[i].zDatabase;
    pTab = sqliteFindTable(pParse->db, zTab, zDb);
    if( pTab==0 ){
      if( zDb==0 || zDb[0]==0 ){
        sqliteSetString(&pParse->zErrMsg, "no such table: ", zTab, 0);
      }else{
        sqliteSetString(&pParse->zErrMsg, "no such table: ", zDb, ".", zTab, 0);
      }
      pParse->nErr++;
      break;
    }
    pSrc->a[i].pTab = pTab;
  }
  return pTab;
}

................................................................................
/*
** Check to make sure the given table is writable.  If it is not
** writable, generate an error message and return 1.  If it is
** writable return 0;
*/
int sqliteIsReadOnly(Parse *pParse, Table *pTab){
  if( pTab->readOnly || pTab->pSelect ){
    sqliteSetString(&pParse->zErrMsg, 
      pTab->pSelect ? "view " : "table ", pTab->zName,
      " may not be modified", 0);
    pParse->nErr++;
    return 1;
  }
  return 0;
}

/*
** Process a DELETE FROM statement.







|







 







|
<
<
<
<
<







 







|
|
|
<







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
25
26
27
28
29
30
31
32





33
34
35
36
37
38
39
..
40
41
42
43
44
45
46
47
48
49

50
51
52
53
54
55
56
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle DELETE FROM statements.
**
** $Id: delete.c,v 1.50 2003/03/31 02:12:47 drh Exp $
*/
#include "sqliteInt.h"

/*
** Look up every table that is named in pSrc.  If any table is not found,
** add an error message to pParse->zErrMsg and return NULL.  If all tables
** are found, return a pointer to the last table.
................................................................................
  Table *pTab = 0;
  int i;
  for(i=0; i<pSrc->nSrc; i++){
    const char *zTab = pSrc->a[i].zName;
    const char *zDb = pSrc->a[i].zDatabase;
    pTab = sqliteFindTable(pParse->db, zTab, zDb);
    if( pTab==0 ){
      sqliteErrorMsg(pParse, "no such table: %S", pSrc, 0);





      break;
    }
    pSrc->a[i].pTab = pTab;
  }
  return pTab;
}

................................................................................
/*
** Check to make sure the given table is writable.  If it is not
** writable, generate an error message and return 1.  If it is
** writable return 0;
*/
int sqliteIsReadOnly(Parse *pParse, Table *pTab){
  if( pTab->readOnly || pTab->pSelect ){
    sqliteErrorMsg(pParse, "%s %s may not be modified",
      pTab->pSelect ? "view" : "table",
      pTab->zName);

    return 1;
  }
  return 0;
}

/*
** Process a DELETE FROM statement.

Changes to src/expr.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
...
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
...
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
....
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
** $Id: expr.c,v 1.90 2003/03/27 12:51:25 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Construct a new expression node and return a pointer to it.  Memory
** for this node is obtained from sqliteMalloc().  The calling function
................................................................................
        pExpr->iTable = base;
        cnt = 1 + (pTabList->nSrc>1);
        pExpr->op = TK_COLUMN;
        pExpr->dataType = SQLITE_SO_NUM;
      }
      sqliteFree(z);
      if( cnt==0 && pExpr->token.z[0]!='"' ){
        sqliteSetNString(&pParse->zErrMsg, "no such column: ", -1,  
          pExpr->token.z, pExpr->token.n, 0);
        pParse->nErr++;
        return 1;
      }else if( cnt>1 ){
        sqliteSetNString(&pParse->zErrMsg, "ambiguous column name: ", -1,  
          pExpr->token.z, pExpr->token.n, 0);
        pParse->nErr++;
        return 1;
      }
      if( pExpr->op==TK_COLUMN ){
        sqliteAuthRead(pParse, pExpr, pTabList, base);
      }
      break; 
    }
................................................................................
        pExpr->iColumn = -1;
        pExpr->dataType = SQLITE_SO_NUM;
      }
      sqliteFree(zDb);
      sqliteFree(zLeft);
      sqliteFree(zRight);
      if( cnt==0 ){
        sqliteSetNString(&pParse->zErrMsg, "no such column: ", -1,  
          pLeft->token.z, pLeft->token.n, ".", 1, 
          pRight->token.z, pRight->token.n, 0);
        pParse->nErr++;
        return 1;
      }else if( cnt>1 ){
        sqliteSetNString(&pParse->zErrMsg, "ambiguous column name: ", -1,  
          pLeft->token.z, pLeft->token.n, ".", 1,
          pRight->token.z, pRight->token.n, 0);
        pParse->nErr++;
        return 1;
      }
      sqliteExprDelete(pExpr->pLeft);
      pExpr->pLeft = 0;
      sqliteExprDelete(pExpr->pRight);
      pExpr->pRight = 0;
      pExpr->op = TK_COLUMN;
................................................................................
        ** Create a set to put the exprlist values in.  The Set id is stored
        ** in iTable.
        */
        int i, iSet;
        for(i=0; i<pExpr->pList->nExpr; i++){
          Expr *pE2 = pExpr->pList->a[i].pExpr;
          if( !sqliteExprIsConstant(pE2) ){
            sqliteSetString(&pParse->zErrMsg,
              "right-hand side of IN operator must be constant", 0);
            pParse->nErr++;
            return 1;
          }
          if( sqliteExprCheck(pParse, pE2, 0, 0) ){
            return 1;
          }
        }
        iSet = pExpr->iTable = pParse->nSet++;
................................................................................
        sqliteVdbeAddOp(v, OP_String, 0, 0);
      }
      sqliteVdbeResolveLabel(v, expr_end_label);
      break;
    }
    case TK_RAISE: {
      if( !pParse->trigStack ){
        sqliteSetNString(&pParse->zErrMsg, 
		"RAISE() may only be used within a trigger-program", -1, 0);
        pParse->nErr++;
	return;
      }
      if( pExpr->iColumn == OE_Rollback ||
	  pExpr->iColumn == OE_Abort ||
	  pExpr->iColumn == OE_Fail ){
	  char * msg = sqliteStrNDup(pExpr->token.z, pExpr->token.n);







|







 







|
<
<


|
<
<







 







|
<
|
<


|
<
|
<







 







|
|
<







 







|
|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
473
474
475
476
477
478
479
480


481
482
483


484
485
486
487
488
489
490
...
592
593
594
595
596
597
598
599

600

601
602
603

604

605
606
607
608
609
610
611
...
635
636
637
638
639
640
641
642
643

644
645
646
647
648
649
650
....
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
** $Id: expr.c,v 1.91 2003/03/31 02:12:47 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Construct a new expression node and return a pointer to it.  Memory
** for this node is obtained from sqliteMalloc().  The calling function
................................................................................
        pExpr->iTable = base;
        cnt = 1 + (pTabList->nSrc>1);
        pExpr->op = TK_COLUMN;
        pExpr->dataType = SQLITE_SO_NUM;
      }
      sqliteFree(z);
      if( cnt==0 && pExpr->token.z[0]!='"' ){
        sqliteErrorMsg(pParse, "no such column: %T", &pExpr->token);


        return 1;
      }else if( cnt>1 ){
        sqliteErrorMsg(pParse, "ambiguous column name: %T", &pExpr->token);


        return 1;
      }
      if( pExpr->op==TK_COLUMN ){
        sqliteAuthRead(pParse, pExpr, pTabList, base);
      }
      break; 
    }
................................................................................
        pExpr->iColumn = -1;
        pExpr->dataType = SQLITE_SO_NUM;
      }
      sqliteFree(zDb);
      sqliteFree(zLeft);
      sqliteFree(zRight);
      if( cnt==0 ){
        sqliteErrorMsg(pParse, "no such column: %T.%T",

               &pLeft->token, &pRight->token);

        return 1;
      }else if( cnt>1 ){
        sqliteErrorMsg(pParse, "ambiguous column name: %T.%T",

          &pLeft->token, &pRight->token);

        return 1;
      }
      sqliteExprDelete(pExpr->pLeft);
      pExpr->pLeft = 0;
      sqliteExprDelete(pExpr->pRight);
      pExpr->pRight = 0;
      pExpr->op = TK_COLUMN;
................................................................................
        ** Create a set to put the exprlist values in.  The Set id is stored
        ** in iTable.
        */
        int i, iSet;
        for(i=0; i<pExpr->pList->nExpr; i++){
          Expr *pE2 = pExpr->pList->a[i].pExpr;
          if( !sqliteExprIsConstant(pE2) ){
            sqliteErrorMsg(pParse,
              "right-hand side of IN operator must be constant");

            return 1;
          }
          if( sqliteExprCheck(pParse, pE2, 0, 0) ){
            return 1;
          }
        }
        iSet = pExpr->iTable = pParse->nSet++;
................................................................................
        sqliteVdbeAddOp(v, OP_String, 0, 0);
      }
      sqliteVdbeResolveLabel(v, expr_end_label);
      break;
    }
    case TK_RAISE: {
      if( !pParse->trigStack ){
        sqliteErrorMsg(pParse,
                       "RAISE() may only be used within a trigger-program");
        pParse->nErr++;
	return;
      }
      if( pExpr->iColumn == OE_Rollback ||
	  pExpr->iColumn == OE_Abort ||
	  pExpr->iColumn == OE_Fail ){
	  char * msg = sqliteStrNDup(pExpr->token.z, pExpr->token.n);

Changes to src/insert.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
...
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255

256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
...
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle INSERT statements in SQLite.
**
** $Id: insert.c,v 1.76 2003/03/27 13:50:00 drh Exp $
*/
#include "sqliteInt.h"

/*
** This routine is call to handle SQL of the following forms:
**
**    insert into TABLE (IDLIST) values(EXPRLIST)
................................................................................
  *  (b) that if it is a view then ON INSERT triggers exist
  */
  row_triggers_exist = 
    sqliteTriggersExist(pParse, pTab->pTrigger, TK_INSERT, 
        TK_BEFORE, TK_ROW, 0) ||
    sqliteTriggersExist(pParse, pTab->pTrigger, TK_INSERT, TK_AFTER, TK_ROW, 0);
  if( pTab->readOnly || (pTab->pSelect && !row_triggers_exist) ){
    sqliteSetString(&pParse->zErrMsg, 
      pTab->pSelect ? "view " : "table ",
      zTab,
      " may not be modified", 0);
    pParse->nErr++;
    goto insert_cleanup;
  }

  if( pTab==0 ) goto insert_cleanup;

  /* If pTab is really a view, make sure it has been initialized.
  */
................................................................................
    }
  }

  /* Make sure the number of columns in the source data matches the number
  ** of columns to be inserted into the table.
  */
  if( pColumn==0 && nColumn!=pTab->nCol ){
    char zNum1[30];
    char zNum2[30];
    sprintf(zNum1,"%d", nColumn);
    sprintf(zNum2,"%d", pTab->nCol);
    sqliteSetString(&pParse->zErrMsg, "table ", pTab->zName,
       " has ", zNum2, " columns but ",
       zNum1, " values were supplied", 0);
    pParse->nErr++;

    goto insert_cleanup;
  }
  if( pColumn!=0 && nColumn!=pColumn->nId ){
    char zNum1[30];
    char zNum2[30];
    sprintf(zNum1,"%d", nColumn);
    sprintf(zNum2,"%d", pColumn->nId);
    sqliteSetString(&pParse->zErrMsg, zNum1, " values for ",
       zNum2, " columns", 0);
    pParse->nErr++;
    goto insert_cleanup;
  }

  /* If the INSERT statement included an IDLIST term, then make sure
  ** all elements of the IDLIST really are columns of the table and 
  ** remember the column indices.
  **
................................................................................
          if( j==pTab->iPKey ){
            keyColumn = i;
          }
          break;
        }
      }
      if( j>=pTab->nCol ){
        sqliteSetString(&pParse->zErrMsg, "table ", pTab->zName,
           " has no column named ", pColumn->a[i].zName, 0);
        pParse->nErr++;
        goto insert_cleanup;
      }
    }
  }

  /* If there is no IDLIST term but the table has an integer primary







|







 







|
|
|
<
<







 







|
<
<
<
<
<
|
<
>



|
<
<
<
<
<
<







 







|
|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
133
134
135
136
137
138
139
140
141
142


143
144
145
146
147
148
149
...
239
240
241
242
243
244
245
246





247

248
249
250
251
252






253
254
255
256
257
258
259
...
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle INSERT statements in SQLite.
**
** $Id: insert.c,v 1.77 2003/03/31 02:12:47 drh Exp $
*/
#include "sqliteInt.h"

/*
** This routine is call to handle SQL of the following forms:
**
**    insert into TABLE (IDLIST) values(EXPRLIST)
................................................................................
  *  (b) that if it is a view then ON INSERT triggers exist
  */
  row_triggers_exist = 
    sqliteTriggersExist(pParse, pTab->pTrigger, TK_INSERT, 
        TK_BEFORE, TK_ROW, 0) ||
    sqliteTriggersExist(pParse, pTab->pTrigger, TK_INSERT, TK_AFTER, TK_ROW, 0);
  if( pTab->readOnly || (pTab->pSelect && !row_triggers_exist) ){
    sqliteErrorMsg(pParse, "%s %s may not be modified",
      pTab->pSelect ? "view" : "table",
      zTab);


    goto insert_cleanup;
  }

  if( pTab==0 ) goto insert_cleanup;

  /* If pTab is really a view, make sure it has been initialized.
  */
................................................................................
    }
  }

  /* Make sure the number of columns in the source data matches the number
  ** of columns to be inserted into the table.
  */
  if( pColumn==0 && nColumn!=pTab->nCol ){
    sqliteErrorMsg(pParse, 





       "table %S has %d columns but %d values were supplied",

       pTabList, 0, pTab->nCol, nColumn);
    goto insert_cleanup;
  }
  if( pColumn!=0 && nColumn!=pColumn->nId ){
    sqliteErrorMsg(pParse, "%d values for %d columns", nColumn, pColumn->nId);






    goto insert_cleanup;
  }

  /* If the INSERT statement included an IDLIST term, then make sure
  ** all elements of the IDLIST really are columns of the table and 
  ** remember the column indices.
  **
................................................................................
          if( j==pTab->iPKey ){
            keyColumn = i;
          }
          break;
        }
      }
      if( j>=pTab->nCol ){
        sqliteErrorMsg(pParse, "table %S has no column named %s",
            pTabList, 0, pColumn->a[i].zName);
        pParse->nErr++;
        goto insert_cleanup;
      }
    }
  }

  /* If there is no IDLIST term but the table has an integer primary

Changes to src/select.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
...
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
...
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
...
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
....
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
....
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
....
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
....
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
....
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
....
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
....
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
....
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056

2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
....
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087

2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.128 2003/03/27 12:51:25 drh Exp $
*/
#include "sqliteInt.h"


/*
** Allocate a new Select structure and return a pointer to that
** structure.
................................................................................
    if( pB==0 ){ pB = &dummy; zSp1 = 0; }
    if( pC==0 ){ pC = &dummy; zSp2 = 0; }
    sqliteSetNString(&pParse->zErrMsg, "unknown or unsupported join type: ", 0,
       pA->z, pA->n, zSp1, 1, pB->z, pB->n, zSp2, 1, pC->z, pC->n, 0);
    pParse->nErr++;
    jointype = JT_INNER;
  }else if( jointype & JT_RIGHT ){
    sqliteSetString(&pParse->zErrMsg, 
      "RIGHT and FULL OUTER JOINs are not currently supported", 0);
    pParse->nErr++;
    jointype = JT_INNER;
  }
  return jointype;
}

/*
** Return the index of a column in a table.  Return -1 if the column
................................................................................

    /* When the NATURAL keyword is present, add WHERE clause terms for
    ** every column that the two tables have in common.
    */
    if( pTerm->jointype & JT_NATURAL ){
      Table *pTab;
      if( pTerm->pOn || pTerm->pUsing ){
        sqliteSetString(&pParse->zErrMsg, "a NATURAL join may not have "
           "an ON or USING clause", 0);
        pParse->nErr++;
        return 1;
      }
      pTab = pTerm->pTab;
      for(j=0; j<pTab->nCol; j++){
        if( columnIndex(pOther->pTab, pTab->aCol[j].zName)>=0 ){
          addWhereTerm(pTab->aCol[j].zName, pTab, pOther->pTab, &p->pWhere);
        }
      }
    }

    /* Disallow both ON and USING clauses in the same join
    */
    if( pTerm->pOn && pTerm->pUsing ){
      sqliteSetString(&pParse->zErrMsg, "cannot have both ON and USING "
        "clauses in the same join", 0);
      pParse->nErr++;
      return 1;
    }

    /* Add the ON clause to the end of the WHERE clause, connected by
    ** and AND operator.
    */
    if( pTerm->pOn ){
................................................................................
      IdList *pList;
      int j;
      assert( i<pSrc->nSrc-1 );
      pList = pTerm->pUsing;
      for(j=0; j<pList->nId; j++){
        if( columnIndex(pTerm->pTab, pList->a[j].zName)<0 ||
            columnIndex(pOther->pTab, pList->a[j].zName)<0 ){
          sqliteSetString(&pParse->zErrMsg, "cannot join using column ",
            pList->a[j].zName, " - column not present in both tables", 0);
          pParse->nErr++;
          return 1;
        }
        addWhereTerm(pList->a[j].zName, pTerm->pTab, pOther->pTab, &p->pWhere);
      }
    }
  }
  return 0;
................................................................................
      pTab->isTransient = 1;
    }else{
      /* An ordinary table or view name in the FROM clause */
      pTabList->a[i].pTab = pTab = 
        sqliteFindTable(pParse->db, pTabList->a[i].zName,
                                    pTabList->a[i].zDatabase);
      if( pTab==0 ){
        sqliteSetString(&pParse->zErrMsg, "no such table: ", 
           pTabList->a[i].zName, 0);
        pParse->nErr++;
        return 1;
      }
      if( pTab->pSelect ){
        if( sqliteViewGetColumnNames(pParse, pTab) ){
          return 1;
        }
        sqliteSelectDelete(pTabList->a[i].pSelect);
................................................................................
              pExpr->span = pExpr->token;
            }
            pNew = sqliteExprListAppend(pNew, pExpr, 0);
          }
        }
        if( !tableSeen ){
          if( pName ){
            sqliteSetNString(&pParse->zErrMsg, "no such table: ", -1, 
              pName->z, pName->n, 0);
          }else{
            sqliteSetString(&pParse->zErrMsg, "no tables specified", 0);
          }
          rc = 1;
        }
      }
    }
    sqliteExprListDelete(pEList);
    p->pEList = pNew;
................................................................................
  pEList = pSelect->pEList;
  for(i=0; i<pOrderBy->nExpr; i++){
    Expr *pE = pOrderBy->a[i].pExpr;
    int iCol = -1;
    if( pOrderBy->a[i].done ) continue;
    if( sqliteExprIsInteger(pE, &iCol) ){
      if( iCol<=0 || iCol>pEList->nExpr ){
        char zBuf[200];
        sprintf(zBuf,"ORDER BY position %d should be between 1 and %d",
           iCol, pEList->nExpr);
        sqliteSetString(&pParse->zErrMsg, zBuf, 0);
        pParse->nErr++;
        nErr++;
        break;
      }
      if( !mustComplete ) continue;
      iCol--;
    }
    for(j=0; iCol<0 && j<pEList->nExpr; j++){
................................................................................
    if( iCol>=0 ){
      pE->op = TK_COLUMN;
      pE->iColumn = iCol;
      pE->iTable = iTable;
      pOrderBy->a[i].done = 1;
    }
    if( iCol<0 && mustComplete ){
      char zBuf[30];
      sprintf(zBuf,"%d",i+1);
      sqliteSetString(&pParse->zErrMsg, "ORDER BY term number ", zBuf, 
        " does not match any result column", 0);
      pParse->nErr++;
      nErr++;
      break;
    }
  }
  return nErr;  
}

................................................................................

  /* Make sure there is no ORDER BY clause on prior SELECTs.  Only the 
  ** last SELECT in the series may have an ORDER BY.
  */
  if( p==0 || p->pPrior==0 ) return 1;
  pPrior = p->pPrior;
  if( pPrior->pOrderBy ){
    sqliteSetString(&pParse->zErrMsg,"ORDER BY clause should come after ",
      selectOpName(p->op), " not before", 0);
    pParse->nErr++;
    return 1;
  }

  /* Make sure we have a valid query engine.  If not, create a new one.
  */
  v = sqliteGetVdbe(pParse);
  if( v==0 ) return 1;
................................................................................
        generateSortTail(p, v, p->pEList->nExpr, eDest, iParm);
      }
      break;
    }
  }
  assert( p->pEList && pPrior->pEList );
  if( p->pEList->nExpr!=pPrior->pEList->nExpr ){
    sqliteSetString(&pParse->zErrMsg, "SELECTs to the left and right of ",
      selectOpName(p->op), " do not have the same number of result columns", 0);
    pParse->nErr++;
    return 1;
  }

  /* Issue a null callback if that is what the user wants.
  */
  if( eDest==SRT_Callback &&
    (pParse->useCallback==0 || (pParse->db->flags & SQLITE_NullCallback)!=0)
................................................................................
  pEList = p->pEList;
  if( pEList==0 ) goto select_end;

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

  /* ORDER BY is ignored for some destinations.
  */
  switch( eDest ){
    case SRT_Union:
................................................................................
    if( sqliteExprCheck(pParse, pWhere, 0, 0) ){
      goto select_end;
    }
    sqliteOracle8JoinFixup(base, pTabList, pWhere);
  }
  if( pHaving ){
    if( pGroupBy==0 ){
      sqliteSetString(&pParse->zErrMsg, "a GROUP BY clause is required "
         "before HAVING", 0);
      pParse->nErr++;
      goto select_end;
    }
    if( sqliteExprResolveIds(pParse, base, pTabList, pEList, pHaving) ){
      goto select_end;
    }
    if( sqliteExprCheck(pParse, pHaving, 1, &isAgg) ){
      goto select_end;
................................................................................
        goto select_end;
      }
      if( sqliteExprCheck(pParse, pE, isAgg, 0) ){
        goto select_end;
      }
      if( sqliteExprIsConstant(pE) ){
        if( sqliteExprIsInteger(pE, &iCol)==0 ){
          sqliteSetString(&pParse->zErrMsg, 
               "ORDER BY terms must not be non-integer constants", 0);
          pParse->nErr++;
          goto select_end;
        }else if( iCol<=0 || iCol>pEList->nExpr ){
          char zBuf[2000];

          sprintf(zBuf,"ORDER BY column number %d out of range - should be "
             "between 1 and %d", iCol, pEList->nExpr);
          sqliteSetString(&pParse->zErrMsg, zBuf, 0);
          pParse->nErr++;
          goto select_end;
        }
      }
    }
  }
  if( pGroupBy ){
    for(i=0; i<pGroupBy->nExpr; i++){
................................................................................
        goto select_end;
      }
      if( sqliteExprCheck(pParse, pE, isAgg, 0) ){
        goto select_end;
      }
      if( sqliteExprIsConstant(pE) ){
        if( sqliteExprIsInteger(pE, &iCol)==0 ){
          sqliteSetString(&pParse->zErrMsg, 
               "GROUP BY terms must not be non-integer constants", 0);
          pParse->nErr++;
          goto select_end;
        }else if( iCol<=0 || iCol>pEList->nExpr ){
          char zBuf[2000];

          sprintf(zBuf,"GROUP BY column number %d out of range - should be "
             "between 1 and %d", iCol, pEList->nExpr);
          sqliteSetString(&pParse->zErrMsg, zBuf, 0);
          pParse->nErr++;
          goto select_end;
        }
      }
    }
  }

  /* Check for the special case of a min() or max() function by itself







|







 







|
|
<







 







|

<













|
|
<







 







|
|
<







 







|
<
<







 







|
<

|







 







|
|
|
<
<







 







|
<
<
|
<







 







|
|
<







 







|
|
<







 







|
|
<







 







|
<
<







 







|
|
<


<
>
|

<
<







 







|
|
<


<
>
|

<
<







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
116
117
118
119
120
121
122
123
124

125
126
127
128
129
130
131
...
213
214
215
216
217
218
219
220
221

222
223
224
225
226
227
228
229
230
231
232
233
234
235
236

237
238
239
240
241
242
243
...
261
262
263
264
265
266
267
268
269

270
271
272
273
274
275
276
...
907
908
909
910
911
912
913
914


915
916
917
918
919
920
921
....
1023
1024
1025
1026
1027
1028
1029
1030

1031
1032
1033
1034
1035
1036
1037
1038
1039
....
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128


1129
1130
1131
1132
1133
1134
1135
....
1151
1152
1153
1154
1155
1156
1157
1158


1159

1160
1161
1162
1163
1164
1165
1166
....
1262
1263
1264
1265
1266
1267
1268
1269
1270

1271
1272
1273
1274
1275
1276
1277
....
1434
1435
1436
1437
1438
1439
1440
1441
1442

1443
1444
1445
1446
1447
1448
1449
....
1960
1961
1962
1963
1964
1965
1966
1967
1968

1969
1970
1971
1972
1973
1974
1975
....
2001
2002
2003
2004
2005
2006
2007
2008


2009
2010
2011
2012
2013
2014
2015
....
2027
2028
2029
2030
2031
2032
2033
2034
2035

2036
2037

2038
2039
2040


2041
2042
2043
2044
2045
2046
2047
....
2055
2056
2057
2058
2059
2060
2061
2062
2063

2064
2065

2066
2067
2068


2069
2070
2071
2072
2073
2074
2075
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.129 2003/03/31 02:12:47 drh Exp $
*/
#include "sqliteInt.h"


/*
** Allocate a new Select structure and return a pointer to that
** structure.
................................................................................
    if( pB==0 ){ pB = &dummy; zSp1 = 0; }
    if( pC==0 ){ pC = &dummy; zSp2 = 0; }
    sqliteSetNString(&pParse->zErrMsg, "unknown or unsupported join type: ", 0,
       pA->z, pA->n, zSp1, 1, pB->z, pB->n, zSp2, 1, pC->z, pC->n, 0);
    pParse->nErr++;
    jointype = JT_INNER;
  }else if( jointype & JT_RIGHT ){
    sqliteErrorMsg(pParse, 
      "RIGHT and FULL OUTER JOINs are not currently supported");

    jointype = JT_INNER;
  }
  return jointype;
}

/*
** Return the index of a column in a table.  Return -1 if the column
................................................................................

    /* When the NATURAL keyword is present, add WHERE clause terms for
    ** every column that the two tables have in common.
    */
    if( pTerm->jointype & JT_NATURAL ){
      Table *pTab;
      if( pTerm->pOn || pTerm->pUsing ){
        sqliteErrorMsg(pParse, "a NATURAL join may not have "
           "an ON or USING clause", 0);

        return 1;
      }
      pTab = pTerm->pTab;
      for(j=0; j<pTab->nCol; j++){
        if( columnIndex(pOther->pTab, pTab->aCol[j].zName)>=0 ){
          addWhereTerm(pTab->aCol[j].zName, pTab, pOther->pTab, &p->pWhere);
        }
      }
    }

    /* Disallow both ON and USING clauses in the same join
    */
    if( pTerm->pOn && pTerm->pUsing ){
      sqliteErrorMsg(pParse, "cannot have both ON and USING "
        "clauses in the same join");

      return 1;
    }

    /* Add the ON clause to the end of the WHERE clause, connected by
    ** and AND operator.
    */
    if( pTerm->pOn ){
................................................................................
      IdList *pList;
      int j;
      assert( i<pSrc->nSrc-1 );
      pList = pTerm->pUsing;
      for(j=0; j<pList->nId; j++){
        if( columnIndex(pTerm->pTab, pList->a[j].zName)<0 ||
            columnIndex(pOther->pTab, pList->a[j].zName)<0 ){
          sqliteErrorMsg(pParse, "cannot join using column %s - column "
            "not present in both tables", pList->a[j].zName);

          return 1;
        }
        addWhereTerm(pList->a[j].zName, pTerm->pTab, pOther->pTab, &p->pWhere);
      }
    }
  }
  return 0;
................................................................................
      pTab->isTransient = 1;
    }else{
      /* An ordinary table or view name in the FROM clause */
      pTabList->a[i].pTab = pTab = 
        sqliteFindTable(pParse->db, pTabList->a[i].zName,
                                    pTabList->a[i].zDatabase);
      if( pTab==0 ){
        sqliteErrorMsg(pParse, "no such table: %S", pTabList, i);


        return 1;
      }
      if( pTab->pSelect ){
        if( sqliteViewGetColumnNames(pParse, pTab) ){
          return 1;
        }
        sqliteSelectDelete(pTabList->a[i].pSelect);
................................................................................
              pExpr->span = pExpr->token;
            }
            pNew = sqliteExprListAppend(pNew, pExpr, 0);
          }
        }
        if( !tableSeen ){
          if( pName ){
            sqliteErrorMsg(pParse, "no such table: %T", pName);

          }else{
            sqliteErrorMsg(pParse, "no tables specified");
          }
          rc = 1;
        }
      }
    }
    sqliteExprListDelete(pEList);
    p->pEList = pNew;
................................................................................
  pEList = pSelect->pEList;
  for(i=0; i<pOrderBy->nExpr; i++){
    Expr *pE = pOrderBy->a[i].pExpr;
    int iCol = -1;
    if( pOrderBy->a[i].done ) continue;
    if( sqliteExprIsInteger(pE, &iCol) ){
      if( iCol<=0 || iCol>pEList->nExpr ){
        sqliteErrorMsg(pParse,
          "ORDER BY position %d should be between 1 and %d",
          iCol, pEList->nExpr);


        nErr++;
        break;
      }
      if( !mustComplete ) continue;
      iCol--;
    }
    for(j=0; iCol<0 && j<pEList->nExpr; j++){
................................................................................
    if( iCol>=0 ){
      pE->op = TK_COLUMN;
      pE->iColumn = iCol;
      pE->iTable = iTable;
      pOrderBy->a[i].done = 1;
    }
    if( iCol<0 && mustComplete ){
      sqliteErrorMsg(pParse,


        "ORDER BY term number %d does not match any result column", i+1);

      nErr++;
      break;
    }
  }
  return nErr;  
}

................................................................................

  /* Make sure there is no ORDER BY clause on prior SELECTs.  Only the 
  ** last SELECT in the series may have an ORDER BY.
  */
  if( p==0 || p->pPrior==0 ) return 1;
  pPrior = p->pPrior;
  if( pPrior->pOrderBy ){
    sqliteErrorMsg(pParse,"ORDER BY clause should come after %s not before",
      selectOpName(p->op));

    return 1;
  }

  /* Make sure we have a valid query engine.  If not, create a new one.
  */
  v = sqliteGetVdbe(pParse);
  if( v==0 ) return 1;
................................................................................
        generateSortTail(p, v, p->pEList->nExpr, eDest, iParm);
      }
      break;
    }
  }
  assert( p->pEList && pPrior->pEList );
  if( p->pEList->nExpr!=pPrior->pEList->nExpr ){
    sqliteErrorMsg(pParse, "SELECTs to the left and right of %s"
      " do not have the same number of result columns", selectOpName(p->op));

    return 1;
  }

  /* Issue a null callback if that is what the user wants.
  */
  if( eDest==SRT_Callback &&
    (pParse->useCallback==0 || (pParse->db->flags & SQLITE_NullCallback)!=0)
................................................................................
  pEList = p->pEList;
  if( pEList==0 ) goto select_end;

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

    goto select_end;
  }

  /* ORDER BY is ignored for some destinations.
  */
  switch( eDest ){
    case SRT_Union:
................................................................................
    if( sqliteExprCheck(pParse, pWhere, 0, 0) ){
      goto select_end;
    }
    sqliteOracle8JoinFixup(base, pTabList, pWhere);
  }
  if( pHaving ){
    if( pGroupBy==0 ){
      sqliteErrorMsg(pParse, "a GROUP BY clause is required before HAVING");


      goto select_end;
    }
    if( sqliteExprResolveIds(pParse, base, pTabList, pEList, pHaving) ){
      goto select_end;
    }
    if( sqliteExprCheck(pParse, pHaving, 1, &isAgg) ){
      goto select_end;
................................................................................
        goto select_end;
      }
      if( sqliteExprCheck(pParse, pE, isAgg, 0) ){
        goto select_end;
      }
      if( sqliteExprIsConstant(pE) ){
        if( sqliteExprIsInteger(pE, &iCol)==0 ){
          sqliteErrorMsg(pParse,
             "ORDER BY terms must not be non-integer constants");

          goto select_end;
        }else if( iCol<=0 || iCol>pEList->nExpr ){

          sqliteErrorMsg(pParse, 
             "ORDER BY column number %d out of range - should be "
             "between 1 and %d", iCol, pEList->nExpr);


          goto select_end;
        }
      }
    }
  }
  if( pGroupBy ){
    for(i=0; i<pGroupBy->nExpr; i++){
................................................................................
        goto select_end;
      }
      if( sqliteExprCheck(pParse, pE, isAgg, 0) ){
        goto select_end;
      }
      if( sqliteExprIsConstant(pE) ){
        if( sqliteExprIsInteger(pE, &iCol)==0 ){
          sqliteErrorMsg(pParse,
            "GROUP BY terms must not be non-integer constants");

          goto select_end;
        }else if( iCol<=0 || iCol>pEList->nExpr ){

          sqliteErrorMsg(pParse,
             "GROUP BY column number %d out of range - should be "
             "between 1 and %d", iCol, pEList->nExpr);


          goto select_end;
        }
      }
    }
  }

  /* Check for the special case of a min() or max() function by itself

Changes to src/sqliteInt.h.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
957
958
959
960
961
962
963

964
965
966
967
968
969
970
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.167 2003/03/31 00:30:49 drh Exp $
*/
#include "config.h"
#include "sqlite.h"
#include "hash.h"
#include "vdbe.h"
#include "parse.h"
#include "btree.h"
................................................................................
  char *sqliteStrDup(const char*);
  char *sqliteStrNDup(const char*, int);
# define sqliteCheckMemory(a,b)
#endif
char *sqliteMPrintf(const char *,...);
void sqliteSetString(char **, const char *, ...);
void sqliteSetNString(char **, ...);

void sqliteDequote(char*);
int sqliteKeywordCode(const char*, int);
int sqliteRunParser(Parse*, const char*, char **);
void sqliteExec(Parse*);
Expr *sqliteExpr(int, Expr*, Expr*, Token*);
void sqliteExprSpan(Expr*,Token*,Token*);
Expr *sqliteExprFunction(ExprList*, Token*);







|







 







>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.168 2003/03/31 02:12:48 drh Exp $
*/
#include "config.h"
#include "sqlite.h"
#include "hash.h"
#include "vdbe.h"
#include "parse.h"
#include "btree.h"
................................................................................
  char *sqliteStrDup(const char*);
  char *sqliteStrNDup(const char*, int);
# define sqliteCheckMemory(a,b)
#endif
char *sqliteMPrintf(const char *,...);
void sqliteSetString(char **, const char *, ...);
void sqliteSetNString(char **, ...);
void sqliteErrorMsg(Parse*, const char*, ...);
void sqliteDequote(char*);
int sqliteKeywordCode(const char*, int);
int sqliteRunParser(Parse*, const char*, char **);
void sqliteExec(Parse*);
Expr *sqliteExpr(int, Expr*, Expr*, Token*);
void sqliteExprSpan(Expr*,Token*,Token*);
Expr *sqliteExprFunction(ExprList*, Token*);

Changes to src/trigger.c.

62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
...
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
...
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
  if( sqlite_malloc_failed ) goto trigger_cleanup;
  assert( pTableName->nSrc==1 );
  tab = sqliteSrcListLookup(pParse, pTableName);
  if( !tab ){
    goto trigger_cleanup;
  }
  if( tab->iDb>=2 ){
    sqliteSetString(&pParse->zErrMsg, "triggers may not be added to "
       "auxiliary database \"", db->aDb[tab->iDb].zName, "\"", 0);
    pParse->nErr++;
    goto trigger_cleanup;
  }

  zName = sqliteStrNDup(pName->z, pName->n);
  if( sqliteHashFind(&(db->aDb[tab->iDb].trigHash), zName,pName->n+1) ){
    sqliteSetNString(&pParse->zErrMsg, "trigger ", -1,
        pName->z, pName->n, " already exists", -1, 0);
    pParse->nErr++;
    goto trigger_cleanup;
  }
  if( sqliteStrNICmp(tab->zName, "sqlite_", 7)==0 ){
    sqliteSetString(&pParse->zErrMsg,"cannot create trigger on system table",0);
    pParse->nErr++;
    goto trigger_cleanup;
  }
  if( tab->pSelect && tr_tm != TK_INSTEAD ){
    sqliteSetString(&pParse->zErrMsg, "cannot create ", 
        (tr_tm == TK_BEFORE)?"BEFORE":"AFTER", " trigger on view: ",
        pTableName->a[0].zName, 0);
    goto trigger_cleanup;
  }
  if( !tab->pSelect && tr_tm == TK_INSTEAD ){
    sqliteSetString(&pParse->zErrMsg, "cannot create INSTEAD OF", 
        " trigger on table: ", pTableName->a[0].zName, 0);
    goto trigger_cleanup;
  }
#ifndef SQLITE_OMIT_AUTHORIZATION
  {
    int code = SQLITE_CREATE_TRIGGER;
    if( tab->iDb==1 ) code = SQLITE_CREATE_TEMP_TRIGGER;
    if( sqliteAuthCheck(pParse, code, zName, tab->zName) ){
................................................................................
  for(i=0; i<db->nDb; i++){
    int j = (i<2) ? i^1 : i;  /* Search TEMP before MAIN */
    if( zDb && sqliteStrICmp(db->aDb[j].zName, zDb) ) continue;
    pTrigger = sqliteHashFind(&(db->aDb[j].trigHash), zName, nName+1);
    if( pTrigger ) break;
  }
  if( !pTrigger ){
    sqliteSetString(&pParse->zErrMsg, "no such trigger: ", zName, 0);
    goto drop_trigger_cleanup;
  }
  assert( pTrigger->iDb>=0 && pTrigger->iDb<db->nDb );
  if( pTrigger->iDb>=2 ){
    sqliteSetString(&pParse->zErrMsg, "triggers may not be removed from "
       "auxiliary database \"", db->aDb[pTrigger->iDb].zName, "\"", 0);
    pParse->nErr++;
    goto drop_trigger_cleanup;
  }
  pTable = sqliteFindTable(db, pTrigger->table, db->aDb[pTrigger->iDb].zName);
  assert(pTable);
  assert( pTable->iDb==pTrigger->iDb );
#ifndef SQLITE_OMIT_AUTHORIZATION
  {
................................................................................
      for(jj=0; jj<pTab->nCol; jj++){
        if( sqliteStrICmp(pTab->aCol[jj].zName, pChanges->a[ii].zName)==0 ){
          aXRef[jj] = ii;
          break;
        }
      }
      if( jj>=pTab->nCol ){
        sqliteSetString(&pParse->zErrMsg, "no such column: ", 
            pChanges->a[ii].zName, 0);
        pParse->nErr++;
        goto trigger_cleanup;
      }
    }

    sqliteVdbeAddOp(v, OP_Integer, 13, 0);

    for(ii = 0; ii<pTab->nCol; ii++){







|
|
<





|
<
<



|




|
|
<



|
|







 







|




|
|
<







 







<
|
<







62
63
64
65
66
67
68
69
70

71
72
73
74
75
76


77
78
79
80
81
82
83
84
85
86

87
88
89
90
91
92
93
94
95
96
97
98
...
354
355
356
357
358
359
360
361
362
363
364
365
366
367

368
369
370
371
372
373
374
...
755
756
757
758
759
760
761

762

763
764
765
766
767
768
769
  if( sqlite_malloc_failed ) goto trigger_cleanup;
  assert( pTableName->nSrc==1 );
  tab = sqliteSrcListLookup(pParse, pTableName);
  if( !tab ){
    goto trigger_cleanup;
  }
  if( tab->iDb>=2 ){
    sqliteErrorMsg(pParse, "triggers may not be added to auxiliary "
       "database %s", db->aDb[tab->iDb].zName);

    goto trigger_cleanup;
  }

  zName = sqliteStrNDup(pName->z, pName->n);
  if( sqliteHashFind(&(db->aDb[tab->iDb].trigHash), zName,pName->n+1) ){
    sqliteErrorMsg(pParse, "trigger %T already exists", pName);


    goto trigger_cleanup;
  }
  if( sqliteStrNICmp(tab->zName, "sqlite_", 7)==0 ){
    sqliteErrorMsg(pParse, "cannot create trigger on system table");
    pParse->nErr++;
    goto trigger_cleanup;
  }
  if( tab->pSelect && tr_tm != TK_INSTEAD ){
    sqliteErrorMsg(pParse, "cannot create %s trigger on view: %S", 
        (tr_tm == TK_BEFORE)?"BEFORE":"AFTER", pTableName, 0);

    goto trigger_cleanup;
  }
  if( !tab->pSelect && tr_tm == TK_INSTEAD ){
    sqliteErrorMsg(pParse, "cannot create INSTEAD OF"
        " trigger on table: %S", pTableName, 0);
    goto trigger_cleanup;
  }
#ifndef SQLITE_OMIT_AUTHORIZATION
  {
    int code = SQLITE_CREATE_TRIGGER;
    if( tab->iDb==1 ) code = SQLITE_CREATE_TEMP_TRIGGER;
    if( sqliteAuthCheck(pParse, code, zName, tab->zName) ){
................................................................................
  for(i=0; i<db->nDb; i++){
    int j = (i<2) ? i^1 : i;  /* Search TEMP before MAIN */
    if( zDb && sqliteStrICmp(db->aDb[j].zName, zDb) ) continue;
    pTrigger = sqliteHashFind(&(db->aDb[j].trigHash), zName, nName+1);
    if( pTrigger ) break;
  }
  if( !pTrigger ){
    sqliteErrorMsg(pParse, "no such trigger: %S", pName, 0);
    goto drop_trigger_cleanup;
  }
  assert( pTrigger->iDb>=0 && pTrigger->iDb<db->nDb );
  if( pTrigger->iDb>=2 ){
    sqliteErrorMsg(pParse, "triggers may not be removed from "
       "auxiliary database %s", db->aDb[pTrigger->iDb].zName);

    goto drop_trigger_cleanup;
  }
  pTable = sqliteFindTable(db, pTrigger->table, db->aDb[pTrigger->iDb].zName);
  assert(pTable);
  assert( pTable->iDb==pTrigger->iDb );
#ifndef SQLITE_OMIT_AUTHORIZATION
  {
................................................................................
      for(jj=0; jj<pTab->nCol; jj++){
        if( sqliteStrICmp(pTab->aCol[jj].zName, pChanges->a[ii].zName)==0 ){
          aXRef[jj] = ii;
          break;
        }
      }
      if( jj>=pTab->nCol ){

        sqliteErrorMsg(pParse, "no such column: %s", pChanges->a[ii].zName);

        goto trigger_cleanup;
      }
    }

    sqliteVdbeAddOp(v, OP_Integer, 13, 0);

    for(ii = 0; ii<pTab->nCol; ii++){

Changes to src/update.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle UPDATE statements.
**
** $Id: update.c,v 1.57 2003/03/27 13:50:00 drh Exp $
*/
#include "sqliteInt.h"

/*
** Process an UPDATE statement.
*/
void sqliteUpdate(
................................................................................
          pRecnoExpr = pChanges->a[i].pExpr;
        }
        aXRef[j] = i;
        break;
      }
    }
    if( j>=pTab->nCol ){
      sqliteSetString(&pParse->zErrMsg, "no such column: ", 
         pChanges->a[i].zName, 0);
      pParse->nErr++;
      goto update_cleanup;
    }
#ifndef SQLITE_OMIT_AUTHORIZATION
    {
      int rc;
      rc = sqliteAuthCheck(pParse, SQLITE_UPDATE, pTab->zName,
                           pTab->aCol[j].zName);







|







 







<
|
<







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
136
137
138
139
140
141
142

143

144
145
146
147
148
149
150
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle UPDATE statements.
**
** $Id: update.c,v 1.58 2003/03/31 02:12:48 drh Exp $
*/
#include "sqliteInt.h"

/*
** Process an UPDATE statement.
*/
void sqliteUpdate(
................................................................................
          pRecnoExpr = pChanges->a[i].pExpr;
        }
        aXRef[j] = i;
        break;
      }
    }
    if( j>=pTab->nCol ){

      sqliteErrorMsg(pParse, "no such column: %s", pChanges->a[i].zName);

      goto update_cleanup;
    }
#ifndef SQLITE_OMIT_AUTHORIZATION
    {
      int rc;
      rc = sqliteAuthCheck(pParse, SQLITE_UPDATE, pTab->zName,
                           pTab->aCol[j].zName);

Changes to src/util.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
387
388
389
390
391
392
393
































































































































394
395
396
397
398
399
400
**
*************************************************************************
** Utility functions used throughout sqlite.
**
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.58 2003/02/16 22:21:32 drh Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
#include <ctype.h>

/*
** If malloc() ever fails, this global variable gets set to 1.
................................................................................
#ifdef MEMORY_DEBUG
#if MEMORY_DEBUG>1
  fprintf(stderr,"string at 0x%x is %s\n", (int)*pz, *pz);
#endif
#endif
  va_end(ap);
}

































































































































/*
** Convert an SQL-style quoted string into a normal string by removing
** the quote characters.  The conversion is done in-place.  If the
** input does not begin with a quote character, then this routine
** is a no-op.
**







|







 







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







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
**
*************************************************************************
** Utility functions used throughout sqlite.
**
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.59 2003/03/31 02:12:48 drh Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
#include <ctype.h>

/*
** If malloc() ever fails, this global variable gets set to 1.
................................................................................
#ifdef MEMORY_DEBUG
#if MEMORY_DEBUG>1
  fprintf(stderr,"string at 0x%x is %s\n", (int)*pz, *pz);
#endif
#endif
  va_end(ap);
}

/*
** Add an error message to pParse->zErrMsg and increment pParse->nErr.
** The following formatting characters are allowed:
**
**      %s      Insert a string
**      %z      A string that should be freed after use
**      %d      Insert an integer
**      %T      Insert a token
**      %S      Insert the first element of a SrcList
*/
void sqliteErrorMsg(Parse *pParse, const char *zFormat, ...){
  va_list ap;
  int nByte;
  int i, j;
  char *z;
  static char zNull[] = "NULL";

  pParse->nErr++;
  nByte = 1 + strlen(zFormat);
  va_start(ap, zFormat);
  for(i=0; zFormat[i]; i++){
    if( zFormat[i]!='%' && zFormat[i+1] ) continue;
    i++;
    switch( zFormat[i] ){
      case 'd': {
        (void)va_arg(ap, int);
        nByte += 20;
        break;
      }
      case 'z':
      case 's': {
        char *z2 = va_arg(ap, char*);
        if( z2==0 ) z2 = zNull;
        nByte += strlen(z2);
        break;
      }
      case 'T': {
        Token *p = va_arg(ap, Token*);
        nByte += p->n;
        break;
      }
      case 'S': {
        SrcList *p = va_arg(ap, SrcList*);
        int k = va_arg(ap, int);
        assert( p->nSrc>k && k>=0 );
        nByte += strlen(p->a[k].zName);
        if( p->a[k].zDatabase && p->a[k].zDatabase[0] ){
          nByte += strlen(p->a[k].zDatabase)+1;
        }
        break;
      }
      default: {
        nByte++;
        break;
      }
    }
  }
  va_end(ap);
  z = sqliteMalloc( nByte );
  if( z==0 ) return;
  sqliteFree(pParse->zErrMsg);
  pParse->zErrMsg = z;
  va_start(ap, zFormat);
  for(i=j=0; zFormat[i]; i++){
    if( zFormat[i]!='%' ) continue;
    if( i>j ){
      memcpy(z, &zFormat[j], i-j);
      z += i-j;
    }
    j = i+2;
    i++;
    switch( zFormat[i] ){
      case 'd': {
        int x = va_arg(ap, int);
        sprintf(z, "%d", x);
        z += strlen(z);
        break;
      }
      case 'z':
      case 's': {
        int len;
        char *z2 = va_arg(ap, char*);
        if( z2==0 ) z2 = zNull;
        len = strlen(z2);
        memcpy(z, z2, len);
        z += len;
        if( zFormat[i]=='z' && z2!=zNull ){
          sqliteFree(z2);
        }
        break;
      }
      case 'T': {
        Token *p = va_arg(ap, Token*);
        memcpy(z, p->z, p->n);
        z += p->n;
        break;
      }
      case 'S': {
        int len;
        SrcList *p = va_arg(ap, SrcList*);
        int k = va_arg(ap, int);
        assert( p->nSrc>k && k>=0 );
        if( p->a[k].zDatabase && p->a[k].zDatabase[0] ){
          len = strlen(p->a[k].zDatabase);
          memcpy(z, p->a[k].zDatabase, len);
          z += len;
          *(z++) = '.';
        }
        len = strlen(p->a[k].zName);
        memcpy(z, p->a[k].zName, len);
        z += len;
        break;
      }
      default: {
        *(z++) = zFormat[i];
        break;
      }
    }
  }
  va_end(ap);
  if( i>j ){
    memcpy(z, &zFormat[j], i-j);
    z += i-j;
  }
  assert( (z - pParse->zErrMsg) < nByte );
  *z = 0;
}

/*
** Convert an SQL-style quoted string into a normal string by removing
** the quote characters.  The conversion is done in-place.  If the
** input does not begin with a quote character, then this routine
** is a no-op.
**