IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PostgreSQL Discussion :

Fonction C postgres apres trigger


Sujet :

PostgreSQL

  1. #1
    Nouveau membre du Club
    Inscrit en
    Avril 2007
    Messages
    31
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 31
    Points : 31
    Points
    31
    Par défaut Fonction C postgres apres trigger
    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 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    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

    Tartine

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Points : 2 890
    Points
    2 890
    Par défaut
    Quel est le rapport entre le trigger et le group by qui ne renvoie pas les résultats attendus?

  3. #3
    Nouveau membre du Club
    Inscrit en
    Avril 2007
    Messages
    31
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 31
    Points : 31
    Points
    31
    Par défaut
    Le trigger est sur la table sur laquelle j'effectue mes requêtes.
    et c'est une valeur que je switch dans le trigger qui me donne les résultats inattendus.
    c'est pourquoi je pense que j'ai mal fais ma fonction.
    voila.

  4. #4
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Points : 2 890
    Points
    2 890
    Par défaut
    C'est une fonction assez compliquée mais déjà les 2 dernières lignes paraissent bizarres
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
           rettuple=SPI_modifytuple(rel,newtuple,1,&ret,(Datum *)&serial,NULL);
           return PointerGetDatum(newtuple);
    en ce sens que ça met la ligne de résultat dans rettuple mais la valeur n'est pas utilisée, au lieu de ça c'est newtuple qui est renvoyé.

    Quoiqu'il en soit, le group by qui ne fonctionne pas c'est extrêmement étonnant comme résultat, à moins qu'il n'y ait une explication du style caractères invisibles à l'intérieur des champs, ça voudrait dire que les données sont complètement vrillées.
    Pour vérifier si le contenu affiché est propre, on peut utiliser la fonction octet_length() sur le champ à problème:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SELECT country,octet_length(country),count(*) FROM http GROUP BY country, octet_length(country);
    Il serait intéressant de voir s'il y a des doublons dans les 2 colonnes de gauche.
    S'il y a un index sur country, il peut être intéressant de réindexer aussi des fois qu'il soit corrompu.

  5. #5
    Nouveau membre du Club
    Inscrit en
    Avril 2007
    Messages
    31
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 31
    Points : 31
    Points
    31
    Par défaut
    Oui, c'est vrai, la dernière ligne ne marche pas, c'est en fait pour les tests : la ligne est changée avant et j'utilise le premier changement : on règle un problème a la fois .

    En ce qui concerne la longueur des strings
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SELECT country,octet_length(country),count(*) FROM http GROUP BY country, octet_length(country);
    Cela me retourne des valeurs plutot enormes

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     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
    comparé a une colonne qui fonctionne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    SELECT hostname,octet_length(hostname),count(*) FROM http GROUP BY hostname, octet_length(hostname);
           hostname        | octet_length | count 
    -----------------------+--------------+-------
     t3.gstatic.com        |           14 |     2
     cdn0.knowyourmeme.com |           21 |     2
     cdn1.knowyourmeme.com |           21 |     4
     cdn2.knowyourmeme.com |           21 |     4
     a0.rbcdn.com          |           12 |     2
     www.google.ch         |           13 |    12
     knowyourmeme.com      |           16 |     4
    Comment régler ce problème ? est-ce que le palloc de mon trigger en C fait des misères ?
    la strlen de mon trigger m'indique une longueur de 13. pourquoi postgres me le fait différemment ?

  6. #6
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Points : 2 890
    Points
    2 890
    Par défaut
    Je ne suis pas familier de l'API en C de postgres, mais j'ai l'impression qu'à l'appel à SPI_modifytuple(), le fait de faire simplement un cast en Datum* de ton pointeur sur chaine avec la nouvelle valeur, ce n'est pas ce qu'il faudrait faire.
    Par exemple dans ce bout de code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    ret=SPI_fnumber(tupdesc, "country");
    ereport( INFO,( errcode( ERRCODE_FEATURE_NOT_SUPPORTED ),errmsg( serial_num )));
    newtuple=SPI_modifytuple(rel,rettuple,1,&ret,(Datum *)&serial_num,NULL);
    Il faudrait plutôt faire qqch du genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Datum new_data;
    ...
    new_data = PointerGetDatum(textin(serial_num));
    newtuple=SPI_modifytuple(rel,rettuple,1,&ret, &new_data, NULL);

  7. #7
    Nouveau membre du Club
    Inscrit en
    Avril 2007
    Messages
    31
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 31
    Points : 31
    Points
    31
    Par défaut
    Parfait ! j'ai résolu mon problème : voici la portion du code qui posait problème ( merci à estofilo pour le tuyau )
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    newtuple=SPI_modifytuple(rel,rettuple,1,&ret,(Datum *)&serial_num,NULL);
    a transformer en :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    	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

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Fonctions avant ou après "main"
    Par acacia dans le forum Débuter
    Réponses: 9
    Dernier message: 15/02/2008, 17h00
  2. actualisation des tables après trigger
    Par DarkDev dans le forum PL/SQL
    Réponses: 1
    Dernier message: 04/09/2007, 09h35
  3. Fonction IMP - Déclenchement des Triggers ou non?
    Par JahPil78 dans le forum Import/Export
    Réponses: 2
    Dernier message: 13/07/2007, 22h08
  4. Fonctions Delphi + Postgres
    Par Brunier dans le forum Bases de données
    Réponses: 2
    Dernier message: 16/04/2007, 18h09
  5. fonction javascript inutilisables apres un document.write?
    Par Vesta dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 29/11/2005, 02h13

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo