[spip-dev] Problème des jointures avec PostGreSQL quand on utilise des schémas

Bonjour,

j'utilise une base de données PostGreSQL avec des schémas:
http://docs.postgresqlfr.org/8.4/ddl-schemas.html
qui sont, en gros, une manière de grouper les tables d'une même base en
groupes sémantiques.
Au lieu d'accéder à une table par: SELECT ... FROM table, on y
accède par SELECT ... FROM schema1.table si elle se trouve dans le
schema schema1.

Le problème est que lors de l'utilisation des jointures dans les boucles de
SPIP, le schéma disparaît dans la ligne INNER JOIN ..., alors qu'il est présent
sur la ligne FROM.
Il faudrait conserver l'information complète "schema.table"
au lieu de "table" sur la ligne "INNER JOIN".

Tout est détaillé dans le petit exemple ci-dessous. Pour info et pour bien
comprendre, le schéma "public" est le schéma par défaut de PostGreSQL, et la
requête SELECT ... FROM table fonctionnera si "table" est dans le schéma
"public" ("public.table").
En revanche pour accéder aux tables des autres
schémas, il faut les spécifier explicitement "schema1.table".

--- Création SQL ---
http://pastebin.com/B3ZNa8p8

--- Squelette ---
http://pastebin.com/TBvmy9va

--- Résultat HTML ---
http://pastebin.com/iuAvUema

--- Résultat du débogueur SPIP ---
http://pastebin.com/Dbn9x7Ru

J'espère que cette présentation aride intéressera qqn :slight_smile: Je suis prêt à donner
plus de détails si c'est confus...

Severo

PS: on peut contourner le problème depuis PostGreSQL en modifiant le
"search_path" pour rechercher dans tous les schémas lorsque seul le nom de la
table est spécifié. Pour cela, dans l'exemple ci-dessus:
  ALTER DATABASE test SET search_path=schema1,public;

C'est assez délicat parce que justement le nom du schéma doit être éliminé dans certains cas, c'était le sens de:
http://core.spip.org/projects/export/repository/revisions/10652/diff/spip/ecrire/base/trouver_table.php
il faudrait regarder en détail car en 3 ans j'ai bien oublié pourquoi il fallait le faire, et le message est cryptique:
http://core.spip.org/projects/export/repository/revisions/10652

Committo,Ergo:Sum

Normalement en élargissant le "search_path" de PostGreSQL à
tous les schémas qui nous intéressent, on s'en sort.

Malheureusement, pour mon cas, je crois que je vais me passer
des jointures. J'utilise une base externe, PostGreSQL, avec des
schemas, ce qui me donne une boucle du genre

<BOUCLE_partidos(atlas:elec.candidatos atlas:elec.partidos){tous}...>
  #ID_PARTIDO #ID_CANDIDATO #NOMBRE
</BOUCLE_partidos>

et je n'arrive pas à selectionner la colonne (id_partido) qui
doit faire la jointure. Je veux avoir:
... ON (atlas:elec.partidos.id_partido=atlas:elec.candidatos.id_partido)

et je me retrouve avec un
SELECT elec.candidatos.id_partido,
       elec.candidatos.id_candidato,
       L1.nombre
  FROM elec.candidatos
  INNER JOIN partidos AS L1 ON ( L1.sigla = elec.candidatos.sigla )

alors que elec.candidatos n'a pas de colonne "sigla"...

Je ne sais pas si je m'y prends mal pour selectionner cette
colonne id_partido, mais j'ai cherché dans tous les sens,
je n'y arrive pas. Quelle serait la boucle correcte ?
Est-ce possible avec ma configuration ?

je me réponds: la jointure se faisait mal parce que j'avais plusieurs clés
primaires dans la table partidos (contraintes UNIQUE + NON NULL = clé primaire).
Du coup SPIP choisit une des clés primaires, malheureusement pas la bonne pour
moi.

Il me reste a trouver comment selectionner la bonne clé primaire, mais je pense
que je suis plus dans la bonne liste de mails.

je me réponds: la jointure se faisait mal parce que j'avais plusieurs clés
primaires dans la table partidos (contraintes UNIQUE + NON NULL = clé primaire).
Du coup SPIP choisit une des clés primaires, malheureusement pas la bonne pour
moi.

Il est étonnant voire bugant que le compilateur choisisse pour faire la jointure
une clé primaire qui n'existe que dans une seule des tables...

Il me reste a trouver comment selectionner la bonne clé primaire, mais je pense
que je suis plus dans la bonne liste de mails.

en inversant l'ordre dans lequel ils apparaissent dans la table...
:frowning:

JL