mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
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
This commit is contained in:
38
src/build.c
38
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);
|
||||
|
16
src/delete.c
16
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;
|
||||
|
31
src/expr.c
31
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;
|
||||
}
|
||||
|
33
src/insert.c
33
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;
|
||||
}
|
||||
|
85
src/select.c
85
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;
|
||||
}
|
||||
}
|
||||
|
@ -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 **);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
130
src/util.c
130
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>
|
||||
@ -392,6 +392,134 @@ void sqliteSetNString(char **pz, ...){
|
||||
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
|
||||
|
Reference in New Issue
Block a user