Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix EXPLAIN and EXPLAIN query plan to work with new opcode format. (CVS 4662) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
b166c33a7b9a58d571619d2248019eda |
User & Date: | danielk1977 2008-01-03 07:09:48.000 |
Context
2008-01-03
| ||
07:54 | Change OP_OpenRead and OP_OpenWrite so that the database number is read from the P3 operand, not the stack. (CVS 4663) (check-in: 35da261daf user: danielk1977 tags: trunk) | |
07:09 | Fix EXPLAIN and EXPLAIN query plan to work with new opcode format. (CVS 4662) (check-in: b166c33a7b user: danielk1977 tags: trunk) | |
01:28 | Revamp sqlite3VdbeAddOpList() so that the structure holds integer values for P1, P2, and P3. (CVS 4661) (check-in: 4dc507d87b user: drh tags: trunk) | |
Changes
Changes to src/prepare.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the implementation of the sqlite3_prepare() ** interface, and routines that contribute to loading the database schema ** from disk. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the implementation of the sqlite3_prepare() ** interface, and routines that contribute to loading the database schema ** from disk. ** ** $Id: prepare.c,v 1.70 2008/01/03 07:09:48 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** Fill the InitData structure with an error message that indicates ** that the database is corrupt. |
︙ | ︙ | |||
568 569 570 571 572 573 574 | if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){ if( sParse.explain==2 ){ sqlite3VdbeSetNumCols(sParse.pVdbe, 3); sqlite3VdbeSetColName(sParse.pVdbe, 0, COLNAME_NAME, "order", P4_STATIC); sqlite3VdbeSetColName(sParse.pVdbe, 1, COLNAME_NAME, "from", P4_STATIC); sqlite3VdbeSetColName(sParse.pVdbe, 2, COLNAME_NAME, "detail", P4_STATIC); }else{ | | > > > | 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 | if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){ if( sParse.explain==2 ){ sqlite3VdbeSetNumCols(sParse.pVdbe, 3); sqlite3VdbeSetColName(sParse.pVdbe, 0, COLNAME_NAME, "order", P4_STATIC); sqlite3VdbeSetColName(sParse.pVdbe, 1, COLNAME_NAME, "from", P4_STATIC); sqlite3VdbeSetColName(sParse.pVdbe, 2, COLNAME_NAME, "detail", P4_STATIC); }else{ sqlite3VdbeSetNumCols(sParse.pVdbe, 8); sqlite3VdbeSetColName(sParse.pVdbe, 0, COLNAME_NAME, "addr", P4_STATIC); sqlite3VdbeSetColName(sParse.pVdbe, 1, COLNAME_NAME, "opcode", P4_STATIC); sqlite3VdbeSetColName(sParse.pVdbe, 2, COLNAME_NAME, "p1", P4_STATIC); sqlite3VdbeSetColName(sParse.pVdbe, 3, COLNAME_NAME, "p2", P4_STATIC); sqlite3VdbeSetColName(sParse.pVdbe, 4, COLNAME_NAME, "p3", P4_STATIC); sqlite3VdbeSetColName(sParse.pVdbe, 5, COLNAME_NAME, "p4", P4_STATIC); sqlite3VdbeSetColName(sParse.pVdbe, 6, COLNAME_NAME, "p5", P4_STATIC); sqlite3VdbeSetColName(sParse.pVdbe, 7, COLNAME_NAME, "comment",P4_STATIC); } } #endif if( sqlite3SafetyOff(db) ){ rc = SQLITE_MISUSE; } |
︙ | ︙ |
Changes to src/shell.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code to implement the "sqlite" command line ** utility for accessing SQLite databases. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code to implement the "sqlite" command line ** utility for accessing SQLite databases. ** ** $Id: shell.c,v 1.172 2008/01/03 07:09:48 danielk1977 Exp $ */ #include <stdlib.h> #include <string.h> #include <stdio.h> #include <assert.h> #include "sqlite3.h" #include <ctype.h> |
︙ | ︙ | |||
333 334 335 336 337 338 339 340 341 342 343 344 345 346 | #define MODE_List 2 /* One record per line with a separator */ #define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */ #define MODE_Html 4 /* Generate an XHTML table */ #define MODE_Insert 5 /* Generate SQL "insert" statements */ #define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */ #define MODE_Csv 7 /* Quote strings, numbers are plain */ #define MODE_NUM_OF 8 /* The number of modes (not a mode itself) */ static const char *modeDescr[MODE_NUM_OF] = { "line", "column", "list", "semi", "html", | > | 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 | #define MODE_List 2 /* One record per line with a separator */ #define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */ #define MODE_Html 4 /* Generate an XHTML table */ #define MODE_Insert 5 /* Generate SQL "insert" statements */ #define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */ #define MODE_Csv 7 /* Quote strings, numbers are plain */ #define MODE_NUM_OF 8 /* The number of modes (not a mode itself) */ #define MODE_Explain 9 /* Like MODE_Column, but do not truncate data */ static const char *modeDescr[MODE_NUM_OF] = { "line", "column", "list", "semi", "html", |
︙ | ︙ | |||
522 523 524 525 526 527 528 529 530 531 532 533 | if( p->cnt++>0 ) fprintf(p->out,"\n"); for(i=0; i<nArg; i++){ fprintf(p->out,"%*s = %s\n", w, azCol[i], azArg[i] ? azArg[i] : p->nullvalue); } break; } case MODE_Column: { if( p->cnt++==0 ){ for(i=0; i<nArg; i++){ int w, n; if( i<ArraySize(p->colWidth) ){ | > | | | 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 | if( p->cnt++>0 ) fprintf(p->out,"\n"); for(i=0; i<nArg; i++){ fprintf(p->out,"%*s = %s\n", w, azCol[i], azArg[i] ? azArg[i] : p->nullvalue); } break; } case MODE_Explain: case MODE_Column: { if( p->cnt++==0 ){ for(i=0; i<nArg; i++){ int w, n; if( i<ArraySize(p->colWidth) ){ w = p->colWidth[i]; }else{ w = 0; } if( w<=0 ){ w = strlen(azCol[i] ? azCol[i] : ""); if( w<10 ) w = 10; n = strlen(azArg && azArg[i] ? azArg[i] : p->nullvalue); if( w<n ) w = n; } |
︙ | ︙ | |||
565 566 567 568 569 570 571 572 573 574 575 576 577 578 | if( azArg==0 ) break; for(i=0; i<nArg; i++){ int w; if( i<ArraySize(p->actualWidth) ){ w = p->actualWidth[i]; }else{ w = 10; } fprintf(p->out,"%-*.*s%s",w,w, azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " "); } break; } case MODE_Semi: | > > > | 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 | if( azArg==0 ) break; for(i=0; i<nArg; i++){ int w; if( i<ArraySize(p->actualWidth) ){ w = p->actualWidth[i]; }else{ w = 10; } if( p->mode==MODE_Explain && azArg[i] && strlen(azArg[i])>w ){ w = strlen(azArg[i]); } fprintf(p->out,"%-*.*s%s",w,w, azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " "); } break; } case MODE_Semi: |
︙ | ︙ | |||
1141 1142 1143 1144 1145 1146 1147 | /* We could put this code under the !p->explainValid ** condition so that it does not execute if we are already in ** explain mode. However, always executing it allows us an easy ** was to reset to explain mode in case the user previously ** did an .explain followed by a .width, .mode or .header ** command. */ | | | | | | | > > > | 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 | /* We could put this code under the !p->explainValid ** condition so that it does not execute if we are already in ** explain mode. However, always executing it allows us an easy ** was to reset to explain mode in case the user previously ** did an .explain followed by a .width, .mode or .header ** command. */ p->mode = MODE_Explain; p->showHeader = 1; memset(p->colWidth,0,ArraySize(p->colWidth)); p->colWidth[0] = 4; /* addr */ p->colWidth[1] = 14; /* opcode */ p->colWidth[2] = 10; /* P1 */ p->colWidth[3] = 10; /* P2 */ p->colWidth[4] = 10; /* P3 */ p->colWidth[5] = 20; /* P4 */ p->colWidth[6] = 2; /* P5 */ p->colWidth[7] = 7; /* Comment */ }else if (p->explainPrev.valid) { p->explainPrev.valid = 0; p->mode = p->explainPrev.mode; p->showHeader = p->explainPrev.showHeader; memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth)); } }else |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
39 40 41 42 43 44 45 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** ** $Id: vdbe.c,v 1.665 2008/01/03 07:09:48 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> #include "vdbeInt.h" /* ** The following global variable is incremented every time a cursor |
︙ | ︙ | |||
2033 2034 2035 2036 2037 2038 2039 | ** Interpret the data that cursor P1 points to as a structure built using ** the MakeRecord instruction. (See the MakeRecord opcode for additional ** information about the format of the data.) Extract the P2-th column ** from this record. If there are less that (P2+1) ** values in the record, extract a NULL. ** ** The value extracted is pushed onto the stack. Or if P3 is a positive | | > | 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 | ** Interpret the data that cursor P1 points to as a structure built using ** the MakeRecord instruction. (See the MakeRecord opcode for additional ** information about the format of the data.) Extract the P2-th column ** from this record. If there are less that (P2+1) ** values in the record, extract a NULL. ** ** The value extracted is pushed onto the stack. Or if P3 is a positive ** non-zero integer register number, then the value is written into that ** register. ** ** If the KeyAsData opcode has previously executed on this cursor, then the ** field might be extracted from the key rather than the data. ** ** If the column contains fewer than P2 fields, then extract a NULL. Or ** if the next instruction is OP_DfltValue then the P4 argument to the ** OP_DfltValue instruction will be a P4_MEM. Use the P4 argument of |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
611 612 613 614 615 616 617 | || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG) /* ** Compute a string that describes the P4 parameter for an opcode. ** Use zTemp for any required temporary buffer space. */ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ char *zP4 = zTemp; | < | 611 612 613 614 615 616 617 618 619 620 621 622 623 624 | || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG) /* ** Compute a string that describes the P4 parameter for an opcode. ** Use zTemp for any required temporary buffer space. */ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ char *zP4 = zTemp; assert( nTemp>=20 ); switch( pOp->p4type ){ case P4_KEYINFO: { int i, j; KeyInfo *pKeyInfo = (KeyInfo*)pOp->p4.p; sqlite3_snprintf(nTemp, zTemp, "keyinfo(%d", pKeyInfo->nField); i = strlen(zTemp); |
︙ | ︙ | |||
694 695 696 697 698 699 700 | if( zP4==0 || pOp->opcode==OP_Noop ){ zP4 = zTemp; zTemp[0] = 0; } } } assert( zP4!=0 ); | < < < < < < | 693 694 695 696 697 698 699 700 701 702 703 704 705 706 | if( zP4==0 || pOp->opcode==OP_Noop ){ zP4 = zTemp; zTemp[0] = 0; } } } assert( zP4!=0 ); return zP4; } #endif /* ** Declare to the Vdbe that the BTree object at db->aDb[i] is used. ** |
︙ | ︙ | |||
790 791 792 793 794 795 796 | }else if( db->u1.isInterrupted ){ p->rc = SQLITE_INTERRUPT; rc = SQLITE_ERROR; sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(p->rc), (char*)0); }else{ Op *pOp = &p->aOp[i]; Mem *pMem = p->pResultSet = p->aStack; | > | | | | | | | | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > | | 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 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 | }else if( db->u1.isInterrupted ){ p->rc = SQLITE_INTERRUPT; rc = SQLITE_ERROR; sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(p->rc), (char*)0); }else{ Op *pOp = &p->aOp[i]; Mem *pMem = p->pResultSet = p->aStack; if( p->explain==1 ){ pMem->flags = MEM_Int; pMem->type = SQLITE_INTEGER; pMem->u.i = i; /* Program counter */ pMem++; pMem->flags = MEM_Static|MEM_Str|MEM_Term; pMem->z = (char*)sqlite3OpcodeName(pOp->opcode); /* Opcode */ assert( pMem->z!=0 ); pMem->n = strlen(pMem->z); pMem->type = SQLITE_TEXT; pMem->enc = SQLITE_UTF8; pMem++; } pMem->flags = MEM_Int; pMem->u.i = pOp->p1; /* P1 */ pMem->type = SQLITE_INTEGER; pMem++; pMem->flags = MEM_Int; pMem->u.i = pOp->p2; /* P2 */ pMem->type = SQLITE_INTEGER; pMem++; if( p->explain==1 ){ pMem->flags = MEM_Int; pMem->u.i = pOp->p3; /* P3 */ pMem->type = SQLITE_INTEGER; pMem++; } pMem->flags = MEM_Ephem|MEM_Str|MEM_Term; /* P4 */ pMem->z = displayP4(pOp, pMem->zShort, sizeof(pMem->zShort)); assert( pMem->z!=0 ); pMem->n = strlen(pMem->z); pMem->type = SQLITE_TEXT; pMem->enc = SQLITE_UTF8; pMem++; if( p->explain==1 ){ pMem->flags = MEM_Str|MEM_Term|MEM_Short; pMem->n = sprintf(pMem->zShort, "%.2x", pOp->p5); /* P5 */ pMem->z = pMem->zShort; pMem->type = SQLITE_TEXT; pMem->enc = SQLITE_UTF8; pMem++; pMem->flags = MEM_Null; /* Comment */ if( pOp->zComment ){ pMem->flags = MEM_Str|MEM_Term; pMem->z = pOp->zComment; pMem->n = strlen(pMem->z); pMem->enc = SQLITE_UTF8; } } p->nResColumn = 8 - 5*(p->explain-1); p->pTos = pMem; p->rc = SQLITE_OK; rc = SQLITE_ROW; } return rc; } #endif /* SQLITE_OMIT_EXPLAIN */ |
︙ | ︙ |