tsapi-seriesdb-shared-sql/sql/migrate/migrate_drop_series_if_exists.sql
peter eed06559c0 Canonical TSAPI series DB schema v1.0.0
Single source of truth for the timeseries PostgreSQL schema shared by the
Python (TSAPI_SERIESDB_PG_PY) and C++ (TSAPI_POSTGRES_CPP) libraries. SQL
seeded byte-for-byte from TSAPI_SERIESDB_PG_PY/tsapi_pgdb/sql on 2026-09-02.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-02 17:27:26 +01:00

48 lines
1.8 KiB
PL/PgSQL

-- Migration: repair meta.drop_series_if_exists()
--
-- The function dropped a registered series without setting
-- application.dropping_series, so the prevent_direct_drop event trigger
-- rejected its own DROP:
--
-- Table series.X is registered in series and can only be dropped
-- using TimeseriesDB.drop_series()
--
-- Unlike meta.drop_series() and meta.drop_all_series(), which set the flag
-- correctly, this one never did -- so it always failed on exactly the case it
-- exists to handle. The Python API does not call it, which is why the defect
-- went unnoticed.
--
-- New databases pick this up from 05_procedures.sql. Run this against any
-- database initialised before the fix.
--
-- Safe to run more than once (CREATE OR REPLACE).
CREATE OR REPLACE FUNCTION meta.drop_series_if_exists(_table_name text, _schema_name text DEFAULT 'series'::text)
RETURNS void
LANGUAGE plpgsql
AS $function$
BEGIN
-- Check if the series exists in series table
IF EXISTS (
SELECT 1 FROM meta.series
WHERE "table_name" = _table_name
AND "db_schema" = _schema_name
) THEN
-- Signal the prevent_direct_drop event trigger that this DROP is
-- coming from a sanctioned procedure. Without it the trigger rejects
-- the statement below, because the table is registered in meta.series.
-- Local to the transaction, so it cannot leak to later statements.
PERFORM set_config('application.dropping_series', 'true', true);
-- Drop the table
EXECUTE format('DROP TABLE IF EXISTS %I.%I', _schema_name, _table_name);
-- Remove from series table
DELETE FROM meta.series
WHERE "table_name" = _table_name
AND "db_schema" = _schema_name;
PERFORM set_config('application.dropping_series', 'false', true);
END IF;
END;
$function$;