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