DBD-SQLite
view release on metacpan or search on metacpan
s++; if (s == send || (*s != 'F' && *s != 'f')) return 0;
s++; if (s < send && (*s == 'I' || *s == 'i')) {
s++; if (s == send || (*s != 'N' && *s != 'n')) return 0;
s++; if (s == send || (*s != 'I' && *s != 'i')) return 0;
s++; if (s == send || (*s != 'T' && *s != 't')) return 0;
s++; if (s == send || (*s != 'Y' && *s != 'y')) return 0;
s++;
}
sawinf = 1;
} else if (*s == 'N' || *s == 'n') {
/* XXX TODO: There are signaling NaNs and quiet NaNs. */
s++; if (s == send || (*s != 'A' && *s != 'a')) return 0;
s++; if (s == send || (*s != 'N' && *s != 'n')) return 0;
s++;
sawnan = 1;
} else
return 0;
if (sawinf) {
numtype &= IS_NUMBER_NEG; /* Keep track of sign */
numtype |= IS_NUMBER_INFINITY | IS_NUMBER_NOT_INT;
#if defined(SQLITE_ENABLE_MULTITHREADED_CHECKS) && !defined(SQLITE_MUTEX_OMIT)
SQLITE_PRIVATE void sqlite3MutexWarnOnContention(sqlite3_mutex*);
#else
# define sqlite3MutexWarnOnContention(x)
#endif
#ifndef SQLITE_OMIT_FLOATING_POINT
# define EXP754 (((u64)0x7ff)<<52)
# define MAN754 ((((u64)1)<<52)-1)
# define IsNaN(X) (((X)&EXP754)==EXP754 && ((X)&MAN754)!=0)
# define IsOvfl(X) (((X)&EXP754)==EXP754)
SQLITE_PRIVATE int sqlite3IsNaN(double);
SQLITE_PRIVATE int sqlite3IsOverflow(double);
#else
# define IsNaN(X) 0
# define sqlite3IsNaN(X) 0
# define sqlite3IsOVerflow(X) 0
#endif
/*
** An instance of the following structure holds information about SQL
** functions arguments that are the parameters to the printf() function.
*/
struct PrintfArguments {
int nArg; /* Total number of arguments */
int nUsed; /* Number of arguments used so far */
sqlite3_value **apArg; /* The argument values */
};
/*
** An instance of this object receives the decoding of a floating point
** value into an approximate decimal representation.
*/
struct FpDecode {
char sign; /* '+' or '-' */
char isSpecial; /* 1: Infinity 2: NaN */
int n; /* Significant digits in the decode */
int iDP; /* Location of the decimal point */
char *z; /* Start of significant digits */
char zBuf[24]; /* Storage for significant digits */
};
SQLITE_PRIVATE void sqlite3FpDecode(FpDecode*,double,int,int);
SQLITE_PRIVATE char *sqlite3MPrintf(sqlite3*,const char*, ...);
SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
iRound = -precision;
}else if( xtype==etGENERIC ){
if( precision==0 ) precision = 1;
iRound = precision;
}else{
iRound = precision+1;
}
sqlite3FpDecode(&s, realvalue, iRound, flag_altform2 ? 26 : 16);
if( s.isSpecial ){
if( s.isSpecial==2 ){
bufpt = flag_zeropad ? "null" : "NaN";
length = sqlite3Strlen30(bufpt);
break;
}else if( flag_zeropad ){
s.z[0] = '9';
s.iDP = 1000;
s.n = 1;
}else{
memcpy(buf, "-Inf", 5);
bufpt = buf;
if( s.sign=='-' ){
*/
#ifndef SQLITE_UNTESTABLE
SQLITE_PRIVATE int sqlite3FaultSim(int iTest){
int (*xCallback)(int) = sqlite3GlobalConfig.xTestCallback;
return xCallback ? xCallback(iTest) : SQLITE_OK;
}
#endif
#ifndef SQLITE_OMIT_FLOATING_POINT
/*
** Return true if the floating point value is Not a Number (NaN).
**
** Use the math library isnan() function if compiled with SQLITE_HAVE_ISNAN.
** Otherwise, we have our own implementation that works on most systems.
*/
SQLITE_PRIVATE int sqlite3IsNaN(double x){
int rc; /* The value return */
#if !SQLITE_HAVE_ISNAN && !HAVE_ISNAN
u64 y;
memcpy(&y,&x,sizeof(y));
rc = IsNaN(y);
#else
rc = isnan(x);
#endif /* HAVE_ISNAN */
testcase( rc );
return rc;
}
#endif /* SQLITE_OMIT_FLOATING_POINT */
#ifndef SQLITE_OMIT_FLOATING_POINT
/*
** Return true if the floating point value is NaN or +Inf or -Inf.
*/
SQLITE_PRIVATE int sqlite3IsOverflow(double x){
int rc; /* The value return */
u64 y;
memcpy(&y,&x,sizeof(y));
rc = IsOvfl(y);
return rc;
}
#endif /* SQLITE_OMIT_FLOATING_POINT */
while( e<=-10 ){
e += 10;
dekkerMul2(rr, 1.0e-10, -3.6432197315497741579e-27);
}
while( e<=-1 ){
e += 1;
dekkerMul2(rr, 1.0e-01, -5.5511151231257827021e-18);
}
}
*pResult = rr[0]+rr[1];
if( sqlite3IsNaN(*pResult) ) *pResult = 1e300*1e300;
}
if( sign<0 ) *pResult = -*pResult;
assert( !sqlite3IsNaN(*pResult) );
atof_return:
/* return true if number and no extra non-whitespace characters after */
if( z==zEnd && nDigit>0 && eValid && eType>0 ){
return eType;
}else if( eType>=2 && (eType==3 || eValid) && nDigit>0 ){
return -1;
}else{
return 0;
}
** The p->z[] array is *not* zero-terminated.
*/
SQLITE_PRIVATE void sqlite3FpDecode(FpDecode *p, double r, int iRound, int mxRound){
int i;
u64 v;
int e, exp = 0;
p->isSpecial = 0;
p->z = p->zBuf;
/* Convert negative numbers to positive. Deal with Infinity, 0.0, and
** NaN. */
if( r<0.0 ){
p->sign = '-';
r = -r;
}else if( r==0.0 ){
p->sign = '+';
p->n = 1;
p->iDP = 1;
p->z = "0";
return;
}else{
pMem->xDel = xDestructor ? xDestructor : sqlite3NoopDestructor;
}
#ifndef SQLITE_OMIT_FLOATING_POINT
/*
** Delete any previous value and set the value stored in *pMem to val,
** manifest type REAL.
*/
SQLITE_PRIVATE void sqlite3VdbeMemSetDouble(Mem *pMem, double val){
sqlite3VdbeMemSetNull(pMem);
if( !sqlite3IsNaN(val) ){
pMem->u.r = val;
pMem->flags = MEM_Real;
}
}
#endif
#ifdef SQLITE_DEBUG
/*
** Return true if the Mem holds a RowSet object. This routine is intended
** for use inside of assert() statements.
*/
static const u64 t1 = ((u64)0x3ff00000)<<32;
static const double r1 = 1.0;
u64 t2 = t1;
swapMixedEndianFloat(t2);
assert( sizeof(r1)==sizeof(t2) && memcmp(&r1, &t2, sizeof(r1))==0 );
#endif
assert( sizeof(x)==8 && sizeof(pMem->u.r)==8 );
swapMixedEndianFloat(x);
memcpy(&pMem->u.r, &x, sizeof(x));
pMem->flags = IsNaN(x) ? MEM_Null : MEM_Real;
}
}
static int serialGet7(
const unsigned char *buf, /* Buffer to deserialize from */
Mem *pMem /* Memory cell to write value into */
){
u64 x = FOUR_BYTE_UINT(buf);
u32 y = FOUR_BYTE_UINT(buf+4);
x = (x<<32) + y;
assert( sizeof(x)==8 && sizeof(pMem->u.r)==8 );
swapMixedEndianFloat(x);
memcpy(&pMem->u.r, &x, sizeof(x));
if( IsNaN(x) ){
pMem->flags = MEM_Null;
return 1;
}
pMem->flags = MEM_Real;
return 0;
}
SQLITE_PRIVATE void sqlite3VdbeSerialGet(
const unsigned char *buf, /* Buffer to deserialize from */
u32 serial_type, /* Serial type to deserialize */
Mem *pMem /* Memory cell to write value into */
static int SQLITE_NOINLINE doubleLt(double a, double b){ return a<b; }
static int SQLITE_NOINLINE doubleEq(double a, double b){ return a==b; }
#endif
/*
** Do a comparison between a 64-bit signed integer and a 64-bit floating-point
** number. Return negative, zero, or positive if the first (i64) is less than,
** equal to, or greater than the second (double).
*/
SQLITE_PRIVATE int sqlite3IntFloatCompare(i64 i, double r){
if( sqlite3IsNaN(r) ){
/* SQLite considers NaN to be a NULL. And all integer values are greater
** than NULL */
return 1;
}
if( sqlite3Config.bUseLongDouble ){
LONGDOUBLE_TYPE x = (LONGDOUBLE_TYPE)i;
testcase( x<r );
testcase( x>r );
testcase( x==r );
return (x<r) ? -1 : (x>r);
}else{
/* Serial types 12 or greater are strings and blobs (greater than
** numbers). Types 10 and 11 are currently "reserved for future
** use", so it doesn't really matter what the results of comparing
** them to numeric values are. */
rc = serial_type==10 ? -1 : +1;
}else if( serial_type==0 ){
rc = -1;
}else{
if( serial_type==7 ){
if( serialGet7(&aKey1[d1], &mem1) ){
rc = -1; /* mem1 is a NaN */
}else if( mem1.u.r<pRhs->u.r ){
rc = -1;
}else if( mem1.u.r>pRhs->u.r ){
rc = +1;
}else{
assert( rc==0 );
}
}else{
sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1);
rc = sqlite3IntFloatCompare(mem1.u.i, pRhs->u.r);
#ifndef SQLITE_OMIT_FLOATING_POINT
/* Opcode: Real * P2 * P4 *
** Synopsis: r[P2]=P4
**
** P4 is a pointer to a 64-bit floating point value.
** Write that value into register P2.
*/
case OP_Real: { /* same as TK_FLOAT, out2 */
pOut = out2Prerelease(p, pOp);
pOut->flags = MEM_Real;
assert( !sqlite3IsNaN(*pOp->p4.pReal) );
pOut->u.r = *pOp->p4.pReal;
break;
}
#endif
/* Opcode: String8 * P2 * P4 *
** Synopsis: r[P2]='P4'
**
** P4 points to a nul terminated UTF-8 string. This opcode is transformed
** into a String opcode before it is executed for the first time. During
if( iA==0 ) goto arithmetic_result_is_null;
if( iA==-1 ) iA = 1;
rB = (double)(iB % iA);
break;
}
}
#ifdef SQLITE_OMIT_FLOATING_POINT
pOut->u.i = rB;
MemSetTypeFlag(pOut, MEM_Int);
#else
if( sqlite3IsNaN(rB) ){
goto arithmetic_result_is_null;
}
pOut->u.r = rB;
MemSetTypeFlag(pOut, MEM_Real);
#endif
}
break;
arithmetic_result_is_null:
sqlite3VdbeMemSetNull(pOut);
** datatype.
**
** If P1 is -1, then P3 is a register number and the datatype is taken
** from the value in that register.
**
** P5 is a bitmask of data types. SQLITE_INTEGER is the least significant
** (0x01) bit. SQLITE_FLOAT is the 0x02 bit. SQLITE_TEXT is 0x04.
** SQLITE_BLOB is 0x08. SQLITE_NULL is 0x10.
**
** WARNING: This opcode does not reliably distinguish between NULL and REAL
** when P1>=0. If the database contains a NaN value, this opcode will think
** that the datatype is REAL when it should be NULL. When P1<0 and the value
** is already stored in register P3, then this opcode does reliably
** distinguish between NULL and REAL. The problem only arises then P1>=0.
**
** Take the jump to address P2 if and only if the datatype of the
** value determined by P1 and P3 corresponds to one of the bits in the
** P5 bitmask.
**
*/
case OP_IsType: { /* jump */
** value described by z[0..n-1] into register iMem.
**
** The z[] string will probably not be zero-terminated. But the
** z[n] character is guaranteed to be something that does not look
** like the continuation of the number.
*/
static void codeReal(Vdbe *v, const char *z, int negateFlag, int iMem){
if( ALWAYS(z!=0) ){
double value;
sqlite3AtoF(z, &value, sqlite3Strlen30(z), SQLITE_UTF8);
assert( !sqlite3IsNaN(value) ); /* The new AtoF never returns NaN */
if( negateFlag ) value = -value;
sqlite3VdbeAddOp4Dup8(v, OP_Real, 0, iMem, 0, (u8*)&value, P4_REAL);
}
}
#endif
/*
** Generate an instruction that will put the integer describe by
** text z[0..n-1] into register iMem.
double x;
int y, z;
char zBuf[100];
UNUSED_PARAMETER(argc);
assert( argc==3 );
x = sqlite3_value_double(argv[0]);
y = sqlite3_value_int(argv[1]);
z = sqlite3_value_int(argv[2]);
sqlite3FpDecode(&s, x, y, z);
if( s.isSpecial==2 ){
sqlite3_snprintf(sizeof(zBuf), zBuf, "NaN");
}else{
sqlite3_snprintf(sizeof(zBuf), zBuf, "%c%.*s/%d", s.sign, s.n, s.z, s.iDP);
}
sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
}
#endif /* SQLITE_DEBUG */
/*
** All of the FuncDef structures in the aBuiltinFunc[] array above
** to the global function hash table. This occurs at start-time (as
if( pCol->notNull ){
/* (1) NOT NULL columns may not contain a NULL */
int jmp3;
int jmp2 = sqlite3VdbeAddOp4Int(v, OP_IsType, p1, labelOk, p3, p4);
VdbeCoverage(v);
if( p1<0 ){
sqlite3VdbeChangeP5(v, 0x0f); /* INT, REAL, TEXT, or BLOB */
jmp3 = jmp2;
}else{
sqlite3VdbeChangeP5(v, 0x0d); /* INT, TEXT, or BLOB */
/* OP_IsType does not detect NaN values in the database file
** which should be treated as a NULL. So if the header type
** is REAL, we have to load the actual data using OP_Column
** to reliably determine if the value is a NULL. */
sqlite3VdbeAddOp3(v, OP_Column, p1, p3, 3);
sqlite3ColumnDefault(v, pTab, j, 3);
jmp3 = sqlite3VdbeAddOp2(v, OP_NotNull, 3, labelOk);
VdbeCoverage(v);
}
zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName,
pCol->zCnName);
*/
#ifndef NDEBUG
#ifndef SQLITE_OMIT_FLOATING_POINT
/* This section of code's only "output" is via assert() statements. */
if( rc==SQLITE_OK ){
u64 x = (((u64)1)<<63)-1;
double y;
assert(sizeof(x)==8);
assert(sizeof(x)==sizeof(y));
memcpy(&y, &x, 8);
assert( sqlite3IsNaN(y) );
}
#endif
#endif
/* Do extra initialization steps requested by the SQLITE_EXTRA_INIT
** compile-time option.
*/
#ifdef SQLITE_EXTRA_INIT
if( bRunExtraInit ){
int SQLITE_EXTRA_INIT(const char*);
char c1;
char c2;
char n;
char eType;
char nRepl;
char *zMatch;
char *zRepl;
} aNanInfName[] = {
{ 'i', 'I', 3, JSONB_FLOAT, 7, "inf", "9.0e999" },
{ 'i', 'I', 8, JSONB_FLOAT, 7, "infinity", "9.0e999" },
{ 'n', 'N', 3, JSONB_NULL, 4, "NaN", "null" },
{ 'q', 'Q', 4, JSONB_NULL, 4, "QNaN", "null" },
{ 's', 'S', 4, JSONB_NULL, 4, "SNaN", "null" },
};
/*
** Report the wrong number of arguments for json_insert(), json_replace()
** or json_set().
*/
static void jsonWrongNumArgs(
sqlite3_context *pCtx,
const char *zFuncName
goto json_parse_restart;
}
pParse->iErr = i;
return -1;
}
case 'n': {
if( strncmp(z+i,"null",4)==0 && !sqlite3Isalnum(z[i+4]) ){
jsonBlobAppendOneByte(pParse, JSONB_NULL);
return i+4;
}
/* fall-through into the default case that checks for NaN */
/* no break */ deliberate_fall_through
}
default: {
u32 k;
int nn;
c = z[i];
for(k=0; k<sizeof(aNanInfName)/sizeof(aNanInfName[0]); k++){
if( c!=aNanInfName[k].c1 && c!=aNanInfName[k].c2 ) continue;
nn = aNanInfName[k].n;
if( sqlite3StrNICmp(&z[i], aNanInfName[k].zMatch, nn)!=0 ){
memset(pParse, 0, sizeof(pParse[0]));
return 1;
}
}else{
jsonBlobAppendNode(pParse, JSONB_TEXTRAW, nJson, zJson);
}
break;
}
case SQLITE_FLOAT: {
double r = sqlite3_value_double(pArg);
if( NEVER(sqlite3IsNaN(r)) ){
jsonBlobAppendNode(pParse, JSONB_NULL, 0, 0);
}else{
int n = sqlite3_value_bytes(pArg);
const char *z = (const char*)sqlite3_value_text(pArg);
if( z==0 ) return 1;
if( z[0]=='I' ){
jsonBlobAppendNode(pParse, JSONB_FLOAT, 5, "9e999");
}else if( z[0]=='-' && z[1]=='I' ){
jsonBlobAppendNode(pParse, JSONB_FLOAT, 6, "-9e999");
}else{
( run in 0.253 second using v1.01-cache-2.11-cpan-4d50c553e7e )