wasCSharpSQLite – Blame information for rev
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | using System; |
2 | using System.Diagnostics; |
||
3 | using System.Text; |
||
4 | |||
5 | using i64 = System.Int64; |
||
6 | using u8 = System.Byte; |
||
7 | using u16 = System.UInt16; |
||
8 | using u32 = System.UInt32; |
||
9 | |||
10 | namespace Community.CsharpSqlite |
||
11 | { |
||
12 | using sqlite3_value = Sqlite3.Mem; |
||
13 | using System.Globalization; |
||
14 | |||
15 | public partial class Sqlite3 |
||
16 | { |
||
17 | /* |
||
18 | ** 2004 May 26 |
||
19 | ** |
||
20 | ** The author disclaims copyright to this source code. In place of |
||
21 | ** a legal notice, here is a blessing: |
||
22 | ** |
||
23 | ** May you do good and not evil. |
||
24 | ** May you find forgiveness for yourself and forgive others. |
||
25 | ** May you share freely, never taking more than you give. |
||
26 | ** |
||
27 | ************************************************************************* |
||
28 | ** |
||
29 | ** This file contains code use to manipulate "Mem" structure. A "Mem" |
||
30 | ** stores a single value in the VDBE. Mem is an opaque structure visible |
||
31 | ** only within the VDBE. Interface routines refer to a Mem using the |
||
32 | ** name sqlite_value |
||
33 | ************************************************************************* |
||
34 | ** Included in SQLite3 port to C#-SQLite; 2008 Noah B Hart |
||
35 | ** C#-SQLite is an independent reimplementation of the SQLite software library |
||
36 | ** |
||
37 | ** SQLITE_SOURCE_ID: 2011-05-19 13:26:54 ed1da510a239ea767a01dc332b667119fa3c908e |
||
38 | ** |
||
39 | ************************************************************************* |
||
40 | */ |
||
41 | //#include "sqliteInt.h" |
||
42 | //#include "vdbeInt.h" |
||
43 | |||
44 | /* |
||
45 | ** Call sqlite3VdbeMemExpandBlob() on the supplied value (type Mem*) |
||
46 | ** P if required. |
||
47 | */ |
||
48 | //#define expandBlob(P) (((P)->flags&MEM_Zero)?sqlite3VdbeMemExpandBlob(P):0) |
||
49 | ////static void expandBlob( Mem P ) |
||
50 | ////{ |
||
51 | //// if ( ( P.flags & MEM_Zero ) != 0 ) |
||
52 | //// sqlite3VdbeMemExpandBlob( P ); |
||
53 | ////} // TODO -- Convert to inline for speed |
||
54 | |||
55 | /* |
||
56 | ** If pMem is an object with a valid string representation, this routine |
||
57 | ** ensures the internal encoding for the string representation is |
||
58 | ** 'desiredEnc', one of SQLITE_UTF8, SQLITE_UTF16LE or SQLITE_UTF16BE. |
||
59 | ** |
||
60 | ** If pMem is not a string object, or the encoding of the string |
||
61 | ** representation is already stored using the requested encoding, then this |
||
62 | ** routine is a no-op. |
||
63 | ** |
||
64 | ** SQLITE_OK is returned if the conversion is successful (or not required). |
||
65 | ** SQLITE_NOMEM may be returned if a malloc() fails during conversion |
||
66 | ** between formats. |
||
67 | */ |
||
68 | static int sqlite3VdbeChangeEncoding( Mem pMem, int desiredEnc ) |
||
69 | { |
||
70 | int rc; |
||
71 | Debug.Assert( ( pMem.flags & MEM_RowSet ) == 0 ); |
||
72 | Debug.Assert( desiredEnc == SQLITE_UTF8 || desiredEnc == SQLITE_UTF16LE |
||
73 | || desiredEnc == SQLITE_UTF16BE ); |
||
74 | if ( ( pMem.flags & MEM_Str ) == 0 || pMem.enc == desiredEnc ) |
||
75 | { |
||
76 | if ( string.IsNullOrEmpty( pMem.z ) && pMem.zBLOB != null ) |
||
77 | pMem.z = Encoding.UTF8.GetString( pMem.zBLOB, 0, pMem.zBLOB.Length ); |
||
78 | return SQLITE_OK; |
||
79 | } |
||
80 | Debug.Assert( pMem.db == null || sqlite3_mutex_held( pMem.db.mutex ) ); |
||
81 | #if SQLITE_OMIT_UTF16 |
||
82 | return SQLITE_ERROR; |
||
83 | #else |
||
84 | |||
85 | /* MemTranslate() may return SQLITE_OK or SQLITE_NOMEM. If NOMEM is returned, |
||
86 | ** then the encoding of the value may not have changed. |
||
87 | */ |
||
88 | rc = sqlite3VdbeMemTranslate(pMem, (u8)desiredEnc); |
||
89 | Debug.Assert(rc==SQLITE_OK || rc==SQLITE_NOMEM); |
||
90 | Debug.Assert(rc==SQLITE_OK || pMem.enc!=desiredEnc); |
||
91 | Debug.Assert(rc==SQLITE_NOMEM || pMem.enc==desiredEnc); |
||
92 | return rc; |
||
93 | #endif |
||
94 | } |
||
95 | |||
96 | /* |
||
97 | ** Make sure pMem.z points to a writable allocation of at least |
||
98 | ** n bytes. |
||
99 | ** |
||
100 | ** If the memory cell currently contains string or blob data |
||
101 | ** and the third argument passed to this function is true, the |
||
102 | ** current content of the cell is preserved. Otherwise, it may |
||
103 | ** be discarded. |
||
104 | ** |
||
105 | ** This function sets the MEM_Dyn flag and clears any xDel callback. |
||
106 | ** It also clears MEM_Ephem and MEM_Static. If the preserve flag is |
||
107 | ** not set, Mem.n is zeroed. |
||
108 | */ |
||
109 | static int sqlite3VdbeMemGrow( Mem pMem, int n, int preserve ) |
||
110 | { |
||
111 | // TODO -- What do we want to do about this routine? |
||
112 | //Debug.Assert( 1 >= |
||
113 | // ((pMem.zMalloc !=null )? 1 : 0) + //&& pMem.zMalloc==pMem.z) ? 1 : 0) + |
||
114 | // (((pMem.flags & MEM_Dyn)!=0 && pMem.xDel!=null) ? 1 : 0) + |
||
115 | // ((pMem.flags & MEM_Ephem)!=0 ? 1 : 0) + |
||
116 | // ((pMem.flags & MEM_Static)!=0 ? 1 : 0) |
||
117 | //); |
||
118 | //assert( (pMem->flags&MEM_RowSet)==0 ); |
||
119 | |||
120 | //if( n<32 ) n = 32; |
||
121 | //if( sqlite3DbMallocSize(pMem->db, pMem.zMalloc)<n ){ |
||
122 | if ( preserve != 0 ) |
||
123 | {//& pMem.z==pMem.zMalloc ){ |
||
124 | if ( pMem.z == null ) |
||
125 | pMem.z = string.Empty;// sqlite3DbReallocOrFree( pMem.db, pMem.z, n ); |
||
126 | else |
||
127 | if ( n < pMem.z.Length ) |
||
128 | pMem.z = pMem.z.Substring( 0, n ); |
||
129 | preserve = 0; |
||
130 | } |
||
131 | else |
||
132 | { |
||
133 | // sqlite3DbFree(pMem->db,ref pMem.zMalloc); |
||
134 | pMem.z = string.Empty;// sqlite3DbMallocRaw( pMem.db, n ); |
||
135 | } |
||
136 | //} |
||
137 | |||
138 | // if( pMem->z && preserve && pMem->zMalloc && pMem->z!=pMem->zMalloc ){ |
||
139 | // memcpy(pMem.zMalloc, pMem.z, pMem.n); |
||
140 | //} |
||
141 | if ( ( pMem.flags & MEM_Dyn ) != 0 && pMem.xDel != null ) |
||
142 | { |
||
143 | pMem.xDel( ref pMem.z ); |
||
144 | } |
||
145 | |||
146 | // TODO --pMem.z = pMem.zMalloc; |
||
147 | if ( pMem.z == null ) |
||
148 | { |
||
149 | pMem.flags = MEM_Null; |
||
150 | } |
||
151 | else |
||
152 | { |
||
153 | pMem.flags = (u16)( pMem.flags & ~( MEM_Ephem | MEM_Static ) ); |
||
154 | } |
||
155 | pMem.xDel = null; |
||
156 | return pMem.z != null ? SQLITE_OK : SQLITE_NOMEM; |
||
157 | } |
||
158 | |||
159 | /* |
||
160 | ** Make the given Mem object MEM_Dyn. In other words, make it so |
||
161 | ** that any TEXT or BLOB content is stored in memory obtained from |
||
162 | ** malloc(). In this way, we know that the memory is safe to be |
||
163 | ** overwritten or altered. |
||
164 | ** |
||
165 | ** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails. |
||
166 | */ |
||
167 | static int sqlite3VdbeMemMakeWriteable( Mem pMem ) |
||
168 | { |
||
169 | int f; |
||
170 | Debug.Assert( pMem.db == null || sqlite3_mutex_held( pMem.db.mutex ) ); |
||
171 | Debug.Assert( ( pMem.flags & MEM_RowSet ) == 0 ); |
||
172 | ////expandBlob( pMem ); |
||
173 | f = pMem.flags; |
||
174 | if ( ( f & ( MEM_Str | MEM_Blob ) ) != 0 ) // TODO -- && pMem.z != pMem.zMalloc ) |
||
175 | { |
||
176 | if ( sqlite3VdbeMemGrow( pMem, pMem.n + 2, 1 ) != 0 ) |
||
177 | //{ |
||
178 | // return SQLITE_NOMEM; |
||
179 | //} |
||
180 | //pMem.z[pMem->n] = 0; |
||
181 | //pMem.z[pMem->n + 1] = 0; |
||
182 | pMem.flags |= MEM_Term; |
||
183 | #if SQLITE_DEBUG |
||
184 | pMem.pScopyFrom = null; |
||
185 | #endif |
||
186 | } |
||
187 | |||
188 | return SQLITE_OK; |
||
189 | } |
||
190 | /* |
||
191 | ** If the given Mem* has a zero-filled tail, turn it into an ordinary |
||
192 | ** blob stored in dynamically allocated space. |
||
193 | */ |
||
194 | #if !SQLITE_OMIT_INCRBLOB |
||
195 | static int sqlite3VdbeMemExpandBlob( Mem pMem ) |
||
196 | { |
||
197 | if ( ( pMem.flags & MEM_Zero ) != 0 ) |
||
198 | { |
||
199 | u32 nByte; |
||
200 | Debug.Assert( ( pMem.flags & MEM_Blob ) != 0 ); |
||
201 | Debug.Assert( ( pMem.flags & MEM_RowSet ) == 0 ); |
||
202 | Debug.Assert( pMem.db == null || sqlite3_mutex_held( pMem.db.mutex ) ); |
||
203 | /* Set nByte to the number of bytes required to store the expanded blob. */ |
||
204 | nByte = (u32)( pMem.n + pMem.u.nZero ); |
||
205 | if ( nByte <= 0 ) |
||
206 | { |
||
207 | nByte = 1; |
||
208 | } |
||
209 | if ( sqlite3VdbeMemGrow( pMem, (int)nByte, 1 ) != 0 ) |
||
210 | { |
||
211 | return SQLITE_NOMEM; |
||
212 | } /* Set nByte to the number of bytes required to store the expanded blob. */ |
||
213 | nByte = (u32)( pMem.n + pMem.u.nZero ); |
||
214 | if ( nByte <= 0 ) |
||
215 | { |
||
216 | nByte = 1; |
||
217 | } |
||
218 | if ( sqlite3VdbeMemGrow( pMem, (int)nByte, 1 ) != 0 ) |
||
219 | { |
||
220 | return SQLITE_NOMEM; |
||
221 | } |
||
222 | //memset(&pMem->z[pMem->n], 0, pMem->u.nZero); |
||
223 | pMem.zBLOB = Encoding.UTF8.GetBytes( pMem.z ); |
||
224 | pMem.z = null; |
||
225 | pMem.n += (int)pMem.u.nZero; |
||
226 | pMem.u.i = 0; |
||
227 | pMem.flags = (u16)( pMem.flags & ~( MEM_Zero | MEM_Static | MEM_Ephem | MEM_Term ) ); |
||
228 | pMem.flags |= MEM_Dyn; |
||
229 | } |
||
230 | return SQLITE_OK; |
||
231 | } |
||
232 | #endif |
||
233 | |||
234 | |||
235 | /* |
||
236 | ** Make sure the given Mem is \u0000 terminated. |
||
237 | */ |
||
238 | static int sqlite3VdbeMemNulTerminate( Mem pMem ) |
||
239 | { |
||
240 | Debug.Assert( pMem.db == null || sqlite3_mutex_held( pMem.db.mutex ) ); |
||
241 | if ( ( pMem.flags & MEM_Term ) != 0 || ( pMem.flags & MEM_Str ) == 0 ) |
||
242 | { |
||
243 | return SQLITE_OK; /* Nothing to do */ |
||
244 | } |
||
245 | //if ( pMem.n != 0 && sqlite3VdbeMemGrow( pMem, pMem.n + 2, 1 ) != 0 ) |
||
246 | //{ |
||
247 | // return SQLITE_NOMEM; |
||
248 | //} |
||
249 | // pMem.z[pMem->n] = 0; |
||
250 | // pMem.z[pMem->n+1] = 0; |
||
251 | if ( pMem.z != null && pMem.n < pMem.z.Length ) |
||
252 | pMem.z = pMem.z.Substring( 0, pMem.n ); |
||
253 | pMem.flags |= MEM_Term; |
||
254 | return SQLITE_OK; |
||
255 | } |
||
256 | |||
257 | /* |
||
258 | ** Add MEM_Str to the set of representations for the given Mem. Numbers |
||
259 | ** are converted using sqlite3_snprintf(). Converting a BLOB to a string |
||
260 | ** is a no-op. |
||
261 | ** |
||
262 | ** Existing representations MEM_Int and MEM_Real are *not* invalidated. |
||
263 | ** |
||
264 | ** A MEM_Null value will never be passed to this function. This function is |
||
265 | ** used for converting values to text for returning to the user (i.e. via |
||
266 | ** sqlite3_value_text()), or for ensuring that values to be used as btree |
||
267 | ** keys are strings. In the former case a NULL pointer is returned the |
||
268 | ** user and the later is an internal programming error. |
||
269 | */ |
||
270 | static int sqlite3VdbeMemStringify( Mem pMem, int enc ) |
||
271 | { |
||
272 | int rc = SQLITE_OK; |
||
273 | int fg = pMem.flags; |
||
274 | const int nByte = 32; |
||
275 | |||
276 | Debug.Assert( pMem.db == null || sqlite3_mutex_held( pMem.db.mutex ) ); |
||
277 | Debug.Assert( ( fg & MEM_Zero ) == 0 ); |
||
278 | Debug.Assert( ( fg & ( MEM_Str | MEM_Blob ) ) == 0 ); |
||
279 | Debug.Assert( ( fg & ( MEM_Int | MEM_Real ) ) != 0 ); |
||
280 | Debug.Assert( ( pMem.flags & MEM_RowSet ) == 0 ); |
||
281 | //assert( EIGHT_BYTE_ALIGNMENT(pMem) ); |
||
282 | |||
283 | if ( sqlite3VdbeMemGrow( pMem, nByte, 0 ) != 0 ) |
||
284 | { |
||
285 | return SQLITE_NOMEM; |
||
286 | } |
||
287 | |||
288 | /* For a Real or Integer, use sqlite3_snprintf() to produce the UTF-8 |
||
289 | ** string representation of the value. Then, if the required encoding |
||
290 | ** is UTF-16le or UTF-16be do a translation. |
||
291 | ** |
||
292 | ** FIX ME: It would be better if sqlite3_snprintf() could do UTF-16. |
||
293 | */ |
||
294 | if ( ( fg & MEM_Int ) != 0 ) |
||
295 | { |
||
296 | pMem.z = pMem.u.i.ToString(); //sqlite3_snprintf(nByte, pMem.z, "%lld", pMem->u.i); |
||
297 | } |
||
298 | else |
||
299 | { |
||
300 | Debug.Assert( ( fg & MEM_Real ) != 0 ); |
||
301 | if ( Double.IsNegativeInfinity( pMem.r ) ) |
||
302 | pMem.z = "-Inf"; |
||
303 | else if ( Double.IsInfinity( pMem.r ) ) |
||
304 | pMem.z = "Inf"; |
||
305 | else if ( Double.IsPositiveInfinity( pMem.r ) ) |
||
306 | pMem.z = "+Inf"; |
||
307 | else if ( pMem.r.ToString( CultureInfo.InvariantCulture ).Contains( "." ) ) |
||
308 | pMem.z = pMem.r.ToString( CultureInfo.InvariantCulture ).ToLower();//sqlite3_snprintf(nByte, pMem.z, "%!.15g", pMem->r); |
||
309 | else |
||
310 | pMem.z = pMem.r.ToString( CultureInfo.InvariantCulture) + ".0"; |
||
311 | } |
||
312 | pMem.n = sqlite3Strlen30( pMem.z ); |
||
313 | pMem.enc = SQLITE_UTF8; |
||
314 | pMem.flags |= MEM_Str | MEM_Term; |
||
315 | sqlite3VdbeChangeEncoding( pMem, enc ); |
||
316 | return rc; |
||
317 | } |
||
318 | |||
319 | /* |
||
320 | ** Memory cell pMem contains the context of an aggregate function. |
||
321 | ** This routine calls the finalize method for that function. The |
||
322 | ** result of the aggregate is stored back into pMem. |
||
323 | ** |
||
324 | ** Return SQLITE_ERROR if the finalizer reports an error. SQLITE_OK |
||
325 | ** otherwise. |
||
326 | */ |
||
327 | static int sqlite3VdbeMemFinalize( Mem pMem, FuncDef pFunc ) |
||
328 | { |
||
329 | int rc = SQLITE_OK; |
||
330 | if ( ALWAYS( pFunc != null && pFunc.xFinalize != null ) ) |
||
331 | { |
||
332 | sqlite3_context ctx = new sqlite3_context(); |
||
333 | Debug.Assert( ( pMem.flags & MEM_Null ) != 0 || pFunc == pMem.u.pDef ); |
||
334 | Debug.Assert( pMem.db == null || sqlite3_mutex_held( pMem.db.mutex ) ); |
||
335 | //memset(&ctx, 0, sizeof(ctx)); |
||
336 | ctx.s.flags = MEM_Null; |
||
337 | ctx.s.db = pMem.db; |
||
338 | ctx.pMem = pMem; |
||
339 | ctx.pFunc = pFunc; |
||
340 | pFunc.xFinalize( ctx ); /* IMP: R-24505-23230 */ |
||
341 | Debug.Assert( 0 == ( pMem.flags & MEM_Dyn ) && pMem.xDel == null ); |
||
342 | sqlite3DbFree( pMem.db, ref pMem.zBLOB );//zMalloc ); |
||
343 | ctx.s.CopyTo( ref pMem );//memcpy(pMem, &ctx.s, sizeof(ctx.s)); |
||
344 | rc = ctx.isError; |
||
345 | } |
||
346 | return rc; |
||
347 | } |
||
348 | |||
349 | /* |
||
350 | ** If the memory cell contains a string value that must be freed by |
||
351 | ** invoking an external callback, free it now. Calling this function |
||
352 | ** does not free any Mem.zMalloc buffer. |
||
353 | */ |
||
354 | static void sqlite3VdbeMemReleaseExternal( Mem p ) |
||
355 | { |
||
356 | Debug.Assert( p.db == null || sqlite3_mutex_held( p.db.mutex ) ); |
||
357 | testcase( p.flags & MEM_Agg ); |
||
358 | testcase( p.flags & MEM_Dyn ); |
||
359 | testcase( p.flags & MEM_RowSet ); |
||
360 | testcase( p.flags & MEM_Frame ); |
||
361 | if ( ( p.flags & ( MEM_Agg | MEM_Dyn | MEM_RowSet | MEM_Frame ) ) != 0 ) |
||
362 | { |
||
363 | if ( ( p.flags & MEM_Agg ) != 0 ) |
||
364 | { |
||
365 | sqlite3VdbeMemFinalize( p, p.u.pDef ); |
||
366 | Debug.Assert( ( p.flags & MEM_Agg ) == 0 ); |
||
367 | sqlite3VdbeMemRelease( p ); |
||
368 | } |
||
369 | else if ( ( p.flags & MEM_Dyn ) != 0 && p.xDel != null ) |
||
370 | { |
||
371 | Debug.Assert( ( p.flags & MEM_RowSet ) == 0 ); |
||
372 | p.xDel( ref p.z ); |
||
373 | p.xDel = null; |
||
374 | } |
||
375 | else if ( ( p.flags & MEM_RowSet ) != 0 ) |
||
376 | { |
||
377 | sqlite3RowSetClear( p.u.pRowSet ); |
||
378 | } |
||
379 | else if ( ( p.flags & MEM_Frame ) != 0 ) |
||
380 | { |
||
381 | sqlite3VdbeMemSetNull( p ); |
||
382 | } |
||
383 | } |
||
384 | p.n = 0; |
||
385 | p.z = null; |
||
386 | p.zBLOB = null; |
||
387 | } |
||
388 | |||
389 | /* |
||
390 | ** Release any memory held by the Mem. This may leave the Mem in an |
||
391 | ** inconsistent state, for example with (Mem.z==0) and |
||
392 | ** (Mem.type==SQLITE_TEXT). |
||
393 | */ |
||
394 | static void sqlite3VdbeMemRelease( Mem p ) |
||
395 | { |
||
396 | sqlite3VdbeMemReleaseExternal( p ); |
||
397 | sqlite3DbFree( p.db, ref p.zBLOB );//zMalloc ); |
||
398 | p.z = null; |
||
399 | //p.zMalloc = 0; |
||
400 | p.xDel = null; |
||
401 | } |
||
402 | |||
403 | /* |
||
404 | ** Convert a 64-bit IEEE double into a 64-bit signed integer. |
||
405 | ** If the double is too large, return 0x8000000000000000. |
||
406 | ** |
||
407 | ** Most systems appear to do this simply by assigning |
||
408 | ** variables and without the extra range tests. But |
||
409 | ** there are reports that windows throws an expection |
||
410 | ** if the floating point value is out of range. (See ticket #2880.) |
||
411 | ** Because we do not completely understand the problem, we will |
||
412 | ** take the conservative approach and always do range tests |
||
413 | ** before attempting the conversion. |
||
414 | */ |
||
415 | static i64 doubleToInt64( double r ) |
||
416 | { |
||
417 | #if SQLITE_OMIT_FLOATING_POINT |
||
418 | /* When floating-point is omitted, double and int64 are the same thing */ |
||
419 | return r; |
||
420 | #else |
||
421 | /* |
||
422 | ** Many compilers we encounter do not define constants for the |
||
423 | ** minimum and maximum 64-bit integers, or they define them |
||
424 | ** inconsistently. And many do not understand the "LL" notation. |
||
425 | ** So we define our own static constants here using nothing |
||
426 | ** larger than a 32-bit integer constant. |
||
427 | */ |
||
428 | const i64 maxInt = LARGEST_INT64; |
||
429 | const i64 minInt = SMALLEST_INT64; |
||
430 | |||
431 | if ( r < (double)minInt ) |
||
432 | { |
||
433 | return minInt; |
||
434 | } |
||
435 | else if ( r > (double)maxInt ) |
||
436 | { |
||
437 | /* minInt is correct here - not maxInt. It turns out that assigning |
||
438 | ** a very large positive number to an integer results in a very large |
||
439 | ** negative integer. This makes no sense, but it is what x86 hardware |
||
440 | ** does so for compatibility we will do the same in software. */ |
||
441 | return minInt; |
||
442 | } |
||
443 | else |
||
444 | { |
||
445 | return (i64)r; |
||
446 | } |
||
447 | #endif |
||
448 | } |
||
449 | |||
450 | /* |
||
451 | ** Return some kind of integer value which is the best we can do |
||
452 | ** at representing the value that *pMem describes as an integer. |
||
453 | ** If pMem is an integer, then the value is exact. If pMem is |
||
454 | ** a floating-point then the value returned is the integer part. |
||
455 | ** If pMem is a string or blob, then we make an attempt to convert |
||
456 | ** it into a integer and return that. If pMem represents an |
||
457 | ** an SQL-NULL value, return 0. |
||
458 | ** |
||
459 | ** If pMem represents a string value, its encoding might be changed. |
||
460 | */ |
||
461 | static i64 sqlite3VdbeIntValue( Mem pMem ) |
||
462 | { |
||
463 | int flags; |
||
464 | Debug.Assert( pMem.db == null || sqlite3_mutex_held( pMem.db.mutex ) ); |
||
465 | // assert( EIGHT_BYTE_ALIGNMENT(pMem) ); |
||
466 | flags = pMem.flags; |
||
467 | if ( ( flags & MEM_Int ) != 0 ) |
||
468 | { |
||
469 | return pMem.u.i; |
||
470 | } |
||
471 | else if ( ( flags & MEM_Real ) != 0 ) |
||
472 | { |
||
473 | return doubleToInt64( pMem.r ); |
||
474 | } |
||
475 | else if ( ( flags & ( MEM_Str ) ) != 0 ) |
||
476 | { |
||
477 | i64 value = 0; |
||
478 | Debug.Assert( pMem.z != null || pMem.n == 0 ); |
||
479 | testcase( pMem.z == null ); |
||
480 | sqlite3Atoi64( pMem.z, ref value, pMem.n, pMem.enc ); |
||
481 | return value; |
||
482 | } |
||
483 | else if ( ( flags & ( MEM_Blob ) ) != 0 ) |
||
484 | { |
||
485 | i64 value = 0; |
||
486 | Debug.Assert( pMem.zBLOB != null || pMem.n == 0 ); |
||
487 | testcase( pMem.zBLOB == null ); |
||
488 | sqlite3Atoi64( Encoding.UTF8.GetString( pMem.zBLOB, 0, pMem.n ), ref value, pMem.n, pMem.enc ); |
||
489 | return value; |
||
490 | } |
||
491 | else |
||
492 | { |
||
493 | return 0; |
||
494 | } |
||
495 | } |
||
496 | |||
497 | /* |
||
498 | ** Return the best representation of pMem that we can get into a |
||
499 | ** double. If pMem is already a double or an integer, return its |
||
500 | ** value. If it is a string or blob, try to convert it to a double. |
||
501 | ** If it is a NULL, return 0.0. |
||
502 | */ |
||
503 | static double sqlite3VdbeRealValue( Mem pMem ) |
||
504 | { |
||
505 | Debug.Assert( pMem.db == null || sqlite3_mutex_held( pMem.db.mutex ) ); |
||
506 | //assert( EIGHT_BYTE_ALIGNMENT(pMem) ); |
||
507 | if ( ( pMem.flags & MEM_Real ) != 0 ) |
||
508 | { |
||
509 | return pMem.r; |
||
510 | } |
||
511 | else if ( ( pMem.flags & MEM_Int ) != 0 ) |
||
512 | { |
||
513 | return (double)pMem.u.i; |
||
514 | } |
||
515 | else if ( ( pMem.flags & ( MEM_Str ) ) != 0 ) |
||
516 | { |
||
517 | /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ |
||
518 | double val = (double)0; |
||
519 | sqlite3AtoF( pMem.z, ref val, pMem.n, pMem.enc ); |
||
520 | return val; |
||
521 | } |
||
522 | else if ( ( pMem.flags & ( MEM_Blob ) ) != 0 ) |
||
523 | { |
||
524 | /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ |
||
525 | double val = (double)0; |
||
526 | Debug.Assert( pMem.zBLOB != null || pMem.n == 0 ); |
||
527 | sqlite3AtoF( Encoding.UTF8.GetString( pMem.zBLOB, 0, pMem.n ), ref val, pMem.n, pMem.enc ); |
||
528 | return val; |
||
529 | } |
||
530 | else |
||
531 | { |
||
532 | /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ |
||
533 | return (double)0; |
||
534 | } |
||
535 | } |
||
536 | |||
537 | /* |
||
538 | ** The MEM structure is already a MEM_Real. Try to also make it a |
||
539 | ** MEM_Int if we can. |
||
540 | */ |
||
541 | static void sqlite3VdbeIntegerAffinity( Mem pMem ) |
||
542 | { |
||
543 | Debug.Assert( ( pMem.flags & MEM_Real ) != 0 ); |
||
544 | Debug.Assert( ( pMem.flags & MEM_RowSet ) == 0 ); |
||
545 | Debug.Assert( pMem.db == null || sqlite3_mutex_held( pMem.db.mutex ) ); |
||
546 | //assert( EIGHT_BYTE_ALIGNMENT(pMem) ); |
||
547 | |||
548 | pMem.u.i = doubleToInt64( pMem.r ); |
||
549 | |||
550 | /* Only mark the value as an integer if |
||
551 | ** |
||
552 | ** (1) the round-trip conversion real->int->real is a no-op, and |
||
553 | ** (2) The integer is neither the largest nor the smallest |
||
554 | ** possible integer (ticket #3922) |
||
555 | ** |
||
556 | ** The second and third terms in the following conditional enforces |
||
557 | ** the second condition under the assumption that addition overflow causes |
||
558 | ** values to wrap around. On x86 hardware, the third term is always |
||
559 | ** true and could be omitted. But we leave it in because other |
||
560 | ** architectures might behave differently. |
||
561 | */ |
||
562 | if ( pMem.r == (double)pMem.u.i && pMem.u.i > SMALLEST_INT64 |
||
563 | && ALWAYS( pMem.u.i < LARGEST_INT64 ) ) |
||
564 | { |
||
565 | pMem.flags |= MEM_Int; |
||
566 | } |
||
567 | } |
||
568 | |||
569 | /* |
||
570 | ** Convert pMem to type integer. Invalidate any prior representations. |
||
571 | */ |
||
572 | static int sqlite3VdbeMemIntegerify( Mem pMem ) |
||
573 | { |
||
574 | Debug.Assert( pMem.db == null || sqlite3_mutex_held( pMem.db.mutex ) ); |
||
575 | Debug.Assert( ( pMem.flags & MEM_RowSet ) == 0 ); |
||
576 | //assert( EIGHT_BYTE_ALIGNMENT(pMem) ); |
||
577 | |||
578 | pMem.u.i = sqlite3VdbeIntValue( pMem ); |
||
579 | MemSetTypeFlag( pMem, MEM_Int ); |
||
580 | return SQLITE_OK; |
||
581 | } |
||
582 | |||
583 | /* |
||
584 | ** Convert pMem so that it is of type MEM_Real. |
||
585 | ** Invalidate any prior representations. |
||
586 | */ |
||
587 | static int sqlite3VdbeMemRealify( Mem pMem ) |
||
588 | { |
||
589 | Debug.Assert( pMem.db == null || sqlite3_mutex_held( pMem.db.mutex ) ); |
||
590 | //assert( EIGHT_BYTE_ALIGNMENT(pMem) ); |
||
591 | |||
592 | pMem.r = sqlite3VdbeRealValue( pMem ); |
||
593 | MemSetTypeFlag( pMem, MEM_Real ); |
||
594 | return SQLITE_OK; |
||
595 | } |
||
596 | |||
597 | /* |
||
598 | ** Convert pMem so that it has types MEM_Real or MEM_Int or both. |
||
599 | ** Invalidate any prior representations. |
||
600 | ** |
||
601 | ** Every effort is made to force the conversion, even if the input |
||
602 | ** is a string that does not look completely like a number. Convert |
||
603 | ** as much of the string as we can and ignore the rest. |
||
604 | */ |
||
605 | static int sqlite3VdbeMemNumerify( Mem pMem ) |
||
606 | { |
||
607 | if ( ( pMem.flags & ( MEM_Int | MEM_Real | MEM_Null ) ) == 0 ) |
||
608 | { |
||
609 | Debug.Assert( ( pMem.flags & ( MEM_Blob | MEM_Str ) ) != 0 ); |
||
610 | Debug.Assert( pMem.db == null || sqlite3_mutex_held( pMem.db.mutex ) ); |
||
611 | if ( ( pMem.flags & MEM_Blob ) != 0 && pMem.z == null ) |
||
612 | { |
||
613 | if ( 0 == sqlite3Atoi64( Encoding.UTF8.GetString( pMem.zBLOB, 0, pMem.zBLOB.Length ), ref pMem.u.i, pMem.n, pMem.enc ) ) |
||
614 | MemSetTypeFlag( pMem, MEM_Int ); |
||
615 | else |
||
616 | { |
||
617 | pMem.r = sqlite3VdbeRealValue( pMem ); |
||
618 | MemSetTypeFlag( pMem, MEM_Real ); |
||
619 | sqlite3VdbeIntegerAffinity( pMem ); |
||
620 | } |
||
621 | } |
||
622 | else if ( 0 == sqlite3Atoi64( pMem.z, ref pMem.u.i, pMem.n, pMem.enc ) ) |
||
623 | { |
||
624 | MemSetTypeFlag( pMem, MEM_Int ); |
||
625 | } |
||
626 | else |
||
627 | { |
||
628 | pMem.r = sqlite3VdbeRealValue( pMem ); |
||
629 | MemSetTypeFlag( pMem, MEM_Real ); |
||
630 | sqlite3VdbeIntegerAffinity( pMem ); |
||
631 | } |
||
632 | } |
||
633 | Debug.Assert( ( pMem.flags & ( MEM_Int | MEM_Real | MEM_Null ) ) != 0 ); |
||
634 | pMem.flags = (ushort)( pMem.flags & ~( MEM_Str | MEM_Blob ) ); |
||
635 | return SQLITE_OK; |
||
636 | } |
||
637 | |||
638 | #if !SQLITE_OMIT_FLOATING_POINT |
||
639 | /* |
||
640 | ** Delete any previous value and set the value stored in pMem to NULL. |
||
641 | */ |
||
642 | static void sqlite3VdbeMemSetNull( Mem pMem ) |
||
643 | { |
||
644 | if ( ( pMem.flags & MEM_Frame ) != 0 ) |
||
645 | { |
||
646 | VdbeFrame pFrame = pMem.u.pFrame; |
||
647 | pFrame.pParent = pFrame.v.pDelFrame; |
||
648 | pFrame.v.pDelFrame = pFrame; |
||
649 | } |
||
650 | if ( ( pMem.flags & MEM_RowSet ) != 0 ) |
||
651 | { |
||
652 | sqlite3RowSetClear( pMem.u.pRowSet ); |
||
653 | } |
||
654 | MemSetTypeFlag( pMem, MEM_Null ); |
||
655 | sqlite3_free( ref pMem.zBLOB ); |
||
656 | pMem.z = null; |
||
657 | pMem.type = SQLITE_NULL; |
||
658 | } |
||
659 | #endif |
||
660 | |||
661 | /* |
||
662 | ** Delete any previous value and set the value to be a BLOB of length |
||
663 | ** n containing all zeros. |
||
664 | */ |
||
665 | static void sqlite3VdbeMemSetZeroBlob( Mem pMem, int n ) |
||
666 | { |
||
667 | sqlite3VdbeMemRelease( pMem ); |
||
668 | pMem.flags = MEM_Blob | MEM_Zero; |
||
669 | pMem.type = SQLITE_BLOB; |
||
670 | pMem.n = 0; |
||
671 | if ( n < 0 ) |
||
672 | n = 0; |
||
673 | pMem.u.nZero = n; |
||
674 | pMem.enc = SQLITE_UTF8; |
||
675 | #if SQLITE_OMIT_INCRBLOB |
||
676 | sqlite3VdbeMemGrow( pMem, n, 0 ); |
||
677 | //if( pMem.z!= null ){ |
||
678 | pMem.n = n; |
||
679 | pMem.z = null;//memset(pMem.z, 0, n); |
||
680 | pMem.zBLOB = sqlite3Malloc( n ); |
||
681 | //} |
||
682 | #endif |
||
683 | } |
||
684 | |||
685 | /* |
||
686 | ** Delete any previous value and set the value stored in pMem to val, |
||
687 | ** manifest type INTEGER. |
||
688 | */ |
||
689 | static void sqlite3VdbeMemSetInt64( Mem pMem, i64 val ) |
||
690 | { |
||
691 | sqlite3VdbeMemRelease( pMem ); |
||
692 | pMem.u.i = val; |
||
693 | pMem.flags = MEM_Int; |
||
694 | pMem.type = SQLITE_INTEGER; |
||
695 | } |
||
696 | |||
697 | /* |
||
698 | ** Delete any previous value and set the value stored in pMem to val, |
||
699 | ** manifest type REAL. |
||
700 | */ |
||
701 | static void sqlite3VdbeMemSetDouble( Mem pMem, double val ) |
||
702 | { |
||
703 | if ( sqlite3IsNaN( val ) ) |
||
704 | { |
||
705 | sqlite3VdbeMemSetNull( pMem ); |
||
706 | } |
||
707 | else |
||
708 | { |
||
709 | sqlite3VdbeMemRelease( pMem ); |
||
710 | pMem.r = val; |
||
711 | pMem.flags = MEM_Real; |
||
712 | pMem.type = SQLITE_FLOAT; |
||
713 | } |
||
714 | } |
||
715 | |||
716 | /* |
||
717 | ** Delete any previous value and set the value of pMem to be an |
||
718 | ** empty boolean index. |
||
719 | */ |
||
720 | static void sqlite3VdbeMemSetRowSet( Mem pMem ) |
||
721 | { |
||
722 | sqlite3 db = pMem.db; |
||
723 | Debug.Assert( db != null ); |
||
724 | Debug.Assert( ( pMem.flags & MEM_RowSet ) == 0 ); |
||
725 | sqlite3VdbeMemRelease( pMem ); |
||
726 | //pMem.zMalloc = sqlite3DbMallocRaw( db, 64 ); |
||
727 | //if ( db.mallocFailed != 0 ) |
||
728 | //{ |
||
729 | // pMem.flags = MEM_Null; |
||
730 | //} |
||
731 | //else |
||
732 | { |
||
733 | //Debug.Assert( pMem.zMalloc ); |
||
734 | pMem.u.pRowSet = new RowSet( db, 5 );// sqlite3RowSetInit( db, pMem.zMalloc, |
||
735 | // sqlite3DbMallocSize( db, pMem.zMalloc ) ); |
||
736 | Debug.Assert( pMem.u.pRowSet != null ); |
||
737 | pMem.flags = MEM_RowSet; |
||
738 | } |
||
739 | } |
||
740 | |||
741 | /* |
||
742 | ** Return true if the Mem object contains a TEXT or BLOB that is |
||
743 | ** too large - whose size exceeds p.db.aLimit[SQLITE_LIMIT_LENGTH]. |
||
744 | */ |
||
745 | static bool sqlite3VdbeMemTooBig( Mem p ) |
||
746 | { |
||
747 | //Debug.Assert( p.db != null ); |
||
748 | if ( ( p.flags & ( MEM_Str | MEM_Blob ) ) != 0 ) |
||
749 | { |
||
750 | int n = p.n; |
||
751 | if ( ( p.flags & MEM_Zero ) != 0 ) |
||
752 | { |
||
753 | n += p.u.nZero; |
||
754 | } |
||
755 | return n > p.db.aLimit[SQLITE_LIMIT_LENGTH]; |
||
756 | } |
||
757 | return false; |
||
758 | } |
||
759 | |||
760 | #if SQLITE_DEBUG |
||
761 | /* |
||
762 | ** This routine prepares a memory cell for modification by breaking |
||
763 | ** its link to a shallow copy and by marking any current shallow |
||
764 | ** copies of this cell as invalid. |
||
765 | ** |
||
766 | ** This is used for testing and debugging only - to make sure shallow |
||
767 | ** copies are not misused. |
||
768 | */ |
||
769 | static void sqlite3VdbeMemPrepareToChange( Vdbe pVdbe, Mem pMem ) |
||
770 | { |
||
771 | int i; |
||
772 | Mem pX; |
||
773 | for ( i = 1; i <= pVdbe.nMem; i++ ) |
||
774 | { |
||
775 | pX = pVdbe.aMem[i]; |
||
776 | if ( pX.pScopyFrom == pMem ) |
||
777 | { |
||
778 | pX.flags |= MEM_Invalid; |
||
779 | pX.pScopyFrom = null; |
||
780 | } |
||
781 | } |
||
782 | pMem.pScopyFrom = null; |
||
783 | } |
||
784 | #endif //* SQLITE_DEBUG */ |
||
785 | |||
786 | /* |
||
787 | ** Size of struct Mem not including the Mem.zMalloc member. |
||
788 | */ |
||
789 | //#define MEMCELLSIZE (size_t)(&(((Mem *)0).zMalloc)) |
||
790 | |||
791 | /* |
||
792 | ** Make an shallow copy of pFrom into pTo. Prior contents of |
||
793 | ** pTo are freed. The pFrom.z field is not duplicated. If |
||
794 | ** pFrom.z is used, then pTo.z points to the same thing as pFrom.z |
||
795 | ** and flags gets srcType (either MEM_Ephem or MEM_Static). |
||
796 | */ |
||
797 | static void sqlite3VdbeMemShallowCopy( Mem pTo, Mem pFrom, int srcType ) |
||
798 | { |
||
799 | Debug.Assert( ( pFrom.flags & MEM_RowSet ) == 0 ); |
||
800 | sqlite3VdbeMemReleaseExternal( pTo ); |
||
801 | pFrom.CopyTo( ref pTo );// memcpy(pTo, pFrom, MEMCELLSIZE); |
||
802 | pTo.xDel = null; |
||
803 | if ( ( pFrom.flags & MEM_Static ) != 0 ) |
||
804 | { |
||
805 | pTo.flags = (u16)( pFrom.flags & ~( MEM_Dyn | MEM_Static | MEM_Ephem ) ); |
||
806 | Debug.Assert( srcType == MEM_Ephem || srcType == MEM_Static ); |
||
807 | pTo.flags |= (u16)srcType; |
||
808 | } |
||
809 | } |
||
810 | |||
811 | /* |
||
812 | ** Make a full copy of pFrom into pTo. Prior contents of pTo are |
||
813 | ** freed before the copy is made. |
||
814 | */ |
||
815 | static int sqlite3VdbeMemCopy( Mem pTo, Mem pFrom ) |
||
816 | { |
||
817 | int rc = SQLITE_OK; |
||
818 | |||
819 | Debug.Assert( ( pFrom.flags & MEM_RowSet ) == 0 ); |
||
820 | sqlite3VdbeMemReleaseExternal( pTo ); |
||
821 | pFrom.CopyTo( ref pTo );// memcpy(pTo, pFrom, MEMCELLSIZE); |
||
822 | pTo.flags = (u16)( pTo.flags & ~MEM_Dyn ); |
||
823 | |||
824 | if ( ( pTo.flags & ( MEM_Str | MEM_Blob ) ) != 0 ) |
||
825 | { |
||
826 | if ( 0 == ( pFrom.flags & MEM_Static ) ) |
||
827 | { |
||
828 | pTo.flags |= MEM_Ephem; |
||
829 | rc = sqlite3VdbeMemMakeWriteable( pTo ); |
||
830 | } |
||
831 | } |
||
832 | |||
833 | return rc; |
||
834 | } |
||
835 | |||
836 | /* |
||
837 | ** Transfer the contents of pFrom to pTo. Any existing value in pTo is |
||
838 | ** freed. If pFrom contains ephemeral data, a copy is made. |
||
839 | ** |
||
840 | ** pFrom contains an SQL NULL when this routine returns. |
||
841 | */ |
||
842 | static void sqlite3VdbeMemMove( Mem pTo, Mem pFrom ) |
||
843 | { |
||
844 | Debug.Assert( pFrom.db == null || sqlite3_mutex_held( pFrom.db.mutex ) ); |
||
845 | Debug.Assert( pTo.db == null || sqlite3_mutex_held( pTo.db.mutex ) ); |
||
846 | Debug.Assert( pFrom.db == null || pTo.db == null || pFrom.db == pTo.db ); |
||
847 | sqlite3VdbeMemRelease( pTo ); |
||
848 | pFrom.CopyTo( ref pTo );// memcpy(pTo, pFrom, Mem).Length; |
||
849 | pFrom.flags = MEM_Null; |
||
850 | pFrom.xDel = null; |
||
851 | pFrom.z = null; |
||
852 | sqlite3_free( ref pFrom.zBLOB ); //pFrom.zMalloc=0; |
||
853 | } |
||
854 | |||
855 | /* |
||
856 | ** Change the value of a Mem to be a string or a BLOB. |
||
857 | ** |
||
858 | ** The memory management strategy depends on the value of the xDel |
||
859 | ** parameter. If the value passed is SQLITE_TRANSIENT, then the |
||
860 | ** string is copied into a (possibly existing) buffer managed by the |
||
861 | ** Mem structure. Otherwise, any existing buffer is freed and the |
||
862 | ** pointer copied. |
||
863 | ** |
||
864 | ** If the string is too large (if it exceeds the SQLITE_LIMIT_LENGTH |
||
865 | ** size limit) then no memory allocation occurs. If the string can be |
||
866 | ** stored without allocating memory, then it is. If a memory allocation |
||
867 | ** is required to store the string, then value of pMem is unchanged. In |
||
868 | ** either case, SQLITE_TOOBIG is returned. |
||
869 | */ |
||
870 | static int sqlite3VdbeMemSetBlob( |
||
871 | Mem pMem, /* Memory cell to set to string value */ |
||
872 | byte[] zBlob, /* Blob pointer */ |
||
873 | int n, /* Bytes in Blob */ |
||
874 | u8 enc, /* 0 for BLOBs */ |
||
875 | dxDel xDel /* Destructor function */ |
||
876 | ) |
||
877 | { |
||
878 | return sqlite3VdbeMemSetBlob( pMem, zBlob, 0, n >= 0 ? n : zBlob.Length, enc, xDel ); |
||
879 | } // Call w/o offset |
||
880 | |||
881 | static int sqlite3VdbeMemSetBlob( |
||
882 | Mem pMem, /* Memory cell to set to string value */ |
||
883 | byte[] zBlob, /* Blob pointer */ |
||
884 | int offset, /* offset into string */ |
||
885 | int n, /* Bytes in string, or negative */ |
||
886 | u8 enc, /* Encoding of z. 0 for BLOBs */ |
||
887 | dxDel xDel//)(void*)/* Destructor function */ |
||
888 | ) |
||
889 | { |
||
890 | int nByte = n; /* New value for pMem->n */ |
||
891 | int iLimit; /* Maximum allowed string or blob size */ |
||
892 | |||
893 | Debug.Assert( pMem.db == null || sqlite3_mutex_held( pMem.db.mutex ) ); |
||
894 | Debug.Assert( ( pMem.flags & MEM_RowSet ) == 0 ); |
||
895 | |||
896 | /* If zBlob is a NULL pointer, set pMem to contain an SQL NULL. */ |
||
897 | if ( zBlob == null || zBlob.Length < offset ) |
||
898 | { |
||
899 | sqlite3VdbeMemSetNull( pMem ); |
||
900 | return SQLITE_OK; |
||
901 | } |
||
902 | |||
903 | if ( pMem.db != null ) |
||
904 | { |
||
905 | iLimit = pMem.db.aLimit[SQLITE_LIMIT_LENGTH]; |
||
906 | } |
||
907 | else |
||
908 | { |
||
909 | iLimit = SQLITE_MAX_LENGTH; |
||
910 | } |
||
911 | if ( nByte < 0 ) |
||
912 | { |
||
913 | Debug.Assert( enc != 0 ); |
||
914 | if ( enc == SQLITE_UTF8 ) |
||
915 | { |
||
916 | for ( nByte = 0; nByte <= iLimit && nByte < zBlob.Length - offset && zBlob[offset + nByte] != 0; nByte++ ) |
||
917 | { |
||
918 | } |
||
919 | } |
||
920 | else |
||
921 | { |
||
922 | for ( nByte = 0; nByte <= iLimit && zBlob[nByte + offset] != 0 || zBlob[offset + nByte + 1] != 0; nByte += 2 ) |
||
923 | { |
||
924 | } |
||
925 | } |
||
926 | } |
||
927 | |||
928 | /* The following block sets the new values of Mem.z and Mem.xDel. It |
||
929 | ** also sets a flag in local variable "flags" to indicate the memory |
||
930 | ** management (one of MEM_Dyn or MEM_Static). |
||
931 | */ |
||
932 | Debug.Assert( enc == 0 ); |
||
933 | { |
||
934 | pMem.z = null; |
||
935 | pMem.zBLOB = sqlite3Malloc( n ); |
||
936 | Buffer.BlockCopy( zBlob, offset, pMem.zBLOB, 0, n ); |
||
937 | } |
||
938 | pMem.n = nByte; |
||
939 | pMem.flags = MEM_Blob | MEM_Term; |
||
940 | pMem.enc = ( enc == 0 ? SQLITE_UTF8 : enc ); |
||
941 | pMem.type = ( enc == 0 ? SQLITE_BLOB : SQLITE_TEXT ); |
||
942 | |||
943 | if ( nByte > iLimit ) |
||
944 | { |
||
945 | return SQLITE_TOOBIG; |
||
946 | } |
||
947 | |||
948 | return SQLITE_OK; |
||
949 | } |
||
950 | |||
951 | static int sqlite3VdbeMemSetStr( |
||
952 | Mem pMem, /* Memory cell to set to string value */ |
||
953 | string z, /* String pointer */ |
||
954 | int n, /* Bytes in string, or negative */ |
||
955 | u8 enc, /* Encoding of z. 0 for BLOBs */ |
||
956 | dxDel xDel /* Destructor function */ |
||
957 | ) |
||
958 | { |
||
959 | return sqlite3VdbeMemSetStr( pMem, z, 0, n, enc, xDel ); |
||
960 | } // Call w/o offset |
||
961 | |||
962 | static int sqlite3VdbeMemSetStr( |
||
963 | Mem pMem, /* Memory cell to set to string value */ |
||
964 | string z, /* String pointer */ |
||
965 | int offset, /* offset into string */ |
||
966 | int n, /* Bytes in string, or negative */ |
||
967 | u8 enc, /* Encoding of z. 0 for BLOBs */ |
||
968 | dxDel xDel//)(void*)/* Destructor function */ |
||
969 | ) |
||
970 | { |
||
971 | int nByte = n; /* New value for pMem->n */ |
||
972 | int iLimit; /* Maximum allowed string or blob size */ |
||
973 | u16 flags = 0; /* New value for pMem->flags */ |
||
974 | |||
975 | Debug.Assert( pMem.db == null || sqlite3_mutex_held( pMem.db.mutex ) ); |
||
976 | Debug.Assert( ( pMem.flags & MEM_RowSet ) == 0 ); |
||
977 | |||
978 | /* If z is a NULL pointer, set pMem to contain an SQL NULL. */ |
||
979 | if ( z == null || z.Length < offset ) |
||
980 | { |
||
981 | sqlite3VdbeMemSetNull( pMem ); |
||
982 | return SQLITE_OK; |
||
983 | } |
||
984 | |||
985 | if ( pMem.db != null ) |
||
986 | { |
||
987 | iLimit = pMem.db.aLimit[SQLITE_LIMIT_LENGTH]; |
||
988 | } |
||
989 | else |
||
990 | { |
||
991 | iLimit = SQLITE_MAX_LENGTH; |
||
992 | } |
||
993 | flags = (u16)( enc == 0 ? MEM_Blob : MEM_Str ); |
||
994 | if ( nByte < 0 ) |
||
995 | { |
||
996 | Debug.Assert( enc != 0 ); |
||
997 | if ( enc == SQLITE_UTF8 ) |
||
998 | { |
||
999 | for ( nByte = 0; nByte <= iLimit && nByte < z.Length - offset && z[offset + nByte] != 0; nByte++ ) |
||
1000 | { |
||
1001 | } |
||
1002 | } |
||
1003 | else |
||
1004 | { |
||
1005 | for ( nByte = 0; nByte <= iLimit && z[nByte + offset] != 0 || z[offset + nByte + 1] != 0; nByte += 2 ) |
||
1006 | { |
||
1007 | } |
||
1008 | } |
||
1009 | flags |= MEM_Term; |
||
1010 | } |
||
1011 | |||
1012 | /* The following block sets the new values of Mem.z and Mem.xDel. It |
||
1013 | ** also sets a flag in local variable "flags" to indicate the memory |
||
1014 | ** management (one of MEM_Dyn or MEM_Static). |
||
1015 | */ |
||
1016 | if ( xDel == SQLITE_TRANSIENT ) |
||
1017 | { |
||
1018 | u32 nAlloc = (u32)nByte; |
||
1019 | if ( ( flags & MEM_Term ) != 0 ) |
||
1020 | { |
||
1021 | nAlloc += (u32)( enc == SQLITE_UTF8 ? 1 : 2 ); |
||
1022 | } |
||
1023 | if ( nByte > iLimit ) |
||
1024 | { |
||
1025 | return SQLITE_TOOBIG; |
||
1026 | } |
||
1027 | if ( sqlite3VdbeMemGrow( pMem, (int)nAlloc, 0 ) != 0 ) |
||
1028 | { |
||
1029 | return SQLITE_NOMEM; |
||
1030 | } |
||
1031 | //if ( nAlloc < z.Length ) |
||
1032 | //pMem.z = new byte[nAlloc]; Buffer.BlockCopy( z, 0, pMem.z, 0, (int)nAlloc ); } |
||
1033 | //else |
||
1034 | if ( enc == 0 ) |
||
1035 | { |
||
1036 | pMem.z = null; |
||
1037 | pMem.zBLOB = sqlite3Malloc( n ); |
||
1038 | for ( int i = 0; i < n && i < z.Length - offset; i++ ) |
||
1039 | pMem.zBLOB[i] = (byte)z[offset + i]; |
||
1040 | } |
||
1041 | else |
||
1042 | { |
||
1043 | pMem.z = n > 0 && z.Length - offset > n ? z.Substring( offset, n ) : z.Substring( offset );//memcpy(pMem.z, z, nAlloc); |
||
1044 | sqlite3_free( ref pMem.zBLOB ); |
||
1045 | } |
||
1046 | } |
||
1047 | else if ( xDel == SQLITE_DYNAMIC ) |
||
1048 | { |
||
1049 | sqlite3VdbeMemRelease( pMem ); |
||
1050 | //pMem.zMalloc = pMem.z = (char*)z; |
||
1051 | if ( enc == 0 ) |
||
1052 | { |
||
1053 | pMem.z = null; |
||
1054 | if ( pMem.zBLOB != null ) |
||
1055 | sqlite3_free( ref pMem.zBLOB ); |
||
1056 | pMem.zBLOB = Encoding.UTF8.GetBytes( offset == 0 ? z : z.Length + offset < n ? z.Substring( offset, n ) : z.Substring( offset ) ); |
||
1057 | } |
||
1058 | else |
||
1059 | { |
||
1060 | pMem.z = n > 0 && z.Length - offset > n ? z.Substring( offset, n ) : z.Substring( offset );//memcpy(pMem.z, z, nAlloc); |
||
1061 | sqlite3_free( ref pMem.zBLOB ); |
||
1062 | } |
||
1063 | pMem.xDel = null; |
||
1064 | } |
||
1065 | else |
||
1066 | { |
||
1067 | sqlite3VdbeMemRelease( pMem ); |
||
1068 | if ( enc == 0 ) |
||
1069 | { |
||
1070 | pMem.z = null; |
||
1071 | if ( pMem.zBLOB != null ) |
||
1072 | sqlite3_free( ref pMem.zBLOB ); |
||
1073 | pMem.zBLOB = Encoding.UTF8.GetBytes( offset == 0 ? z : z.Length + offset < n ? z.Substring( offset, n ) : z.Substring( offset ) ); |
||
1074 | } |
||
1075 | else |
||
1076 | { |
||
1077 | pMem.z = n > 0 && z.Length - offset > n ? z.Substring( offset, n ) : z.Substring( offset );//memcpy(pMem.z, z, nAlloc); |
||
1078 | sqlite3_free( ref pMem.zBLOB ); |
||
1079 | } |
||
1080 | pMem.xDel = xDel; |
||
1081 | flags |= (u16)( ( xDel == SQLITE_STATIC ) ? MEM_Static : MEM_Dyn ); |
||
1082 | } |
||
1083 | pMem.n = nByte; |
||
1084 | pMem.flags = flags; |
||
1085 | pMem.enc = ( enc == 0 ? SQLITE_UTF8 : enc ); |
||
1086 | pMem.type = ( enc == 0 ? SQLITE_BLOB : SQLITE_TEXT ); |
||
1087 | |||
1088 | #if !SQLITE_OMIT_UTF16 |
||
1089 | if( pMem.enc!=SQLITE_UTF8 && sqlite3VdbeMemHandleBom(pMem)!=0 ){ |
||
1090 | return SQLITE_NOMEM; |
||
1091 | } |
||
1092 | #endif |
||
1093 | |||
1094 | if ( nByte > iLimit ) |
||
1095 | { |
||
1096 | return SQLITE_TOOBIG; |
||
1097 | } |
||
1098 | |||
1099 | return SQLITE_OK; |
||
1100 | } |
||
1101 | |||
1102 | /* |
||
1103 | ** Compare the values contained by the two memory cells, returning |
||
1104 | ** negative, zero or positive if pMem1 is less than, equal to, or greater |
||
1105 | ** than pMem2. Sorting order is NULL's first, followed by numbers (integers |
||
1106 | ** and reals) sorted numerically, followed by text ordered by the collating |
||
1107 | ** sequence pColl and finally blob's ordered by memcmp(). |
||
1108 | ** |
||
1109 | ** Two NULL values are considered equal by this function. |
||
1110 | */ |
||
1111 | static int sqlite3MemCompare( Mem pMem1, Mem pMem2, CollSeq pColl ) |
||
1112 | { |
||
1113 | int rc; |
||
1114 | int f1, f2; |
||
1115 | int combined_flags; |
||
1116 | |||
1117 | f1 = pMem1.flags; |
||
1118 | f2 = pMem2.flags; |
||
1119 | combined_flags = f1 | f2; |
||
1120 | Debug.Assert( ( combined_flags & MEM_RowSet ) == 0 ); |
||
1121 | |||
1122 | /* If one value is NULL, it is less than the other. If both values |
||
1123 | ** are NULL, return 0. |
||
1124 | */ |
||
1125 | if ( ( combined_flags & MEM_Null ) != 0 ) |
||
1126 | { |
||
1127 | return ( f2 & MEM_Null ) - ( f1 & MEM_Null ); |
||
1128 | } |
||
1129 | |||
1130 | /* If one value is a number and the other is not, the number is less. |
||
1131 | ** If both are numbers, compare as reals if one is a real, or as integers |
||
1132 | ** if both values are integers. |
||
1133 | */ |
||
1134 | if ( ( combined_flags & ( MEM_Int | MEM_Real ) ) != 0 ) |
||
1135 | { |
||
1136 | if ( ( f1 & ( MEM_Int | MEM_Real ) ) == 0 ) |
||
1137 | { |
||
1138 | return 1; |
||
1139 | } |
||
1140 | if ( ( f2 & ( MEM_Int | MEM_Real ) ) == 0 ) |
||
1141 | { |
||
1142 | return -1; |
||
1143 | } |
||
1144 | if ( ( f1 & f2 & MEM_Int ) == 0 ) |
||
1145 | { |
||
1146 | double r1, r2; |
||
1147 | if ( ( f1 & MEM_Real ) == 0 ) |
||
1148 | { |
||
1149 | r1 = (double)pMem1.u.i; |
||
1150 | } |
||
1151 | else |
||
1152 | { |
||
1153 | r1 = pMem1.r; |
||
1154 | } |
||
1155 | if ( ( f2 & MEM_Real ) == 0 ) |
||
1156 | { |
||
1157 | r2 = (double)pMem2.u.i; |
||
1158 | } |
||
1159 | else |
||
1160 | { |
||
1161 | r2 = pMem2.r; |
||
1162 | } |
||
1163 | if ( r1 < r2 ) |
||
1164 | return -1; |
||
1165 | if ( r1 > r2 ) |
||
1166 | return 1; |
||
1167 | return 0; |
||
1168 | } |
||
1169 | else |
||
1170 | { |
||
1171 | Debug.Assert( ( f1 & MEM_Int ) != 0 ); |
||
1172 | Debug.Assert( ( f2 & MEM_Int ) != 0 ); |
||
1173 | if ( pMem1.u.i < pMem2.u.i ) |
||
1174 | return -1; |
||
1175 | if ( pMem1.u.i > pMem2.u.i ) |
||
1176 | return 1; |
||
1177 | return 0; |
||
1178 | } |
||
1179 | } |
||
1180 | |||
1181 | /* If one value is a string and the other is a blob, the string is less. |
||
1182 | ** If both are strings, compare using the collating functions. |
||
1183 | */ |
||
1184 | if ( ( combined_flags & MEM_Str ) != 0 ) |
||
1185 | { |
||
1186 | if ( ( f1 & MEM_Str ) == 0 ) |
||
1187 | { |
||
1188 | return 1; |
||
1189 | } |
||
1190 | if ( ( f2 & MEM_Str ) == 0 ) |
||
1191 | { |
||
1192 | return -1; |
||
1193 | } |
||
1194 | |||
1195 | Debug.Assert( pMem1.enc == pMem2.enc ); |
||
1196 | Debug.Assert( pMem1.enc == SQLITE_UTF8 || |
||
1197 | pMem1.enc == SQLITE_UTF16LE || pMem1.enc == SQLITE_UTF16BE ); |
||
1198 | |||
1199 | /* The collation sequence must be defined at this point, even if |
||
1200 | ** the user deletes the collation sequence after the vdbe program is |
||
1201 | ** compiled (this was not always the case). |
||
1202 | */ |
||
1203 | Debug.Assert( pColl == null || pColl.xCmp != null ); |
||
1204 | |||
1205 | if ( pColl != null ) |
||
1206 | { |
||
1207 | if ( pMem1.enc == pColl.enc ) |
||
1208 | { |
||
1209 | /* The strings are already in the correct encoding. Call the |
||
1210 | ** comparison function directly */ |
||
1211 | return pColl.xCmp( pColl.pUser, pMem1.n, pMem1.z, pMem2.n, pMem2.z ); |
||
1212 | } |
||
1213 | else |
||
1214 | { |
||
1215 | string v1, v2; |
||
1216 | int n1, n2; |
||
1217 | Mem c1 = null; |
||
1218 | Mem c2 = null; |
||
1219 | |||
1220 | c1 = sqlite3Malloc( c1 );// memset( &c1, 0, sizeof( c1 ) ); |
||
1221 | c2 = sqlite3Malloc( c2 );// memset( &c2, 0, sizeof( c2 ) ); |
||
1222 | |||
1223 | sqlite3VdbeMemShallowCopy( c1, pMem1, MEM_Ephem ); |
||
1224 | sqlite3VdbeMemShallowCopy( c2, pMem2, MEM_Ephem ); |
||
1225 | v1 = sqlite3ValueText( (sqlite3_value)c1, pColl.enc ); |
||
1226 | n1 = v1 == null ? 0 : c1.n; |
||
1227 | v2 = sqlite3ValueText( (sqlite3_value)c2, pColl.enc ); |
||
1228 | n2 = v2 == null ? 0 : c2.n; |
||
1229 | rc = pColl.xCmp( pColl.pUser, n1, v1, n2, v2 ); |
||
1230 | sqlite3VdbeMemRelease( c1 ); |
||
1231 | sqlite3VdbeMemRelease( c2 ); |
||
1232 | return rc; |
||
1233 | } |
||
1234 | } |
||
1235 | /* If a NULL pointer was passed as the collate function, fall through |
||
1236 | ** to the blob case and use memcmp(). */ |
||
1237 | } |
||
1238 | |||
1239 | /* Both values must be blobs. Compare using memcmp(). */ |
||
1240 | if ( ( pMem1.flags & MEM_Blob ) != 0 ) |
||
1241 | if ( pMem1.zBLOB != null ) |
||
1242 | rc = memcmp( pMem1.zBLOB, pMem2.zBLOB, ( pMem1.n > pMem2.n ) ? pMem2.n : pMem1.n ); |
||
1243 | else |
||
1244 | rc = memcmp( pMem1.z, pMem2.zBLOB, ( pMem1.n > pMem2.n ) ? pMem2.n : pMem1.n ); |
||
1245 | else |
||
1246 | rc = memcmp( pMem1.z, pMem2.z, ( pMem1.n > pMem2.n ) ? pMem2.n : pMem1.n ); |
||
1247 | if ( rc == 0 ) |
||
1248 | { |
||
1249 | rc = pMem1.n - pMem2.n; |
||
1250 | } |
||
1251 | return rc; |
||
1252 | } |
||
1253 | |||
1254 | /* |
||
1255 | ** Move data out of a btree key or data field and into a Mem structure. |
||
1256 | ** The data or key is taken from the entry that pCur is currently pointing |
||
1257 | ** to. offset and amt determine what portion of the data or key to retrieve. |
||
1258 | ** key is true to get the key or false to get data. The result is written |
||
1259 | ** into the pMem element. |
||
1260 | ** |
||
1261 | ** The pMem structure is assumed to be uninitialized. Any prior content |
||
1262 | ** is overwritten without being freed. |
||
1263 | ** |
||
1264 | ** If this routine fails for any reason (malloc returns NULL or unable |
||
1265 | ** to read from the disk) then the pMem is left in an inconsistent state. |
||
1266 | */ |
||
1267 | static int sqlite3VdbeMemFromBtree( |
||
1268 | BtCursor pCur, /* Cursor pointing at record to retrieve. */ |
||
1269 | int offset, /* Offset from the start of data to return bytes from. */ |
||
1270 | int amt, /* Number of bytes to return. */ |
||
1271 | bool key, /* If true, retrieve from the btree key, not data. */ |
||
1272 | Mem pMem /* OUT: Return data in this Mem structure. */ |
||
1273 | ) |
||
1274 | { |
||
1275 | byte[] zData; /* Data from the btree layer */ |
||
1276 | int available = 0; /* Number of bytes available on the local btree page */ |
||
1277 | int rc = SQLITE_OK; /* Return code */ |
||
1278 | |||
1279 | Debug.Assert( sqlite3BtreeCursorIsValid( pCur ) ); |
||
1280 | |||
1281 | /* Note: the calls to BtreeKeyFetch() and DataFetch() below assert() |
||
1282 | ** that both the BtShared and database handle mutexes are held. */ |
||
1283 | Debug.Assert( ( pMem.flags & MEM_RowSet ) == 0 ); |
||
1284 | int outOffset = -1; |
||
1285 | if ( key ) |
||
1286 | { |
||
1287 | zData = sqlite3BtreeKeyFetch( pCur, ref available, ref outOffset ); |
||
1288 | } |
||
1289 | else |
||
1290 | { |
||
1291 | zData = sqlite3BtreeDataFetch( pCur, ref available, ref outOffset ); |
||
1292 | } |
||
1293 | Debug.Assert( zData != null ); |
||
1294 | |||
1295 | if ( offset + amt <= available && ( pMem.flags & MEM_Dyn ) == 0 ) |
||
1296 | { |
||
1297 | sqlite3VdbeMemRelease( pMem ); |
||
1298 | pMem.zBLOB = sqlite3Malloc( amt ); |
||
1299 | Buffer.BlockCopy( zData, offset, pMem.zBLOB, 0, amt );//pMem.z = &zData[offset]; |
||
1300 | pMem.flags = MEM_Blob | MEM_Ephem; |
||
1301 | } |
||
1302 | else if ( SQLITE_OK == ( rc = sqlite3VdbeMemGrow( pMem, amt + 2, 0 ) ) ) |
||
1303 | { |
||
1304 | pMem.enc = 0; |
||
1305 | pMem.type = SQLITE_BLOB; |
||
1306 | pMem.z = null; |
||
1307 | pMem.zBLOB = sqlite3Malloc( amt ); |
||
1308 | pMem.flags = MEM_Blob | MEM_Dyn | MEM_Term; |
||
1309 | if ( key ) |
||
1310 | { |
||
1311 | rc = sqlite3BtreeKey( pCur, (u32)offset, (u32)amt, pMem.zBLOB ); |
||
1312 | } |
||
1313 | else |
||
1314 | { |
||
1315 | rc = sqlite3BtreeData( pCur, (u32)offset, (u32)amt, pMem.zBLOB );//pMem.z = pMem_z ; |
||
1316 | } |
||
1317 | //pMem.z[amt] = 0; |
||
1318 | //pMem.z[amt+1] = 0; |
||
1319 | if ( rc != SQLITE_OK ) |
||
1320 | { |
||
1321 | sqlite3VdbeMemRelease( pMem ); |
||
1322 | } |
||
1323 | } |
||
1324 | pMem.n = amt; |
||
1325 | sqlite3_free( ref zData ); |
||
1326 | |||
1327 | return rc; |
||
1328 | } |
||
1329 | |||
1330 | /* This function is only available internally, it is not part of the |
||
1331 | ** external API. It works in a similar way to sqlite3_value_text(), |
||
1332 | ** except the data returned is in the encoding specified by the second |
||
1333 | ** parameter, which must be one of SQLITE_UTF16BE, SQLITE_UTF16LE or |
||
1334 | ** SQLITE_UTF8. |
||
1335 | ** |
||
1336 | ** (2006-02-16:) The enc value can be or-ed with SQLITE_UTF16_ALIGNED. |
||
1337 | ** If that is the case, then the result must be aligned on an even byte |
||
1338 | ** boundary. |
||
1339 | */ |
||
1340 | static string sqlite3ValueText( sqlite3_value pVal, int enc ) |
||
1341 | { |
||
1342 | if ( pVal == null ) |
||
1343 | return null; |
||
1344 | |||
1345 | Debug.Assert( pVal.db == null || sqlite3_mutex_held( pVal.db.mutex ) ); |
||
1346 | Debug.Assert( ( enc & 3 ) == ( enc & ~SQLITE_UTF16_ALIGNED ) ); |
||
1347 | Debug.Assert( ( pVal.flags & MEM_RowSet ) == 0 ); |
||
1348 | |||
1349 | if ( ( pVal.flags & MEM_Null ) != 0 ) |
||
1350 | { |
||
1351 | return null; |
||
1352 | } |
||
1353 | Debug.Assert( ( MEM_Blob >> 3 ) == MEM_Str ); |
||
1354 | pVal.flags |= (u16)( ( pVal.flags & MEM_Blob ) >> 3 ); |
||
1355 | ////if ( ( pVal.flags & MEM_Zero ) != 0 ) |
||
1356 | //// sqlite3VdbeMemExpandBlob( pVal ); // expandBlob(pVal); |
||
1357 | if ( ( pVal.flags & MEM_Str ) != 0 ) |
||
1358 | { |
||
1359 | if ( sqlite3VdbeChangeEncoding( pVal, enc & ~SQLITE_UTF16_ALIGNED ) != SQLITE_OK ) |
||
1360 | { |
||
1361 | return null; // Encoding Error |
||
1362 | } |
||
1363 | if ( ( enc & SQLITE_UTF16_ALIGNED ) != 0 && 1 == ( 1 & ( pVal.z[0] ) ) ) //1==(1&SQLITE_PTR_TO_INT(pVal.z)) |
||
1364 | { |
||
1365 | Debug.Assert( ( pVal.flags & ( MEM_Ephem | MEM_Static ) ) != 0 ); |
||
1366 | if ( sqlite3VdbeMemMakeWriteable( pVal ) != SQLITE_OK ) |
||
1367 | { |
||
1368 | return null; |
||
1369 | } |
||
1370 | } |
||
1371 | sqlite3VdbeMemNulTerminate( pVal ); /* IMP: R-59893-45467 */ |
||
1372 | } |
||
1373 | else |
||
1374 | { |
||
1375 | Debug.Assert( ( pVal.flags & MEM_Blob ) == 0 ); |
||
1376 | sqlite3VdbeMemStringify( pVal, enc ); |
||
1377 | // assert( 0==(1&SQLITE_PTR_TO_INT(pVal->z)) ); |
||
1378 | } |
||
1379 | Debug.Assert( pVal.enc == ( enc & ~SQLITE_UTF16_ALIGNED ) || pVal.db == null |
||
1380 | //|| pVal.db.mallocFailed != 0 |
||
1381 | ); |
||
1382 | if ( pVal.enc == ( enc & ~SQLITE_UTF16_ALIGNED ) ) |
||
1383 | { |
||
1384 | return pVal.z; |
||
1385 | } |
||
1386 | else |
||
1387 | { |
||
1388 | return null; |
||
1389 | } |
||
1390 | } |
||
1391 | |||
1392 | /* |
||
1393 | ** Create a new sqlite3_value object. |
||
1394 | */ |
||
1395 | static sqlite3_value sqlite3ValueNew( sqlite3 db ) |
||
1396 | { |
||
1397 | Mem p = null; |
||
1398 | p = sqlite3DbMallocZero( db, p ); |
||
1399 | //if ( p != null ) |
||
1400 | //{ |
||
1401 | p.flags = MEM_Null; |
||
1402 | p.type = SQLITE_NULL; |
||
1403 | p.db = db; |
||
1404 | //} |
||
1405 | return p; |
||
1406 | } |
||
1407 | |||
1408 | /* |
||
1409 | ** Create a new sqlite3_value object, containing the value of pExpr. |
||
1410 | ** |
||
1411 | ** This only works for very simple expressions that consist of one constant |
||
1412 | ** token (i.e. "5", "5.1", "'a string'"). If the expression can |
||
1413 | ** be converted directly into a value, then the value is allocated and |
||
1414 | ** a pointer written to ppVal. The caller is responsible for deallocating |
||
1415 | ** the value by passing it to sqlite3ValueFree() later on. If the expression |
||
1416 | ** cannot be converted to a value, then ppVal is set to NULL. |
||
1417 | */ |
||
1418 | static int sqlite3ValueFromExpr( |
||
1419 | sqlite3 db, /* The database connection */ |
||
1420 | Expr pExpr, /* The expression to evaluate */ |
||
1421 | int enc, /* Encoding to use */ |
||
1422 | char affinity, /* Affinity to use */ |
||
1423 | ref sqlite3_value ppVal /* Write the new value here */ |
||
1424 | ) |
||
1425 | { |
||
1426 | int op; |
||
1427 | string zVal = string.Empty; |
||
1428 | sqlite3_value pVal = null; |
||
1429 | int negInt = 1; |
||
1430 | string zNeg = string.Empty; |
||
1431 | |||
1432 | if ( pExpr == null ) |
||
1433 | { |
||
1434 | ppVal = null; |
||
1435 | return SQLITE_OK; |
||
1436 | } |
||
1437 | op = pExpr.op; |
||
1438 | |||
1439 | /* op can only be TK_REGISTER if we have compiled with SQLITE_ENABLE_STAT2. |
||
1440 | ** The ifdef here is to enable us to achieve 100% branch test coverage even |
||
1441 | ** when SQLITE_ENABLE_STAT2 is omitted. |
||
1442 | */ |
||
1443 | #if SQLITE_ENABLE_STAT2 |
||
1444 | if ( op == TK_REGISTER ) |
||
1445 | op = pExpr.op2; |
||
1446 | #else |
||
1447 | if( NEVER(op==TK_REGISTER) ) op = pExpr.op2; |
||
1448 | #endif |
||
1449 | |||
1450 | /* Handle negative integers in a single step. This is needed in the |
||
1451 | ** case when the value is -9223372036854775808. |
||
1452 | */ |
||
1453 | if ( op == TK_UMINUS |
||
1454 | && ( pExpr.pLeft.op == TK_INTEGER || pExpr.pLeft.op == TK_FLOAT ) ) |
||
1455 | { |
||
1456 | pExpr = pExpr.pLeft; |
||
1457 | op = pExpr.op; |
||
1458 | negInt = -1; |
||
1459 | zNeg = "-"; |
||
1460 | } |
||
1461 | |||
1462 | if ( op == TK_STRING || op == TK_FLOAT || op == TK_INTEGER ) |
||
1463 | { |
||
1464 | pVal = sqlite3ValueNew( db ); |
||
1465 | if ( pVal == null ) |
||
1466 | goto no_mem; |
||
1467 | if ( ExprHasProperty( pExpr, EP_IntValue ) ) |
||
1468 | { |
||
1469 | sqlite3VdbeMemSetInt64( pVal, (i64)pExpr.u.iValue * negInt ); |
||
1470 | } |
||
1471 | else |
||
1472 | { |
||
1473 | zVal = sqlite3MPrintf( db, "%s%s", zNeg, pExpr.u.zToken ); |
||
1474 | //if ( zVal == null ) goto no_mem; |
||
1475 | sqlite3ValueSetStr( pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC ); |
||
1476 | if ( op == TK_FLOAT ) |
||
1477 | pVal.type = SQLITE_FLOAT; |
||
1478 | } |
||
1479 | if ( ( op == TK_INTEGER || op == TK_FLOAT ) && affinity == SQLITE_AFF_NONE ) |
||
1480 | { |
||
1481 | sqlite3ValueApplyAffinity( pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8 ); |
||
1482 | } |
||
1483 | else |
||
1484 | { |
||
1485 | sqlite3ValueApplyAffinity( pVal, affinity, SQLITE_UTF8 ); |
||
1486 | } |
||
1487 | if ( ( pVal.flags & ( MEM_Int | MEM_Real ) ) != 0 ) |
||
1488 | pVal.flags = (ushort)( pVal.flags & ~MEM_Str ); |
||
1489 | if ( enc != SQLITE_UTF8 ) |
||
1490 | { |
||
1491 | sqlite3VdbeChangeEncoding( pVal, enc ); |
||
1492 | } |
||
1493 | } |
||
1494 | if ( enc != SQLITE_UTF8 ) |
||
1495 | { |
||
1496 | sqlite3VdbeChangeEncoding( pVal, enc ); |
||
1497 | } |
||
1498 | else if ( op == TK_UMINUS ) |
||
1499 | { |
||
1500 | /* This branch happens for multiple negative signs. Ex: -(-5) */ |
||
1501 | if ( SQLITE_OK == sqlite3ValueFromExpr( db, pExpr.pLeft, enc, affinity, ref pVal ) ) |
||
1502 | { |
||
1503 | sqlite3VdbeMemNumerify( pVal ); |
||
1504 | if ( pVal.u.i == SMALLEST_INT64 ) |
||
1505 | { |
||
1506 | pVal.flags &= MEM_Int; |
||
1507 | pVal.flags |= MEM_Real; |
||
1508 | pVal.r = (double)LARGEST_INT64; |
||
1509 | } |
||
1510 | else |
||
1511 | { |
||
1512 | pVal.u.i = -pVal.u.i; |
||
1513 | } |
||
1514 | pVal.r = -pVal.r; |
||
1515 | sqlite3ValueApplyAffinity( pVal, affinity, enc ); |
||
1516 | } |
||
1517 | } |
||
1518 | else if ( op == TK_NULL ) |
||
1519 | { |
||
1520 | pVal = sqlite3ValueNew( db ); |
||
1521 | if ( pVal == null) |
||
1522 | goto no_mem; |
||
1523 | } |
||
1524 | #if !SQLITE_OMIT_BLOB_LITERAL |
||
1525 | else if ( op == TK_BLOB ) |
||
1526 | { |
||
1527 | int nVal; |
||
1528 | Debug.Assert( pExpr.u.zToken[0] == 'x' || pExpr.u.zToken[0] == 'X' ); |
||
1529 | Debug.Assert( pExpr.u.zToken[1] == '\'' ); |
||
1530 | pVal = sqlite3ValueNew( db ); |
||
1531 | if ( null == pVal ) |
||
1532 | goto no_mem; |
||
1533 | zVal = pExpr.u.zToken.Substring( 2 ); |
||
1534 | nVal = sqlite3Strlen30( zVal ) - 1; |
||
1535 | Debug.Assert( zVal[nVal] == '\'' ); |
||
1536 | byte[] blob = sqlite3HexToBlob( db, zVal, nVal ); |
||
1537 | sqlite3VdbeMemSetStr( pVal, Encoding.UTF8.GetString( blob, 0, blob.Length ), nVal / 2, 0, SQLITE_DYNAMIC ); |
||
1538 | } |
||
1539 | #endif |
||
1540 | |||
1541 | if ( pVal != null ) |
||
1542 | { |
||
1543 | sqlite3VdbeMemStoreType( pVal ); |
||
1544 | } |
||
1545 | |||
1546 | ppVal = pVal; |
||
1547 | return SQLITE_OK; |
||
1548 | |||
1549 | no_mem: |
||
1550 | //db.mallocFailed = 1; |
||
1551 | sqlite3DbFree( db, ref zVal ); |
||
1552 | pVal = null;// sqlite3ValueFree(pVal); |
||
1553 | ppVal = null; |
||
1554 | return SQLITE_NOMEM; |
||
1555 | } |
||
1556 | |||
1557 | /* |
||
1558 | ** Change the string value of an sqlite3_value object |
||
1559 | */ |
||
1560 | static void sqlite3ValueSetStr( |
||
1561 | sqlite3_value v, /* Value to be set */ |
||
1562 | int n, /* Length of string z */ |
||
1563 | string z, /* Text of the new string */ |
||
1564 | u8 enc, /* Encoding to use */ |
||
1565 | dxDel xDel//)(void*) /* Destructor for the string */ |
||
1566 | ) |
||
1567 | { |
||
1568 | if ( v != null ) |
||
1569 | sqlite3VdbeMemSetStr( v, z, n, enc, xDel ); |
||
1570 | } |
||
1571 | |||
1572 | /* |
||
1573 | ** Free an sqlite3_value object |
||
1574 | */ |
||
1575 | static void sqlite3ValueFree( ref sqlite3_value v ) |
||
1576 | { |
||
1577 | if ( v == null ) |
||
1578 | return; |
||
1579 | sqlite3VdbeMemRelease( v ); |
||
1580 | sqlite3DbFree( v.db, ref v ); |
||
1581 | } |
||
1582 | |||
1583 | /* |
||
1584 | ** Return the number of bytes in the sqlite3_value object assuming |
||
1585 | ** that it uses the encoding "enc" |
||
1586 | */ |
||
1587 | static int sqlite3ValueBytes( sqlite3_value pVal, int enc ) |
||
1588 | { |
||
1589 | Mem p = (Mem)pVal; |
||
1590 | if ( ( p.flags & MEM_Blob ) != 0 || sqlite3ValueText( pVal, enc ) != null ) |
||
1591 | { |
||
1592 | if ( ( p.flags & MEM_Zero ) != 0 ) |
||
1593 | { |
||
1594 | return p.n + p.u.nZero; |
||
1595 | } |
||
1596 | else |
||
1597 | { |
||
1598 | return p.z == null ? p.zBLOB.Length : p.n; |
||
1599 | } |
||
1600 | } |
||
1601 | return 0; |
||
1602 | } |
||
1603 | } |
||
1604 | } |