Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | First code for the new callback-free API. All regression tests pass but the new API is mostly untested and is unlikely to work. (CVS 852) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
065fa818ffc8d7562889172acea16e4e |
User & Date: | drh 2003-01-28 23:13:11.000 |
Context
2003-01-29
| ||
14:06 | The callback-free API is now working, though much more testing is need. (CVS 853) (check-in: 162b259188 user: drh tags: trunk) | |
2003-01-28
| ||
23:13 | First code for the new callback-free API. All regression tests pass but the new API is mostly untested and is unlikely to work. (CVS 852) (check-in: 065fa818ff user: drh tags: trunk) | |
2003-01-26
| ||
15:28 | Added section on comments. Corrected broken end tags. (CVS 851) (check-in: c957f4f0c6 user: jplyon tags: trunk) | |
Changes
Changes to src/build.c.
︙ | ︙ | |||
21 22 23 24 25 26 27 | ** COPY ** VACUUM ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** PRAGMA ** | | | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | ** COPY ** VACUUM ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** PRAGMA ** ** $Id: build.c,v 1.126 2003/01/28 23:13:11 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** This routine is called when a new SQL statement is beginning to ** be parsed. Check to see if the schema for the database needs |
︙ | ︙ | |||
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | int rc = sqliteInit(db, &pParse->zErrMsg); if( rc!=SQLITE_OK ){ pParse->rc = rc; pParse->nErr++; } } } /* ** This routine is called after a single SQL statement has been ** parsed and we want to execute the VDBE code to implement ** that statement. Prior action routines should have already ** constructed VDBE code to do the work of the SQL statement. ** This routine just has to execute the VDBE code. ** ** Note that if an error occurred, it might be the case that ** no VDBE code was generated. */ void sqliteExec(Parse *pParse){ int rc = SQLITE_OK; sqlite *db = pParse->db; if( sqlite_malloc_failed ) return; | > > > > > > > > > > > > > > > > | > > > > | | < | | < | < > | < < | | < | > > > > > | 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | int rc = sqliteInit(db, &pParse->zErrMsg); if( rc!=SQLITE_OK ){ pParse->rc = rc; pParse->nErr++; } } } /* ** This is a fake callback procedure used when sqlite_exec() is ** invoked with a NULL callback pointer. If we pass a NULL callback ** pointer into sqliteVdbeExec() it will return at every OP_Callback, ** which we do not want it to do. So we substitute a pointer to this ** procedure in place of the NULL. */ static int fakeCallback(void *NotUsed, int n, char **az1, char **az2){ return 0; } /* ** This routine is called after a single SQL statement has been ** parsed and we want to execute the VDBE code to implement ** that statement. Prior action routines should have already ** constructed VDBE code to do the work of the SQL statement. ** This routine just has to execute the VDBE code. ** ** Note that if an error occurred, it might be the case that ** no VDBE code was generated. */ void sqliteExec(Parse *pParse){ int rc = SQLITE_OK; sqlite *db = pParse->db; Vdbe *v = pParse->pVdbe; int (*xCallback)(void*,int,char**,char**); if( sqlite_malloc_failed ) return; xCallback = pParse->xCallback; if( xCallback==0 && pParse->useCallback ) xCallback = fakeCallback; if( v && pParse->nErr==0 ){ FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stdout : 0; sqliteVdbeTrace(v, trace); sqliteVdbeMakeReady(v, xCallback, pParse->pArg, pParse->explain); if( pParse->useCallback ){ if( pParse->explain ){ rc = sqliteVdbeList(v); db->next_cookie = db->schema_cookie; }else{ sqliteVdbeExec(v); } rc = sqliteVdbeFinalize(v, &pParse->zErrMsg); if( rc ) pParse->nErr++; sqliteVdbeDelete(v); pParse->pVdbe = 0; pParse->rc = rc; if( rc ) pParse->nErr++; }else{ pParse->rc = pParse->nErr ? SQLITE_ERROR : SQLITE_DONE; } pParse->colNamesSet = 0; pParse->schemaVerified = 0; } pParse->nTab = 0; pParse->nMem = 0; pParse->nSet = 0; pParse->nAgg = 0; } |
︙ | ︙ |
Changes to src/main.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** 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. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** 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.110 2003/01/28 23:13:12 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> /* ** A pointer to this structure is used to communicate information |
︙ | ︙ | |||
65 66 67 68 69 70 71 72 73 74 75 76 77 78 | ** structures that describe the table, index, or view. */ memset(&sParse, 0, sizeof(sParse)); sParse.db = pData->db; sParse.initFlag = 1; sParse.isTemp = argv[4][0] - '0'; sParse.newTnum = atoi(argv[2]); sqliteRunParser(&sParse, argv[3], pData->pzErrMsg); }else{ /* If the SQL column is blank it means this is an index that ** was created to be the PRIMARY KEY or to fulfill a UNIQUE ** constraint for a CREATE TABLE. The index should have already ** been created when we processed the CREATE TABLE. All we have ** to do here is record the root page number for that index. | > | 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | ** structures that describe the table, index, or view. */ memset(&sParse, 0, sizeof(sParse)); sParse.db = pData->db; sParse.initFlag = 1; sParse.isTemp = argv[4][0] - '0'; sParse.newTnum = atoi(argv[2]); sParse.useCallback = 1; sqliteRunParser(&sParse, argv[3], pData->pzErrMsg); }else{ /* If the SQL column is blank it means this is an index that ** was created to be the PRIMARY KEY or to fulfill a UNIQUE ** constraint for a CREATE TABLE. The index should have already ** been created when we processed the CREATE TABLE. All we have ** to do here is record the root page number for that index. |
︙ | ︙ | |||
293 294 295 296 297 298 299 300 301 302 303 304 305 306 | */ memset(&sParse, 0, sizeof(sParse)); sParse.db = db; sParse.pBe = db->pBe; sParse.xCallback = sqliteInitCallback; sParse.pArg = (void*)&initData; sParse.initFlag = 1; sqliteRunParser(&sParse, db->file_format>=2 ? init_script : older_init_script, pzErrMsg); if( sqlite_malloc_failed ){ sqliteSetString(pzErrMsg, "out of memory", 0); sParse.rc = SQLITE_NOMEM; sqliteBtreeRollback(db->pBe); | > | 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 | */ memset(&sParse, 0, sizeof(sParse)); sParse.db = db; sParse.pBe = db->pBe; sParse.xCallback = sqliteInitCallback; sParse.pArg = (void*)&initData; sParse.initFlag = 1; sParse.useCallback = 1; sqliteRunParser(&sParse, db->file_format>=2 ? init_script : older_init_script, pzErrMsg); if( sqlite_malloc_failed ){ sqliteSetString(pzErrMsg, "out of memory", 0); sParse.rc = SQLITE_NOMEM; sqliteBtreeRollback(db->pBe); |
︙ | ︙ | |||
580 581 582 583 584 585 586 | } zSql++; } return seenText && isComplete && requireEnd==0; } /* | | | < | < < < < | > > | < < < | 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 | } zSql++; } return seenText && isComplete && requireEnd==0; } /* ** This routine does the work of either sqlite_exec() or sqlite_compile(). ** It works like sqlite_exec() if pVm==NULL and it works like sqlite_compile() ** otherwise. */ static int sqliteMain( sqlite *db, /* The database on which the SQL executes */ const char *zSql, /* The SQL to be executed */ sqlite_callback xCallback, /* Invoke this callback routine */ void *pArg, /* First argument to xCallback() */ const char **pzTail, /* OUT: Next statement after the first */ sqlite_vm **ppVm, /* OUT: The virtual machine */ char **pzErrMsg /* OUT: Write error messages here */ ){ Parse sParse; if( pzErrMsg ) *pzErrMsg = 0; if( sqliteSafetyOn(db) ) goto exec_misuse; if( (db->flags & SQLITE_Initialized)==0 ){ int rc, cnt = 1; while( (rc = sqliteInit(db, pzErrMsg))==SQLITE_BUSY && db->xBusyCallback && db->xBusyCallback(db->pBusyArg, "", cnt++)!=0 ){} if( rc!=SQLITE_OK ){ sqliteStrRealloc(pzErrMsg); sqliteSafetyOff(db); |
︙ | ︙ | |||
629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 | if( db->recursionDepth==0 ){ db->nChange = 0; } db->recursionDepth++; memset(&sParse, 0, sizeof(sParse)); sParse.db = db; sParse.pBe = db->pBe; sParse.xCallback = xCallback; sParse.pArg = pArg; sqliteRunParser(&sParse, zSql, pzErrMsg); if( sqlite_malloc_failed ){ sqliteSetString(pzErrMsg, "out of memory", 0); sParse.rc = SQLITE_NOMEM; sqliteBtreeRollback(db->pBe); if( db->pBeTemp ) sqliteBtreeRollback(db->pBeTemp); db->flags &= ~SQLITE_InTrans; sqliteResetInternalSchema(db); } if( sParse.rc!=SQLITE_OK && pzErrMsg && *pzErrMsg==0 ){ sqliteSetString(pzErrMsg, sqlite_error_string(sParse.rc), 0); } sqliteStrRealloc(pzErrMsg); if( sParse.rc==SQLITE_SCHEMA ){ sqliteResetInternalSchema(db); } db->recursionDepth--; if( sqliteSafetyOff(db) ) goto exec_misuse; return sParse.rc; exec_misuse: if( pzErrMsg ){ *pzErrMsg = 0; sqliteSetString(pzErrMsg, sqlite_error_string(SQLITE_MISUSE), 0); sqliteStrRealloc(pzErrMsg); } return SQLITE_MISUSE; } /* ** Return a static string that describes the kind of error specified in the ** argument. */ const char *sqlite_error_string(int rc){ const char *z; | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 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 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 | if( db->recursionDepth==0 ){ db->nChange = 0; } db->recursionDepth++; memset(&sParse, 0, sizeof(sParse)); sParse.db = db; sParse.pBe = db->pBe; sParse.xCallback = xCallback; sParse.pArg = pArg; sParse.useCallback = ppVm==0; #ifndef SQLITE_OMIT_TRACE if( db->xTrace ) db->xTrace(db->pTraceArg, zSql); #endif sqliteRunParser(&sParse, zSql, pzErrMsg); if( sqlite_malloc_failed ){ sqliteSetString(pzErrMsg, "out of memory", 0); sParse.rc = SQLITE_NOMEM; sqliteBtreeRollback(db->pBe); if( db->pBeTemp ) sqliteBtreeRollback(db->pBeTemp); db->flags &= ~SQLITE_InTrans; sqliteResetInternalSchema(db); } if( sParse.rc!=SQLITE_OK && pzErrMsg && *pzErrMsg==0 ){ sqliteSetString(pzErrMsg, sqlite_error_string(sParse.rc), 0); } sqliteStrRealloc(pzErrMsg); if( sParse.rc==SQLITE_SCHEMA ){ sqliteResetInternalSchema(db); } db->recursionDepth--; if( sParse.useCallback==0 ){ assert( ppVm ); *ppVm = sParse.pVdbe; *pzTail = &sParse.sLastToken.z[sParse.sLastToken.n]; } if( sqliteSafetyOff(db) ) goto exec_misuse; return sParse.rc; exec_misuse: if( pzErrMsg ){ *pzErrMsg = 0; sqliteSetString(pzErrMsg, sqlite_error_string(SQLITE_MISUSE), 0); sqliteStrRealloc(pzErrMsg); } return SQLITE_MISUSE; } /* ** Execute SQL code. Return one of the SQLITE_ success/failure ** codes. Also write an error message into memory obtained from ** malloc() and make *pzErrMsg point to that message. ** ** If the SQL is a query, then for each row in the query result ** the xCallback() function is called. pArg becomes the first ** argument to xCallback(). If xCallback=NULL then no callback ** is invoked, even for queries. */ int sqlite_exec( sqlite *db, /* The database on which the SQL executes */ const char *zSql, /* The SQL to be executed */ sqlite_callback xCallback, /* Invoke this callback routine */ void *pArg, /* First argument to xCallback() */ char **pzErrMsg /* Write error messages here */ ){ return sqliteMain(db, zSql, xCallback, pArg, 0, 0, pzErrMsg); } /* ** Compile a single statement of SQL into a virtual machine. Return one ** of the SQLITE_ success/failure codes. Also write an error message into ** memory obtained from malloc() and make *pzErrMsg point to that message. */ int sqlite_compile( sqlite *db, /* The database on which the SQL executes */ const char *zSql, /* The SQL to be executed */ const char **pzTail, /* OUT: Next statement after the first */ sqlite_vm **ppVm, /* OUT: The virtual machine */ char **pzErrMsg /* OUT: Write error messages here */ ){ return sqliteMain(db, zSql, 0, 0, pzTail, ppVm, pzErrMsg); } /* ** The following routine destroys a virtual machine that is created by ** the sqlite_compile() routine. ** ** The integer returned is an SQLITE_ success/failure code that describes ** the result of executing the virtual machine. An error message is ** written into memory obtained from malloc and *pzErrMsg is made to ** point to that error if pzErrMsg is not NULL. The calling routine ** should use sqlite_freemem() to delete the message when it has finished ** with it. */ int sqlite_finalize( sqlite_vm *pVm, /* The virtual machine to be destroyed */ char **pzErrMsg /* OUT: Write error messages here */ ){ return sqliteVdbeFinalize((Vdbe*)pVm, pzErrMsg); } /* ** Return a static string that describes the kind of error specified in the ** argument. */ const char *sqlite_error_string(int rc){ const char *z; |
︙ | ︙ |
Changes to src/parse.y.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** This file contains SQLite's grammar for SQL. Process this file ** using the lemon parser generator to generate C code that runs ** the parser. Lemon will also generate a header file containing ** numeric codes for all of the tokens. ** | | > > > > > | > > | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | ** ************************************************************************* ** This file contains SQLite's grammar for SQL. Process this file ** using the lemon parser generator to generate C code that runs ** the parser. Lemon will also generate a header file containing ** numeric codes for all of the tokens. ** ** @(#) $Id: parse.y,v 1.89 2003/01/28 23:13:12 drh Exp $ */ %token_prefix TK_ %token_type {Token} %default_type {Token} %extra_argument {Parse *pParse} %syntax_error { if( pParse->zErrMsg==0 ){ if( TOKEN.z[0] ){ sqliteSetNString(&pParse->zErrMsg, "near \"", -1, TOKEN.z, TOKEN.n, "\": syntax error", -1, 0); }else{ sqliteSetString(&pParse->zErrMsg, "incomplete SQL statement", 0); } } pParse->nErr++; } %name sqliteParser %include { #include "sqliteInt.h" #include "parse.h" /* |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the SQLite library ** presents to client programs. ** | | < < < < < > > > > > | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the SQLite library ** presents to client programs. ** ** @(#) $Id: sqlite.h.in,v 1.40 2003/01/28 23:13:12 drh Exp $ */ #ifndef _SQLITE_H_ #define _SQLITE_H_ #include <stdarg.h> /* Needed for the definition of va_list */ /* ** Make sure we can call this stuff from C++. */ #ifdef __cplusplus extern "C" { #endif /* ** The version of the SQLite library. */ #define SQLITE_VERSION "--VERS--" /* ** The version string is also compiled into the library so that a program ** can check to make sure that the lib*.a file and the *.h file are from ** the same version. */ extern const char sqlite_version[]; |
︙ | ︙ | |||
69 70 71 72 73 74 75 | ** ** If mode does not indicates user write permission, then the ** database is opened read-only. ** ** The Truth: As currently implemented, all databases are opened ** for writing all the time. Maybe someday we will provide the ** ability to open a database readonly. The mode parameters is | | | 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | ** ** If mode does not indicates user write permission, then the ** database is opened read-only. ** ** The Truth: As currently implemented, all databases are opened ** for writing all the time. Maybe someday we will provide the ** ability to open a database readonly. The mode parameters is ** provided in anticipation of that enhancement. */ sqlite *sqlite_open(const char *filename, int mode, char **errmsg); /* ** A function to close the database. ** ** Call this function with a pointer to a structure that was previously |
︙ | ︙ | |||
114 115 116 117 118 119 120 | ** will be invoked. ** ** If an error occurs while parsing or evaluating the SQL (but ** not while executing the callback) then an appropriate error ** message is written into memory obtained from malloc() and ** *errmsg is made to point to that message. The calling function ** is responsible for freeing the memory that holds the error | > | | | 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 | ** will be invoked. ** ** If an error occurs while parsing or evaluating the SQL (but ** not while executing the callback) then an appropriate error ** message is written into memory obtained from malloc() and ** *errmsg is made to point to that message. The calling function ** is responsible for freeing the memory that holds the error ** message. Use sqlite_freemem() for this. If errmsg==NULL, ** then no error message is ever written. ** ** The return value is is SQLITE_OK if there are no errors and ** some other return code if there is an error. The particular ** return value depends on the type of error. ** ** If the query could not be executed because a database file is ** locked or busy, then this function returns SQLITE_BUSY. (This ** behavior can be modified somewhat using the sqlite_busy_handler() ** and sqlite_busy_timeout() functions below.) */ int sqlite_exec( sqlite*, /* An open database */ const char *sql, /* SQL to be executed */ sqlite_callback, /* Callback function */ void *, /* 1st argument to callback function */ char **errmsg /* Error msg written here */ ); /* ** Return values for sqlite_exec() and sqlite_step() */ #define SQLITE_OK 0 /* Successful result */ #define SQLITE_ERROR 1 /* SQL error or missing database */ #define SQLITE_INTERNAL 2 /* An internal logic error in SQLite */ #define SQLITE_PERM 3 /* Access permission denied */ #define SQLITE_ABORT 4 /* Callback routine requested an abort */ #define SQLITE_BUSY 5 /* The database file is locked */ |
︙ | ︙ | |||
160 161 162 163 164 165 166 167 168 169 170 171 172 173 | #define SQLITE_SCHEMA 17 /* The database schema changed */ #define SQLITE_TOOBIG 18 /* Too much data for one row of a table */ #define SQLITE_CONSTRAINT 19 /* Abort due to contraint violation */ #define SQLITE_MISMATCH 20 /* Data type mismatch */ #define SQLITE_MISUSE 21 /* Library used incorrectly */ #define SQLITE_NOLFS 22 /* Uses OS features not supported on host */ #define SQLITE_AUTH 23 /* Authorization denied */ /* ** Each entry in an SQLite table has a unique integer key. (The key is ** the value of the INTEGER PRIMARY KEY column if there is such a column, ** otherwise the key is generated at random. The unique key is always ** available as the ROWID, OID, or _ROWID_ column.) The following routine ** returns the integer key of the most recent insert in the database. | > > | 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | #define SQLITE_SCHEMA 17 /* The database schema changed */ #define SQLITE_TOOBIG 18 /* Too much data for one row of a table */ #define SQLITE_CONSTRAINT 19 /* Abort due to contraint violation */ #define SQLITE_MISMATCH 20 /* Data type mismatch */ #define SQLITE_MISUSE 21 /* Library used incorrectly */ #define SQLITE_NOLFS 22 /* Uses OS features not supported on host */ #define SQLITE_AUTH 23 /* Authorization denied */ #define SQLITE_ROW 100 /* sqlite_step() has another row ready */ #define SQLITE_DONE 101 /* sqlite_step() has finished executing */ /* ** Each entry in an SQLite table has a unique integer key. (The key is ** the value of the INTEGER PRIMARY KEY column if there is such a column, ** otherwise the key is generated at random. The unique key is always ** available as the ROWID, OID, or _ROWID_ column.) The following routine ** returns the integer key of the most recent insert in the database. |
︙ | ︙ | |||
497 498 499 500 501 502 503 | ** aggregate function instance. The current call to xStep counts so this ** routine always returns at least 1. */ int sqlite_aggregate_count(sqlite_func*); /* ** This routine registers a callback with the SQLite library. The | > | | | | | 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 | ** aggregate function instance. The current call to xStep counts so this ** routine always returns at least 1. */ int sqlite_aggregate_count(sqlite_func*); /* ** This routine registers a callback with the SQLite library. The ** callback is invoked (at compile-time, not at run-time) for each ** attempt to access a column of a table in the database. The callback ** returns SQLITE_OK if access is allowed, SQLITE_DENY if the entire ** SQL statement should be aborted with an error and SQLITE_IGNORE ** if the column should be treated as a NULL value. */ int sqlite_set_authorizer( sqlite*, int (*xAuth)(void*,int,const char*,const char*), void *pUserData ); |
︙ | ︙ | |||
551 552 553 554 555 556 557 | ** following constants: */ /* #define SQLITE_OK 0 // Allow access (This is actually defined above) */ #define SQLITE_DENY 1 /* Abort the SQL statement with an error */ #define SQLITE_IGNORE 2 /* Don't allow access, but don't generate an error */ /* | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 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 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 | ** following constants: */ /* #define SQLITE_OK 0 // Allow access (This is actually defined above) */ #define SQLITE_DENY 1 /* Abort the SQL statement with an error */ #define SQLITE_IGNORE 2 /* Don't allow access, but don't generate an error */ /* ** Register a function that is called at every invocation of sqlite_exec() ** or sqlite_compile(). This function can be used (for example) to generate ** a log file of all SQL executed against a database. */ void *sqlite_trace(sqlite*, void(*xTrace)(void*,const char*), void*); /*** The Callback-Free API ** ** The following routines implement a new way to access SQLite that does not ** involve the use of callbacks. ** ** An sqlite_vm is an opaque object that represents a single SQL statement ** that is ready to be executed. */ typedef struct sqlite_vm sqlite_vm; /* ** To execute an SQLite query without the use of callbacks, you first have ** to compile the SQL using this routine. The 1st parameter "db" is a pointer ** to an sqlite object obtained from sqlite_open(). The 2nd parameter ** "zSql" is the text of the SQL to be compiled. The remaining parameters ** are all outputs. ** ** *pzTail is made to point to the first character past the end of the first ** SQL statement in zSql. This routine only compiles the first statement ** in zSql, so *pzTail is left pointing to what remains uncompiled. ** ** *ppVm is left pointing to a "virtual machine" that can be used to execute ** the compiled statement. Or if there is an error, *ppVm may be set to NULL. ** ** If any errors are detected during compilation, an error message is written ** into space obtained from malloc() and *pzErrMsg is made to point to that ** error message. The calling routine is responsible for freeing the text ** of this message when it has finished with it. Use sqlite_freemem() to ** free the message. pzErrMsg may be NULL in which case no error message ** will be generated. ** ** On success, SQLITE_OK is returned. Otherwise and error code is returned. */ int sqlite_compile( sqlite *db, /* The open database */ const char *zSql, /* SQL statement to be compiled */ const char **pzTail, /* OUT: uncompiled tail of zSql */ sqlite_vm **ppVm, /* OUT: the virtual machine to execute zSql */ char **pzErrmsg /* OUT: Error message. */ ); /* ** After an SQL statement has been compiled, it is handed to this routine ** to be executed. This routine executes the statement as far as it can ** go then returns. The return value will be one of SQLITE_DONE, ** SQLITE_ERROR, SQLITE_BUSY, SQLITE_ROW, or SQLITE_MISUSE. ** ** SQLITE_DONE means that the execute of the SQL statement is complete ** an no errors have occurred. sqlite_step() should not be called again ** for the same virtual machine. *pN is set to the number of columns in ** the result set and *pazColName is set to an array of strings that ** describe the column names and datatypes. The name of the i-th column ** is (*pazColName)[i] and the datatype of the i-th column is ** (*pazColName)[i+*pN]. *pazValue is set to NULL. ** ** SQLITE_ERROR means that the virtual machine encountered a run-time ** error. sqlite_step() should not be called again for the same ** virtual machine. *pN is set to 0 and *pazColName and *pazValue are set ** to NULL. Use sqlite_finalize() to obtain the specific error code ** and the error message text for the error. ** ** SQLITE_BUSY means that an attempt to open the database failed because ** another thread or process is holding a lock. The calling routine ** can try again to open the database by calling sqlite_step() again. ** The return code will only be SQLITE_BUSY if no busy handler is registered ** using the sqlite_busy_handler() or sqlite_busy_timeout() routines. If ** a busy handler callback has been registered but returns 0, then this ** routine will return SQLITE_ERROR and sqltie_finalize() will return ** SQLITE_BUSY when it is called. ** ** SQLITE_ROW means that a single row of the result is now available. ** The data is contained in *pazValue. The value of the i-th column is ** (*azValue)[i]. *pN and *pazColName are set as described in SQLITE_DONE. ** Invoke sqlite_step() again to advance to the next row. ** ** SQLITE_MISUSE is returned if sqlite_step() is called incorrectly. ** For example, if you call sqlite_step() after the virtual machine ** has halted (after a prior call to sqlite_step() has returned SQLITE_DONE) ** or if you call sqlite_step() with an incorrectly initialized virtual ** machine or a virtual machine that has been deleted or that is associated ** with an sqlite structure that has been closed. */ int sqlite_step( sqlite_vm *pVm, /* The virtual machine to execute */ int *pN, /* OUT: Number of columns in result */ const char ***pazValue, /* OUT: Column data */ const char ***pazColName /* OUT: Column names and datatypes */ ); /* ** This routine is called to delete a virtual machine after it has finished ** executing. The return value is the result code. SQLITE_OK is returned ** if the statement executed successfully and some other value is returned if ** there was any kind of error. If an error occurred and pzErrMsg is not ** NULL, then an error message is written into memory obtained from malloc() ** and *pzErrMsg is made to point to that error message. The calling routine ** should use sqlite_freemem() to delete this message when it has finished ** with it. ** ** This routine can be called at any point during the execution of the ** virtual machine. If the virtual machine has not completed execution ** when this routine is called, that is like encountering an error or ** an interrupt. (See sqlite_interrupt().) Incomplete updates may be ** rolled back and transactions cancelled, depending on the circumstances, ** and the result code returned will be SQLITE_ABORT. */ int sqlite_finalize(sqlite_vm*, char **pzErrMsg); /* ** Attempt to open the file named in the argument as the auxiliary database ** file. The auxiliary database file is used to store TEMP tables. But ** by using this API, it is possible to trick SQLite into opening two ** separate databases and acting on them as if they were one. ** ****** THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE. ****** */ int sqlite_open_aux_file(sqlite *db, const char *zName, char **pzErrMsg); #ifdef __cplusplus } /* End of the 'extern "C"' block */ #endif #endif /* _SQLITE_H_ */ |
Changes to src/sqliteInt.h.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** ** @(#) $Id: sqliteInt.h,v 1.157 2003/01/28 23:13:12 drh Exp $ */ #include "config.h" #include "sqlite.h" #include "hash.h" #include "vdbe.h" #include "parse.h" #include "btree.h" |
︙ | ︙ | |||
744 745 746 747 748 749 750 751 752 753 754 755 756 757 | u8 initFlag; /* True if reparsing CREATE TABLEs */ u8 nameClash; /* A permanent table name clashes with temp table name */ u8 useAgg; /* If true, extract field values from the aggregator ** while generating expressions. Normally false */ u8 schemaVerified; /* True if an OP_VerifySchema has been coded someplace ** other than after an OP_Transaction */ u8 isTemp; /* True if parsing temporary tables */ int newTnum; /* Table number to use when reparsing CREATE TABLEs */ int nErr; /* Number of errors seen */ int nTab; /* Number of previously allocated VDBE cursors */ 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 */ | > | 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 | u8 initFlag; /* True if reparsing CREATE TABLEs */ u8 nameClash; /* A permanent table name clashes with temp table name */ u8 useAgg; /* If true, extract field values from the aggregator ** while generating expressions. Normally false */ u8 schemaVerified; /* True if an OP_VerifySchema has been coded someplace ** other than after an OP_Transaction */ u8 isTemp; /* True if parsing temporary tables */ u8 useCallback; /* True if callbacks should be used to report results */ int newTnum; /* Table number to use when reparsing CREATE TABLEs */ int nErr; /* Number of errors seen */ int nTab; /* Number of previously allocated VDBE cursors */ 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 */ |
︙ | ︙ |
Changes to src/test1.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the printf() interface to SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** | | > > > > > > > > > > > > > > > > > > > > > > | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the printf() interface to SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** ** $Id: test1.c,v 1.17 2003/01/28 23:13:12 drh Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include <stdlib.h> #include <string.h> /* ** Decode a pointer to an sqlite object. */ static int getDbPointer(Tcl_Interp *interp, const char *zArg, sqlite **ppDb){ if( sscanf(zArg, "%p", (void**)ppDb)!=1 ){ Tcl_AppendResult(interp, "\"", zArg, "\" is not a valid pointer value", 0); return TCL_ERROR; } return TCL_OK; } /* ** Decode a pointer to an sqlite_vm object. */ static int getVmPointer(Tcl_Interp *interp, const char *zArg, sqlite_vm **ppVm){ if( sscanf(zArg, "%p", (void**)ppVm)!=1 ){ Tcl_AppendResult(interp, "\"", zArg, "\" is not a valid pointer value", 0); return TCL_ERROR; } return TCL_OK; } /* ** Usage: sqlite_open filename ** ** Returns: The name of an open database. */ static int sqlite_test_open( |
︙ | ︙ | |||
41 42 43 44 45 46 47 | } db = sqlite_open(argv[1], 0666, &zErr); if( db==0 ){ Tcl_AppendResult(interp, zErr, 0); free(zErr); return TCL_ERROR; } | | | 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | } db = sqlite_open(argv[1], 0666, &zErr); if( db==0 ){ Tcl_AppendResult(interp, zErr, 0); free(zErr); return TCL_ERROR; } sprintf(zBuf,"%p", db); Tcl_AppendResult(interp, zBuf, 0); return TCL_OK; } /* ** The callback routine for sqlite_exec_printf(). */ |
︙ | ︙ | |||
87 88 89 90 91 92 93 | char *zErr = 0; char zBuf[30]; if( argc!=4 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB FORMAT STRING", 0); return TCL_ERROR; } | | | 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | char *zErr = 0; char zBuf[30]; if( argc!=4 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB FORMAT STRING", 0); return TCL_ERROR; } if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; Tcl_DStringInit(&str); rc = sqlite_exec_printf(db, argv[2], exec_printf_cb, &str, &zErr, argv[3]); sprintf(zBuf, "%d", rc); Tcl_AppendElement(interp, zBuf); Tcl_AppendElement(interp, rc==SQLITE_OK ? Tcl_DStringValue(&str) : zErr); Tcl_DStringFree(&str); if( zErr ) free(zErr); |
︙ | ︙ | |||
124 125 126 127 128 129 130 | int i; char zBuf[30]; if( argc!=4 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB FORMAT STRING", 0); return TCL_ERROR; } | | | 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | int i; char zBuf[30]; if( argc!=4 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB FORMAT STRING", 0); return TCL_ERROR; } if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; Tcl_DStringInit(&str); rc = sqlite_get_table_printf(db, argv[2], &aResult, &nRow, &nCol, &zErr, argv[3]); sprintf(zBuf, "%d", rc); Tcl_AppendElement(interp, zBuf); if( rc==SQLITE_OK ){ sprintf(zBuf, "%d", nRow); |
︙ | ︙ | |||
165 166 167 168 169 170 171 | sqlite *db; char zBuf[30]; if( argc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB\"", 0); return TCL_ERROR; } | | | 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 | sqlite *db; char zBuf[30]; if( argc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB\"", 0); return TCL_ERROR; } if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; sprintf(zBuf, "%d", sqlite_last_insert_rowid(db)); Tcl_AppendResult(interp, zBuf, 0); return SQLITE_OK; } /* ** Usage: sqlite_close DB |
︙ | ︙ | |||
188 189 190 191 192 193 194 | ){ sqlite *db; if( argc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " FILENAME\"", 0); return TCL_ERROR; } | | | 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 | ){ sqlite *db; if( argc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " FILENAME\"", 0); return TCL_ERROR; } if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; sqlite_close(db); return TCL_OK; } /* ** Implementation of the x_coalesce() function. ** Return the first argument non-NULL argument. |
︙ | ︙ | |||
247 248 249 250 251 252 253 | sqlite *db; extern void Md5_Register(sqlite*); if( argc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " FILENAME\"", 0); return TCL_ERROR; } | | | 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 | sqlite *db; extern void Md5_Register(sqlite*); if( argc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " FILENAME\"", 0); return TCL_ERROR; } if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; sqlite_create_function(db, "x_coalesce", -1, ifnullFunc, 0); sqlite_create_function(db, "x_sqlite_exec", 1, sqliteExecFunc, db); return TCL_OK; } /* ** Routines to implement the x_count() aggregate function. |
︙ | ︙ | |||
296 297 298 299 300 301 302 | ){ sqlite *db; if( argc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " FILENAME\"", 0); return TCL_ERROR; } | | | 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 | ){ sqlite *db; if( argc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " FILENAME\"", 0); return TCL_ERROR; } if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; sqlite_create_aggregate(db, "x_count", 0, countStep, countFinalize, 0); sqlite_create_aggregate(db, "x_count", 1, countStep, countFinalize, 0); return TCL_OK; } |
︙ | ︙ | |||
493 494 495 496 497 498 499 | sqlite *db; int rc; if( argc!=3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB FUNCTION-NAME", 0); return TCL_ERROR; } | | | 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 | sqlite *db; int rc; if( argc!=3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB FUNCTION-NAME", 0); return TCL_ERROR; } if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; rc = sqlite_create_function(db, argv[2], -1, testFunc, 0); if( rc!=0 ){ Tcl_AppendResult(interp, sqlite_error_string(rc), 0); return TCL_ERROR; } return TCL_OK; } |
︙ | ︙ | |||
546 547 548 549 550 551 552 | sqlite *db; int rc; if( argc!=3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB SQL", 0); return TCL_ERROR; } | | | 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 | sqlite *db; int rc; if( argc!=3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB SQL", 0); return TCL_ERROR; } if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; rc = sqlite_exec(db, argv[2], rememberDataTypes, interp, 0); if( rc!=0 && rc!=SQLITE_ABORT ){ Tcl_AppendResult(interp, sqlite_error_string(rc), 0); return TCL_ERROR; } return TCL_OK; } |
︙ | ︙ | |||
655 656 657 658 659 660 661 | sqlite *db; char *zCmd; if( argc!=3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB CALLBACK\"", 0); return TCL_ERROR; } | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 677 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 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 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 799 800 801 802 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 | sqlite *db; char *zCmd; if( argc!=3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB CALLBACK\"", 0); return TCL_ERROR; } if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; zCmd = argv[2]; if( zCmd[0]==0 ){ sqlite_set_authorizer(db, 0, 0); return TCL_OK; } if( strlen(zCmd)>sizeof(authInfo.zCmd) ){ Tcl_AppendResult(interp, "command too big", 0); return TCL_ERROR; } authInfo.interp = interp; authInfo.nCmd = strlen(zCmd); strcpy(authInfo.zCmd, zCmd); sqlite_set_authorizer(db, auth_callback, 0); return TCL_OK; } #endif /* SQLITE_OMIT_AUTHORIZATION */ /* ** Usage: sqlite_compile DB SQL TAILVAR ** ** Attempt to compile an SQL statement. Return a pointer to the virtual ** machine used to execute that statement. Unprocessed SQL is written ** into TAILVAR. */ static int test_compile( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ char **argv /* Text of each argument */ ){ sqlite *db; sqlite_vm *vm; int rc; char *zErr = 0; const char *zTail; char zBuf[50]; if( argc!=4 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB SQL TAILVAR", 0); return TCL_ERROR; } if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; rc = sqlite_compile(db, argv[2], &zTail, &vm, &zErr); if( rc ){ assert( vm==0 ); sprintf(zBuf, "(%d) ", rc); Tcl_AppendResult(interp, zBuf, zErr, 0); sqlite_freemem(zErr); return TCL_ERROR; } sprintf(zBuf, "%p", vm); Tcl_AppendResult(interp, zBuf, 0); Tcl_SetVar(interp, argv[3], zTail, 0); return TCL_OK; } /* ** Usage: sqlite_step VM NVAR VALUEVAR COLNAMEVAR ** ** Step a virtual machine. Return a the result code as a string. ** Column results are written into three variables. */ static int test_step( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ char **argv /* Text of each argument */ ){ sqlite_vm *vm; int rc, i; const char **azValue; const char **azColName; int N; char *zRc; char zBuf[50]; if( argc!=5 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " VM NVAR VALUEVAR COLNAMEVAR", 0); return TCL_ERROR; } if( getVmPointer(interp, argv[1], &vm) ) return TCL_ERROR; rc = sqlite_step(vm, &N, &azValue, &azColName); if( rc==SQLITE_DONE || SQLITE_ROW ){ sprintf(zBuf, "%d", N); Tcl_SetVar(interp, argv[2], zBuf, 0); Tcl_SetVar(interp, argv[3], "", 0); if( rc==SQLITE_ROW ){ for(i=0; i<N; i++){ Tcl_SetVar(interp, argv[3], azValue[i] ? azValue[i] : "", TCL_APPEND_VALUE | TCL_LIST_ELEMENT); } } Tcl_SetVar(interp, argv[4], "", 0); for(i=0; i<N*2; i++){ Tcl_SetVar(interp, argv[4], azValue[i] ? azValue[i] : "", TCL_APPEND_VALUE | TCL_LIST_ELEMENT); } } switch( rc ){ case SQLITE_DONE: zRc = "SQLITE_DONE"; break; case SQLITE_BUSY: zRc = "SQLITE_DONE"; break; case SQLITE_ROW: zRc = "SQLITE_DONE"; break; case SQLITE_ERROR: zRc = "SQLITE_DONE"; break; case SQLITE_MISUSE: zRc = "SQLITE_MISUSE"; break; default: zRc = "unknown"; break; } Tcl_AppendResult(interp, zRc, 0); return TCL_OK; } /* ** Usage: sqlite_finalize VM ** ** Shutdown a virtual machine. */ static int test_finalize( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ char **argv /* Text of each argument */ ){ sqlite_vm *vm; int rc; char *zErrMsg = 0; if( argc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " VM NVAR VALUEVAR COLNAMEVAR", 0); return TCL_ERROR; } if( getVmPointer(interp, argv[1], &vm) ) return TCL_ERROR; rc = sqlite_finalize(vm, &zErrMsg); if( rc ){ char zBuf[50]; sprintf(zBuf, "(%d) ", rc); Tcl_AppendResult(interp, zBuf, zErrMsg, 0); sqlite_freemem(zErrMsg); return TCL_ERROR; } return TCL_OK; } /* ** Register commands with the TCL interpreter. */ int Sqlitetest1_Init(Tcl_Interp *interp){ extern int sqlite_search_count; static struct { char *zName; |
︙ | ︙ | |||
702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 | #ifndef SQLITE_OMIT_AUTHORIZATION { "sqlite_set_authorizer", (Tcl_CmdProc*)test_set_authorizer }, #endif #ifdef MEMORY_DEBUG { "sqlite_malloc_fail", (Tcl_CmdProc*)sqlite_malloc_fail }, { "sqlite_malloc_stat", (Tcl_CmdProc*)sqlite_malloc_stat }, #endif }; int i; for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){ Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0); } Tcl_LinkVar(interp, "sqlite_search_count", (char*)&sqlite_search_count, TCL_LINK_INT); return TCL_OK; } | > > > | 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 | #ifndef SQLITE_OMIT_AUTHORIZATION { "sqlite_set_authorizer", (Tcl_CmdProc*)test_set_authorizer }, #endif #ifdef MEMORY_DEBUG { "sqlite_malloc_fail", (Tcl_CmdProc*)sqlite_malloc_fail }, { "sqlite_malloc_stat", (Tcl_CmdProc*)sqlite_malloc_stat }, #endif { "sqlite_compile", (Tcl_CmdProc*)test_compile }, { "sqlite_step", (Tcl_CmdProc*)test_step }, { "sqlite_finalize", (Tcl_CmdProc*)test_finalize }, }; int i; for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){ Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0); } Tcl_LinkVar(interp, "sqlite_search_count", (char*)&sqlite_search_count, TCL_LINK_INT); return TCL_OK; } |
Changes to src/tokenize.c.
︙ | ︙ | |||
11 12 13 14 15 16 17 | ************************************************************************* ** An tokenizer for SQL ** ** This file contains C code that splits an SQL input string up into ** individual tokens and sends those tokens one-by-one over to the ** parser for analysis. ** | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | ************************************************************************* ** An tokenizer for SQL ** ** This file contains C code that splits an SQL input string up into ** individual tokens and sends those tokens one-by-one over to the ** parser for analysis. ** ** $Id: tokenize.c,v 1.54 2003/01/28 23:13:12 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> #include <stdlib.h> /* |
︙ | ︙ | |||
402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 | ** memory obtained from malloc() and *pzErrMsg made to point to that ** error message. Or maybe not. */ int sqliteRunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ int nErr = 0; int i; void *pEngine; sqlite *db = pParse->db; extern void *sqliteParserAlloc(void*(*)(int)); extern void sqliteParserFree(void*, void(*)(void*)); extern int sqliteParser(void*, int, Token, Parse*); db->flags &= ~SQLITE_Interrupt; pParse->rc = SQLITE_OK; i = 0; pEngine = sqliteParserAlloc((void*(*)(int))malloc); if( pEngine==0 ){ sqliteSetString(pzErrMsg, "out of memory", 0); return 1; } pParse->sLastToken.dyn = 0; while( sqlite_malloc_failed==0 && zSql[i]!=0 ){ | > > < | 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 | ** memory obtained from malloc() and *pzErrMsg made to point to that ** error message. Or maybe not. */ int sqliteRunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ int nErr = 0; int i; void *pEngine; int tokenType; int lastTokenParsed = -1; sqlite *db = pParse->db; extern void *sqliteParserAlloc(void*(*)(int)); extern void sqliteParserFree(void*, void(*)(void*)); extern int sqliteParser(void*, int, Token, Parse*); db->flags &= ~SQLITE_Interrupt; pParse->rc = SQLITE_OK; i = 0; pEngine = sqliteParserAlloc((void*(*)(int))malloc); if( pEngine==0 ){ sqliteSetString(pzErrMsg, "out of memory", 0); return 1; } pParse->sLastToken.dyn = 0; while( sqlite_malloc_failed==0 && zSql[i]!=0 ){ assert( i>=0 ); pParse->sLastToken.z = &zSql[i]; assert( pParse->sLastToken.dyn==0 ); pParse->sLastToken.n = sqliteGetToken((unsigned char*)&zSql[i], &tokenType); i += pParse->sLastToken.n; switch( tokenType ){ |
︙ | ︙ | |||
442 443 444 445 446 447 448 | sqliteSetNString(pzErrMsg, "unrecognized token: \"", -1, pParse->sLastToken.z, pParse->sLastToken.n, "\"", 1, 0); nErr++; goto abort_parse; } default: { sqliteParser(pEngine, tokenType, pParse->sLastToken, pParse); | < < < < | < < < < < | < < | > | > < < < < < < < < < | < > > > | < > | | | 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 | sqliteSetNString(pzErrMsg, "unrecognized token: \"", -1, pParse->sLastToken.z, pParse->sLastToken.n, "\"", 1, 0); nErr++; goto abort_parse; } default: { sqliteParser(pEngine, tokenType, pParse->sLastToken, pParse); lastTokenParsed = tokenType; if( pParse->rc!=SQLITE_OK ){ goto abort_parse; } break; } } } abort_parse: if( zSql[i]==0 && nErr==0 && pParse->rc==SQLITE_OK ){ if( lastTokenParsed!=TK_SEMI ){ sqliteParser(pEngine, TK_SEMI, pParse->sLastToken, pParse); } sqliteParser(pEngine, 0, pParse->sLastToken, pParse); } sqliteParserFree(pEngine, free); if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){ sqliteSetString(&pParse->zErrMsg, sqlite_error_string(pParse->rc), 0); } if( pParse->zErrMsg ){ if( pzErrMsg && *pzErrMsg==0 ){ *pzErrMsg = pParse->zErrMsg; }else{ sqliteFree(pParse->zErrMsg); } pParse->zErrMsg = 0; if( !nErr ) nErr++; } if( pParse->pVdbe && (pParse->useCallback || pParse->nErr>0) ){ sqliteVdbeDelete(pParse->pVdbe); pParse->pVdbe = 0; } if( pParse->pNewTable ){ sqliteDeleteTable(pParse->db, pParse->pNewTable); pParse->pNewTable = 0; } if( nErr>0 && (pParse->rc==SQLITE_OK || pParse->rc==SQLITE_DONE) ){ pParse->rc = SQLITE_ERROR; } return nErr; } |
Changes to src/vdbe.c.
︙ | ︙ | |||
32 33 34 35 36 37 38 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** | | | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** ** $Id: vdbe.c,v 1.200 2003/01/28 23:13:12 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** The makefile scans this source file and creates the following ** array of string constants which are the names of all VDBE opcodes. |
︙ | ︙ | |||
230 231 232 233 234 235 236 | int nUsed; /* Next unwritten slot in aKey[] */ int nRead; /* Next unread slot in aKey[] */ Keylist *pNext; /* Next block of keys */ int aKey[1]; /* One or more keys. Extra space allocated as needed */ }; /* | | > > > > < | > | | | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > | 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 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 | int nUsed; /* Next unwritten slot in aKey[] */ int nRead; /* Next unread slot in aKey[] */ Keylist *pNext; /* Next block of keys */ int aKey[1]; /* One or more keys. Extra space allocated as needed */ }; /* ** An instance of the virtual machine. This structure contains the complete ** state of the virtual machine. ** ** The "sqlite_vm" structure pointer that is returned by sqlite_compile() ** is really a pointer to an instance of this structure. */ struct Vdbe { sqlite *db; /* The whole database */ Btree *pBt; /* Opaque context structure used by DB backend */ FILE *trace; /* Write an execution trace here, if not NULL */ int nOp; /* Number of instructions in the program */ int nOpAlloc; /* Number of slots allocated for aOp[] */ Op *aOp; /* Space to hold the virtual machine's program */ int nLabel; /* Number of labels used */ int nLabelAlloc; /* Number of slots allocated in aLabel[] */ int *aLabel; /* Space to hold the labels */ int tos; /* Index of top of stack */ Stack *aStack; /* The operand stack, except string values */ char **zStack; /* Text or binary values of the stack */ char **azColName; /* Becomes the 4th parameter to callbacks */ int nCursor; /* Number of slots in aCsr[] */ Cursor *aCsr; /* One element of this array for each open cursor */ Sorter *pSort; /* A linked list of objects to be sorted */ FILE *pFile; /* At most one open file handler */ int nField; /* Number of file fields */ char **azField; /* Data for each file field */ char *zLine; /* A single line from the input file */ int magic; /* Magic number for sanity checking */ int nLineAlloc; /* Number of spaces allocated for zLine */ int nMem; /* Number of memory locations currently allocated */ Mem *aMem; /* The memory locations */ Agg agg; /* Aggregate information */ int nSet; /* Number of sets allocated */ Set *aSet; /* An array of sets */ int nCallback; /* Number of callbacks invoked so far */ Keylist *pList; /* A list of ROWIDs */ int keylistStackDepth; /* The size of the "keylist" stack */ Keylist **keylistStack; /* The stack used by opcodes ListPush & ListPop */ int pc; /* The program counter */ int rc; /* Value to return */ unsigned uniqueCnt; /* Used by OP_MakeRecord when P2!=0 */ int errorAction; /* Recovery action to do in case of an error */ int undoTransOnError; /* If error, either ROLLBACK or COMMIT */ int inTempTrans; /* True if temp database is transactioned */ int returnStack[100]; /* Return address stack for OP_Gosub & OP_Return */ int returnDepth; /* Next unused element in returnStack[] */ int nResColumn; /* Number of columns in one row of the result set */ char **azResColumn; /* Values for one row of result */ int (*xCallback)(void*,int,char**,char**); /* Callback for SELECT results */ void *pCbArg; /* First argument to xCallback() */ int popStack; /* Pop the stack this much on entry to VdbeExec() */ char *zErrMsg; /* Error message written here */ u8 explain; /* True if EXPLAIN present on SQL command */ }; /* ** The following are allowed values for Vdbe.magic */ #define VDBE_MAGIC_INIT 0x26bceaa5 /* Building a VDBE program */ #define VDBE_MAGIC_RUN 0xbdf20da3 /* VDBE is ready to execute */ #define VDBE_MAGIC_HALT 0x519c2973 /* VDBE has completed execution */ #define VDBE_MAGIC_DEAD 0xb606c3c8 /* The VDBE has been deallocated */ /* ** When debugging the code generator in a symbolic debugger, one can ** set the sqlite_vdbe_addop_trace to 1 and all opcodes will be printed ** as they are added to the instruction stream. */ #ifndef NDEBUG int sqlite_vdbe_addop_trace = 0; static void vdbePrintOp(FILE*, int, Op*); #endif /* ** Create a new virtual database engine. */ Vdbe *sqliteVdbeCreate(sqlite *db){ Vdbe *p; p = sqliteMalloc( sizeof(Vdbe) ); if( p==0 ) return 0; p->pBt = db->pBe; p->db = db; p->magic = VDBE_MAGIC_INIT; return p; } /* ** Turn tracing on or off */ void sqliteVdbeTrace(Vdbe *p, FILE *trace){ |
︙ | ︙ | |||
315 316 317 318 319 320 321 322 323 324 325 326 327 328 | ** operand. */ int sqliteVdbeAddOp(Vdbe *p, int op, int p1, int p2){ int i; i = p->nOp; p->nOp++; if( i>=p->nOpAlloc ){ int oldSize = p->nOpAlloc; Op *aNew; p->nOpAlloc = p->nOpAlloc*2 + 100; aNew = sqliteRealloc(p->aOp, p->nOpAlloc*sizeof(Op)); if( aNew==0 ){ p->nOpAlloc = oldSize; | > | 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 | ** operand. */ int sqliteVdbeAddOp(Vdbe *p, int op, int p1, int p2){ int i; i = p->nOp; p->nOp++; assert( p->magic==VDBE_MAGIC_INIT ); if( i>=p->nOpAlloc ){ int oldSize = p->nOpAlloc; Op *aNew; p->nOpAlloc = p->nOpAlloc*2 + 100; aNew = sqliteRealloc(p->aOp, p->nOpAlloc*sizeof(Op)); if( aNew==0 ){ p->nOpAlloc = oldSize; |
︙ | ︙ | |||
356 357 358 359 360 361 362 363 364 365 366 367 368 369 | ** The VDBE knows that a P2 value is a label because labels are ** always negative and P2 values are suppose to be non-negative. ** Hence, a negative P2 value is a label that has yet to be resolved. */ int sqliteVdbeMakeLabel(Vdbe *p){ int i; i = p->nLabel++; if( i>=p->nLabelAlloc ){ int *aNew; p->nLabelAlloc = p->nLabelAlloc*2 + 10; aNew = sqliteRealloc( p->aLabel, p->nLabelAlloc*sizeof(p->aLabel[0])); if( aNew==0 ){ sqliteFree(p->aLabel); } | > | 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 | ** The VDBE knows that a P2 value is a label because labels are ** always negative and P2 values are suppose to be non-negative. ** Hence, a negative P2 value is a label that has yet to be resolved. */ int sqliteVdbeMakeLabel(Vdbe *p){ int i; i = p->nLabel++; assert( p->magic==VDBE_MAGIC_INIT ); if( i>=p->nLabelAlloc ){ int *aNew; p->nLabelAlloc = p->nLabelAlloc*2 + 10; aNew = sqliteRealloc( p->aLabel, p->nLabelAlloc*sizeof(p->aLabel[0])); if( aNew==0 ){ sqliteFree(p->aLabel); } |
︙ | ︙ | |||
381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 | /* ** Resolve label "x" to be the address of the next instruction to ** be inserted. The parameter "x" must have been obtained from ** a prior call to sqliteVdbeMakeLabel(). */ void sqliteVdbeResolveLabel(Vdbe *p, int x){ int j; if( x<0 && (-x)<=p->nLabel && p->aOp ){ if( p->aLabel[-1-x]==p->nOp ) return; assert( p->aLabel[-1-x]<0 ); p->aLabel[-1-x] = p->nOp; for(j=0; j<p->nOp; j++){ if( p->aOp[j].p2==x ) p->aOp[j].p2 = p->nOp; } } } /* ** Return the address of the next instruction to be inserted. */ int sqliteVdbeCurrentAddr(Vdbe *p){ return p->nOp; } /* ** Add a whole list of operations to the operation stack. Return the ** address of the first operation added. */ int sqliteVdbeAddOpList(Vdbe *p, int nOp, VdbeOp const *aOp){ int addr; if( p->nOp + nOp >= p->nOpAlloc ){ int oldSize = p->nOpAlloc; Op *aNew; p->nOpAlloc = p->nOpAlloc*2 + nOp + 10; aNew = sqliteRealloc(p->aOp, p->nOpAlloc*sizeof(Op)); if( aNew==0 ){ p->nOpAlloc = oldSize; | > > > | 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 | /* ** Resolve label "x" to be the address of the next instruction to ** be inserted. The parameter "x" must have been obtained from ** a prior call to sqliteVdbeMakeLabel(). */ void sqliteVdbeResolveLabel(Vdbe *p, int x){ int j; assert( p->magic==VDBE_MAGIC_INIT ); if( x<0 && (-x)<=p->nLabel && p->aOp ){ if( p->aLabel[-1-x]==p->nOp ) return; assert( p->aLabel[-1-x]<0 ); p->aLabel[-1-x] = p->nOp; for(j=0; j<p->nOp; j++){ if( p->aOp[j].p2==x ) p->aOp[j].p2 = p->nOp; } } } /* ** Return the address of the next instruction to be inserted. */ int sqliteVdbeCurrentAddr(Vdbe *p){ assert( p->magic==VDBE_MAGIC_INIT ); return p->nOp; } /* ** Add a whole list of operations to the operation stack. Return the ** address of the first operation added. */ int sqliteVdbeAddOpList(Vdbe *p, int nOp, VdbeOp const *aOp){ int addr; assert( p->magic==VDBE_MAGIC_INIT ); if( p->nOp + nOp >= p->nOpAlloc ){ int oldSize = p->nOpAlloc; Op *aNew; p->nOpAlloc = p->nOpAlloc*2 + nOp + 10; aNew = sqliteRealloc(p->aOp, p->nOpAlloc*sizeof(Op)); if( aNew==0 ){ p->nOpAlloc = oldSize; |
︙ | ︙ | |||
440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 | /* ** Change the value of the P1 operand for a specific instruction. ** This routine is useful when a large program is loaded from a ** static array using sqliteVdbeAddOpList but we want to make a ** few minor changes to the program. */ void sqliteVdbeChangeP1(Vdbe *p, int addr, int val){ if( p && addr>=0 && p->nOp>addr && p->aOp ){ p->aOp[addr].p1 = val; } } /* ** Change the value of the P2 operand for a specific instruction. ** This routine is useful for setting a jump destination. */ void sqliteVdbeChangeP2(Vdbe *p, int addr, int val){ assert( val>=0 ); if( p && addr>=0 && p->nOp>addr && p->aOp ){ p->aOp[addr].p2 = val; } } /* ** Change the value of the P3 operand for a specific instruction. | > > | 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 | /* ** Change the value of the P1 operand for a specific instruction. ** This routine is useful when a large program is loaded from a ** static array using sqliteVdbeAddOpList but we want to make a ** few minor changes to the program. */ void sqliteVdbeChangeP1(Vdbe *p, int addr, int val){ assert( p->magic==VDBE_MAGIC_INIT ); if( p && addr>=0 && p->nOp>addr && p->aOp ){ p->aOp[addr].p1 = val; } } /* ** Change the value of the P2 operand for a specific instruction. ** This routine is useful for setting a jump destination. */ void sqliteVdbeChangeP2(Vdbe *p, int addr, int val){ assert( val>=0 ); assert( p->magic==VDBE_MAGIC_INIT ); if( p && addr>=0 && p->nOp>addr && p->aOp ){ p->aOp[addr].p2 = val; } } /* ** Change the value of the P3 operand for a specific instruction. |
︙ | ︙ | |||
475 476 477 478 479 480 481 482 483 484 485 486 487 488 | ** string and we can just copy the pointer. n==P3_POINTER means zP3 is ** a pointer to some object other than a string. ** ** If addr<0 then change P3 on the most recently inserted instruction. */ void sqliteVdbeChangeP3(Vdbe *p, int addr, const char *zP3, int n){ Op *pOp; if( p==0 || p->aOp==0 ) return; if( addr<0 || addr>=p->nOp ){ addr = p->nOp - 1; if( addr<0 ) return; } pOp = &p->aOp[addr]; if( pOp->p3 && pOp->p3type==P3_DYNAMIC ){ | > | 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 | ** string and we can just copy the pointer. n==P3_POINTER means zP3 is ** a pointer to some object other than a string. ** ** If addr<0 then change P3 on the most recently inserted instruction. */ void sqliteVdbeChangeP3(Vdbe *p, int addr, const char *zP3, int n){ Op *pOp; assert( p->magic==VDBE_MAGIC_INIT ); if( p==0 || p->aOp==0 ) return; if( addr<0 || addr>=p->nOp ){ addr = p->nOp - 1; if( addr<0 ) return; } pOp = &p->aOp[addr]; if( pOp->p3 && pOp->p3type==P3_DYNAMIC ){ |
︙ | ︙ | |||
508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 | ** ** The quoting operator can be either a grave ascent (ASCII 0x27) ** or a double quote character (ASCII 0x22). Two quotes in a row ** resolve to be a single actual quote character within the string. */ void sqliteVdbeDequoteP3(Vdbe *p, int addr){ Op *pOp; if( p->aOp==0 || addr<0 || addr>=p->nOp ) return; pOp = &p->aOp[addr]; if( pOp->p3==0 || pOp->p3[0]==0 ) return; if( pOp->p3type==P3_POINTER ) return; if( pOp->p3type!=P3_DYNAMIC ){ pOp->p3 = sqliteStrDup(pOp->p3); pOp->p3type = P3_DYNAMIC; } sqliteDequote(pOp->p3); } /* ** On the P3 argument of the given instruction, change all ** strings of whitespace characters into a single space and ** delete leading and trailing whitespace. */ void sqliteVdbeCompressSpace(Vdbe *p, int addr){ char *z; int i, j; Op *pOp; if( p->aOp==0 || addr<0 || addr>=p->nOp ) return; pOp = &p->aOp[addr]; if( pOp->p3type==P3_POINTER ){ return; } if( pOp->p3type!=P3_DYNAMIC ){ pOp->p3 = sqliteStrDup(pOp->p3); | > > | 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 | ** ** The quoting operator can be either a grave ascent (ASCII 0x27) ** or a double quote character (ASCII 0x22). Two quotes in a row ** resolve to be a single actual quote character within the string. */ void sqliteVdbeDequoteP3(Vdbe *p, int addr){ Op *pOp; assert( p->magic==VDBE_MAGIC_INIT ); if( p->aOp==0 || addr<0 || addr>=p->nOp ) return; pOp = &p->aOp[addr]; if( pOp->p3==0 || pOp->p3[0]==0 ) return; if( pOp->p3type==P3_POINTER ) return; if( pOp->p3type!=P3_DYNAMIC ){ pOp->p3 = sqliteStrDup(pOp->p3); pOp->p3type = P3_DYNAMIC; } sqliteDequote(pOp->p3); } /* ** On the P3 argument of the given instruction, change all ** strings of whitespace characters into a single space and ** delete leading and trailing whitespace. */ void sqliteVdbeCompressSpace(Vdbe *p, int addr){ char *z; int i, j; Op *pOp; assert( p->magic==VDBE_MAGIC_INIT ); if( p->aOp==0 || addr<0 || addr>=p->nOp ) return; pOp = &p->aOp[addr]; if( pOp->p3type==P3_POINTER ){ return; } if( pOp->p3type!=P3_DYNAMIC ){ pOp->p3 = sqliteStrDup(pOp->p3); |
︙ | ︙ | |||
559 560 561 562 563 564 565 566 567 568 569 570 571 572 | /* ** Search for the current program for the given opcode and P2 ** value. Return 1 if found and 0 if not found. */ int sqliteVdbeFindOp(Vdbe *p, int op, int p2){ int i; for(i=0; i<p->nOp; i++){ if( p->aOp[i].opcode==op && p->aOp[i].p2==p2 ) return 1; } return 0; } /* | > | 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 | /* ** Search for the current program for the given opcode and P2 ** value. Return 1 if found and 0 if not found. */ int sqliteVdbeFindOp(Vdbe *p, int op, int p2){ int i; assert( p->magic==VDBE_MAGIC_INIT ); for(i=0; i<p->nOp; i++){ if( p->aOp[i].opcode==op && p->aOp[i].p2==p2 ) return 1; } return 0; } /* |
︙ | ︙ | |||
683 684 685 686 687 688 689 690 691 692 693 694 695 696 | ** the internals of the sqlite_func structure which is only defined in ** this source file. */ int sqlite_aggregate_count(sqlite_func *p){ assert( p && p->pFunc && p->pFunc->xStep ); return p->cnt; } /* ** Reset an Agg structure. Delete all its contents. ** ** For installable aggregate functions, if the step function has been ** called, make sure the finalizer function has also been called. The ** finalizer might need to free memory that was allocated as part of its | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 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 | ** the internals of the sqlite_func structure which is only defined in ** this source file. */ int sqlite_aggregate_count(sqlite_func *p){ assert( p && p->pFunc && p->pFunc->xStep ); return p->cnt; } /* ** Advance the virtual machine to the next output row. ** ** The return vale will be either SQLITE_BUSY, SQLITE_DONE, or ** SQLITE_ROW. ** ** SQLITE_BUSY means that the virtual machine attempted to open ** a locked database and there is no busy callback registered. ** Call sqlite_step() again to retry the open. *pN is set to 0 ** and *pazColName and *pazValue are both set to NULL. ** ** SQLITE_DONE means that the virtual machine has finished ** executing. sqlite_step() should not be called again on this ** virtual machine. *pN and *pazColName are set appropriately ** but *pazValue is set to NULL. ** ** SQLITE_ROW means that the virtual machine has generated another ** row of the result set. *pN is set to the number of columns in ** the row. *pazColName is set to the names of the columns followed ** by the column datatypes. *pazValue is set to the values of each ** column in the row. The value of the i-th column is (*pazValue)[i]. ** The name of the i-th column is (*pazColName)[i] and the datatype ** of the i-th column is (*pazColName)[i+*pN]. ** ** If a run-time error is encountered, SQLITE_DONE is returned. You ** can access the error code and error message using the sqlite_finalize() ** routine. */ int sqlite_step( sqlite_vm *pVm, /* The virtual machine to execute */ int *pN, /* OUT: Number of columns in result */ const char ***pazValue, /* OUT: Column data */ const char ***pazColName /* OUT: Column names and datatypes */ ){ Vdbe *p = (Vdbe*)pVm; int rc; if( p->magic!=VDBE_MAGIC_RUN ){ return SQLITE_MISUSE; } if( p->explain ){ rc = sqliteVdbeList(p); }else{ rc = sqliteVdbeExec(p); } if( rc!=SQLITE_DONE ){ *pazColName = (const char**)p->azColName; *pN = p->nResColumn; }else{ *pN = 0; *pazColName = 0; } if( rc==SQLITE_ROW ){ *pazValue = (const char**)p->azResColumn; }else{ *pazValue = 0; } return rc; } /* ** Reset an Agg structure. Delete all its contents. ** ** For installable aggregate functions, if the step function has been ** called, make sure the finalizer function has also been called. The ** finalizer might need to free memory that was allocated as part of its |
︙ | ︙ | |||
1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 | for(ii = 0; ii < p->keylistStackDepth; ii++){ KeylistFree(p->keylistStack[ii]); } sqliteFree(p->keylistStack); p->keylistStackDepth = 0; p->keylistStack = 0; } } /* ** Delete an entire VDBE. */ void sqliteVdbeDelete(Vdbe *p){ int i; | > > > | 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 | for(ii = 0; ii < p->keylistStackDepth; ii++){ KeylistFree(p->keylistStack[ii]); } sqliteFree(p->keylistStack); p->keylistStackDepth = 0; p->keylistStack = 0; } sqliteFree(p->zErrMsg); p->zErrMsg = 0; p->magic = VDBE_MAGIC_DEAD; } /* ** Delete an entire VDBE. */ void sqliteVdbeDelete(Vdbe *p){ int i; |
︙ | ︙ | |||
1107 1108 1109 1110 1111 1112 1113 | ** Give a listing of the program in the virtual machine. ** ** The interface is the same as sqliteVdbeExec(). But instead of ** running the code, it invokes the callback once for each instruction. ** This feature is used to implement "EXPLAIN". */ int sqliteVdbeList( | | < < < | < < < < < | > > | < > | | | | | | | | | | | | | | | > > > > > > | | | | | | 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 | ** Give a listing of the program in the virtual machine. ** ** The interface is the same as sqliteVdbeExec(). But instead of ** running the code, it invokes the callback once for each instruction. ** This feature is used to implement "EXPLAIN". */ int sqliteVdbeList( Vdbe *p /* The VDBE */ ){ sqlite *db = p->db; int i; static char *azColumnNames[] = { "addr", "opcode", "p1", "p2", "p3", "int", "text", "int", "int", "text", 0 }; assert( p->popStack==0 ); assert( p->explain ); p->azColName = azColumnNames; p->azResColumn = p->zStack; for(i=0; i<5; i++) p->zStack[i] = p->aStack[i].z; p->rc = SQLITE_OK; for(i=p->pc; p->rc==SQLITE_OK && i<p->nOp; i++){ if( db->flags & SQLITE_Interrupt ){ db->flags &= ~SQLITE_Interrupt; if( db->magic!=SQLITE_MAGIC_BUSY ){ p->rc = SQLITE_MISUSE; }else{ p->rc = SQLITE_INTERRUPT; } sqliteSetString(&p->zErrMsg, sqlite_error_string(p->rc), 0); break; } sprintf(p->zStack[0],"%d",i); sprintf(p->zStack[2],"%d", p->aOp[i].p1); sprintf(p->zStack[3],"%d", p->aOp[i].p2); if( p->aOp[i].p3type==P3_POINTER ){ sprintf(p->aStack[4].z, "ptr(%#x)", (int)p->aOp[i].p3); p->zStack[4] = p->aStack[4].z; }else{ p->zStack[4] = p->aOp[i].p3; } p->zStack[1] = sqliteOpcodeNames[p->aOp[i].opcode]; if( p->xCallback==0 ){ p->pc = i+1; p->azResColumn = p->zStack; p->nResColumn = 5; return SQLITE_CALLBACK; } if( sqliteSafetyOff(db) ){ p->rc = SQLITE_MISUSE; break; } if( p->xCallback(p->pCbArg, 5, p->zStack, p->azColName) ){ p->rc = SQLITE_ABORT; } if( sqliteSafetyOn(db) ){ p->rc = SQLITE_MISUSE; } } return p->rc==SQLITE_OK ? SQLITE_OK : SQLITE_ERROR; } /* ** The parameters are pointers to the head of two sorted lists ** of Sorter structures. Merge these two lists together and return ** a single sorted list. This routine forms the core of the merge-sort ** algorithm. |
︙ | ︙ | |||
1339 1340 1341 1342 1343 1344 1345 | ** flag on jump instructions, we get a (small) speed improvement. */ #define CHECK_FOR_INTERRUPT \ if( db->flags & SQLITE_Interrupt ) goto abort_due_to_interrupt; /* | > | < | < < | < < < > | < < | < < < < > | < < < | | | | | < < | < > < < | | < < < | < < < < < | | | < | > > < | | | | < < | < < < < < < < < < < < < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 | ** flag on jump instructions, we get a (small) speed improvement. */ #define CHECK_FOR_INTERRUPT \ if( db->flags & SQLITE_Interrupt ) goto abort_due_to_interrupt; /* ** Prepare a virtual machine for execution. This involves things such ** as allocating stack space and initializing the program counter. ** After the VDBE has be prepped, it can be executed by one or more ** calls to sqliteVdbeExec(). ** ** The behavior of sqliteVdbeExec() is influenced by the parameters to ** this routine. If xCallback is NULL, then sqliteVdbeExec() will return ** with SQLITE_CALLBACK whenever there is a row of the result set ready ** to be delivered. p->azResColumn will point to the row and ** p->nResColumn gives the number of columns in the row. If xCallback ** is not NULL, then the xCallback() routine is invoked to process each ** row in the result set. */ void sqliteVdbeMakeReady( Vdbe *p, /* The VDBE */ sqlite_callback xCallback, /* Result callback */ void *pCallbackArg, /* 1st argument to xCallback() */ int isExplain /* True if the EXPLAIN keywords is present */ ){ int n; assert( p!=0 ); assert( p->aStack==0 ); assert( p->magic==VDBE_MAGIC_INIT ); /* Add a HALT instruction to the very end of the program. */ sqliteVdbeAddOp(p, OP_Halt, 0, 0); /* No instruction ever pushes more than a single element onto the ** stack. And the stack never grows on successive executions of the ** same loop. So the total number of instructions is an upper bound ** on the maximum stack depth required. ** ** Allocation all the stack space we will ever need. */ n = isExplain ? 10 : p->nOp; p->aStack = sqliteMalloc( n*(sizeof(p->aStack[0]) + 2*sizeof(char*)) ); p->zStack = (char**)&p->aStack[n]; p->azColName = (char**)&p->zStack[n]; sqliteHashInit(&p->agg.hash, SQLITE_HASH_BINARY, 0); p->agg.pSearch = 0; #ifdef MEMORY_DEBUG if( access("vdbe_trace",0)==0 ){ p->trace = stdout; } #endif p->tos = -1; p->pc = 0; p->rc = SQLITE_OK; p->uniqueCnt = 0; p->returnDepth = 0; p->errorAction = OE_Abort; p->undoTransOnError = 0; p->xCallback = xCallback; p->pCbArg = pCallbackArg; p->popStack = 0; p->explain = isExplain; p->magic = VDBE_MAGIC_RUN; #ifdef VDBE_PROFILE for(i=0; i<p->nOp; i++){ p->aOp[i].cnt = 0; p->aOp[i].cycles = 0; } #endif } /* ** Execute as much of a VDBE program as we can then return. ** ** sqliteVdbeMakeReady() must be called before this routine in order to ** close the program with a final OP_Halt and to set up the callbacks ** and the error message pointer. ** ** Whenever a row or result data is available, this routine will either ** invoke the result callback (if there is one) or return with ** SQLITE_CALLBACK. ** ** If an attempt is made to open a locked database, then this routine ** will either invoke the busy callback (if there is one) or it will ** return SQLITE_BUSY. ** ** If an error occurs, an error message is written to memory obtained ** from sqliteMalloc() and p->zErrMsg is made to point to that memory. ** The error code is stored in p->rc and this routine returns SQLITE_ERROR. ** ** If the callback ever returns non-zero, then the program exits ** immediately. There will be no error message but the p->rc field is ** set to SQLITE_ABORT and this routine will return SQLITE_ERROR. ** ** A memory allocation error causes p->rc to be set SQLITE_NOMEM and this ** routien to return SQLITE_ERROR. ** ** Other fatal errors return SQLITE_ERROR. ** ** After this routine has finished, sqliteVdbeFinalize() should be ** used to clean up the mess that was left behind. */ int sqliteVdbeExec( Vdbe *p /* The VDBE */ ){ int pc; /* The program counter */ Op *pOp; /* Current operation */ int rc = SQLITE_OK; /* Value to return */ Btree *pBt = p->pBt; /* The backend driver */ sqlite *db = p->db; /* The database */ char **zStack = p->zStack; /* Text stack */ Stack *aStack = p->aStack; /* Additional stack information */ char zBuf[100]; /* Space to sprintf() an integer */ #ifdef VDBE_PROFILE unsigned long long start; /* CPU clock count at start of opcode */ int origPc; /* Program counter at start of opcode */ #endif if( p->magic!=VDBE_MAGIC_RUN ) return SQLITE_MISUSE; assert( db->magic==SQLITE_MAGIC_BUSY ); assert( p->rc==SQLITE_OK ); assert( p->explain==0 ); if( sqlite_malloc_failed ) goto no_mem; if( p->popStack ){ PopStack(p, p->popStack); p->popStack = 0; } for(pc=p->pc; rc==SQLITE_OK; pc++){ assert( pc>=0 && pc<p->nOp ); #ifdef VDBE_PROFILE origPc = pc; start = hwtime(); #endif pOp = &p->aOp[pc]; |
︙ | ︙ | |||
1496 1497 1498 1499 1500 1501 1502 | ** ** The return address stack is of limited depth. If too many ** OP_Gosub operations occur without intervening OP_Returns, then ** the return address stack will fill up and processing will abort ** with a fatal error. */ case OP_Gosub: { | | | | | | | | | | | | | 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 | ** ** The return address stack is of limited depth. If too many ** OP_Gosub operations occur without intervening OP_Returns, then ** the return address stack will fill up and processing will abort ** with a fatal error. */ case OP_Gosub: { if( p->returnDepth>=sizeof(p->returnStack)/sizeof(p->returnStack[0]) ){ sqliteSetString(&p->zErrMsg, "return address stack overflow", 0); p->rc = SQLITE_INTERNAL; return SQLITE_ERROR; } p->returnStack[p->returnDepth++] = pc+1; pc = pOp->p2 - 1; break; } /* Opcode: Return * * * ** ** Jump immediately to the next instruction after the last unreturned ** OP_Gosub. If an OP_Return has occurred for all OP_Gosubs, then ** processing aborts with a fatal error. */ case OP_Return: { if( p->returnDepth<=0 ){ sqliteSetString(&p->zErrMsg, "return address stack underflow", 0); p->rc = SQLITE_INTERNAL; return SQLITE_ERROR; } p->returnDepth--; pc = p->returnStack[p->returnDepth] - 1; break; } /* Opcode: Halt P1 P2 * ** ** Exit immediately. All open cursors, Lists, Sorts, etc are closed ** automatically. |
︙ | ︙ | |||
1542 1543 1544 1545 1546 1547 1548 | ** ** There is an implied "Halt 0 0 0" instruction inserted at the very end of ** every program. So a jump past the last instruction of the program ** is the same as executing Halt. */ case OP_Halt: { if( pOp->p1!=SQLITE_OK ){ | | | | < < < > > > | 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 | ** ** There is an implied "Halt 0 0 0" instruction inserted at the very end of ** every program. So a jump past the last instruction of the program ** is the same as executing Halt. */ case OP_Halt: { if( pOp->p1!=SQLITE_OK ){ p->rc = pOp->p1; p->errorAction = pOp->p2; if( pOp->p3 ){ sqliteSetString(&p->zErrMsg, pOp->p3, 0); } }else{ p->rc = SQLITE_OK; } p->magic = VDBE_MAGIC_HALT; return SQLITE_DONE; } /* Opcode: Integer P1 * P3 ** ** The integer value P1 is pushed onto the stack. If P3 is not zero ** then it is assumed to be a string representation of the same integer. */ |
︙ | ︙ | |||
1738 1739 1740 1741 1742 1743 1744 | if( aStack[j].flags & STK_Null ){ zStack[j] = 0; }else{ Stringify(p, j); } } zStack[p->tos+1] = 0; | | > > > > > > | | | | | | < | 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 | if( aStack[j].flags & STK_Null ){ zStack[j] = 0; }else{ Stringify(p, j); } } zStack[p->tos+1] = 0; if( p->xCallback==0 ){ p->azResColumn = &zStack[i]; p->nResColumn = pOp->p1; p->popStack = pOp->p1; p->pc = pc + 1; return SQLITE_CALLBACK; } if( sqliteSafetyOff(db) ) goto abort_due_to_misuse; if( p->xCallback(p->pCbArg, pOp->p1, &zStack[i], p->azColName)!=0 ){ rc = SQLITE_ABORT; } if( sqliteSafetyOn(db) ) goto abort_due_to_misuse; p->nCallback++; PopStack(p, pOp->p1); if( sqlite_malloc_failed ) goto no_mem; break; } /* Opcode: NullCallback P1 * * ** |
︙ | ︙ | |||
1768 1769 1770 1771 1772 1773 1774 | ** The callback is only invoked if there have been no prior calls ** to OP_Callback or OP_SortCallback. ** ** This opcode is used to report the number and names of columns ** in cases where the result set is empty. */ case OP_NullCallback: { | | | < | > | 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 | ** The callback is only invoked if there have been no prior calls ** to OP_Callback or OP_SortCallback. ** ** This opcode is used to report the number and names of columns ** in cases where the result set is empty. */ case OP_NullCallback: { if( p->nCallback==0 && p->xCallback!=0 ){ if( sqliteSafetyOff(db) ) goto abort_due_to_misuse; if( p->xCallback(p->pCbArg, pOp->p1, 0, p->azColName)!=0 ){ rc = SQLITE_ABORT; } if( sqliteSafetyOn(db) ) goto abort_due_to_misuse; p->nCallback++; if( sqlite_malloc_failed ) goto no_mem; } break; } /* Opcode: Concat P1 P2 P3 ** ** Look at the first P1 elements of the stack. Append them all ** together with the lowest element first. Use P3 as a separator. |
︙ | ︙ | |||
2001 2002 2003 2004 2005 2006 2007 | zStack[p->tos] = ctx.z; }else if( ctx.s.flags & STK_Str ){ zStack[p->tos] = aStack[p->tos].z; }else{ zStack[p->tos] = 0; } if( ctx.isError ){ | | | 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 | zStack[p->tos] = ctx.z; }else if( ctx.s.flags & STK_Str ){ zStack[p->tos] = aStack[p->tos].z; }else{ zStack[p->tos] = 0; } if( ctx.isError ){ sqliteSetString(&p->zErrMsg, zStack[p->tos] ? zStack[p->tos] : "user function error", 0); rc = SQLITE_ERROR; } break; } /* Opcode: BitAnd * * * |
︙ | ︙ | |||
2721 2722 2723 2724 2725 2726 2727 | if( (aStack[i].flags & STK_Null) ){ addUnique = pOp->p2; }else{ Stringify(p, i); nByte += aStack[i].n; } } | | | | | | | 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 | if( (aStack[i].flags & STK_Null) ){ addUnique = pOp->p2; }else{ Stringify(p, i); nByte += aStack[i].n; } } if( addUnique ) nByte += sizeof(p->uniqueCnt); if( nByte + nField + 1 < 256 ){ idxWidth = 1; }else if( nByte + 2*nField + 2 < 65536 ){ idxWidth = 2; }else{ idxWidth = 3; } nByte += idxWidth*(nField + 1); if( nByte>MAX_BYTES_PER_ROW ){ rc = SQLITE_TOOBIG; goto abort_due_to_error; } if( nByte<=NBFS ){ zNewRecord = zTemp; }else{ zNewRecord = sqliteMallocRaw( nByte ); if( zNewRecord==0 ) goto no_mem; } j = 0; addr = idxWidth*(nField+1) + addUnique*sizeof(p->uniqueCnt); for(i=p->tos-nField+1; i<=p->tos; i++){ zNewRecord[j++] = addr & 0xff; if( idxWidth>1 ){ zNewRecord[j++] = (addr>>8)&0xff; if( idxWidth>2 ){ zNewRecord[j++] = (addr>>16)&0xff; } } if( (aStack[i].flags & STK_Null)==0 ){ addr += aStack[i].n; } } zNewRecord[j++] = addr & 0xff; if( idxWidth>1 ){ zNewRecord[j++] = (addr>>8)&0xff; if( idxWidth>2 ){ zNewRecord[j++] = (addr>>16)&0xff; } } if( addUnique ){ memcpy(&zNewRecord[j], &p->uniqueCnt, sizeof(p->uniqueCnt)); p->uniqueCnt++; j += sizeof(p->uniqueCnt); } for(i=p->tos-nField+1; i<=p->tos; i++){ if( (aStack[i].flags & STK_Null)==0 ){ memcpy(&zNewRecord[j], zStack[i], aStack[i].n); j += aStack[i].n; } } |
︙ | ︙ | |||
3002 3003 3004 3005 3006 3007 3008 | ** A write lock is obtained on the database file when a transaction is ** started. No other process can read or write the file while the ** transaction is underway. Starting a transaction also creates a ** rollback journal. A transaction must be started before any changes ** can be made to the database. */ case OP_Transaction: { | | | | | > > > > > | | | < > | | | | 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 | ** A write lock is obtained on the database file when a transaction is ** started. No other process can read or write the file while the ** transaction is underway. Starting a transaction also creates a ** rollback journal. A transaction must be started before any changes ** can be made to the database. */ case OP_Transaction: { int busy = 1; if( db->pBeTemp && !p->inTempTrans ){ rc = sqliteBtreeBeginTrans(db->pBeTemp); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } p->inTempTrans = 1; } while( pOp->p1==0 && busy ){ rc = sqliteBtreeBeginTrans(pBt); switch( rc ){ case SQLITE_BUSY: { if( db->xBusyCallback==0 ){ p->pc = pc; p->undoTransOnError = 1; p->rc = SQLITE_BUSY; return SQLITE_BUSY; }else if( (*db->xBusyCallback)(db->pBusyArg, "", busy++)==0 ){ sqliteSetString(&p->zErrMsg, sqlite_error_string(rc), 0); busy = 0; } break; } case SQLITE_READONLY: { rc = SQLITE_OK; /* Fall thru into the next case */ } case SQLITE_OK: { p->inTempTrans = 0; busy = 0; break; } default: { goto abort_due_to_error; } } } p->undoTransOnError = 1; break; } /* Opcode: Commit * * * ** ** Cause all modifications to the database that have been made since the ** last Transaction to actually take effect. No additional modifications ** are allowed until another transaction is started. The Commit instruction ** deletes the journal file and releases the write lock on the database. ** A read lock continues to be held if there are still cursors open. */ case OP_Commit: { if( db->pBeTemp==0 || (rc = sqliteBtreeCommit(db->pBeTemp))==SQLITE_OK ){ rc = p->inTempTrans ? SQLITE_OK : sqliteBtreeCommit(pBt); } if( rc==SQLITE_OK ){ sqliteCommitInternalChanges(db); }else{ if( db->pBeTemp ) sqliteBtreeRollback(db->pBeTemp); sqliteBtreeRollback(pBt); sqliteRollbackInternalChanges(db); } p->inTempTrans = 0; break; } /* Opcode: Rollback * * * ** ** Cause all modifications to the database that have been made since the ** last Transaction to be undone. The database is restored to its state |
︙ | ︙ | |||
3158 3159 3160 3161 3162 3163 3164 | ** invoked. */ case OP_VerifyCookie: { int aMeta[SQLITE_N_BTREE_META]; assert( pOp->p2<SQLITE_N_BTREE_META ); rc = sqliteBtreeGetMeta(pBt, aMeta); if( rc==SQLITE_OK && aMeta[1+pOp->p2]!=pOp->p1 ){ | | | 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 | ** invoked. */ case OP_VerifyCookie: { int aMeta[SQLITE_N_BTREE_META]; assert( pOp->p2<SQLITE_N_BTREE_META ); rc = sqliteBtreeGetMeta(pBt, aMeta); if( rc==SQLITE_OK && aMeta[1+pOp->p2]!=pOp->p1 ){ sqliteSetString(&p->zErrMsg, "database schema has changed", 0); rc = SQLITE_SCHEMA; } break; } /* Opcode: Open P1 P2 P3 ** |
︙ | ︙ | |||
3237 3238 3239 3240 3241 3242 3243 | } if( p2<=0 ){ if( tos<0 ) goto not_enough_stack; Integerify(p, tos); p2 = p->aStack[tos].i; POPSTACK; if( p2<2 ){ | | | > > > > | | > > > | 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 | } if( p2<=0 ){ if( tos<0 ) goto not_enough_stack; Integerify(p, tos); p2 = p->aStack[tos].i; POPSTACK; if( p2<2 ){ sqliteSetString(&p->zErrMsg, "root page number less than 2", 0); rc = SQLITE_INTERNAL; break; } } VERIFY( if( i<0 ) goto bad_instruction; ) if( expandCursorArraySize(p, i) ) goto no_mem; cleanupCursor(&p->aCsr[i]); memset(&p->aCsr[i], 0, sizeof(Cursor)); p->aCsr[i].nullRow = 1; if( pX==0 ) break; do{ rc = sqliteBtreeCursor(pX, p2, wrFlag, &p->aCsr[i].pCursor); switch( rc ){ case SQLITE_BUSY: { if( db->xBusyCallback==0 ){ p->pc = pc; p->rc = SQLITE_BUSY; return SQLITE_BUSY; }else if( (*db->xBusyCallback)(db->pBusyArg, pOp->p3, ++busy)==0 ){ sqliteSetString(&p->zErrMsg, sqlite_error_string(rc), 0); busy = 0; } break; } case SQLITE_OK: { busy = 0; break; } default: { goto abort_due_to_error; } } }while( busy ); if( p2<=0 ){ POPSTACK; } break; } /* Opcode: OpenTemp P1 P2 * ** ** Open a new cursor that points to a table or index in a temporary ** database file. The temporary file is opened read/write even if |
︙ | ︙ | |||
4120 4121 4122 4123 4124 4125 4126 | sqliteBtreeKeySize(pCrsr, &n); if( n==nKey && sqliteBtreeKeyCompare(pCrsr, zKey, nKey-4, 4, &c)==SQLITE_OK && c==0 ){ rc = SQLITE_CONSTRAINT; if( pOp->p3 && pOp->p3[0] ){ | | | 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 | sqliteBtreeKeySize(pCrsr, &n); if( n==nKey && sqliteBtreeKeyCompare(pCrsr, zKey, nKey-4, 4, &c)==SQLITE_OK && c==0 ){ rc = SQLITE_CONSTRAINT; if( pOp->p3 && pOp->p3[0] ){ sqliteSetString(&p->zErrMsg, "duplicate index entry: ", pOp->p3,0); } goto abort_due_to_error; } if( res<0 ){ sqliteBtreeNext(pCrsr, &res); res = +1; }else{ |
︙ | ︙ | |||
4677 4678 4679 4680 4681 4682 4683 | ** the SortMakeRec operation with the same P1 value as this ** instruction. Pop this record from the stack and invoke the ** callback on it. */ case OP_SortCallback: { int i = p->tos; VERIFY( if( i<0 ) goto not_enough_stack; ) | | > > > > > > | | 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 | ** the SortMakeRec operation with the same P1 value as this ** instruction. Pop this record from the stack and invoke the ** callback on it. */ case OP_SortCallback: { int i = p->tos; VERIFY( if( i<0 ) goto not_enough_stack; ) if( p->xCallback==0 ){ p->pc = pc+1; p->azResColumn = (char**)zStack[i]; p->nResColumn = pOp->p1; p->popStack = 1; return SQLITE_CALLBACK; }else{ if( sqliteSafetyOff(db) ) goto abort_due_to_misuse; if( p->xCallback(p->pCbArg, pOp->p1, (char**)zStack[i], p->azColName)!=0 ){ rc = SQLITE_ABORT; } if( sqliteSafetyOn(db) ) goto abort_due_to_misuse; p->nCallback++; } POPSTACK; if( sqlite_malloc_failed ) goto no_mem; |
︙ | ︙ | |||
4716 4717 4718 4719 4720 4721 4722 | } if( sqliteStrICmp(pOp->p3,"stdin")==0 ){ p->pFile = stdin; }else{ p->pFile = fopen(pOp->p3, "r"); } if( p->pFile==0 ){ | | < | 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 | } if( sqliteStrICmp(pOp->p3,"stdin")==0 ){ p->pFile = stdin; }else{ p->pFile = fopen(pOp->p3, "r"); } if( p->pFile==0 ){ sqliteSetString(&p->zErrMsg,"unable to open file: ", pOp->p3, 0); rc = SQLITE_ERROR; } break; } /* Opcode: FileRead P1 P2 P3 ** ** Read a single line of input from the open file (the file opened using |
︙ | ︙ | |||
5305 5306 5307 5308 5309 5310 5311 | break; } /* An other opcode is illegal... */ default: { sprintf(zBuf,"%d",pOp->opcode); | | | 5467 5468 5469 5470 5471 5472 5473 5474 5475 5476 5477 5478 5479 5480 5481 | break; } /* An other opcode is illegal... */ default: { sprintf(zBuf,"%d",pOp->opcode); sqliteSetString(&p->zErrMsg, "unknown opcode ", zBuf, 0); rc = SQLITE_INTERNAL; break; } /***************************************************************************** ** The cases of the switch statement above this line should all be indented ** by 6 spaces. But the left-most 6 spaces have been removed to improve the |
︙ | ︙ | |||
5337 5338 5339 5340 5341 5342 5343 | /* The following code adds nothing to the actual functionality ** of the program. It is only here for testing and debugging. ** On the other hand, it does burn CPU cycles every time through ** the evaluator loop. So we can leave it out when NDEBUG is defined. */ #ifndef NDEBUG if( pc<-1 || pc>=p->nOp ){ | | | 5499 5500 5501 5502 5503 5504 5505 5506 5507 5508 5509 5510 5511 5512 5513 | /* The following code adds nothing to the actual functionality ** of the program. It is only here for testing and debugging. ** On the other hand, it does burn CPU cycles every time through ** the evaluator loop. So we can leave it out when NDEBUG is defined. */ #ifndef NDEBUG if( pc<-1 || pc>=p->nOp ){ sqliteSetString(&p->zErrMsg, "jump destination out of range", 0); rc = SQLITE_INTERNAL; } if( p->trace && p->tos>=0 ){ int i; fprintf(p->trace, "Stack:"); for(i=p->tos; i>=0 && i>p->tos-5; i--){ if( aStack[i].flags & STK_Null ){ |
︙ | ︙ | |||
5390 5391 5392 5393 5394 5395 5396 | fprintf(p->trace, " ???"); } } if( rc!=0 ) fprintf(p->trace," rc=%d",rc); fprintf(p->trace,"\n"); } #endif | > | > > > > > > > > | > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | | | 5552 5553 5554 5555 5556 5557 5558 5559 5560 5561 5562 5563 5564 5565 5566 5567 5568 5569 5570 5571 5572 5573 5574 5575 5576 5577 5578 5579 5580 5581 5582 5583 5584 5585 5586 5587 5588 5589 5590 5591 5592 5593 5594 5595 5596 5597 5598 5599 5600 5601 5602 5603 5604 5605 5606 5607 5608 5609 5610 5611 5612 5613 5614 5615 5616 5617 5618 5619 5620 5621 5622 5623 5624 5625 5626 5627 5628 5629 5630 5631 5632 5633 5634 5635 5636 5637 5638 5639 5640 5641 5642 5643 5644 5645 5646 5647 5648 5649 5650 5651 5652 5653 5654 5655 5656 5657 5658 5659 5660 5661 5662 5663 5664 5665 5666 5667 5668 5669 5670 5671 5672 5673 5674 5675 5676 5677 5678 5679 5680 5681 5682 5683 5684 5685 5686 5687 5688 | fprintf(p->trace, " ???"); } } if( rc!=0 ) fprintf(p->trace," rc=%d",rc); fprintf(p->trace,"\n"); } #endif } /* The end of the for(;;) loop the loops through opcodes */ /* If we reach this point, it means that execution is finished. */ vdbe_halt: if( rc ){ p->rc = rc; rc = SQLITE_ERROR; }else{ rc = SQLITE_DONE; } p->magic = VDBE_MAGIC_HALT; return rc; /* Jump to here if a malloc() fails. It's hard to get a malloc() ** to fail on a modern VM computer, so this code is untested. */ no_mem: sqliteSetString(&p->zErrMsg, "out of memory", 0); rc = SQLITE_NOMEM; goto vdbe_halt; /* Jump to here for an SQLITE_MISUSE error. */ abort_due_to_misuse: rc = SQLITE_MISUSE; /* Fall thru into abort_due_to_error */ /* Jump to here for any other kind of fatal error. The "rc" variable ** should hold the error number. */ abort_due_to_error: sqliteSetString(&p->zErrMsg, sqlite_error_string(rc), 0); goto vdbe_halt; /* Jump to here if the sqlite_interrupt() API sets the interrupt ** flag. */ abort_due_to_interrupt: assert( db->flags & SQLITE_Interrupt ); db->flags &= ~SQLITE_Interrupt; if( db->magic!=SQLITE_MAGIC_BUSY ){ rc = SQLITE_MISUSE; }else{ rc = SQLITE_INTERRUPT; } sqliteSetString(&p->zErrMsg, sqlite_error_string(rc), 0); goto vdbe_halt; /* Jump to here if a operator is encountered that requires more stack ** operands than are currently available on the stack. */ not_enough_stack: sprintf(zBuf,"%d",pc); sqliteSetString(&p->zErrMsg, "too few operands on stack at ", zBuf, 0); rc = SQLITE_INTERNAL; goto vdbe_halt; /* Jump here if an illegal or illformed instruction is executed. */ VERIFY( bad_instruction: sprintf(zBuf,"%d",pc); sqliteSetString(&p->zErrMsg, "illegal operation at ", zBuf, 0); rc = SQLITE_INTERNAL; goto vdbe_halt; ) } /* ** Clean up the VDBE after execution. Return an integer which is the ** result code. */ int sqliteVdbeFinalize(Vdbe *p, char **pzErrMsg){ sqlite *db = p->db; Btree *pBt = p->pBt; if( p->magic!=VDBE_MAGIC_RUN && p->magic!=VDBE_MAGIC_HALT ){ sqliteSetString(pzErrMsg, sqlite_error_string(SQLITE_MISUSE), 0); return SQLITE_MISUSE; } if( p->zErrMsg ){ if( pzErrMsg && *pzErrMsg==0 ){ *pzErrMsg = p->zErrMsg; }else{ sqliteFree(p->zErrMsg); } p->zErrMsg = 0; } Cleanup(p); if( p->rc!=SQLITE_OK ){ switch( p->errorAction ){ case OE_Abort: { if( !p->undoTransOnError ){ sqliteBtreeRollbackCkpt(pBt); if( db->pBeTemp ) sqliteBtreeRollbackCkpt(db->pBeTemp); break; } /* Fall through to ROLLBACK */ } case OE_Rollback: { sqliteBtreeRollback(pBt); if( db->pBeTemp ) sqliteBtreeRollback(db->pBeTemp); db->flags &= ~SQLITE_InTrans; db->onError = OE_Default; break; } default: { if( p->undoTransOnError ){ sqliteBtreeCommit(pBt); if( db->pBeTemp ) sqliteBtreeCommit(db->pBeTemp); db->flags &= ~SQLITE_InTrans; db->onError = OE_Default; } break; } } sqliteRollbackInternalChanges(db); } sqliteBtreeCommitCkpt(pBt); if( db->pBeTemp ) sqliteBtreeCommitCkpt(db->pBeTemp); assert( p->tos<p->pc || sqlite_malloc_failed==1 ); #ifdef VDBE_PROFILE { FILE *out = fopen("vdbe_profile.out", "a"); if( out ){ int i; fprintf(out, "---- "); for(i=0; i<p->nOp; i++){ |
︙ | ︙ | |||
5448 5449 5450 5451 5452 5453 5454 | ); vdbePrintOp(out, i, &p->aOp[i]); } fclose(out); } } #endif | | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 5697 5698 5699 5700 5701 5702 5703 5704 5705 | ); vdbePrintOp(out, i, &p->aOp[i]); } fclose(out); } } #endif return p->rc; } |
Changes to src/vdbe.h.
︙ | ︙ | |||
11 12 13 14 15 16 17 | ************************************************************************* ** 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. ** | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | ************************************************************************* ** 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.62 2003/01/28 23:13:13 drh Exp $ */ #ifndef _SQLITE_VDBE_H_ #define _SQLITE_VDBE_H_ #include <stdio.h> /* ** A single VDBE is an opaque structure named "Vdbe". Only routines |
︙ | ︙ | |||
58 59 60 61 62 63 64 65 66 67 68 69 70 71 | ** The following macro converts a relative address in the p2 field ** of a VdbeOp structure into a negative number so that ** sqliteVdbeAddOpList() knows that the address is relative. Calling ** the macro again restores the address. */ #define ADDR(X) (-1-(X)) /* ** The makefile scans the vdbe.c source file and creates the "opcodes.h" ** header file that defines a number for each opcode used by the VDBE. */ #include "opcodes.h" /* | > > > > > > > | 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | ** The following macro converts a relative address in the p2 field ** of a VdbeOp structure into a negative number so that ** sqliteVdbeAddOpList() knows that the address is relative. Calling ** the macro again restores the address. */ #define ADDR(X) (-1-(X)) /* ** The sqliteVdbeExec() routine can return any of the normal SQLite return ** codes defined in sqlite.h. But it can also return the following ** additional values: */ #define SQLITE_CALLBACK 100 /* sqliteVdbeExec() hit an OP_Callback */ /* ** The makefile scans the vdbe.c source file and creates the "opcodes.h" ** header file that defines a number for each opcode used by the VDBE. */ #include "opcodes.h" /* |
︙ | ︙ | |||
79 80 81 82 83 84 85 | void sqliteVdbeChangeP1(Vdbe*, int addr, int P1); void sqliteVdbeChangeP2(Vdbe*, int addr, int P2); void sqliteVdbeChangeP3(Vdbe*, int addr, const char *zP1, int N); void sqliteVdbeDequoteP3(Vdbe*, int addr); int sqliteVdbeFindOp(Vdbe*, int, int); int sqliteVdbeMakeLabel(Vdbe*); void sqliteVdbeDelete(Vdbe*); | > | < | > | 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | void sqliteVdbeChangeP1(Vdbe*, int addr, int P1); void sqliteVdbeChangeP2(Vdbe*, int addr, int P2); void sqliteVdbeChangeP3(Vdbe*, int addr, const char *zP1, int N); void sqliteVdbeDequoteP3(Vdbe*, int addr); int sqliteVdbeFindOp(Vdbe*, int, int); int sqliteVdbeMakeLabel(Vdbe*); void sqliteVdbeDelete(Vdbe*); void sqliteVdbeMakeReady(Vdbe*,sqlite_callback,void*,int); int sqliteVdbeExec(Vdbe*); int sqliteVdbeList(Vdbe*); int sqliteVdbeFinalize(Vdbe*,char**); void sqliteVdbeResolveLabel(Vdbe*, int); int sqliteVdbeCurrentAddr(Vdbe*); void sqliteVdbeTrace(Vdbe*,FILE*); void sqliteVdbeCompressSpace(Vdbe*,int); #endif |
Changes to test/trigger3.test.
︙ | ︙ | |||
32 33 34 35 36 37 38 | do_test trigger3-1.1 { catchsql { BEGIN; INSERT INTO tbl VALUES (5, 5, 6); INSERT INTO tbl VALUES (1, 5, 6); } } {1 {Trigger abort}} | < | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | do_test trigger3-1.1 { catchsql { BEGIN; INSERT INTO tbl VALUES (5, 5, 6); INSERT INTO tbl VALUES (1, 5, 6); } } {1 {Trigger abort}} do_test trigger3-1.2 { execsql { SELECT * FROM tbl; ROLLBACK; } } {5 5 6} do_test trigger3-1.3 { |
︙ | ︙ |