I'm afraid I still didn't make any progress on this.

It looks to me that PRAGMA foreign_key_check; and the deferred foreign key
mechanism sometimes contradict each other,
consequently at least one of these features must have a bug, but I don't
know for sure which one,
so I can't risk using any of them in production until the situation is
resolved.

Do you have any suggestion how I should go about it? Can I escalate this to
someone?

Thanks in advance,
Máté

szmate1618 <szmate1...@gmail.com> ezt írta (időpont: 2018. nov. 23., P,
17:21):

> >"PRAGMA foreign_keys = ?" is a property of the connection only, not the
> >database file. So what advantage would there be in including the PRAGMA
> >statements in the body of a transaction?
>
> Not much, if I do everything right, I guess. But what if I break the
> foreign key integrity?
> If it's inside a transaction, I can rollback easily, given that I realize
> I broke it.
> But if I don't, because foreign key checks are turned off, and I commit
> everything before noticing that
> something's wrong, that's a lot harder to fix.
>
> I can either take extra care not to break anything, or just do a backup of
> the database file before
> 'risky' transactions, but it would be much easier if I could just use
> deferred foreign keys that don't
> let me commit if the database is in an inconsistent state.
>
> Máté
>
> Dan Kennedy <danielk1...@gmail.com> ezt írta (időpont: 2018. nov. 23., P,
> 16:30):
>
>> On 11/23/2018 09:54 PM, szmate1618 wrote:
>> > Dear list members,
>> >
>> > I have the following problem, with which I'd like to request your aid:
>> >
>> > Currently, at version 3.25.2, SQLite only has a limited support for
>> alter
>> > table. E.g. you cannot change the datatype (type affinity) of a column,
>> or
>> > drop a column.
>> >
>> > The usual workaround is to create a new table with the desired schema,
>> fill
>> > it with data from the original table, drop the original table, and
>> rename
>> > the new one. But what if the original table is a parent table in a
>> foreign
>> > key relationship?
>> >
>> > The official solution
>> > <https://www.sqlite.org/lang_altertable.html#otheralter> is turning
>> foreign
>> > keys off, making the changes you want, then turning foreign keys on. But
>> > I'm slightly annoyed this cannot be done in a transaction (because
>> these PRAGMA
>> > foreign_keys =s don't take effect inside of transactions, so they need
>> to
>> > be issued before and after).
>>
>>
>> "PRAGMA foreign_keys = ?" is a property of the connection only, not the
>> database file. So what advantage would there be in including the PRAGMA
>> statements in the body of a transaction?
>>
>> Dan.
>>
>>
>>
>> >
>> > I'd like to use deferred foreign keys instead. I have 3 queries, one of
>> > them seems to work, the two others do not. My questions are the
>> following:
>> >
>> >    - Does the seemingly working query work by design? Or it's just a
>> >    fortunate(?) constellation of multiple factors, and depending on
>> other
>> >    tables or new data in the database it might break in the future?
>> Somewhat
>> >    like undefined behavior in C++?
>> >    - Why do the other ones not work? How are they different from the
>> first
>> >    one?
>> >
>> > Setup
>> >
>> > PRAGMA foreign_keys = OFF;
>> > DROP TABLE IF EXISTS Parent;CREATE TABLE Parent(A TEXT UNIQUE,
>> > COLUMN_TO_DROP FLOAT);INSERT INTO Parent VALUES('whatever', 0.0);
>> > DROP TABLE IF EXISTS Child;CREATE TABLE Child(C TEXT REFERENCES
>> > Parent(A) DEFERRABLE INITIALLY DEFERRED);INSERT INTO Child
>> > VALUES('whatever');
>> >
>> > PRAGMA foreign_keys = ON;
>> >
>> > Query1 - seems to be working as intended
>> >
>> > BEGIN TRANSACTION;CREATE TABLE Temp AS SELECT A FROM Parent;DROP TABLE
>> > Parent;CREATE TABLE Parent (A TEXT UNIQUE);INSERT INTO Parent SELECT *
>> > FROM Temp;DROP TABLE Temp;COMMIT;
>> >
>> > Query2 - create [...] as select [...] fails
>> >
>> > BEGIN TRANSACTION;CREATE TABLE Temp AS SELECT A FROM Parent;DROP TABLE
>> > Parent;CREATE TABLE Parent AS SELECT * FROM Temp;     -- different
>> > from Query1CREATE UNIQUE INDEX ParentIndex on Parent(A);  -- different
>> > from Query1DROP TABLE Temp;COMMIT;
>> >
>> > Result:
>> >
>> > sqlite> PRAGMA foreign_key_check;
>> > sqlite> .schemaCREATE TABLE Child(C TEXT REFERENCES Parent(A)
>> > DEFERRABLE INITIALLY DEFERRED);CREATE TABLE Parent(A TEXT);CREATE
>> > UNIQUE INDEX ParentIndex on Parent(A);
>> > sqlite> SELECT * FROM Parent;
>> > whatever
>> >
>> > Query3 - insert into [...] fails
>> >
>> > BEGIN TRANSACTION;CREATE TABLE Temp (A TEXT UNIQUE);      -- different
>> > from Query1INSERT INTO Temp SELECT A FROM Parent;  -- different from
>> > Query1DROP TABLE Parent;CREATE TABLE Parent (A TEXT UNIQUE);INSERT
>> > INTO Parent SELECT * FROM Temp;DROP TABLE Temp;COMMIT;
>> >
>> > Result:
>> >
>> > sqlite> PRAGMA foreign_key_check;
>> > sqlite> .schemaCREATE TABLE Child(C TEXT REFERENCES Parent(A)
>> > DEFERRABLE INITIALLY DEFERRED);CREATE TABLE Parent (A TEXT UNIQUE);
>> > sqlite> SELECT * FROM Parent;
>> > whatever
>> >
>> > Note that PRAGMA foreign_key_check does not report any problem in any of
>> > the cases.
>> >
>> >
>> > I posted an identical question on StackOverflow, but no one was able to
>> > provide any information so far. Thanks in advance!
>> >
>> > Máté Szabó
>> > _______________________________________________
>> > 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-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to