IdentifiantMot de passe
Loading...
Mot de passe oubli� ?Je m'inscris ! (gratuit)
Voir le flux RSS

Alassane Diakit�

Cr�ation de type personnalis� dans PostgreSQL

Note : 3 votes pour une moyenne de 1,00.
par , 23/08/2016 � 00h28 (1313 Affichages)
PostgreSQL permet la cr�ation d'un type personnalis� de donn�e.
Dans notre exemple nous cr�erons le type � fraction � et mettrons en place la possibilit� de d�finir un index sur notre type.

La commande CREATE TYPE permet de cr�er votre type.
Dans notre cas (fraction) nous devons tenir compte des contraintes�
  • le d�nominateur ne peut �tre nul (z�ro !)
  • ni le num�rateur et ni le d�nominateur ne peuvent �tre NULL (absence de valeur !)


Le deuxi�me point peut amener une confusion : la fraction (globalement) peut �tre NULL (fraction non d�finie) mais si une fraction est d�finie (non NULL) alors le deuxi�me point ci-dessous s�applique.
Pour cela nous cr�erons deux DOMAINEs (un type existant avec contrainte)
Cr�ation des Domaines
d�nominateur�
Code SQL : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
CREATE DOMAIN ddenominateur 
AS INTEGER
DEFAULT 1 --la contrainte de NOT NULL prend le dessus sur DEFAULT!!!
CHECK (VALUE IS NOT NULL AND VALUE <> 0);
num�rateur
Code SQL : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
CREATE DOMAIN dnumerateur
AS INTEGER
DEFAULT 0 --la contrainte de NOT NULL prend le dessus sur DEFAULT!!!
CHECK (VALUE IS NOT NULL);

Creation du type fraction�
Code SQL : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
CREATE TYPE fraction 
AS (numerateur dnumerateur, denominateur ddenominateur)

Les functions outis pour la simplification
Le pgcd (plus grand commun diviseur)
Code SQL : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
CREATE OR REPLACE FUNCTION public.pgcd(
    a integer,
    b integer)
  RETURNS integer AS
$BODY$
declare
t integer;
begin
a=abs(a);
b=abs(b);
if(a=0 and b=0) then
raise EXCEPTION 'Les deux valeurs ne peuvent être nulles';
elsif(a=0 or b=0) then
return a+b;
else
	if(a<b) then 
	t=a;
	a=b;
	b=t;
	end if;
	t=a-b;
	if(t=0) then
	return a;
	else
	return pgcd(b,t);
	end if;
end if;
end
$BODY$
  LANGUAGE plpgsql IMMUTABLE

La simplification
Code SQL : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
CREATE OR REPLACE FUNCTION public.simplifie_fraction(a fraction)
  RETURNS fraction AS
$BODY$
declare
p integer;
begin
p=pgcd(a.numerateur, a.denominateur);
a.numerateur=a.numerateur/p;
a.denominateur=a.denominateur/p;
return a;
end
 
$BODY$
  LANGUAGE plpgsql IMMUTABLE
Les op�rateurs arithm�tiques (+, -, /, *)
Pour chaque op�rateur on d�fini une function et la dite op�rateur.
Remarque : il est possible de definir ces fonctions en C, nous utiliserons plpgsql.
Addition

Fonction Op�rateur
Code SQL : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
CREATE OR REPLACE FUNCTION public.add_fraction(
    gauche fraction,
    droite fraction)
  RETURNS fraction AS
$BODY$
declare 
	n integer;
	d integer;
begin
n=gauche.numerateur*droite.denominateur+gauche.denominateur*droite.numerateur;
d=gauche.denominateur*droite.denominateur;
return simplifie_fraction((n,d)::fraction);
end
$BODY$
  LANGUAGE plpgsql IMMUTABLE
Code SQL : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
CREATE OPERATOR public.+(
  PROCEDURE = add_fraction,
  LEFTARG = fraction,
  RIGHTARG = fraction,
  COMMUTATOR = +);
Soustraction

Fonction Op�rateur
Code SQL : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
CREATE OR REPLACE FUNCTION public.sous_fraction(
    gauche fraction,
    droite fraction)
  RETURNS fraction AS
$BODY$
declare 
	n integer;
	d integer;
begin
n=gauche.numerateur*droite.denominateur-gauche.denominateur*droite.numerateur;
d=gauche.denominateur*droite.denominateur;
return simplifie_fraction((n,d)::fraction);
end
$BODY$
  LANGUAGE plpgsql IMMUTABLE
Code SQL : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
CREATE OPERATOR public.-(
  PROCEDURE = sous_fraction,
  LEFTARG = fraction,
  RIGHTARG = fraction);
Multiplication

Fonction Op�rateur
Code SQL : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
CREATE OR REPLACE FUNCTION public.mult_fraction(
    gauche fraction,
    droite fraction)
  RETURNS fraction AS
$BODY$
declare 
	n integer;
	d integer;
begin
n=gauche.numerateur*droite.numerateur;
d=gauche.denominateur*droite.denominateur;
return simplifie_fraction((n,d)::fraction);
end
$BODY$
  LANGUAGE plpgsql IMMUTABLE
Code SQL : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
CREATE OPERATOR public.*(
  PROCEDURE = mult_fraction,
  LEFTARG = fraction,
  RIGHTARG = fraction,
  COMMUTATOR = *);
Division

Fonction Op�rateur
Code SQL : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
CREATE OR REPLACE FUNCTION public.div_fraction(
    gauche fraction,
    droite fraction)
  RETURNS fraction AS
$BODY$
declare 
	n integer;
	d integer;
begin
n=gauche.numerateur*droite.denominateur;
d=gauche.denominateur*droite.numerateur;
return simplifie_fraction((n,d)::fraction);
end
$BODY$
  LANGUAGE plpgsql IMMUTABLE
Code SQL : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
CREATE OPERATOR public./(
  PROCEDURE = div_fraction,
  LEFTARG = fraction,
  RIGHTARG = fraction);

Les converstions: INTEGER � fraction et fraction � NUMERIC
Une conversion est r�alis�e par une fonction et objet CAST
INTEGER � fraction

Fonction CAST
Code SQL : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7
8
9
10
11
CREATE OR REPLACE FUNCTION public.inttofraction(intsrc integer)
  RETURNS fraction AS
$BODY$
declare resultat fraction;
begin
resultat.numerateur=$1::dnumerateur;
resultat.denominateur=1::ddenominateur;
return resultat;
end 
$BODY$
  LANGUAGE plpgsql IMMUTABLE
Code SQL : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
CREATE CAST (integer AS fraction)
  WITH FUNCTION public.inttofraction(integer)
  AS ASSIGNMENT;

fraction � NUMERIC

Fonction CAST
Code SQL : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7
8
9
10
CREATE OR REPLACE FUNCTION public.fractiontonumeric(fractionsrc fraction)
  RETURNS numeric AS
$BODY$
declare resultat numeric;
begin
resultat=(fractionsrc.numerateur::numeric/fractionsrc.denominateur::numeric)::numeric;
return resultat;
end 
$BODY$
  LANGUAGE plpgsql IMMUTABLE
Code SQL : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
CREATE CAST (fraction AS numeric)
  WITH FUNCTION public.fractiontonumeric(fraction)
  AS ASSIGNMENT;

Les op�rateurs de comparaison:=, >, < >=, <=
L'�galit� =

Fonction Op�rateur
Code SQL : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
CREATE OR REPLACE FUNCTION public.egal_fraction(
    gauche fraction,
    droite fraction)
  RETURNS boolean AS
$BODY$
begin
if $1.numerateur*$2.denominateur=$2.numerateur*$1.denominateur
then return true;
else
return false;
end if;
end
$BODY$
  LANGUAGE plpgsql IMMUTABLE
Code SQL : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
CREATE OPERATOR public.=(
  PROCEDURE = egal_fraction,
  LEFTARG = fraction,
  RIGHTARG = fraction,
  COMMUTATOR = =);

Sup�rieur >

Fonction Op�rateur
Code SQL : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
CREATE OR REPLACE FUNCTION public.supp_fraction(
    gauche fraction,
    droite fraction)
  RETURNS boolean AS
$BODY$
begin
if $1::numeric>$2::numeric
then return true;
else
return false;
end if;
end
$BODY$
  LANGUAGE plpgsql IMMUTABLE
Code SQL : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
CREATE OPERATOR public.>(
  PROCEDURE = supp_fraction,
  LEFTARG = fraction,
  RIGHTARG = fraction,
  COMMUTATOR = <);

Sup�rieur ou �gal>=

Fonction Op�rateur
Code SQL : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
CREATE OR REPLACE FUNCTION public.suppouegal_fraction(
    gauche fraction,
    droite fraction)
  RETURNS boolean AS
$BODY$
begin
if (supp_fraction($1,$2)=true) or (egal_fraction($1,$2)=true)
then return true;
else
return false;
end if;
end
$BODY$
  LANGUAGE plpgsql IMMUTABLE
Code SQL : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
CREATE OPERATOR public.>=(
  PROCEDURE = suppouegal_fraction,
  LEFTARG = fraction,
  RIGHTARG = fraction,
  COMMUTATOR = <=);


Inf�rieur <

Fonction Op�rateur
Code SQL : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
CREATE OR REPLACE FUNCTION public.inf_fraction(
    gauche fraction,
    droite fraction)
  RETURNS boolean AS
$BODY$
begin
if $1::numeric<$2::numeric
then return true;
else
return false;
end if;
end
$BODY$
  LANGUAGE plpgsql IMMUTABLE
Code SQL : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
CREATE OPERATOR public.<(
  PROCEDURE = inf_fraction,
  LEFTARG = fraction,
  RIGHTARG = fraction,
  COMMUTATOR = >);

Inf�rieur ou �gal>=

Fonction Op�rateur
Code SQL : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
CREATE OR REPLACE FUNCTION public.infouegal_fraction(
    gauche fraction,
    droite fraction)
  RETURNS boolean AS
$BODY$
begin
if (inf_fraction($1,$2)=true) or (egal_fraction($1,$2)=true)
then return true;
else
return false;
end if;
end
$BODY$
  LANGUAGE plpgsql IMMUTABLE
Code SQL : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
	CREATE OPERATOR public.<=(
  PROCEDURE = infouegal_fraction,
  LEFTARG = fraction,
  RIGHTARG = fraction,
  COMMUTATOR = >=);


Classe et famille d�op�rateurs
Pour un d�finir un index sur notre type nous avons besoin de cr�er une classe d�op�rateur
La classe
Code SQL : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7
8
CREATE OPERATOR CLASS public.fraction_ops DEFAULT
   FOR TYPE fraction USING btree AS
   OPERATOR 1  <,
   OPERATOR 2  <=,
   OPERATOR 3  =,
   OPERATOR 4  >=,
   OPERATOR 5  >,
   FUNCTION 1  public.compare_fraction(fraction, fraction);
... la fonction de comparaison
Code SQL : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
CREATE OR REPLACE FUNCTION public.compare_fraction(
    gauche fraction,
    droite fraction)
  RETURNS integer AS
$BODY$
begin
if $1>$2
then return 1;
elsif $1<$2
then return -1;
else
return 0;
end if;
end
$BODY$
  LANGUAGE plpgsql IMMUTABLE

La famille (automatiquement cr��e)
Code SQL : S�lectionner tout - Visualiser dans une fen�tre � part
CREATE OPERATOR FAMILY public.fraction_ops USING btree;

Cr�ation d'une table avec index
Code SQL : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7
8
9
10
CREATE TABLE public.lesfractions
(
  idfraction serial NOT NULL,
  unevaleur fraction,
  CONSTRAINT lesfractions_pkey PRIMARY KEY (idfraction)
);
CREATE INDEX ind2
  ON public.lesfractions
  USING btree
  (unevaleur);

Envoyer le billet � Cr�ation de type personnalis� dans PostgreSQL � dans le blog Viadeo Envoyer le billet � Cr�ation de type personnalis� dans PostgreSQL � dans le blog Twitter Envoyer le billet � Cr�ation de type personnalis� dans PostgreSQL � dans le blog Google Envoyer le billet � Cr�ation de type personnalis� dans PostgreSQL � dans le blog Facebook Envoyer le billet � Cr�ation de type personnalis� dans PostgreSQL � dans le blog Digg Envoyer le billet � Cr�ation de type personnalis� dans PostgreSQL � dans le blog Delicious Envoyer le billet � Cr�ation de type personnalis� dans PostgreSQL � dans le blog MySpace Envoyer le billet � Cr�ation de type personnalis� dans PostgreSQL � dans le blog Yahoo

Mis � jour 17/08/2017 � 14h29 par Malick (Ajout balises code)

Cat�gories
Bases de donn�es , SQL , PostgreSQL

Commentaires