Files
query-orchestration/internal/database/migrations/00000000000119_remove_queries.down.sql
T
Jay Brown c10fa98d0a Merged in feature/restore-migrations-v2 (pull request #205)
Restore original migrations (001-120) to fix schema_migrations version mismatch

* Restore original migrations (001-120) to fix schema_migrations version mismatch

The previous migration collapse broke deployed databases because:
- Dev database was at version 120 (the real remove_text_extraction migration)
- Main had collapsed migrations (001-012) + stub files (119_stub, 120_stub)
- The migrate tool couldn't find version 119/120 with matching content

This commit restores the original 27 migrations (versions 001-120) from
before the collapse, ensuring backward compatibility with existing databases.
2026-01-15 23:18:53 +00:00

288 lines
9.9 KiB
PL/PgSQL

-- Down migration to restore query functionality
-- This recreates all query-related tables, views, and functions
-- Drop the simplified fullActiveCollectors view
DROP VIEW IF EXISTS fullActiveCollectors;
-- Recreate query type enum
CREATE TYPE queryType AS ENUM ('context_full', 'json_extractor');
-- Recreate queries table
CREATE TABLE queries (
queryId uuid primary key DEFAULT uuid_generate_v7(),
queryType queryType not null
);
-- Recreate queryVersions table
CREATE TABLE queryVersions (
queryId uuid not null,
versionId int not null,
addedAt timestamp not null default current_timestamp,
primary key (versionId, queryId),
foreign key (queryId) references queries(queryId)
);
-- Recreate version number function and trigger
CREATE OR REPLACE FUNCTION setQueryVersionNumber()
RETURNS TRIGGER AS $$
BEGIN
SELECT COALESCE(MAX(versionId), 0) + 1
INTO NEW.versionId
FROM queryVersions
WHERE queryId = NEW.queryId;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER setQueryVersionNumberTrigger
BEFORE INSERT ON queryVersions
FOR EACH ROW
EXECUTE FUNCTION setQueryVersionNumber();
-- Recreate queryActiveVersions table
CREATE TABLE queryActiveVersions (
activeVersionEntryId uuid primary key DEFAULT uuid_generate_v7(),
queryId uuid not null,
versionId int not null,
foreign key (queryId, versionId) references queryVersions(queryId, versionId)
);
-- Recreate requiredQueries table
CREATE TABLE requiredQueries (
requiredQueryEntryId uuid primary key DEFAULT uuid_generate_v7(),
queryId uuid not null,
requiredQueryId uuid not null,
addedVersion int not null,
removedVersion int,
foreign key (queryId) references queries(queryId),
foreign key (requiredQueryId) references queries(queryId),
foreign key (queryId, addedVersion) references queryVersions(queryId, versionId),
foreign key (queryId, removedVersion) references queryVersions(queryId, versionId),
unique (queryId, requiredQueryId, removedVersion)
);
-- Recreate queryConfigs table
CREATE TABLE queryConfigs (
configId uuid primary key DEFAULT uuid_generate_v7(),
queryId uuid not null,
config jsonb not null,
addedVersion int not null,
removedVersion int,
foreign key (queryId) references queries(queryId),
foreign key (queryId, addedVersion) references queryVersions(queryId, versionId),
foreign key (queryId, removedVersion) references queryVersions(queryId, versionId),
unique (queryId, removedVersion)
);
-- Recreate removeQueryConfig function and trigger
CREATE OR REPLACE FUNCTION removeQueryConfig()
RETURNS TRIGGER AS $$
BEGIN
UPDATE queryConfigs
SET removedVersion = NEW.addedVersion
WHERE queryId = NEW.queryId and removedVersion is null;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER removeQueryConfigTrigger
BEFORE INSERT ON queryConfigs
FOR EACH ROW
EXECUTE FUNCTION removeQueryConfig();
-- Recreate collectorQueries table
CREATE TABLE collectorQueries (
id uuid primary key DEFAULT uuid_generate_v7(),
clientId varchar(255) not null,
name varchar(255) not null,
queryId uuid not null,
addedVersion int not null,
removedVersion int,
foreign key (queryId) references queries(queryId),
foreign key (clientId) references clients(clientId),
foreign key (clientId, addedVersion) references collectorVersions(clientId, id),
foreign key (clientId, removedVersion) references collectorVersions(clientId, id),
unique (clientId, name, removedVersion)
);
-- Recreate results table
CREATE TABLE results (
id uuid primary key DEFAULT uuid_generate_v7(),
textEntryId uuid not null,
queryId uuid not null,
value TEXT not null,
queryVersion int not null,
foreign key (queryId) references queries(queryId),
foreign key (textEntryId) references documentTextExtractions(id),
foreign key (queryId, queryVersion) references queryVersions(queryId, versionId)
);
-- Recreate resultDependencies table
CREATE TABLE resultDependencies (
resultId uuid not null,
requiredResultId uuid not null,
foreign key (resultId) references results(id),
foreign key (requiredResultId) references results(id),
CONSTRAINT result_not_self_dependent CHECK (resultId != requiredResultId)
);
-- Recreate query views
CREATE VIEW queryCurrentActiveVersions as
SELECT DISTINCT
q.queryId,
coalesce(
(FIRST_VALUE(av.versionId) OVER (PARTITION BY q.queryId ORDER BY av.activeVersionEntryId DESC)),
0
)::int as activeVersion
FROM queries AS q
LEFT JOIN queryActiveVersions as av on av.queryId = q.queryId;
CREATE VIEW queryLatestVersions as
SELECT
q.queryId,
coalesce(max(v.versionId), 0)::int as latestVersion
FROM queries AS q
LEFT JOIN queryVersions as v on v.queryId = q.queryId
GROUP BY q.queryId;
CREATE VIEW queryCurrentConfigs as
SELECT av.queryId, c.config
FROM queryCurrentActiveVersions as av
LEFT JOIN queryConfigs AS c ON av.queryId = c.queryId
and isInVersion(av.activeVersion, c.addedVersion, c.removedVersion);
CREATE VIEW queryCurrentRequiredIds as
SELECT DISTINCT av.queryId, r.requiredQueryId
FROM queryCurrentActiveVersions as av
LEFT JOIN requiredQueries AS r ON av.queryId = r.queryId
and isInVersion(av.activeVersion, r.addedVersion, r.removedVersion);
CREATE VIEW queryCurrentRequiredIdsAGG as
SELECT queryId,
coalesce(
ARRAY_AGG(DISTINCT requiredQueryId)
FILTER (WHERE requiredQueryId != '00000000-0000-0000-0000-000000000000')::uuid[],
array[]::uuid[]
)::uuid[] as requiredIds
FROM queryCurrentRequiredIds
GROUP BY queryId;
CREATE VIEW fullActiveQueries AS
SELECT DISTINCT q.queryId, q.queryType, av.activeVersion, lv.latestVersion, c.config, r.requiredIds
FROM queries AS q
JOIN queryCurrentActiveVersions as av on q.queryId = av.queryId
JOIN queryLatestVersions as lv on lv.queryId = q.queryId
JOIN queryCurrentConfigs AS c ON q.queryId = c.queryId
JOIN queryCurrentRequiredIdsAGG AS r ON q.queryId = r.queryId;
CREATE VIEW queryActiveDependencies AS
WITH RECURSIVE queryActiveDependencies(queryId, requiredQueryId, path, cycle) AS (
SELECT
queryId,
requiredQueryId,
ARRAY[queryId, requiredQueryId]::uuid[] AS path,
false AS cycle
FROM queryCurrentRequiredIds
UNION ALL
SELECT
q.queryId,
qd.requiredQueryId,
path || qd.requiredQueryId,
qd.requiredQueryId = ANY(path) AS cycle
FROM queryCurrentRequiredIds as q
JOIN queryActiveDependencies as qd ON q.queryId = qd.requiredQueryId
WHERE NOT qd.cycle
)
SELECT DISTINCT queryId as id, requiredQueryId
FROM queryActiveDependencies
WHERE NOT cycle;
-- Recreate collector views that depend on queries
CREATE VIEW currentCollectorQueries as
SELECT DISTINCT
av.clientId,
q.name,
q.queryId
FROM collectorCurrentActiveVersions as av
LEFT JOIN collectorQueries AS q ON av.clientId = q.clientId
and isInVersion(av.activeVersion, q.addedVersion, q.removedVersion);
CREATE VIEW currentCollectorQueriesJSONAGG as
SELECT DISTINCT
clientId,
jsonb_object_agg(name, queryId) FILTER (WHERE name is not null) AS fields
FROM currentCollectorQueries
GROUP BY clientId;
CREATE VIEW fullActiveCollectors AS
SELECT DISTINCT av.clientId,
ccv.minCleanVersion, ctv.minTextVersion,
av.activeVersion, lv.latestVersion,
q.fields
FROM collectorCurrentActiveVersions as av
JOIN collectorLatestVersions as lv on lv.clientId = av.clientId
JOIN currentCollectorMinCleanVersions AS ccv ON av.clientId = ccv.clientId
JOIN currentCollectorMinTextVersions AS ctv ON av.clientId = ctv.clientId
JOIN currentCollectorQueriesJSONAGG AS q ON av.clientId = q.clientId;
CREATE VIEW collectorQueryDependencyTree AS
WITH RECURSIVE collectorQueryDependencyTree AS (
SELECT cq.clientId, cq.queryId, ri.requiredIds
FROM currentCollectorQueries as cq
JOIN queryCurrentRequiredIdsAGG as ri on cq.queryId = ri.queryId
UNION ALL
SELECT acq.clientId, q.queryId, q.requiredIds
FROM queryCurrentRequiredIdsAGG as q
JOIN collectorQueryDependencyTree as acq on q.queryId = ANY(acq.requiredIds)
)
SELECT DISTINCT ct.clientId, ct.queryId, q.queryType, av.activeVersion as queryVersion, ct.requiredIds
FROM collectorQueryDependencyTree as ct
JOIN queryCurrentActiveVersions as av on ct.queryId = av.queryId
JOIN queries as q on q.queryId = ct.queryId;
CREATE OR REPLACE FUNCTION collectorQueryDependencyTreeByClient(
_clientId varchar(255)
)
RETURNS TABLE (
clientId varchar(255),
queryId uuid,
queryType queryType,
queryVersion int,
requiredIds uuid[]
) AS $$
BEGIN
RETURN QUERY
WITH clientQueries as (
SELECT q.clientId, q.queryId
FROM currentCollectorQueries as q
WHERE q.clientId = _clientId
),
dependencyTree as (
WITH RECURSIVE collectorQueryDependencyTree AS (
SELECT cq.clientId, cq.queryId, ri.requiredIds
FROM clientQueries as cq
JOIN queryCurrentRequiredIdsAGG as ri on cq.queryId = ri.queryId
UNION ALL
SELECT acq.clientId, q.queryId, q.requiredIds
FROM queryCurrentRequiredIdsAGG as q
JOIN collectorQueryDependencyTree as acq on q.queryId = ANY(acq.requiredIds)
)
SELECT DISTINCT ct.clientId, ct.queryId, q.queryType, av.activeVersion as queryVersion, ct.requiredIds
FROM collectorQueryDependencyTree as ct
JOIN queryCurrentActiveVersions as av on ct.queryId = av.queryId
JOIN queries as q on q.queryId = ct.queryId
)
SELECT t.clientId, t.queryId, t.queryType, t.queryVersion, t.requiredIds
FROM dependencyTree as t
WHERE t.clientID is not null;
END;
$$ LANGUAGE plpgsql;