Je travaille sur une fonction qui me permet d'ajouter un index s'il n'existe pas. Je rencontre le problème que je ne peux pas obtenir une liste d'index à comparer. Des pensées?
Il s'agit d'un problème similaire à celui de la création de colonnes qui est résolu avec ce code:
https://stackoverflow.com/a/12603892/368511
Si vous ne vous souciez pas du nom de l'index, demandez à Postgres de le nommer automatiquement:
CREATE INDEX ON tbl1 (col1);
est (presque) identique à:
CREATE INDEX tbl1_col1_idx ON tbl1 USING btree (col1);
Sauf que Postgres évitera les collisions de noms et choisira automatiquement le prochain nom gratuit:
tbl1_col1_idx
tbl1_col1_idx2
tbl1_col1_idx3
...
Essayez-le. Mais, évidemment, vous ne voudriez pas créer plusieurs index redondants. Il ne serait donc pas judicieux d'en créer un aveuglément.
Un moyen très simple de tester consiste à convertir le nom qualifié du schéma en regclass
:
SELECT 'myschema.myname'::regclass;
S'il lève une exception, le nom est libre.
Ou, pour tester le même sans lever d'exception, utilisé dans une instruction DO
:
DO
$$
BEGIN
IF NOT EXISTS (
SELECT
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relname = 'mytable_mycolumn_idx'
AND n.nspname = 'myschema'
) THEN
CREATE INDEX mytable_mycolumn_idx ON myschema.mytable (mycolumn);
END IF;
END
$$;
Cela ne fonctionne pas pour CREATE INDEX CONCURRENTLY
, Car cette variante ne peut pas être encapsulée dans une transaction externe. Voir commentaire de @Gregory ci-dessous.
L'instruction DO
a été introduite avec Postgres 9.0. Dans les versions antérieures, vous devez créer une fonction pour faire de même.
Détails sur pg_class
Dans le manuel .
Notions de base sur index dans le manuel .
Vous pouvez utiliser la nouvelle fonction to_regclass()
pour vérifier sans lever d'exception:
DO
$$
BEGIN
IF to_regclass('myschema.mytable_mycolumn_idx') IS NULL THEN
CREATE INDEX mytable_mycolumn_idx ON myschema.mytable (mycolumn);
END IF;
END
$$;
Renvoie NULL si un index (ou un autre objet) de ce nom n'existe pas. Voir:
Maintenant disponible:
CREATE INDEX IF NOT EXISTS ...
Cela fonctionne également pour CREATE INDEX CONCURRENTLY IF NOT EXISTS
.
Cependant, le manuel met en garde :
Notez qu'il n'y a aucune garantie que l'index existant ressemble à celui qui aurait été créé.
C'est une simple vérification du nom de l'objet. S'applique à toutes les variantes ici.
Il sera disponible en 9.5. Voici le vrai git commit https://github.com/postgres/postgres/commit/08309aaf74ee879699165ec8a2d53e56f2d2e947
Discussion sur les pirates informatiques pg http://postgresql.nabble.com/CREATE-IF-NOT-EXISTS-INDEX-td5821173.html