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

31.8. Bibliothèque pgtypes

La bibliothèque pgtypes établie une correspondance entre les types PostgreSQL™ et les équivalents en C. Elle fournit aussi des fonctions permettant des calculs simples sur ces types en C, c'est-à-dire sans l'aide du serveur PostgreSQL™. Par exemple :

EXEC SQL BEGIN DECLARE SECTION;
   date date1;
   timestamp ts1, tsout;
   interval iv1;
   char *out;
EXEC SQL END DECLARE SECTION;

PGTYPESdate_today(&date1);
EXEC SQL SELECT started, duration INTO :ts1, :iv1 FROM datetbl WHERE d=:date1;
PGTYPEStimestamp_add_interval(&ts1, &iv1, &tsout);
out = PGTYPEStimestamp_to_asc(&tsout);
printf("Started + duration: %s\n", out);
free(out);

31.8.1. Le type numeric

Le type numeric permet des calculs avec une précision arbitraire. Voir Section 8.1, « Types numériques » pour le type équivalent dans le serveur PostgreSQL™. Du fait de la précision arbitraire, une variable de ce type doit pouvoir étendre et diminuer sa taille dynamiquement. C'est pourquoi il est obligatoire d'utiliser les fonctions PGTYPESnumeric_new et PGTYPESnumeric_free pour créer de telles variables, et uniquement en mémoire heap . Le type decimal, similaire mais limité en précision, peut être créé sur la pile comme sur le « heap ».

Les fonctions suivantes peuvent être utilisées avec le type numeric :

PGTYPESnumeric_new

réclame un pointeur vers une variable numeric nouvellement allouée.

numeric *PGTYPESnumeric_new(void);
PGTYPESnumeric_free

libère un type numeric en vidant toute sa mémoire.

void PGTYPESnumeric_free(numeric *var);
PGTYPESnumeric_from_asc

analyse un type numeric à partir de sa notation en chaîne.

numeric *PGTYPESnumeric_from_asc(char *str, char **endptr);

Les formats valides sont, par exemple : -2, .794, +3.44, 592.49E07 ou -32.84e-4. Si la valeur a pu être analysée correctement, un pointeur valide est renvoyé. Dans le cas contraire, il s'agit d'un pointeur NULL. Actuellement, ecpg analyse toujours la chaîne complète et, du coup, ne supporte pas le stockage de l'adresse du premier caractère invalide dans *endptr. endptr peut être initailisé à NULL en toute sécurité.

PGTYPESnumeric_to_asc

renvoie un pointeur vers une chaîne allouée via malloc qui contient la représentation en chaîne du type numeric num.

char *PGTYPESnumeric_to_asc(numeric *num, int dscale);

La valeur numerique est affichée avec dscale chiffres décimaux, arrondie si nécessaire.

PGTYPESnumeric_add

additionne deux variables de type numeric dans une troisième.

int PGTYPESnumeric_add(numeric *var1, numeric *var2, numeric *result);

La fonction additionne les variables var1 et var2 dans la variable résultat result. Elle renvoie 0 en cas de succès et -1 en cas d'erreur.

PGTYPESnumeric_sub

soustrait deux variables de type numeric et renvoie le résultat dans une troisième.

int PGTYPESnumeric_sub(numeric *var1, numeric *var2, numeric *result);

La fonction soustrait la variable var2 à la variable var1. Le résultat de cette opération est stocké dans la variable result. La fonction renvoie 0 en cas de succès et -1 en cas d'erreur.

PGTYPESnumeric_mul

multiplie deux variables de type numeric et renvoie le résultat dans une troisième.

int PGTYPESnumeric_mul(numeric *var1, numeric *var2, numeric *result);

La fonction multiplie les variables var1 et var2. Le résultat de cette opération est stocké dans la variable result. La fonction renvoie 0 en cas de succès et -1 en cas d'erreur.

PGTYPESnumeric_div

divise deux variables de type numeric et renvoie le résultat dans une troisième.

int PGTYPESnumeric_div(numeric *var1, numeric *var2, numeric *result);

La fonction divise la variable var1 par var2. Le résultat de cette opération est stocké dans la variable result. La fonction renvoie 0 en cas de succès et -1 en cas d'erreur.

PGTYPESnumeric_cmp

compare deux variables de type numeric.

int PGTYPESnumeric_cmp(numeric *var1, numeric *var2)

La fonction compare deux variables de type numeric. En cas d'erreur, INT_MAX est renvoyé. En cas de succès, la fonction renvoie un des trois résultats possibles :

  • 1, si var1 est plus grand que var2

  • -1, si var1 est plus petit que var2

  • 0, si var1 est égal à var2

PGTYPESnumeric_from_int

convertit une variable de type int en une variable de type numeric.

int PGTYPESnumeric_from_int(signed int int_val, numeric *var);

La fonction accepte une variable de type signed int (entier signé) et la stocke dans la variable var de type numeric. La fonction renvoie 0 en cas de succès et -1 en cas d'erreur.

PGTYPESnumeric_from_long

convertit une variable de type long int en une variable de type numeric.

int PGTYPESnumeric_from_long(signed long int long_val, numeric *var);

La fonction accepte une variable de type signed long int (entier long signé) et la stocke dans la variable var de type numeric. La fonction renvoie 0 en cas de succès et -1 en cas d'erreur.

PGTYPESnumeric_copy

copie une variable de type numeric dans une autre.

int PGTYPESnumeric_copy(numeric *src, numeric *dst);

la fonction copie la valeur de la variable sur laquelle pointe src dans la variable sur laquelle pointe dst. La fonction renvoie 0 en cas de succès et -1 en cas d'erreur.

PGTYPESnumeric_from_double

convertit une variable de type double en numeric.

int  PGTYPESnumeric_from_double(double d, numeric *dst);

La fonction accepte une variable de type double et la stocke dans la variable sur laquelle pointe dst. La fonction renvoie 0 en cas de succès et -1 en cas d'erreur.

PGTYPESnumeric_to_double

convertit une variable de type numeric en double.

int PGTYPESnumeric_to_double(numeric *nv, double *dp)

La fonction convertit la valeur numérique de la variable pointée par nv dans la variable de type double pointée par dp. La fonction renvoie 0 en cas de succès et -1 en cas d'erreur, dépassement inclus. En cas de dépassement, la variable globale errno est positionnée à PGTYPES_NUM_OVERFLOW.

PGTYPESnumeric_to_int

convertit une variable de type numeric en int.

int PGTYPESnumeric_to_int(numeric *nv, int *ip);

La fonction convertit la valeur numérique de la variable pointée par nv en une variable de type integer pointée par ip. La fonction renvoie 0 en cas de succès et -1 en cas d'erreur, dépassement inclus. En cas de dépassement, la variable globale errno est initialisée à PGTYPES_NUM_OVERFLOW.

PGTYPESnumeric_to_long

convertit une variable de type numeric en long int.

int PGTYPESnumeric_to_long(numeric *nv, long *lp);

La fonction convertit la valeur numérique de la variable pointée par nv en une variable de type long integer pointée par lp. La fonction renvoie 0 en cas de succès et -1 en cas d'erreur, dépassement inclus. En cas de dépassement, la variable globale errno est initialisée à PGTYPES_NUM_OVERFLOW.

PGTYPESnumeric_to_decimal

convertit une variable de type numeric en decimal.

int PGTYPESnumeric_to_decimal(numeric *src, decimal *dst);

La fonction convertit la valeur numérique de la variable pontée par nv en une variable de type decimal pointée par dst. La fonction renvoie 0 en cas de succès et -1 en cas d'erreur, dépassement inclus. En cas de débodrdement, la variable globale errno est initialisée à PGTYPES_NUM_OVERFLOW.

PGTYPESnumeric_from_decimal

convertit une variable de type decimal en numeric.

int PGTYPESnumeric_from_decimal(decimal *src, numeric *dst);

La fonction convertit la valeur décimale de la variable pointée par nv en une variable de type numeric pointée par dst. La fonction renvoie 0 en cas de succès et -1 en cas d'erreur. Comme le type decimal est une version limitée du type numeric, aucun dépassement ne peut survenir avec cette conversion.

31.8.2. Le type date

Le type date en C permet aux programmes de gérer les données de type date SQL. Voir Section 8.5, « Types date/heure » pour le type équivalent dans le serveur PostgreSQL™.

Les fonctions qui suivent peuvent être utilisées pour travailler avec le type date :

PGTYPESdate_from_timestamp

extrait la date d'une variable de type timestamp.

date PGTYPESdate_from_timestamp(timestamp dt);

La fonction reçoit une variable de type timestamp comme seul argument et en retourne la partie date.

PGTYPESdate_from_asc

analyse une date à partir de sa représentation textuelle.

date PGTYPESdate_from_asc(char *str, char **endptr);

La fonction reçoit une chaîne C (char*) str et un pointeur vers une autre chaîne C, endptr. À ce jour, ecpg analyse toujours la chaîne complète et ne peut donc pas stocker l'adresse du premier caractère invalide dans *endptr. endptr peut être initialisé à NULL en toute sécurité.

La fonction estime systématiquement recevoir des dates au format MDY. Il n'y a actuellement aucune variable qui permette de modifier cela dans ecpg.

Formats de saisie autorisés :


PGTYPESdate_to_asc

renvoie la représentation textuelle d'une variable date.

char *PGTYPESdate_to_asc(date dDate);

La fonction reçoit la date dDate comme seul paramètre. Elle affiche la date sous la forme 1999-01-18, c'est-à-dire dans le format YYYY-MM-DD.

PGTYPESdate_julmdy

extrait les valeurs du jour, du mois et de l'année à partir d'une variable de type date.

void PGTYPESdate_julmdy(date d, int *mdy);

La fonction reçoit la date d et un pointeur sur un tableau de trois valeurs entières mdy. Le nom de la variable indique l'ordre de séquence : mdy[0] contient le numéro du mois, mdy[1] le jour et mdy[2] l'année.

PGTYPESdate_mdyjul

crée une valeur date à partir d'un tableau de trois entiers qui précisent le jour, le mois et l'année de la date.

void PGTYPESdate_mdyjul(int *mdy, date *jdate);

La fonction prend le tableau de trois entiers (mdy) comme premier argument et un pointeur sur une variable de type date comme second argument. Ce dernier reçoit le résultat de l'opération.

PGTYPESdate_dayofweek

renvoie un nombre représentant le jour de la semaine pour une valeur de type date.

int PGTYPESdate_dayofweek(date d);

La fonction reçoit la variable d de type date comme seul argument et renvoie un entier indiquant le jour de la semaine associé à cette date.

  • 0 - Dimanche

  • 1 - Lundi

  • 2 - Mardi

  • 3 - Mercredi

  • 4 - Jeudi

  • 5 - Vendredi

  • 6 - Samedi

PGTYPESdate_today

récupère la date courante.

void PGTYPESdate_today(date *d);

La fonction reçoit un pointeur vers une variable date (d) et l'initialise à la date couratne.

PGTYPESdate_fmt_asc

convertit une variable de type date en sa représentation textuelle à l'aide d'un masque de format.

int PGTYPESdate_fmt_asc(date dDate, char *fmtstring, char *outbuf);

La fonction reçoit la date à convertir (dDate), le masque de format (fmtstring) et la chaîne de récupération de la représentation textuelle de la date (outbuf).

La fonction renvoie 0 en cas de succès et une valeur négative en cas d'erreur.

Les chaînes suivantes indiquent les champs à utiliser :

  • dd - le numéro du jour dans le mois ;

  • mm - le numéro du mois dans l'année ;

  • yy - le numéro de l'année sur deux chiffres ;

  • yyyy - le numéro de l'année sur quatre chiffres ;

  • ddd - l'abréviation du nom du jour ;

  • mmm - l'abréviation du nom du mois.

Tous les autres caractères sont copiés un à un dans la chaîne de sortie.

La table qui suit propose quelques formats possibles. Cela donne des idées d'utilisation de cette fonction. Toutes les lignes en sortie sont fondées sur la même date, le 23 novembre 1959.


PGTYPESdate_defmt_asc

utilise un masque de format pour convertir une chaîne C (char*) en une valeur de type date.

int PGTYPESdate_defmt_asc(date *d, char *fmt, char *str);

Cette fonction prend en argumant un pointeur sur la valeur de type date de stockage du résultat de l'opération (d), le masque du format à utiliser pour analyser la date (fmt) et la chaîne C qui contient la représentation textuelle de la date (str). La représentation textuelle doit correspondre au masque de format. Il n'est toutefois pas nécessaire d'avoir une correspondance exacte. La fonction analyse simplement l'ordre séquentiel et cherche les libellés yy ou yyyy qui indiquent la position de l'année, mm pour celle du mois et dd pour celle du jour.

La table qui suit indique quelques formats possibles. Cela donne des idées sur l'utilisation de cette fonction.


31.8.3. Le type timestamp

Le type timestamp en C permet aux programmes de gérer les données de type timestamp SQL. Voir Section 8.5, « Types date/heure » pour le type équivalent dans le serveur PostgreSQL™.

Le fonctions qui suivent sont utilisées pour travailler avec le type timestamp :

PGTYPEStimestamp_from_asc

analyse une variable de type timestamp à partir de sa représentation textuelle et la stocke dans une variable de type timestamp.

timestamp PGTYPEStimestamp_from_asc(char *str, char **endptr);

La fonction prend en arguments la chaîne à analyser (str) et un pointeur sur une chaîne C de type char* (endptr). Actuellement, ecpg analyse toujours la chaîne complète et ne supporte donc pas le stockage de l'adresse du premier caractère invalide dans *endptr. endptr peut être initialisé à NULL en toute sécurité.

La fonction renvoie la variable de type timestamp analysée en cas de succès. En cas d'erreur, PGTYPESInvalidTimestamp est renvoyée et errno vaut PGTYPES_TS_BAD_TIMESTAMP. Voir PGTYPESInvalidTimestamp pour d'importantes informations sur cette valeur.

En général, la chaîne saisie peut contenir toute combinaison de spécification autorisée de date, d'espace et de spécification autorisée d'heure. Les fuseaux horaires ne sont pas supportés par ecpg. Il peut les analyser mais n'applique aucun calcul au contraire de serveur PostgreSQL™ par exemple. Les fuseaux horaires sont ignorés silencieusement.

Le tableau qui suit contient quelques exemples de saisie de chaînes :


PGTYPEStimestamp_to_asc

convertit une date en chaîne C char*.

char *PGTYPEStimestamp_to_asc(timestamp tstamp);

La fonction prend comme seul argument la variable tstamp de type timestamp et renvoie une chaîne allouée qui contient la représentation textuelle du timestamp.

PGTYPEStimestamp_current

récupère le timestamp courant.

void PGTYPEStimestamp_current(timestamp *ts);

La fonction récupère le timestamp courant et le sauvegarde dans la variable de type timestamp pointée par ts.

PGTYPEStimestamp_fmt_asc

convertit une variable de type timestamp en une chaîne C de type char* à l'aide d'un masque de formatage.

int PGTYPEStimestamp_fmt_asc(timestamp *ts, char *output, int str_len, char *fmtstr);

La fonction prend en arguments un pointeur vers la variable de type timestamp (ts), un pointeur vers le tampon de sortie (output), la longueur maximale allouée pour le tampon de sortie (str_len) et le masque de formatage à utiliser pour la conversion (fmtstr).

La fonction renvoie 0 en cas de succès et une valeur négative en cas d'erreur.

Les caractères de formatage qui suivent peuvent être utilisés comme masque de formatage. Ces caractères sont identiques à ceux utilisés dans la fonction strftime de libc™. Tout caractère n'en faisant pas partie est copié tel quel dans le tampon de sortie.

  • %A - remplacé par la représentation nationale du nom complet du jour de la semaine ;

  • %a - remplacé par la représentation nationale de l'abréviation du nom de la semaine ;

  • %B - remplacé par la représentation nationale du nom complet du mois ;

  • %b - remplacé par la représentation nationale de l'abréviation du nom du mois ;

  • %C - remplacé par (année / 100) en nombre décimal, les chiffres seuls sont précédés d'un zéro ;

  • %c - remplacé par la représentation nationale de l'heure et de la date ;

  • %D - est équivalent à %m/%d/%y.

  • %d - est remplacé par le jour du mois en nombre décimal (01-31) ;

  • %E* %O* - extensions POSIX de la locale. Les séquences %Ec %EC %Ex %EX %Ey %EY %Od %Oe %OH %OI %Om %OM %OS %Ou %OU %OV %Ow %OW %Oy sont supposées fournir d'autres représentations.

    De plus, %OB permet de représenter les autres noms des mois (utilisés en autonome, sans mention du jour) ;

  • %e - est remplacé par le jour du mois en nombre décimal (1-31) ; les chiffres seuls sont précédés d'un zéro ;

  • %F - est équivalent à %Y-%m-%d ;

  • %G - est remplacé par une année comme nombre déciaml avec le siècle. Il s'agit de l'année qui contient la plus grande partie de la semaine (lundi étant le premier jour de la semaine) ;

  • %g - est remplacé par la même année que %G mais en décimal sans le siècle (00-99) ;

  • %H - est remplacé par l'heure (sur 24 heures) en nombre décimal (00-23) ;

  • %h - idem à %b ;

  • %I - est remplacé par l'heure (sur 12 heures) en nombre décimal (01-12) ;

  • %j - est remplacé par le jour de l'année en nombre décimal (001-366) ;

  • %k - est remplacé par l'heure (sur 24 heures) en nombre décimal (0-23), les chiffres seuls sont précédés d'un zéro ;

  • %l - est remplacé par l'heure (sur 12 heures) en nombre décimal (1-12), les chiffres seuls sont précédés d'un zéro ;

  • %M - est remplacé par la minute en nombre décimal (00-59) ;

  • %m - est remplacé par le mois en nombre décimal (01-12) ;

  • %n - est remplacé par un retour chariot ;

  • %O* - identique à %E* ;

  • %p - remplacé par la représentation nationale de "ante meridiem" ou "post meridiem" suivant le cas ;

  • %R - est équivalent à %H:%M ;

  • %r - est équivalent à %I:%M:%S %p ;

  • %S - est remplacé par la seconde en nombre décimal (00-60) ;

  • %s - est remplacé par le nombre de secondes depuis Epoch, UTC ;

  • %T - est équivalent à %H:%M:%S ;

  • %t - est remplacé par une tabulation ;

  • %U - est remplacé par le numéro de la semaine dans l'année (dimanche étant le premier jour de l'année) en nombre décimal (00-53) ;

  • %u - est remplacé par le jour de la semaine (lundi étant le premier jour de la semaine) en nombre décimal (1-7) ;

  • %V - est remplacé par le numéro de la semaine dans l'année (lundi étant le premier jour de la semaine) en nombre décimal (01-53). Si la semaine contenant le 1er janvier a quatre jours ou plus dans la nouvelle année, alors c'est la semaine 1 ; sinon c'est la dernière semaine de l'année précédente et la semaine suivante est la semaine 1 ;

  • %v - est équivalent à %e-%b-%Y ;

  • %W - est remplacé par le numéro de semaine de l'année (lundi étant le premier jour de la semaine) en nombre décimal (00-53) ;

  • %w - est remplacé par le jour de la semaine (dimanche étant le premier jour de la semaine) en nombre décimal (0-6) ;

  • %X - est remplacé par la représentation nationale de l'heure ;

  • %x - est remplacé par la représentation nationale de la date ;

  • %Y - est remplacé par l'année avec le siècle en nombre décimal ;

  • %y - est remplacé par l'année sans le siècle en nombre décimal (00-99) ;

  • %Z - est remplacé par le nom du fuseau horaire ;

  • %z - est remplacé par le décalage du fuseau horaire à partir d'UTC ; un signe plus au début signifie à l'est d'UTC, un signe moins signifie à l'ouest d'UTC ; les heures et les minutes suivent avec deux chiffres chacun et aucun délimiteur entre eux (format habituel pour les en-têtes de date au standard RFC 822) ;

  • %+ - est remplacé par la représentation nationale de la date et l'heure ;

  • %-* - extension GNU libc. N'ajoute aucune espace de remplissage lors du traitement des sorties numériques ;

  • $_* - extension GNU libc. Indique explicitement l'espace comme caractère de remplissage ;

  • %0* - extension GNU libc. Indique explicitement zéro comme caractère de remplissage ;

  • %% - est remplacé par %.

PGTYPEStimestamp_sub

soustrait une valeur de type timestamp à une autre valeur et sauvegarde le résultat dans une variable de type interval.

int PGTYPEStimestamp_sub(timestamp *ts1, timestamp *ts2, interval *iv);

La fonction soustraie la variable timestamp pointée par ts2 de la variable timestamp pointée par ts1 et stocke le résultat dans la variable de type interval pointée par iv.

La fonction renvoie 0 en cas de succès et une valeur négative en cas d'erreur.

PGTYPEStimestamp_defmt_asc

analyse une valeur de type timestamp à partir de sa représentation textuelle à l'aide d'un masque de formatage.

int PGTYPEStimestamp_defmt_asc(char *str, char *fmt, timestamp *d);

La fonction reçoit la représentation textuelle d'une valeur de type timestamp dans la variable str ainsi que le masque de formatage à utiliser dans la variable fmt. Le résultat est stocké dans la variable pointée par d.

Si le masque de formatage fmt est NULL, la fonction utiliser la masque de formatage par défaut qui est %Y-%m-%d %H:%M:%S.

C'est la fonction inverse de PGTYPEStimestamp_fmt_asc . Voir la documentation pour découvrir les saisies possibles pour le masque de formatage.

PGTYPEStimestamp_add_interval

ajoute une variable de type interval à une variable de type timestamp.

int PGTYPEStimestamp_add_interval(timestamp *tin, interval *span, timestamp *tout);

La fonction recçoit un pointeur vers une variable de type timestamp, tin, et un pointeur vers une variable de type interval span. Elle ajoute l'interval au timestamp et sauvegarde le résultat, de type timestamp, dans la variable pointée par tout.

La fonction renvoie 0 en cas de succès et une valeur négative en cas d'erreur.

PGTYPEStimestamp_sub_interval

soustrait une variable de type interval à une variable de type timestamp.

int PGTYPEStimestamp_sub_interval(timestamp *tin, interval *span, timestamp *tout);

La fonction soustrait la variable de type interval pointée par span à la variable timestamp pointée par tin et sauvegarde le résultat dans une variable pointée par tout.

La fonction renvoie 0 en cas de succès et une valeur négative en cas d'erreur.

31.8.4. Type interval

Le type interval en C permet aux programmes de gérer des données du type SQL interval. Voir Section 8.5, « Types date/heure » pour le type équivalent dans le serveur PostgreSQL™.

Les fonctions qui suivent peuvent être utilisées pour travailler avec le type interval :

31.8.5. Type decimal

Le type decimal est similaire au type numeric. Néanmoins, il est limité à une précision maximale de 30 chiffres significatifs. Contrairement au type numeric qui ne peut être créé que sur la partie heap de la mémoire, le type decimal peut être créé soit sur la pile soit sur le heap (au moyen des fonctions PGTYPESdecimal_new() et PGTYPESdecimal_free()). Il existe d'autres fonctions qui gèrent le type decimal dans le mode de compatibilité Informix™ décrit dans Section 31.9, « Mode de compatibilité Informix™ ».

Les fonctions qui suivent sont utilisées pour travailler avec le type decimal et ne sont pas uniquement contenues dans la bibliothèque libcompat.

PGTYPESdecimal_new

réclame un pointeur vers une variable de type decimal nouvellement allouée.

decimal *PGTYPESdecimal_new(void);
PGTYPESdecimal_free

libère toute la mémoire d'un type decimal.

void PGTYPESdecimal_free(decimal *var);

31.8.6. Valeurs errno de pgtypeslib

PGTYPES_NUM_BAD_NUMERIC

Un argument doit contenir une variable de type numeric (ou pointer sur une variable numeric) mais, en fait, sa représentation en mémoire est invalide.

PGTYPES_NUM_OVERFLOW

Un dépassement ( overflow ) est survenu. Comme le type numeric peut gérer une précision quasiment arbitraire, transtyper une variable de type numeric peut causer un dépassement.

PGTYPES_NUM_OVERFLOW

Un soupassement ( underflow , erreur de traitement survenant quand la valeur absolue d'une quantité calculée est plus petite que les limites de précision) est survenu. Comme le type numeric peut gérer une précision quasiment arbitraire, transtyper une variable de type numeric peut causer un soupassement.

PGTYPES_NUM_DIVIDE_ZERO

Tentative de division par zéro.

PGTYPES_DATE_BAD_DATE
PGTYPES_DATE_ERR_EARGS
PGTYPES_DATE_ERR_ENOSHORTDATE
PGTYPES_INTVL_BAD_INTERVAL
PGTYPES_DATE_ERR_ENOTDMY
PGTYPES_DATE_BAD_DAY
PGTYPES_DATE_BAD_MONTH
PGTYPES_TS_BAD_TIMESTAMP