Remove the OP_HexBlob instruction and code OP_Blob directly.  Reduce
the amount of memory allocation required to encode blob literals.
Remove the "out2" instruction type.  Other minor optimizations. (CVS 4726)

FossilOrigin-Name: 0e50c0200a3c1c04e63cbb55a7255cdbbd225347
diff --git a/src/expr.c b/src/expr.c
index ec850ea..01574f2 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.349 2008/01/18 02:31:56 drh Exp $
+** $Id: expr.c,v 1.350 2008/01/18 14:08:24 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -2004,14 +2004,15 @@
     case TK_BLOB: {
       int n;
       const char *z;
-      assert( TK_BLOB==OP_HexBlob );
+      char *zBlob;
+      assert( pExpr->token.n>=3 );
+      assert( pExpr->token.z[0]=='x' || pExpr->token.z[0]=='X' );
+      assert( pExpr->token.z[1]=='\'' );
+      assert( pExpr->token.z[pExpr->token.n-1]=='\'' );
       n = pExpr->token.n - 3;
       z = (char*)pExpr->token.z + 2;
-      assert( n>=0 );
-      if( n==0 ){
-        z = "";
-      }
-      sqlite3VdbeAddOp4(v, op, 0, target, 0, z, n);
+      zBlob = sqlite3HexToBlob(sqlite3VdbeDb(v), z, n);
+      sqlite3VdbeAddOp4(v, OP_Blob, n/2, target, 0, zBlob, P4_DYNAMIC);
       break;
     }
 #endif
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 7529318..943e396 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.651 2008/01/17 16:22:15 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.652 2008/01/18 14:08:24 drh Exp $
 */
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
@@ -1889,7 +1889,7 @@
 char sqlite3ExprAffinity(Expr *pExpr);
 int sqlite3Atoi64(const char*, i64*);
 void sqlite3Error(sqlite3*, int, const char*,...);
-void *sqlite3HexToBlob(sqlite3*, const char *z);
+void *sqlite3HexToBlob(sqlite3*, const char *z, int n);
 int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);
 const char *sqlite3ErrStr(int);
 int sqlite3ReadSchema(Parse *pParse);
diff --git a/src/util.c b/src/util.c
index 318bd25..846029e 100644
--- a/src/util.c
+++ b/src/util.c
@@ -14,7 +14,7 @@
 ** This file contains functions for allocating memory, comparing
 ** strings, and stuff like that.
 **
-** $Id: util.c,v 1.213 2007/10/23 15:39:45 drh Exp $
+** $Id: util.c,v 1.214 2008/01/18 14:08:25 drh Exp $
 */
 #include "sqliteInt.h"
 #include <stdarg.h>
@@ -637,17 +637,17 @@
 ** binary value has been obtained from malloc and must be freed by
 ** the calling routine.
 */
-void *sqlite3HexToBlob(sqlite3 *db, const char *z){
+void *sqlite3HexToBlob(sqlite3 *db, const char *z, int n){
   char *zBlob;
   int i;
-  int n = strlen(z);
-  if( n%2 ) return 0;
 
-  zBlob = (char *)sqlite3DbMallocRaw(db, n/2);
+  zBlob = (char *)sqlite3DbMallocRaw(db, n/2 + 1);
+  n--;
   if( zBlob ){
     for(i=0; i<n; i+=2){
       zBlob[i/2] = (hexToInt(z[i])<<4) | hexToInt(z[i+1]);
     }
+    zBlob[i/2] = 0;
   }
   return zBlob;
 }
diff --git a/src/vdbe.c b/src/vdbe.c
index 50394d6..f7293e1 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.698 2008/01/17 16:22:15 drh Exp $
+** $Id: vdbe.c,v 1.699 2008/01/18 14:08:25 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -92,6 +92,11 @@
 */
 #ifdef SQLITE_TEST
 int sqlite3_max_blobsize = 0;
+static void updateMaxBlobsize(Mem *p){
+  if( (p->flags & (MEM_Str|MEM_Blob))!=0 && p->n>sqlite3_max_blobsize ){
+    sqlite3_max_blobsize = p->n;
+  }
+}
 #endif
 
 /*
@@ -99,9 +104,7 @@
 ** If it does, record the new maximum blob size.
 */
 #ifdef SQLITE_TEST
-# define UPDATE_MAX_BLOBSIZE(P)  if( ((P)->flags&(MEM_Str|MEM_Blob))!=0 \
-                                      && (P)->n>sqlite3_max_blobsize ) \
-                                          {sqlite3_max_blobsize = (P)->n;}
+# define UPDATE_MAX_BLOBSIZE(P)  updateMaxBlobsize(P)
 #else
 # define UPDATE_MAX_BLOBSIZE(P)
 #endif
@@ -509,7 +512,7 @@
   int nProgressOps = 0;      /* Opcodes executed since progress callback. */
 #endif
 
-  if( p->magic!=VDBE_MAGIC_RUN ) return SQLITE_MISUSE;
+  assert( p->magic==VDBE_MAGIC_RUN );  /* sqlite3_step() verifies this */
   assert( db->magic==SQLITE_MAGIC_BUSY );
   sqlite3BtreeMutexArrayEnter(&p->aMutex);
   if( p->rc==SQLITE_NOMEM ){
@@ -621,7 +624,6 @@
     **           in1 in2
     **           in1 in2 out3
     **           in1 in3
-    **           in1 out2
     **
     ** Variables pIn1, pIn2, and pIn3 are made to point to appropriate
     ** registers for inputs.  Variable pOut points to the output register.
@@ -646,10 +648,6 @@
         assert( pOp->p3<=p->nMem );
         pIn3 = &p->aMem[pOp->p3];
         REGISTER_TRACE(pOp->p3, pIn3);
-      }else if( (opProperty & OPFLG_OUT2)!=0 ){
-        assert( pOp->p2>0 );
-        assert( pOp->p2<=p->nMem );
-        pOut = &p->aMem[pOp->p2];
       }
     }else if( (opProperty & OPFLG_IN2)!=0 ){
       assert( pOp->p2>0 );
@@ -872,39 +870,6 @@
 
 
 #ifndef SQLITE_OMIT_BLOB_LITERAL
-/* Opcode: HexBlob * P2 * P4 *
-**
-** P4 is an UTF-8 SQL hex encoding of a blob. The blob is stored in
-** register P2.
-**
-** The first time this instruction executes, in transforms itself into a
-** 'Blob' opcode with a binary blob as P4.
-*/
-case OP_HexBlob: {            /* same as TK_BLOB, out2-prerelease */
-  pOp->opcode = OP_Blob;
-  pOp->p1 = strlen(pOp->p4.z)/2;
-  if( pOp->p1>SQLITE_MAX_LENGTH ){
-    goto too_big;
-  }
-  if( pOp->p1 ){
-    char *zBlob = sqlite3HexToBlob(db, pOp->p4.z);
-    if( !zBlob ) goto no_mem;
-    if( pOp->p4type==P4_DYNAMIC ){
-      sqlite3_free(pOp->p4.z);
-    }
-    pOp->p4.z = zBlob;
-    pOp->p4type = P4_DYNAMIC;
-  }else{
-    if( pOp->p4type==P4_DYNAMIC ){
-      sqlite3_free(pOp->p4.z);
-    }
-    pOp->p4type = P4_STATIC;
-    pOp->p4.z = "";
-  }
-
-  /* Fall through to the next case, OP_Blob. */
-}
-
 /* Opcode: Blob P1 P2 * P4
 **
 ** P4 points to a blob of data P1 bytes long.  Store this
@@ -4814,10 +4779,10 @@
 #ifdef SQLITE_DEBUG
     if( p->trace ){
       if( rc!=0 ) fprintf(p->trace,"rc=%d\n",rc);
-      if( (opProperty&(OPFLG_OUT2_PRERELEASE|OPFLG_OUT2))!=0 && pOp->p2>0 ){
+      if( opProperty & OPFLG_OUT2_PRERELEASE ){
         registerTrace(p->trace, pOp->p2, pOut);
       }
-      if( (opProperty&OPFLG_OUT3)!=0 && pOp->p3>0 ){
+      if( opProperty & OPFLG_OUT3 ){
         registerTrace(p->trace, pOp->p3, pOut);
       }
     }
diff --git a/src/vdbemem.c b/src/vdbemem.c
index 4438192..2d9a943 100644
--- a/src/vdbemem.c
+++ b/src/vdbemem.c
@@ -989,13 +989,15 @@
 #ifndef SQLITE_OMIT_BLOB_LITERAL
   else if( op==TK_BLOB ){
     int nVal;
+    assert( pExpr->token.n>=3 );
+    assert( pExpr->token.z[0]=='x' || pExpr->token.z[0]=='X' );
+    assert( pExpr->token.z[1]=='\'' );
+    assert( pExpr->token.z[pExpr->token.n-1]=='\'' );
     pVal = sqlite3ValueNew(db);
-    zVal = sqlite3StrNDup((char*)pExpr->token.z+1, pExpr->token.n-1);
-    if( !zVal || !pVal ) goto no_mem;
-    sqlite3Dequote(zVal);
-    nVal = strlen(zVal)/2;
-    sqlite3VdbeMemSetStr(pVal, sqlite3HexToBlob(db, zVal), nVal,0,sqlite3_free);
-    sqlite3_free(zVal);
+    nVal = pExpr->token.n - 3;
+    zVal = (char*)pExpr->token.z + 2;
+    sqlite3VdbeMemSetStr(pVal, sqlite3HexToBlob(db, zVal, nVal), nVal/2,
+                         0, sqlite3_free);
   }
 #endif