/ Check-in [ce8b1520]
Login

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

Overview
Comment:Ensure the type of an sqlite3_value* is not modified by calls to sqlite3_value_*() calls. (CVS 1463)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: ce8b15203413f38a8b7127eb08ae5db1c1eb164a
User & Date: danielk1977 2004-05-26 13:27:00
Context
2004-05-26
16:54
Remove dataType and includeTypes flags from function definitions. Added new P3_FUNCDEF type for P3 arguments on opcodes. Fixes to several user functions. 28 tests fail now. (CVS 1464) check-in: 36e03162 user: drh tags: trunk
13:27
Ensure the type of an sqlite3_value* is not modified by calls to sqlite3_value_*() calls. (CVS 1463) check-in: ce8b1520 user: danielk1977 tags: trunk
10:11
Add some tests for the new API. Many more to come. (CVS 1462) check-in: d5659f2e user: danielk1977 tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/test1.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
691
692
693
694
695
696
697
698
699
700
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
...
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the printf() interface to SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.57 2004/05/26 10:11:06 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include "os.h"
#include <stdlib.h>
#include <string.h>

................................................................................
  if( rc!=0 ){
    Tcl_AppendResult(interp, sqlite3_error_string(rc), 0);
    return TCL_ERROR;
  }
  return TCL_OK;
}

/*
** This SQLite callback records the datatype of all columns.
**
** The pArg argument is really a pointer to a TCL interpreter.  The
** column names are inserted as the result of this interpreter.
**
** This routine returns non-zero which causes the query to abort.
*/
static int rememberDataTypes(void *pArg, int nCol, char **argv, char **colv){
  int i;
  Tcl_Interp *interp = (Tcl_Interp*)pArg;
  Tcl_Obj *pList, *pElem;
  if( colv[nCol+1]==0 ){
    return 1;
  }
  pList = Tcl_NewObj();
  for(i=0; i<nCol; i++){
    pElem = Tcl_NewStringObj(colv[i+nCol] ? colv[i+nCol] : "NULL", -1);
    Tcl_ListObjAppendElement(interp, pList, pElem);
  }
  Tcl_SetObjResult(interp, pList);
  return 1;
}

/*
** Usage:  sqlite3_finalize  STMT 
**
** Finalize a statement handle.
*/
static int test_finalize(
  void * clientData,
................................................................................
        Tcl_GetStringFromObj(objv[0], 0), " <STMT>", 0);
    return TCL_ERROR;
  }

  if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;

  rc = sqlite3_finalize(pStmt);
  Tcl_SetResult(interp, errorName(rc), TCL_STATIC);
  if( rc ){
    return TCL_ERROR;
  }
  return TCL_OK;
}

/*







|







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
691
692
693
694
695
696
697
























698
699
700
701
702
703
704
...
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the printf() interface to SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.58 2004/05/26 13:27:00 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include "os.h"
#include <stdlib.h>
#include <string.h>

................................................................................
  if( rc!=0 ){
    Tcl_AppendResult(interp, sqlite3_error_string(rc), 0);
    return TCL_ERROR;
  }
  return TCL_OK;
}

























/*
** Usage:  sqlite3_finalize  STMT 
**
** Finalize a statement handle.
*/
static int test_finalize(
  void * clientData,
................................................................................
        Tcl_GetStringFromObj(objv[0], 0), " <STMT>", 0);
    return TCL_ERROR;
  }

  if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;

  rc = sqlite3_finalize(pStmt);
  Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC);
  if( rc ){
    return TCL_ERROR;
  }
  return TCL_OK;
}

/*

Changes to src/vdbe.c.

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
..
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
...
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
...
234
235
236
237
238
239
240












241
242
243
244
245
246
247
248
249
250
251
252
253
254
...
373
374
375
376
377
378
379
380


381
382
383
384
385
386
387
...
571
572
573
574
575
576
577


578
579
580
581
582
583
584
585
586
587
588
589
590







591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
...
637
638
639
640
641
642
643
644
645
646
647
648
649



















650
651
652
653
654
655
656
...
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
...
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
....
1768
1769
1770
1771
1772
1773
1774










1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
....
2023
2024
2025
2026
2027
2028
2029

2030
2031
2032
2033
2034
2035
2036
....
2273
2274
2275
2276
2277
2278
2279

2280
2281
2282
2283
2284
2285
2286
....
5620
5621
5622
5623
5624
5625
5626
5627
5628

5629
5630
5631
5632
5633
5634
5635
**
** 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.333 2004/05/26 10:11:06 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
................................................................................
** MemIsBlob     # Blobs.
**
** These macros do not alter the contents of the Mem structure.
*/
#define MemIsNull(p) ((p)->flags&Mem_Null)
#define MemIsBlob(p) ((p)->flags&Mem_Blob)
#define MemIsStr(p) ((p)->flags&(MEM_Int|MEM_Real|MEM_Str))
#define MemIsInt(p) ((p)->flags&MEM_Int || hardMemIsInt(p))
#define MemIsReal(p) ((p)->flags&(MEM_Int|MEM_Real) || hardMemIsReal(p))
static int hardMemIsInt(Mem *p){
  assert( !(p->flags&(MEM_Int|MEM_Real)) );
  if( p->flags&MEM_Str ){
    int realnum = 0;
    if( sqlite3IsNumber(p->z, &realnum, MemEnc(p)) && !realnum ){
      return 1;
................................................................................
** MemInt
** MemReal
**
** These macros do not alter the contents of the Mem structure, although
** they may cache the integer or real value cast of the value.
*/
#define MemInt(p) (((p)->flags&MEM_Int)?(p)->i:hardMemInt(p))
#define MemReal(p) (((p)->flags&MEM_Real)?(p)->i:hardMemReal(p))
static i64 hardMemInt(Mem *p){
  assert( !(p->flags&MEM_Int) );
  if( !MemIsInt(p) ) return 0;

  if( p->flags&MEM_Real ){
    p->i = p->r;
  }else{
................................................................................
** Set the encoding flags of memory cell "pMem" to the correct values
** for the database encoding "enc" (one of TEXT_Utf8, TEXT_Utf16le or
** TEXT_Utf16be).
*/
#define SetEncodingFlags(pMem, enc) ((pMem)->flags = \
((pMem->flags & ~(MEM_Utf8|MEM_Utf16le|MEM_Utf16be))) | encToFlags(enc))
static int SetEncoding(Mem*, int);













/*
** Convert the given stack entity into a string if it isn't one
** already. Return non-zero if a malloc() fails.
*/
#define Stringify(P, enc) \
(!((P)->flags&(MEM_Str|MEM_Blob)) && hardStringify(P, enc))
static int hardStringify(Mem *pStack, u8 enc){
  int rc = SQLITE_OK;
  int fg = pStack->flags;

  assert( !(fg&(MEM_Str|MEM_Blob)) );
  assert( fg&(MEM_Int|MEM_Real|MEM_Null) );

................................................................................
  
      /* Result of sqlite3utfTranslate is currently always dynamically
      ** allocated and nul terminated. This might be altered as a performance
      ** enhancement later.
      */
      pMem->z = z;
      pMem->n = n;
      pMem->flags = (MEM_Str | MEM_Dyn | MEM_Term | flags);


    }else{
      /* Must be translating between UTF-16le and UTF-16be. */
      int i;
      if( pMem->flags&MEM_Static ){
        Dynamicify(pMem, enc1);
      }
      for(i=0; i<pMem->n; i+=2){
................................................................................
** correctly when this function is called. If a translation occurs,
** the flags are set to reflect the new encoding of the string.
**
** If a translation fails because of a malloc() failure, a NULL pointer
** is returned.
*/
const unsigned char *sqlite3_value_data(sqlite3_value *pVal){


  if( pVal->flags&MEM_Null ){
    /* For a NULL return a NULL Pointer */
    return 0;
  }

  if( pVal->flags&MEM_Str ){
    /* If there is already a string representation, make sure it is in
    ** encoded in UTF-8.
    */
    SetEncoding(pVal, MEM_Utf8|MEM_Term);
  }else if( !(pVal->flags&MEM_Blob) ){
    /* Otherwise, unless this is a blob, convert it to a UTF-8 string */
    Stringify(pVal, TEXT_Utf8);







  }

  return pVal->z;
}

/*
** Return the value of the 'i'th column of the current row of the currently
** executing statement pStmt.
*/
const void *sqlite3_column_data16(sqlite3_stmt *pStmt, int i){
  int vals;
  Vdbe *pVm = (Vdbe *)pStmt;
  Mem *pVal;

  vals = sqlite3_data_count(pStmt);
  if( i>=vals || i<0 ){
    sqlite3Error(pVm->db, SQLITE_RANGE, 0);
    return 0;
  }

  pVal = &pVm->pTos[(1-vals)+i];
  return sqlite3_value_data16((sqlite3_value *)pVal);
}

/*
** pVal is a Mem* cast to an sqlite_value* value. Return a pointer to
** the nul terminated UTF-16 string representation if the value is 
** not a blob or NULL. If the value is a blob, then just return a pointer
** to the blob of data. If it is a NULL, return a NULL pointer.
**
** The byte-order of the returned string data is the machines native byte
................................................................................

  if( pVal->flags&MEM_Str ){
    /* If there is already a string representation, make sure it is in
    ** encoded in UTF-16 machine byte order.
    */
    SetEncoding(pVal, encToFlags(TEXT_Utf16)|MEM_Term);
  }else if( !(pVal->flags&MEM_Blob) ){
    /* Otherwise, unless this is a blob, convert it to a UTF-16 string */
    Stringify(pVal, TEXT_Utf16);
  }

  return (const void *)(pVal->z);
}




















/*
** Return the number of bytes of data that will be returned by the
** equivalent sqlite3_value_data() call.
*/
int sqlite3_value_bytes(sqlite3_value *pVal){
  if( sqlite3_value_data(pVal) ){
................................................................................

/*
** Return the value of the sqlite_value* argument coerced to a 64-bit
** integer.
*/
long long int sqlite3_value_int(sqlite3_value *pVal){
  Mem *pMem = (Mem *)pVal;
  Integerify(pMem, flagsToEnc(pMem->flags));
  return pVal->i;
}

/*
** Return the value of the sqlite_value* argument coerced to a 64-bit
** IEEE float.
*/
double sqlite3_value_float(sqlite3_value *pVal){
  Mem *pMem = (Mem *)pVal;
  Realify(pMem, flagsToEnc(pMem->flags));
  return pMem->r;
}

/*
** Return the number of bytes of data that will be returned by the
** equivalent sqlite3_column_data() call.
*/
int sqlite3_column_bytes(sqlite3_stmt *pStmt, int i){
................................................................................
** Return the type of the value stored in the sqlite_value* object.
*/
int sqlite3_value_type(sqlite3_value* pVal){
  int f = ((Mem *)pVal)->flags;
  if( f&MEM_Null ){
    return SQLITE3_NULL;
  }
  if( f&MEM_Int ){
    return SQLITE3_INTEGER;
  }
  if( f&MEM_Real ){
    return SQLITE3_FLOAT;
  }
  if( f&MEM_Str ){
    return SQLITE3_TEXT;
  }
  if( f&MEM_Blob ){
    return SQLITE3_BLOB;
  }
  assert(0);
}
................................................................................
case OP_String: {
  char *z = pOp->p3;
  u8 op = pOp->opcode;

  pTos++;
  pTos->flags = 0;
 










  /* If this is an OP_Real or OP_Integer opcode, set the pTos->r or pTos->i
  ** values respectively.
  */
  if( op==OP_Real ){
    assert( z );
    assert( sqlite3IsNumber(z, 0, TEXT_Utf8) );
    pTos->r = sqlite3AtoF(z, 0);
    pTos->flags = MEM_Real;
  }else if( op==OP_Integer ){
    pTos->flags = MEM_Int;
    pTos->i = pOp->p1;
    if( pTos->i==0 && pOp->p3 ){
      sqlite3GetInt64(pOp->p3, &pTos->i);
    }
  }

  if( z ){
    /* FIX ME: For now the code in expr.c always puts UTF-8 in P3. It
    ** should transform text to the native encoding before doing so.
    */
    if( db->enc!=TEXT_Utf8 ){
      rc = sqlite3utfTranslate(z, -1, TEXT_Utf8, (void **)&pTos->z, 
          &pTos->n, db->enc);
      if( rc!=SQLITE_OK ){
        assert( !pTos->z );
        goto abort_due_to_error;
      }
      pTos->flags |= MEM_Str | MEM_Dyn | MEM_Term;
    }else{
      pTos->z = z;
      pTos->n = strlen(z) + 1;
      pTos->flags |= MEM_Str | MEM_Static | MEM_Term;
    }
  }else if( op==OP_String ){
    pTos->flags = MEM_Null;
  }

  break;
}

/* Opcode: Variable P1 * *
**
................................................................................
  int i;
  assert( p->nResColumn==pOp->p1 );

  for(i=0; i<pOp->p1; i++){
    Mem *pVal = &pTos[0-i];
    SetEncodingFlags(pVal, db->enc);
    MemNulTerminate(pVal);

  }

  p->resOnStack = 1;
  p->nCallback++;
  p->popStack = pOp->p1;
  p->pc = pc + 1;
  p->pTos = pTos;
................................................................................
  n = pOp->p1;
  apVal = p->apArg;
  assert( apVal || n==0 );

  pArg = &pTos[1-n];
  for(i=0; i<n; i++, pArg++){
    SetEncodingFlags(pArg, db->enc);

    apVal[i] = pArg;
  }

  ctx.pFunc = (FuncDef*)pOp->p3;
  ctx.s.flags = MEM_Null;
  ctx.s.z = 0;
  ctx.isError = 0;
................................................................................
  pRec = &pTos[-n];
  assert( pRec>=p->aStack );

  apVal = p->apArg;
  assert( apVal || n==0 );

  for(i=0; i<n; i++, pRec++){
      apVal[i] = pRec;
      SetEncodingFlags(pRec, db->enc);

  }
  i = pTos->i;
  assert( i>=0 && i<p->agg.nMem );
  ctx.pFunc = (FuncDef*)pOp->p3;
  pMem = &p->agg.pCurrent->aMem[i];
  ctx.s.z = pMem->zShort;  /* Space used for small aggregate contexts */
  ctx.pAgg = pMem->z;







|







 







|







 







|







 







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






|







 







|
>
>







 







>
>
|




|




|
|
|
>
>
>
>
>
>
>





<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







|
|




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







 







<
|








<
|







 







|


|


|







 







>
>
>
>
>
>
>
>
>
>







|

<


|

<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<







 







>







 







>







 







|
|
>







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
..
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
...
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
...
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
...
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
...
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618



















619
620
621
622
623
624
625
...
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
...
695
696
697
698
699
700
701

702
703
704
705
706
707
708
709
710

711
712
713
714
715
716
717
718
...
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
....
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814

1815
1816
1817
1818













1819







1820
1821
1822
1823
1824
1825
1826
....
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
....
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
....
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
**
** 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.334 2004/05/26 13:27:00 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
................................................................................
** MemIsBlob     # Blobs.
**
** These macros do not alter the contents of the Mem structure.
*/
#define MemIsNull(p) ((p)->flags&Mem_Null)
#define MemIsBlob(p) ((p)->flags&Mem_Blob)
#define MemIsStr(p) ((p)->flags&(MEM_Int|MEM_Real|MEM_Str))
#define MemIsInt(p) ((p)->flags&(MEM_Int|MEM_Real) || hardMemIsInt(p))
#define MemIsReal(p) ((p)->flags&(MEM_Int|MEM_Real) || hardMemIsReal(p))
static int hardMemIsInt(Mem *p){
  assert( !(p->flags&(MEM_Int|MEM_Real)) );
  if( p->flags&MEM_Str ){
    int realnum = 0;
    if( sqlite3IsNumber(p->z, &realnum, MemEnc(p)) && !realnum ){
      return 1;
................................................................................
** MemInt
** MemReal
**
** These macros do not alter the contents of the Mem structure, although
** they may cache the integer or real value cast of the value.
*/
#define MemInt(p) (((p)->flags&MEM_Int)?(p)->i:hardMemInt(p))
#define MemReal(p) (((p)->flags&MEM_Real)?(p)->r:hardMemReal(p))
static i64 hardMemInt(Mem *p){
  assert( !(p->flags&MEM_Int) );
  if( !MemIsInt(p) ) return 0;

  if( p->flags&MEM_Real ){
    p->i = p->r;
  }else{
................................................................................
** Set the encoding flags of memory cell "pMem" to the correct values
** for the database encoding "enc" (one of TEXT_Utf8, TEXT_Utf16le or
** TEXT_Utf16be).
*/
#define SetEncodingFlags(pMem, enc) ((pMem)->flags = \
((pMem->flags & ~(MEM_Utf8|MEM_Utf16le|MEM_Utf16be))) | encToFlags(enc))
static int SetEncoding(Mem*, int);

/*
** Set the MEM_TypeStr, MEM_TypeReal or MEM_TypeInt flags in pMem if
** required.
*/
static void MemSetTypeFlags(Mem *pMem){
  int f = pMem->flags;
  if( f&MEM_Int ) pMem->flags |= MEM_TypeInt;
  else if( f&MEM_Real ) pMem->flags |= MEM_TypeReal;
  else if( f&MEM_Str ) pMem->flags |= MEM_TypeStr;
}


/*
** Convert the given stack entity into a string if it isn't one
** already. Return non-zero if a malloc() fails.
*/
#define Stringify(P, enc) \
if( !((P)->flags&(MEM_Str|MEM_Blob)) ) hardStringify(P, enc);
static int hardStringify(Mem *pStack, u8 enc){
  int rc = SQLITE_OK;
  int fg = pStack->flags;

  assert( !(fg&(MEM_Str|MEM_Blob)) );
  assert( fg&(MEM_Int|MEM_Real|MEM_Null) );

................................................................................
  
      /* Result of sqlite3utfTranslate is currently always dynamically
      ** allocated and nul terminated. This might be altered as a performance
      ** enhancement later.
      */
      pMem->z = z;
      pMem->n = n;
      pMem->flags &= ~(MEM_Utf8|MEM_Utf16le|MEM_Utf16be);
      pMem->flags &= ~(MEM_Static|MEM_Short|MEM_Ephem);
      pMem->flags |= (MEM_Dyn|MEM_Term|flags);
    }else{
      /* Must be translating between UTF-16le and UTF-16be. */
      int i;
      if( pMem->flags&MEM_Static ){
        Dynamicify(pMem, enc1);
      }
      for(i=0; i<pMem->n; i+=2){
................................................................................
** correctly when this function is called. If a translation occurs,
** the flags are set to reflect the new encoding of the string.
**
** If a translation fails because of a malloc() failure, a NULL pointer
** is returned.
*/
const unsigned char *sqlite3_value_data(sqlite3_value *pVal){
  int flags = pVal->flags;

  if( flags&MEM_Null ){
    /* For a NULL return a NULL Pointer */
    return 0;
  }

  if( flags&MEM_Str ){
    /* If there is already a string representation, make sure it is in
    ** encoded in UTF-8.
    */
    SetEncoding(pVal, MEM_Utf8|MEM_Term);
  }else if( !(flags&MEM_Blob) ){
    if( flags&MEM_Int ){
      sqlite3_snprintf(NBFS, pVal->zShort, "%lld", pVal->i);
    }else{
      assert( flags&MEM_Real );
      sqlite3_snprintf(NBFS, pVal->zShort, "%.15g", pVal->r);
    }
    pVal->z = pVal->zShort;
    pVal->n = strlen(pVal->z)+1;
    pVal->flags |= (MEM_Str|MEM_Short);
  }

  return pVal->z;
}




















/*
** pVal is a Mem* cast to an sqlite_value* value. Return a pointer to
** the nul terminated UTF-16 string representation if the value is 
** not a blob or NULL. If the value is a blob, then just return a pointer
** to the blob of data. If it is a NULL, return a NULL pointer.
**
** The byte-order of the returned string data is the machines native byte
................................................................................

  if( pVal->flags&MEM_Str ){
    /* If there is already a string representation, make sure it is in
    ** encoded in UTF-16 machine byte order.
    */
    SetEncoding(pVal, encToFlags(TEXT_Utf16)|MEM_Term);
  }else if( !(pVal->flags&MEM_Blob) ){
    sqlite3_value_data(pVal);
    SetEncoding(pVal, encToFlags(TEXT_Utf16)|MEM_Term);
  }

  return (const void *)(pVal->z);
}

/*
** Return the value of the 'i'th column of the current row of the currently
** executing statement pStmt.
*/
const void *sqlite3_column_data16(sqlite3_stmt *pStmt, int i){
  int vals;
  Vdbe *pVm = (Vdbe *)pStmt;
  Mem *pVal;

  vals = sqlite3_data_count(pStmt);
  if( i>=vals || i<0 ){
    sqlite3Error(pVm->db, SQLITE_RANGE, 0);
    return 0;
  }

  pVal = &pVm->pTos[(1-vals)+i];
  return sqlite3_value_data16((sqlite3_value *)pVal);
}

/*
** Return the number of bytes of data that will be returned by the
** equivalent sqlite3_value_data() call.
*/
int sqlite3_value_bytes(sqlite3_value *pVal){
  if( sqlite3_value_data(pVal) ){
................................................................................

/*
** Return the value of the sqlite_value* argument coerced to a 64-bit
** integer.
*/
long long int sqlite3_value_int(sqlite3_value *pVal){
  Mem *pMem = (Mem *)pVal;

  return MemInt(pMem);
}

/*
** Return the value of the sqlite_value* argument coerced to a 64-bit
** IEEE float.
*/
double sqlite3_value_float(sqlite3_value *pVal){
  Mem *pMem = (Mem *)pVal;

  return MemReal(pMem);
}

/*
** Return the number of bytes of data that will be returned by the
** equivalent sqlite3_column_data() call.
*/
int sqlite3_column_bytes(sqlite3_stmt *pStmt, int i){
................................................................................
** Return the type of the value stored in the sqlite_value* object.
*/
int sqlite3_value_type(sqlite3_value* pVal){
  int f = ((Mem *)pVal)->flags;
  if( f&MEM_Null ){
    return SQLITE3_NULL;
  }
  if( f&MEM_TypeInt ){
    return SQLITE3_INTEGER;
  }
  if( f&MEM_TypeReal ){
    return SQLITE3_FLOAT;
  }
  if( f&MEM_TypeStr ){
    return SQLITE3_TEXT;
  }
  if( f&MEM_Blob ){
    return SQLITE3_BLOB;
  }
  assert(0);
}
................................................................................
case OP_String: {
  char *z = pOp->p3;
  u8 op = pOp->opcode;

  pTos++;
  pTos->flags = 0;
 
  if( z ){
    /* FIX ME: For now the code in expr.c always puts UTF-8 in P3. It
    ** should transform text to the native encoding before doing so.
    */
    MemSetStr(pTos, z, -1, TEXT_Utf8, 0);
    SetEncoding(pTos, encToFlags(db->enc)|MEM_Term);
  }else if( op==OP_String ){
    pTos->flags = MEM_Null;
  }

  /* If this is an OP_Real or OP_Integer opcode, set the pTos->r or pTos->i
  ** values respectively.
  */
  if( op==OP_Real ){
    assert( z );
    assert( sqlite3IsNumber(z, 0, TEXT_Utf8) );
    pTos->r = sqlite3AtoF(z, 0);
    pTos->flags |= MEM_Real;
  }else if( op==OP_Integer ){

    pTos->i = pOp->p1;
    if( pTos->i==0 && pOp->p3 ){
      sqlite3GetInt64(z, &pTos->i);
    }













    pTos->flags |= MEM_Int;







  }

  break;
}

/* Opcode: Variable P1 * *
**
................................................................................
  int i;
  assert( p->nResColumn==pOp->p1 );

  for(i=0; i<pOp->p1; i++){
    Mem *pVal = &pTos[0-i];
    SetEncodingFlags(pVal, db->enc);
    MemNulTerminate(pVal);
    MemSetTypeFlags(pVal);
  }

  p->resOnStack = 1;
  p->nCallback++;
  p->popStack = pOp->p1;
  p->pc = pc + 1;
  p->pTos = pTos;
................................................................................
  n = pOp->p1;
  apVal = p->apArg;
  assert( apVal || n==0 );

  pArg = &pTos[1-n];
  for(i=0; i<n; i++, pArg++){
    SetEncodingFlags(pArg, db->enc);
    MemSetTypeFlags(pArg);
    apVal[i] = pArg;
  }

  ctx.pFunc = (FuncDef*)pOp->p3;
  ctx.s.flags = MEM_Null;
  ctx.s.z = 0;
  ctx.isError = 0;
................................................................................
  pRec = &pTos[-n];
  assert( pRec>=p->aStack );

  apVal = p->apArg;
  assert( apVal || n==0 );

  for(i=0; i<n; i++, pRec++){
    apVal[i] = pRec;
    SetEncodingFlags(pRec, db->enc);
    MemSetTypeFlags(pRec);
  }
  i = pTos->i;
  assert( i>=0 && i<p->agg.nMem );
  ctx.pFunc = (FuncDef*)pOp->p3;
  pMem = &p->agg.pCurrent->aMem[i];
  ctx.s.z = pMem->zShort;  /* Space used for small aggregate contexts */
  ctx.pAgg = pMem->z;

Changes to src/vdbeInt.h.

140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
...
155
156
157
158
159
160
161
162
163
164
165
166
167
168


169
170
171


172


173
174

175
176
177
178
179
180
181
182
183
184
185
186


















187
188
189
190
191
192
193
194
195
196
197
...
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
/*
** The following three macros are used to set the value and manifest type
** stored by a Mem structure.
**
** MemSetNull - Set the value to NULL.
** MemSetInt  - Set the value to an integer.
** MemSetReal - Set the value to a real.
** MemSetStr - Set the value to a string.
*/
#define MemSetNull(p) sqlite3VdbeMemSetNull(p)
#define MemSetInt(p,v) sqlite3VdbeMemSetInt(p,v)
#define MemSetReal(p,v) sqlite3VdbeMemSetReal(p,v)
#define MemSetStr(p,z,n,enc,eCopy) sqlite3VdbeMemSetStr(p,z,n,enc,eCopy)

/*
................................................................................
** This macro is used to ensure a string stored in a Mem struct is NULL
** terminated. When used on an object that is not a string or is a nul
** terminated string this is a no-op. When used on a non-nul-terminated
** string a nul terminator character is appended.
**
** Non-zero is returned if a malloc() fails.
*/
#define MemNulTerminate(p) ( \
  ((p)->flags&MEM_Str) && \
  !((p)->flags&MEM_Term) && \
  sqlite3VdbeMemNulTerminate(p) )

/*
** Allowed values for Mem.flags.


**
** The first 5 values determine the data type(s).  Null and Blob must
** occur alone.  But Str, Int, and Real can occur together.


**


** The next 3 utf entries determine the text representation for strings.
** These values are only meaningful if the type is Str.

**
** The last 4 values specify what kind of memory Mem.z points to.
** These valus are only meaningful if the Str or Blob types are used.
*/
#define MEM_Null      0x0001   /* Value is NULL */
#define MEM_Str       0x0002   /* Value is a string */
#define MEM_Int       0x0004   /* Value is an integer */
#define MEM_Real      0x0008   /* Value is a real number */
#define MEM_Blob      0x0010   /* Value is a BLOB */

#define MEM_Term      0x0200   /* String has a nul terminator character */



















#define MEM_Dyn       0x0400   /* Need to call sqliteFree() on Mem.z */
#define MEM_Static    0x0800   /* Mem.z points to a static string */
#define MEM_Ephem     0x1000   /* Mem.z points to an ephemeral string */
#define MEM_Short     0x2000   /* Mem.z points to Mem.zShort */

/* Internally, all strings manipulated by the  VDBE are encoded using the
** native encoding for the main database. Therefore the following three
** flags, which describe the text encoding of the string if the MEM_Str
** flag is true, are not generally valid for Mem* objects handled by the
** VDBE.
**
................................................................................
** is ready for processing by the caller, the data values are stored
** internally as Mem* objects. Before sqlite3_step() returns, the MEM_Utf*
** flags are set correctly for the database encoding. A translation may
** take place if the user requests a non-native encoding via
** sqlite3_column_data() or sqlite3_column_data16(). If this occurs, then
** the MEM_Utf* flags are updated accordingly.
*/
#define MEM_Utf8      0x0040   /* String uses UTF-8 encoding */
#define MEM_Utf16be   0x0080   /* String uses UTF-16 big-endian */
#define MEM_Utf16le   0x0100   /* String uses UTF-16 little-endian */

/* The following MEM_ value appears only in AggElem.aMem.s.flag fields.
** It indicates that the corresponding AggElem.aMem.z points to a
** aggregate function context that needs to be finalized.
*/
#define MEM_AggCtx    0x4000   /* Mem.z points to an agg function context */

/*
** The "context" argument for a installable function.  A pointer to an
** instance of this structure is the first argument to the routines used
** implement the SQL functions.
**
** There is a typedef for this structure in sqlite.h.  So all routines,







|







 







|
<
<
|

<
<
>
>

<
<
>
>

>
>
|
|
>
|
<
<







|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|







 







|
|
|





|







140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
...
155
156
157
158
159
160
161
162


163
164


165
166
167


168
169
170
171
172
173
174
175
176


177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
...
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
/*
** The following three macros are used to set the value and manifest type
** stored by a Mem structure.
**
** MemSetNull - Set the value to NULL.
** MemSetInt  - Set the value to an integer.
** MemSetReal - Set the value to a real.
** MemSetStr - Set the value to a string (or blob if enc==0).
*/
#define MemSetNull(p) sqlite3VdbeMemSetNull(p)
#define MemSetInt(p,v) sqlite3VdbeMemSetInt(p,v)
#define MemSetReal(p,v) sqlite3VdbeMemSetReal(p,v)
#define MemSetStr(p,z,n,enc,eCopy) sqlite3VdbeMemSetStr(p,z,n,enc,eCopy)

/*
................................................................................
** This macro is used to ensure a string stored in a Mem struct is NULL
** terminated. When used on an object that is not a string or is a nul
** terminated string this is a no-op. When used on a non-nul-terminated
** string a nul terminator character is appended.
**
** Non-zero is returned if a malloc() fails.
*/
#define MemNulTerminate(p) \


if( ((p)->flags&MEM_Str) && !((p)->flags&MEM_Term) ) sqlite3VdbeMemNulTerminate(p);



/* One or more of the following flags are set to indicate the valid
** representations of the value stored in the Mem struct.
**


** If the MEM_Null flag is set, then the value is an SQL NULL value.
** No other flags may be set in this case.
**
** If the MEM_Str flag is set then Mem.z points at a string representation.
** Usually this is encoded in the same unicode encoding as the main
** database (see below for exceptions). If the MEM_Term flag is also
** set, then the string is nul terminated. The MEM_Int and MEM_Real 
** flags may coexist with the MEM_Str flag.
** 


*/
#define MEM_Null      0x0001   /* Value is NULL */
#define MEM_Str       0x0002   /* Value is a string */
#define MEM_Int       0x0004   /* Value is an integer */
#define MEM_Real      0x0008   /* Value is a real number */
#define MEM_Blob      0x0010   /* Value is a BLOB */

#define MEM_Term       0x0100   /* String rep is nul terminated */

/* Values with type NULL or BLOB can have only one representation. But
** values with a manifest type of REAL, INTEGER or STRING may have one
** or more representation cached in the Mem struct at any one time. The
** flags MEM_IntVal, MEM_RealVal and MEM_StrVal are true whenever the real,
** integer or string representation stored in a Mem struct is valid.
**
** When MEM_StrVal is set, then MEM_Term may also be set. This indicates
** that the string is terminated with a nul-terminator character.
*/
#define MEM_TypeInt    0x0020   /* Value type is an integer */
#define MEM_TypeReal   0x0040   /* Value type is real */
#define MEM_TypeStr    0x0080   /* Value type is string */


/* Whenever Mem contains a valid string or blob representation, one of
** the following flags must be set to determine the memory management
** policy for Mem.z
*/
#define MEM_Dyn       0x0200   /* Need to call sqliteFree() on Mem.z */
#define MEM_Static    0x0400   /* Mem.z points to a static string */
#define MEM_Ephem     0x0800   /* Mem.z points to an ephemeral string */
#define MEM_Short     0x1000   /* Mem.z points to Mem.zShort */

/* Internally, all strings manipulated by the  VDBE are encoded using the
** native encoding for the main database. Therefore the following three
** flags, which describe the text encoding of the string if the MEM_Str
** flag is true, are not generally valid for Mem* objects handled by the
** VDBE.
**
................................................................................
** is ready for processing by the caller, the data values are stored
** internally as Mem* objects. Before sqlite3_step() returns, the MEM_Utf*
** flags are set correctly for the database encoding. A translation may
** take place if the user requests a non-native encoding via
** sqlite3_column_data() or sqlite3_column_data16(). If this occurs, then
** the MEM_Utf* flags are updated accordingly.
*/
#define MEM_Utf8      0x2000   /* String uses UTF-8 encoding */
#define MEM_Utf16be   0x4000   /* String uses UTF-16 big-endian */
#define MEM_Utf16le   0x8000   /* String uses UTF-16 little-endian */

/* The following MEM_ value appears only in AggElem.aMem.s.flag fields.
** It indicates that the corresponding AggElem.aMem.z points to a
** aggregate function context that needs to be finalized.
*/
#define MEM_AggCtx    0x10000  /* Mem.z points to an agg function context */

/*
** The "context" argument for a installable function.  A pointer to an
** instance of this structure is the first argument to the routines used
** implement the SQL functions.
**
** There is a typedef for this structure in sqlite.h.  So all routines,

Changes to test/capi3.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
...
204
205
206
207
208
209
210

211
212
213
214
215
216
217
218
219
220
221

222
223
224
225
226
227
228
...
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
#    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 testing the callback-free C/C++ API.
#
# $Id: capi3.test,v 1.4 2004/05/26 10:11:07 danielk1977 Exp $
#

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

# Return the UTF-16 representation of the supplied UTF-8 string $str.
# If $nt is true, append two 0x00 bytes as a nul terminator.
................................................................................
# row of data.
#

do_test capi3-5.0 {
  execsql {
    CREATE TABLE t1(a VARINT, b BLOB, c VARCHAR(16));
    INSERT INTO t1 VALUES(1, 2, 3);
    INSERT INTO t1 VALUES('one', 'two', 'three');
  }
  set sql "SELECT * FROM t1"
  set STMT [sqlite3_prepare $DB $sql -1 TAIL]

  sqlite3_column_count $STMT
} 3

................................................................................

do_test capi3-5.4 {
  set types [list]
  foreach i {0 1 2} {lappend types [sqlite3_column_type $STMT $i]}
  set types
} {INTEGER INTEGER TEXT}


do_test capi3-5.5 {
  set ints [list]
  foreach i {0 1 2} {lappend ints [sqlite3_column_int $STMT $i]}
  set ints
} {1 2 3}

do_test capi3-5.6 {
  set utf8 [list]
  foreach i {0 1 2} {lappend utf8 [sqlite3_column_data $STMT $i]}
  set utf8
} {1 2 3}


do_test capi3-5.7 {
  set utf8 [list]
  foreach i {0 1 2} {lappend utf8 [utf8 [sqlite3_column_data16 $STMT $i]]}
  set utf8
} {1 2 3}

................................................................................
  sqlite3_step $STMT
} SQLITE_ROW

do_test capi3-5.10 {
  set types [list]
  foreach i {0 1 2} {lappend types [sqlite3_column_type $STMT $i]}
  set types
} {TEXT TEXT TEXT}

do_test capi3-5.11 {
  set ints [list]
  foreach i {0 1 2} {lappend ints [sqlite3_column_int $STMT $i]}
  set ints
} {0 0 0}

do_test capi3-5.12 {
  set utf8 [list]
  foreach i {0 1 2} {lappend utf8 [sqlite3_column_data $STMT $i]}
  set utf8
} {one two three}

do_test capi3-5.13 {
  set utf8 [list]
  foreach i {0 1 2} {lappend utf8 [utf8 [sqlite3_column_data16 $STMT $i]]}
  set utf8
} {one two three}

do_test capi3-5.14 {
  set types [list]
  foreach i {0 1 2} {lappend types [sqlite3_column_type $STMT $i]}
  set types
} {TEXT TEXT TEXT}

do_test capi3-5.15 {
  sqlite3_step $STMT
} SQLITE_DONE

do_test capi3-5.99 {
  sqlite3_finalize $STMT







|







 







|







 







>











>







 







|











|





|





|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
...
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
...
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
#    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 testing the callback-free C/C++ API.
#
# $Id: capi3.test,v 1.5 2004/05/26 13:27:00 danielk1977 Exp $
#

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

# Return the UTF-16 representation of the supplied UTF-8 string $str.
# If $nt is true, append two 0x00 bytes as a nul terminator.
................................................................................
# row of data.
#

do_test capi3-5.0 {
  execsql {
    CREATE TABLE t1(a VARINT, b BLOB, c VARCHAR(16));
    INSERT INTO t1 VALUES(1, 2, 3);
    INSERT INTO t1 VALUES('one', 'two', NULL);
  }
  set sql "SELECT * FROM t1"
  set STMT [sqlite3_prepare $DB $sql -1 TAIL]

  sqlite3_column_count $STMT
} 3

................................................................................

do_test capi3-5.4 {
  set types [list]
  foreach i {0 1 2} {lappend types [sqlite3_column_type $STMT $i]}
  set types
} {INTEGER INTEGER TEXT}

if 0 {
do_test capi3-5.5 {
  set ints [list]
  foreach i {0 1 2} {lappend ints [sqlite3_column_int $STMT $i]}
  set ints
} {1 2 3}

do_test capi3-5.6 {
  set utf8 [list]
  foreach i {0 1 2} {lappend utf8 [sqlite3_column_data $STMT $i]}
  set utf8
} {1 2 3}
}

do_test capi3-5.7 {
  set utf8 [list]
  foreach i {0 1 2} {lappend utf8 [utf8 [sqlite3_column_data16 $STMT $i]]}
  set utf8
} {1 2 3}

................................................................................
  sqlite3_step $STMT
} SQLITE_ROW

do_test capi3-5.10 {
  set types [list]
  foreach i {0 1 2} {lappend types [sqlite3_column_type $STMT $i]}
  set types
} {TEXT TEXT NULL}

do_test capi3-5.11 {
  set ints [list]
  foreach i {0 1 2} {lappend ints [sqlite3_column_int $STMT $i]}
  set ints
} {0 0 0}

do_test capi3-5.12 {
  set utf8 [list]
  foreach i {0 1 2} {lappend utf8 [sqlite3_column_data $STMT $i]}
  set utf8
} {one two {}}

do_test capi3-5.13 {
  set utf8 [list]
  foreach i {0 1 2} {lappend utf8 [utf8 [sqlite3_column_data16 $STMT $i]]}
  set utf8
} {one two {}}

do_test capi3-5.14 {
  set types [list]
  foreach i {0 1 2} {lappend types [sqlite3_column_type $STMT $i]}
  set types
} {TEXT TEXT NULL}

do_test capi3-5.15 {
  sqlite3_step $STMT
} SQLITE_DONE

do_test capi3-5.99 {
  sqlite3_finalize $STMT