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

Fixes to the MEM changes. The library now links. (CVS 1470)

FossilOrigin-Name: f33d15d95f195e26e1ef396158597a2caa06f374
This commit is contained in:
drh
2004-05-27 03:12:53 +00:00
parent eb2e176a12
commit f44795013f
11 changed files with 210 additions and 287 deletions

View File

@@ -43,7 +43,7 @@
** in this file for details. If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.337 2004/05/27 01:53:56 drh Exp $
** $Id: vdbe.c,v 1.338 2004/05/27 03:12:55 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@@ -80,7 +80,8 @@ int sqlite3_interrupt_count = 0;
** already. Return non-zero if a malloc() fails.
*/
#define Stringify(P, enc) \
(!((P)->flags&(MEM_Str|MEM_Blob)) && sqlite3VdbeMemStringify(P,enc))
if(((P)->flags&(MEM_Str|MEM_Blob))==0 && sqlite3VdbeMemStringify(P,enc)) \
{ goto no_mem; }
/*
** Convert the given stack entity into a string that has been obtained
@@ -309,7 +310,7 @@ static void applyAffinity(Mem *pRec, char affinity, u8 enc){
** representation.
*/
if( 0==(pRec->flags&MEM_Str) && (pRec->flags&(MEM_Real|MEM_Int)) ){
Stringify(pRec, enc);
sqlite3VdbeMemStringify(pRec, enc);
}
pRec->flags &= ~(MEM_Real|MEM_Int);
@@ -432,24 +433,27 @@ static int getBtreeMem(
pMem->flags = MEM_Blob|MEM_Ephem;
}else{
int rc;
if( amt>NBFS ){
zData = (char *)sqliteMallocRaw(amt);
if( amt>NBFS-2 ){
zData = (char *)sqliteMallocRaw(amt+2);
if( !zData ){
return SQLITE_NOMEM;
}
pMem->flags = MEM_Blob|MEM_Dyn;
pMem->flags = MEM_Blob|MEM_Dyn|MEM_Term;
}else{
zData = &(pMem->zShort[0]);
pMem->flags = MEM_Blob|MEM_Short;
pMem->flags = MEM_Blob|MEM_Short|MEM_Term;
}
pMem->z = zData;
pMem->enc = 0;
pMem->type = SQLITE3_BLOB;
if( key ){
rc = sqlite3BtreeKey(pCur, offset, amt, zData);
}else{
rc = sqlite3BtreeData(pCur, offset, amt, zData);
}
zData[amt] = 0;
zData[amt+1] = 0;
if( rc!=SQLITE_OK ){
if( amt>NBFS ){
sqliteFree(zData);
@@ -715,67 +719,54 @@ case OP_Halt: {
}
}
/* Opcode: String * * P3
**
** The string value P3 is pushed onto the stack. If P3==0 then a
** NULL is pushed onto the stack.
*/
/* Opcode: Real * * P3
**
** The string value P3 is converted to a real and pushed on to the stack.
*/
/* Opcode: Integer P1 * P3
**
** The integer value P1 is pushed onto the stack. If P3 is not zero
** then it is assumed to be a string representation of the same integer.
** If P1 is zero and P3 is not zero, then the value is derived from P3.
*/
case OP_Integer:
case OP_Real:
case OP_String: {
char *z = pOp->p3;
u8 op = pOp->opcode;
case OP_Integer: {
pTos++;
pTos->flags = 0;
/* If this is an OP_Real or OP_Integer opcode, set the pTos->r or pTos->i
** values respectively.
*/
if( op==OP_Real ){
assert( z );
assert( sqlite3IsNumber(z, 0, TEXT_Utf8) );
pTos->r = sqlite3AtoF(z, 0);
pTos->flags = MEM_Real;
}else if( op==OP_Integer ){
if( pOp->p3==0 ){
pTos->flags = MEM_Int;
pTos->i = pOp->p1;
if( pTos->i==0 && pOp->p3 ){
sqlite3GetInt64(pOp->p3, &pTos->i);
}
}
if( z ){
/* FIX ME: For now the code in expr.c always puts UTF-8 in P3. It
** should transform text to the native encoding before doing so.
*/
if( db->enc!=TEXT_Utf8 ){
rc = sqlite3utfTranslate(z, -1, TEXT_Utf8, (void **)&pTos->z,
&pTos->n, db->enc);
if( rc!=SQLITE_OK ){
assert( !pTos->z );
goto abort_due_to_error;
}
pTos->flags |= MEM_Str | MEM_Dyn | MEM_Term;
}else{
pTos->z = z;
pTos->n = strlen(z) + 1;
pTos->flags |= MEM_Str | MEM_Static | MEM_Term;
}
}else if( op==OP_String ){
pTos->flags = MEM_Null;
pTos->type = SQLITE3_INTEGER;
}else{
pTos->flags = MEM_Str|MEM_Static|MEM_Term;
pTos->z = pOp->p3;
pTos->n = strlen(pTos->z);
pTos->enc = TEXT_Utf8;
Integerify(pTos, 0);
}
break;
}
/* Opcode: Real * * P3
**
** The string value P3 is converted to a real and pushed on to the stack.
*/
case OP_Real: {
pTos++;
pTos->flags = MEM_Str|MEM_Static|MEM_Term;
pTos->z = pOp->p3;
pTos->n = strlen(pTos->z);
pTos->enc = TEXT_Utf8;
Realify(pTos, 0);
break;
}
/* Opcode: String * * P3
**
** The string value P3 is pushed onto the stack. If P3==0 then a
** NULL is pushed onto the stack.
*/
case OP_String: {
pTos++;
pTos->flags = MEM_Str|MEM_Static|MEM_Term;
pTos->enc = TEXT_Utf8;
pTos->z = pOp->p3;
pTos->n = strlen(pTos->z);
sqlite3VdbeChangeEncoding(pTos, db->enc);
break;
}
@@ -889,14 +880,15 @@ case OP_Dup: {
pTos->flags &= ~MEM_Dyn;
pTos->flags |= MEM_Ephem;
}else if( pTos->flags & MEM_Short ){
memcpy(pTos->zShort, pFrom->zShort, pTos->n);
memcpy(pTos->zShort, pFrom->zShort, pTos->n+2);
pTos->z = pTos->zShort;
}else if( (pTos->flags & MEM_Static)==0 ){
pTos->z = sqliteMallocRaw(pFrom->n);
pTos->z = sqliteMallocRaw(pFrom->n+2);
if( sqlite3_malloc_failed ) goto no_mem;
memcpy(pTos->z, pFrom->z, pFrom->n);
memcpy(&pTos->z[pTos->n], "\0", 2);
pTos->flags &= ~(MEM_Static|MEM_Ephem|MEM_Short);
pTos->flags |= MEM_Dyn;
pTos->flags |= MEM_Dyn|MEM_Term;
}
}
break;
@@ -992,7 +984,6 @@ case OP_Callback: {
for(i=0; i<pOp->p1; i++){
Mem *pVal = &pTos[0-i];
SetEncodingFlags(pVal, db->enc);
sqlite3VdbeMemNulTerminate(pVal);
}
@@ -1089,7 +1080,7 @@ case OP_Concat: {
}
pTos++;
pTos->n = j;
pTos->flags = MEM_Str|MEM_Dyn|MEM_Term
pTos->flags = MEM_Str|MEM_Dyn|MEM_Term;
pTos->enc = db->enc;
pTos->type = SQLITE3_TEXT;
pTos->z = zNew;
@@ -1239,7 +1230,6 @@ case OP_Function: {
pArg = &pTos[1-n];
for(i=0; i<n; i++, pArg++){
SetEncodingFlags(pArg, db->enc);
apVal[i] = pArg;
}
@@ -1265,11 +1255,6 @@ case OP_Function: {
(pTos->flags & MEM_Str)!=0 ? pTos->z : "user function error", (char*)0);
rc = SQLITE_ERROR;
}
if( pTos->flags&MEM_Str ){
SetEncoding(pTos, encToFlags(db->enc)|MEM_Term);
}
break;
}
@@ -1414,7 +1399,7 @@ case OP_MustBeInt: {
}else if( pTos->flags & MEM_Str ){
i64 v;
if( sqlite3VdbeChangeEncoding(pTos, TEXT_Utf8)
|| sqlite3VdbeNulTerminate(pTos) ){
|| sqlite3VdbeMemNulTerminate(pTos) ){
goto no_mem;
}
if( !sqlite3atoi64(pTos->z, &v) ){
@@ -1776,64 +1761,6 @@ case OP_NotNull: {
break;
}
/* Opcode: Class * * *
**
** Pop a single value from the top of the stack and push on one of the
** following strings, according to the storage class of the value just
** popped:
**
** "NULL", "INTEGER", "REAL", "TEXT", "BLOB"
**
** This opcode is probably temporary.
*/
case OP_Class: {
int flags = pTos->flags;
int i;
struct {
int mask;
char * zClass;
char * zClass16;
} classes[] = {
{MEM_Null, "NULL", "\0N\0U\0L\0L\0\0\0"},
{MEM_Int, "INTEGER", "\0I\0N\0T\0E\0G\0E\0R\0\0\0"},
{MEM_Real, "REAL", "\0R\0E\0A\0L\0\0\0"},
{MEM_Str, "TEXT", "\0T\0E\0X\0T\0\0\0"},
{MEM_Blob, "BLOB", "\0B\0L\0O\0B\0\0\0"}
};
Release(pTos);
pTos->flags = MEM_Str|MEM_Static|MEM_Term;
for(i=0; i<5; i++){
if( classes[i].mask&flags ){
switch( db->enc ){
case TEXT_Utf8:
pTos->z = classes[i].zClass;
break;
case TEXT_Utf16be:
pTos->z = classes[i].zClass16;
break;
case TEXT_Utf16le:
pTos->z = &(classes[i].zClass16[1]);
break;
default:
assert(0);
}
break;
}
}
assert( i<5 );
if( db->enc==TEXT_Utf8 ){
pTos->n = strlen(pTos->z) + 1;
}else{
pTos->n = sqlite3utf16ByteLen(pTos->z, -1) + 2;
}
break;
}
/* Opcode: SetNumColumns P1 P2 *
**
** Before the OP_Column opcode can be executed on a cursor, this
@@ -2277,7 +2204,7 @@ case OP_MakeIdxKey: {
popStack(&pTos, nField+addRowid);
}
pTos++;
pTos->flags = MEM_Blob|MEM_Dyn; /* TODO: should eventually be MEM_Blob */
pTos->flags = MEM_Blob|MEM_Dyn;
pTos->z = zKey;
pTos->n = nByte;
@@ -3220,10 +3147,12 @@ case OP_PutStrKey: {
pC->pData = pTos->z;
pTos->flags = MEM_Null;
}else{
pC->pData = sqliteMallocRaw( pC->nData );
pC->pData = sqliteMallocRaw( pC->nData+2 );
if( pC->pData ){
memcpy(pC->pData, pTos->z, pC->nData);
}
pC->pData[pC->nData] = 0;
pC->pData[pC->nData+1] = 0;
}
pC->nullRow = 0;
}else{
@@ -4000,17 +3929,15 @@ case OP_IntegrityCk: {
if( z==0 || z[0]==0 ){
if( z ) sqliteFree(z);
pTos->z = "ok";
pTos->n = 3;
pTos->flags = MEM_Str | MEM_Static;
pTos->n = 2;
pTos->flags = MEM_Str | MEM_Static | MEM_Term;
}else{
pTos->z = z;
pTos->n = strlen(z) + 1;
pTos->flags = MEM_Str | MEM_Dyn;
}
if( db->enc!=TEXT_Utf8 ){
SetEncodingFlags(pTos, TEXT_Utf8);
SetEncoding(pTos, encToFlags(db->enc)|MEM_Term);
pTos->n = strlen(z);
pTos->flags = MEM_Str | MEM_Dyn | MEM_Term;
}
pTos->enc = TEXT_Utf8;
sqlite3VdbeChangeEncoding(pTos, db->enc);
sqliteFree(aRoot);
break;
}
@@ -4419,6 +4346,7 @@ fileread_jump:
** from the input file.
*/
case OP_FileColumn: {
#if 0 /* Will be deleting this soon */
int i = pOp->p1;
char *z;
assert( i>=0 && i<p->nField );
@@ -4431,11 +4359,11 @@ case OP_FileColumn: {
if( z ){
pTos->n = strlen(z) + 1;
pTos->z = z;
pTos->flags = MEM_Utf8 | MEM_Str | MEM_Ephem | MEM_Term;
SetEncoding(pTos, encToFlags(db->enc)|MEM_Term);
pTos->flags = MEM_Str | MEM_Ephem | MEM_Term;
}else{
pTos->flags = MEM_Null;
}
#endif
break;
}
@@ -4480,9 +4408,11 @@ case OP_MemStore: {
if( pOp->p2 ){
pTos->flags = MEM_Null;
}else{
pMem->z = sqliteMallocRaw( pMem->n );
pMem->z = sqliteMallocRaw( pMem->n+2 );
if( pMem->z==0 ) goto no_mem;
memcpy(pMem->z, pTos->z, pMem->n);
memcpy(&pMem->z[pMem->n], "\000", 2);
pMem->flags |= MEM_Term;
}
}else if( pMem->flags & MEM_Short ){
pMem->z = pMem->zShort;
@@ -4591,7 +4521,6 @@ case OP_AggFunc: {
for(i=0; i<n; i++, pRec++){
apVal[i] = pRec;
SetEncodingFlags(pRec, db->enc);
}
i = pTos->i;
assert( i>=0 && i<p->agg.nMem );
@@ -4669,9 +4598,6 @@ case OP_AggSet: {
}else if( pMem->flags & MEM_Short ){
pMem->z = pMem->zShort;
}
SetEncodingFlags(pMem, db->enc);
SetEncoding(pMem, MEM_Utf8|MEM_Term);
Release(pTos);
pTos--;
break;
}
@@ -4696,8 +4622,7 @@ case OP_AggGet: {
pTos->flags |= MEM_Ephem;
}
if( pTos->flags&MEM_Str ){
SetEncodingFlags(pTos, TEXT_Utf8);
SetEncoding(pTos, encToFlags(db->enc)|MEM_Term);
sqlite3VdbeChangeEncoding(pTos, db->enc);
}
break;
}
@@ -4812,6 +4737,8 @@ default: {
/* Mem.z points to Mem.zShort iff the subtype is MEM_Short */
assert( (pTos->flags & MEM_Short)==0 || pTos->z==pTos->zShort );
assert( (pTos->flags & MEM_Short)!=0 || pTos->z!=pTos->zShort );
assert( (pTos->flags & MEM_Term)==0 || (pTos->flags & MEM_Str)==0
|| db->enc!=TEXT_Utf8 || strlen(pTos->z)==pTos->n );
}else{
/* Cannot define a string subtype for non-string objects */
assert( (pTos->flags & (MEM_Static|MEM_Dyn|MEM_Ephem|MEM_Short))==0 );