Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Autoincrement code installed. Simple smoke-testing only. No regression tests developed yet. (CVS 2091) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
8fde833c812b91c5a574208a70b5f92b |
User & Date: | drh 2004-11-12 03:56:15.000 |
Context
2004-11-12
| ||
13:42 | Add the "ALTER TABLE xxx RENAME TO yyy" command. (CVS 2092) (check-in: a1b2cc63e6 user: danielk1977 tags: trunk) | |
03:56 | Autoincrement code installed. Simple smoke-testing only. No regression tests developed yet. (CVS 2091) (check-in: 8fde833c81 user: drh tags: trunk) | |
2004-11-11
| ||
19:32 | Website updates. (CVS 2090) (check-in: 60fb0cef09 user: drh tags: trunk) | |
Changes
Changes to src/build.c.
︙ | ︙ | |||
18 19 20 21 22 23 24 | ** CREATE INDEX ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | ** CREATE INDEX ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** ** $Id: build.c,v 1.276 2004/11/12 03:56:15 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 |
︙ | ︙ | |||
317 318 319 320 321 322 323 324 325 326 327 328 329 330 | sqlite3HashClear(&temp2); sqlite3HashInit(&pDb->tblHash, SQLITE_HASH_STRING, 0); for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){ Table *pTab = sqliteHashData(pElem); sqlite3DeleteTable(db, pTab); } sqlite3HashClear(&temp1); DbClearProperty(db, i, DB_SchemaLoaded); if( iDb>0 ) return; } assert( iDb==0 ); db->flags &= ~SQLITE_InternChanges; /* If one or more of the auxiliary database files has been closed, | > | 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 | sqlite3HashClear(&temp2); sqlite3HashInit(&pDb->tblHash, SQLITE_HASH_STRING, 0); for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){ Table *pTab = sqliteHashData(pElem); sqlite3DeleteTable(db, pTab); } sqlite3HashClear(&temp1); pDb->pSeqTab = 0; DbClearProperty(db, i, DB_SchemaLoaded); if( iDb>0 ) return; } assert( iDb==0 ); db->flags &= ~SQLITE_InternChanges; /* If one or more of the auxiliary database files has been closed, |
︙ | ︙ | |||
513 514 515 516 517 518 519 520 | ** "temp" or the name of an attached db). This routine returns the ** index of the named database in db->aDb[], or -1 if the named db ** does not exist. */ int findDb(sqlite3 *db, Token *pName){ int i; Db *pDb; for(pDb=db->aDb, i=0; i<db->nDb; i++, pDb++){ | > > | | > | 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 | ** "temp" or the name of an attached db). This routine returns the ** index of the named database in db->aDb[], or -1 if the named db ** does not exist. */ int findDb(sqlite3 *db, Token *pName){ int i; Db *pDb; char *zName = sqlite3NameFromToken(pName); int n = strlen(zName); for(pDb=db->aDb, i=0; i<db->nDb; i++, pDb++){ if( n==strlen(pDb->zName) && 0==sqlite3StrICmp(pDb->zName, zName) ){ sqliteFree(zName); return i; } } sqliteFree(zName); return -1; } /* The table or view or trigger name is passed to this routine via tokens ** pName1 and pName2. If the table name was fully qualified, for example: ** ** CREATE TABLE xxx.yyy (...); |
︙ | ︙ | |||
716 717 718 719 720 721 722 | /* If this is the magic sqlite_sequence table used by autoincrement, ** then record a pointer to this table in the main database structure ** so that INSERT can find the table easily. */ #ifndef SQLITE_OMIT_AUTOINCREMENT if( strcmp(zName, "sqlite_sequence")==0 ){ | < | 720 721 722 723 724 725 726 727 728 729 730 731 732 733 | /* If this is the magic sqlite_sequence table used by autoincrement, ** then record a pointer to this table in the main database structure ** so that INSERT can find the table easily. */ #ifndef SQLITE_OMIT_AUTOINCREMENT if( strcmp(zName, "sqlite_sequence")==0 ){ db->aDb[iDb].pSeqTab = pTable; } #endif /* Begin generating the code that will insert the table record into ** the SQLITE_MASTER table. Note in particular that we must go ahead ** and allocate the record number for the table entry now. Before any |
︙ | ︙ | |||
1448 1449 1450 1451 1452 1453 1454 1455 1456 | db->aDb[p->iDb].zName, SCHEMA_TABLE(p->iDb), zType, p->zName, p->zName, zStmt ); sqliteFree(zStmt); /* Reparse everything to update our internal data structures */ | > > > > > > > > > > > > > > > > > > > > > < > | 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 | db->aDb[p->iDb].zName, SCHEMA_TABLE(p->iDb), zType, p->zName, p->zName, zStmt ); sqliteFree(zStmt); sqlite3ChangeCookie(db, v, p->iDb); #ifndef SQLITE_OMIT_AUTOINCREMENT /* Check to see if we need to create an sqlite_sequence table for ** keeping track of autoincrement keys. */ if( p->autoInc ){ Db *pDb = &db->aDb[p->iDb]; if( pDb->pSeqTab==0 ){ sqlite3NestedParse(pParse, "CREATE TABLE %Q.sqlite_sequence AS SELECT %Q AS name, 0 AS seq;", pDb->zName, p->zName ); }else{ sqlite3NestedParse(pParse, "INSERT INTO %Q.sqlite_sequence VALUES(%Q,0)", pDb->zName, p->zName ); } } #endif /* Reparse everything to update our internal data structures */ sqlite3VdbeOp3(v, OP_ParseSchema, p->iDb, 0, sqlite3MPrintf("tbl_name='%q'",p->zName), P3_DYNAMIC); } /* Add the table to the in-memory representation of the database. */ if( db->init.busy && pParse->nErr==0 ){ Table *pOld; FKey *pFKey; Db *pDb = &db->aDb[p->iDb]; |
︙ | ︙ | |||
1803 1804 1805 1806 1807 1808 1809 | /* Generate code to remove the table from the master table ** on disk. */ v = sqlite3GetVdbe(pParse); if( v ){ Trigger *pTrigger; | > > | | | > > > > > > > > > > > > > > | | 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 | /* Generate code to remove the table from the master table ** on disk. */ v = sqlite3GetVdbe(pParse); if( v ){ Trigger *pTrigger; int iDb = pTab->iDb; Db *pDb = &db->aDb[iDb]; sqlite3BeginWriteOperation(pParse, 0, iDb); /* Drop all triggers associated with the table being dropped. Code ** is generated to remove entries from sqlite_master and/or ** sqlite_temp_master if required. */ pTrigger = pTab->pTrigger; while( pTrigger ){ assert( pTrigger->iDb==iDb || pTrigger->iDb==1 ); sqlite3DropTriggerPtr(pParse, pTrigger, 1); pTrigger = pTrigger->pNext; } /* Drop all SQLITE_MASTER table and index entries that refer to the ** table. The program name loops through the master table and deletes ** every row that refers to a table of the same name as the one being ** dropped. Triggers are handled seperately because a trigger can be ** created in the temp database that refers to a table in another ** database. */ sqlite3NestedParse(pParse, "DELETE FROM %Q.%s WHERE tbl_name=%Q and type!='trigger'", pDb->zName, SCHEMA_TABLE(iDb), pTab->zName); if( !isView ){ destroyTable(pParse, pTab); } #ifndef SQLITE_OMIT_AUTOINCREMENT /* Remove any entries of the sqlite_sequence table associated with ** the table being dropped */ if( pTab->autoInc ){ sqlite3NestedParse(pParse, "DELETE FROM %s.sqlite_sequence WHERE name=%Q", pDb->zName, pTab->zName ); } #endif /* Remove the table entry from SQLite's internal schema */ sqlite3VdbeOp3(v, OP_DropTable, iDb, 0, pTab->zName, 0); } sqliteViewResetAll(db, iDb); exit_drop_table: sqlite3SrcListDelete(pName); } |
︙ | ︙ |
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.170 2004/11/12 03:56:15 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** Return the 'affinity' of the expression pExpr if any. ** |
︙ | ︙ | |||
198 199 200 201 202 203 204 | return pNew; } /* ** When doing a nested parse, you can include terms in an expression ** that look like this: #0 #1 #2 ... These terms refer to elements ** on the stack. "#0" (or just "#") means the top of the stack. | | > > | | | > > > | 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 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 | return pNew; } /* ** When doing a nested parse, you can include terms in an expression ** that look like this: #0 #1 #2 ... These terms refer to elements ** on the stack. "#0" (or just "#") means the top of the stack. ** "#1" means the next down on the stack. And so forth. #-1 means ** memory location 0. #-2 means memory location 1. And so forth. ** ** This routine is called by the parser to deal with on of those terms. ** It immediately generates code to store the value in a memory location. ** The returns an expression that will code to extract the value from ** that memory location as needed. */ Expr *sqlite3RegisterExpr(Parse *pParse, Token *pToken){ Vdbe *v = pParse->pVdbe; Expr *p; int depth; if( v==0 ) return 0; if( pParse->nested==0 ){ sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", pToken); return 0; } p = sqlite3Expr(TK_REGISTER, 0, 0, pToken); depth = atoi(&pToken->z[1]); if( depth>=0 ){ p->iTable = pParse->nMem++; sqlite3VdbeAddOp(v, OP_Dup, depth, 0); sqlite3VdbeAddOp(v, OP_MemStore, p->iTable, 1); }else{ p->iTable = -1-depth; } return p; } /* ** Join two expressions using an AND operator. If either expression is ** NULL, then just return the other expression. */ |
︙ | ︙ |
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.125 2004/11/12 03:56:15 drh Exp $ */ #include "sqliteInt.h" /* ** Set P3 of the most recently inserted opcode to a column affinity ** string for index pIdx. A column affinity string has one character ** for each column in the table, according to the affinity of the column: |
︙ | ︙ | |||
185 186 187 188 189 190 191 192 193 194 195 196 197 198 | int useTempTable; /* Store SELECT results in intermediate table */ int srcTab = 0; /* Data comes from this temporary cursor if >=0 */ int iSelectLoop = 0; /* Address of code that implements the SELECT */ int iCleanup = 0; /* Address of the cleanup code */ int iInsertBlock = 0; /* Address of the subroutine used to insert data */ int iCntMem = 0; /* Memory cell used for the row counter */ int newIdx = -1; /* Cursor for the NEW table */ #ifndef SQLITE_OMIT_TRIGGER int isView; /* True if attempting to insert into a view */ int row_triggers_exist = 0; /* True if there are FOR EACH ROW triggers */ int before_triggers; /* True if there are BEFORE triggers */ int after_triggers; /* True if there are AFTER triggers */ #endif | > > | 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 | int useTempTable; /* Store SELECT results in intermediate table */ int srcTab = 0; /* Data comes from this temporary cursor if >=0 */ int iSelectLoop = 0; /* Address of code that implements the SELECT */ int iCleanup = 0; /* Address of the cleanup code */ int iInsertBlock = 0; /* Address of the subroutine used to insert data */ int iCntMem = 0; /* Memory cell used for the row counter */ int newIdx = -1; /* Cursor for the NEW table */ Db *pDb; /* The database containing table being inserted into */ int counterMem = 0; /* Memory cell holding AUTOINCREMENT counter */ #ifndef SQLITE_OMIT_TRIGGER int isView; /* True if attempting to insert into a view */ int row_triggers_exist = 0; /* True if there are FOR EACH ROW triggers */ int before_triggers; /* True if there are BEFORE triggers */ int after_triggers; /* True if there are AFTER triggers */ #endif |
︙ | ︙ | |||
206 207 208 209 210 211 212 | zTab = pTabList->a[0].zName; if( zTab==0 ) goto insert_cleanup; pTab = sqlite3SrcListLookup(pParse, pTabList); if( pTab==0 ){ goto insert_cleanup; } assert( pTab->iDb<db->nDb ); | | > | 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 | zTab = pTabList->a[0].zName; if( zTab==0 ) goto insert_cleanup; pTab = sqlite3SrcListLookup(pParse, pTabList); if( pTab==0 ){ goto insert_cleanup; } assert( pTab->iDb<db->nDb ); pDb = &db->aDb[pTab->iDb]; zDb = pDb->zName; if( sqlite3AuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, zDb) ){ goto insert_cleanup; } /* Figure out if we have any triggers and if the table being ** inserted into is a view */ |
︙ | ︙ | |||
266 267 268 269 270 271 272 273 274 275 276 277 278 279 | sqlite3BeginWriteOperation(pParse, pSelect || row_triggers_exist, pTab->iDb); /* if there are row triggers, allocate a temp table for new.* references. */ if( row_triggers_exist ){ newIdx = pParse->nTab++; } /* Figure out how many columns of data are supplied. If the data ** is coming from a SELECT statement, then this step also generates ** all the code to implement the SELECT statement and invoke a subroutine ** to process each row of the result. (Template 2.) If the SELECT ** statement uses the the table that is being inserted into, then the ** subroutine is also coded here. That subroutine stores the SELECT ** results in a temporary table. (Template 3.) | > > > > > > > > > > > > > > > | 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 | sqlite3BeginWriteOperation(pParse, pSelect || row_triggers_exist, pTab->iDb); /* if there are row triggers, allocate a temp table for new.* references. */ if( row_triggers_exist ){ newIdx = pParse->nTab++; } #ifndef SQLITE_OMIT_AUTOINCREMENT /* If this is an AUTOINCREMENT table, look up the sequence number in the ** sqlite_sequence table and store it in a memory cell. Create a new ** sqlite_sequence table entry if one does not already exist. */ if( pTab->autoInc ){ counterMem = ++pParse->nMem; assert( counterMem>0 ); /* Must be so for OP_NewRecno to work right */ sqlite3NestedParse(pParse, "SELECT seq FROM %Q.sqlite_sequence WHERE name=%Q INTO %d", pDb->zName, pTab->zName, counterMem ); } #endif /* SQLITE_OMIT_AUTOINCREMENT */ /* Figure out how many columns of data are supplied. If the data ** is coming from a SELECT statement, then this step also generates ** all the code to implement the SELECT statement and invoke a subroutine ** to process each row of the result. (Template 2.) If the SELECT ** statement uses the the table that is being inserted into, then the ** subroutine is also coded here. That subroutine stores the SELECT ** results in a temporary table. (Template 3.) |
︙ | ︙ | |||
541 542 543 544 545 546 547 | sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr); } /* If the PRIMARY KEY expression is NULL, then use OP_NewRecno ** to generate a unique primary key value. */ sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3); sqlite3VdbeAddOp(v, OP_Pop, 1, 0); | | > > > > > | 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 | sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr); } /* If the PRIMARY KEY expression is NULL, then use OP_NewRecno ** to generate a unique primary key value. */ sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3); sqlite3VdbeAddOp(v, OP_Pop, 1, 0); sqlite3VdbeAddOp(v, OP_NewRecno, base, counterMem); sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0); }else{ sqlite3VdbeAddOp(v, OP_NewRecno, base, 0); } #ifndef SQLITE_OMIT_AUTOINCREMENT if( pTab->autoInc ){ sqlite3VdbeAddOp(v, OP_MemMax, counterMem, 0); } #endif /* SQLITE_OMIT_AUTOINCREMENT */ /* Push onto the stack, data for all columns of the new entry, beginning ** with the first column. */ for(i=0; i<pTab->nCol; i++){ if( i==pTab->iPKey ){ /* The value of the INTEGER PRIMARY KEY column is always a NULL. |
︙ | ︙ | |||
628 629 630 631 632 633 634 635 636 637 638 639 640 641 | if( !row_triggers_exist ){ /* Close all tables opened */ sqlite3VdbeAddOp(v, OP_Close, base, 0); for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){ sqlite3VdbeAddOp(v, OP_Close, idx+base, 0); } } /* ** Return the number of rows inserted. If this routine is ** generating code because of a call to sqlite3NestedParse(), do not ** invoke the callback function. */ if( db->flags & SQLITE_CountRows && pParse->nested==0 ){ | > > > > > > > > > > > | 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 | if( !row_triggers_exist ){ /* Close all tables opened */ sqlite3VdbeAddOp(v, OP_Close, base, 0); for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){ sqlite3VdbeAddOp(v, OP_Close, idx+base, 0); } } #ifndef SQLITE_OMIT_AUTOINCREMENT /* Update the sqlite_sequence table */ if( pTab->autoInc ){ sqlite3NestedParse(pParse, "UPDATE %Q.sqlite_sequence SET seq=#-%d WHERE name=%Q", pDb->zName, counterMem+1, pTab->zName ); } #endif /* ** Return the number of rows inserted. If this routine is ** generating code because of a call to sqlite3NestedParse(), do not ** invoke the callback function. */ if( db->flags & SQLITE_CountRows && pParse->nested==0 ){ |
︙ | ︙ |
Changes to src/parse.y.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** This file contains SQLite's grammar for SQL. Process this file ** using the lemon parser generator to generate C code that runs ** the parser. Lemon will also generate a header file containing ** numeric codes for all of the tokens. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** This file contains SQLite's grammar for SQL. Process this file ** using the lemon parser generator to generate C code that runs ** the parser. Lemon will also generate a header file containing ** numeric codes for all of the tokens. ** ** @(#) $Id: parse.y,v 1.153 2004/11/12 03:56:15 drh Exp $ */ %token_prefix TK_ %token_type {Token} %default_type {Token} %extra_argument {Parse *pParse} %syntax_error { if( pParse->zErrMsg==0 ){ |
︙ | ︙ | |||
146 147 148 149 150 151 152 | DATABASE DEFERRED DESC DETACH EACH END EXCLUSIVE EXPLAIN FAIL FOR GLOB IGNORE IMMEDIATE INITIALLY INSTEAD LIKE MATCH KEY OF OFFSET PRAGMA RAISE REPLACE RESTRICT ROW STATEMENT TEMP TRIGGER VACUUM VIEW %ifdef SQLITE_OMIT_COMPOUND_SELECT EXCEPT INTERSECT UNION %endif | | | 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | DATABASE DEFERRED DESC DETACH EACH END EXCLUSIVE EXPLAIN FAIL FOR GLOB IGNORE IMMEDIATE INITIALLY INSTEAD LIKE MATCH KEY OF OFFSET PRAGMA RAISE REPLACE RESTRICT ROW STATEMENT TEMP TRIGGER VACUUM VIEW %ifdef SQLITE_OMIT_COMPOUND_SELECT EXCEPT INTERSECT UNION %endif REINDEX RENAME CDATE CTIME CTIMESTAMP ALTER . // Define operator precedence early so that this is the first occurance // of the operator tokens in the grammer. Keeping the operators together // causes them to be assigned integer values that are close together, // which keeps parser tables smaller. // |
︙ | ︙ | |||
226 227 228 229 230 231 232 | ccons ::= REFERENCES nm(T) idxlist_opt(TA) refargs(R). {sqlite3CreateForeignKey(pParse,0,&T,TA,R);} ccons ::= defer_subclause(D). {sqlite3DeferForeignKey(pParse,D);} ccons ::= COLLATE id(C). {sqlite3AddCollateType(pParse, C.z, C.n);} // The optional AUTOINCREMENT keyword %type autoinc {int} | | | | 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 | ccons ::= REFERENCES nm(T) idxlist_opt(TA) refargs(R). {sqlite3CreateForeignKey(pParse,0,&T,TA,R);} ccons ::= defer_subclause(D). {sqlite3DeferForeignKey(pParse,D);} ccons ::= COLLATE id(C). {sqlite3AddCollateType(pParse, C.z, C.n);} // The optional AUTOINCREMENT keyword %type autoinc {int} autoinc(X) ::= . {X = 0;} autoinc(X) ::= AUTOINCR. {X = 1;} // The next group of rules parses the arguments to a REFERENCES clause // that determine if the referential integrity checking is deferred or // or immediate and which determine what action to take if a ref-integ // check fails. // %type refargs {int} |
︙ | ︙ | |||
316 317 318 319 320 321 322 323 324 325 326 327 328 329 | //////////////////////// The SELECT statement ///////////////////////////////// // cmd ::= select(X). { sqlite3Select(pParse, X, SRT_Callback, 0, 0, 0, 0, 0); sqlite3SelectDelete(X); } %type select {Select*} %destructor select {sqlite3SelectDelete($$);} %type oneselect {Select*} %destructor oneselect {sqlite3SelectDelete($$);} select(A) ::= oneselect(X). {A = X;} %ifndef SQLITE_OMIT_COMPOUND_SELECT | > > > > > > > > > > > > > > > | 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 | //////////////////////// The SELECT statement ///////////////////////////////// // cmd ::= select(X). { sqlite3Select(pParse, X, SRT_Callback, 0, 0, 0, 0, 0); sqlite3SelectDelete(X); } %ifndef SQLITE_OMIT_AUTOINCREMENT // The INTO clause after a select only works in nested mode. It causes // the result of the SELECT to be stored in a memory register of the // virtual machine. // cmd ::= select(X) INTO INTEGER(M). { if( pParse->nested ){ sqlite3Select(pParse, X, SRT_Mem, atoi(M.z), 0, 0, 0, 0); }else{ sqlite3ErrorMsg(pParse, "near \"INTO\": syntax error"); } sqlite3SelectDelete(X); } %endif // SQLITE_OMIT_AUTOINCREMENT %type select {Select*} %destructor select {sqlite3SelectDelete($$);} %type oneselect {Select*} %destructor oneselect {sqlite3SelectDelete($$);} select(A) ::= oneselect(X). {A = X;} %ifndef SQLITE_OMIT_COMPOUND_SELECT |
︙ | ︙ |
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.338 2004/11/12 03:56:15 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ /* ** These #defines should enable >2GB file support on Posix if the ** underlying operating system supports it. If the OS lacks |
︙ | ︙ | |||
1453 1454 1455 1456 1457 1458 1459 1460 1461 | void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, void(*)(void*)); void sqlite3ValueFree(sqlite3_value*); sqlite3_value *sqlite3ValueNew(); sqlite3_value *sqlite3GetTransientValue(sqlite3*db); extern const unsigned char sqlite3UpperToLower[]; void sqlite3RootPageMoved(Db*, int, int); void sqlite3Reindex(Parse*, Token*, Token*); #endif | > | 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 | void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, void(*)(void*)); void sqlite3ValueFree(sqlite3_value*); sqlite3_value *sqlite3ValueNew(); sqlite3_value *sqlite3GetTransientValue(sqlite3*db); extern const unsigned char sqlite3UpperToLower[]; void sqlite3RootPageMoved(Db*, int, int); void sqlite3Reindex(Parse*, Token*, Token*); void sqlite3NestedParse(Parse*, const char*, ...); #endif |
Changes to src/tokenize.c.
︙ | ︙ | |||
11 12 13 14 15 16 17 | ************************************************************************* ** An tokenizer for SQL ** ** This file contains C code that splits an SQL input string up into ** individual tokens and sends those tokens one-by-one over to the ** parser for analysis. ** | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | ************************************************************************* ** An tokenizer for SQL ** ** This file contains C code that splits an SQL input string up into ** individual tokens and sends those tokens one-by-one over to the ** parser for analysis. ** ** $Id: tokenize.c,v 1.96 2004/11/12 03:56:15 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> #include <stdlib.h> /* |
︙ | ︙ | |||
174 175 176 177 178 179 180 | return 1; } case '~': { *tokenType = TK_BITNOT; return 1; } case '#': { | | | 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | return 1; } case '~': { *tokenType = TK_BITNOT; return 1; } case '#': { for(i=1; isdigit(z[i]) || (i==1 && z[1]=='-'); i++){} *tokenType = TK_REGISTER; return i; } case '\'': case '"': { int delim = z[0]; for(i=1; (c=z[i])!=0; i++){ if( c==delim ){ |
︙ | ︙ | |||
405 406 407 408 409 410 411 | *pzErrMsg = pParse->zErrMsg; }else{ sqliteFree(pParse->zErrMsg); } pParse->zErrMsg = 0; if( !nErr ) nErr++; } | | | 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 | *pzErrMsg = pParse->zErrMsg; }else{ sqliteFree(pParse->zErrMsg); } pParse->zErrMsg = 0; if( !nErr ) nErr++; } if( pParse->pVdbe && pParse->nErr>0 && pParse->nested==0 ){ sqlite3VdbeDelete(pParse->pVdbe); pParse->pVdbe = 0; } sqlite3DeleteTable(pParse->db, pParse->pNewTable); sqlite3DeleteTrigger(pParse->pNewTrigger); sqliteFree(pParse->apVarExpr); if( nErr>0 && (pParse->rc==SQLITE_OK || pParse->rc==SQLITE_DONE) ){ |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
39 40 41 42 43 44 45 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** ** $Id: vdbe.c,v 1.426 2004/11/12 03:56:15 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> #include "vdbeInt.h" /* |
︙ | ︙ | |||
2818 2819 2820 2821 2822 2823 2824 | ** Get a new integer record number used as the key to a table. ** The record number is not previously used as a key in the database ** table that cursor P1 points to. The new record number is pushed ** onto the stack. ** ** If P2>0 then P2 is a memory cell that holds the largest previously ** generated record number. No new record numbers are allowed to be less | | | 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 | ** Get a new integer record number used as the key to a table. ** The record number is not previously used as a key in the database ** table that cursor P1 points to. The new record number is pushed ** onto the stack. ** ** If P2>0 then P2 is a memory cell that holds the largest previously ** generated record number. No new record numbers are allowed to be less ** than this value. When this value reaches its maximum, a SQLITE_FULL ** error is generated. The P2 memory cell is updated with the generated ** record number. This P2 mechanism is used to help implement the ** AUTOINCREMENT feature. */ case OP_NewRecno: { int i = pOp->p1; i64 v = 0; |
︙ | ︙ |