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 |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
1d3fc977211abdc7ba3fd51d661863e8 |
User & Date: | drh 2003-03-31 02:12:47.000 |
Context
2003-03-31
| ||
13:36 | Minor follow-on changes to the recent ATTACH patch. (CVS 892) (check-in: e80afe75b3 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: 1d3fc97721 user: drh tags: trunk) | |
00:30 | The ATTACH and DETACH statements are now coded but are still mostly untested. (CVS 890) (check-in: c7c5e927a5 user: drh tags: trunk) | |
Changes
Changes to src/build.c.
︙ | ︙ | |||
21 22 23 24 25 26 27 | ** COPY ** VACUUM ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** PRAGMA ** | | | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | ** 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 |
︙ | ︙ | |||
1746 1747 1748 1749 1750 1751 1752 | 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 ){ | | < | < | < | 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 | 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) ){ |
︙ | ︙ | |||
2104 2105 2106 2107 2108 2109 2110 | 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 ){ | < | < < < | < < | | 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 | 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; } /* ** Commit a transaction */ 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; } /* ** Rollback a transaction */ void sqliteRollbackTransaction(Parse *pParse){ 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; |
︙ | ︙ | |||
2697 2698 2699 2700 2701 2702 2703 | 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 ){ | < | < < | < | 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 | 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++; |
︙ | ︙ | |||
2742 2743 2744 2745 2746 2747 2748 | 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 ){ | | < < | < | 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 | 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 | ** 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. ** | | < | < < < < | | < | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 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 *sqliteSrcListLookup(Parse *pParse, SrcList *pSrc){ 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 | ** 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. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** 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 |
︙ | ︙ | |||
473 474 475 476 477 478 479 | 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]!='"' ){ | | < < | < < | 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 | 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; } |
︙ | ︙ | |||
596 597 598 599 600 601 602 | pExpr->iColumn = -1; pExpr->dataType = SQLITE_SO_NUM; } sqliteFree(zDb); sqliteFree(zLeft); sqliteFree(zRight); if( cnt==0 ){ | | < | < | < | < | 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 | 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; |
︙ | ︙ | |||
643 644 645 646 647 648 649 | ** 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) ){ | | | < | 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 | ** 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++; |
︙ | ︙ | |||
1215 1216 1217 1218 1219 1220 1221 | sqliteVdbeAddOp(v, OP_String, 0, 0); } sqliteVdbeResolveLabel(v, expr_end_label); break; } case TK_RAISE: { if( !pParse->trigStack ){ | | | | 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 | 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 | ** 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. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** 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) |
︙ | ︙ | |||
133 134 135 136 137 138 139 | * (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) ){ | | | | < < | 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | * (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. */ |
︙ | ︙ | |||
241 242 243 244 245 246 247 | } } /* 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 ){ | < < < < | < | | < < < | < < < | 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 | } } /* 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. ** |
︙ | ︙ | |||
288 289 290 291 292 293 294 | if( j==pTab->iPKey ){ keyColumn = i; } break; } } if( j>=pTab->nCol ){ | | | | 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 | 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 | ** 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. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** 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. |
︙ | ︙ | |||
116 117 118 119 120 121 122 | 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 ){ | | | < | 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | 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 |
︙ | ︙ | |||
214 215 216 217 218 219 220 | /* 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 ){ | | < | | < | 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 | /* 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 ){ |
︙ | ︙ | |||
264 265 266 267 268 269 270 | 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 ){ | | | < | 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 | 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; |
︙ | ︙ | |||
911 912 913 914 915 916 917 | 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 ){ | | < < | 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 | 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); |
︙ | ︙ | |||
1029 1030 1031 1032 1033 1034 1035 | pExpr->span = pExpr->token; } pNew = sqliteExprListAppend(pNew, pExpr, 0); } } if( !tableSeen ){ if( pName ){ | | < | | 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 | 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; |
︙ | ︙ | |||
1126 1127 1128 1129 1130 1131 1132 | 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 ){ | | | | < < | 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 | 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++){ |
︙ | ︙ | |||
1160 1161 1162 1163 1164 1165 1166 | if( iCol>=0 ){ pE->op = TK_COLUMN; pE->iColumn = iCol; pE->iTable = iTable; pOrderBy->a[i].done = 1; } if( iCol<0 && mustComplete ){ | < < | | < | 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 | 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; } |
︙ | ︙ | |||
1274 1275 1276 1277 1278 1279 1280 | /* 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 ){ | | | < | 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 | /* 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; |
︙ | ︙ | |||
1447 1448 1449 1450 1451 1452 1453 | generateSortTail(p, v, p->pEList->nExpr, eDest, iParm); } break; } } assert( p->pEList && pPrior->pEList ); if( p->pEList->nExpr!=pPrior->pEList->nExpr ){ | | | < | 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 | 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) |
︙ | ︙ | |||
1974 1975 1976 1977 1978 1979 1980 | 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 ){ | | | < | 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 | 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: |
︙ | ︙ | |||
2016 2017 2018 2019 2020 2021 2022 | if( sqliteExprCheck(pParse, pWhere, 0, 0) ){ goto select_end; } sqliteOracle8JoinFixup(base, pTabList, pWhere); } if( pHaving ){ if( pGroupBy==0 ){ | | < < | 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 | 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; |
︙ | ︙ | |||
2044 2045 2046 2047 2048 2049 2050 | goto select_end; } if( sqliteExprCheck(pParse, pE, isAgg, 0) ){ goto select_end; } if( sqliteExprIsConstant(pE) ){ if( sqliteExprIsInteger(pE, &iCol)==0 ){ | | | < | | < < | 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 | 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++){ |
︙ | ︙ | |||
2075 2076 2077 2078 2079 2080 2081 | goto select_end; } if( sqliteExprCheck(pParse, pE, isAgg, 0) ){ goto select_end; } if( sqliteExprIsConstant(pE) ){ if( sqliteExprIsInteger(pE, &iCol)==0 ){ | | | < | | < < | 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 | 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.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** 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. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** 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" |
︙ | ︙ | |||
957 958 959 960 961 962 963 964 965 966 967 968 969 970 | 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*); | > | 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 | 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 | if( sqlite_malloc_failed ) goto trigger_cleanup; assert( pTableName->nSrc==1 ); tab = sqliteSrcListLookup(pParse, pTableName); if( !tab ){ goto trigger_cleanup; } if( tab->iDb>=2 ){ | | | < < | < | | | < | | | 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 | 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) ){ |
︙ | ︙ | |||
358 359 360 361 362 363 364 | 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 ){ | | | | < | 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 | 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 { |
︙ | ︙ | |||
760 761 762 763 764 765 766 | 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 ){ | < | < | 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 | 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 | ** 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. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** 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( |
︙ | ︙ | |||
136 137 138 139 140 141 142 | pRecnoExpr = pChanges->a[i].pExpr; } aXRef[j] = i; break; } } if( j>=pTab->nCol ){ | < | < | 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | 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 | ** ************************************************************************* ** Utility functions used throughout sqlite. ** ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** 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. |
︙ | ︙ | |||
387 388 389 390 391 392 393 394 395 396 397 398 399 400 | #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. ** | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | #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. ** |
︙ | ︙ |