| From: | Samuel ROZE <samuel(dot)roze(at)gmail(dot)com> | 
|---|---|
| To: | Cédric Villemain <cedric(dot)villemain(at)dalibo(dot)com> | 
| Cc: | pgsql-fr-generale(at)postgresql(dot)org | 
| Subject: | Re: Fonction C: Segmentation fault | 
| Date: | 2009-10-14 17:46:55 | 
| Message-ID: | 1255542415.27829.11.camel@samuel-laptop | 
| Views: | Whole Thread | Raw Message | Download mbox | Resend email | 
| Thread: | |
| Lists: | pgsql-fr-generale | 
Je retourne un..
"PG_RETURN_DATUM(HeapTupleGetDatum(tuple));"
Et dans le CREATE FUNCTION j'ai mis "RECORD"
Est-ce bien ça ?
Merci !
Samuel.
Le mercredi 14 octobre 2009 à 19:43 +0200, Cédric Villemain a écrit :
> Le mercredi 14 octobre 2009 19:32:26, Samuel ROZE a écrit :
> > Bonjour à tous,
> > 
> > Je souhaites créer une fonction "parse_url" afin de pouvoir récupérer
> > l'hostname, le path, le schéma ou autre chose à partir d'une adresse URL
> > (text).
> > 
> > Je souhaites donc créer une fonction C. Seulement, j'ai quelques soucis
> > pour la création d'une fonction de base. La fonction doit retourner un
> > type composite (i.e. une colonne "scheme" et une colonne "host" avec des
> > valeurs de base, pour le moment (pour faire ma première fonction C pour
> > PostgreSQL). Bref, voilà le code que j'ai.
> > 
> > Fichier: parse_url.c
> > ------------------------------------------------------------------------
> > /*
> >  * parse_url.c
> >  *
> >  *  Created on: 14 oct. 2009
> >  *      Author: Samuel ROZE <samuel(dot)roze(at)gmail(dot)com>
> >  */
> > #include "postgres.h"
> > #include <string.h>
> > #include "fmgr.h"
> > // Tuple building functions and macros
> > #include "access/heapam.h"
> > #include "funcapi.h"
> > 
> > #include "parse_url.h"
> > 
> > #ifdef PG_MODULE_MAGIC
> > PG_MODULE_MAGIC;
> > #endif
> > 
> > PG_FUNCTION_INFO_V1(parse_url);
> > Datum parse_url (PG_FUNCTION_ARGS)
> > {
> > 	// Vars about the params
> > 	text *str = PG_GETARG_TEXT_P(0);
> > 	int32 length = VARSIZE(str);
> > 
> > 	// Vars about the pg_url instance
> > 	pg_url 		*ret = palloc(sizeof(pg_url));
> > 
> > 	// Some vars which will used to create the composite output type
> > 	TupleDesc	tupdesc;
> > 	Datum		values[8]; // 8 values
> > 	HeapTuple	tuple;
> > 	bool		*nulls;
> > 	int			tuplen;
> > 
> > 	// Check NULLs values
> > 	if(PG_ARGISNULL(0) || PG_ARGISNULL(1)) {
> > 		PG_RETURN_NULL();
> > 	}
> > 
> > 	// Parse URL
> > 	ret->scheme = parse_url_alloc("schema", 7);
> > 	ret->host = parse_url_alloc("host", 5);
> > 
> > 	// Add datas into the values Datum
> > 	values[0] = PointerGetDatum(ret->scheme);
> > 	values[1] = PointerGetDatum(ret->host);
> > 
> > 	// Convert values into a composite type
> > 	tuplen = tupdesc->natts;
> > 	nulls = palloc(tuplen * sizeof(bool));
> > 
> > 	// build tuple from datum array
> > 	tuple = heap_form_tuple(tupdesc, values, nulls);
> > 	// Free null values
> > 	pfree(nulls);
> > 
> > 	// Return the composite type
> > 	PG_RETURN_DATUM(HeapTupleGetDatum(tuple));
> > }
> > 
> > char *parse_url_alloc(const char *s, int length)
> > {
> > 	char *p;
> > 
> > 	p = (char *) palloc(length+1);
> > 	if (p != NULL) {
> > 		memcpy(p, s, length);
> > 		p[length] = 0;
> > 		return p;
> > 	}
> > }
> > ------------------------------------------------------------------------
> > 
> > Fichier: parse_url.h
> > ------------------------------------------------------------------------
> > /*
> >  * parse_url.h
> >  *
> >  *  Created on: 14 oct. 2009
> >  *      Author: Samuel ROZE <samuel(dot)roze(at)gmail(dot)com>
> >  */
> > 
> > #ifndef PARSE_URL_H
> > #define PARSE_URL_H
> > 
> > Datum parse_url (PG_FUNCTION_ARGS);
> > char *parse_url_alloc(const char *s, int length);
> > 
> > typedef struct pg_url {
> > 	char *scheme;
> > 	char *user;
> > 	char *pass;
> > 	char *host;
> > 	unsigned short port;
> > 	char *path;
> > 	char *query;
> > 	char *fragment;
> > } pg_url;
> > 
> > #endif /* PARSE_URL_H */
> > ------------------------------------------------------------------------
> > 
> > Pour le compilation, voilà ce que j'ai fait:
> > ------------------------------------------------------------------------
> > $ gcc -O2 -Wall -Wmissing-prototypes -Wpointer-arith -Winline
> > -Wdeclaration-after-statement -Wendif-labels -fno-strict-aliasing
> > -fwrapv -fpic -I. -I/usr/include/postgresql/server
> > -I/usr/include/postgresql/internal -D_GNU_SOURCE   -c -o parse_url.o
> > parse_url.c -I/usr/include/postgresql/
> > -I/usr/local/pgsql/include/server/
> > ------------------------------------------------------------------------
> > $ gcc -shared -o parse_url.so parse_url.o
> > ------------------------------------------------------------------------
> > 
> > Ça marche bien. Quelques petites erreurs:
> > ------------------------------------------------------------------------
> > parse_url.c: In function ‘parse_url’:
> > parse_url.c:25: warning: unused variable ‘length’
> > parse_url.c: In function ‘parse_url_alloc’:
> > parse_url.c:73: warning: control reaches end of non-void function
> > parse_url.c: In function ‘parse_url’:
> > parse_url.c:51: warning: ‘tupdesc’ may be used uninitialized in this
> > function
> > ------------------------------------------------------------------------
> > 
> > Pour la création de la fonction dans PostgreSQL:
> > ------------------------------------------------------------------------
> > CREATE FUNCTION parse_url (text) RETURNS record AS
> >  '/root/PgSQL-parse_url/parse_url.so', 'parse_url' LANGUAGE C;
> >  ------------------------------------------------------------------------
> > 
> > Pour l'éxécution:
> > ------------------------------------------------------------------------
> > SELECT * FROM parse_url('http://www.google.fr') as ("schema" text, "query"
> >  text);
> >  ------------------------------------------------------------------------
> > 
> > L'erreur suivante m'est retournée:
> > ------------------------------------------------------------------------
> > server closed the connection unexpectedly
> > 	This probably means the server terminated abnormally
> > 	before or while processing the request.
> > ------------------------------------------------------------------------
> 
> Je n'ai pas le temps de suite de bien lire le code, mais souvent cela peut 
> etre lié a un type de retour de fonction C différent de ce que réclame le sql.
> 
> Par exemple le sql attend du text et recoit autre chsoe (un char...)
> 
> 
> > 
> > Et j'ai dans les logs:
> > ------------------------------------------------------------------------
> > LOG:  processus serveur (PID 26272) a été arrêté par le signal 11 :
> >  Segmentation fault LOG:  arrêt des autres processus serveur actifs
> > LOG:  tous les processus serveur se sont arrêtés, réinitialisation
> > LOG:  le système de bases de données a été interrompu ; dernier lancement
> >  connu à 2009-10-14 19:07:19 CEST LOG:  le système de bases de données n'a
> >  pas été arrêté proprement ; restauration automatique en cours
> > LOG:  enregistrement de longueur nulle à 0/43855468
> > LOG:  la ré-exécution n'est pas nécessaire
> > LOG:  lancement du processus autovacuum
> > LOG:  le système de bases de données est prêt pour accepter les connexions
> > ------------------------------------------------------------------------
> > 
> > Est-ce que quelqu'un d'entre vous voit le problème ?
> > 
> > Merci d'avance.
> > Cordialement, Samuel ROZE.
> > 
> 
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Dimitri Fontaine | 2009-10-14 18:53:16 | Re: Fonction C: Segmentation fault | 
| Previous Message | Cédric Villemain | 2009-10-14 17:43:44 | Re: Fonction C: Segmentation fault |