Vous n'êtes pas identifié(e).

#1 16/08/2010 10:26:07

iris
Membre

Fonction Postgres en C

Bonjour

Voici une fonction que j'ai creer :

http://pastebin.com/6h95N9Sf

c'est un trigger qui intervient Before Insert/update
Le trigger fonctionne ainsi que la fonction et l'insertion.
Le probleme survient quand je fais une requête de ce type :

select count(*),country from http group by country;

Le resultat est incorect ( du style : UK=12 FR=3 UK=2 UK=4 ) en gros : il ne regroupe pas (ne trie pas).

Voila, j'ai aussi testé avec du INT et ça marche tres bien ( comptage et regroupage).

Si quelqu'un a une idée wink

IRIS

Hors ligne

#2 16/08/2010 10:45:56

Marc Cousin
Membre

Re : Fonction Postgres en C

À priori, d'après le résultat, il regroupe. Simplement, il doit y avoir d'autres caractères dans les 'UK', soit non imprimables, soit des blancs, par exemple.


Marc.

Hors ligne

#3 16/08/2010 12:27:54

iris
Membre

Re : Fonction Postgres en C

comment verifer la présence de ces caracteres ?
est-ce qu'un petit script python qui select * from matable est suffisant, ou faut il aller plus loins ?

Dernière modification par iris (16/08/2010 12:31:01)

Hors ligne

#4 16/08/2010 12:36:15

Marc Cousin
Membre

Re : Fonction Postgres en C

si dans votre script python vous êtes capable d'afficher le résultat d'une façon qui mette en évidence les blancs par exemple, oui

Sinon, vous pouvez tout simplement faire un dump de la table (via pg_dump par exemple), trouver ces qq champs et les passer dans un éditeur hexadécimal, par exemple. Il y a de nombreuses façons de le faire. Pour juste les blancs :

select count(*), '<' || country || '>' from http group by country;


Marc.

Hors ligne

#5 16/08/2010 14:58:34

iris
Membre

Re : Fonction Postgres en C

J'ai effectué un pg_dump de ma base et hex-dumpé le tout  : voici la partie intéressante.

http://pastebin.com/CYzt7zHR

Je n'ai pas trouvé de caractère caché dans mon dump.
Il semble que postgres fasse un comptage en fonction d'une autre colonne ( j'ai découvert cela en effectuant plusieurs fois la même requête).


D'autre part je n'ai pas tout a fait compris votre requête.

select count(*), '<' || country || '>' from http group by country;

IRIS

Hors ligne

#6 16/08/2010 15:59:58

gleu
Administrateur

Re : Fonction Postgres en C

L'intérêt de cette requête, c'est qu'elle vous affiche la chaîne country entouré par des symboles. Donc si vous avez des espaces ou des tabulations (en bref, tout caractère normalement invisible), ils seront visibles grâce aux symboles (par exemple, <toto> se différencie bien de <toto >). Par contre, je ne suis pas sûr qu'elle fonctionne telle quelle. J'essairais plutôt :

select count(*), '<' || country || '>' from http group by 2;

Guillaume.

Hors ligne

#7 16/08/2010 16:44:20

Marc Cousin
Membre

Re : Fonction Postgres en C

Elle marche ma requête. Non mais ! smile


Marc.

Hors ligne

#8 16/08/2010 17:03:03

iris
Membre

Re : Fonction Postgres en C

C'est intéressant : voici le résultat : on ne voit pas le deuxième chevron.

select count(*), '<' || country || '>' from http group by 2;

 count |    ?column?    
-------+----------------
     2 | <United States
     1 | <United States
     2 | <United States
     1 | <United States
    12 | <United States
     1 | <United States
     1 | <United States

A quoi cela pourrait il être dû ?

PS , les deux requetes marches tongue

Dernière modification par iris (16/08/2010 17:06:12)

Hors ligne

#9 16/08/2010 22:54:36

Marc Cousin
Membre

Re : Fonction Postgres en C

Il y a des "cochonneries" (caractères non imprimables sans doute) dans votre chaîne de caractères, à priori. C'est ce qui fait que le group by échoue.

Pour savoir ce qui est dedans, le plus simple est encore de faire un dump de la table avec COPY (via pg_dump par exemple), puis de regarder les caractères avec un éditeur hexadécimal.


Marc.

Hors ligne

#10 17/08/2010 09:30:10

iris
Membre

Re : Fonction Postgres en C

Le pg_dump ne donne rien (cf post de 14:58:34 16 aout ) mais une requete de ce type  :
SELECT country,octet_length(country),count(*) FROM http GROUP BY country, octet_length(country);
me donne des valeurs farfelues.

 United States |           46 |     1
 United States |           46 |     1
 nited States  |           41 |     1
 nited States  |           41 |     1
 nited States  |           41 |     1
 nited States  |           41 |     1
 United States |           46 |    12
 United States |           46 |     2
 United States |           46 |     1
 nited States  |           41 |     2
 nited States  |           41 |     2
 nited States  |           41 |     1
 nited States  |           41 |     1
 United States |           46 |     2
 United States |           46 |     1

Donc, il semble qu'il y ai effectivement des problemes de caractères mais le pg_dump ne me sort rien.
est-il possible que ce sois le palloc de mon trigger qui ne fasse pas bien son travail ?
sachant que le strlen sur la string que je remplis me sort une valeur correct.

IRIS

Hors ligne

#11 17/08/2010 15:05:23

iris
Membre

Re : Fonction Postgres en C

Parfait ! j'ai résolu mon problème : voici la portion du code qui posait problème

 
newtuple=SPI_modifytuple(rel,rettuple,1,&ret,(Datum *)&serial_num,NULL);

a transformer en :

 
	DatumBuffer = palloc(sizeof(Datum));
 
	DatumBuffer = DirectFunctionCall1(textin,CStringGetDatum(serial_num));
 
	newtuple=SPI_modifytuple(rel,rettuple,1,&ret,&DatumBuffer,NULL);

cependant, il y a beaucoup de warning a la compilation, mais, le tout marche donc : résolue.
Merci a tous!

Tartine

Hors ligne

Pied de page des forums