Quand / comment sont les valeurs par défaut de la valeur de l'expression des fonctions liées à l'égard de search_path?

StackOverflow https://stackoverflow.com//questions/25068040

Question

Pour des fins de test, j'ai ma propre mise en œuvre de la now() la fonction qui est public.now().À l'aide de search_path pour remplacer la valeur par défaut pg_catalog.now() avec ma propre version, l'ensemble fonctionne, mais j'ai une table avec une table avec un défaut d'expression de now().Montrant la table produit quelque chose de semblable à la suivante:

 start_date   | date    | not null default now()

Cependant, après un schéma de sauvegarder et de restaurer (pour un essai DB), le même spectacle de la table produit

 start_date   | date    | not null default pg_catalog.now()

Je suppose que de cela, d'abord la fonction dans l'expression par défaut n'est pas lié à un quelconque schéma et le search_path sera utilisé pour trouver la bonne.Cependant, de décharge ou de l'opération de restauration de l'air de "lier" la fonction de l'actuel.

Est ma compréhension de la "liaison" de la fonction correcte?Est-il un moyen de garder la unbound-ness de la fonction de sauvegarde/restauration des limites?

Était-ce utile?

La solution

Les valeurs par défaut sont analysées au moment de la création (début de la liaison!).Ce que vous voyez dans psql, pgAdmin ou d'autres clients est une représentation de texte, mais, en fait, l' OID de la fonction now() au moment de la création de la colonne par défaut est stocké dans le système de catalogue pg_attrdef.Je cite:

adbin   pg_node_tree  The internal representation of the column default value
adsrc   text          A human-readable representation of the default value

Lorsque vous modifiez l' search_path, qui provoque Postgres pour afficher le nom de la fonction de schéma-qualifiés, puisqu'il ne serait pas résolu plus correctement avec le courant search_path.

Dump et restore sont pas concernés par votre personnalisé search_path le réglage.Ils l'ont mis explicitement.Donc ce que vous voyez n'est pas lié à la le dump / restore cycle.

Remplacer les fonctions intégrées

Placer public avant pg_catalog dans le search_path est un jeu de hazard.Défavorisés utilisateurs (y compris vous-même) sont souvent autorisés à y écrire et de créer des fonctions qui peuvent, par inadvertance, annuler les fonctions du système - avec arbitraires (ou malveillante) résultat.

Vous voulez un dédié schéma avec accès restreint pour remplacer les fonctions intégrées.Utiliser quelque chose comme ceci à la place:

SET search_path = remplacer, pg_catalog, public;

Les détails dans ce liés à la réponse sur le dba.SE.

Autres conseils

La fonction par défaut est "lié" à l'heure de la contrainte par défaut est créé.La vue montrant le nom non qualifié est tout simplement abréger il.

Cela peut être démontré par l'insertion de lignes avant et après l'occultation de la fonction:

Set search_path to public,pg_catalog;

Create Temp Table foo (
    test date not null default now()
);

Insert Into foo default values;

Create Function public.now() Returns timestamp with time zone Language SQL As $$ 
     -- No idea why I chose this date.
     Select '1942-05-09'::timestamp with time zone;
$$;

Insert Into foo default values;

Select * from foo;

Notez que les deux lignes (inséré avant et après la fonction de création) contiennent la date d'aujourd'hui, pas le faux jour.

En outre, la création d'un tableau avec la fonction ci-dessus déjà dans le champ d'application, puis d'essayer de supprimer la fonction, les résultats d'une erreur de dépendance:

Set search_path to public,pg_catalog;

Create Function public.now() Returns timestamp with time zone Language SQL As $$ 
    Select '1942-05-09'::timestamp with time zone;
$$;

Create Temp Table bar (
    test date not null default now()
);

Insert Into bar default values;

Select * from bar;
-- Single row containing the dummy date rather than today

Drop Function public.now();
-- ERROR:  cannot drop function now() because other objects depend on it

Si la liaison s'est produit uniquement lors de l'insertion, il n'y aurait pas une telle dépendance.

Ne vous embêtez pas à tout ça.Postgres est parfois écrit weired choses après la les choses sont compilés.En particulier les Vues sont souvent changé de beyound reconnaissance.

Et:maintenant() et pg_catalog.maintenant() est normalement la même chose.Voir:

CREATE OR REPLACE FUNCTION now()
    RETURNS timestamp with time zone AS
'now'
    LANGUAGE internal STABLE STRICT
 COST 1;
 ALTER FUNCTION now()
    OWNER TO postgres;
 COMMENT ON FUNCTION now() IS 'current transaction time';

Ne vous inquiétez pas.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top