From 72c952a1c49de6356df9e249c544af77f133f5a5 Mon Sep 17 00:00:00 2001 From: danielk1977 Date: Mon, 21 Jun 2004 09:06:41 +0000 Subject: [PATCH] Add the OP_Concat8 opcode, similar in concept to OP_String8. (CVS 1648) FossilOrigin-Name: bbd3e93348bc3a1178f5278c6cf0b82e75bbf642 --- manifest | 20 +++++------ manifest.uuid | 2 +- src/build.c | 6 ++-- src/expr.c | 4 +-- src/pragma.c | 8 ++--- src/trigger.c | 2 +- src/vdbe.c | 96 +++++++++++++++++++++++---------------------------- 7 files changed, 64 insertions(+), 74 deletions(-) diff --git a/manifest b/manifest index 28b92e55e2..affa485fbb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\ssqlite3ErrorMsg()\sis\sused\sto\sreport\serrors\sduring\scompilation,\nsqlite3Error()\sduring\sexecution.\sAlso\sremove\sunused\sparam\sfrom\nsqlite3VdbeReset()\sand\sFinalize().\s(CVS\s1647) -D 2004-06-21T08:18:52 +C Add\sthe\sOP_Concat8\sopcode,\ssimilar\sin\sconcept\sto\sOP_String8.\s(CVS\s1648) +D 2004-06-21T09:06:42 F Makefile.in d69d53c543518c1572ee0a8e8723d7e00bdb2266 F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd @@ -28,11 +28,11 @@ F src/attach.c 05102e2e8ac43ce639d07b47a99c7772a62420e6 F src/auth.c 60db23b98bb94c8b0178180faaf49dc116674217 F src/btree.c 0cf8a52a57a7eb13d50719114ee1fa353e89d7d3 F src/btree.h 32f96abef464cf8765b23ca669acfe90d191fcc5 -F src/build.c 2ed1f14a72ce94a2e4adf333272d67a49925304b +F src/build.c b1180cfc82b29fae42f9eac84aa869f3f7e207a8 F src/date.c b3e8b2bef1e3f2ce24e5b057203036defb18c3f1 F src/delete.c 19287dd204569519636a04eca2b66c49c26e9266 F src/encode.c a876af473d1d636faa3dca51c7571f2e007eea37 -F src/expr.c c5c875be667d76f92221f8fa6b30d507a7643612 +F src/expr.c a0372aa8d27ce9a82f6419c066b47f0500ec50a6 F src/func.c 3d32878eeb4c6a9977c72ec19984d329b6954c7e F src/hash.c 440c2f8cb373ee1b4e13a0988489c7cd95d55b6f F src/hash.h 762d95f1e567664d1eafc1687de755626be962fb @@ -51,7 +51,7 @@ F src/os_win.h 004eec47b1780fcaf07420ddc2072294b698d48c F src/pager.c d627c5e46084b0c757a16cec2c17adcc8046f8ee F src/pager.h bc58d32a9dee464f7268fb68652c130a4216e438 F src/parse.y 097438674976355a10cf177bd97326c548820b86 -F src/pragma.c 7d75803f3e28dd769b1b013f4395030e3dfdec43 +F src/pragma.c 0750e1c360647dbe0a991f16133b0fe5e42e5039 F src/printf.c 823b6a5cbedb6971a9e62f5d83204fe9b0be7c1b F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3 F src/select.c 7305795965f7702c6d95fc023dee138b40e90d41 @@ -66,12 +66,12 @@ F src/test3.c 7247090d15a5a43823079b6fd8dad1ed3cccdedf F src/test4.c a921a69821fd30209589228e64f94e9f715b6fe2 F src/test5.c 1b7c275b2929dbd034a567255d2aca339410d1d6 F src/tokenize.c 900374b6b37f04748bcd48c2d29a41c251542935 -F src/trigger.c 65fa572487f945d3d11ab451f232b430a370bae3 +F src/trigger.c 368fb2953bef9399273c67bca283914822de8762 F src/update.c b66b1896c9da54678ba3eff2bf0b4d291a95986a F src/utf.c 3a2596013e4b9582d075ca742de7f067ff7dee95 F src/util.c e31e35d3d76cab7a02045095064897eca49cbce3 F src/vacuum.c fcb930215a3f6c50087300782555f61ad11dd80c -F src/vdbe.c d8e533a537997ddfdf224cc802abaf3aa4448c69 +F src/vdbe.c 78d675c104d917a3061218775dddc5283cfff49d F src/vdbe.h 2d87155e31e84bb00cdc48cc1ce6987a3a484250 F src/vdbeInt.h 4d56da610923efa8d4c9db89dff17cb721e69a9b F src/vdbeapi.c 8a9421341e09b506a934132c9015f26362ae8c0e @@ -225,7 +225,7 @@ F www/tclsqlite.tcl 19191cf2a1010eaeff74c51d83fd5f5a4d899075 F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9 F www/version3.tcl af528563442e3039928f9018327a18157e53a44f F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4 -P ee9dffd986621490af7bd45c7fe070bb7da8c357 -R 728404e0c220e38b5c2b0297db2e65c7 +P 7a33daef5b49b1f2d89f27e0063372fe4f1702c8 +R 7ca92734bb4802e7f5046704b052bee6 U danielk1977 -Z b421bbf3c1e7b9c043b8dcb0de5ecf25 +Z f888e07c9fa8c25fdc20925aefd11399 diff --git a/manifest.uuid b/manifest.uuid index aa9f9ad31e..af75d5edab 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7a33daef5b49b1f2d89f27e0063372fe4f1702c8 \ No newline at end of file +bbd3e93348bc3a1178f5278c6cf0b82e75bbf642 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 35ddad2732..04b60a0a1e 100644 --- a/src/build.c +++ b/src/build.c @@ -23,7 +23,7 @@ ** ROLLBACK ** PRAGMA ** -** $Id: build.c,v 1.227 2004/06/19 17:33:07 drh Exp $ +** $Id: build.c,v 1.228 2004/06/21 09:06:42 danielk1977 Exp $ */ #include "sqliteInt.h" #include @@ -1379,7 +1379,7 @@ void sqlite3EndTable(Parse *pParse, Token *pEnd, Select *pSelect){ 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_Concat, 2, 0); + sqlite3VdbeAddOp(v, OP_Concat8, 2, 0); } sqlite3VdbeOp3(v, OP_MakeRecord, 5, 0, "tttit", P3_STATIC); sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0); @@ -2178,7 +2178,7 @@ void sqlite3CreateIndex( sqlite3VdbeAddOp(v, OP_String8, 0, 0); n = Addr(pEnd->z) - Addr(pName->z) + 1; sqlite3VdbeChangeP3(v, -1, pName->z, n); - sqlite3VdbeAddOp(v, OP_Concat, 2, 0); + sqlite3VdbeAddOp(v, OP_Concat8, 2, 0); } sqlite3VdbeOp3(v, OP_MakeRecord, 5, 0, "tttit", P3_STATIC); sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0); diff --git a/src/expr.c b/src/expr.c index 6cad4eefe0..6665daf7b1 100644 --- a/src/expr.c +++ b/src/expr.c @@ -12,7 +12,7 @@ ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** -** $Id: expr.c,v 1.146 2004/06/21 07:36:32 danielk1977 Exp $ +** $Id: expr.c,v 1.147 2004/06/21 09:06:42 danielk1977 Exp $ */ #include "sqliteInt.h" #include @@ -1181,7 +1181,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ case TK_CONCAT: { sqlite3ExprCode(pParse, pExpr->pLeft); sqlite3ExprCode(pParse, pExpr->pRight); - sqlite3VdbeAddOp(v, OP_Concat, 2, 0); + sqlite3VdbeAddOp(v, OP_Concat8, 2, 0); break; } case TK_UMINUS: { diff --git a/src/pragma.c b/src/pragma.c index c44d7509ff..a4fba9fa23 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -11,7 +11,7 @@ ************************************************************************* ** This file contains code used to implement the PRAGMA command. ** -** $Id: pragma.c,v 1.51 2004/06/21 08:18:53 danielk1977 Exp $ +** $Id: pragma.c,v 1.52 2004/06/21 09:06:42 danielk1977 Exp $ */ #include "sqliteInt.h" #include @@ -666,7 +666,7 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){ sqlite3MPrintf("*** in database %s ***\n", db->aDb[i].zName), P3_DYNAMIC); sqlite3VdbeAddOp(v, OP_Pull, 1, 0); - sqlite3VdbeAddOp(v, OP_Concat, 2, 1); + sqlite3VdbeAddOp(v, OP_Concat8, 2, 1); sqlite3VdbeAddOp(v, OP_Callback, 1, 0); /* Make sure all the indices are constructed correctly. @@ -699,7 +699,7 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){ { OP_Recno, 1, 0, 0}, { OP_String8, 0, 0, " missing from index "}, { OP_String8, 0, 0, 0}, /* 4 */ - { OP_Concat, 4, 0, 0}, + { OP_Concat8, 4, 0, 0}, { OP_Callback, 1, 0, 0}, }; sqlite3GenerateIndexKey(v, pIdx, 1); @@ -723,7 +723,7 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){ { OP_MemIncr, 0, 0, 0}, { OP_String8, 0, 0, "wrong # of entries in index "}, { OP_String8, 0, 0, 0}, /* 10 */ - { OP_Concat, 2, 0, 0}, + { OP_Concat8, 2, 0, 0}, { OP_Callback, 1, 0, 0}, }; if( pIdx->tnum==0 ) continue; diff --git a/src/trigger.c b/src/trigger.c index 19fd50ddd4..a10474f0b9 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -219,7 +219,7 @@ void sqlite3FinishTrigger( { OP_Integer, 0, 0, 0 }, { OP_String8, 0, 0, "CREATE TRIGGER "}, { OP_String8, 0, 0, 0 }, /* 6: SQL */ - { OP_Concat, 2, 0, 0 }, + { OP_Concat8, 2, 0, 0 }, { OP_MakeRecord, 5, 0, "tttit" }, { OP_PutIntKey, 0, 0, 0 }, }; diff --git a/src/vdbe.c b/src/vdbe.c index 68661340dd..df1303fcec 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -43,7 +43,7 @@ ** 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.382 2004/06/21 06:50:29 danielk1977 Exp $ +** $Id: vdbe.c,v 1.383 2004/06/21 09:06:42 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -768,11 +768,11 @@ case OP_String: { /* Opcode: HexBlob * * P3 ** -** P3 is an SQL hex encoding of a blob. The blob is pushed -** onto the vdbe stack. +** 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. +** 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; @@ -1018,6 +1018,38 @@ case OP_Callback: { 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 @@ -1038,16 +1070,15 @@ case OP_Concat: { Mem *pTerm; Mem mSep; /* Memory cell containing the seperator string, if any */ - /* FIX ME: Eventually, P3 will be in database native encoding. But for - ** now it is always UTF-8. So set up zSep to hold the native encoding of - ** P3. - */ if( pOp->p3 ){ mSep.z = pOp->p3; - mSep.n = strlen(mSep.z); + 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 = SQLITE_UTF8; - sqlite3VdbeChangeEncoding(&mSep, db->enc); + mSep.enc = db->enc; }else{ mSep.flags = MEM_Null; mSep.n = 0; @@ -3614,38 +3645,6 @@ case OP_IdxRecno: { pTos->flags = MEM_Int; pTos->i = rowid; } - -#if 0 - /* Read the final 9 bytes of the key into buf[]. If the whole key is - ** less than 9 bytes then just load the whole thing. Set len to the - ** number of bytes read. - */ - sqlite3BtreeKeySize(pCrsr, &sz); - len = ((sz>10)?10:sz); - rc = sqlite3BtreeKey(pCrsr, sz-len, len, buf); - if( rc!=SQLITE_OK ){ - goto abort_due_to_error; - } - - len--; - if( buf[len]&0x80 ){ - /* If the last byte read has the 0x80 bit set, then the key does - ** not end with a varint. Push a NULL onto the stack instead. - */ - pTos->flags = MEM_Null; - }else{ - /* Find the start of the varint by searching backwards for a 0x00 - ** byte. If one does not exists, then intepret the whole 9 bytes as a - ** varint. - */ - while( len && buf[len-1] ){ - len--; - } - sqlite3GetVarint32(&buf[len], &sz); - pTos->flags = MEM_Int; - pTos->i = sz; - } -#endif }else{ pTos->flags = MEM_Null; } @@ -4039,11 +4038,6 @@ case OP_ContextPush: { p->contextStack[p->contextStackDepth - 1].lastRowid = p->db->lastRowid; p->contextStack[p->contextStackDepth - 1].nChange = p->nChange; - -#if 0 - p->contextStack[p->contextStackDepth - 1].lsChange = p->db->lsChange; - p->contextStack[p->contextStackDepth - 1].csChange = p->db->csChange; -#endif break; } @@ -4058,10 +4052,6 @@ case OP_ContextPop: { p->contextStackDepth--; p->db->lastRowid = p->contextStack[p->contextStackDepth].lastRowid; p->nChange = p->contextStack[p->contextStackDepth].nChange; -#if 0 - p->db->lsChange = p->contextStack[p->contextStackDepth].lsChange; - p->db->csChange = p->contextStack[p->contextStackDepth].csChange; -#endif if( p->contextStackDepth == 0 ){ sqliteFree(p->contextStack); p->contextStack = 0;