SQLite

Check-in [bbd3e93348]
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
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: bbd3e93348bc3a1178f5278c6cf0b82e75bbf642
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
Side-by-Side Diff Ignore Whitespace Patch
Changes to src/build.c.
19
20
21
22
23
24
25
26

27
28
29
30
31
32
33
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.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 <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
1382

1383
1384
1385
1386
1387
1388
1389
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_Concat, 2, 0);
      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
2181

2182
2183
2184
2185
2186
2187
2188
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_Concat, 2, 0);
      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
15

16
17
18
19
20
21
22
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.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 <ctype.h>

char const *sqlite3AffinityString(char affinity){
  switch( affinity ){
    case SQLITE_AFF_INTEGER: return "i";
1177
1178
1179
1180
1181
1182
1183
1184

1185
1186
1187
1188
1189
1190
1191
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_Concat, 2, 0);
      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
14

15
16
17
18
19
20
21
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.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 <ctype.h>

#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
# include "pager.h"
# include "btree.h"
662
663
664
665
666
667
668
669

670
671
672
673
674
675
676
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_Concat, 2, 1);
      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
702

703
704
705
706
707
708
709
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_Concat,      4,  0,  0},
            { 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
726

727
728
729
730
731
732
733
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_Concat,       2,  0,  0},
             { 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
222

223
224
225
226
227
228
229
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_Concat,     2, 0,  0          }, 
      { 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
46

47
48
49
50
51
52
53
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.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"
#include <ctype.h>
#include "vdbeInt.h"

/*
764
765
766
767
768
769
770
771
772


773
774
775


776
777
778
779
780
781
782
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 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;
  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
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
1041
1042
1043
1044
1045
1046

1047




1048
1049

1050
1051
1052
1053
1054
1055
1056
1057
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 */

  /* 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;
    if( db->enc==SQLITE_UTF8 ){
    mSep.n = strlen(mSep.z);
      mSep.n = strlen(mSep.z);
    }else{
      mSep.n = sqlite3utf16ByteLen(mSep.z, -1);
    }
    mSep.flags = MEM_Str|MEM_Static|MEM_Term;
    mSep.enc = SQLITE_UTF8;
    mSep.enc = db->enc;
    sqlite3VdbeChangeEncoding(&mSep, 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
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
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;
    }

#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;
  }
  break;
}

/* Opcode: IdxGT P1 P2 *
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
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
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;

#if 0
  p->contextStack[p->contextStackDepth - 1].lsChange = p->db->lsChange;
  p->contextStack[p->contextStackDepth - 1].csChange = p->db->csChange;
#endif
  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 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;
  }
  break;
}