aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--manifest28
-rw-r--r--manifest.uuid2
-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
11 files changed, 228 insertions, 175 deletions
diff --git a/manifest b/manifest
index 2e38bb3ef..029455550 100644
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C The\sATTACH\sand\sDETACH\sstatements\sare\snow\scoded\sbut\sare\sstill\smostly\suntested.\s(CVS\s890)
-D 2003-03-31T00:30:48
+C Add\sthe\ssqliteErrorMsg()\sfunction\sand\suse\sit\sto\sgenerate\serror\smessage\ntext\sduring\sparsing\sand\scode\sgeneration.\s\sThis\ssimplifies\sthe\scode\nsomewhat\sand\smakes\sit\seasier\sto\shandle\snames\swith\sa\sdatabase\sprefix.\s(CVS\s891)
+D 2003-03-31T02:12:47
F Makefile.in 3c4ba24253e61c954d67adbbb4245e7117c5357e
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@@ -22,14 +22,14 @@ F sqlite.pc.in 30552343140c53304c2a658c080fbe810cd09ca2
F src/auth.c f37bfc9451b8c1fa52f34adff474560018892729
F src/btree.c dba4d12945228dd7e94de7da0e1d8638b70d99f2
F src/btree.h 8209bfadf5845d4fdaa60f471bb360f894cd4095
-F src/build.c e56df7b1ccf923e75707953181c91380134253be
-F src/delete.c 923497248e0ff9097a595c6333ec6d67fe6650b5
+F src/build.c 5ea24a62f447f3beabe6fb6218ec24f4dd6aff95
+F src/delete.c 58d698779a6b7f819718ecd45b310a9de8537088
F src/encode.c faf03741efe921755ec371cf4a6984536de00042
-F src/expr.c eae205a27ec45232f234f281f8827c3be58b303d
+F src/expr.c b8daee83f837b24a22d889200bdd74973ca2d8db
F src/func.c 882c3ed5a02be18cd904715c7ec62947a34a3605
F src/hash.c 4fc39feb7b7711f6495ee9f2159559bedb043e1f
F src/hash.h cd0433998bc1a3759d244e1637fe5a3c13b53bf8
-F src/insert.c 95e7ab3fb51909351273a6c6f8aa831201130ce7
+F src/insert.c dad4d914dc729a94e48de171802c23587a62c34f
F src/main.c 6d9a38491fdc40c041df64a7399244c364481a09
F src/md5.c fe4f9c9c6f71dfc26af8da63e4d04489b1430565
F src/os.c dfed46091f69cd2d1e601f8a214d41344f2b00b6
@@ -39,11 +39,11 @@ F src/pager.h 97d9a8cc5103750efd8037d71ebfb41849ef2f2f
F src/parse.y 3be47fa18323aa2e3364fc42bf7a6ba5b3cc0a81
F src/printf.c fc5fdef6e92ad205005263661fe9716f55a49f3e
F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe
-F src/select.c afdc06d4606d14ab5793ef480206def6b02a2f19
+F src/select.c 7d69e569339e7ce9e672eb41d50a454110ea8a05
F src/shell.c c13ff46e905a59eb1c7dbea7c1850f8f115e6395
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
F src/sqlite.h.in be3e56214fecc73d72195ca62d8a3d6663602ff4
-F src/sqliteInt.h b86c03c496bdc9ff543a12a1d88766fbcf28cd0c
+F src/sqliteInt.h 1ce5af48f980d63ec6fbb41d3f8517b4eaf446ce
F src/table.c eed2098c9b577aa17f8abe89313a9c4413f57d63
F src/tclsqlite.c 4cb0ffa863123ae037db359849a231ff5cebfed4
F src/test1.c 7ad4e6308dde0bf5a0f0775ce20cb2ec37a328f8
@@ -51,9 +51,9 @@ F src/test2.c 5014337d8576b731cce5b5a14bec4f0daf432700
F src/test3.c c12ea7f1c3fbbd58904e81e6cb10ad424e6fc728
F src/threadtest.c d641a5219e718e18a1a80a50eb9bb549f451f42e
F src/tokenize.c 675b4718d17c69fe7609dc8e85e426ef002be811
-F src/trigger.c b07dc1ff60f2b18a701a85b83577a967e193dee2
-F src/update.c ab8c48ce00747ccf8f449f7f51ae56e08b5428ba
-F src/util.c 73b668d1ed468df650dc00685a5e4ffa6887feb4
+F src/trigger.c bd5a5b234b47f28f9f21a46243dcaf1c5b2383a3
+F src/update.c b368369f1fbe6d7f56a53e5ffad3b75dae9e3e1a
+F src/util.c 96178ddf8a01fe81f66620f555a53bcff54bd3d7
F src/vdbe.c 7171dbe873760f403b2501e96fd3d1bd852b3ce8
F src/vdbe.h ed43771f1dc2b994d5c484fdf2eab357c6ef0ee3
F src/where.c e5733f7d5e9cc4ed3590dc3401f779e7b7bb8127
@@ -155,7 +155,7 @@ F www/speed.tcl cb4c10a722614aea76d2c51f32ee43400d5951be
F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098
F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331
F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
-P 0a358844e40020557c1aeea5779b194670350930
-R b07af9b76a439a5b405050fd15558aa2
+P c7c5e927a54f0fbc2ca625754787aff4d9c4eff1
+R 049a3c05f7f7ec86278cb228c093cf6f
U drh
-Z 8c6d8642908a4e47e8f8d0600ce4a4a6
+Z 310a08d8c23f76a9c9a4ece27530433b
diff --git a/manifest.uuid b/manifest.uuid
index b6b9aa9ae..b6ecefe2e 100644
--- a/manifest.uuid
+++ b/manifest.uuid
@@ -1 +1 @@
-c7c5e927a54f0fbc2ca625754787aff4d9c4eff1 \ No newline at end of file
+1d3fc977211abdc7ba3fd51d661863e8ce5aef69 \ No newline at end of file
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