SQLite Forum

DROP TABLE failure - is it intentional or a bug?
Login
Ah, I see now what confused you.

It wasn't the base references that broke - that is very much allowed.   
Your schema breaks because of what you specified it should DO when removing entries for those references.

In other words, your original script (unlike this new one you've posted) included REFERENCES to columns with ON DELETE CASCADE and ON DELETE RESTRICT directives.

When you say DROP the "dataset" table, the first thing that is needed is to see if there are any entries in a referred table that will be affected, and sure enough, there is a "REFERENCES dataset(id)" entry in the "trace" table with an "ON DELETE CASCADE" directive, so it knows that any deletes from this drop have to be also deleted (via the id) in that "traces" table, but wait, does deleting from the "traces" table affect any other table? Well YES, there is a reference to the another table that says "ON DELETE RESTRICT", as in prevent the deletes from happening if they exist in the target table, and when checking THAT table, it sees that it doesn't exist anymore, and thus fails with that message. 

That's why the schema is broken and that is why you get the error.

There's actually more than one problematic reference, but I've reduced it and made a minimal example that still breaks using your original tables (with any unimportant fields removed):

```
  -- SQLite version 3.35.2  [ Release: 2021-03-17 ]  on  SQLitespeed version 2.1.3.11.
  -- ================================================================================================
CREATE TABLE IF NOT EXISTS "dataset" (
  id INTEGER PRIMARY KEY AUTOINCREMENT
);

CREATE TABLE IF NOT EXISTS "trace" (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  datasetid INTEGER NOT NULL REFERENCES dataset(id) ON UPDATE CASCADE ON DELETE CASCADE,
  quantityid INTEGER NOT NULL REFERENCES quantity(id) ON UPDATE CASCADE ON DELETE RESTRICT
);

DROP TABLE IF EXISTS dataset;

  -- -------  DB-Engine Logs (Contains logged information from all DB connections during run)  ------
  -- [2021-03-25 01:23:11.007] QUERY       : Failed Query: DROP TABLE IF EXISTS dataset;  
  -- [2021-03-25 01:23:11.007] INTERFACE   : DB Error: no such table: main.quantity
  -- ================================================================================================
```
Note 1: If you change any of the ON DELETE CASCADE/RESTRICT directives, it all will work because a non-existing reference will be ignored, but a RESTRICT directive cannot be ignored (and the RESTRICT directive won't be activated if the CASCADE directive wasn't there signalling that deletes may happen). Also, the Query engine cannot know that the table is empty or there will be no rows affected at the time of preparing the statement, it only sees that it "should" check for deletes and restrict it where needed, but putting that mechanism in place fails because that referenced table doesn't exist.

Note 2: Dropping the "type" table or not is irrelevant to the problem. Dropping the "trace" table first (with the RESTRICT directive) also fixes the problem.