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 |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
14474fa144fe7c5dc63e0990d6cc92d7 |
User & Date: | drh 2001-09-15 00:57:28.000 |
Context
2001-09-15
| ||
00:58 | Release 2.0-alpha-1 (CVS 247) (check-in: 264f23315e user: drh tags: trunk) | |
00:57 | Everything is working on Linux. This is release 2.0-Alpha-1. (CVS 246) (check-in: 14474fa144 user: drh tags: trunk) | |
2001-09-14
| ||
18:54 | Added a PRAGMA statement. Took out the special comment parsing. (CVS 245) (check-in: 5e3724603e user: drh tags: trunk) | |
Changes
Changes to src/TODO.
1 2 3 4 5 | * 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. | < | 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 | ** DROP TABLE ** CREATE INDEX ** DROP INDEX ** creating expressions and ID lists ** COPY ** VACUUM ** | | | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | ** 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 |
︙ | ︙ | |||
63 64 65 66 67 68 69 70 71 72 73 74 75 76 | &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){ | > | 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | &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){ |
︙ | ︙ | |||
274 275 276 277 278 279 280 281 282 283 284 285 286 287 | ** 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 ){ | > | 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 | ** 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 ){ |
︙ | ︙ | |||
310 311 312 313 314 315 316 317 318 319 320 321 322 323 | ** 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 ){ | > | 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 | ** 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 ){ |
︙ | ︙ | |||
394 395 396 397 398 399 400 401 402 403 404 405 406 407 | 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. ** | > | 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 | 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. ** |
︙ | ︙ | |||
445 446 447 448 449 450 451 452 453 454 455 456 457 458 | 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. ** | > > > > > > > > > > > > > > > > > > > > > > > > | 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 | 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. ** |
︙ | ︙ | |||
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 | { 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 ); | > > > | 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 | { 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 ); |
︙ | ︙ | |||
582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 | { 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); } } | > > > > | 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 | { 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); } } |
︙ | ︙ | |||
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 | { 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); | > > > > | 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 | { 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); |
︙ | ︙ | |||
857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 | { 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. | > > > > | 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 | { 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. |
︙ | ︙ | |||
1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 | 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); | > | 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 | 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); |
︙ | ︙ | |||
1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 | 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; | > | 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 | 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; |
︙ | ︙ | |||
1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 | 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 */ | > | 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 | 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 | ** 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. ** | | | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | ** 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( |
︙ | ︙ | |||
88 89 90 91 92 93 94 95 96 97 98 99 100 101 | /* 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 ){ | > | 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | /* 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 | ** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle INSERT statements. ** | | | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | ** 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) |
︙ | ︙ | |||
83 84 85 86 87 88 89 90 91 92 93 94 95 96 | /* 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. | > | 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | /* 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 | ** ************************************************************************* ** 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. ** | | | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | ** ************************************************************************* ** 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 /* |
︙ | ︙ | |||
47 48 49 50 51 52 53 | sqlite *db = (sqlite*)pDb; Parse sParse; int nErr = 0; assert( argc==4 ); switch( argv[0][0] ){ case 'm': { /* Meta information */ | > | > > > > | 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | 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; |
︙ | ︙ | |||
166 167 168 169 170 171 172 | { 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}, | > > > > > | | 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | { 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); |
︙ | ︙ | |||
277 278 279 280 281 282 283 | no_mem_on_open: sqliteSetString(pzErrMsg, "out of memory", 0); sqliteStrRealloc(pzErrMsg); return 0; } /* | > > | > > > > | < > > > > > > > > > | 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 | 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){ |
︙ | ︙ | |||
383 384 385 386 387 388 389 390 391 392 393 394 395 396 | 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 | > > > | 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 | 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 | ************************************************************************* ** 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. ** | | | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | ************************************************************************* ** 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> |
︙ | ︙ | |||
678 679 680 681 682 683 684 685 686 687 688 689 690 691 | ** 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. ** | > > > > > > > > > > > > > > > > > > > > > > | 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 | ** 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. ** |
︙ | ︙ | |||
787 788 789 790 791 792 793 | 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 */ | | < | > > > > > > > > > > > > > > | 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 | 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 ){ |
︙ | ︙ | |||
821 822 823 824 825 826 827 828 829 830 831 832 833 834 | 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 ); | > > | 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 | 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 | ** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ************************************************************************* ** This header file defines the interface that the sqlite library ** presents to client programs. ** | | | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | ** 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. |
︙ | ︙ | |||
156 157 158 159 160 161 162 163 164 165 166 167 168 169 | #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. */ | > | 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | #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 | ** Author contact information: ** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ************************************************************************* ** Internal interface definitions for SQLite. ** | | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | ** 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> |
︙ | ︙ | |||
139 140 141 142 143 144 145 146 147 148 149 150 151 152 | /* ** 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 */ }; | > > | 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | /* ** 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 */ }; |
︙ | ︙ | |||
372 373 374 375 376 377 378 379 380 381 382 383 384 385 | 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); | > > | 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 | 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 | ** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle UPDATE statements. ** | | | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | ** 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( |
︙ | ︙ | |||
142 143 144 145 146 147 148 149 150 151 152 153 154 155 | /* 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; | > | 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | /* 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 | ** ************************************************************************* ** Utility functions used throughout sqlite. ** ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** | | | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | ** ************************************************************************* ** 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. |
︙ | ︙ | |||
974 975 976 977 978 979 980 | } /* ** Return a static string that describes the kind of error specified in the ** argument. */ const char *sqliteErrStr(int rc){ | | | | | | | | | | | | | | | | | | > | | 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 | } /* ** 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 | ** 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. ** | | | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | ** 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 |
︙ | ︙ | |||
754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 | 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++){ | > > > > > > > > > > > > > > > > > | < < < < < < < < < < < < | 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 | 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); |
︙ | ︙ | |||
867 868 869 870 871 872 873 | ** ** 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, | | > | | | | | | | | | | | | | | | | | | | | | | | | | 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 | ** ** 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. |
︙ | ︙ | |||
1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 | ** 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. | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | ** 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. |
︙ | ︙ | |||
2009 2010 2011 2012 2013 2014 2015 | 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; | < < > | 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 | 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); |
︙ | ︙ | |||
2054 2055 2056 2057 2058 2059 2060 | 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; | < < > | < < < < < < < < < < | 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 | 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); } break; } /* Opcode: Close P1 * * ** ** 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 |
︙ | ︙ | |||
2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 | 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); | > | 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 | 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 | ************************************************************************* ** 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. ** | | | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | ************************************************************************* ** 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 |
︙ | ︙ | |||
71 72 73 74 75 76 77 | ** 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 | > > > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 | ** 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 | ** 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. ** | | | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | ** 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. |
︙ | ︙ | |||
295 296 297 298 299 300 301 302 303 304 305 306 307 308 | } /* 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)); | > > > > > | 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 | } /* 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)); |
︙ | ︙ |