SQLite User Forum

Why is ’0’ a string OR BLOB?
Login

Why is '0' a string OR BLOB?

(1) By Aask (AAsk1902) on 2022-11-05 15:59:47 [link] [source]

Abs(X) returns 0.0 if X is a string or blob that cannot be converted to a numeric value is from the documentation of the abs(x) function.

sqlite> with tbl(val) as (Values('0'),('0.0'),('char'),('-12'),('5')) select val,abs(val) from tbl;
┌──────┬──────────┐
│ val  │ abs(val) │
├──────┼──────────┤
│ 0    │ 0.0      │
│ 0.0  │ 0.0      │
│ char │ 0.0      │
│ -12  │ 12.0     │
│ 5    │ 5.0      │
└──────┴──────────┘

Why could '0' and '0.0' (first two rows) NOT be converted to a numeric value (and get treated as string)?

(2) By MBL (UserMBL) on 2022-11-05 16:30:20 in reply to 1 [source]

I think the only question here can be be why text '0' was not converted into an integer but into a real value. This can be tricked out by adding zero:

sqlite> .mode qbox
sqlite> with tbl(val) as (Values('0'),(X'404142'),(NULL),(0),(0.0),('0.0'),('char'),('-12'),('5'))
   ...> select typeof(val), val, abs(val), val+0, abs(val+0), typeof(abs(val+0)) from tbl;
┌─────────────┬───────────┬──────────┬───────┬────────────┬────────────────────┐
│ typeof(val) │    val    │ abs(val) │ val+0 │ abs(val+0) │ typeof(abs(val+0)) │
├─────────────┼───────────┼──────────┼───────┼────────────┼────────────────────┤
│ 'text'      │ '0'       │ 0.0      │ 0     │ 0          │ 'integer'          │
│ 'blob'      │ x'404142' │ 0.0      │ 0     │ 0          │ 'integer'          │
│ 'null'      │ NULL      │ NULL     │ NULL  │ NULL       │ 'null'             │
│ 'integer'   │ 0         │ 0        │ 0     │ 0          │ 'integer'          │
│ 'real'      │ 0.0       │ 0.0      │ 0.0   │ 0.0        │ 'real'             │
│ 'text'      │ '0.0'     │ 0.0      │ 0.0   │ 0.0        │ 'real'             │
│ 'text'      │ 'char'    │ 0.0      │ 0     │ 0          │ 'integer'          │
│ 'text'      │ '-12'     │ 12.0     │ -12   │ 12         │ 'integer'          │
│ 'text'      │ '5'       │ 5.0      │ 5     │ 5          │ 'integer'          │
└─────────────┴───────────┴──────────┴───────┴────────────┴────────────────────┘
sqlite> select sqlite_version();
┌──────────────────┐
│ sqlite_version() │
├──────────────────┤
│ '3.39.4'         │
└──────────────────┘

(3) By Simon Slavin (slavin) on 2022-11-05 16:39:04 in reply to 1 [link] [source]

sqlite> with tbl(val) as (Values(0),('0'),('0.0'),(0.4),('0.4'),(-0.4),('-0.4'),('char'),('-12'),('5')) select typeof(val),val,abs(val) from tbl;
┌─────────────┬──────┬──────────┐
│ typeof(val) │ val  │ abs(val) │
├─────────────┼──────┼──────────┤
│ integer     │ 0    │ 0        │
│ text        │ 0    │ 0.0      │
│ text        │ 0.0  │ 0.0      │
│ real        │ 0.4  │ 0.4      │
│ text        │ 0.4  │ 0.4      │
│ real        │ -0.4 │ 0.4      │
│ text        │ -0.4 │ 0.4      │
│ text        │ char │ 0.0      │
│ text        │ -12  │ 12.0     │
│ text        │ 5    │ 5.0      │
└─────────────┴──────┴──────────┘
The values would be coerced into numbers if you put them into a table with a numeric column. But what you have in the WITH statement just passes a sequence of values. They are never stored in a table so they don't have to be coerced.

I'm not entirely sure about '0.0'. The string '0.0' cannot be converted into a number because if you convert it to a number, then convert it back to a string, you don't get the original string back. SQLite understands this as some of the original information having been lost, and doesn't consider the conversion as successful. I can't figure out whether what I see in the results is a result of that.