Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Everything is working on Linux. This is release 2.0-Alpha-1. (CVS 246) |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
14474fa144fe7c5dc63e0990d6cc92d7 |
User & Date: | drh 2001-09-15 00:57:28 |
Context
2001-09-15
| ||
00:58 | Release 2.0-alpha-1 (CVS 247) check-in: 264f2331 user: drh tags: trunk | |
00:57 | Everything is working on Linux. This is release 2.0-Alpha-1. (CVS 246) check-in: 14474fa1 user: drh tags: trunk | |
2001-09-14
| ||
18:54 | Added a PRAGMA statement. Took out the special comment parsing. (CVS 245) check-in: 5e372460 user: drh tags: trunk | |
Changes
Changes to src/TODO.
1 2 3 4 5 6 7 |
* Document all the changes and release Sqlite 2.0.
* Implement CLUSTER command like in PostgreSQL.
* "OPTIMIZE select" statement to automatically create indices and/or
invoke a CLUSTER command.
* "CREATE INDEX FOR select" to automatically generate needed indices.
* Implement a PRAGMA command
* Parse and use constraints.
|
< |
1 2 3 4 5 6 |
* Document all the changes and release Sqlite 2.0. * Implement CLUSTER command like in PostgreSQL. * "OPTIMIZE select" statement to automatically create indices and/or invoke a CLUSTER command. * "CREATE INDEX FOR select" to automatically generate needed indices. * Parse and use constraints. |
Changes to src/build.c.
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 .. 63 64 65 66 67 68 69 70 71 72 73 74 75 76 ... 274 275 276 277 278 279 280 281 282 283 284 285 286 287 ... 310 311 312 313 314 315 316 317 318 319 320 321 322 323 ... 394 395 396 397 398 399 400 401 402 403 404 405 406 407 ... 445 446 447 448 449 450 451 452 453 454 455 456 457 458 ... 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 ... 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 ... 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 ... 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 .... 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 .... 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 .... 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 |
** DROP TABLE ** CREATE INDEX ** DROP INDEX ** creating expressions and ID lists ** COPY ** VACUUM ** ** $Id: build.c,v 1.34 2001/09/14 18:54:08 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** This routine is called after a single SQL statement has been ** parsed and we want to execute the VDBE code to implement ................................................................................ &pParse->zErrMsg, db->pBusyArg, db->xBusyCallback); } sqliteVdbeDelete(pParse->pVdbe); pParse->pVdbe = 0; pParse->colNamesSet = 0; pParse->rc = rc; } } /* ** Construct a new expression node and return a pointer to it. */ Expr *sqliteExpr(int op, Expr *pLeft, Expr *pRight, Token *pToken){ ................................................................................ ** deallocation. ** ** See also: sqliteRollbackInternalChanges() */ void sqliteCommitInternalChanges(sqlite *db){ int i; if( (db->flags & SQLITE_InternChanges)==0 ) return; for(i=0; i<N_HASH; i++){ Table *pTable, *pNext; for(pTable = db->apTblHash[i]; pTable; pTable=pNext){ pNext = pTable->pHash; if( pTable->isDelete ){ sqliteUnlinkAndDeleteTable(db, pTable); }else if( pTable->isCommit==0 ){ ................................................................................ ** internal hash tables are undone. ** ** See also: sqliteCommitInternalChanges() */ void sqliteRollbackInternalChanges(sqlite *db){ int i; if( (db->flags & SQLITE_InternChanges)==0 ) return; for(i=0; i<N_HASH; i++){ Table *pTable, *pNext; for(pTable = db->apTblHash[i]; pTable; pTable=pNext){ pNext = pTable->pHash; if( !pTable->isCommit ){ sqliteUnlinkAndDeleteTable(db, pTable); }else if( pTable->isDelete ){ ................................................................................ pTable->pIndex = 0; if( pParse->pNewTable ) sqliteDeleteTable(db, pParse->pNewTable); pParse->pNewTable = pTable; if( !pParse->initFlag && (db->flags & SQLITE_InTrans)==0 ){ Vdbe *v = sqliteGetVdbe(pParse); if( v ){ sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0); } } } /* ** Add a new column to the table currently being constructed. ** ................................................................................ if( minusFlag ){ sqliteSetNString(pz, "-", 1, pVal->z, pVal->n, 0); }else{ sqliteSetNString(pz, pVal->z, pVal->n, 0); } sqliteDequote(*pz); } /* ** This routine is called to report the final ")" that terminates ** a CREATE TABLE statement. ** ** The table structure is added to the internal hash tables. ** ................................................................................ { OP_String, 0, 0, "table" }, { OP_String, 0, 0, 0}, /* 3 */ { OP_CreateTable, 0, 0, 0}, { OP_String, 0, 0, 0}, /* 5 */ { OP_String, 0, 0, 0}, /* 6 */ { OP_MakeRecord, 5, 0, 0}, { OP_Put, 0, 0, 0}, }; int n, base; Vdbe *v; v = sqliteGetVdbe(pParse); if( v==0 ) return; n = (int)pEnd->z - (int)pParse->sFirstToken.z + 1; base = sqliteVdbeAddOpList(v, ArraySize(addTable), addTable); sqliteVdbeChangeP3(v, base+3, p->zName, 0); sqliteVdbeTableRootAddr(v, &p->tnum); sqliteVdbeChangeP3(v, base+5, p->zName, 0); sqliteVdbeChangeP3(v, base+6, pParse->sFirstToken.z, n); sqliteVdbeAddOp(v, OP_Close, 0, 0, 0, 0); if( p->pIndex ){ /* If the table has a primary key, create an index in the database ** for that key. */ Index *pIndex = p->pIndex; assert( pIndex->pNext==0 ); assert( pIndex->tnum==0 ); ................................................................................ { OP_Next, 0, ADDR(9), 0}, /* 3 */ { OP_Dup, 0, 0, 0}, { OP_Column, 0, 3, 0}, { OP_Ne, 0, ADDR(3), 0}, { OP_Delete, 0, 0, 0}, { OP_Goto, 0, ADDR(3), 0}, { OP_Destroy, 0, 0, 0}, /* 9 */ { OP_Close, 0, 0, 0}, }; Index *pIdx; if( (db->flags & SQLITE_InTrans)==0 ){ sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0); } base = sqliteVdbeAddOpList(v, ArraySize(dropTable), dropTable); sqliteVdbeChangeP3(v, base+2, pTable->zName, 0); sqliteVdbeChangeP1(v, base+9, pTable->tnum); for(pIdx=pTable->pIndex; pIdx; pIdx=pIdx->pNext){ sqliteVdbeAddOp(v, OP_Destroy, pIdx->tnum, 0, 0, 0); } if( (db->flags & SQLITE_InTrans)==0 ){ sqliteVdbeAddOp(v, OP_Commit, 0, 0, 0, 0); } } ................................................................................ { OP_CreateIndex, 1, 0, 0}, { OP_Dup, 0, 0, 0}, { OP_Open, 1, 0, 0}, /* 6 */ { OP_String, 0, 0, 0}, /* 7 */ { OP_String, 0, 0, 0}, /* 8 */ { OP_MakeRecord, 5, 0, 0}, { OP_Put, 2, 0, 0}, { OP_Close, 2, 0, 0}, }; int n; Vdbe *v = pParse->pVdbe; int lbl1, lbl2; int i; v = sqliteGetVdbe(pParse); if( v==0 ) goto exit_create_index; if( pTable!=0 && (db->flags & SQLITE_InTrans)==0 ){ sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0); } if( pStart && pEnd ){ int base; n = (int)pEnd->z - (int)pStart->z + 1; base = sqliteVdbeAddOpList(v, ArraySize(addTable), addTable); sqliteVdbeChangeP3(v, base+3, pIndex->zName, 0); sqliteVdbeIndexRootAddr(v, &pIndex->tnum); sqliteVdbeChangeP3(v, base+6, pIndex->zName, 0); sqliteVdbeChangeP3(v, base+7, pTab->zName, 0); sqliteVdbeChangeP3(v, base+8, pStart->z, n); } sqliteVdbeAddOp(v, OP_Open, 0, pTab->tnum, pTab->zName, 0); lbl1 = sqliteVdbeMakeLabel(v); lbl2 = sqliteVdbeMakeLabel(v); sqliteVdbeAddOp(v, OP_Rewind, 0, 0, 0, 0); sqliteVdbeAddOp(v, OP_Next, 0, lbl2, 0, lbl1); sqliteVdbeAddOp(v, OP_Recno, 0, 0, 0, 0); ................................................................................ { OP_String, 0, 0, 0}, /* 2 */ { OP_Next, 0, ADDR(8), 0}, /* 3 */ { OP_Dup, 0, 0, 0}, { OP_Column, 0, 1, 0}, { OP_Ne, 0, ADDR(3), 0}, { OP_Delete, 0, 0, 0}, { OP_Destroy, 0, 0, 0}, /* 8 */ { OP_Close, 0, 0, 0}, }; int base; if( (db->flags & SQLITE_InTrans)==0 ){ sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0); } base = sqliteVdbeAddOpList(v, ArraySize(dropIndex), dropIndex); sqliteVdbeChangeP3(v, base+2, pIndex->zName, 0); sqliteVdbeChangeP1(v, base+8, pIndex->tnum); if( (db->flags & SQLITE_InTrans)==0 ){ sqliteVdbeAddOp(v, OP_Commit, 0, 0, 0, 0); } } /* Mark the internal Index structure for deletion by the ** sqliteCommitInternalChanges routine. ................................................................................ pParse->nErr++; goto copy_cleanup; } v = sqliteGetVdbe(pParse); if( v ){ if( (db->flags & SQLITE_InTrans)==0 ){ sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0); } addr = sqliteVdbeAddOp(v, OP_FileOpen, 0, 0, 0, 0); sqliteVdbeChangeP3(v, addr, pFilename->z, pFilename->n); sqliteVdbeDequoteP3(v, addr); sqliteVdbeAddOp(v, OP_Open, 0, pTab->tnum, pTab->zName, 0); for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ sqliteVdbeAddOp(v, OP_Open, i, pIdx->tnum, pIdx->zName, 0); ................................................................................ pParse->nErr++; goto vacuum_cleanup; } v = sqliteGetVdbe(pParse); if( v==0 ) goto vacuum_cleanup; if( (db->flags & SQLITE_InTrans)==0 ){ sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0); } if( zName ){ sqliteVdbeAddOp(v, OP_Reorganize, 0, 0, zName, 0); }else{ int h; Table *pTab; Index *pIdx; ................................................................................ if( pParse==0 || (db=pParse->db)==0 || db->pBe==0 ) return; if( pParse->nErr || sqlite_malloc_failed ) return; if( db->flags & SQLITE_InTrans ) return; v = sqliteGetVdbe(pParse); if( v ){ sqliteVdbeAddOp(v, OP_Transaction, 1, 0, 0, 0); } db->flags |= SQLITE_InTrans; } /* ** Commit a transaction */ |
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 .. 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 ... 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 ... 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 ... 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 ... 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 ... 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 ... 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 ... 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 ... 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 .... 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 .... 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 .... 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 |
** DROP TABLE ** CREATE INDEX ** DROP INDEX ** creating expressions and ID lists ** COPY ** VACUUM ** ** $Id: build.c,v 1.35 2001/09/15 00:57:28 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** This routine is called after a single SQL statement has been ** parsed and we want to execute the VDBE code to implement ................................................................................ &pParse->zErrMsg, db->pBusyArg, db->xBusyCallback); } sqliteVdbeDelete(pParse->pVdbe); pParse->pVdbe = 0; pParse->colNamesSet = 0; pParse->rc = rc; pParse->schemaVerified = 0; } } /* ** Construct a new expression node and return a pointer to it. */ Expr *sqliteExpr(int op, Expr *pLeft, Expr *pRight, Token *pToken){ ................................................................................ ** deallocation. ** ** See also: sqliteRollbackInternalChanges() */ void sqliteCommitInternalChanges(sqlite *db){ int i; if( (db->flags & SQLITE_InternChanges)==0 ) return; db->schema_cookie = db->next_cookie; for(i=0; i<N_HASH; i++){ Table *pTable, *pNext; for(pTable = db->apTblHash[i]; pTable; pTable=pNext){ pNext = pTable->pHash; if( pTable->isDelete ){ sqliteUnlinkAndDeleteTable(db, pTable); }else if( pTable->isCommit==0 ){ ................................................................................ ** internal hash tables are undone. ** ** See also: sqliteCommitInternalChanges() */ void sqliteRollbackInternalChanges(sqlite *db){ int i; if( (db->flags & SQLITE_InternChanges)==0 ) return; db->next_cookie = db->schema_cookie; for(i=0; i<N_HASH; i++){ Table *pTable, *pNext; for(pTable = db->apTblHash[i]; pTable; pTable=pNext){ pNext = pTable->pHash; if( !pTable->isCommit ){ sqliteUnlinkAndDeleteTable(db, pTable); }else if( pTable->isDelete ){ ................................................................................ pTable->pIndex = 0; if( pParse->pNewTable ) sqliteDeleteTable(db, pParse->pNewTable); pParse->pNewTable = pTable; if( !pParse->initFlag && (db->flags & SQLITE_InTrans)==0 ){ Vdbe *v = sqliteGetVdbe(pParse); if( v ){ sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0); sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0, 0, 0); } } } /* ** Add a new column to the table currently being constructed. ** ................................................................................ if( minusFlag ){ sqliteSetNString(pz, "-", 1, pVal->z, pVal->n, 0); }else{ sqliteSetNString(pz, pVal->z, pVal->n, 0); } sqliteDequote(*pz); } /* ** Come up with a new random value for the schema cookie. Make sure ** the new value is different from the old. ** ** The schema cookie is used to determine when the schema for the ** database changes. After each schema change, the cookie value ** changes. When a process first reads the schema it records the ** cookie. Thereafter, whenever it goes to access the database, ** it checks the cookie to make sure the schema has not changed ** since it was last read. ** ** This plan is not completely bullet-proof. It is possible for ** the schema to change multiple times and for the cookie to be ** set back to prior value. But schema changes are infrequent ** and the probability of hitting the same cookie value is only ** 1 chance in 2^32. So we're safe enough. */ static void changeCookie(sqlite *db){ if( db->next_cookie==db->schema_cookie ){ db->next_cookie = db->schema_cookie + sqliteRandomByte() + 1; db->flags |= SQLITE_InternChanges; } } /* ** This routine is called to report the final ")" that terminates ** a CREATE TABLE statement. ** ** The table structure is added to the internal hash tables. ** ................................................................................ { OP_String, 0, 0, "table" }, { OP_String, 0, 0, 0}, /* 3 */ { OP_CreateTable, 0, 0, 0}, { OP_String, 0, 0, 0}, /* 5 */ { OP_String, 0, 0, 0}, /* 6 */ { OP_MakeRecord, 5, 0, 0}, { OP_Put, 0, 0, 0}, { OP_SetCookie, 0, 0, 0}, /* 9 */ }; int n, base; Vdbe *v; v = sqliteGetVdbe(pParse); if( v==0 ) return; n = (int)pEnd->z - (int)pParse->sFirstToken.z + 1; base = sqliteVdbeAddOpList(v, ArraySize(addTable), addTable); sqliteVdbeChangeP3(v, base+3, p->zName, 0); sqliteVdbeTableRootAddr(v, &p->tnum); sqliteVdbeChangeP3(v, base+5, p->zName, 0); sqliteVdbeChangeP3(v, base+6, pParse->sFirstToken.z, n); changeCookie(db); sqliteVdbeChangeP1(v, base+9, db->next_cookie); sqliteVdbeAddOp(v, OP_Close, 0, 0, 0, 0); if( p->pIndex ){ /* If the table has a primary key, create an index in the database ** for that key. */ Index *pIndex = p->pIndex; assert( pIndex->pNext==0 ); assert( pIndex->tnum==0 ); ................................................................................ { OP_Next, 0, ADDR(9), 0}, /* 3 */ { OP_Dup, 0, 0, 0}, { OP_Column, 0, 3, 0}, { OP_Ne, 0, ADDR(3), 0}, { OP_Delete, 0, 0, 0}, { OP_Goto, 0, ADDR(3), 0}, { OP_Destroy, 0, 0, 0}, /* 9 */ { OP_SetCookie, 0, 0, 0}, /* 10 */ { OP_Close, 0, 0, 0}, }; Index *pIdx; if( (db->flags & SQLITE_InTrans)==0 ){ sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0); sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0, 0, 0); } base = sqliteVdbeAddOpList(v, ArraySize(dropTable), dropTable); sqliteVdbeChangeP3(v, base+2, pTable->zName, 0); sqliteVdbeChangeP1(v, base+9, pTable->tnum); changeCookie(db); sqliteVdbeChangeP1(v, base+10, db->next_cookie); for(pIdx=pTable->pIndex; pIdx; pIdx=pIdx->pNext){ sqliteVdbeAddOp(v, OP_Destroy, pIdx->tnum, 0, 0, 0); } if( (db->flags & SQLITE_InTrans)==0 ){ sqliteVdbeAddOp(v, OP_Commit, 0, 0, 0, 0); } } ................................................................................ { OP_CreateIndex, 1, 0, 0}, { OP_Dup, 0, 0, 0}, { OP_Open, 1, 0, 0}, /* 6 */ { OP_String, 0, 0, 0}, /* 7 */ { OP_String, 0, 0, 0}, /* 8 */ { OP_MakeRecord, 5, 0, 0}, { OP_Put, 2, 0, 0}, { OP_SetCookie, 0, 0, 0}, /* 11 */ { OP_Close, 2, 0, 0}, }; int n; Vdbe *v = pParse->pVdbe; int lbl1, lbl2; int i; v = sqliteGetVdbe(pParse); if( v==0 ) goto exit_create_index; if( pTable!=0 && (db->flags & SQLITE_InTrans)==0 ){ sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0); sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0, 0, 0); } if( pStart && pEnd ){ int base; n = (int)pEnd->z - (int)pStart->z + 1; base = sqliteVdbeAddOpList(v, ArraySize(addTable), addTable); sqliteVdbeChangeP3(v, base+3, pIndex->zName, 0); sqliteVdbeIndexRootAddr(v, &pIndex->tnum); sqliteVdbeChangeP3(v, base+6, pIndex->zName, 0); sqliteVdbeChangeP3(v, base+7, pTab->zName, 0); sqliteVdbeChangeP3(v, base+8, pStart->z, n); changeCookie(db); sqliteVdbeChangeP1(v, base+11, db->next_cookie); } sqliteVdbeAddOp(v, OP_Open, 0, pTab->tnum, pTab->zName, 0); lbl1 = sqliteVdbeMakeLabel(v); lbl2 = sqliteVdbeMakeLabel(v); sqliteVdbeAddOp(v, OP_Rewind, 0, 0, 0, 0); sqliteVdbeAddOp(v, OP_Next, 0, lbl2, 0, lbl1); sqliteVdbeAddOp(v, OP_Recno, 0, 0, 0, 0); ................................................................................ { OP_String, 0, 0, 0}, /* 2 */ { OP_Next, 0, ADDR(8), 0}, /* 3 */ { OP_Dup, 0, 0, 0}, { OP_Column, 0, 1, 0}, { OP_Ne, 0, ADDR(3), 0}, { OP_Delete, 0, 0, 0}, { OP_Destroy, 0, 0, 0}, /* 8 */ { OP_SetCookie, 0, 0, 0}, /* 9 */ { OP_Close, 0, 0, 0}, }; int base; if( (db->flags & SQLITE_InTrans)==0 ){ sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0); sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0, 0, 0); } base = sqliteVdbeAddOpList(v, ArraySize(dropIndex), dropIndex); sqliteVdbeChangeP3(v, base+2, pIndex->zName, 0); sqliteVdbeChangeP1(v, base+8, pIndex->tnum); changeCookie(db); sqliteVdbeChangeP1(v, base+9, db->next_cookie); if( (db->flags & SQLITE_InTrans)==0 ){ sqliteVdbeAddOp(v, OP_Commit, 0, 0, 0, 0); } } /* Mark the internal Index structure for deletion by the ** sqliteCommitInternalChanges routine. ................................................................................ pParse->nErr++; goto copy_cleanup; } v = sqliteGetVdbe(pParse); if( v ){ if( (db->flags & SQLITE_InTrans)==0 ){ sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0); sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0, 0, 0); } addr = sqliteVdbeAddOp(v, OP_FileOpen, 0, 0, 0, 0); sqliteVdbeChangeP3(v, addr, pFilename->z, pFilename->n); sqliteVdbeDequoteP3(v, addr); sqliteVdbeAddOp(v, OP_Open, 0, pTab->tnum, pTab->zName, 0); for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ sqliteVdbeAddOp(v, OP_Open, i, pIdx->tnum, pIdx->zName, 0); ................................................................................ pParse->nErr++; goto vacuum_cleanup; } v = sqliteGetVdbe(pParse); if( v==0 ) goto vacuum_cleanup; if( (db->flags & SQLITE_InTrans)==0 ){ sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0); sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0, 0, 0); } if( zName ){ sqliteVdbeAddOp(v, OP_Reorganize, 0, 0, zName, 0); }else{ int h; Table *pTab; Index *pIdx; ................................................................................ if( pParse==0 || (db=pParse->db)==0 || db->pBe==0 ) return; if( pParse->nErr || sqlite_malloc_failed ) return; if( db->flags & SQLITE_InTrans ) return; v = sqliteGetVdbe(pParse); if( v ){ sqliteVdbeAddOp(v, OP_Transaction, 1, 0, 0, 0); sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0, 0, 0); } db->flags |= SQLITE_InTrans; } /* ** Commit a transaction */ |
Changes to src/delete.c.
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
..
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle DELETE FROM statements. ** ** $Id: delete.c,v 1.12 2001/09/13 21:53:10 drh Exp $ */ #include "sqliteInt.h" /* ** Process a DELETE FROM statement. */ void sqliteDeleteFrom( ................................................................................ /* Begin generating code. */ v = sqliteGetVdbe(pParse); if( v==0 ) goto delete_from_cleanup; if( (pParse->db->flags & SQLITE_InTrans)==0 ){ sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0); } /* Special case: A DELETE without a WHERE clause deletes everything. ** It is easier just to clear all information the database tables directly. */ if( pWhere==0 ){ |
|
>
|
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
..
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle DELETE FROM statements. ** ** $Id: delete.c,v 1.13 2001/09/15 00:57:29 drh Exp $ */ #include "sqliteInt.h" /* ** Process a DELETE FROM statement. */ void sqliteDeleteFrom( ................................................................................ /* Begin generating code. */ v = sqliteGetVdbe(pParse); if( v==0 ) goto delete_from_cleanup; if( (pParse->db->flags & SQLITE_InTrans)==0 ){ sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0); sqliteVdbeAddOp(v, OP_VerifyCookie, pParse->db->schema_cookie, 0, 0, 0); } /* Special case: A DELETE without a WHERE clause deletes everything. ** It is easier just to clear all information the database tables directly. */ if( pWhere==0 ){ |
Changes to src/insert.c.
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
..
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle INSERT statements. ** ** $Id: insert.c,v 1.16 2001/09/14 03:24:25 drh Exp $ */ #include "sqliteInt.h" /* ** This routine is call to handle SQL of the following forms: ** ** insert into TABLE (IDLIST) values(EXPRLIST) ................................................................................ /* Allocate a VDBE */ v = sqliteGetVdbe(pParse); if( v==0 ) goto insert_cleanup; if( (pParse->db->flags & SQLITE_InTrans)==0 ){ sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0); } /* Figure out how many columns of data are supplied. If the data ** is comming from a SELECT statement, then this step has to generate ** all the code to implement the SELECT statement and leave the data ** in a temporary table. If data is coming from an expression list, ** then we just have to count the number of expressions. |
|
>
|
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
..
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle INSERT statements. ** ** $Id: insert.c,v 1.17 2001/09/15 00:57:29 drh Exp $ */ #include "sqliteInt.h" /* ** This routine is call to handle SQL of the following forms: ** ** insert into TABLE (IDLIST) values(EXPRLIST) ................................................................................ /* Allocate a VDBE */ v = sqliteGetVdbe(pParse); if( v==0 ) goto insert_cleanup; if( (pParse->db->flags & SQLITE_InTrans)==0 ){ sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0); sqliteVdbeAddOp(v, OP_VerifyCookie, pParse->db->schema_cookie, 0, 0, 0); } /* Figure out how many columns of data are supplied. If the data ** is comming from a SELECT statement, then this step has to generate ** all the code to implement the SELECT statement and leave the data ** in a temporary table. If data is coming from an expression list, ** then we just have to count the number of expressions. |
Changes to src/main.c.
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 .. 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 ... 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 ... 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 ... 383 384 385 386 387 388 389 390 391 392 393 394 395 396 |
** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** ** $Id: main.c,v 1.35 2001/09/14 16:42:12 drh Exp $ */ #include "sqliteInt.h" #if defined(HAVE_USLEEP) && HAVE_USLEEP #include <unistd.h> #endif /* ................................................................................ sqlite *db = (sqlite*)pDb; Parse sParse; int nErr = 0; assert( argc==4 ); switch( argv[0][0] ){ case 'm': { /* Meta information */ sscanf(argv[1],"file format %d",&db->file_format); break; } case 'i': case 't': { /* CREATE TABLE and CREATE INDEX statements */ memset(&sParse, 0, sizeof(sParse)); sParse.db = db; sParse.initFlag = 1; ................................................................................ { OP_Ne, 0, 24, 0}, { OP_Column, 0, 0, 0}, { OP_Column, 0, 1, 0}, { OP_Column, 0, 2, 0}, { OP_Column, 0, 4, 0}, { OP_Callback, 4, 0, 0}, { OP_Goto, 0, 24, 0}, { OP_Close, 0, 0, 0}, /* 34 */ { OP_Halt, 0, 0, 0}, }; /* Create a virtual machine to run the initialization program. Run ** the program. The delete the virtual machine. */ vdbe = sqliteVdbeCreate(db); ................................................................................ no_mem_on_open: sqliteSetString(pzErrMsg, "out of memory", 0); sqliteStrRealloc(pzErrMsg); return 0; } /* ** Close an existing SQLite database */ void sqlite_close(sqlite *db){ int i; sqliteBtreeClose(db->pBe); for(i=0; i<N_HASH; i++){ Table *pNext, *pList = db->apTblHash[i]; db->apTblHash[i] = 0; while( pList ){ pNext = pList->pHash; pList->pHash = 0; sqliteDeleteTable(db, pList); pList = pNext; } } sqliteFree(db); } /* ** Return TRUE if the given SQL string ends in a semicolon. */ int sqlite_complete(const char *zSql){ ................................................................................ sParse.pArg = pArg; sqliteRunParser(&sParse, zSql, pzErrMsg); if( sqlite_malloc_failed ){ sqliteSetString(pzErrMsg, "out of memory", 0); sParse.rc = SQLITE_NOMEM; } sqliteStrRealloc(pzErrMsg); return sParse.rc; } /* ** This routine implements a busy callback that sleeps and tries ** again until a timeout value is reached. The timeout value is ** an integer number of milliseconds passed in as the first |
| > | > > > > > > > > > | | > > > > > > | < > > > > > > > > > > > > |
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 .. 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 ... 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 ... 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 ... 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 |
** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** ** $Id: main.c,v 1.36 2001/09/15 00:57:29 drh Exp $ */ #include "sqliteInt.h" #if defined(HAVE_USLEEP) && HAVE_USLEEP #include <unistd.h> #endif /* ................................................................................ sqlite *db = (sqlite*)pDb; Parse sParse; int nErr = 0; assert( argc==4 ); switch( argv[0][0] ){ case 'm': { /* Meta information */ if( strcmp(argv[1],"file-format")==0 ){ db->file_format = atoi(argv[3]); }else if( strcmp(argv[1],"schema-cookie")==0 ){ db->schema_cookie = atoi(argv[3]); db->next_cookie = db->schema_cookie; } break; } case 'i': case 't': { /* CREATE TABLE and CREATE INDEX statements */ memset(&sParse, 0, sizeof(sParse)); sParse.db = db; sParse.initFlag = 1; ................................................................................ { OP_Ne, 0, 24, 0}, { OP_Column, 0, 0, 0}, { OP_Column, 0, 1, 0}, { OP_Column, 0, 2, 0}, { OP_Column, 0, 4, 0}, { OP_Callback, 4, 0, 0}, { OP_Goto, 0, 24, 0}, { OP_String, 0, 0, "meta"}, /* 34 */ { OP_String, 0, 0, "schema-cookie"}, { OP_String, 0, 0, ""}, { OP_ReadCookie,0,0, 0}, { OP_Callback, 4, 0, 0}, { OP_Close, 0, 0, 0}, { OP_Halt, 0, 0, 0}, }; /* Create a virtual machine to run the initialization program. Run ** the program. The delete the virtual machine. */ vdbe = sqliteVdbeCreate(db); ................................................................................ no_mem_on_open: sqliteSetString(pzErrMsg, "out of memory", 0); sqliteStrRealloc(pzErrMsg); return 0; } /* ** Erase all schema information from the schema hash table. ** ** The database schema is normally read in once when the database ** is first opened and stored in a hash table in the sqlite structure. ** This routine erases the stored schema. This erasure occurs because ** either the database is being closed or because some other process ** changed the schema and this process needs to reread it. */ static void clearHashTable(sqlite *db){ int i; for(i=0; i<N_HASH; i++){ Table *pNext, *pList = db->apTblHash[i]; db->apTblHash[i] = 0; while( pList ){ pNext = pList->pHash; pList->pHash = 0; sqliteDeleteTable(db, pList); pList = pNext; } } db->flags &= ~SQLITE_Initialized; } /* ** Close an existing SQLite database */ void sqlite_close(sqlite *db){ sqliteBtreeClose(db->pBe); clearHashTable(db); sqliteFree(db); } /* ** Return TRUE if the given SQL string ends in a semicolon. */ int sqlite_complete(const char *zSql){ ................................................................................ sParse.pArg = pArg; sqliteRunParser(&sParse, zSql, pzErrMsg); if( sqlite_malloc_failed ){ sqliteSetString(pzErrMsg, "out of memory", 0); sParse.rc = SQLITE_NOMEM; } sqliteStrRealloc(pzErrMsg); if( sParse.rc==SQLITE_SCHEMA ){ clearHashTable(db); } return sParse.rc; } /* ** This routine implements a busy callback that sleeps and tries ** again until a timeout value is reached. The timeout value is ** an integer number of milliseconds passed in as the first |
Changes to src/pager.c.
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 ... 678 679 680 681 682 683 684 685 686 687 688 689 690 691 ... 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 ... 821 822 823 824 825 826 827 828 829 830 831 832 833 834 |
************************************************************************* ** This is the implementation of the page cache subsystem. ** ** The page cache is used to access a database file. The pager journals ** all writes in order to support rollback. Locking is used to limit ** access to one or more reader or to one writer. ** ** @(#) $Id: pager.c,v 1.18 2001/09/14 18:54:09 drh Exp $ */ #include "sqliteInt.h" #include "pager.h" #include <fcntl.h> #include <sys/stat.h> #include <unistd.h> #include <assert.h> ................................................................................ ** a reference to the page data. */ int sqlitepager_ref(void *pData){ PgHdr *pPg = DATA_TO_PGHDR(pData); page_ref(pPg); return SQLITE_OK; } /* ** Acquire a page. ** ** A read lock on the disk file is obtained when the first page acquired. ** This read lock is dropped when the last page is released. ** ................................................................................ pPg->pPrevAll = 0; pPager->pAll = pPg; pPager->nPage++; }else{ /* Recycle an older page. First locate the page to be recycled. ** Try to find one that is not dirty and is near the head of ** of the free list */ /* int cnt = pPager->mxPage/2; */ int cnt = 10; pPg = pPager->pFirst; while( pPg->dirty && 0<cnt-- && pPg->pNextFree ){ pPg = pPg->pNextFree; } if( pPg==0 || pPg->dirty ) pPg = pPager->pFirst; assert( pPg->nRef==0 ); /* If the page to be recycled is dirty, sync the journal and write ** the old page into the database. */ if( pPg->dirty ){ int rc; assert( pPg->inJournal==1 ); assert( pPager->state==SQLITE_WRITELOCK ); if( pPager->needSync ){ ................................................................................ if( rc!=SQLITE_OK ){ rc = sqlitepager_rollback(pPager); *ppPage = 0; if( rc==SQLITE_OK ) rc = SQLITE_FULL; return rc; } } /* Unlink the old page from the free list and the hash table */ if( pPg->pPrevFree ){ pPg->pPrevFree->pNextFree = pPg->pNextFree; }else{ assert( pPager->pFirst==pPg ); |
| > > > > > > > > > > > > > > > > > > > > > > | < | > > > > > > > > > > > > > > > > |
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 ... 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 ... 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 ... 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 |
************************************************************************* ** This is the implementation of the page cache subsystem. ** ** The page cache is used to access a database file. The pager journals ** all writes in order to support rollback. Locking is used to limit ** access to one or more reader or to one writer. ** ** @(#) $Id: pager.c,v 1.19 2001/09/15 00:57:29 drh Exp $ */ #include "sqliteInt.h" #include "pager.h" #include <fcntl.h> #include <sys/stat.h> #include <unistd.h> #include <assert.h> ................................................................................ ** a reference to the page data. */ int sqlitepager_ref(void *pData){ PgHdr *pPg = DATA_TO_PGHDR(pData); page_ref(pPg); return SQLITE_OK; } /* ** Sync the journal and write all free dirty pages to the database file. */ static int syncAllPages(Pager *pPager){ PgHdr *pPg; int rc = SQLITE_OK; if( pPager->needSync ){ rc = fsync(pPager->jfd); if( rc!=0 ) return rc; pPager->needSync = 0; } for(pPg=pPager->pFirst; pPg; pPg=pPg->pNextFree){ if( pPg->dirty ){ pager_seek(pPager->fd, (pPg->pgno-1)*SQLITE_PAGE_SIZE); rc = pager_write(pPager->fd, PGHDR_TO_DATA(pPg), SQLITE_PAGE_SIZE); if( rc!=SQLITE_OK ) break; pPg->dirty = 0; } } return SQLITE_OK; } /* ** Acquire a page. ** ** A read lock on the disk file is obtained when the first page acquired. ** This read lock is dropped when the last page is released. ** ................................................................................ pPg->pPrevAll = 0; pPager->pAll = pPg; pPager->nPage++; }else{ /* Recycle an older page. First locate the page to be recycled. ** Try to find one that is not dirty and is near the head of ** of the free list */ int cnt = pPager->mxPage/2; pPg = pPager->pFirst; while( pPg->dirty && 0<cnt-- && pPg->pNextFree ){ pPg = pPg->pNextFree; } if( pPg==0 || pPg->dirty ){ int rc = syncAllPages(pPager); if( rc!=0 ){ sqlitepager_rollback(pPager); *ppPage = 0; return SQLITE_IOERR; } pPg = pPager->pFirst; } assert( pPg->nRef==0 ); #if 0 /**** Since putting in the call to syncAllPages() above, this code ** is no longer used. I've kept it here for historical reference ** only. */ /* If the page to be recycled is dirty, sync the journal and write ** the old page into the database. */ if( pPg->dirty ){ int rc; assert( pPg->inJournal==1 ); assert( pPager->state==SQLITE_WRITELOCK ); if( pPager->needSync ){ ................................................................................ if( rc!=SQLITE_OK ){ rc = sqlitepager_rollback(pPager); *ppPage = 0; if( rc==SQLITE_OK ) rc = SQLITE_FULL; return rc; } } #endif assert( pPg->dirty==0 ); /* Unlink the old page from the free list and the hash table */ if( pPg->pPrevFree ){ pPg->pPrevFree->pNextFree = pPg->pNextFree; }else{ assert( pPager->pFirst==pPg ); |
Changes to src/sqlite.h.in.
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
...
156
157
158
159
160
161
162
163
164
165
166
167
168
169
|
** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ************************************************************************* ** This header file defines the interface that the sqlite library ** presents to client programs. ** ** @(#) $Id: sqlite.h.in,v 1.14 2001/09/13 13:46:57 drh Exp $ */ #ifndef _SQLITE_H_ #define _SQLITE_H_ #include <stdarg.h> /* Needed for the definition of va_list */ /* ** The version of the SQLite library. ................................................................................ #define SQLITE_IOERR 9 /* Disk full or other I/O error */ #define SQLITE_CORRUPT 10 /* The database disk image is malformed */ #define SQLITE_NOTFOUND 11 /* Table or record not found */ #define SQLITE_FULL 12 /* Insertion failed because database is full */ #define SQLITE_CANTOPEN 13 /* Unable to open the database file */ #define SQLITE_PROTOCOL 14 /* Database lock protocol error */ #define SQLITE_EMPTY 15 /* Database table is empty */ /* This function causes any pending database operation to abort and ** return at its earliest opportunity. This routine is typically ** called in response to a user action such as pressing "Cancel" ** or Ctrl-C where the user wants a long query operation to halt ** immediately. */ |
|
>
|
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
...
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
|
** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ************************************************************************* ** This header file defines the interface that the sqlite library ** presents to client programs. ** ** @(#) $Id: sqlite.h.in,v 1.15 2001/09/15 00:57:29 drh Exp $ */ #ifndef _SQLITE_H_ #define _SQLITE_H_ #include <stdarg.h> /* Needed for the definition of va_list */ /* ** The version of the SQLite library. ................................................................................ #define SQLITE_IOERR 9 /* Disk full or other I/O error */ #define SQLITE_CORRUPT 10 /* The database disk image is malformed */ #define SQLITE_NOTFOUND 11 /* Table or record not found */ #define SQLITE_FULL 12 /* Insertion failed because database is full */ #define SQLITE_CANTOPEN 13 /* Unable to open the database file */ #define SQLITE_PROTOCOL 14 /* Database lock protocol error */ #define SQLITE_EMPTY 15 /* Database table is empty */ #define SQLITE_SCHEMA 16 /* The database schema changed */ /* This function causes any pending database operation to abort and ** return at its earliest opportunity. This routine is typically ** called in response to a user action such as pressing "Cancel" ** or Ctrl-C where the user wants a long query operation to halt ** immediately. */ |
Changes to src/sqliteInt.h.
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 ... 139 140 141 142 143 144 145 146 147 148 149 150 151 152 ... 372 373 374 375 376 377 378 379 380 381 382 383 384 385 |
** Author contact information: ** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ************************************************************************* ** Internal interface definitions for SQLite. ** ** @(#) $Id: sqliteInt.h,v 1.47 2001/09/14 18:54:09 drh Exp $ */ #include "sqlite.h" #include "vdbe.h" #include "parse.h" #include "btree.h" #include <stdio.h> #include <stdlib.h> ................................................................................ /* ** Each database is an instance of the following structure */ struct sqlite { Btree *pBe; /* The B*Tree backend */ int flags; /* Miscellanous flags. See below */ int file_format; /* What file format version is this database? */ int nTable; /* Number of tables in the database */ void *pBusyArg; /* 1st Argument to the busy callback */ int (*xBusyCallback)(void *,const char*,int); /* The busy callback */ Table *apTblHash[N_HASH]; /* All tables of the database */ Index *apIdxHash[N_HASH]; /* All indices of the database */ }; ................................................................................ int nMem; /* Number of memory cells used so far */ int nSet; /* Number of sets used so far */ int nAgg; /* Number of aggregate expressions */ AggExpr *aAgg; /* An array of aggregate expressions */ int iAggCount; /* Index of the count(*) aggregate in aAgg[] */ int useAgg; /* If true, extract field values from the aggregator ** while generating expressions. Normally false */ }; /* ** Internal function prototypes */ int sqliteStrICmp(const char *, const char *); int sqliteStrNICmp(const char *, const char *, int); |
| > > > > |
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 ... 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 ... 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 |
** Author contact information: ** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ************************************************************************* ** Internal interface definitions for SQLite. ** ** @(#) $Id: sqliteInt.h,v 1.48 2001/09/15 00:57:29 drh Exp $ */ #include "sqlite.h" #include "vdbe.h" #include "parse.h" #include "btree.h" #include <stdio.h> #include <stdlib.h> ................................................................................ /* ** Each database is an instance of the following structure */ struct sqlite { Btree *pBe; /* The B*Tree backend */ int flags; /* Miscellanous flags. See below */ int file_format; /* What file format version is this database? */ int schema_cookie; /* Magic number that changes with the schema */ int next_cookie; /* Value of schema_cookie after commit */ int nTable; /* Number of tables in the database */ void *pBusyArg; /* 1st Argument to the busy callback */ int (*xBusyCallback)(void *,const char*,int); /* The busy callback */ Table *apTblHash[N_HASH]; /* All tables of the database */ Index *apIdxHash[N_HASH]; /* All indices of the database */ }; ................................................................................ int nMem; /* Number of memory cells used so far */ int nSet; /* Number of sets used so far */ int nAgg; /* Number of aggregate expressions */ AggExpr *aAgg; /* An array of aggregate expressions */ int iAggCount; /* Index of the count(*) aggregate in aAgg[] */ int useAgg; /* If true, extract field values from the aggregator ** while generating expressions. Normally false */ int schemaVerified; /* True if an OP_VerifySchema has been coded someplace ** other than after an OP_Transaction */ }; /* ** Internal function prototypes */ int sqliteStrICmp(const char *, const char *); int sqliteStrNICmp(const char *, const char *, int); |
Changes to src/update.c.
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
...
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle UPDATE statements. ** ** $Id: update.c,v 1.12 2001/09/13 13:46:57 drh Exp $ */ #include "sqliteInt.h" /* ** Process an UPDATE statement. */ void sqliteUpdate( ................................................................................ /* Begin generating code. */ v = sqliteGetVdbe(pParse); if( v==0 ) goto update_cleanup; if( (pParse->db->flags & SQLITE_InTrans)==0 ){ sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0); } /* Begin the database scan */ sqliteVdbeAddOp(v, OP_ListOpen, 0, 0, 0, 0); pWInfo = sqliteWhereBegin(pParse, pTabList, pWhere, 1); if( pWInfo==0 ) goto update_cleanup; |
|
>
|
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
...
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
|
** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle UPDATE statements. ** ** $Id: update.c,v 1.13 2001/09/15 00:57:29 drh Exp $ */ #include "sqliteInt.h" /* ** Process an UPDATE statement. */ void sqliteUpdate( ................................................................................ /* Begin generating code. */ v = sqliteGetVdbe(pParse); if( v==0 ) goto update_cleanup; if( (pParse->db->flags & SQLITE_InTrans)==0 ){ sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0); sqliteVdbeAddOp(v, OP_VerifyCookie, pParse->db->schema_cookie, 0, 0, 0); } /* Begin the database scan */ sqliteVdbeAddOp(v, OP_ListOpen, 0, 0, 0, 0); pWInfo = sqliteWhereBegin(pParse, pTabList, pWhere, 1); if( pWInfo==0 ) goto update_cleanup; |
Changes to src/util.c.
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
...
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
|
** ************************************************************************* ** Utility functions used throughout sqlite. ** ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** ** $Id: util.c,v 1.22 2001/09/13 13:46:57 drh Exp $ */ #include "sqliteInt.h" #include <stdarg.h> #include <ctype.h> /* ** If malloc() ever fails, this global variable gets set to 1. ................................................................................ } /* ** Return a static string that describes the kind of error specified in the ** argument. */ const char *sqliteErrStr(int rc){ char *z = 0; switch( rc ){ case SQLITE_OK: z = "not an error"; break; case SQLITE_ERROR: z = "SQL logic error or missing database"; break; case SQLITE_INTERNAL: z = "internal SQLite implementation flaw"; break; case SQLITE_PERM: z = "access permission denied"; break; case SQLITE_ABORT: z = "callback requested query abort"; break; case SQLITE_BUSY: z = "database in use by another process"; break; case SQLITE_NOMEM: z = "out of memory"; break; case SQLITE_READONLY: z = "attempt to write a readonly database"; break; case SQLITE_INTERRUPT: z = "interrupted"; break; case SQLITE_IOERR: z = "disk I/O error"; break; case SQLITE_CORRUPT: z = "database disk image is malformed"; break; case SQLITE_NOTFOUND: z = "table or record not found"; break; case SQLITE_FULL: z = "database is full"; break; case SQLITE_CANTOPEN: z = "unable to open database file"; break; case SQLITE_PROTOCOL: z = "database locking protocol failure"; break; case SQLITE_EMPTY: z = "table contains no data"; default: } return z; } |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
...
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
|
** ************************************************************************* ** Utility functions used throughout sqlite. ** ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** ** $Id: util.c,v 1.23 2001/09/15 00:57:29 drh Exp $ */ #include "sqliteInt.h" #include <stdarg.h> #include <ctype.h> /* ** If malloc() ever fails, this global variable gets set to 1. ................................................................................ } /* ** Return a static string that describes the kind of error specified in the ** argument. */ const char *sqliteErrStr(int rc){ const char *z; switch( rc ){ case SQLITE_OK: z = "not an error"; break; case SQLITE_ERROR: z = "SQL logic error or missing database"; break; case SQLITE_INTERNAL: z = "internal SQLite implementation flaw"; break; case SQLITE_PERM: z = "access permission denied"; break; case SQLITE_ABORT: z = "callback requested query abort"; break; case SQLITE_BUSY: z = "database in use by another process"; break; case SQLITE_NOMEM: z = "out of memory"; break; case SQLITE_READONLY: z = "attempt to write a readonly database"; break; case SQLITE_INTERRUPT: z = "interrupted"; break; case SQLITE_IOERR: z = "disk I/O error"; break; case SQLITE_CORRUPT: z = "database disk image is malformed"; break; case SQLITE_NOTFOUND: z = "table or record not found"; break; case SQLITE_FULL: z = "database is full"; break; case SQLITE_CANTOPEN: z = "unable to open database file"; break; case SQLITE_PROTOCOL: z = "database locking protocol failure"; break; case SQLITE_EMPTY: z = "table contains no data"; break; case SQLITE_SCHEMA: z = "database schema has changed"; break; default: z = "unknown error"; break; } return z; } |
Changes to src/vdbe.c.
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 ... 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 ... 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 .... 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 .... 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 .... 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 .... 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 .... 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 |
** inplicit conversion from one type to the other occurs as necessary. ** ** Most of the code in this file is taken up by the sqliteVdbeExec() ** function which does the work of interpreting a VDBE program. ** But other routines are also provided to help in building up ** a program instruction by instruction. ** ** $Id: vdbe.c,v 1.66 2001/09/14 16:42:12 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> #include <unistd.h> /* ** SQL is translated into a sequence of instructions to be ................................................................................ static void KeylistFree(Keylist *p){ while( p ){ Keylist *pNext = p->pNext; sqliteFree(p); p = pNext; } } /* ** Clean up the VM after execution. ** ** This routine will automatically close any cursors, lists, and/or ** sorters that were left open. */ static void Cleanup(Vdbe *p){ int i; PopStack(p, p->tos+1); sqliteFree(p->azColName); p->azColName = 0; for(i=0; i<p->nCursor; i++){ Cursor *pCx = &p->aCsr[i]; if( pCx->pCursor ){ sqliteBtreeCloseCursor(pCx->pCursor); pCx->pCursor = 0; } if( pCx->zKey ){ sqliteFree(pCx->zKey); pCx->zKey = 0; } if( pCx->pBt ){ sqliteBtreeClose(pCx->pBt); pCx->pBt = 0; } } sqliteFree(p->aCsr); p->aCsr = 0; p->nCursor = 0; for(i=0; i<p->nMem; i++){ if( p->aMem[i].s.flags & STK_Dyn ){ sqliteFree(p->aMem[i].z); ................................................................................ ** ** If any of the numeric OP_ values for opcodes defined in sqliteVdbe.h ** change, be sure to change this array to match. You can use the ** "opNames.awk" awk script which is part of the source tree to regenerate ** this array, then copy and paste it into this file, if you want. */ static char *zOpName[] = { 0, "Transaction", "Commit", "Rollback", "Open", "OpenTemp", "Close", "MoveTo", "Fcnt", "NewRecno", "Put", "Distinct", "Found", "NotFound", "Delete", "Column", "KeyAsData", "Recno", "FullKey", "Rewind", "Next", "Destroy", "Clear", "CreateIndex", "CreateTable", "Reorganize", "BeginIdx", "NextIdx", "PutIdx", "DeleteIdx", "MemLoad", "MemStore", "ListOpen", "ListWrite", "ListRewind", "ListRead", "ListClose", "SortOpen", "SortPut", "SortMakeRec", "SortMakeKey", "Sort", "SortNext", "SortKey", "SortCallback", "SortClose", "FileOpen", "FileRead", "FileColumn", "FileClose", "AggReset", "AggFocus", "AggIncr", "AggNext", "AggSet", "AggGet", "SetInsert", "SetFound", "SetNotFound", "SetClear", "MakeRecord", "MakeKey", "MakeIdxKey", "Goto", "If", "Halt", "ColumnCount", "ColumnName", "Callback", "Integer", "String", "Null", "Pop", "Dup", "Pull", "Add", "AddImm", "Subtract", "Multiply", "Divide", "Min", "Max", "Like", "Glob", "Eq", "Ne", "Lt", "Le", "Gt", "Ge", "IsNull", "NotNull", "Negative", "And", "Or", "Not", "Concat", "Noop", "Strlen", "Substr", }; /* ** Given the name of an opcode, return its number. Return 0 if ** there is no match. ** ** This routine is used for testing and debugging. ................................................................................ ** are allowed until another transaction is started. */ case OP_Rollback: { rc = sqliteBtreeRollback(pBt); sqliteRollbackInternalChanges(db); break; } /* Opcode: Open P1 P2 P3 ** ** Open a new cursor for the database table whose root page is ** P2 in the main database file. Give the new cursor an identifier ** of P1. The P1 values need not be contiguous but all P1 values ** should be small integers. It is an error for P1 to be negative. ................................................................................ int j; p->aCsr = sqliteRealloc( p->aCsr, (i+1)*sizeof(Cursor) ); if( p->aCsr==0 ){ p->nCursor = 0; goto no_mem; } for(j=p->nCursor; j<=i; j++){ memset(&p->aCsr[j], 0, sizeof(Cursor)); } p->nCursor = i+1; }else if( p->aCsr[i].pCursor ){ sqliteBtreeCloseCursor(p->aCsr[i].pCursor); } memset(&p->aCsr[i], 0, sizeof(Cursor)); do{ rc = sqliteBtreeCursor(pBt, p2, &p->aCsr[i].pCursor); switch( rc ){ case SQLITE_BUSY: { if( xBusy==0 || (*xBusy)(pBusyArg, pOp->p3, ++busy)==0 ){ sqliteSetString(pzErrMsg, sqliteErrStr(rc), 0); ................................................................................ int j; p->aCsr = sqliteRealloc( p->aCsr, (i+1)*sizeof(Cursor) ); if( p->aCsr==0 ){ p->nCursor = 0; goto no_mem; } for(j=p->nCursor; j<=i; j++){ memset(&p->aCsr[j], 0, sizeof(Cursor)); } p->nCursor = i+1; }else if( p->aCsr[i].pCursor ){ sqliteBtreeCloseCursor(p->aCsr[i].pCursor); } pCx = &p->aCsr[i]; memset(pCx, 0, sizeof(*pCx)); rc = sqliteBtreeOpen(0, 0, TEMP_PAGES, &pCx->pBt); if( rc==SQLITE_OK ){ rc = sqliteBtreeCursor(pCx->pBt, 2, &pCx->pCursor); } if( rc==SQLITE_OK ){ rc = sqliteBtreeBeginTrans(pCx->pBt); ................................................................................ ** ** Close a cursor previously opened as P1. If P1 is not ** currently open, this instruction is a no-op. */ case OP_Close: { int i = pOp->p1; if( i>=0 && i<p->nCursor && p->aCsr[i].pCursor ){ Cursor *pCx = &p->aCsr[i]; sqliteBtreeCloseCursor(pCx->pCursor); pCx->pCursor = 0; if( pCx->zKey ){ sqliteFree(pCx->zKey); pCx->zKey = 0; } if( pCx->pBt ){ sqliteBtreeClose(pCx->pBt); pCx->pBt = 0; } } break; } /* Opcode: MoveTo P1 * * ** ** Pop the top of the stack and use its value as a key. Reposition ................................................................................ int i = pOp->p1; int tos = p->tos; int res, rx; Cursor *pCrsr; VERIFY( if( tos<0 ) goto not_enough_stack; ) if( i>=0 && i<p->nCursor && (pCrsr = &p->aCsr[i])->pCursor!=0 ){ if( Stringify(p, tos) ) goto no_mem; pCrsr->nKey = aStack[tos].n; pCrsr->zKey = sqliteMalloc( 2*(pCrsr->nKey + 1) ); if( pCrsr->zKey==0 ) goto no_mem; pCrsr->zBuf = &pCrsr->zKey[pCrsr->nKey+1]; strncpy(pCrsr->zKey, zStack[tos], aStack[tos].n); pCrsr->zKey[aStack[tos].n] = 0; rx = sqliteBtreeMoveto(pCrsr->pCursor, zStack[tos], aStack[tos].n, &res); |
| > > > > > > > > > > > > > > > > > | < < < < < < < < < < < < | > | | | | | | | | | | | | | | | | | | | | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < < > < < > | < < < < < < < < < < > |
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 ... 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 ... 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 .... 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 .... 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 .... 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 .... 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 .... 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 |
** inplicit conversion from one type to the other occurs as necessary. ** ** Most of the code in this file is taken up by the sqliteVdbeExec() ** function which does the work of interpreting a VDBE program. ** But other routines are also provided to help in building up ** a program instruction by instruction. ** ** $Id: vdbe.c,v 1.67 2001/09/15 00:57:29 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> #include <unistd.h> /* ** SQL is translated into a sequence of instructions to be ................................................................................ static void KeylistFree(Keylist *p){ while( p ){ Keylist *pNext = p->pNext; sqliteFree(p); p = pNext; } } /* ** Close a cursor and release all the resources that cursor happens ** to hold. */ static void cleanupCursor(Cursor *pCx){ if( pCx->pCursor ){ sqliteBtreeCloseCursor(pCx->pCursor); } if( pCx->zKey ){ sqliteFree(pCx->zKey); } if( pCx->pBt ){ sqliteBtreeClose(pCx->pBt); } memset(pCx, 0, sizeof(Cursor)); } /* ** Clean up the VM after execution. ** ** This routine will automatically close any cursors, lists, and/or ** sorters that were left open. */ static void Cleanup(Vdbe *p){ int i; PopStack(p, p->tos+1); sqliteFree(p->azColName); p->azColName = 0; for(i=0; i<p->nCursor; i++){ cleanupCursor(&p->aCsr[i]); } sqliteFree(p->aCsr); p->aCsr = 0; p->nCursor = 0; for(i=0; i<p->nMem; i++){ if( p->aMem[i].s.flags & STK_Dyn ){ sqliteFree(p->aMem[i].z); ................................................................................ ** ** If any of the numeric OP_ values for opcodes defined in sqliteVdbe.h ** change, be sure to change this array to match. You can use the ** "opNames.awk" awk script which is part of the source tree to regenerate ** this array, then copy and paste it into this file, if you want. */ static char *zOpName[] = { 0, "Transaction", "Commit", "Rollback", "ReadCookie", "SetCookie", "VerifyCookie", "Open", "OpenTemp", "Close", "MoveTo", "Fcnt", "NewRecno", "Put", "Distinct", "Found", "NotFound", "Delete", "Column", "KeyAsData", "Recno", "FullKey", "Rewind", "Next", "Destroy", "Clear", "CreateIndex", "CreateTable", "Reorganize", "BeginIdx", "NextIdx", "PutIdx", "DeleteIdx", "MemLoad", "MemStore", "ListOpen", "ListWrite", "ListRewind", "ListRead", "ListClose", "SortOpen", "SortPut", "SortMakeRec", "SortMakeKey", "Sort", "SortNext", "SortKey", "SortCallback", "SortClose", "FileOpen", "FileRead", "FileColumn", "FileClose", "AggReset", "AggFocus", "AggIncr", "AggNext", "AggSet", "AggGet", "SetInsert", "SetFound", "SetNotFound", "SetClear", "MakeRecord", "MakeKey", "MakeIdxKey", "Goto", "If", "Halt", "ColumnCount", "ColumnName", "Callback", "Integer", "String", "Null", "Pop", "Dup", "Pull", "Add", "AddImm", "Subtract", "Multiply", "Divide", "Min", "Max", "Like", "Glob", "Eq", "Ne", "Lt", "Le", "Gt", "Ge", "IsNull", "NotNull", "Negative", "And", "Or", "Not", "Concat", "Noop", "Strlen", "Substr", }; /* ** Given the name of an opcode, return its number. Return 0 if ** there is no match. ** ** This routine is used for testing and debugging. ................................................................................ ** are allowed until another transaction is started. */ case OP_Rollback: { rc = sqliteBtreeRollback(pBt); sqliteRollbackInternalChanges(db); break; } /* Opcode: ReadCookie * * * ** ** Read the magic cookie from the database file and push it onto the ** stack. The magic cookie is an integer that is used like a version ** number for the database schema. Everytime the schema changes, the ** cookie changes to a new random value. This opcode is used during ** initialization to read the initial cookie value so that subsequent ** database accesses can verify that the cookie has not changed. ** ** There must be a read-lock on the database (either a transaction ** must be started or there must be a prior OP_Open opcode) before ** executing this instruction. */ case OP_ReadCookie: { int i = ++p->tos; int aMeta[SQLITE_N_BTREE_META]; VERIFY( if( NeedStack(p, p->tos) ) goto no_mem; ) rc = sqliteBtreeGetMeta(pBt, aMeta); aStack[i].i = aMeta[1]; aStack[i].flags = STK_Int; break; } /* Opcode: SetCookie P1 * * ** ** This operation changes the value of the cookie on the database. ** The new value is P1. ** ** The cookie changes its value whenever the database schema changes. ** That way, other processes can recognize when the schema has changed ** and reread it. ** ** A transaction must be started before executing this opcode. */ case OP_SetCookie: { int aMeta[SQLITE_N_BTREE_META]; rc = sqliteBtreeGetMeta(pBt, aMeta); if( rc==SQLITE_OK ){ aMeta[1] = pOp->p1; rc = sqliteBtreeUpdateMeta(pBt, aMeta); } break; } /* Opcode: VerifyCookie P1 * * ** ** Check the current value of the database cookie and make sure it is ** equal to P1. If it is not, abort with an SQLITE_SCHEMA error. ** ** The cookie changes its value whenever the database schema changes. ** This operation is used to detech when that the cookie has changed ** and that the current process needs to reread the schema. ** ** Either a transaction needs to have been started or an OP_Open needs ** to be executed (to establish a read lock) before this opcode is ** invoked. */ case OP_VerifyCookie: { int aMeta[SQLITE_N_BTREE_META]; rc = sqliteBtreeGetMeta(pBt, aMeta); if( rc==SQLITE_OK && aMeta[1]!=pOp->p1 ){ sqliteSetString(pzErrMsg, "database schema has changed", 0); rc = SQLITE_SCHEMA; } break; } /* Opcode: Open P1 P2 P3 ** ** Open a new cursor for the database table whose root page is ** P2 in the main database file. Give the new cursor an identifier ** of P1. The P1 values need not be contiguous but all P1 values ** should be small integers. It is an error for P1 to be negative. ................................................................................ int j; p->aCsr = sqliteRealloc( p->aCsr, (i+1)*sizeof(Cursor) ); if( p->aCsr==0 ){ p->nCursor = 0; goto no_mem; } for(j=p->nCursor; j<=i; j++){ memset(&p->aCsr[j], 0, sizeof(Cursor)); } p->nCursor = i+1; } cleanupCursor(&p->aCsr[i]); memset(&p->aCsr[i], 0, sizeof(Cursor)); do{ rc = sqliteBtreeCursor(pBt, p2, &p->aCsr[i].pCursor); switch( rc ){ case SQLITE_BUSY: { if( xBusy==0 || (*xBusy)(pBusyArg, pOp->p3, ++busy)==0 ){ sqliteSetString(pzErrMsg, sqliteErrStr(rc), 0); ................................................................................ int j; p->aCsr = sqliteRealloc( p->aCsr, (i+1)*sizeof(Cursor) ); if( p->aCsr==0 ){ p->nCursor = 0; goto no_mem; } for(j=p->nCursor; j<=i; j++){ memset(&p->aCsr[j], 0, sizeof(Cursor)); } p->nCursor = i+1; } pCx = &p->aCsr[i]; cleanupCursor(pCx); memset(pCx, 0, sizeof(*pCx)); rc = sqliteBtreeOpen(0, 0, TEMP_PAGES, &pCx->pBt); if( rc==SQLITE_OK ){ rc = sqliteBtreeCursor(pCx->pBt, 2, &pCx->pCursor); } if( rc==SQLITE_OK ){ rc = sqliteBtreeBeginTrans(pCx->pBt); ................................................................................ ** ** Close a cursor previously opened as P1. If P1 is not ** currently open, this instruction is a no-op. */ case OP_Close: { int i = pOp->p1; if( i>=0 && i<p->nCursor && p->aCsr[i].pCursor ){ cleanupCursor(&p->aCsr[i]); } break; } /* Opcode: MoveTo P1 * * ** ** Pop the top of the stack and use its value as a key. Reposition ................................................................................ int i = pOp->p1; int tos = p->tos; int res, rx; Cursor *pCrsr; VERIFY( if( tos<0 ) goto not_enough_stack; ) if( i>=0 && i<p->nCursor && (pCrsr = &p->aCsr[i])->pCursor!=0 ){ if( Stringify(p, tos) ) goto no_mem; if( pCrsr->zKey ) sqliteFree(pCrsr->zKey); pCrsr->nKey = aStack[tos].n; pCrsr->zKey = sqliteMalloc( 2*(pCrsr->nKey + 1) ); if( pCrsr->zKey==0 ) goto no_mem; pCrsr->zBuf = &pCrsr->zKey[pCrsr->nKey+1]; strncpy(pCrsr->zKey, zStack[tos], aStack[tos].n); pCrsr->zKey[aStack[tos].n] = 0; rx = sqliteBtreeMoveto(pCrsr->pCursor, zStack[tos], aStack[tos].n, &res); |
Changes to src/vdbe.h.
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
..
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
|
************************************************************************* ** Header file for the Virtual DataBase Engine (VDBE) ** ** This header defines the interface to the virtual database engine ** or VDBE. The VDBE implements an abstract machine that runs a ** simple program to access and modify the underlying database. ** ** $Id: vdbe.h,v 1.21 2001/09/13 21:53:10 drh Exp $ */ #ifndef _SQLITE_VDBE_H_ #define _SQLITE_VDBE_H_ #include <stdio.h> /* ** A single VDBE is an opaque structure named "Vdbe". Only routines ................................................................................ ** The source tree contains an AWK script named renumberOps.awk that ** can be used to renumber these opcodes when new opcodes are inserted. */ #define OP_Transaction 1 #define OP_Commit 2 #define OP_Rollback 3 #define OP_Open 4 #define OP_OpenTemp 5 #define OP_Close 6 #define OP_MoveTo 7 #define OP_Fcnt 8 #define OP_NewRecno 9 #define OP_Put 10 #define OP_Distinct 11 #define OP_Found 12 #define OP_NotFound 13 #define OP_Delete 14 #define OP_Column 15 #define OP_KeyAsData 16 #define OP_Recno 17 #define OP_FullKey 18 #define OP_Rewind 19 #define OP_Next 20 #define OP_Destroy 21 #define OP_Clear 22 #define OP_CreateIndex 23 #define OP_CreateTable 24 #define OP_Reorganize 25 #define OP_BeginIdx 26 #define OP_NextIdx 27 #define OP_PutIdx 28 #define OP_DeleteIdx 29 #define OP_MemLoad 30 #define OP_MemStore 31 #define OP_ListOpen 32 #define OP_ListWrite 33 #define OP_ListRewind 34 #define OP_ListRead 35 #define OP_ListClose 36 #define OP_SortOpen 37 #define OP_SortPut 38 #define OP_SortMakeRec 39 #define OP_SortMakeKey 40 #define OP_Sort 41 #define OP_SortNext 42 #define OP_SortKey 43 #define OP_SortCallback 44 #define OP_SortClose 45 #define OP_FileOpen 46 #define OP_FileRead 47 #define OP_FileColumn 48 #define OP_FileClose 49 #define OP_AggReset 50 #define OP_AggFocus 51 #define OP_AggIncr 52 #define OP_AggNext 53 #define OP_AggSet 54 #define OP_AggGet 55 #define OP_SetInsert 56 #define OP_SetFound 57 #define OP_SetNotFound 58 #define OP_SetClear 59 #define OP_MakeRecord 60 #define OP_MakeKey 61 #define OP_MakeIdxKey 62 #define OP_Goto 63 #define OP_If 64 #define OP_Halt 65 #define OP_ColumnCount 66 #define OP_ColumnName 67 #define OP_Callback 68 #define OP_Integer 69 #define OP_String 70 #define OP_Null 71 #define OP_Pop 72 #define OP_Dup 73 #define OP_Pull 74 #define OP_Add 75 #define OP_AddImm 76 #define OP_Subtract 77 #define OP_Multiply 78 #define OP_Divide 79 #define OP_Min 80 #define OP_Max 81 #define OP_Like 82 #define OP_Glob 83 #define OP_Eq 84 #define OP_Ne 85 #define OP_Lt 86 #define OP_Le 87 #define OP_Gt 88 #define OP_Ge 89 #define OP_IsNull 90 #define OP_NotNull 91 #define OP_Negative 92 #define OP_And 93 #define OP_Or 94 #define OP_Not 95 #define OP_Concat 96 #define OP_Noop 97 #define OP_Strlen 98 #define OP_Substr 99 #define OP_MAX 99 /* ** Prototypes for the VDBE interface. See comments on the implementation ** for a description of what each of these routines does. */ Vdbe *sqliteVdbeCreate(sqlite*); void sqliteVdbeCreateCallback(Vdbe*, int*); |
|
>
>
>
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
..
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
|
************************************************************************* ** Header file for the Virtual DataBase Engine (VDBE) ** ** This header defines the interface to the virtual database engine ** or VDBE. The VDBE implements an abstract machine that runs a ** simple program to access and modify the underlying database. ** ** $Id: vdbe.h,v 1.22 2001/09/15 00:57:29 drh Exp $ */ #ifndef _SQLITE_VDBE_H_ #define _SQLITE_VDBE_H_ #include <stdio.h> /* ** A single VDBE is an opaque structure named "Vdbe". Only routines ................................................................................ ** The source tree contains an AWK script named renumberOps.awk that ** can be used to renumber these opcodes when new opcodes are inserted. */ #define OP_Transaction 1 #define OP_Commit 2 #define OP_Rollback 3 #define OP_ReadCookie 4 #define OP_SetCookie 5 #define OP_VerifyCookie 6 #define OP_Open 7 #define OP_OpenTemp 8 #define OP_Close 9 #define OP_MoveTo 10 #define OP_Fcnt 11 #define OP_NewRecno 12 #define OP_Put 13 #define OP_Distinct 14 #define OP_Found 15 #define OP_NotFound 16 #define OP_Delete 17 #define OP_Column 18 #define OP_KeyAsData 19 #define OP_Recno 20 #define OP_FullKey 21 #define OP_Rewind 22 #define OP_Next 23 #define OP_Destroy 24 #define OP_Clear 25 #define OP_CreateIndex 26 #define OP_CreateTable 27 #define OP_Reorganize 28 #define OP_BeginIdx 29 #define OP_NextIdx 30 #define OP_PutIdx 31 #define OP_DeleteIdx 32 #define OP_MemLoad 33 #define OP_MemStore 34 #define OP_ListOpen 35 #define OP_ListWrite 36 #define OP_ListRewind 37 #define OP_ListRead 38 #define OP_ListClose 39 #define OP_SortOpen 40 #define OP_SortPut 41 #define OP_SortMakeRec 42 #define OP_SortMakeKey 43 #define OP_Sort 44 #define OP_SortNext 45 #define OP_SortKey 46 #define OP_SortCallback 47 #define OP_SortClose 48 #define OP_FileOpen 49 #define OP_FileRead 50 #define OP_FileColumn 51 #define OP_FileClose 52 #define OP_AggReset 53 #define OP_AggFocus 54 #define OP_AggIncr 55 #define OP_AggNext 56 #define OP_AggSet 57 #define OP_AggGet 58 #define OP_SetInsert 59 #define OP_SetFound 60 #define OP_SetNotFound 61 #define OP_SetClear 62 #define OP_MakeRecord 63 #define OP_MakeKey 64 #define OP_MakeIdxKey 65 #define OP_Goto 66 #define OP_If 67 #define OP_Halt 68 #define OP_ColumnCount 69 #define OP_ColumnName 70 #define OP_Callback 71 #define OP_Integer 72 #define OP_String 73 #define OP_Null 74 #define OP_Pop 75 #define OP_Dup 76 #define OP_Pull 77 #define OP_Add 78 #define OP_AddImm 79 #define OP_Subtract 80 #define OP_Multiply 81 #define OP_Divide 82 #define OP_Min 83 #define OP_Max 84 #define OP_Like 85 #define OP_Glob 86 #define OP_Eq 87 #define OP_Ne 88 #define OP_Lt 89 #define OP_Le 90 #define OP_Gt 91 #define OP_Ge 92 #define OP_IsNull 93 #define OP_NotNull 94 #define OP_Negative 95 #define OP_And 96 #define OP_Or 97 #define OP_Not 98 #define OP_Concat 99 #define OP_Noop 100 #define OP_Strlen 101 #define OP_Substr 102 #define OP_MAX 102 /* ** Prototypes for the VDBE interface. See comments on the implementation ** for a description of what each of these routines does. */ Vdbe *sqliteVdbeCreate(sqlite*); void sqliteVdbeCreateCallback(Vdbe*, int*); |
Changes to src/where.c.
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
...
295
296
297
298
299
300
301
302
303
304
305
306
307
308
|
** http://www.hwaci.com/drh/ ** ************************************************************************* ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. Also found here are subroutines ** to generate VDBE code to evaluate expressions. ** ** $Id: where.c,v 1.18 2001/09/13 16:18:55 drh Exp $ */ #include "sqliteInt.h" /* ** The query generator uses an array of instances of this structure to ** help it analyze the subexpressions of the WHERE clause. Each WHERE ** clause subexpression is separated from the others by an AND operator. ................................................................................ } /* Open all tables in the pTabList and all indices in aIdx[]. */ for(i=0; i<pTabList->nId; i++){ sqliteVdbeAddOp(v, OP_Open, base+i, pTabList->a[i].pTab->tnum, pTabList->a[i].pTab->zName, 0); if( i<ARRAYSIZE(aIdx) && aIdx[i]!=0 ){ sqliteVdbeAddOp(v, OP_Open, base+pTabList->nId+i, aIdx[i]->tnum, aIdx[i]->zName, 0); } } memcpy(pWInfo->aIdx, aIdx, sizeof(aIdx)); |
|
>
>
>
>
>
|
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
...
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
|
** http://www.hwaci.com/drh/ ** ************************************************************************* ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. Also found here are subroutines ** to generate VDBE code to evaluate expressions. ** ** $Id: where.c,v 1.19 2001/09/15 00:57:29 drh Exp $ */ #include "sqliteInt.h" /* ** The query generator uses an array of instances of this structure to ** help it analyze the subexpressions of the WHERE clause. Each WHERE ** clause subexpression is separated from the others by an AND operator. ................................................................................ } /* Open all tables in the pTabList and all indices in aIdx[]. */ for(i=0; i<pTabList->nId; i++){ sqliteVdbeAddOp(v, OP_Open, base+i, pTabList->a[i].pTab->tnum, pTabList->a[i].pTab->zName, 0); if( i==0 && !pParse->schemaVerified && (pParse->db->flags & SQLITE_InTrans)==0 ){ sqliteVdbeAddOp(v, OP_VerifyCookie, pParse->db->schema_cookie, 0, 0, 0); pParse->schemaVerified = 1; } if( i<ARRAYSIZE(aIdx) && aIdx[i]!=0 ){ sqliteVdbeAddOp(v, OP_Open, base+pTabList->nId+i, aIdx[i]->tnum, aIdx[i]->zName, 0); } } memcpy(pWInfo->aIdx, aIdx, sizeof(aIdx)); |