Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add the OP_Concat8 opcode, similar in concept to OP_String8. (CVS 1648) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
bbd3e93348bc3a1178f5278c6cf0b82e |
User & Date: | danielk1977 2004-06-21 09:06:42.000 |
Context
2004-06-21
| ||
10:45 | Avoid opening a temp table for aggregate queries with no GROUP BY clause. (CVS 1649) (check-in: 4d02df6349 user: danielk1977 tags: trunk) | |
09:06 | Add the OP_Concat8 opcode, similar in concept to OP_String8. (CVS 1648) (check-in: bbd3e93348 user: danielk1977 tags: trunk) | |
08:18 | Ensure sqlite3ErrorMsg() is used to report errors during compilation, sqlite3Error() during execution. Also remove unused param from sqlite3VdbeReset() and Finalize(). (CVS 1647) (check-in: 7a33daef5b user: danielk1977 tags: trunk) | |
Changes
Changes to src/build.c.
︙ | ︙ | |||
19 20 21 22 23 24 25 | ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** PRAGMA ** | | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** PRAGMA ** ** $Id: build.c,v 1.228 2004/06/21 09:06:42 danielk1977 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 |
︙ | ︙ | |||
1375 1376 1377 1378 1379 1380 1381 | }else{ sqlite3VdbeOp3(v, OP_String8, 0, 0, "CREATE TABLE ", P3_STATIC); } assert( pEnd!=0 ); n = Addr(pEnd->z) - Addr(pParse->sNameToken.z) + 1; sqlite3VdbeAddOp(v, OP_String8, 0, 0); sqlite3VdbeChangeP3(v, -1, pParse->sNameToken.z, n); | | | 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 | }else{ sqlite3VdbeOp3(v, OP_String8, 0, 0, "CREATE TABLE ", P3_STATIC); } assert( pEnd!=0 ); n = Addr(pEnd->z) - Addr(pParse->sNameToken.z) + 1; sqlite3VdbeAddOp(v, OP_String8, 0, 0); sqlite3VdbeChangeP3(v, -1, pParse->sNameToken.z, n); sqlite3VdbeAddOp(v, OP_Concat8, 2, 0); } sqlite3VdbeOp3(v, OP_MakeRecord, 5, 0, "tttit", P3_STATIC); sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0); if( p->iDb!=1 ){ sqlite3ChangeCookie(db, v, p->iDb); } sqlite3VdbeAddOp(v, OP_Close, 0, 0); |
︙ | ︙ | |||
2174 2175 2176 2177 2178 2179 2180 | sqlite3VdbeChangeP3(v, -1, "CREATE INDEX ", P3_STATIC); }else{ sqlite3VdbeChangeP3(v, -1, "CREATE UNIQUE INDEX ", P3_STATIC); } sqlite3VdbeAddOp(v, OP_String8, 0, 0); n = Addr(pEnd->z) - Addr(pName->z) + 1; sqlite3VdbeChangeP3(v, -1, pName->z, n); | | | 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 | sqlite3VdbeChangeP3(v, -1, "CREATE INDEX ", P3_STATIC); }else{ sqlite3VdbeChangeP3(v, -1, "CREATE UNIQUE INDEX ", P3_STATIC); } sqlite3VdbeAddOp(v, OP_String8, 0, 0); n = Addr(pEnd->z) - Addr(pName->z) + 1; sqlite3VdbeChangeP3(v, -1, pName->z, n); sqlite3VdbeAddOp(v, OP_Concat8, 2, 0); } sqlite3VdbeOp3(v, OP_MakeRecord, 5, 0, "tttit", P3_STATIC); sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0); if( pTblName ){ sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0); sqlite3VdbeAddOp(v, OP_OpenRead, 2, pTab->tnum); /* VdbeComment((v, "%s", pTab->zName)); */ |
︙ | ︙ |
Changes to src/expr.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** ** $Id: expr.c,v 1.147 2004/06/21 09:06:42 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> char const *sqlite3AffinityString(char affinity){ switch( affinity ){ case SQLITE_AFF_INTEGER: return "i"; |
︙ | ︙ | |||
1177 1178 1179 1180 1181 1182 1183 | sqlite3ExprCode(pParse, pExpr->pLeft); sqlite3VdbeAddOp(v, op, 0, 0); break; } case TK_CONCAT: { sqlite3ExprCode(pParse, pExpr->pLeft); sqlite3ExprCode(pParse, pExpr->pRight); | | | 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 | sqlite3ExprCode(pParse, pExpr->pLeft); sqlite3VdbeAddOp(v, op, 0, 0); break; } case TK_CONCAT: { sqlite3ExprCode(pParse, pExpr->pLeft); sqlite3ExprCode(pParse, pExpr->pRight); sqlite3VdbeAddOp(v, OP_Concat8, 2, 0); break; } case TK_UMINUS: { Expr *pLeft = pExpr->pLeft; assert( pLeft ); if( pLeft->op==TK_FLOAT || pLeft->op==TK_INTEGER ){ Token *p = &pLeft->token; |
︙ | ︙ |
Changes to src/pragma.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2003 April 6 ** ** 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. ** ************************************************************************* ** This file contains code used to implement the PRAGMA command. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2003 April 6 ** ** 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. ** ************************************************************************* ** This file contains code used to implement the PRAGMA command. ** ** $Id: pragma.c,v 1.52 2004/06/21 09:06:42 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) # include "pager.h" # include "btree.h" |
︙ | ︙ | |||
662 663 664 665 666 667 668 | sqlite3VdbeAddOp(v, OP_Dup, 0, 1); addr = sqlite3VdbeOp3(v, OP_String8, 0, 0, "ok", P3_STATIC); sqlite3VdbeAddOp(v, OP_Eq, 0, addr+6); sqlite3VdbeOp3(v, OP_String8, 0, 0, sqlite3MPrintf("*** in database %s ***\n", db->aDb[i].zName), P3_DYNAMIC); sqlite3VdbeAddOp(v, OP_Pull, 1, 0); | | | 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 | sqlite3VdbeAddOp(v, OP_Dup, 0, 1); addr = sqlite3VdbeOp3(v, OP_String8, 0, 0, "ok", P3_STATIC); sqlite3VdbeAddOp(v, OP_Eq, 0, addr+6); sqlite3VdbeOp3(v, OP_String8, 0, 0, sqlite3MPrintf("*** in database %s ***\n", db->aDb[i].zName), P3_DYNAMIC); sqlite3VdbeAddOp(v, OP_Pull, 1, 0); sqlite3VdbeAddOp(v, OP_Concat8, 2, 1); sqlite3VdbeAddOp(v, OP_Callback, 1, 0); /* Make sure all the indices are constructed correctly. */ sqlite3CodeVerifySchema(pParse, i); for(x=sqliteHashFirst(&db->aDb[i].tblHash); x; x=sqliteHashNext(x)){ Table *pTab = sqliteHashData(x); |
︙ | ︙ | |||
695 696 697 698 699 700 701 | int jmp2; static VdbeOpList idxErr[] = { { OP_MemIncr, 0, 0, 0}, { OP_String8, 0, 0, "rowid "}, { OP_Recno, 1, 0, 0}, { OP_String8, 0, 0, " missing from index "}, { OP_String8, 0, 0, 0}, /* 4 */ | | | 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 | int jmp2; static VdbeOpList idxErr[] = { { OP_MemIncr, 0, 0, 0}, { OP_String8, 0, 0, "rowid "}, { OP_Recno, 1, 0, 0}, { OP_String8, 0, 0, " missing from index "}, { OP_String8, 0, 0, 0}, /* 4 */ { OP_Concat8, 4, 0, 0}, { OP_Callback, 1, 0, 0}, }; sqlite3GenerateIndexKey(v, pIdx, 1); jmp2 = sqlite3VdbeAddOp(v, OP_Found, j+2, 0); addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr); sqlite3VdbeChangeP3(v, addr+4, pIdx->zName, P3_STATIC); sqlite3VdbeChangeP2(v, jmp2, sqlite3VdbeCurrentAddr(v)); |
︙ | ︙ | |||
719 720 721 722 723 724 725 | { OP_Next, 0, 0, 0}, /* 4 */ { OP_MemLoad, 1, 0, 0}, { OP_MemLoad, 2, 0, 0}, { OP_Eq, 0, 0, 0}, /* 7 */ { OP_MemIncr, 0, 0, 0}, { OP_String8, 0, 0, "wrong # of entries in index "}, { OP_String8, 0, 0, 0}, /* 10 */ | | | 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 | { OP_Next, 0, 0, 0}, /* 4 */ { OP_MemLoad, 1, 0, 0}, { OP_MemLoad, 2, 0, 0}, { OP_Eq, 0, 0, 0}, /* 7 */ { OP_MemIncr, 0, 0, 0}, { OP_String8, 0, 0, "wrong # of entries in index "}, { OP_String8, 0, 0, 0}, /* 10 */ { OP_Concat8, 2, 0, 0}, { OP_Callback, 1, 0, 0}, }; if( pIdx->tnum==0 ) continue; addr = sqlite3VdbeAddOpList(v, ArraySize(cntIdx), cntIdx); sqlite3VdbeChangeP1(v, addr+2, j+2); sqlite3VdbeChangeP2(v, addr+2, addr+5); sqlite3VdbeChangeP1(v, addr+4, j+2); |
︙ | ︙ |
Changes to src/trigger.c.
︙ | ︙ | |||
215 216 217 218 219 220 221 | { OP_NewRecno, 0, 0, 0 }, { OP_String8, 0, 0, "trigger" }, { OP_String8, 0, 0, 0 }, /* 2: trigger name */ { OP_String8, 0, 0, 0 }, /* 3: table name */ { OP_Integer, 0, 0, 0 }, { OP_String8, 0, 0, "CREATE TRIGGER "}, { OP_String8, 0, 0, 0 }, /* 6: SQL */ | | | 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 | { OP_NewRecno, 0, 0, 0 }, { OP_String8, 0, 0, "trigger" }, { OP_String8, 0, 0, 0 }, /* 2: trigger name */ { OP_String8, 0, 0, 0 }, /* 3: table name */ { OP_Integer, 0, 0, 0 }, { OP_String8, 0, 0, "CREATE TRIGGER "}, { OP_String8, 0, 0, 0 }, /* 6: SQL */ { OP_Concat8, 2, 0, 0 }, { OP_MakeRecord, 5, 0, "tttit" }, { OP_PutIntKey, 0, 0, 0 }, }; int addr; Vdbe *v; /* Make an entry in the sqlite_master table */ |
︙ | ︙ |
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.383 2004/06/21 09:06:42 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> #include "vdbeInt.h" /* |
︙ | ︙ | |||
764 765 766 767 768 769 770 | pTos->flags = MEM_Null; } break; } /* Opcode: HexBlob * * P3 ** | | | | | | 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 | pTos->flags = MEM_Null; } break; } /* Opcode: HexBlob * * P3 ** ** P3 is an UTF-8 SQL hex encoding of a blob. The blob is pushed onto the ** vdbe stack. ** ** The first time this instruction executes, in transforms itself into a ** 'Blob' opcode with a binary blob as P3. */ case OP_HexBlob: { pOp->opcode = OP_Blob; pOp->p1 = strlen(pOp->p3)/2; if( pOp->p1 ){ char *zBlob = sqlite3HexToBlob(pOp->p3); if( !zBlob ) goto no_mem; |
︙ | ︙ | |||
1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 | p->resOnStack = 1; p->nCallback++; p->popStack = pOp->p1; p->pc = pc + 1; p->pTos = pTos; return SQLITE_ROW; } /* 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. ** Put the result on the top of the stack. The original P1 elements ** are popped from the stack if P2==0 and retained if P2==1. If | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 | p->resOnStack = 1; p->nCallback++; p->popStack = pOp->p1; p->pc = pc + 1; p->pTos = pTos; return SQLITE_ROW; } /* Opcode: Concat8 P1 P2 P3 ** ** P3 points to a nul terminated UTF-8 string. When it is executed for ** the first time, P3 is converted to the native database encoding and ** the opcode replaced with Concat (see Concat for details of processing). */ case OP_Concat8: { pOp->opcode = OP_Concat; if( db->enc!=SQLITE_UTF8 && pOp->p3 ){ Mem tmp; tmp.flags = MEM_Null; sqlite3VdbeMemSetStr(&tmp, pOp->p3, -1, SQLITE_UTF8, SQLITE_STATIC); if( SQLITE_OK!=sqlite3VdbeChangeEncoding(&tmp, db->enc) || SQLITE_OK!=sqlite3VdbeMemDynamicify(&tmp) ){ goto no_mem; } assert( tmp.flags|MEM_Dyn ); assert( !tmp.xDel ); pOp->p3type = P3_DYNAMIC; pOp->p3 = tmp.z; /* Don't call sqlite3VdbeMemRelease() on &tmp, the dynamic allocation ** is cleaned up when the vdbe is deleted. */ } /* If it wasn't already, P3 has been converted to the database text ** encoding. Fall through to OP_Concat to process this instruction. */ } /* 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. ** Put the result on the top of the stack. The original P1 elements ** are popped from the stack if P2==0 and retained if P2==1. If |
︙ | ︙ | |||
1034 1035 1036 1037 1038 1039 1040 | char *zNew; int nByte; int nField; int i, j; Mem *pTerm; Mem mSep; /* Memory cell containing the seperator string, if any */ | < < < < > | > > > | < | 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 | char *zNew; int nByte; int nField; int i, j; Mem *pTerm; Mem mSep; /* Memory cell containing the seperator string, if any */ if( pOp->p3 ){ mSep.z = pOp->p3; if( db->enc==SQLITE_UTF8 ){ mSep.n = strlen(mSep.z); }else{ mSep.n = sqlite3utf16ByteLen(mSep.z, -1); } mSep.flags = MEM_Str|MEM_Static|MEM_Term; mSep.enc = db->enc; }else{ mSep.flags = MEM_Null; mSep.n = 0; } /* Loop through the stack elements to see how long the result will be. */ nField = pOp->p1; |
︙ | ︙ | |||
3610 3611 3612 3613 3614 3615 3616 | rc = sqlite3VdbeIdxRowid(pCrsr, &rowid); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } pTos->flags = MEM_Int; pTos->i = rowid; } | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 | rc = sqlite3VdbeIdxRowid(pCrsr, &rowid); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } pTos->flags = MEM_Int; pTos->i = rowid; } }else{ pTos->flags = MEM_Null; } break; } /* Opcode: IdxGT P1 P2 * |
︙ | ︙ | |||
4035 4036 4037 4038 4039 4040 4041 | /* FIX ME: This should be allocated as part of the vdbe at compile-time */ p->contextStack = sqliteRealloc(p->contextStack, sizeof(Context) * p->contextStackDepth); if( p->contextStack==0 ) goto no_mem; p->contextStack[p->contextStackDepth - 1].lastRowid = p->db->lastRowid; p->contextStack[p->contextStackDepth - 1].nChange = p->nChange; | < < < < < < < < < | 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 | /* FIX ME: This should be allocated as part of the vdbe at compile-time */ p->contextStack = sqliteRealloc(p->contextStack, sizeof(Context) * p->contextStackDepth); if( p->contextStack==0 ) goto no_mem; p->contextStack[p->contextStackDepth - 1].lastRowid = p->db->lastRowid; p->contextStack[p->contextStackDepth - 1].nChange = p->nChange; break; } /* Opcode: ContextPop * * * ** ** Restore the Vdbe context to the state it was in when contextPush was last ** executed. The context stores the last insert row id, the last statement ** change count, and the current statement change count. */ case OP_ContextPop: { assert(p->contextStackDepth > 0); p->contextStackDepth--; p->db->lastRowid = p->contextStack[p->contextStackDepth].lastRowid; p->nChange = p->contextStack[p->contextStackDepth].nChange; if( p->contextStackDepth == 0 ){ sqliteFree(p->contextStack); p->contextStack = 0; } break; } |
︙ | ︙ |