aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2003-03-31 02:12:46 +0000
committerdrh <drh@noemail.net>2003-03-31 02:12:46 +0000
commitda93d238c2067a1951b8043c3c30355947fd6da9 (patch)
tree29057f4a84763deb95565d3e8bd2622614c85c15 /src
parent1c2d84148a6bb2f8d231debd65bc09e948abf029 (diff)
downloadsqlite-da93d238c2067a1951b8043c3c30355947fd6da9.tar.gz
sqlite-da93d238c2067a1951b8043c3c30355947fd6da9.zip
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) FossilOrigin-Name: 1d3fc977211abdc7ba3fd51d661863e8ce5aef69
Diffstat (limited to 'src')
-rw-r--r--src/build.c38
-rw-r--r--src/delete.c16
-rw-r--r--src/expr.c31
-rw-r--r--src/insert.c33
-rw-r--r--src/select.c85
-rw-r--r--src/sqliteInt.h3
-rw-r--r--src/trigger.c31
-rw-r--r--src/update.c6
-rw-r--r--src/util.c130
9 files changed, 213 insertions, 160 deletions
diff --git a/src/build.c b/src/build.c
index 059c69be8..a14a72d2f 100644
--- a/src/build.c
+++ b/src/build.c
@@ -25,7 +25,7 @@
** ROLLBACK
** PRAGMA
**
-** $Id: build.c,v 1.137 2003/03/31 00:30:48 drh Exp $
+** $Id: build.c,v 1.138 2003/03/31 02:12:47 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@@ -1750,20 +1750,17 @@ void sqliteDropIndex(Parse *pParse, SrcList *pName){
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++;
+ sqliteErrorMsg(pParse, "no such index: %S", pName, 0);
goto exit_drop_index;
}
if( pIndex->autoIndex ){
- sqliteSetString(&pParse->zErrMsg, "index associated with UNIQUE "
+ sqliteErrorMsg(pParse, "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 "
+ sqliteErrorMsg(pParse, "cannot alter schema of attached "
"databases", 0);
- pParse->nErr++;
goto exit_drop_index;
}
#ifndef SQLITE_OMIT_AUTHORIZATION
@@ -2108,9 +2105,7 @@ void sqliteBeginTransaction(Parse *pParse, int onError){
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);
+ sqliteErrorMsg(pParse, "cannot start a transaction within a transaction");
return;
}
sqliteBeginWriteOperation(pParse, 0, 0);
@@ -2128,9 +2123,7 @@ void sqliteCommitTransaction(Parse *pParse){
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);
+ sqliteErrorMsg(pParse, "cannot commit - no transaction is active");
return;
}
db->flags &= ~SQLITE_InTrans;
@@ -2149,9 +2142,7 @@ void sqliteRollbackTransaction(Parse *pParse){
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);
+ sqliteErrorMsg(pParse, "cannot rollback - no transaction is active");
return;
}
v = sqliteGetVdbe(pParse);
@@ -2701,10 +2692,7 @@ void sqliteAttach(Parse *pParse, Token *pFilename, Token *pDbname){
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++;
+ sqliteErrorMsg(pParse, "database %z is already in use", zName);
return;
}
}
@@ -2715,8 +2703,7 @@ void sqliteAttach(Parse *pParse, Token *pFilename, Token *pDbname){
sqliteDequote(zFile);
rc = sqliteBtreeOpen(zFile, 0, MAX_PAGES, &aNew->pBt);
if( rc ){
- sqliteSetString(&pParse->zErrMsg, "unable to open database: ", zFile, 0);
- pParse->nErr++;
+ sqliteErrorMsg(pParse, "unable to open database: %s", zFile);
}
sqliteFree(zFile);
db->flags &= ~SQLITE_Initialized;
@@ -2746,14 +2733,11 @@ void sqliteDetach(Parse *pParse, Token *pDbname){
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++;
+ sqliteErrorMsg(pParse, "no such database: %T", pDbname);
return;
}
if( i<2 ){
- sqliteSetString(&pParse->zErrMsg, "cannot detached \"main\" or \"temp\"",0);
- pParse->nErr++;
+ sqliteErrorMsg(pParse, "cannot detached database %T", pDbname);
return;
}
sqliteBtreeClose(db->aDb[i].pBt);
diff --git a/src/delete.c b/src/delete.c
index 7fc2ddf91..fecb8cc12 100644
--- a/src/delete.c
+++ b/src/delete.c
@@ -12,7 +12,7 @@
** 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 $
+** $Id: delete.c,v 1.50 2003/03/31 02:12:47 drh Exp $
*/
#include "sqliteInt.h"
@@ -29,12 +29,7 @@ Table *sqliteSrcListLookup(Parse *pParse, SrcList *pSrc){
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++;
+ sqliteErrorMsg(pParse, "no such table: %S", pSrc, 0);
break;
}
pSrc->a[i].pTab = pTab;
@@ -49,10 +44,9 @@ Table *sqliteSrcListLookup(Parse *pParse, SrcList *pSrc){
*/
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++;
+ sqliteErrorMsg(pParse, "%s %s may not be modified",
+ pTab->pSelect ? "view" : "table",
+ pTab->zName);
return 1;
}
return 0;
diff --git a/src/expr.c b/src/expr.c
index 576ae2db8..caa6de11a 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -12,7 +12,7 @@
** 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 $
+** $Id: expr.c,v 1.91 2003/03/31 02:12:47 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@@ -477,14 +477,10 @@ int sqliteExprResolveIds(
}
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++;
+ sqliteErrorMsg(pParse, "no such column: %T", &pExpr->token);
return 1;
}else if( cnt>1 ){
- sqliteSetNString(&pParse->zErrMsg, "ambiguous column name: ", -1,
- pExpr->token.z, pExpr->token.n, 0);
- pParse->nErr++;
+ sqliteErrorMsg(pParse, "ambiguous column name: %T", &pExpr->token);
return 1;
}
if( pExpr->op==TK_COLUMN ){
@@ -600,16 +596,12 @@ int sqliteExprResolveIds(
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++;
+ sqliteErrorMsg(pParse, "no such column: %T.%T",
+ &pLeft->token, &pRight->token);
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++;
+ sqliteErrorMsg(pParse, "ambiguous column name: %T.%T",
+ &pLeft->token, &pRight->token);
return 1;
}
sqliteExprDelete(pExpr->pLeft);
@@ -647,9 +639,8 @@ int sqliteExprResolveIds(
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++;
+ sqliteErrorMsg(pParse,
+ "right-hand side of IN operator must be constant");
return 1;
}
if( sqliteExprCheck(pParse, pE2, 0, 0) ){
@@ -1219,8 +1210,8 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){
}
case TK_RAISE: {
if( !pParse->trigStack ){
- sqliteSetNString(&pParse->zErrMsg,
- "RAISE() may only be used within a trigger-program", -1, 0);
+ sqliteErrorMsg(pParse,
+ "RAISE() may only be used within a trigger-program");
pParse->nErr++;
return;
}
diff --git a/src/insert.c b/src/insert.c
index f9f72f8c4..705bd8e9d 100644
--- a/src/insert.c
+++ b/src/insert.c
@@ -12,7 +12,7 @@
** 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 $
+** $Id: insert.c,v 1.77 2003/03/31 02:12:47 drh Exp $
*/
#include "sqliteInt.h"
@@ -137,11 +137,9 @@ void sqliteInsert(
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++;
+ sqliteErrorMsg(pParse, "%s %s may not be modified",
+ pTab->pSelect ? "view" : "table",
+ zTab);
goto insert_cleanup;
}
@@ -245,24 +243,13 @@ void sqliteInsert(
** 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++;
+ 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 ){
- 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++;
+ sqliteErrorMsg(pParse, "%d values for %d columns", nColumn, pColumn->nId);
goto insert_cleanup;
}
@@ -292,8 +279,8 @@ void sqliteInsert(
}
}
if( j>=pTab->nCol ){
- sqliteSetString(&pParse->zErrMsg, "table ", pTab->zName,
- " has no column named ", pColumn->a[i].zName, 0);
+ sqliteErrorMsg(pParse, "table %S has no column named %s",
+ pTabList, 0, pColumn->a[i].zName);
pParse->nErr++;
goto insert_cleanup;
}
diff --git a/src/select.c b/src/select.c
index 48283550f..e1704d2bf 100644
--- a/src/select.c
+++ b/src/select.c
@@ -12,7 +12,7 @@
** 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 $
+** $Id: select.c,v 1.129 2003/03/31 02:12:47 drh Exp $
*/
#include "sqliteInt.h"
@@ -120,9 +120,8 @@ int sqliteJoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){
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++;
+ sqliteErrorMsg(pParse,
+ "RIGHT and FULL OUTER JOINs are not currently supported");
jointype = JT_INNER;
}
return jointype;
@@ -218,9 +217,8 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){
if( pTerm->jointype & JT_NATURAL ){
Table *pTab;
if( pTerm->pOn || pTerm->pUsing ){
- sqliteSetString(&pParse->zErrMsg, "a NATURAL join may not have "
+ sqliteErrorMsg(pParse, "a NATURAL join may not have "
"an ON or USING clause", 0);
- pParse->nErr++;
return 1;
}
pTab = pTerm->pTab;
@@ -234,9 +232,8 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){
/* 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++;
+ sqliteErrorMsg(pParse, "cannot have both ON and USING "
+ "clauses in the same join");
return 1;
}
@@ -268,9 +265,8 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){
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++;
+ 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);
@@ -915,9 +911,7 @@ static int fillInColumnList(Parse *pParse, Select *p){
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++;
+ sqliteErrorMsg(pParse, "no such table: %S", pTabList, i);
return 1;
}
if( pTab->pSelect ){
@@ -1033,10 +1027,9 @@ static int fillInColumnList(Parse *pParse, Select *p){
}
if( !tableSeen ){
if( pName ){
- sqliteSetNString(&pParse->zErrMsg, "no such table: ", -1,
- pName->z, pName->n, 0);
+ sqliteErrorMsg(pParse, "no such table: %T", pName);
}else{
- sqliteSetString(&pParse->zErrMsg, "no tables specified", 0);
+ sqliteErrorMsg(pParse, "no tables specified");
}
rc = 1;
}
@@ -1130,11 +1123,9 @@ static int matchOrderbyToColumn(
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++;
+ sqliteErrorMsg(pParse,
+ "ORDER BY position %d should be between 1 and %d",
+ iCol, pEList->nExpr);
nErr++;
break;
}
@@ -1164,11 +1155,8 @@ static int matchOrderbyToColumn(
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++;
+ sqliteErrorMsg(pParse,
+ "ORDER BY term number %d does not match any result column", i+1);
nErr++;
break;
}
@@ -1278,9 +1266,8 @@ static int multiSelect(Parse *pParse, Select *p, int eDest, int iParm){
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++;
+ sqliteErrorMsg(pParse,"ORDER BY clause should come after %s not before",
+ selectOpName(p->op));
return 1;
}
@@ -1451,9 +1438,8 @@ static int multiSelect(Parse *pParse, Select *p, int eDest, int iParm){
}
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++;
+ sqliteErrorMsg(pParse, "SELECTs to the left and right of %s"
+ " do not have the same number of result columns", selectOpName(p->op));
return 1;
}
@@ -1978,9 +1964,8 @@ int sqliteSelect(
** 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++;
+ sqliteErrorMsg(pParse, "only a single result allowed for "
+ "a SELECT that is part of an expression");
goto select_end;
}
@@ -2020,9 +2005,7 @@ int sqliteSelect(
}
if( pHaving ){
if( pGroupBy==0 ){
- sqliteSetString(&pParse->zErrMsg, "a GROUP BY clause is required "
- "before HAVING", 0);
- pParse->nErr++;
+ sqliteErrorMsg(pParse, "a GROUP BY clause is required before HAVING");
goto select_end;
}
if( sqliteExprResolveIds(pParse, base, pTabList, pEList, pHaving) ){
@@ -2048,16 +2031,13 @@ int sqliteSelect(
}
if( sqliteExprIsConstant(pE) ){
if( sqliteExprIsInteger(pE, &iCol)==0 ){
- sqliteSetString(&pParse->zErrMsg,
- "ORDER BY terms must not be non-integer constants", 0);
- pParse->nErr++;
+ sqliteErrorMsg(pParse,
+ "ORDER BY terms must not be non-integer constants");
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 "
+ sqliteErrorMsg(pParse,
+ "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;
}
}
@@ -2079,16 +2059,13 @@ int sqliteSelect(
}
if( sqliteExprIsConstant(pE) ){
if( sqliteExprIsInteger(pE, &iCol)==0 ){
- sqliteSetString(&pParse->zErrMsg,
- "GROUP BY terms must not be non-integer constants", 0);
- pParse->nErr++;
+ sqliteErrorMsg(pParse,
+ "GROUP BY terms must not be non-integer constants");
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 "
+ sqliteErrorMsg(pParse,
+ "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;
}
}
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index bffef93a4..f4e6999dc 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -11,7 +11,7 @@
*************************************************************************
** Internal interface definitions for SQLite.
**
-** @(#) $Id: sqliteInt.h,v 1.167 2003/03/31 00:30:49 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.168 2003/03/31 02:12:48 drh Exp $
*/
#include "config.h"
#include "sqlite.h"
@@ -961,6 +961,7 @@ void sqliteRealToSortable(double r, char *);
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 **);
diff --git a/src/trigger.c b/src/trigger.c
index 7e48e4d57..ec95daae6 100644
--- a/src/trigger.c
+++ b/src/trigger.c
@@ -66,33 +66,29 @@ void sqliteCreateTrigger(
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++;
+ 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) ){
- sqliteSetNString(&pParse->zErrMsg, "trigger ", -1,
- pName->z, pName->n, " already exists", -1, 0);
- pParse->nErr++;
+ sqliteErrorMsg(pParse, "trigger %T already exists", pName);
goto trigger_cleanup;
}
if( sqliteStrNICmp(tab->zName, "sqlite_", 7)==0 ){
- sqliteSetString(&pParse->zErrMsg,"cannot create trigger on system table",0);
+ sqliteErrorMsg(pParse, "cannot create trigger on system table");
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);
+ 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 ){
- sqliteSetString(&pParse->zErrMsg, "cannot create INSTEAD OF",
- " trigger on table: ", pTableName->a[0].zName, 0);
+ sqliteErrorMsg(pParse, "cannot create INSTEAD OF"
+ " trigger on table: %S", pTableName, 0);
goto trigger_cleanup;
}
#ifndef SQLITE_OMIT_AUTHORIZATION
@@ -362,14 +358,13 @@ void sqliteDropTrigger(Parse *pParse, SrcList *pName, int nested){
if( pTrigger ) break;
}
if( !pTrigger ){
- sqliteSetString(&pParse->zErrMsg, "no such trigger: ", zName, 0);
+ sqliteErrorMsg(pParse, "no such trigger: %S", pName, 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++;
+ 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);
@@ -764,9 +759,7 @@ void sqliteViewTriggers(
}
}
if( jj>=pTab->nCol ){
- sqliteSetString(&pParse->zErrMsg, "no such column: ",
- pChanges->a[ii].zName, 0);
- pParse->nErr++;
+ sqliteErrorMsg(pParse, "no such column: %s", pChanges->a[ii].zName);
goto trigger_cleanup;
}
}
diff --git a/src/update.c b/src/update.c
index fb0603061..58ff54b48 100644
--- a/src/update.c
+++ b/src/update.c
@@ -12,7 +12,7 @@
** 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 $
+** $Id: update.c,v 1.58 2003/03/31 02:12:48 drh Exp $
*/
#include "sqliteInt.h"
@@ -140,9 +140,7 @@ void sqliteUpdate(
}
}
if( j>=pTab->nCol ){
- sqliteSetString(&pParse->zErrMsg, "no such column: ",
- pChanges->a[i].zName, 0);
- pParse->nErr++;
+ sqliteErrorMsg(pParse, "no such column: %s", pChanges->a[i].zName);
goto update_cleanup;
}
#ifndef SQLITE_OMIT_AUTHORIZATION
diff --git a/src/util.c b/src/util.c
index 8231e9818..87e5f4431 100644
--- a/src/util.c
+++ b/src/util.c
@@ -14,7 +14,7 @@
** 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 $
+** $Id: util.c,v 1.59 2003/03/31 02:12:48 drh Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
@@ -393,6 +393,134 @@ void sqliteSetNString(char **pz, ...){
}
/*
+** 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