/ Check-in [7e30fd6a]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Floating point and 64-bit integer constants store in the virtual machine opcodes in binary, not as text. Performance improvement. Ticket #2733. (CVS 4507)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 7e30fd6a09899842c922b044714dc66796e545d4
User & Date: drh 2007-10-23 15:39:45
Context
2007-10-23
15:51
Make sure the _LARGEFILE_SOURCE macro occurs before any system includes. Ticket #2739. (CVS 4508) check-in: 36465aeb user: drh tags: trunk
15:39
Floating point and 64-bit integer constants store in the virtual machine opcodes in binary, not as text. Performance improvement. Ticket #2733. (CVS 4507) check-in: 7e30fd6a user: drh tags: trunk
14:55
Fix limit assertions in vdbe.c. Ticket #2740. (CVS 4506) check-in: 27f846d0 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/expr.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
1675
1676
1677
1678
1679
1680
1681




























1682
1683
1684
1685
1686
1687
1688
1689
1690
1691

1692
1693





1694
1695
1696

1697
1698
1699
1700
1701
1702
1703
....
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775



1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
....
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884

1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
**    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.313 2007/09/18 15:55:07 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Return the 'affinity' of the expression pExpr if any.
**
................................................................................
  if( testAddr ){
    sqlite3VdbeJumpHere(v, testAddr);
  }

  return;
}
#endif /* SQLITE_OMIT_SUBQUERY */





























/*
** Generate an instruction that will put the integer describe by
** text z[0..n-1] on the stack.
*/
static void codeInteger(Vdbe *v, const char *z, int n){
  assert( z || v==0 || sqlite3VdbeDb(v)->mallocFailed );
  if( z ){
    int i;
    if( sqlite3GetInt32(z, &i) ){

      sqlite3VdbeAddOp(v, OP_Integer, i, 0);
    }else if( sqlite3FitsIn64Bits(z) ){





      sqlite3VdbeOp3(v, OP_Int64, 0, 0, z, n);
    }else{
      sqlite3VdbeOp3(v, OP_Real, 0, 0, z, n);

    }
  }
}


/*
** Generate code that will extract the iColumn-th column from
................................................................................
        sqlite3VdbeAddOp(v, OP_Dup, pParse->ckOffset-pExpr->iColumn-1, 1);
      }else{
        sqlite3ExprCodeGetColumn(v, pExpr->pTab, pExpr->iColumn, pExpr->iTable);
      }
      break;
    }
    case TK_INTEGER: {
      codeInteger(v, (char*)pExpr->token.z, pExpr->token.n);
      break;
    }
    case TK_FLOAT:



    case TK_STRING: {
      assert( TK_FLOAT==OP_Real );
      assert( TK_STRING==OP_String8 );
      sqlite3DequoteExpr(pParse->db, pExpr);
      sqlite3VdbeOp3(v, op, 0, 0, (char*)pExpr->token.z, pExpr->token.n);
      break;
    }
    case TK_NULL: {
      sqlite3VdbeAddOp(v, OP_Null, 0, 0);
      break;
    }
#ifndef SQLITE_OMIT_BLOB_LITERAL
................................................................................
      break;
    }
    case TK_UMINUS: {
      Expr *pLeft = pExpr->pLeft;
      assert( pLeft );
      if( pLeft->op==TK_FLOAT || pLeft->op==TK_INTEGER ){
        Token *p = &pLeft->token;
        char *z = sqlite3MPrintf(pParse->db, "-%.*s", p->n, p->z);
        if( pLeft->op==TK_FLOAT ){
          sqlite3VdbeOp3(v, OP_Real, 0, 0, z, p->n+1);

        }else{
          codeInteger(v, z, p->n+1);
        }
        sqlite3_free(z);
        break;
      }
      /* Fall through into TK_NOT */
    }
    case TK_BITNOT:
    case TK_NOT: {
      assert( TK_BITNOT==OP_BitNot );







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





|




>

|
>
>
>
>
>
|

<
>







 







|


|
>
>
>

<
<

|







 







<

<
>

|

<







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729

1730
1731
1732
1733
1734
1735
1736
1737
....
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813


1814
1815
1816
1817
1818
1819
1820
1821
1822
....
1910
1911
1912
1913
1914
1915
1916

1917

1918
1919
1920
1921

1922
1923
1924
1925
1926
1927
1928
**    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.314 2007/10/23 15:39:45 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Return the 'affinity' of the expression pExpr if any.
**
................................................................................
  if( testAddr ){
    sqlite3VdbeJumpHere(v, testAddr);
  }

  return;
}
#endif /* SQLITE_OMIT_SUBQUERY */

/*
** Duplicate an 8-byte value
*/
static char *dup8bytes(Vdbe *v, const char *in){
  char *out = sqlite3DbMallocRaw(sqlite3VdbeDb(v), 8);
  if( out ){
    memcpy(out, in, 8);
  }
  return out;
}

/*
** Generate an instruction that will put the floating point
** value described by z[0..n-1] on the stack.
*/
static void codeReal(Vdbe *v, const char *z, int n, int negateFlag){
  assert( z || v==0 || sqlite3VdbeDb(v)->mallocFailed );
  if( z ){
    double value;
    char *zV;
    sqlite3AtoF(z, &value);
    if( negateFlag ) value = -value;
    zV = dup8bytes(v, (char*)&value);
    sqlite3VdbeOp3(v, OP_Real, 0, 0, zV, P3_REAL);
  }
}


/*
** Generate an instruction that will put the integer describe by
** text z[0..n-1] on the stack.
*/
static void codeInteger(Vdbe *v, const char *z, int n, int negateFlag){
  assert( z || v==0 || sqlite3VdbeDb(v)->mallocFailed );
  if( z ){
    int i;
    if( sqlite3GetInt32(z, &i) ){
      if( negateFlag ) i = -i;
      sqlite3VdbeAddOp(v, OP_Integer, i, 0);
    }else if( sqlite3FitsIn64Bits(z, negateFlag) ){
      i64 value;
      char *zV;
      sqlite3Atoi64(z, &value);
      if( negateFlag ) value = -value;
      zV = dup8bytes(v, (char*)&value);
      sqlite3VdbeOp3(v, OP_Int64, 0, 0, zV, P3_INT64);
    }else{

      codeReal(v, z, n, negateFlag);
    }
  }
}


/*
** Generate code that will extract the iColumn-th column from
................................................................................
        sqlite3VdbeAddOp(v, OP_Dup, pParse->ckOffset-pExpr->iColumn-1, 1);
      }else{
        sqlite3ExprCodeGetColumn(v, pExpr->pTab, pExpr->iColumn, pExpr->iTable);
      }
      break;
    }
    case TK_INTEGER: {
      codeInteger(v, (char*)pExpr->token.z, pExpr->token.n, 0);
      break;
    }
    case TK_FLOAT: {
      codeReal(v, (char*)pExpr->token.z, pExpr->token.n, 0);
      break;
    }
    case TK_STRING: {


      sqlite3DequoteExpr(pParse->db, pExpr);
      sqlite3VdbeOp3(v,OP_String8, 0, 0, (char*)pExpr->token.z, pExpr->token.n);
      break;
    }
    case TK_NULL: {
      sqlite3VdbeAddOp(v, OP_Null, 0, 0);
      break;
    }
#ifndef SQLITE_OMIT_BLOB_LITERAL
................................................................................
      break;
    }
    case TK_UMINUS: {
      Expr *pLeft = pExpr->pLeft;
      assert( pLeft );
      if( pLeft->op==TK_FLOAT || pLeft->op==TK_INTEGER ){
        Token *p = &pLeft->token;

        if( pLeft->op==TK_FLOAT ){

          codeReal(v, (char*)p->z, p->n, 1);
        }else{
          codeInteger(v, (char*)p->z, p->n, 1);
        }

        break;
      }
      /* Fall through into TK_NOT */
    }
    case TK_BITNOT:
    case TK_NOT: {
      assert( TK_BITNOT==OP_BitNot );

Changes to src/sqliteInt.h.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
**    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.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.614 2007/10/04 18:11:16 danielk1977 Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
#include "sqliteLimit.h"

/*
** For testing purposes, the various size limit constants are really
................................................................................
int sqlite3FixSelect(DbFixer*, Select*);
int sqlite3FixExpr(DbFixer*, Expr*);
int sqlite3FixExprList(DbFixer*, ExprList*);
int sqlite3FixTriggerStep(DbFixer*, TriggerStep*);
int sqlite3AtoF(const char *z, double*);
char *sqlite3_snprintf(int,char*,const char*,...);
int sqlite3GetInt32(const char *, int*);
int sqlite3FitsIn64Bits(const char *);
int sqlite3Utf16ByteLen(const void *pData, int nChar);
int sqlite3Utf8CharLen(const char *pData, int nByte);
int sqlite3Utf8Read(const u8*, const u8*, const u8**);
int sqlite3PutVarint(unsigned char *, u64);
int sqlite3GetVarint(const unsigned char *, u64 *);
int sqlite3GetVarint32(const unsigned char *, u32 *);
int sqlite3VarintLen(u64 v);







|







 







|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
**    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.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.615 2007/10/23 15:39:45 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
#include "sqliteLimit.h"

/*
** For testing purposes, the various size limit constants are really
................................................................................
int sqlite3FixSelect(DbFixer*, Select*);
int sqlite3FixExpr(DbFixer*, Expr*);
int sqlite3FixExprList(DbFixer*, ExprList*);
int sqlite3FixTriggerStep(DbFixer*, TriggerStep*);
int sqlite3AtoF(const char *z, double*);
char *sqlite3_snprintf(int,char*,const char*,...);
int sqlite3GetInt32(const char *, int*);
int sqlite3FitsIn64Bits(const char *, int);
int sqlite3Utf16ByteLen(const void *pData, int nChar);
int sqlite3Utf8CharLen(const char *pData, int nByte);
int sqlite3Utf8Read(const u8*, const u8*, const u8**);
int sqlite3PutVarint(unsigned char *, u64);
int sqlite3GetVarint(const unsigned char *, u64 *);
int sqlite3GetVarint32(const unsigned char *, u32 *);
int sqlite3VarintLen(u64 v);

Changes to src/test1.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
....
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing all sorts of SQLite interfaces.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.278 2007/10/23 14:49:59 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>

/*
................................................................................
}

/*
** If zNum represents an integer that will fit in 64-bits, then set
** *pValue to that integer and return true.  Otherwise return false.
*/
static int sqlite3GetInt64(const char *zNum, i64 *pValue){
  if( sqlite3FitsIn64Bits(zNum) ){
    sqlite3Atoi64(zNum, pValue);
    return 1;
  }
  return 0;
}

/*







|







 







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
....
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing all sorts of SQLite interfaces.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.279 2007/10/23 15:39:45 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>

/*
................................................................................
}

/*
** If zNum represents an integer that will fit in 64-bits, then set
** *pValue to that integer and return true.  Otherwise return false.
*/
static int sqlite3GetInt64(const char *zNum, i64 *pValue){
  if( sqlite3FitsIn64Bits(zNum, 0) ){
    sqlite3Atoi64(zNum, pValue);
    return 1;
  }
  return 0;
}

/*

Changes to src/util.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387

388
389
390
391
392
393
394
**
*************************************************************************
** Utility functions used throughout sqlite.
**
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.212 2007/09/01 10:01:13 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
#include <ctype.h>


/*
................................................................................
** 64-bit signed integer, return TRUE.  Otherwise return FALSE.
**
** This routine returns FALSE for the string -9223372036854775808 even that
** that number will, in theory fit in a 64-bit integer.  Positive
** 9223373036854775808 will not fit in 64 bits.  So it seems safer to return
** false.
*/
int sqlite3FitsIn64Bits(const char *zNum){
  int i, c;
  int neg = 0;
  if( *zNum=='-' ){
    neg = 1;
    zNum++;
  }else if( *zNum=='+' ){
    zNum++;
  }

  while( *zNum=='0' ){
    zNum++;   /* Skip leading zeros.  Ticket #2454 */
  }
  for(i=0; (c=zNum[i])>='0' && c<='9'; i++){}
  if( i<19 ){
    /* Guaranteed to fit if less than 19 digits */
    return 1;







|







 







|








>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
**
*************************************************************************
** Utility functions used throughout sqlite.
**
** 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 $
*/
#include "sqliteInt.h"
#include <stdarg.h>
#include <ctype.h>


/*
................................................................................
** 64-bit signed integer, return TRUE.  Otherwise return FALSE.
**
** This routine returns FALSE for the string -9223372036854775808 even that
** that number will, in theory fit in a 64-bit integer.  Positive
** 9223373036854775808 will not fit in 64 bits.  So it seems safer to return
** false.
*/
int sqlite3FitsIn64Bits(const char *zNum, int negFlag){
  int i, c;
  int neg = 0;
  if( *zNum=='-' ){
    neg = 1;
    zNum++;
  }else if( *zNum=='+' ){
    zNum++;
  }
  if( negFlag ) neg = 1-neg;
  while( *zNum=='0' ){
    zNum++;   /* Skip leading zeros.  Ticket #2454 */
  }
  for(i=0; (c=zNum[i])>='0' && c<='9'; i++){}
  if( i<19 ){
    /* Guaranteed to fit if less than 19 digits */
    return 1;

Changes to src/vdbe.c.

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
...
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725

726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
**
** 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.652 2007/10/23 14:55:07 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
** The following global variable is incremented every time a cursor
................................................................................
  pTos->flags = MEM_Int;
  pTos->u.i = pOp->p1;
  break;
}

/* Opcode: Int64 * * P3
**
** P3 is a string representation of an integer.  Convert that integer
** to a 64-bit value and push it onto the stack.
*/
case OP_Int64: {
  pTos++;
  assert( pOp->p3!=0 );
  pTos->flags = MEM_Str|MEM_Static|MEM_Term;
  pTos->z = pOp->p3;
  pTos->n = strlen(pTos->z);
  pTos->enc = SQLITE_UTF8;
  pTos->u.i = sqlite3VdbeIntValue(pTos);
  pTos->flags |= MEM_Int;
  break;
}

/* Opcode: Real * * P3
**
** The string value P3 is converted to a real and pushed on to the stack.

*/
case OP_Real: {            /* same as TK_FLOAT, */
  pTos++;
  pTos->flags = MEM_Str|MEM_Static|MEM_Term;
  pTos->z = pOp->p3;
  pTos->n = strlen(pTos->z);
  pTos->enc = SQLITE_UTF8;
  pTos->r = sqlite3VdbeRealValue(pTos);
  pTos->flags |= MEM_Real;
  sqlite3VdbeChangeEncoding(pTos, encoding);
  break;
}

/* Opcode: String8 * * P3
**
** P3 points to a nul terminated UTF-8 string. This opcode is transformed 
** into an OP_String before it is executed for the first time.







|







 







|
|




|
|
<
<
<
<





|
>



|
|
<
<
<
<
<







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
...
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715




716
717
718
719
720
721
722
723
724
725
726
727





728
729
730
731
732
733
734
**
** 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.653 2007/10/23 15:39:45 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
** The following global variable is incremented every time a cursor
................................................................................
  pTos->flags = MEM_Int;
  pTos->u.i = pOp->p1;
  break;
}

/* Opcode: Int64 * * P3
**
** P3 is a pointer to a 64-bit integer value.
** Push  that value onto  the stack.
*/
case OP_Int64: {
  pTos++;
  assert( pOp->p3!=0 );
  pTos->flags = MEM_Int;
  memcpy(&pTos->u.i, pOp->p3, 8);




  break;
}

/* Opcode: Real * * P3
**
** P3 is a pointer to a 64-bit floating point value.  Push that value
** onto the stack.
*/
case OP_Real: {            /* same as TK_FLOAT, */
  pTos++;
  pTos->flags = MEM_Real;
  memcpy(&pTos->r, pOp->p3, 8);





  break;
}

/* Opcode: String8 * * P3
**
** P3 points to a nul terminated UTF-8 string. This opcode is transformed 
** into an OP_String before it is executed for the first time.

Changes to src/vdbe.h.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
..
68
69
70
71
72
73
74


75
76
77
78
79
80
81
*************************************************************************
** Header file for the Virtual DataBase Engine (VDBE)
**
** This header defines the interface to the virtual database engine
** or VDBE.  The VDBE implements an abstract machine that runs a
** simple program to access and modify the underlying database.
**
** $Id: vdbe.h,v 1.113 2007/08/30 01:19:59 drh Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
#include <stdio.h>

/*
** A single VDBE is an opaque structure named "Vdbe".  Only routines
................................................................................
#define P3_FUNCDEF  (-5)  /* P3 is a pointer to a FuncDef structure */
#define P3_KEYINFO  (-6)  /* P3 is a pointer to a KeyInfo structure */
#define P3_VDBEFUNC (-7)  /* P3 is a pointer to a VdbeFunc structure */
#define P3_MEM      (-8)  /* P3 is a pointer to a Mem*    structure */
#define P3_TRANSIENT (-9) /* P3 is a pointer to a transient string */
#define P3_VTAB     (-10) /* P3 is a pointer to an sqlite3_vtab structure */
#define P3_MPRINTF  (-11) /* P3 is a string obtained from sqlite3_mprintf() */



/* When adding a P3 argument using P3_KEYINFO, a copy of the KeyInfo structure
** is made.  That copy is freed when the Vdbe is finalized.  But if the
** argument is P3_KEYINFO_HANDOFF, the passed in pointer is used.  It still
** gets freed when the Vdbe is finalized so it still should be obtained
** from a single sqliteMalloc().  But no copy is made and the calling
** function should *not* try to free the KeyInfo.







|







 







>
>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
..
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
*************************************************************************
** Header file for the Virtual DataBase Engine (VDBE)
**
** This header defines the interface to the virtual database engine
** or VDBE.  The VDBE implements an abstract machine that runs a
** simple program to access and modify the underlying database.
**
** $Id: vdbe.h,v 1.114 2007/10/23 15:39:45 drh Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
#include <stdio.h>

/*
** A single VDBE is an opaque structure named "Vdbe".  Only routines
................................................................................
#define P3_FUNCDEF  (-5)  /* P3 is a pointer to a FuncDef structure */
#define P3_KEYINFO  (-6)  /* P3 is a pointer to a KeyInfo structure */
#define P3_VDBEFUNC (-7)  /* P3 is a pointer to a VdbeFunc structure */
#define P3_MEM      (-8)  /* P3 is a pointer to a Mem*    structure */
#define P3_TRANSIENT (-9) /* P3 is a pointer to a transient string */
#define P3_VTAB     (-10) /* P3 is a pointer to an sqlite3_vtab structure */
#define P3_MPRINTF  (-11) /* P3 is a string obtained from sqlite3_mprintf() */
#define P3_REAL     (-12) /* P3 is a 64-bit floating point value */
#define P3_INT64    (-13) /* P3 is a 64-bit signed integer */

/* When adding a P3 argument using P3_KEYINFO, a copy of the KeyInfo structure
** is made.  That copy is freed when the Vdbe is finalized.  But if the
** argument is P3_KEYINFO_HANDOFF, the passed in pointer is used.  It still
** gets freed when the Vdbe is finalized so it still should be obtained
** from a single sqliteMalloc().  But no copy is made and the calling
** function should *not* try to free the KeyInfo.

Changes to src/vdbeaux.c.

428
429
430
431
432
433
434



435
436
437
438
439
440
441
442
443
444
445
446
447
448
...
626
627
628
629
630
631
632










633
634
635
636
637
638
639

/*
** Delete a P3 value if necessary.
*/
static void freeP3(int p3type, void *p3){
  if( p3 ){
    switch( p3type ){



      case P3_DYNAMIC:
      case P3_KEYINFO:
      case P3_KEYINFO_HANDOFF: {
        sqlite3_free(p3);
        break;
      }
      case P3_MPRINTF: {
        sqlite3_free(p3);
        break;
      }
      case P3_VDBEFUNC: {
        VdbeFunc *pVdbeFunc = (VdbeFunc *)p3;
        freeEphemeralFunction(pVdbeFunc->pFunc);
        sqlite3VdbeDeleteAuxData(pVdbeFunc, 0);
................................................................................
      break;
    }
    case P3_FUNCDEF: {
      FuncDef *pDef = (FuncDef*)pOp->p3;
      sqlite3_snprintf(nTemp, zTemp, "%s(%d)", pDef->zName, pDef->nArg);
      zP3 = zTemp;
      break;










    }
#ifndef SQLITE_OMIT_VIRTUALTABLE
    case P3_VTAB: {
      sqlite3_vtab *pVtab = (sqlite3_vtab*)pOp->p3;
      sqlite3_snprintf(nTemp, zTemp, "vtab:%p:%p", pVtab, pVtab->pModule);
      zP3 = zTemp;
      break;







>
>
>



<
<
<
<







 







>
>
>
>
>
>
>
>
>
>







428
429
430
431
432
433
434
435
436
437
438
439
440




441
442
443
444
445
446
447
...
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648

/*
** Delete a P3 value if necessary.
*/
static void freeP3(int p3type, void *p3){
  if( p3 ){
    switch( p3type ){
      case P3_REAL:
      case P3_INT64:
      case P3_MPRINTF:
      case P3_DYNAMIC:
      case P3_KEYINFO:
      case P3_KEYINFO_HANDOFF: {




        sqlite3_free(p3);
        break;
      }
      case P3_VDBEFUNC: {
        VdbeFunc *pVdbeFunc = (VdbeFunc *)p3;
        freeEphemeralFunction(pVdbeFunc->pFunc);
        sqlite3VdbeDeleteAuxData(pVdbeFunc, 0);
................................................................................
      break;
    }
    case P3_FUNCDEF: {
      FuncDef *pDef = (FuncDef*)pOp->p3;
      sqlite3_snprintf(nTemp, zTemp, "%s(%d)", pDef->zName, pDef->nArg);
      zP3 = zTemp;
      break;
    }
    case P3_INT64: {
      sqlite3_snprintf(nTemp, zTemp, "%lld", *(sqlite3_int64*)pOp->p3);
      zP3 = zTemp;
      break;
    }
    case P3_REAL: {
      sqlite3_snprintf(nTemp, zTemp, "%.16g", *(double*)pOp->p3);
      zP3 = zTemp;
      break;
    }
#ifndef SQLITE_OMIT_VIRTUALTABLE
    case P3_VTAB: {
      sqlite3_vtab *pVtab = (sqlite3_vtab*)pOp->p3;
      sqlite3_snprintf(nTemp, zTemp, "vtab:%p:%p", pVtab, pVtab->pModule);
      zP3 = zTemp;
      break;

Changes to test/alter.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#*************************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is testing the ALTER TABLE statement.
#
# $Id: alter.test,v 1.26 2007/10/09 08:29:32 danielk1977 Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# If SQLITE_OMIT_ALTERTABLE is defined, omit this file.
ifcapable !altertable {
................................................................................
# that includes a COLLATE clause.
#
do_test alter-7.1 {
  execsql {
    CREATE TABLE t1(a TEXT COLLATE BINARY);
    ALTER TABLE t1 ADD COLUMN b INTEGER COLLATE NOCASE;
    INSERT INTO t1 VALUES(1,'-2');
    INSERT INTO t1 VALUES(5.4e-8,'5.4e-8');
    SELECT typeof(a), a, typeof(b), b FROM t1;
  }
} {text 1 integer -2 text 5.4e-8 real 5.4e-08}

# Make sure that when a column is added by ALTER TABLE ADD COLUMN and has
# a default value that the default value is used by aggregate functions.
#
do_test alter-8.1 {
  execsql {
    CREATE TABLE t2(a INTEGER);







|







 







|


|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#*************************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is testing the ALTER TABLE statement.
#
# $Id: alter.test,v 1.27 2007/10/23 15:39:46 drh Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# If SQLITE_OMIT_ALTERTABLE is defined, omit this file.
ifcapable !altertable {
................................................................................
# that includes a COLLATE clause.
#
do_test alter-7.1 {
  execsql {
    CREATE TABLE t1(a TEXT COLLATE BINARY);
    ALTER TABLE t1 ADD COLUMN b INTEGER COLLATE NOCASE;
    INSERT INTO t1 VALUES(1,'-2');
    INSERT INTO t1 VALUES(5.4e-08,'5.4e-08');
    SELECT typeof(a), a, typeof(b), b FROM t1;
  }
} {text 1 integer -2 text 5.4e-08 real 5.4e-08}

# Make sure that when a column is added by ALTER TABLE ADD COLUMN and has
# a default value that the default value is used by aggregate functions.
#
do_test alter-8.1 {
  execsql {
    CREATE TABLE t2(a INTEGER);