Le message d'erreur est
Vous avez deux EXECUTE
commandes :
_query := 'CREATE TABLE public.'
|| quote_ident(_table_name) || ' ( ) INHERITS (public.evidence)';
EXECUTE _query;
...
EXECUTE 'INSERT INTO public.'
|| quote_ident(_table_name) || ' VALUES ($1.*)' USING NEW;
La seule partie qui peut être NULL
est table_name
.
La seule chance pour table_name
devenir NULL
est ici :
SELECT raised_local_time FROM notifications WHERE id=_notification_id
INTO _raised_local_time;
La cause doit donc être l'une des deux raisons :
-
NEW.notification_id
estNULL
. -
Il n'y a pas de ligne dans les
notifications
pour leNEW.notification_id
donné .
Essayez cette fonction de déclenchement modifiée pour le débogage :
CREATE OR REPLACE FUNCTION partition_evidence_by_month()
RETURNS trigger AS
$func$
DECLARE
_table_name text;
BEGIN
SELECT 'evidence-' || to_char(raised_local_time, 'YYYY-MM')
FROM public.notifications -- schema-qualify to be sure
WHERE id = NEW.notification_id
INTO _table_name;
IF _table_name IS NULL THEN
RAISE EXCEPTION '_table_name is NULL. Should not occur!';
END IF;
IF NOT EXISTS ( -- create table if it does not exist
SELECT 1
FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind = 'r'
AND c.relname = _table_name
AND n.nspname = 'public') THEN
EXECUTE 'CREATE TABLE public.'
|| quote_ident(_table_name) || ' ( ) INHERITS (public.evidence)';
END IF;
EXECUTE 'INSERT INTO public.'
|| quote_ident(_table_name) || ' VALUES $1' -- Use NEW row directly
USING NEW; -- write data to the partition table
RETURN NULL;
END
$func$ LANGUAGE plpgsql;
-
Supprimez les variables inutilisées et simplifiez le code. (Il s'agit évidemment d'un exemple simplifié.)
-
Entre autres choses, vous n'avez pas besoin de
date_trunc()
du tout. Envoyez simplement l'horodatage d'origine àto_char()
. -
Inutile d'utiliser
varchar(n)
. Utilisez simplementtext
ouvarchar
. -
Évitez trop d'affectations inutiles - relativement coûteuses en PL/pgSQL.
-
-
Ajouter une
RAISE
pour vérifier mon hypothèse.
Si vous obtenez le message d'erreur, la distinction entre les deux causes possibles serait la prochaine étape. Ça devrait être trivial...