annotate sqlite/vdbemem.c @ 1631:20ff61083530 trunk

[svn] - make audtool build - make plugins work
author nenolod
date Wed, 06 Sep 2006 14:46:09 -0700
parents b6b61becdf4e
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1434
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
1 /*
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
2 ** 2004 May 26
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
3 **
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
4 ** The author disclaims copyright to this source code. In place of
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
5 ** a legal notice, here is a blessing:
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
6 **
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
7 ** May you do good and not evil.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
8 ** May you find forgiveness for yourself and forgive others.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
9 ** May you share freely, never taking more than you give.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
10 **
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
11 *************************************************************************
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
12 **
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
13 ** This file contains code use to manipulate "Mem" structure. A "Mem"
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
14 ** stores a single value in the VDBE. Mem is an opaque structure visible
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
15 ** only within the VDBE. Interface routines refer to a Mem using the
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
16 ** name sqlite_value
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
17 */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
18 #include "sqliteInt.h"
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
19 #include "os.h"
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
20 #include <ctype.h>
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
21 #include "vdbeInt.h"
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
22
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
23 /*
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
24 ** If pMem is an object with a valid string representation, this routine
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
25 ** ensures the internal encoding for the string representation is
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
26 ** 'desiredEnc', one of SQLITE_UTF8, SQLITE_UTF16LE or SQLITE_UTF16BE.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
27 **
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
28 ** If pMem is not a string object, or the encoding of the string
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
29 ** representation is already stored using the requested encoding, then this
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
30 ** routine is a no-op.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
31 **
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
32 ** SQLITE_OK is returned if the conversion is successful (or not required).
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
33 ** SQLITE_NOMEM may be returned if a malloc() fails during conversion
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
34 ** between formats.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
35 */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
36 int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
37 int rc;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
38 if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
39 return SQLITE_OK;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
40 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
41 #ifdef SQLITE_OMIT_UTF16
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
42 return SQLITE_ERROR;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
43 #else
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
44
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
45
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
46 /* MemTranslate() may return SQLITE_OK or SQLITE_NOMEM. If NOMEM is returned,
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
47 ** then the encoding of the value may not have changed.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
48 */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
49 rc = sqlite3VdbeMemTranslate(pMem, desiredEnc);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
50 assert(rc==SQLITE_OK || rc==SQLITE_NOMEM);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
51 assert(rc==SQLITE_OK || pMem->enc!=desiredEnc);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
52 assert(rc==SQLITE_NOMEM || pMem->enc==desiredEnc);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
53
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
54 if( rc==SQLITE_NOMEM ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
55 /*
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
56 sqlite3VdbeMemRelease(pMem);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
57 pMem->flags = MEM_Null;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
58 pMem->z = 0;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
59 */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
60 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
61 return rc;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
62 #endif
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
63 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
64
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
65 /*
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
66 ** Make the given Mem object MEM_Dyn.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
67 **
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
68 ** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
69 */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
70 int sqlite3VdbeMemDynamicify(Mem *pMem){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
71 int n = pMem->n;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
72 u8 *z;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
73 if( (pMem->flags & (MEM_Ephem|MEM_Static|MEM_Short))==0 ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
74 return SQLITE_OK;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
75 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
76 assert( (pMem->flags & MEM_Dyn)==0 );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
77 assert( pMem->flags & (MEM_Str|MEM_Blob) );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
78 z = sqliteMallocRaw( n+2 );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
79 if( z==0 ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
80 return SQLITE_NOMEM;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
81 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
82 pMem->flags |= MEM_Dyn|MEM_Term;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
83 pMem->xDel = 0;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
84 memcpy(z, pMem->z, n );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
85 z[n] = 0;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
86 z[n+1] = 0;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
87 pMem->z = (char*)z;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
88 pMem->flags &= ~(MEM_Ephem|MEM_Static|MEM_Short);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
89 return SQLITE_OK;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
90 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
91
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
92 /*
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
93 ** Make the given Mem object either MEM_Short or MEM_Dyn so that bytes
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
94 ** of the Mem.z[] array can be modified.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
95 **
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
96 ** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
97 */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
98 int sqlite3VdbeMemMakeWriteable(Mem *pMem){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
99 int n;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
100 u8 *z;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
101 if( (pMem->flags & (MEM_Ephem|MEM_Static))==0 ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
102 return SQLITE_OK;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
103 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
104 assert( (pMem->flags & MEM_Dyn)==0 );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
105 assert( pMem->flags & (MEM_Str|MEM_Blob) );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
106 if( (n = pMem->n)+2<sizeof(pMem->zShort) ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
107 z = (u8*)pMem->zShort;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
108 pMem->flags |= MEM_Short|MEM_Term;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
109 }else{
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
110 z = sqliteMallocRaw( n+2 );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
111 if( z==0 ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
112 return SQLITE_NOMEM;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
113 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
114 pMem->flags |= MEM_Dyn|MEM_Term;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
115 pMem->xDel = 0;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
116 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
117 memcpy(z, pMem->z, n );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
118 z[n] = 0;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
119 z[n+1] = 0;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
120 pMem->z = (char*)z;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
121 pMem->flags &= ~(MEM_Ephem|MEM_Static);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
122 assert(0==(1&(int)pMem->z));
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
123 return SQLITE_OK;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
124 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
125
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
126 /*
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
127 ** Make sure the given Mem is \u0000 terminated.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
128 */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
129 int sqlite3VdbeMemNulTerminate(Mem *pMem){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
130 /* In SQLite, a string without a nul terminator occurs when a string
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
131 ** is loaded from disk (in this case the memory management is ephemeral),
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
132 ** or when it is supplied by the user as a bound variable or function
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
133 ** return value. Therefore, the memory management of the string must be
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
134 ** either ephemeral, static or controlled by a user-supplied destructor.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
135 */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
136 assert(
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
137 !(pMem->flags&MEM_Str) || /* it's not a string, or */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
138 (pMem->flags&MEM_Term) || /* it's nul term. already, or */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
139 (pMem->flags&(MEM_Ephem|MEM_Static)) || /* it's static or ephem, or */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
140 (pMem->flags&MEM_Dyn && pMem->xDel) /* external management */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
141 );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
142 if( (pMem->flags & MEM_Term)!=0 || (pMem->flags & MEM_Str)==0 ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
143 return SQLITE_OK; /* Nothing to do */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
144 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
145
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
146 if( pMem->flags & (MEM_Static|MEM_Ephem) ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
147 return sqlite3VdbeMemMakeWriteable(pMem);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
148 }else{
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
149 char *z = sqliteMalloc(pMem->n+2);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
150 if( !z ) return SQLITE_NOMEM;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
151 memcpy(z, pMem->z, pMem->n);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
152 z[pMem->n] = 0;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
153 z[pMem->n+1] = 0;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
154 pMem->xDel(pMem->z);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
155 pMem->xDel = 0;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
156 pMem->z = z;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
157 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
158 return SQLITE_OK;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
159 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
160
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
161 /*
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
162 ** Add MEM_Str to the set of representations for the given Mem. Numbers
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
163 ** are converted using sqlite3_snprintf(). Converting a BLOB to a string
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
164 ** is a no-op.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
165 **
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
166 ** Existing representations MEM_Int and MEM_Real are *not* invalidated.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
167 **
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
168 ** A MEM_Null value will never be passed to this function. This function is
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
169 ** used for converting values to text for returning to the user (i.e. via
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
170 ** sqlite3_value_text()), or for ensuring that values to be used as btree
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
171 ** keys are strings. In the former case a NULL pointer is returned the
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
172 ** user and the later is an internal programming error.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
173 */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
174 int sqlite3VdbeMemStringify(Mem *pMem, int enc){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
175 int rc = SQLITE_OK;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
176 int fg = pMem->flags;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
177 char *z = pMem->zShort;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
178
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
179 assert( !(fg&(MEM_Str|MEM_Blob)) );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
180 assert( fg&(MEM_Int|MEM_Real) );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
181
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
182 /* For a Real or Integer, use sqlite3_snprintf() to produce the UTF-8
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
183 ** string representation of the value. Then, if the required encoding
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
184 ** is UTF-16le or UTF-16be do a translation.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
185 **
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
186 ** FIX ME: It would be better if sqlite3_snprintf() could do UTF-16.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
187 */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
188 if( fg & MEM_Int ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
189 sqlite3_snprintf(NBFS, z, "%lld", pMem->i);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
190 }else{
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
191 assert( fg & MEM_Real );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
192 sqlite3_snprintf(NBFS, z, "%!.15g", pMem->r);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
193 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
194 pMem->n = strlen(z);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
195 pMem->z = z;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
196 pMem->enc = SQLITE_UTF8;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
197 pMem->flags |= MEM_Str | MEM_Short | MEM_Term;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
198 sqlite3VdbeChangeEncoding(pMem, enc);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
199 return rc;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
200 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
201
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
202 /*
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
203 ** Memory cell pMem contains the context of an aggregate function.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
204 ** This routine calls the finalize method for that function. The
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
205 ** result of the aggregate is stored back into pMem.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
206 **
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
207 ** Return SQLITE_ERROR if the finalizer reports an error. SQLITE_OK
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
208 ** otherwise.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
209 */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
210 int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
211 int rc = SQLITE_OK;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
212 if( pFunc && pFunc->xFinalize ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
213 sqlite3_context ctx;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
214 assert( (pMem->flags & MEM_Null)!=0 || pFunc==*(FuncDef**)&pMem->i );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
215 ctx.s.flags = MEM_Null;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
216 ctx.s.z = pMem->zShort;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
217 ctx.pMem = pMem;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
218 ctx.pFunc = pFunc;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
219 ctx.isError = 0;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
220 pFunc->xFinalize(&ctx);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
221 if( pMem->z && pMem->z!=pMem->zShort ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
222 sqliteFree( pMem->z );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
223 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
224 *pMem = ctx.s;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
225 if( pMem->flags & MEM_Short ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
226 pMem->z = pMem->zShort;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
227 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
228 if( ctx.isError ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
229 rc = SQLITE_ERROR;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
230 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
231 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
232 return rc;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
233 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
234
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
235 /*
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
236 ** Release any memory held by the Mem. This may leave the Mem in an
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
237 ** inconsistent state, for example with (Mem.z==0) and
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
238 ** (Mem.type==SQLITE_TEXT).
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
239 */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
240 void sqlite3VdbeMemRelease(Mem *p){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
241 if( p->flags & (MEM_Dyn|MEM_Agg) ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
242 if( p->xDel ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
243 if( p->flags & MEM_Agg ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
244 sqlite3VdbeMemFinalize(p, *(FuncDef**)&p->i);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
245 assert( (p->flags & MEM_Agg)==0 );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
246 sqlite3VdbeMemRelease(p);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
247 }else{
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
248 p->xDel((void *)p->z);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
249 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
250 }else{
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
251 sqliteFree(p->z);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
252 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
253 p->z = 0;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
254 p->xDel = 0;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
255 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
256 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
257
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
258 /*
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
259 ** Return some kind of integer value which is the best we can do
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
260 ** at representing the value that *pMem describes as an integer.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
261 ** If pMem is an integer, then the value is exact. If pMem is
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
262 ** a floating-point then the value returned is the integer part.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
263 ** If pMem is a string or blob, then we make an attempt to convert
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
264 ** it into a integer and return that. If pMem is NULL, return 0.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
265 **
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
266 ** If pMem is a string, its encoding might be changed.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
267 */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
268 i64 sqlite3VdbeIntValue(Mem *pMem){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
269 int flags = pMem->flags;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
270 if( flags & MEM_Int ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
271 return pMem->i;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
272 }else if( flags & MEM_Real ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
273 return (i64)pMem->r;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
274 }else if( flags & (MEM_Str|MEM_Blob) ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
275 i64 value;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
276 if( sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8)
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
277 || sqlite3VdbeMemNulTerminate(pMem) ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
278 return 0;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
279 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
280 assert( pMem->z );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
281 sqlite3atoi64(pMem->z, &value);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
282 return value;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
283 }else{
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
284 return 0;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
285 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
286 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
287
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
288 /*
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
289 ** Return the best representation of pMem that we can get into a
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
290 ** double. If pMem is already a double or an integer, return its
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
291 ** value. If it is a string or blob, try to convert it to a double.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
292 ** If it is a NULL, return 0.0.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
293 */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
294 double sqlite3VdbeRealValue(Mem *pMem){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
295 if( pMem->flags & MEM_Real ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
296 return pMem->r;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
297 }else if( pMem->flags & MEM_Int ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
298 return (double)pMem->i;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
299 }else if( pMem->flags & (MEM_Str|MEM_Blob) ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
300 double val = 0.0;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
301 if( sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8)
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
302 || sqlite3VdbeMemNulTerminate(pMem) ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
303 return 0.0;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
304 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
305 assert( pMem->z );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
306 sqlite3AtoF(pMem->z, &val);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
307 return val;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
308 }else{
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
309 return 0.0;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
310 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
311 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
312
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
313 /*
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
314 ** The MEM structure is already a MEM_Real. Try to also make it a
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
315 ** MEM_Int if we can.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
316 */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
317 void sqlite3VdbeIntegerAffinity(Mem *pMem){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
318 assert( pMem->flags & MEM_Real );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
319 pMem->i = pMem->r;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
320 if( ((double)pMem->i)==pMem->r ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
321 pMem->flags |= MEM_Int;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
322 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
323 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
324
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
325 /*
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
326 ** Convert pMem to type integer. Invalidate any prior representations.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
327 */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
328 int sqlite3VdbeMemIntegerify(Mem *pMem){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
329 pMem->i = sqlite3VdbeIntValue(pMem);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
330 sqlite3VdbeMemRelease(pMem);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
331 pMem->flags = MEM_Int;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
332 return SQLITE_OK;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
333 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
334
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
335 /*
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
336 ** Convert pMem so that it is of type MEM_Real.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
337 ** Invalidate any prior representations.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
338 */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
339 int sqlite3VdbeMemRealify(Mem *pMem){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
340 pMem->r = sqlite3VdbeRealValue(pMem);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
341 sqlite3VdbeMemRelease(pMem);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
342 pMem->flags = MEM_Real;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
343 return SQLITE_OK;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
344 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
345
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
346 /*
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
347 ** Convert pMem so that it has types MEM_Real or MEM_Int or both.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
348 ** Invalidate any prior representations.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
349 */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
350 int sqlite3VdbeMemNumerify(Mem *pMem){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
351 sqlite3VdbeMemRealify(pMem);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
352 sqlite3VdbeIntegerAffinity(pMem);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
353 return SQLITE_OK;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
354 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
355
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
356 /*
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
357 ** Delete any previous value and set the value stored in *pMem to NULL.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
358 */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
359 void sqlite3VdbeMemSetNull(Mem *pMem){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
360 sqlite3VdbeMemRelease(pMem);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
361 pMem->flags = MEM_Null;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
362 pMem->type = SQLITE_NULL;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
363 pMem->n = 0;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
364 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
365
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
366 /*
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
367 ** Delete any previous value and set the value stored in *pMem to val,
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
368 ** manifest type INTEGER.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
369 */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
370 void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
371 sqlite3VdbeMemRelease(pMem);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
372 pMem->i = val;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
373 pMem->flags = MEM_Int;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
374 pMem->type = SQLITE_INTEGER;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
375 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
376
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
377 /*
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
378 ** Delete any previous value and set the value stored in *pMem to val,
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
379 ** manifest type REAL.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
380 */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
381 void sqlite3VdbeMemSetDouble(Mem *pMem, double val){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
382 sqlite3VdbeMemRelease(pMem);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
383 pMem->r = val;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
384 pMem->flags = MEM_Real;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
385 pMem->type = SQLITE_FLOAT;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
386 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
387
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
388 /*
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
389 ** Make an shallow copy of pFrom into pTo. Prior contents of
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
390 ** pTo are overwritten. The pFrom->z field is not duplicated. If
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
391 ** pFrom->z is used, then pTo->z points to the same thing as pFrom->z
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
392 ** and flags gets srcType (either MEM_Ephem or MEM_Static).
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
393 */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
394 void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
395 memcpy(pTo, pFrom, sizeof(*pFrom)-sizeof(pFrom->zShort));
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
396 pTo->xDel = 0;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
397 if( pTo->flags & (MEM_Str|MEM_Blob) ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
398 pTo->flags &= ~(MEM_Dyn|MEM_Static|MEM_Short|MEM_Ephem);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
399 assert( srcType==MEM_Ephem || srcType==MEM_Static );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
400 pTo->flags |= srcType;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
401 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
402 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
403
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
404 /*
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
405 ** Make a full copy of pFrom into pTo. Prior contents of pTo are
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
406 ** freed before the copy is made.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
407 */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
408 int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
409 int rc;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
410 if( pTo->flags & MEM_Dyn ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
411 sqlite3VdbeMemRelease(pTo);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
412 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
413 sqlite3VdbeMemShallowCopy(pTo, pFrom, MEM_Ephem);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
414 if( pTo->flags & MEM_Ephem ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
415 rc = sqlite3VdbeMemMakeWriteable(pTo);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
416 }else{
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
417 rc = SQLITE_OK;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
418 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
419 return rc;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
420 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
421
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
422 /*
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
423 ** Transfer the contents of pFrom to pTo. Any existing value in pTo is
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
424 ** freed. If pFrom contains ephemeral data, a copy is made.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
425 **
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
426 ** pFrom contains an SQL NULL when this routine returns. SQLITE_NOMEM
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
427 ** might be returned if pFrom held ephemeral data and we were unable
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
428 ** to allocate enough space to make a copy.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
429 */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
430 int sqlite3VdbeMemMove(Mem *pTo, Mem *pFrom){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
431 int rc;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
432 if( pTo->flags & MEM_Dyn ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
433 sqlite3VdbeMemRelease(pTo);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
434 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
435 memcpy(pTo, pFrom, sizeof(Mem));
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
436 if( pFrom->flags & MEM_Short ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
437 pTo->z = pTo->zShort;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
438 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
439 pFrom->flags = MEM_Null;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
440 pFrom->xDel = 0;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
441 if( pTo->flags & MEM_Ephem ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
442 rc = sqlite3VdbeMemMakeWriteable(pTo);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
443 }else{
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
444 rc = SQLITE_OK;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
445 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
446 return rc;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
447 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
448
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
449 /*
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
450 ** Change the value of a Mem to be a string or a BLOB.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
451 */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
452 int sqlite3VdbeMemSetStr(
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
453 Mem *pMem, /* Memory cell to set to string value */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
454 const char *z, /* String pointer */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
455 int n, /* Bytes in string, or negative */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
456 u8 enc, /* Encoding of z. 0 for BLOBs */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
457 void (*xDel)(void*) /* Destructor function */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
458 ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
459 sqlite3VdbeMemRelease(pMem);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
460 if( !z ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
461 pMem->flags = MEM_Null;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
462 pMem->type = SQLITE_NULL;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
463 return SQLITE_OK;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
464 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
465
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
466 pMem->z = (char *)z;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
467 if( xDel==SQLITE_STATIC ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
468 pMem->flags = MEM_Static;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
469 }else if( xDel==SQLITE_TRANSIENT ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
470 pMem->flags = MEM_Ephem;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
471 }else{
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
472 pMem->flags = MEM_Dyn;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
473 pMem->xDel = xDel;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
474 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
475
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
476 pMem->enc = enc;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
477 pMem->type = enc==0 ? SQLITE_BLOB : SQLITE_TEXT;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
478 pMem->n = n;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
479
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
480 assert( enc==0 || enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
481 || enc==SQLITE_UTF16BE );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
482 switch( enc ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
483 case 0:
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
484 pMem->flags |= MEM_Blob;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
485 pMem->enc = SQLITE_UTF8;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
486 break;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
487
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
488 case SQLITE_UTF8:
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
489 pMem->flags |= MEM_Str;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
490 if( n<0 ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
491 pMem->n = strlen(z);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
492 pMem->flags |= MEM_Term;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
493 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
494 break;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
495
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
496 #ifndef SQLITE_OMIT_UTF16
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
497 case SQLITE_UTF16LE:
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
498 case SQLITE_UTF16BE:
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
499 pMem->flags |= MEM_Str;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
500 if( pMem->n<0 ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
501 pMem->n = sqlite3utf16ByteLen(pMem->z,-1);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
502 pMem->flags |= MEM_Term;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
503 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
504 if( sqlite3VdbeMemHandleBom(pMem) ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
505 return SQLITE_NOMEM;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
506 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
507 #endif /* SQLITE_OMIT_UTF16 */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
508 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
509 if( pMem->flags&MEM_Ephem ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
510 return sqlite3VdbeMemMakeWriteable(pMem);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
511 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
512 return SQLITE_OK;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
513 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
514
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
515 /*
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
516 ** Compare the values contained by the two memory cells, returning
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
517 ** negative, zero or positive if pMem1 is less than, equal to, or greater
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
518 ** than pMem2. Sorting order is NULL's first, followed by numbers (integers
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
519 ** and reals) sorted numerically, followed by text ordered by the collating
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
520 ** sequence pColl and finally blob's ordered by memcmp().
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
521 **
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
522 ** Two NULL values are considered equal by this function.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
523 */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
524 int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
525 int rc;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
526 int f1, f2;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
527 int combined_flags;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
528
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
529 /* Interchange pMem1 and pMem2 if the collating sequence specifies
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
530 ** DESC order.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
531 */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
532 f1 = pMem1->flags;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
533 f2 = pMem2->flags;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
534 combined_flags = f1|f2;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
535
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
536 /* If one value is NULL, it is less than the other. If both values
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
537 ** are NULL, return 0.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
538 */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
539 if( combined_flags&MEM_Null ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
540 return (f2&MEM_Null) - (f1&MEM_Null);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
541 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
542
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
543 /* If one value is a number and the other is not, the number is less.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
544 ** If both are numbers, compare as reals if one is a real, or as integers
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
545 ** if both values are integers.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
546 */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
547 if( combined_flags&(MEM_Int|MEM_Real) ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
548 if( !(f1&(MEM_Int|MEM_Real)) ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
549 return 1;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
550 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
551 if( !(f2&(MEM_Int|MEM_Real)) ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
552 return -1;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
553 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
554 if( (f1 & f2 & MEM_Int)==0 ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
555 double r1, r2;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
556 if( (f1&MEM_Real)==0 ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
557 r1 = pMem1->i;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
558 }else{
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
559 r1 = pMem1->r;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
560 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
561 if( (f2&MEM_Real)==0 ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
562 r2 = pMem2->i;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
563 }else{
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
564 r2 = pMem2->r;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
565 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
566 if( r1<r2 ) return -1;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
567 if( r1>r2 ) return 1;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
568 return 0;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
569 }else{
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
570 assert( f1&MEM_Int );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
571 assert( f2&MEM_Int );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
572 if( pMem1->i < pMem2->i ) return -1;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
573 if( pMem1->i > pMem2->i ) return 1;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
574 return 0;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
575 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
576 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
577
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
578 /* If one value is a string and the other is a blob, the string is less.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
579 ** If both are strings, compare using the collating functions.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
580 */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
581 if( combined_flags&MEM_Str ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
582 if( (f1 & MEM_Str)==0 ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
583 return 1;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
584 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
585 if( (f2 & MEM_Str)==0 ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
586 return -1;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
587 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
588
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
589 assert( pMem1->enc==pMem2->enc );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
590 assert( pMem1->enc==SQLITE_UTF8 ||
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
591 pMem1->enc==SQLITE_UTF16LE || pMem1->enc==SQLITE_UTF16BE );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
592
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
593 /* The collation sequence must be defined at this point, even if
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
594 ** the user deletes the collation sequence after the vdbe program is
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
595 ** compiled (this was not always the case).
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
596 */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
597 assert( !pColl || pColl->xCmp );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
598
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
599 if( pColl ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
600 if( pMem1->enc==pColl->enc ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
601 /* The strings are already in the correct encoding. Call the
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
602 ** comparison function directly */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
603 return pColl->xCmp(pColl->pUser,pMem1->n,pMem1->z,pMem2->n,pMem2->z);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
604 }else{
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
605 u8 origEnc = pMem1->enc;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
606 const void *v1, *v2;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
607 int n1, n2;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
608 /* Convert the strings into the encoding that the comparison
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
609 ** function expects */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
610 v1 = sqlite3ValueText((sqlite3_value*)pMem1, pColl->enc);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
611 n1 = v1==0 ? 0 : pMem1->n;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
612 assert( n1==sqlite3ValueBytes((sqlite3_value*)pMem1, pColl->enc) );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
613 v2 = sqlite3ValueText((sqlite3_value*)pMem2, pColl->enc);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
614 n2 = v2==0 ? 0 : pMem2->n;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
615 assert( n2==sqlite3ValueBytes((sqlite3_value*)pMem2, pColl->enc) );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
616 /* Do the comparison */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
617 rc = pColl->xCmp(pColl->pUser, n1, v1, n2, v2);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
618 /* Convert the strings back into the database encoding */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
619 sqlite3ValueText((sqlite3_value*)pMem1, origEnc);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
620 sqlite3ValueText((sqlite3_value*)pMem2, origEnc);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
621 return rc;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
622 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
623 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
624 /* If a NULL pointer was passed as the collate function, fall through
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
625 ** to the blob case and use memcmp(). */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
626 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
627
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
628 /* Both values must be blobs. Compare using memcmp(). */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
629 rc = memcmp(pMem1->z, pMem2->z, (pMem1->n>pMem2->n)?pMem2->n:pMem1->n);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
630 if( rc==0 ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
631 rc = pMem1->n - pMem2->n;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
632 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
633 return rc;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
634 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
635
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
636 /*
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
637 ** Move data out of a btree key or data field and into a Mem structure.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
638 ** The data or key is taken from the entry that pCur is currently pointing
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
639 ** to. offset and amt determine what portion of the data or key to retrieve.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
640 ** key is true to get the key or false to get data. The result is written
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
641 ** into the pMem element.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
642 **
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
643 ** The pMem structure is assumed to be uninitialized. Any prior content
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
644 ** is overwritten without being freed.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
645 **
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
646 ** If this routine fails for any reason (malloc returns NULL or unable
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
647 ** to read from the disk) then the pMem is left in an inconsistent state.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
648 */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
649 int sqlite3VdbeMemFromBtree(
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
650 BtCursor *pCur, /* Cursor pointing at record to retrieve. */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
651 int offset, /* Offset from the start of data to return bytes from. */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
652 int amt, /* Number of bytes to return. */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
653 int key, /* If true, retrieve from the btree key, not data. */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
654 Mem *pMem /* OUT: Return data in this Mem structure. */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
655 ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
656 char *zData; /* Data from the btree layer */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
657 int available; /* Number of bytes available on the local btree page */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
658
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
659 if( key ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
660 zData = (char *)sqlite3BtreeKeyFetch(pCur, &available);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
661 }else{
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
662 zData = (char *)sqlite3BtreeDataFetch(pCur, &available);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
663 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
664
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
665 pMem->n = amt;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
666 if( offset+amt<=available ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
667 pMem->z = &zData[offset];
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
668 pMem->flags = MEM_Blob|MEM_Ephem;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
669 }else{
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
670 int rc;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
671 if( amt>NBFS-2 ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
672 zData = (char *)sqliteMallocRaw(amt+2);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
673 if( !zData ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
674 return SQLITE_NOMEM;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
675 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
676 pMem->flags = MEM_Blob|MEM_Dyn|MEM_Term;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
677 pMem->xDel = 0;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
678 }else{
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
679 zData = &(pMem->zShort[0]);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
680 pMem->flags = MEM_Blob|MEM_Short|MEM_Term;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
681 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
682 pMem->z = zData;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
683 pMem->enc = 0;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
684 pMem->type = SQLITE_BLOB;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
685
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
686 if( key ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
687 rc = sqlite3BtreeKey(pCur, offset, amt, zData);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
688 }else{
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
689 rc = sqlite3BtreeData(pCur, offset, amt, zData);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
690 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
691 zData[amt] = 0;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
692 zData[amt+1] = 0;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
693 if( rc!=SQLITE_OK ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
694 if( amt>NBFS-2 ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
695 assert( zData!=pMem->zShort );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
696 assert( pMem->flags & MEM_Dyn );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
697 sqliteFree(zData);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
698 } else {
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
699 assert( zData==pMem->zShort );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
700 assert( pMem->flags & MEM_Short );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
701 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
702 return rc;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
703 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
704 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
705
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
706 return SQLITE_OK;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
707 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
708
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
709 #ifndef NDEBUG
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
710 /*
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
711 ** Perform various checks on the memory cell pMem. An assert() will
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
712 ** fail if pMem is internally inconsistent.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
713 */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
714 void sqlite3VdbeMemSanity(Mem *pMem){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
715 int flags = pMem->flags;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
716 assert( flags!=0 ); /* Must define some type */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
717 if( pMem->flags & (MEM_Str|MEM_Blob) ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
718 int x = pMem->flags & (MEM_Static|MEM_Dyn|MEM_Ephem|MEM_Short);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
719 assert( x!=0 ); /* Strings must define a string subtype */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
720 assert( (x & (x-1))==0 ); /* Only one string subtype can be defined */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
721 assert( pMem->z!=0 ); /* Strings must have a value */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
722 /* Mem.z points to Mem.zShort iff the subtype is MEM_Short */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
723 assert( (pMem->flags & MEM_Short)==0 || pMem->z==pMem->zShort );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
724 assert( (pMem->flags & MEM_Short)!=0 || pMem->z!=pMem->zShort );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
725 /* No destructor unless there is MEM_Dyn */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
726 assert( pMem->xDel==0 || (pMem->flags & MEM_Dyn)!=0 );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
727
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
728 if( (flags & MEM_Str) ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
729 assert( pMem->enc==SQLITE_UTF8 ||
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
730 pMem->enc==SQLITE_UTF16BE ||
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
731 pMem->enc==SQLITE_UTF16LE
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
732 );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
733 /* If the string is UTF-8 encoded and nul terminated, then pMem->n
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
734 ** must be the length of the string. (Later:) If the database file
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
735 ** has been corrupted, '\000' characters might have been inserted
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
736 ** into the middle of the string. In that case, the strlen() might
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
737 ** be less.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
738 */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
739 if( pMem->enc==SQLITE_UTF8 && (flags & MEM_Term) ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
740 assert( strlen(pMem->z)<=pMem->n );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
741 assert( pMem->z[pMem->n]==0 );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
742 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
743 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
744 }else{
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
745 /* Cannot define a string subtype for non-string objects */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
746 assert( (pMem->flags & (MEM_Static|MEM_Dyn|MEM_Ephem|MEM_Short))==0 );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
747 assert( pMem->xDel==0 );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
748 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
749 /* MEM_Null excludes all other types */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
750 assert( (pMem->flags&(MEM_Str|MEM_Int|MEM_Real|MEM_Blob))==0
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
751 || (pMem->flags&MEM_Null)==0 );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
752 /* If the MEM is both real and integer, the values are equal */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
753 assert( (pMem->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real)
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
754 || pMem->r==pMem->i );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
755 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
756 #endif
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
757
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
758 /* This function is only available internally, it is not part of the
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
759 ** external API. It works in a similar way to sqlite3_value_text(),
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
760 ** except the data returned is in the encoding specified by the second
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
761 ** parameter, which must be one of SQLITE_UTF16BE, SQLITE_UTF16LE or
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
762 ** SQLITE_UTF8.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
763 **
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
764 ** (2006-02-16:) The enc value can be or-ed with SQLITE_UTF16_ALIGNED.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
765 ** If that is the case, then the result must be aligned on an even byte
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
766 ** boundary.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
767 */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
768 const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
769 if( !pVal ) return 0;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
770 assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
771
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
772 if( pVal->flags&MEM_Null ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
773 return 0;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
774 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
775 assert( (MEM_Blob>>3) == MEM_Str );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
776 pVal->flags |= (pVal->flags & MEM_Blob)>>3;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
777 if( pVal->flags&MEM_Str ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
778 sqlite3VdbeChangeEncoding(pVal, enc & ~SQLITE_UTF16_ALIGNED);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
779 if( (enc & SQLITE_UTF16_ALIGNED)!=0 && 1==(1&(int)pVal->z) ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
780 assert( (pVal->flags & (MEM_Ephem|MEM_Static))!=0 );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
781 if( sqlite3VdbeMemMakeWriteable(pVal)!=SQLITE_OK ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
782 return 0;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
783 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
784 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
785 }else if( !(pVal->flags&MEM_Blob) ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
786 sqlite3VdbeMemStringify(pVal, enc);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
787 assert( 0==(1&(int)pVal->z) );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
788 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
789 assert(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) || sqlite3MallocFailed() );
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
790 if( pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
791 return pVal->z;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
792 }else{
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
793 return 0;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
794 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
795 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
796
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
797 /*
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
798 ** Create a new sqlite3_value object.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
799 */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
800 sqlite3_value* sqlite3ValueNew(void){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
801 Mem *p = sqliteMalloc(sizeof(*p));
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
802 if( p ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
803 p->flags = MEM_Null;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
804 p->type = SQLITE_NULL;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
805 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
806 return p;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
807 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
808
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
809 /*
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
810 ** Create a new sqlite3_value object, containing the value of pExpr.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
811 **
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
812 ** This only works for very simple expressions that consist of one constant
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
813 ** token (i.e. "5", "5.1", "NULL", "'a string'"). If the expression can
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
814 ** be converted directly into a value, then the value is allocated and
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
815 ** a pointer written to *ppVal. The caller is responsible for deallocating
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
816 ** the value by passing it to sqlite3ValueFree() later on. If the expression
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
817 ** cannot be converted to a value, then *ppVal is set to NULL.
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
818 */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
819 int sqlite3ValueFromExpr(
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
820 Expr *pExpr,
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
821 u8 enc,
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
822 u8 affinity,
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
823 sqlite3_value **ppVal
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
824 ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
825 int op;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
826 char *zVal = 0;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
827 sqlite3_value *pVal = 0;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
828
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
829 if( !pExpr ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
830 *ppVal = 0;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
831 return SQLITE_OK;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
832 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
833 op = pExpr->op;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
834
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
835 if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
836 zVal = sqliteStrNDup((char*)pExpr->token.z, pExpr->token.n);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
837 pVal = sqlite3ValueNew();
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
838 if( !zVal || !pVal ) goto no_mem;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
839 sqlite3Dequote(zVal);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
840 sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, sqlite3FreeX);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
841 if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_NONE ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
842 sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, enc);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
843 }else{
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
844 sqlite3ValueApplyAffinity(pVal, affinity, enc);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
845 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
846 }else if( op==TK_UMINUS ) {
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
847 if( SQLITE_OK==sqlite3ValueFromExpr(pExpr->pLeft, enc, affinity, &pVal) ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
848 pVal->i = -1 * pVal->i;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
849 pVal->r = -1.0 * pVal->r;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
850 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
851 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
852 #ifndef SQLITE_OMIT_BLOB_LITERAL
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
853 else if( op==TK_BLOB ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
854 int nVal;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
855 pVal = sqlite3ValueNew();
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
856 zVal = sqliteStrNDup((char*)pExpr->token.z+1, pExpr->token.n-1);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
857 if( !zVal || !pVal ) goto no_mem;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
858 sqlite3Dequote(zVal);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
859 nVal = strlen(zVal)/2;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
860 sqlite3VdbeMemSetStr(pVal, sqlite3HexToBlob(zVal), nVal, 0, sqlite3FreeX);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
861 sqliteFree(zVal);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
862 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
863 #endif
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
864
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
865 *ppVal = pVal;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
866 return SQLITE_OK;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
867
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
868 no_mem:
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
869 sqliteFree(zVal);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
870 sqlite3ValueFree(pVal);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
871 *ppVal = 0;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
872 return SQLITE_NOMEM;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
873 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
874
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
875 /*
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
876 ** Change the string value of an sqlite3_value object
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
877 */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
878 void sqlite3ValueSetStr(
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
879 sqlite3_value *v,
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
880 int n,
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
881 const void *z,
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
882 u8 enc,
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
883 void (*xDel)(void*)
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
884 ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
885 if( v ) sqlite3VdbeMemSetStr((Mem *)v, z, n, enc, xDel);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
886 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
887
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
888 /*
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
889 ** Free an sqlite3_value object
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
890 */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
891 void sqlite3ValueFree(sqlite3_value *v){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
892 if( !v ) return;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
893 sqlite3ValueSetStr(v, 0, 0, SQLITE_UTF8, SQLITE_STATIC);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
894 sqliteFree(v);
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
895 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
896
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
897 /*
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
898 ** Return the number of bytes in the sqlite3_value object assuming
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
899 ** that it uses the encoding "enc"
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
900 */
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
901 int sqlite3ValueBytes(sqlite3_value *pVal, u8 enc){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
902 Mem *p = (Mem*)pVal;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
903 if( (p->flags & MEM_Blob)!=0 || sqlite3ValueText(pVal, enc) ){
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
904 return p->n;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
905 }
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
906 return 0;
b6b61becdf4e [svn] - add sqlite/ directory
nenolod
parents:
diff changeset
907 }