static void test_destructor( sqlite3_context *pCtx, int nArg, sqlite3_value **argv ){ char *zVal; int len; sqlite3 *db = sqlite3_user_data(pCtx); test_destructor_count_var++; assert( nArg==1 ); if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; len = sqlite3ValueBytes(argv[0], ENC(db)); zVal = sqliteMalloc(len+3); zVal[len] = 0; zVal[len-1] = 0; assert( zVal ); zVal++; memcpy(zVal, sqlite3ValueText(argv[0], ENC(db)), len); if( ENC(db)==SQLITE_UTF8 ){ sqlite3_result_text(pCtx, zVal, -1, destructor); #ifndef SQLITE_OMIT_UTF16 }else if( ENC(db)==SQLITE_UTF16LE ){ sqlite3_result_text16le(pCtx, zVal, -1, destructor); }else{ sqlite3_result_text16be(pCtx, zVal, -1, destructor); #endif /* SQLITE_OMIT_UTF16 */ } }
int sqlite3_value_bytes16(sqlite3_value *pVal){ return sqlite3ValueBytes(pVal, SQLITE_UTF16NATIVE); }
/* ** Compare the values contained by the two memory cells, returning ** negative, zero or positive if pMem1 is less than, equal to, or greater ** than pMem2. Sorting order is NULL's first, followed by numbers (integers ** and reals) sorted numerically, followed by text ordered by the collating ** sequence pColl and finally blob's ordered by memcmp(). ** ** Two NULL values are considered equal by this function. */ int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){ int rc; int f1, f2; int combined_flags; /* Interchange pMem1 and pMem2 if the collating sequence specifies ** DESC order. */ f1 = pMem1->flags; f2 = pMem2->flags; combined_flags = f1|f2; /* If one value is NULL, it is less than the other. If both values ** are NULL, return 0. */ if( combined_flags&MEM_Null ){ return (f2&MEM_Null) - (f1&MEM_Null); } /* If one value is a number and the other is not, the number is less. ** If both are numbers, compare as reals if one is a real, or as integers ** if both values are integers. */ if( combined_flags&(MEM_Int|MEM_Real) ){ if( !(f1&(MEM_Int|MEM_Real)) ){ return 1; } if( !(f2&(MEM_Int|MEM_Real)) ){ return -1; } if( (f1 & f2 & MEM_Int)==0 ){ double r1, r2; if( (f1&MEM_Real)==0 ){ r1 = pMem1->u.i; }else{ r1 = pMem1->r; } if( (f2&MEM_Real)==0 ){ r2 = pMem2->u.i; }else{ r2 = pMem2->r; } if( r1<r2 ) return -1; if( r1>r2 ) return 1; return 0; }else{ assert( f1&MEM_Int ); assert( f2&MEM_Int ); if( pMem1->u.i < pMem2->u.i ) return -1; if( pMem1->u.i > pMem2->u.i ) return 1; return 0; } } /* If one value is a string and the other is a blob, the string is less. ** If both are strings, compare using the collating functions. */ if( combined_flags&MEM_Str ){ if( (f1 & MEM_Str)==0 ){ return 1; } if( (f2 & MEM_Str)==0 ){ return -1; } assert( pMem1->enc==pMem2->enc ); assert( pMem1->enc==SQLITE_UTF8 || pMem1->enc==SQLITE_UTF16LE || pMem1->enc==SQLITE_UTF16BE ); /* The collation sequence must be defined at this point, even if ** the user deletes the collation sequence after the vdbe program is ** compiled (this was not always the case). */ assert( !pColl || pColl->xCmp ); if( pColl ){ if( pMem1->enc==pColl->enc ){ /* The strings are already in the correct encoding. Call the ** comparison function directly */ return pColl->xCmp(pColl->pUser,pMem1->n,pMem1->z,pMem2->n,pMem2->z); }else{ u8 origEnc = pMem1->enc; const void *v1, *v2; int n1, n2; /* Convert the strings into the encoding that the comparison ** function expects */ v1 = sqlite3ValueText((sqlite3_value*)pMem1, pColl->enc); n1 = v1==0 ? 0 : pMem1->n; assert( n1==sqlite3ValueBytes((sqlite3_value*)pMem1, pColl->enc) ); v2 = sqlite3ValueText((sqlite3_value*)pMem2, pColl->enc); n2 = v2==0 ? 0 : pMem2->n; assert( n2==sqlite3ValueBytes((sqlite3_value*)pMem2, pColl->enc) ); /* Do the comparison */ rc = pColl->xCmp(pColl->pUser, n1, v1, n2, v2); /* Convert the strings back into the database encoding */ sqlite3ValueText((sqlite3_value*)pMem1, origEnc); sqlite3ValueText((sqlite3_value*)pMem2, origEnc); return rc; } } /* If a NULL pointer was passed as the collate function, fall through ** to the blob case and use memcmp(). */ } /* Both values must be blobs. Compare using memcmp(). */ rc = memcmp(pMem1->z, pMem2->z, (pMem1->n>pMem2->n)?pMem2->n:pMem1->n); if( rc==0 ){ rc = pMem1->n - pMem2->n; } return rc; }
int sqlite3_value_bytes(sqlite3_value *pVal){ return sqlite3ValueBytes(pVal, SQLITE_UTF8); }
/* ** Compare the values contained by the two memory cells, returning ** negative, zero or positive if pMem1 is less than, equal to, or greater ** than pMem2. Sorting order is NULL's first, followed by numbers (integers ** and reals) sorted numerically, followed by text ordered by the collating ** sequence pColl and finally blob's ordered by memcmp(). ** ** Two NULL values are considered equal by this function. */ int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl) { int rc; int f1, f2; int combined_flags; /* Interchange pMem1 and pMem2 if the collating sequence specifies ** DESC order. */ f1 = pMem1->flags; f2 = pMem2->flags; combined_flags = f1|f2; /* If one value is NULL, it is less than the other. If both values ** are NULL, return 0. */ if( combined_flags&MEM_Null ) { return (f2&MEM_Null) - (f1&MEM_Null); } /* If one value is a number and the other is not, the number is less. ** If both are numbers, compare as reals if one is a real, or as integers ** if both values are integers. */ if( combined_flags&(MEM_Int|MEM_Real) ) { if( !(f1&(MEM_Int|MEM_Real)) ) { return 1; } if( !(f2&(MEM_Int|MEM_Real)) ) { return -1; } if( (f1 & f2 & MEM_Int)==0 ) { double r1, r2; if( (f1&MEM_Real)==0 ) { r1 = pMem1->i; } else { r1 = pMem1->r; } if( (f2&MEM_Real)==0 ) { r2 = pMem2->i; } else { r2 = pMem2->r; } if( r1<r2 ) return -1; if( r1>r2 ) return 1; return 0; } else { assert( f1&MEM_Int ); assert( f2&MEM_Int ); if( pMem1->i < pMem2->i ) return -1; if( pMem1->i > pMem2->i ) return 1; return 0; } } /* If one value is a string and the other is a blob, the string is less. ** If both are strings, compare using the collating functions. */ if( combined_flags&MEM_Str ) { if( (f1 & MEM_Str)==0 ) { return 1; } if( (f2 & MEM_Str)==0 ) { return -1; } assert( pMem1->enc==pMem2->enc ); assert( pMem1->enc==SQLITE_UTF8 || pMem1->enc==SQLITE_UTF16LE || pMem1->enc==SQLITE_UTF16BE ); /* This assert may fail if the collation sequence is deleted after this ** vdbe program is compiled. The documentation defines this as an ** undefined condition. A crash is usual result. */ assert( !pColl || pColl->xCmp ); if( pColl ) { if( pMem1->enc==pColl->enc ) { return pColl->xCmp(pColl->pUser,pMem1->n,pMem1->z,pMem2->n,pMem2->z); } else { u8 origEnc = pMem1->enc; rc = pColl->xCmp( pColl->pUser, sqlite3ValueBytes((sqlite3_value*)pMem1, pColl->enc), sqlite3ValueText((sqlite3_value*)pMem1, pColl->enc), sqlite3ValueBytes((sqlite3_value*)pMem2, pColl->enc), sqlite3ValueText((sqlite3_value*)pMem2, pColl->enc) ); sqlite3ValueBytes((sqlite3_value*)pMem1, origEnc); sqlite3ValueText((sqlite3_value*)pMem1, origEnc); sqlite3ValueBytes((sqlite3_value*)pMem2, origEnc); sqlite3ValueText((sqlite3_value*)pMem2, origEnc); return rc; } } /* If a NULL pointer was passed as the collate function, fall through ** to the blob case and use memcmp(). */ } /* Both values must be blobs. Compare using memcmp(). */ rc = memcmp(pMem1->z, pMem2->z, (pMem1->n>pMem2->n)?pMem2->n:pMem1->n); if( rc==0 ) { rc = pMem1->n - pMem2->n; } return rc; }