1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-08 14:02:16 +03:00

Allow CAST expressions and unary "+" operators to be used in the DEFAULT

argument of an ALTER TABLE ADD COLUMN and to be understand on the RHS of
range constraints interpreted by STAT3/4.  This involves a rewrite of the
implementation of the CAST operator.

FossilOrigin-Name: 91d8a8d0b792ea5c4fe68fd9caaf3345eddea486
This commit is contained in:
drh
2014-08-25 20:11:52 +00:00
parent f741e0491e
commit 4169e430a2
7 changed files with 84 additions and 117 deletions

View File

@@ -1768,106 +1768,30 @@ case OP_RealAffinity: { /* in1 */
#endif
#ifndef SQLITE_OMIT_CAST
/* Opcode: ToText P1 * * * *
/* Opcode: Cast P1 P2 * * *
**
** Force the value in register P1 to be text.
** If the value is numeric, convert it to a string using the
** equivalent of sprintf(). Blob values are unchanged and
** are afterwards simply interpreted as text.
** Force the value in register P1 to be the type defined by P2.
**
** <ul>
** <li value="97"> TEXT
** <li value="98"> BLOB
** <li value="99"> NUMERIC
** <li value="100"> INTEGER
** <li value="101"> REAL
** </ul>
**
** A NULL value is not changed by this routine. It remains NULL.
*/
case OP_ToText: { /* same as TK_TO_TEXT, in1 */
case OP_Cast: { /* in1 */
pIn1 = &aMem[pOp->p1];
memAboutToChange(p, pIn1);
if( pIn1->flags & MEM_Null ) break;
assert( MEM_Str==(MEM_Blob>>3) );
pIn1->flags |= (pIn1->flags&MEM_Blob)>>3;
applyAffinity(pIn1, SQLITE_AFF_TEXT, encoding);
rc = ExpandBlob(pIn1);
assert( pIn1->flags & MEM_Str || db->mallocFailed );
pIn1->flags &= ~(MEM_Int|MEM_Real|MEM_Blob|MEM_Zero);
sqlite3VdbeMemCast(pIn1, pOp->p2, encoding);
UPDATE_MAX_BLOBSIZE(pIn1);
break;
}
/* Opcode: ToBlob P1 * * * *
**
** Force the value in register P1 to be a BLOB.
** If the value is numeric, convert it to a string first.
** Strings are simply reinterpreted as blobs with no change
** to the underlying data.
**
** A NULL value is not changed by this routine. It remains NULL.
*/
case OP_ToBlob: { /* same as TK_TO_BLOB, in1 */
pIn1 = &aMem[pOp->p1];
if( pIn1->flags & MEM_Null ) break;
if( (pIn1->flags & MEM_Blob)==0 ){
applyAffinity(pIn1, SQLITE_AFF_TEXT, encoding);
assert( pIn1->flags & MEM_Str || db->mallocFailed );
MemSetTypeFlag(pIn1, MEM_Blob);
}else{
pIn1->flags &= ~(MEM_TypeMask&~MEM_Blob);
}
UPDATE_MAX_BLOBSIZE(pIn1);
break;
}
/* Opcode: ToNumeric P1 * * * *
**
** Force the value in register P1 to be numeric (either an
** integer or a floating-point number.)
** If the value is text or blob, try to convert it to an using the
** equivalent of atoi() or atof() and store 0 if no such conversion
** is possible.
**
** A NULL value is not changed by this routine. It remains NULL.
*/
case OP_ToNumeric: { /* same as TK_TO_NUMERIC, in1 */
pIn1 = &aMem[pOp->p1];
sqlite3VdbeMemNumerify(pIn1);
break;
}
#endif /* SQLITE_OMIT_CAST */
/* Opcode: ToInt P1 * * * *
**
** Force the value in register P1 to be an integer. If
** The value is currently a real number, drop its fractional part.
** If the value is text or blob, try to convert it to an integer using the
** equivalent of atoi() and store 0 if no such conversion is possible.
**
** A NULL value is not changed by this routine. It remains NULL.
*/
case OP_ToInt: { /* same as TK_TO_INT, in1 */
pIn1 = &aMem[pOp->p1];
if( (pIn1->flags & MEM_Null)==0 ){
sqlite3VdbeMemIntegerify(pIn1);
}
break;
}
#if !defined(SQLITE_OMIT_CAST) && !defined(SQLITE_OMIT_FLOATING_POINT)
/* Opcode: ToReal P1 * * * *
**
** Force the value in register P1 to be a floating point number.
** If The value is currently an integer, convert it.
** If the value is text or blob, try to convert it to an integer using the
** equivalent of atoi() and store 0.0 if no such conversion is possible.
**
** A NULL value is not changed by this routine. It remains NULL.
*/
case OP_ToReal: { /* same as TK_TO_REAL, in1 */
pIn1 = &aMem[pOp->p1];
memAboutToChange(p, pIn1);
if( (pIn1->flags & MEM_Null)==0 ){
sqlite3VdbeMemRealify(pIn1);
}
break;
}
#endif /* !defined(SQLITE_OMIT_CAST) && !defined(SQLITE_OMIT_FLOATING_POINT) */
/* Opcode: Lt P1 P2 P3 P4 P5
** Synopsis: if r[P1]<r[P3] goto P2
**