Re: [sqlite] Check constrain execution timing change? (Now a bug)

2020-02-04 Thread Doug
> On Tue, Feb 4, 2020 at 5:38 PM Doug  wrote:
> > > You're twisting my point here. I obviously want the reverse,
> > > I want the database types to "drive" the binding done. 1-to-1.
> > > Because even if binding a different type would work, via
> SQLite's
> > > own implicit conversion, I don't want that, because it's
> hiding a
> > > bug in the code most likely instead. --DD
> 
> > Is the code inadvertently putting quotes (') around in integer
> value [...]?
> 
> I'm talking about "real" binding here:
> https://www.sqlite.org/c3ref/bind_blob.html
> In C/C++, you could mess up your col indexes when binding, or bind
> incorrectly for some other reason, and "strong static typing" is more
> likely to find those, via SQL failures, than SQLite's default
> flexible-typing, that accepts any value in any typed column,
> unless you have these explicit CHECK+typeof constraints. --DD

So you are talking about a bug in your code where you inadvertently called:
  sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*));
instead of
  sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
and you want SQLite to tell you about it.

I have a hard time seeing how you could make that kind of coding error, given 
the different parameters and types in the calls.

Doug



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


Re: [sqlite] Check constrain execution timing change? (Now a bug)

2020-02-04 Thread Dominique Devienne
On Tue, Feb 4, 2020 at 5:38 PM Doug  wrote:
> > You're twisting my point here. I obviously want the reverse,
> > I want the database types to "drive" the binding done. 1-to-1.
> > Because even if binding a different type would work, via SQLite's
> > own implicit conversion, I don't want that, because it's hiding a
> > bug in the code most likely instead. --DD

> Is the code inadvertently putting quotes (') around in integer value [...]?

I'm talking about "real" binding here:
https://www.sqlite.org/c3ref/bind_blob.html
In C/C++, you could mess up your col indexes when binding, or bind incorrectly
for some other reason, and "strong static typing" is more likely to
find those, via
SQL failures, than SQLite's default flexible-typing, that accepts any
value in any typed column,
unless you have these explicit CHECK+typeof constraints. --DD
___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Check constrain execution timing change? (Now a bug)

2020-02-04 Thread Doug
> You're twisting my point here. I obviously want the reverse,
> I want the database types to "drive" the binding done. 1-to-1.
> Because even if binding a different type would work, via SQLite's
> own implicit conversion, I don't want that, because it's hiding a
> bug in the code most likely instead. --DD

WRT the code that the bug is in: I'm assuming that your code is creating text 
SQL statements which it passes to some process, right? The "binding" you 
mention is confusing me. You can't be using query.addBindValue() because the 
type is coerced to match the column type.

So, if you are generating text SQL statements: Is the code inadvertently 
putting quotes (') around in integer value or is the user entering a string and 
your code is taking that input and slapping it into a SQL INSERT statement?

Please explain your possible code "bug".

Doug

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


Re: [sqlite] Check constrain execution timing change? (Now a bug)

2020-02-04 Thread Dominique Devienne
On Mon, Feb 3, 2020 at 6:42 PM James K. Lowden  wrote:
> Do you want to force applications to "pre-convert" values the DBMS can
> convert implicitly?

Yes, that's exactly what I want James.
I want the enforce the bind-value type to be an exact match for the
column value type.

I could before, via CHECK+typeof(), so that's still breaking BC,
even though I accept that now that I was explained things.

> Do you want binding choices in the application to
> drive the datatype in the database, or do you want the database to
> enforce types?

You're twisting my point here. I obviously want the reverse,
I want the database types to "drive" the binding done. 1-to-1.
Because even if binding a different type would work, via SQLite's
own implicit conversion, I don't want that, because it's hiding a bug
in the code most likely instead. --DD
___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Check constrain execution timing change? (Now a bug)

2020-02-03 Thread Thomas Kurz
> You say that you want to prevent the use of the string literal '123'
> for inserting into the integer field x.  That will no longer be
> possible in SQLite beginning with 3.32.0 (assuming the change
> currently on trunk goes through.)
> But, why do you want to do that?

You are right. I apologize for my first excitement. The new behavior is correct 
and consistent to other RDBMs. Sometimes one misses the forest for the trees :-)

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


Re: [sqlite] Check constrain execution timing change? (Now a bug)

2020-02-03 Thread James K. Lowden
On Mon, 3 Feb 2020 10:45:50 +0100
Dominique Devienne  wrote:

> On Sun, Feb 2, 2020 at 12:50 AM Richard Hipp  wrote:
> 
> > On 2/1/20, Thomas Kurz  wrote:
> > > Does this mean there will be no possibility to prevent inserting
> > > a string into an integer column anymore?
> > >
> > > create table x (x integer check (typeof(x) == 'integer'));
> > > insert into x values ('1');
> > >
> > > --> will pass in future versions???
> >
> > I think that is what it means.  yes.
> 
> Wow... I haven't caught up on this thread, but that's really really
> bad IMHO 
...
> the fact we can no longer do that would be a real shame. I wonder
> where this is coming from... --DD

It's a good thing, really!  The rule would be that the provided value is
converted to the column's type before inserting.  If it can't be
converted, it's still an error.  If it can, great.  I think you'll find
that's the behavior of most SQL DBMS implementations. 

After all, of what significance is the type of the provided argument?
Do you want to force applications to "pre-convert" values the DBMS can
convert implicitly?  Do you want binding choices in the application to
drive the datatype in the database, or do you want the database to
enforce types?  

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


Re: [sqlite] Check constrain execution timing change? (Now a bug)

2020-02-03 Thread Dominique Devienne
On Mon, Feb 3, 2020 at 5:35 PM Richard Hipp  wrote:
> On 2/3/20, Dominique Devienne  wrote:
> > On Sun, Feb 2, 2020 at 12:50 AM Richard Hipp  wrote:
>
> This is the SQL:
>
>   CREATE TABLE t1(x INT CHECK(typeof(x)=='integer'));
>   INSERT INTO t1(x) VALUES('123');
>
> You say that you want to prevent the use of the string literal '123'
> for inserting into the integer field x.  That will no longer be
> possible in SQLite beginning with 3.32.0 (assuming the change
> currently on trunk goes through.)
>
> But, why do you want to do that?  How do you prevent the use of a
> string literal to initialize an integer field in MySQL, PosgreSQL, SQL
> Server, and Oracle - all of which accept and run the SQL above
> (without the CHECK constraint) with no errors?

Right. Implicit conversion also happen in these other DBs (I just
checked Oracle,
but I trust you're way more qualified to assert that me).

> If your goal is to prevent an actual string from being stored in the
> "x" column, then the legacy CHECK constraint still works for that.
> The following insert still fails:
>
>INSERT INTO t1(x) VALUES('xyzzy');

Right again. It fails with "ORA-01722: invalid number" on Oracle.
(no need for a CHECK constraint of course)

> But, you will no longer be allowed to prevent the type coercion that
> forces the '123' value into an integer 123, I think.  At least, I do
> not see a way to do that on trunk right now.

OK. I was more thinking of the '123' staying as text-typed in the DB.
But if it is coerced into the column's type (well, "affinity", not type per se),
then whether the value is bound as a string or a integer should be immaterial.

I still think my code shouldn't be binding values of a type different
than the column's,
and would still greatly prefer "strong *static* typing", which I
emulated with CHECK typeof(),
since it smells like a bug in the code IMHO, but as long as the stored
value is "OK", sure
that makes little differences in the end.

So now that I understand the better, so be it I guess.
I'm sure you have a good reason to make that change, despite the
surprising break in BC for SQLite.

Thanks for taking the time to spell it out for me. --DD

PS: I still wish for a pragma for strong static typing (no need for
CHECK typeof()),
  and now also wish for that to happen even before implicit
conversions. But I've long
  accepted this is unlikely to ever happen :(
___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Check constrain execution timing change? (Now a bug)

2020-02-03 Thread Richard Hipp
On 2/3/20, Dominique Devienne  wrote:
> On Sun, Feb 2, 2020 at 12:50 AM Richard Hipp  wrote:
>
>> On 2/1/20, Thomas Kurz  wrote:
>> >
>> > create table x (x integer check (typeof(x) == 'integer'));
>> > insert into x values ('1');
>> >
>> > --> will pass in future versions???
>>
>> I think that is what it means.  yes.
>
> Wow... I haven't caught up on this thread, but that's really really bad
> IMHO,
> and would consider that a serious regression. I've been enforcing
> "strong-typing",
> (or "inflexible-typing" if you prefer Richard) for many schemas, and
> the fact we can
> no longer do that would be a real shame. I wonder where this is coming
> from... --DD

This is the SQL:

  CREATE TABLE t1(x INT CHECK(typeof(x)=='integer'));
  INSERT INTO t1(x) VALUES('123');

You say that you want to prevent the use of the string literal '123'
for inserting into the integer field x.  That will no longer be
possible in SQLite beginning with 3.32.0 (assuming the change
currently on trunk goes through.)

But, why do you want to do that?  How do you prevent the use of a
string literal to initialize an integer field in MySQL, PosgreSQL, SQL
Server, and Oracle - all of which accept and run the SQL above
(without the CHECK constraint) with no errors?

If your goal is to prevent an actual string from being stored in the
"x" column, then the legacy CHECK constraint still works for that.
The following insert still fails:

   INSERT INTO t1(x) VALUES('xyzzy');

But, you will no longer be allowed to prevent the type coercion that
forces the '123' value into an integer 123, I think.  At least, I do
not see a way to do that on trunk right now.

I have put a "Pre-release Snapshot" of the latest code on the Download
page to try to make it easier for people to try out this new change.

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


Re: [sqlite] Check constrain execution timing change? (Now a bug)

2020-02-03 Thread Dominique Devienne
On Sun, Feb 2, 2020 at 12:50 AM Richard Hipp  wrote:

> On 2/1/20, Thomas Kurz  wrote:
> > Does this mean there will be no possibility to prevent inserting a string
> > into an integer column anymore?
> >
> > create table x (x integer check (typeof(x) == 'integer'));
> > insert into x values ('1');
> >
> > --> will pass in future versions???
>
> I think that is what it means.  yes.

Wow... I haven't caught up on this thread, but that's really really bad IMHO,
and would consider that a serious regression. I've been enforcing
"strong-typing",
(or "inflexible-typing" if you prefer Richard) for many schemas, and
the fact we can
no longer do that would be a real shame. I wonder where this is coming
from... --DD
___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Check constrain execution timing change? (Now a bug)

2020-02-02 Thread Richard Hipp
On 2/2/20, Thomas Kurz  wrote:
> And are there any consequences for something like
>
>> create table x (x text check (typeof(x) == 'text'));
>> insert into x values ('1');
>

Not that I know of.

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


Re: [sqlite] Check constrain execution timing change? (Now a bug)

2020-02-02 Thread Thomas Kurz
And are there any consequences for something like

> create table x (x text check (typeof(x) == 'text'));
> insert into x values ('1');

?


- Original Message - 
From: Richard Hipp 
To: SQLite mailing list 
Sent: Sunday, February 2, 2020, 00:50:34
Subject: [sqlite] Check constrain execution timing change? (Now a bug)

On 2/1/20, Thomas Kurz  wrote:
> Does this mean there will be no possibility to prevent inserting a string
> into an integer column anymore?

> create table x (x integer check (typeof(x) == 'integer'));
> insert into x values ('1');

> --> will pass in future versions???

I think that is what it means.  yes.

-- 
D. Richard Hipp
d...@sqlite.org
___
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


Re: [sqlite] Check constrain execution timing change? (Now a bug)

2020-02-01 Thread Richard Hipp
On 2/1/20, Thomas Kurz  wrote:
> Does this mean there will be no possibility to prevent inserting a string
> into an integer column anymore?
>
> create table x (x integer check (typeof(x) == 'integer'));
> insert into x values ('1');
>
> --> will pass in future versions???

I think that is what it means.  yes.

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


Re: [sqlite] Check constrain execution timing change? (Now a bug)

2020-02-01 Thread Thomas Kurz
Does this mean there will be no possibility to prevent inserting a string into 
an integer column anymore?

create table x (x integer check (typeof(x) == 'integer'));
insert into x values ('1');

--> will pass in future versions???


- Original Message - 
From: Richard Hipp 
To: SQLite mailing list 
Sent: Saturday, February 1, 2020, 00:09:07
Subject: [sqlite] Check constrain execution timing change? (Now a bug)

On 1/31/20, Keith Medcalf  wrote:

> That would elevate this to the status of a bug since it should be impossible
> to do this.


It is also not something that is fixable, so the solution will likely
be to simply document it.
-- 
D. Richard Hipp
d...@sqlite.org
___
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


Re: [sqlite] Check constrain execution timing change?

2020-01-31 Thread Simon Slavin
On 1 Feb 2020, at 1:28am, Simon Slavin  wrote:

> How do you feel about that ?

Sorry, I didn't read the rest of the list first.  I see it's already answered.  
Thanks.
___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Check constrain execution timing change?

2020-01-31 Thread Simon Slavin
On 31 Jan 2020, at 10:51pm, Richard Hipp  wrote:

> CREATE TABLE t1(x INTEGER CHECK(typeof(x)=='text'));
> INSERT INTO t1 VALUES('123');
> PRAGMA integrity_check;

Short and sweet.  That's what I was talking about.

How do you feel about that ?  Should a programmer be able to create a failure 
in integrity_check that easily ?  It's just two legit lines of SQL.  My gut 
feeling is that it points to something wrong with SQLite.  But there are lot of 
people here who know more about it than me.

Would be interesting to see an example which depends only on features of SQL, 
avoiding typeof().  Might make it more obvious whether it's a bug.
___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Check constrain execution timing change? (Now a bug)

2020-01-31 Thread Richard Hipp
On 1/31/20, Keith Medcalf  wrote:
>
> That would elevate this to the status of a bug since it should be impossible
> to do this.
>

It is also not something that is fixable, so the solution will likely
be to simply document it.
-- 
D. Richard Hipp
d...@sqlite.org
___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Check constrain execution timing change? (Now a bug)

2020-01-31 Thread Keith Medcalf

On Friday, 31 January, 2020 14:39, Simon Slavin  wrote:

>On 31 Jan 2020, at 9:27pm, Keith Medcalf  wrote:

>> You are however correct that this is an "application consistency"
>problem more than an SQLite problem and it is a lot of change for little
>actual benefit.

>How about this ?

>A program (possibly part of the SQLite precompiled suite, possibly from a
>third party) goes through any SQLite database as an integrity checker.
>One of its jobs is to check that column constraints are not violated.
>This cannot possible be wrong.  A SQLite database with violated CHECK
>clauses is, by definition, corrupt.

pragma integrity_check and pragma quick_check already do this.

>However, because the checks are performed on the values input, not the
>values stored, some data in the database does violate a CHECK constraint.

>Can this happen, given the behaviour Keith identified ?  If so, I would
>say that something is wrong.

Yes.  It is possible to "craft" a table and a check constraint such that the 
INSERT passes the constraint yet the integrity check fails:

sqlite> create table x(x text not null check (typeof(x) == 'integer'));
sqlite> insert into x values (1);
sqlite> select x, typeof(x) from x;
1|text
sqlite> pragma integrity_check;
CHECK constraint failed in x

That would elevate this to the status of a bug since it should be impossible to 
do this.

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



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


Re: [sqlite] Check constrain execution timing change?

2020-01-31 Thread Richard Hipp
CREATE TABLE t1(x INTEGER CHECK(typeof(x)=='text'));
INSERT INTO t1 VALUES('123');
PRAGMA integrity_check;


On 1/31/20, Graham Holden  wrote:
> Friday, January 31, 2020, 9:39:07 PM, Simon Slavin 
> wrote:
>
>> On 31 Jan 2020, at 9:27pm, Keith Medcalf  wrote:
>
>>> You are however correct that this is an "application consistency"
>>> problem more than an SQLite problem and it is a lot of change for
>>> little actual benefit.
>
>> How about this ?
>
>> A program (possibly part of the SQLite precompiled suite, possibly
>> from a third party) goes through any SQLite database as an integrity
>> checker.  One of its jobs is to check that column constraints
>> are not violated.  This cannot possible be wrong.  A SQLite database
>> with violated CHECK clauses is, by definition, corrupt.
>
>> However, because the checks are performed on the values input, not
>> the values stored, some data in the database does violate a CHECK
>> constraint.
>
>> Can this happen, given the behaviour Keith identified ?  If so, I
>> would say that something is wrong.
>
> Probably not, at least not with the example he used.
>
> In Keith's example (assuming I understand it correctly), you are
> stopped from inserting/updating something that -- if you did the
> insertion/update WITHOUT the checks -- would be stored in such a
> way that it would later pass "pragma integrity_check" if the checks
> were in place.
>
> So, inserting '1' (a string) into a field with integer affinity, but
> no constraints would be allowed, and result in 1 (an integer) being
> stored.
>
> If that column were to magically gain a "check (typeof(x) == 'integer')"
> constraint, it would pass "pragma integrity_check" (because by now it
> contains an integer, not the string that was originally inserted).
>
> If you now repeated the original insert (of the string '1') with the
> check constraint in place it will now REJECT the insertion, because
> the type-of-the-thing-being-inserted doesn't meet the constraint (it's
> a string).
>
> So it doesn't allow you to create an inconsistent database (as defined
> by check constraints), but does stop some ways of inserting/modifying
> data that would have created valid data if the checks weren't there.
>
> Graham
>
>
> ___
> sqlite-users mailing list
> sqlite-users@mailinglists.sqlite.org
> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
>


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


Re: [sqlite] Check constrain execution timing change?

2020-01-31 Thread Graham Holden
Friday, January 31, 2020, 9:39:07 PM, Simon Slavin  wrote:

> On 31 Jan 2020, at 9:27pm, Keith Medcalf  wrote:

>> You are however correct that this is an "application consistency"
>> problem more than an SQLite problem and it is a lot of change for
>> little actual benefit.  

> How about this ?

> A program (possibly part of the SQLite precompiled suite, possibly
> from a third party) goes through any SQLite database as an integrity
> checker.  One of its jobs is to check that column constraints  
> are not violated.  This cannot possible be wrong.  A SQLite database
> with violated CHECK clauses is, by definition, corrupt. 

> However, because the checks are performed on the values input, not
> the values stored, some data in the database does violate a CHECK
> constraint.  

> Can this happen, given the behaviour Keith identified ?  If so, I
> would say that something is wrong.

Probably not, at least not with the example he used.

In Keith's example (assuming I understand it correctly), you are
stopped from inserting/updating something that -- if you did the
insertion/update WITHOUT the checks -- would be stored in such a
way that it would later pass "pragma integrity_check" if the checks
were in place.

So, inserting '1' (a string) into a field with integer affinity, but
no constraints would be allowed, and result in 1 (an integer) being
stored.

If that column were to magically gain a "check (typeof(x) == 'integer')"
constraint, it would pass "pragma integrity_check" (because by now it
contains an integer, not the string that was originally inserted).

If you now repeated the original insert (of the string '1') with the
check constraint in place it will now REJECT the insertion, because
the type-of-the-thing-being-inserted doesn't meet the constraint (it's
a string).

So it doesn't allow you to create an inconsistent database (as defined
by check constraints), but does stop some ways of inserting/modifying
data that would have created valid data if the checks weren't there.

Graham


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


Re: [sqlite] Check constrain execution timing change?

2020-01-31 Thread Simon Slavin
On 31 Jan 2020, at 9:27pm, Keith Medcalf  wrote:

> You are however correct that this is an "application consistency" problem 
> more than an SQLite problem and it is a lot of change for little actual 
> benefit.

How about this ?

A program (possibly part of the SQLite precompiled suite, possibly from a third 
party) goes through any SQLite database as an integrity checker.  One of its 
jobs is to check that column constraints are not violated.  This cannot 
possible be wrong.  A SQLite database with violated CHECK clauses is, by 
definition, corrupt.

However, because the checks are performed on the values input, not the values 
stored, some data in the database does violate a CHECK constraint.

Can this happen, given the behaviour Keith identified ?  If so, I would say 
that something is wrong.
___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Check constrain execution timing change?

2020-01-31 Thread Keith Medcalf

On Friday, 31 January, 2020 13:58, Richard Hipp  wrote:

>On 1/31/20, Keith Medcalf  wrote:

>> The check should occur AFTER defaults and
>> column affinity is applied before the data record is stored

>Why do you think this?  Is it documented somewhere?  I ask because
>your test case gives the same answer (doing the first insert but
>failing the other two) for every version of SQLite I checked from
>trunk going back to 3.1.0 (2005-01-21).  Hence, for backwards
>compatibility, even it is documented to do something differently, I
>should probably change the documentation rather than the behavior.

You are absolutely correct in that this is the way SQLite has worked forever, 
and is the way it is documented (or not, I am not sure).  However, this means 
that the result of a CHECK/NOT NULL contstraint differs between an INSERT and 
when run on existing data (via pragma integrity_check).  This means that, for 
example, the construct

CHECK (typeof(x) in ('integer', 'real'))

enforces different table invariants between UPDATE/INSERT and when the data is 
already in the table since in the case of INSERT/UPDATE it checks the type of 
the value input to the UPDATE/INSERT rather than the value actually stored and 
prohibits the INSERT/UPDATE of values that would pass the table checks later.

You are however correct that this is an "application consistency" problem more 
than an SQLite problem and it is a lot of change for little actual benefit.

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




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


Re: [sqlite] Check constrain execution timing change?

2020-01-31 Thread Keith Medcalf
>collect input data row
>apply column affinity
>fire before triggers
>apply defaults, generated always, rowid etc.
>apply column affinity to above columns
>run constraints
>store actul row
>fire after triggers

Actually, with generated columns it is a bit more complicated.  I think:

collect input data row
run generated column logic including not allowing specification of values for 
generated columns
apply column affinity
fire before triggers
apply defaults, rowid etc.
apply column affinity to defaults, rowid, etc. changed above
run constraints
store actul row
fire after triggers

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

>collect input data row
>apply column affinity
>fire before triggers
>apply defaults, generated always, rowid etc.
>apply column affinity to above columns
>run constraints
>store actul row
>fire after triggers




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


Re: [sqlite] Check constrain execution timing change?

2020-01-31 Thread Richard Hipp
On 1/31/20, Keith Medcalf  wrote:
>
> The check should occur AFTER defaults and
> column affinity is applied before the data record is stored
>

Why do you think this?  Is it documented somewhere?  I ask because
your test case gives the same answer (doing the first insert but
failing the other two) for every version of SQLite I checked from
trunk going back to 3.1.0 (2005-01-21).  Hence, for backwards
compatibility, even it is documented to do something differently, I
should probably change the documentation rather than the behavior.

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


[sqlite] Check constrain execution timing change?

2020-01-31 Thread Keith Medcalf

I believe that when inserting a row into a table the CHECK constraints (which 
includes any NOT NULL constraint) are checked at the wrong time, or at least 
with the wrong data.  The check should occur AFTER defaults and column affinity 
is applied before the data record is stored, meaning that the constraints 
should apply to the row as actually stored.  Consider:

create table x (x integer default ('1') check (typeof(x) == 'integer'));
insert into x values (1);
insert into x values ('1');
insert into x default values;

The last two statements raise constraint errors, even though the values that 
end up in the database would in fact pass the constraint:

create table x (x integer default ('1'));
insert into x values (1);
insert into x values ('1');
insert into x default values;
select x, typeof(x) from x;

1|integer
1|integer
1|integer

Similarly for the NOT NULL column constraint.  If should apply to the data 
actually stored, not the contents of the 'insert' the value may be modified 
before it is actually inserted (the working of the PRIMARY KEY on a ROWID 
table, or a default clause, for example) may modify the value before it is 
stored.

Presently, the NOT NULL column constraint is to the input data, and not to the 
row actually stored:

sqlite> create table x(x integer not null default (1));
sqlite> insert into x values (NULL);
Error: NOT NULL constraint failed: x.x

which also raises a NOT NULL constraint error even though the value stored will 
not be NULL and therefore passes the constraint.

I do not know exactly where before triggers fire, but they should probably fire 
directly on the input data after affinity is applied and before the check 
contraints run.  You could then use before triggers to limit or require 
specifying NULL inputs on an insert even if those NULL values would be changed 
to a default or computed value afterwards.

ie, the processing for inserting a record should be:

collect input data row
apply column affinity
fire before triggers
apply defaults, generated always, rowid etc.
apply column affinity to above columns
run constraints
store actul row
fire after triggers

I don't know if this would constitute a breaking change, but I don't think so 
...

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




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