-- ============================================================ -- CHECK TABLE SIZES - Run in Supabase SQL Editor -- ============================================================ -- Part 1: Shows all public tables with sizes (auto-discovers) -- Part 2: Cleanup candidate counts (only for tables that exist) -- ============================================================ -- PART 1: All public table sizes SELECT c.relname AS table_name, pg_size_pretty(pg_total_relation_size(c.oid)) AS total_size, pg_size_pretty(pg_relation_size(c.oid)) AS data_size, pg_size_pretty(pg_total_relation_size(c.oid) - pg_relation_size(c.oid)) AS index_size, c.reltuples::bigint AS estimated_rows FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace WHERE n.nspname = 'public' AND c.relkind = 'r' ORDER BY pg_total_relation_size(c.oid) DESC; -- PART 2: Cleanup candidates (safe — checks table existence before querying) DO $$ DECLARE rec RECORD; row_count bigint; cleanup_count bigint; query text; BEGIN RAISE NOTICE '--- CLEANUP CANDIDATE BREAKDOWN ---'; -- Processing jobs IF EXISTS (SELECT 1 FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace WHERE n.nspname = 'public' AND c.relname = 'processing_jobs') THEN SELECT count(*), count(*) FILTER (WHERE status IN ('completed', 'failed') AND completed_at < NOW() - INTERVAL '30 days') INTO row_count, cleanup_count FROM processing_jobs; RAISE NOTICE 'processing_jobs: % total, % cleanup candidates (completed/failed > 30d)', row_count, cleanup_count; END IF; -- Vector similarity searches IF EXISTS (SELECT 1 FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace WHERE n.nspname = 'public' AND c.relname = 'vector_similarity_searches') THEN SELECT count(*), count(*) FILTER (WHERE created_at < NOW() - INTERVAL '90 days') INTO row_count, cleanup_count FROM vector_similarity_searches; RAISE NOTICE 'vector_similarity_searches: % total, % cleanup candidates (> 90d)', row_count, cleanup_count; END IF; -- Session events IF EXISTS (SELECT 1 FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace WHERE n.nspname = 'public' AND c.relname = 'session_events') THEN SELECT count(*), count(*) FILTER (WHERE created_at < NOW() - INTERVAL '30 days') INTO row_count, cleanup_count FROM session_events; RAISE NOTICE 'session_events: % total, % cleanup candidates (> 30d)', row_count, cleanup_count; END IF; -- Execution events IF EXISTS (SELECT 1 FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace WHERE n.nspname = 'public' AND c.relname = 'execution_events') THEN SELECT count(*), count(*) FILTER (WHERE created_at < NOW() - INTERVAL '30 days') INTO row_count, cleanup_count FROM execution_events; RAISE NOTICE 'execution_events: % total, % cleanup candidates (> 30d)', row_count, cleanup_count; END IF; -- Performance metrics IF EXISTS (SELECT 1 FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace WHERE n.nspname = 'public' AND c.relname = 'performance_metrics') THEN SELECT count(*), count(*) FILTER (WHERE created_at < NOW() - INTERVAL '90 days') INTO row_count, cleanup_count FROM performance_metrics; RAISE NOTICE 'performance_metrics: % total, % cleanup candidates (> 90d)', row_count, cleanup_count; END IF; -- Service health checks IF EXISTS (SELECT 1 FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace WHERE n.nspname = 'public' AND c.relname = 'service_health_checks') THEN SELECT count(*), count(*) FILTER (WHERE created_at < NOW() - INTERVAL '30 days') INTO row_count, cleanup_count FROM service_health_checks; RAISE NOTICE 'service_health_checks: % total, % cleanup candidates (> 30d)', row_count, cleanup_count; END IF; -- Alert events IF EXISTS (SELECT 1 FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace WHERE n.nspname = 'public' AND c.relname = 'alert_events') THEN SELECT count(*), count(*) FILTER (WHERE created_at < NOW() - INTERVAL '30 days') INTO row_count, cleanup_count FROM alert_events; RAISE NOTICE 'alert_events: % total, % cleanup candidates (> 30d)', row_count, cleanup_count; END IF; -- Agent executions IF EXISTS (SELECT 1 FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace WHERE n.nspname = 'public' AND c.relname = 'agent_executions') THEN SELECT count(*), count(*) FILTER (WHERE created_at < NOW() - INTERVAL '90 days') INTO row_count, cleanup_count FROM agent_executions; RAISE NOTICE 'agent_executions: % total, % cleanup candidates (> 90d)', row_count, cleanup_count; END IF; -- Agentic RAG sessions IF EXISTS (SELECT 1 FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace WHERE n.nspname = 'public' AND c.relname = 'agentic_rag_sessions') THEN SELECT count(*), count(*) FILTER (WHERE created_at < NOW() - INTERVAL '90 days') INTO row_count, cleanup_count FROM agentic_rag_sessions; RAISE NOTICE 'agentic_rag_sessions: % total, % cleanup candidates (> 90d)', row_count, cleanup_count; END IF; -- Processing quality metrics IF EXISTS (SELECT 1 FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace WHERE n.nspname = 'public' AND c.relname = 'processing_quality_metrics') THEN SELECT count(*), count(*) FILTER (WHERE created_at < NOW() - INTERVAL '90 days') INTO row_count, cleanup_count FROM processing_quality_metrics; RAISE NOTICE 'processing_quality_metrics: % total, % cleanup candidates (> 90d)', row_count, cleanup_count; END IF; -- Documents extracted_text IF EXISTS (SELECT 1 FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace WHERE n.nspname = 'public' AND c.relname = 'documents') THEN SELECT count(*), count(*) FILTER (WHERE status = 'completed' AND analysis_data IS NOT NULL AND extracted_text IS NOT NULL AND created_at < NOW() - INTERVAL '30 days') INTO row_count, cleanup_count FROM documents; RAISE NOTICE 'documents (extracted_text nullable): % total, % cleanup candidates (completed > 30d with analysis_data)', row_count, cleanup_count; END IF; RAISE NOTICE '--- END CLEANUP BREAKDOWN ---'; END $$;