/ Check-in [bbd3e933]
Login

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 | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: bbd3e93348bc3a1178f5278c6cf0b82e75bbf642
User & Date: danielk1977 2004-06-21 09:06:42
Context
2004-06-21
10:45
Avoid opening a temp table for aggregate queries with no GROUP BY clause. (CVS 1649) check-in: 4d02df63 user: danielk1977 tags: trunk
09:06
Add the OP_Concat8 opcode, similar in concept to OP_String8. (CVS 1648) check-in: bbd3e933 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: 7a33daef user: danielk1977 tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/build.c.

    19     19   **     DROP INDEX
    20     20   **     creating ID lists
    21     21   **     BEGIN TRANSACTION
    22     22   **     COMMIT
    23     23   **     ROLLBACK
    24     24   **     PRAGMA
    25     25   **
    26         -** $Id: build.c,v 1.227 2004/06/19 17:33:07 drh Exp $
           26  +** $Id: build.c,v 1.228 2004/06/21 09:06:42 danielk1977 Exp $
    27     27   */
    28     28   #include "sqliteInt.h"
    29     29   #include <ctype.h>
    30     30   
    31     31   /*
    32     32   ** This routine is called when a new SQL statement is beginning to
    33     33   ** be parsed.  Check to see if the schema for the database needs
................................................................................
  1375   1375         }else{
  1376   1376           sqlite3VdbeOp3(v, OP_String8, 0, 0, "CREATE TABLE ", P3_STATIC);
  1377   1377         }
  1378   1378         assert( pEnd!=0 );
  1379   1379         n = Addr(pEnd->z) - Addr(pParse->sNameToken.z) + 1;
  1380   1380         sqlite3VdbeAddOp(v, OP_String8, 0, 0);
  1381   1381         sqlite3VdbeChangeP3(v, -1, pParse->sNameToken.z, n);
  1382         -      sqlite3VdbeAddOp(v, OP_Concat, 2, 0);
         1382  +      sqlite3VdbeAddOp(v, OP_Concat8, 2, 0);
  1383   1383       }
  1384   1384       sqlite3VdbeOp3(v, OP_MakeRecord, 5, 0, "tttit", P3_STATIC);
  1385   1385       sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0);
  1386   1386       if( p->iDb!=1 ){
  1387   1387         sqlite3ChangeCookie(db, v, p->iDb);
  1388   1388       }
  1389   1389       sqlite3VdbeAddOp(v, OP_Close, 0, 0);
................................................................................
  2174   2174           sqlite3VdbeChangeP3(v, -1, "CREATE INDEX ", P3_STATIC);
  2175   2175         }else{
  2176   2176           sqlite3VdbeChangeP3(v, -1, "CREATE UNIQUE INDEX ", P3_STATIC);
  2177   2177         }
  2178   2178         sqlite3VdbeAddOp(v, OP_String8, 0, 0);
  2179   2179         n = Addr(pEnd->z) - Addr(pName->z) + 1;
  2180   2180         sqlite3VdbeChangeP3(v, -1, pName->z, n);
  2181         -      sqlite3VdbeAddOp(v, OP_Concat, 2, 0);
         2181  +      sqlite3VdbeAddOp(v, OP_Concat8, 2, 0);
  2182   2182       }
  2183   2183       sqlite3VdbeOp3(v, OP_MakeRecord, 5, 0, "tttit", P3_STATIC);
  2184   2184       sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0);
  2185   2185       if( pTblName ){
  2186   2186         sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
  2187   2187         sqlite3VdbeAddOp(v, OP_OpenRead, 2, pTab->tnum);
  2188   2188         /* VdbeComment((v, "%s", pTab->zName)); */

Changes to src/expr.c.

     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains routines used for analyzing expressions and
    13     13   ** for generating VDBE code that evaluates expressions in SQLite.
    14     14   **
    15         -** $Id: expr.c,v 1.146 2004/06/21 07:36:32 danielk1977 Exp $
           15  +** $Id: expr.c,v 1.147 2004/06/21 09:06:42 danielk1977 Exp $
    16     16   */
    17     17   #include "sqliteInt.h"
    18     18   #include <ctype.h>
    19     19   
    20     20   char const *sqlite3AffinityString(char affinity){
    21     21     switch( affinity ){
    22     22       case SQLITE_AFF_INTEGER: return "i";
................................................................................
  1177   1177         sqlite3ExprCode(pParse, pExpr->pLeft);
  1178   1178         sqlite3VdbeAddOp(v, op, 0, 0);
  1179   1179         break;
  1180   1180       }
  1181   1181       case TK_CONCAT: {
  1182   1182         sqlite3ExprCode(pParse, pExpr->pLeft);
  1183   1183         sqlite3ExprCode(pParse, pExpr->pRight);
  1184         -      sqlite3VdbeAddOp(v, OP_Concat, 2, 0);
         1184  +      sqlite3VdbeAddOp(v, OP_Concat8, 2, 0);
  1185   1185         break;
  1186   1186       }
  1187   1187       case TK_UMINUS: {
  1188   1188         Expr *pLeft = pExpr->pLeft;
  1189   1189         assert( pLeft );
  1190   1190         if( pLeft->op==TK_FLOAT || pLeft->op==TK_INTEGER ){
  1191   1191           Token *p = &pLeft->token;

Changes to src/pragma.c.

     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains code used to implement the PRAGMA command.
    13     13   **
    14         -** $Id: pragma.c,v 1.51 2004/06/21 08:18:53 danielk1977 Exp $
           14  +** $Id: pragma.c,v 1.52 2004/06/21 09:06:42 danielk1977 Exp $
    15     15   */
    16     16   #include "sqliteInt.h"
    17     17   #include <ctype.h>
    18     18   
    19     19   #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
    20     20   # include "pager.h"
    21     21   # include "btree.h"
................................................................................
   662    662         sqlite3VdbeAddOp(v, OP_Dup, 0, 1);
   663    663         addr = sqlite3VdbeOp3(v, OP_String8, 0, 0, "ok", P3_STATIC);
   664    664         sqlite3VdbeAddOp(v, OP_Eq, 0, addr+6);
   665    665         sqlite3VdbeOp3(v, OP_String8, 0, 0,
   666    666            sqlite3MPrintf("*** in database %s ***\n", db->aDb[i].zName),
   667    667            P3_DYNAMIC);
   668    668         sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
   669         -      sqlite3VdbeAddOp(v, OP_Concat, 2, 1);
          669  +      sqlite3VdbeAddOp(v, OP_Concat8, 2, 1);
   670    670         sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
   671    671   
   672    672         /* Make sure all the indices are constructed correctly.
   673    673         */
   674    674         sqlite3CodeVerifySchema(pParse, i);
   675    675         for(x=sqliteHashFirst(&db->aDb[i].tblHash); x; x=sqliteHashNext(x)){
   676    676           Table *pTab = sqliteHashData(x);
................................................................................
   695    695             int jmp2;
   696    696             static VdbeOpList idxErr[] = {
   697    697               { OP_MemIncr,     0,  0,  0},
   698    698               { OP_String8,      0,  0,  "rowid "},
   699    699               { OP_Recno,       1,  0,  0},
   700    700               { OP_String8,      0,  0,  " missing from index "},
   701    701               { OP_String8,      0,  0,  0},    /* 4 */
   702         -            { OP_Concat,      4,  0,  0},
          702  +            { OP_Concat8,      4,  0,  0},
   703    703               { OP_Callback,    1,  0,  0},
   704    704             };
   705    705             sqlite3GenerateIndexKey(v, pIdx, 1);
   706    706             jmp2 = sqlite3VdbeAddOp(v, OP_Found, j+2, 0);
   707    707             addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr);
   708    708             sqlite3VdbeChangeP3(v, addr+4, pIdx->zName, P3_STATIC);
   709    709             sqlite3VdbeChangeP2(v, jmp2, sqlite3VdbeCurrentAddr(v));
................................................................................
   719    719                { OP_Next,         0,  0,  0},  /* 4 */
   720    720                { OP_MemLoad,      1,  0,  0},
   721    721                { OP_MemLoad,      2,  0,  0},
   722    722                { OP_Eq,           0,  0,  0},  /* 7 */
   723    723                { OP_MemIncr,      0,  0,  0},
   724    724                { OP_String8,       0,  0,  "wrong # of entries in index "},
   725    725                { OP_String8,       0,  0,  0},  /* 10 */
   726         -             { OP_Concat,       2,  0,  0},
          726  +             { OP_Concat8,       2,  0,  0},
   727    727                { OP_Callback,     1,  0,  0},
   728    728             };
   729    729             if( pIdx->tnum==0 ) continue;
   730    730             addr = sqlite3VdbeAddOpList(v, ArraySize(cntIdx), cntIdx);
   731    731             sqlite3VdbeChangeP1(v, addr+2, j+2);
   732    732             sqlite3VdbeChangeP2(v, addr+2, addr+5);
   733    733             sqlite3VdbeChangeP1(v, addr+4, j+2);

Changes to src/trigger.c.

   215    215         { OP_NewRecno,   0, 0,  0          },
   216    216         { OP_String8,     0, 0,  "trigger"  },
   217    217         { OP_String8,     0, 0,  0          },  /* 2: trigger name */
   218    218         { OP_String8,     0, 0,  0          },  /* 3: table name */
   219    219         { OP_Integer,    0, 0,  0          },
   220    220         { OP_String8,     0, 0,  "CREATE TRIGGER "},
   221    221         { OP_String8,     0, 0,  0          },  /* 6: SQL */
   222         -      { OP_Concat,     2, 0,  0          }, 
          222  +      { OP_Concat8,     2, 0,  0          }, 
   223    223         { OP_MakeRecord, 5, 0,  "tttit"    },
   224    224         { OP_PutIntKey,  0, 0,  0          },
   225    225       };
   226    226       int addr;
   227    227       Vdbe *v;
   228    228   
   229    229       /* Make an entry in the sqlite_master table */

Changes to src/vdbe.c.

    39     39   **
    40     40   ** Various scripts scan this source file in order to generate HTML
    41     41   ** documentation, headers files, or other derived files.  The formatting
    42     42   ** of the code in this file is, therefore, important.  See other comments
    43     43   ** in this file for details.  If in doubt, do not deviate from existing
    44     44   ** commenting and indentation practices when changing or adding code.
    45     45   **
    46         -** $Id: vdbe.c,v 1.382 2004/06/21 06:50:29 danielk1977 Exp $
           46  +** $Id: vdbe.c,v 1.383 2004/06/21 09:06:42 danielk1977 Exp $
    47     47   */
    48     48   #include "sqliteInt.h"
    49     49   #include "os.h"
    50     50   #include <ctype.h>
    51     51   #include "vdbeInt.h"
    52     52   
    53     53   /*
................................................................................
   764    764       pTos->flags = MEM_Null;
   765    765     }
   766    766     break;
   767    767   }
   768    768   
   769    769   /* Opcode: HexBlob * * P3
   770    770   **
   771         -** P3 is an SQL hex encoding of a blob. The blob is pushed
   772         -** onto the vdbe stack.
          771  +** P3 is an UTF-8 SQL hex encoding of a blob. The blob is pushed onto the
          772  +** vdbe stack.
   773    773   **
   774         -** The first time this instruction executes, in transforms
   775         -** itself into a 'Blob' opcode with a binary blob as P3.
          774  +** The first time this instruction executes, in transforms itself into a
          775  +** 'Blob' opcode with a binary blob as P3.
   776    776   */
   777    777   case OP_HexBlob: {
   778    778     pOp->opcode = OP_Blob;
   779    779     pOp->p1 = strlen(pOp->p3)/2;
   780    780     if( pOp->p1 ){
   781    781       char *zBlob = sqlite3HexToBlob(pOp->p3);
   782    782       if( !zBlob ) goto no_mem;
................................................................................
  1013   1013     p->resOnStack = 1;
  1014   1014     p->nCallback++;
  1015   1015     p->popStack = pOp->p1;
  1016   1016     p->pc = pc + 1;
  1017   1017     p->pTos = pTos;
  1018   1018     return SQLITE_ROW;
  1019   1019   }
         1020  +
         1021  +/* Opcode: Concat8 P1 P2 P3
         1022  +**
         1023  +** P3 points to a nul terminated UTF-8 string. When it is executed for
         1024  +** the first time, P3 is converted to the native database encoding and
         1025  +** the opcode replaced with Concat (see Concat for details of processing).
         1026  +*/
         1027  +case OP_Concat8: {
         1028  +  pOp->opcode = OP_Concat;
         1029  +
         1030  +  if( db->enc!=SQLITE_UTF8 && pOp->p3 ){
         1031  +    Mem tmp;
         1032  +    tmp.flags = MEM_Null;
         1033  +    sqlite3VdbeMemSetStr(&tmp, pOp->p3, -1, SQLITE_UTF8, SQLITE_STATIC);
         1034  +    if( SQLITE_OK!=sqlite3VdbeChangeEncoding(&tmp, db->enc) ||
         1035  +        SQLITE_OK!=sqlite3VdbeMemDynamicify(&tmp) 
         1036  +    ){
         1037  +      goto no_mem;
         1038  +    }
         1039  +    assert( tmp.flags|MEM_Dyn );
         1040  +    assert( !tmp.xDel );
         1041  +    pOp->p3type = P3_DYNAMIC;
         1042  +    pOp->p3 = tmp.z;
         1043  +    /* Don't call sqlite3VdbeMemRelease() on &tmp, the dynamic allocation
         1044  +    ** is cleaned up when the vdbe is deleted. 
         1045  +    */
         1046  +  }
         1047  +
         1048  +  /* If it wasn't already, P3 has been converted to the database text
         1049  +  ** encoding. Fall through to OP_Concat to process this instruction.
         1050  +  */
         1051  +}
  1020   1052   
  1021   1053   /* Opcode: Concat P1 P2 P3
  1022   1054   **
  1023   1055   ** Look at the first P1 elements of the stack.  Append them all 
  1024   1056   ** together with the lowest element first.  Use P3 as a separator.  
  1025   1057   ** Put the result on the top of the stack.  The original P1 elements
  1026   1058   ** are popped from the stack if P2==0 and retained if P2==1.  If
................................................................................
  1034   1066     char *zNew;
  1035   1067     int nByte;
  1036   1068     int nField;
  1037   1069     int i, j;
  1038   1070     Mem *pTerm;
  1039   1071     Mem mSep;     /* Memory cell containing the seperator string, if any */
  1040   1072   
  1041         -  /* FIX ME: Eventually, P3 will be in database native encoding. But for
  1042         -  ** now it is always UTF-8. So set up zSep to hold the native encoding of
  1043         -  ** P3.
  1044         -  */
  1045   1073     if( pOp->p3 ){
  1046   1074       mSep.z = pOp->p3;
  1047         -    mSep.n = strlen(mSep.z);
         1075  +    if( db->enc==SQLITE_UTF8 ){
         1076  +      mSep.n = strlen(mSep.z);
         1077  +    }else{
         1078  +      mSep.n = sqlite3utf16ByteLen(mSep.z, -1);
         1079  +    }
  1048   1080       mSep.flags = MEM_Str|MEM_Static|MEM_Term;
  1049         -    mSep.enc = SQLITE_UTF8;
  1050         -    sqlite3VdbeChangeEncoding(&mSep, db->enc);
         1081  +    mSep.enc = db->enc;
  1051   1082     }else{
  1052   1083       mSep.flags = MEM_Null;
  1053   1084       mSep.n = 0;
  1054   1085     }
  1055   1086   
  1056   1087     /* Loop through the stack elements to see how long the result will be. */
  1057   1088     nField = pOp->p1;
................................................................................
  3610   3641         rc = sqlite3VdbeIdxRowid(pCrsr, &rowid);
  3611   3642         if( rc!=SQLITE_OK ){
  3612   3643           goto abort_due_to_error;
  3613   3644         }
  3614   3645         pTos->flags = MEM_Int;
  3615   3646         pTos->i = rowid;
  3616   3647       }
  3617         -
  3618         -#if 0
  3619         -    /* Read the final 9 bytes of the key into buf[]. If the whole key is
  3620         -    ** less than 9 bytes then just load the whole thing. Set len to the 
  3621         -    ** number of bytes read.
  3622         -    */
  3623         -    sqlite3BtreeKeySize(pCrsr, &sz);
  3624         -    len = ((sz>10)?10:sz);
  3625         -    rc = sqlite3BtreeKey(pCrsr, sz-len, len, buf);
  3626         -    if( rc!=SQLITE_OK ){
  3627         -      goto abort_due_to_error;
  3628         -    }
  3629         -
  3630         -    len--;
  3631         -    if( buf[len]&0x80 ){
  3632         -      /* If the last byte read has the 0x80 bit set, then the key does
  3633         -      ** not end with a varint. Push a NULL onto the stack instead.
  3634         -      */
  3635         -      pTos->flags = MEM_Null;
  3636         -    }else{
  3637         -      /* Find the start of the varint by searching backwards for a 0x00
  3638         -      ** byte. If one does not exists, then intepret the whole 9 bytes as a
  3639         -      ** varint.
  3640         -      */
  3641         -      while( len && buf[len-1] ){
  3642         -        len--;
  3643         -      }
  3644         -      sqlite3GetVarint32(&buf[len], &sz);
  3645         -      pTos->flags = MEM_Int;
  3646         -      pTos->i = sz;
  3647         -    }
  3648         -#endif
  3649   3648     }else{
  3650   3649       pTos->flags = MEM_Null;
  3651   3650     }
  3652   3651     break;
  3653   3652   }
  3654   3653   
  3655   3654   /* Opcode: IdxGT P1 P2 *
................................................................................
  4035   4034     /* FIX ME: This should be allocated as part of the vdbe at compile-time */
  4036   4035     p->contextStack = sqliteRealloc(p->contextStack, 
  4037   4036             sizeof(Context) * p->contextStackDepth);
  4038   4037     if( p->contextStack==0 ) goto no_mem;
  4039   4038   
  4040   4039     p->contextStack[p->contextStackDepth - 1].lastRowid = p->db->lastRowid;
  4041   4040     p->contextStack[p->contextStackDepth - 1].nChange = p->nChange;
  4042         -
  4043         -#if 0
  4044         -  p->contextStack[p->contextStackDepth - 1].lsChange = p->db->lsChange;
  4045         -  p->contextStack[p->contextStackDepth - 1].csChange = p->db->csChange;
  4046         -#endif
  4047   4041     break;
  4048   4042   }
  4049   4043   
  4050   4044   /* Opcode: ContextPop * * * 
  4051   4045   **
  4052   4046   ** Restore the Vdbe context to the state it was in when contextPush was last
  4053   4047   ** executed. The context stores the last insert row id, the last statement
................................................................................
  4054   4048   ** change count, and the current statement change count.
  4055   4049   */
  4056   4050   case OP_ContextPop: {
  4057   4051     assert(p->contextStackDepth > 0);
  4058   4052     p->contextStackDepth--;
  4059   4053     p->db->lastRowid = p->contextStack[p->contextStackDepth].lastRowid;
  4060   4054     p->nChange = p->contextStack[p->contextStackDepth].nChange;
  4061         -#if 0
  4062         -  p->db->lsChange = p->contextStack[p->contextStackDepth].lsChange;
  4063         -  p->db->csChange = p->contextStack[p->contextStackDepth].csChange;
  4064         -#endif
  4065   4055     if( p->contextStackDepth == 0 ){
  4066   4056       sqliteFree(p->contextStack);
  4067   4057       p->contextStack = 0;
  4068   4058     }
  4069   4059     break;
  4070   4060   }
  4071   4061