Это некрасиво, но, похоже, работает:
--SET search_path='tmp';
DROP TABLE dontinsert CASCADE;
CREATE TABLE dontinsert
( id INTEGER NOT NULL PRIMARY KEY
);
DROP TABLE doinsert CASCADE;
CREATE TABLE doinsert ()
INHERITS (dontinsert)
;
CREATE RULE dont_do_it AS
ON INSERT TO dontinsert
DO INSTEAD NOTHING
;
INSERT INTO dontinsert(id) VALUES( 13) ;
INSERT INTO doinsert(id) VALUES( 42) ;
SELECT id AS id_from_dont FROM dontinsert;
SELECT id AS id_from_do FROM doinsert;
Результат:
SET
NOTICE: drop cascades to table doinsert
DROP TABLE
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "dontinsert_pkey" for table "dontinsert"
CREATE TABLE
ERROR: table "doinsert" does not exist
CREATE TABLE
CREATE RULE
INSERT 0 0
INSERT 0 1
id_from_dont
--------------
42
(1 row)
id_from_do
------------
42
(1 row)
ОБНОВЛЕНИЕ: так как ОП хочет, чтобы вставки не работали с большим шумом, у меня былодобавить канареечную таблицу с невозможным ограничением:
DROP TABLE alwaysempty CASCADE;
CREATE TABLE alwaysempty
( id INTEGER NOT NULL
);
ALTER TABLE alwaysempty
ADD CONSTRAINT dont_insert_you_sucker CHECK (id > 0 AND id < 0)
;
CREATE RULE dont_do_it AS
ON INSERT TO dontinsert
DO INSTEAD -- NOTHING
INSERT INTO alwaysempty (id)
VALUES (NEW.id)
;
Новый вывод:
SET
NOTICE: drop cascades to table doinsert
DROP TABLE
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "dontinsert_pkey" for table "dontinsert"
CREATE TABLE
ERROR: table "doinsert" does not exist
CREATE TABLE
DROP TABLE
CREATE TABLE
ALTER TABLE
CREATE RULE
ERROR: new row for relation "alwaysempty" violates check constraint "dont_insert_you_sucker"
INSERT 0 1
id_from_dont
--------------
42
(1 row)
id_from_do
------------
42
(1 row)
Следующая попытка: переместить (ТОЛЬКО) базовую таблицу в недоступную схему (так как я действительно ненавижу вызывает) ...
SET search_path='tmp';
DROP SCHEMA hidden CASCADE;
CREATE SCHEMA hidden;
REVOKE ALL ON SCHEMA hidden FROM PUBLIC;
DROP TABLE dontinsert CASCADE;
CREATE TABLE dontinsert
( id INTEGER NOT NULL PRIMARY KEY
);
DROP TABLE doinsert CASCADE;
CREATE TABLE doinsert ()
INHERITS (dontinsert)
;
ALTER TABLE ONLY dontinsert SET SCHEMA hidden;
INSERT INTO alwaysempty (id) VALUES (NEW.id) ;
INSERT INTO dontinsert(id) VALUES( 13) ;
INSERT INTO doinsert(id) VALUES( 42) ;
SELECT id AS id_from_dont FROM hidden.dontinsert;
SELECT id AS id_from_do FROM doinsert;