Re: [sqlite] Unique index that uses GLOB does not detect duplicate due to REAL conversion

2019-04-30 Thread Keith Medcalf

Actually, the affinity is applied first, however --

c0 has affinity "A" (blob) applied.
c1 has affinity "E" (real) applied, but has the "tryForInteger" set which 
results in an integer value

the GLOB function converts its arguments to text, so when it is presented with 
the "integer" c1 different results are obtained than when the REINDEX command 
presents c1 as an actual "real" value to the same function ... (the integer 1 
is cast to text as '1' and the real 1 is cast to text as '1.0')

select '0' GLOB 1;
0
select '1' GLOB 1;
1
select '0' GLOB 1.0;
0
select '1' GLOB 1.0;
0
select cast(1 as text);
1
select cast(1.0 as text);
1.0
select cast(cast(1 as real) as text);
1.0
select cast(cast('1' as real) as text);
1.0
select cast(cast('1' as numeric) as text);
1

I suppose the "best fix" would be to prohibit the pattern (and the escape 
character) from being a numeric storage class by returning an error.  This also 
applies to the builtin LIKE.

The builtin instr function would do the same and should probably return an 
error if either the needle or the haystack are numeric storage class.

---
The fact that there's a Highway to Hell but only a Stairway to Heaven says a 
lot about anticipated traffic volume.


>-Original Message-
>From: sqlite-users [mailto:sqlite-users-
>boun...@mailinglists.sqlite.org] On Behalf Of Manuel Rigger
>Sent: Tuesday, 30 April, 2019 15:26
>To: SQLite mailing list
>Subject: [sqlite] Unique index that uses GLOB does not detect
>duplicate due to REAL conversion
>
>Hi everyone,
>
>It think that I found a bug where I could circumvent a UNIQUE check
>of an
>index. Consider the example below, which causes "Error: UNIQUE
>constraint
>failed" when invoking REINDEX:
>
>CREATE TABLE test (c0, c1 REAL);
>CREATE UNIQUE INDEX index_1 ON test(c0 GLOB c1);
>
>INSERT INTO test(c0, c1) VALUES ('1', '1');
>INSERT INTO test(c0, c1) VALUES ('0', '1');
>REINDEX;
>
>The '1's stored to c1 are converted to REAL due to the column's
>affinity,
>and supposedly because SQLite determines that the conversion is
>lossless.
>However, while '1' GLOB '1' would yield true and '0' GLOB '1' would
>yield
>false, which would be valid, after the conversion both GLOB
>expressions
>yield false, violating the UNIQUE property of the index, which is not
>detected until the REINDEX:
>
>sqlite> SELECT *, typeof(c0), typeof(c1), c0 GLOB c1, c0 GLOB '1'
>from test;
>1|1.0|text|real|0|1
>0|1.0|text|real|0|0
>
>Probably, the index check is performed before the conversion?
>
>Best,
>Manuel
>___
>sqlite-users mailing list
>sqlite-users@mailinglists.sqlite.org
>http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users



___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


[sqlite] Unique index that uses GLOB does not detect duplicate due to REAL conversion

2019-04-30 Thread Manuel Rigger
Hi everyone,

It think that I found a bug where I could circumvent a UNIQUE check of an
index. Consider the example below, which causes "Error: UNIQUE constraint
failed" when invoking REINDEX:

CREATE TABLE test (c0, c1 REAL);
CREATE UNIQUE INDEX index_1 ON test(c0 GLOB c1);

INSERT INTO test(c0, c1) VALUES ('1', '1');
INSERT INTO test(c0, c1) VALUES ('0', '1');
REINDEX;

The '1's stored to c1 are converted to REAL due to the column's affinity,
and supposedly because SQLite determines that the conversion is lossless.
However, while '1' GLOB '1' would yield true and '0' GLOB '1' would yield
false, which would be valid, after the conversion both GLOB expressions
yield false, violating the UNIQUE property of the index, which is not
detected until the REINDEX:

sqlite> SELECT *, typeof(c0), typeof(c1), c0 GLOB c1, c0 GLOB '1' from test;
1|1.0|text|real|0|1
0|1.0|text|real|0|0

Probably, the index check is performed before the conversion?

Best,
Manuel
___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users