_get_scalar_relation_map (src/read.jl:594) issues a SELECT with no ORDER BY. When the FK column has a covering index, SQLite scans via the index in FK-value order, so the returned vector is shuffled and no longer aligned with source rows in id order.
using PSRDatabase
work_dir = mktempdir()
mig1 = joinpath(work_dir, "migrations", "1"); mkpath(mig1)
write(joinpath(mig1, "up.sql"), """
PRAGMA user_version = 1;
CREATE TABLE Configuration (id INTEGER PRIMARY KEY, label TEXT UNIQUE NOT NULL DEFAULT 'Configuration') STRICT;
CREATE TABLE System (id INTEGER PRIMARY KEY, label TEXT UNIQUE NOT NULL) STRICT;
CREATE TABLE Transmission (
id INTEGER PRIMARY KEY, label TEXT UNIQUE NOT NULL,
system_origin_id INTEGER, system_destination_id INTEGER,
FOREIGN KEY (system_origin_id) REFERENCES System (id) ON UPDATE CASCADE ON DELETE SET NULL,
FOREIGN KEY (system_destination_id) REFERENCES System (id) ON UPDATE CASCADE ON DELETE SET NULL
) STRICT;
CREATE INDEX idx_origin ON Transmission (system_origin_id);
""")
write(joinpath(mig1, "down.sql"), "DROP TABLE Transmission; DROP TABLE System; DROP TABLE Configuration;")
dbfile = joinpath(work_dir, "study.sqlite")
PSRDatabase.close!(PSRDatabase.create_empty_db_from_migrations(dbfile, joinpath(work_dir, "migrations"); force = true))
using PSRDatabase.SQLite, PSRDatabase.DBInterface
sdb = SQLite.DB(dbfile)
for s in ("SE", "SU", "NE")
DBInterface.execute(sdb, "INSERT INTO System (label) VALUES (?)", (s,))
end
for (l, o, d) in [("L1", 1, 2), ("L2", 2, 1), ("L3", 1, 3), ("L4", 3, 1)]
DBInterface.execute(sdb,
"INSERT INTO Transmission (label, system_origin_id, system_destination_id) VALUES (?,?,?)",
(l, o, d))
end
DBInterface.close!(sdb)
db = PSRDatabase.load_db(dbfile; read_only = true)
got = PSRDatabase.read_scalar_relations(db, "Transmission", "System", "origin_id")
expected = ["SE", "SU", "SE", "NE"] # rows L1..L4 origin labels in id order
println("got: ", got)
println("expected: ", expected)
PSRDatabase.close!(db)
Got:
got: Any["SE", "SE", "SU", "NE"]
expected: ["SE", "SU", "SE", "NE"]
_get_scalar_relation_map (src/read.jl:594) issues a SELECT with no ORDER BY. When the FK column has a covering index, SQLite scans via the index in FK-value order, so the returned vector is shuffled and no longer aligned with source rows in id order.
Got: