PostgreSQL La base de donnees la plus sophistiquee au monde.

Forums PostgreSQL.fr

Le forum officiel de la communauté francophone de PostgreSQL

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

#26 Re : Général » Infos sur comportement fonction to_timestamp » 12/07/2011 16:27:32

Bonjour,

Le comportement s'applique aussi avec des nombres négatifs ou une absence de valeur :

bdcp=> select to_timestamp('201107-2','yyyymmdd');       -- bizarre toutefois car 3 jours et non 2 avant le 01 juillet 2011
      to_timestamp     
------------------------
2011-06-28 00:00:00+00
(1 row)

bdcp=> select to_timestamp('201107','yyyymmdd');       -- ok, 01 juillet 2011 à 00 heure
      to_timestamp     
------------------------
2011-07-01 00:00:00+00
(1 row)

bdcp=> show datestyle;
DateStyle
-----------
ISO, MDY
(1 row)

bdcp=> select '201107-2'::timestamp;       -- ok, erreur de formatage
ERROR:  invalid input syntax for type timestamp: "201107-2"
LINE 1: select '201107-2'::timestamp;
               ^
bdcp=> select '201107'::timestamp;  -- bizarre car erreur de formatage
      timestamp     
---------------------
2020-11-07 00:00:00
(1 row)

En fait, dans le dernier exemple, l'année est prise sur 2 digits, soit 2020 11 07,  soit 2020, novembre, le 07
Par contre, la logique du premier exemple n'est pas forcément évidente (2 jours avant le 30 juin et non le 01 juillet).

Par ailleurs, le comportement de to_date semble similaire à celui de to_timestamp et selon Guillaume, cela semble plus être une fonction de calcul de date/timestamp qu'une façon d'indiquer une date/un timestamp.

Y-a-il un moyen de rendre plus " strict " les fonctions to_timestamp... ?

Par avance, merci.

#27 Re : Général » caractères d'échappement \n \f \r retour chariot ou à la ligne » 21/01/2011 10:35:02

Je note bien que le client PostgreSQL, " psql est avant tout un outil d'administration. Son but n'est pas d'interpréter ce qui se trouve dans les champs."

Ceci dit, psql est aussi (je pense, communément) utilisé dans des shell car il s'agit d'un outil simple, léger, robuste et facile à mettre en place.
cf. précédemment :
$ psql -h la_machine_hote -d bdd -p 5433 -U le_user -o toooo -c " SELECT E'ceci est un test \n avec antislash n'"
...

En utilisant psql, je me suis alors interrogé sur le fait que la séquence d'échappement \n ou encore \t était interprétée mais pas \f par exemple.
Mais, je comprends, comme le précise Guillaume, que " La façon dont sont gérés les séquences d'échappement dépend principalement des décisions prises ".

#28 Re : Général » caractères d'échappement \n \f \r retour chariot ou à la ligne » 20/01/2011 20:53:29

Effectivement, l'accès par driver JDBC (postgresql-9.0-801.jdbc4.jar) ne s'appuie pas sur psql et n'applique pas les mêmes règles d'interprétation des séquences d'échappement.

J'ai fait un test sur une base postgreSQL 8.3.13,
en interrogeant une table toto :
Bienvenue dans psql 8.3.13, l'interface interactive de PostgreSQL.
toto=# select * from toto;
pk |                       a                       
----+-----------------------------------------------
  1 | ceci est un test \x0C avec antislash f
  2 | ceci est un test
    :  avec antislash n
  3 | ceci est un test \r avec antislash r
  4 | ceci est un test \r\x0C avec antislash r et f
(4 lignes)


L'accès à l'aide du driver postgresql-9.0-801.jdbc4.jar donne en affichant (en java : System.out.println(rs.getInt("pk")+" "+rs.getString("a"));) la valeur de la première colonne suivie d'un espace puis la valeur de la 2ème colonne :
Début du test :
1  ceci est un test
                     avec antislash f
2  ceci est un test
avec antislash n
avec antislash rst
4  ceci est un test
avec antislash r et f

Merci encore

#29 Re : Général » caractères d'échappement \n \f \r retour chariot ou à la ligne » 20/01/2011 16:15:34

Tout d'abord, je vous remercie de vous intéresser, en apportant des réponses, à cette discussion.

L'interprétation des séquences d'échappement a effectivement changé entre la version 8.1 et 8.4 ou plus précisément 8.2 d'après Gilles.
J'ai bien lu les réponses de Guillaume et Gilles, à savoir qu'il s'agit de " décisions prises pour un meilleur affichage sur des écrans de taille différente " et de la volonté d'" améliorer la lisibilité des données " et je comprends bien que cela résulte d'efforts de la part de l'équipe des programmeurs.
Guillaume répond à ma dernière question en indiquant qu' " il n'y a aucun moyen de changer ce comportement ".
Je pense toutefois qu'il serait intéressant d'avoir la possibilité de choisir de récupérer, soit la séquence d'échappement (par exemple \f), soit le code d'échappement.
Peut-être une proposition à faire pour une version ultérieure ?

Pour répondre à Gilles, dans le cas qui m'intéresse, l'interrogation de la bdd a pour but de réaliser un produit (basé sur une application Java) avec une zone texte et une mise en page adéquate s'appuyant sur le contenu d'une colonne de type VARCHAR.
Quant à la différence entre une séquence d'échappement ou une autre à l'affichage, cela n'a pas d'importance pour moi, ce qui m'intéresse, c'est d'avoir l'affichage souhaité par les séquences que j'ai indiquées et de ne pas les " neutraliser ".
Par ailleurs, à l'affichage, il y a une différence entre \n\t et \f ; mais pas entre \f\r et \n.
Mais, si je veux le code pour faire la différence, j'écris, comme indiqué précédemment, par exemple,
en client 8.1 :
postgres=# SELECT E'ceci est un test pour Gilles \f\r avec antislash f et r'::bytea;
                            bytea                           
-------------------------------------------------------------
ceci est un test pour Gilles \014\015 avec antislash f et r
(1 ligne)
car effectivement, l'affichage avec une requête sans ::bytea ne donne pas de différence entre \f\r et \n :
        1 | ceci est un test pour Gilles
avec antislash f et r |      111
(1 ligne)
ou bien :
postgres=# SELECT 1, E'ceci est un test pour Gilles \n avec antislash n', 111;
?column? |           ?column?            | ?column?
----------+-------------------------------+----------
        1 | ceci est un test pour Gilles
avec antislash n |      111




Juste pour information, sous Oracle 9.2 ou 11.2, le résultat se présente de la sorte :
SQL*Plus: Release 11.2.0.2.0
SQL> select 111, 'ceci est un test '||chr(12)||' avec antislash f', 'Troisième colonne' from dual;

       111 'CECIESTUNTEST'||CHR(12)||'AVECANTISLASHF'                                                                'TROISIÈMECOLONNE'
---------- --------------------------------------------------------------------------------------------------------- ---------------------------------------------------
       111 ceci est un test
                             avec antislash f                                                                       Troisième colonne

SQL> select 222, 'ceci est un test '||chr(10)||' avec antislash n', 'Troisième colonne' from dual;

       222 'CECIESTUNTEST'||CHR(10)||'AVECANTISLASHN'                                                                'TROISIÈMECOLONNE'
---------- --------------------------------------------------------------------------------------------------------- ---------------------------------------------------
       222 ceci est un test                                                                                          Troisième colonne
            avec antislash n


SQL> select 333, 'ceci est un test '||chr(13)||' avec antislash r', 'Troisième colonne' from dual;

       333 'CECIESTUNTEST'||CHR(13)||'AVECANTISLASHR'                                                                'TROISIÈMECOLONNE'
---------- --------------------------------------------------------------------------------------------------------- ---------------------------------------------------
avec antislash r                                                                       Troisième colonne


Assez logiquement, sous client psql 8.4.5 :
$ psql -h la_machine_hote -d bdd -p 5433 -U le_user -o toooo -c " SELECT E'ceci est un test \f avec antislash f'"
$ more toooo
                ?column?               
----------------------------------------
ceci est un test \x0C avec antislash f
(1 row)

$ psql -h la_machine_hote -d bdd -p 5433 -U le_user -o toooo -c " SELECT E'ceci est un test \n avec antislash n'"
$ more toooo
     ?column?     
-------------------
ceci est un test
  avec antislash n
(1 row)


Sous client postgreSQL psql 8.4.5, on peut toutefois écrire :
bdd=> COPY (SELECT 111, 'ceci est un test '||chr(12)||' avec antislash f', 'Troisième colonne') to stdout with csv;
111,ceci est un test
                      avec antislash f,Troisième colonne
bdd=> COPY (SELECT 222, 'ceci est un test '||chr(10)||' avec antislash n', 'Troisième colonne') to stdout with csv;
222,"ceci est un test
avec antislash n",Troisième colonne
bdd=> COPY (SELECT 333, 'ceci est un test '||chr(13)||' avec antislash r', 'Troisième colonne') to stdout with csv;
avec antislash r",Troisième colonne

L'interprétation des séquences d'échappement se fait grâce au COPY (non standard SQL) et non au SELECT.

Encore une fois, je vous (les remerciements s'adressent aussi à un collègue) remercie sincèrement et, bien sûr, si vous avez des éléments nouveaux, je suis preneur.

#30 Re : Général » caractères d'échappement \n \f \r retour chariot ou à la ligne » 20/01/2011 12:41:43

Des tests ont montré que la non-interprétation des séquences d'échappement \f et \r provient du client posgreSQL et non du serveur ; par ailleurs, une version psql cliente 8.1 interprète bien les séquences d'échappement alors qu'une version 8.4 ne les interprète pas.

-bash-3.2$ psql -h la_machnie_hote -d bdd -p 5433 -U le_user
Password for user le_user:
Welcome to psql 8.1.22 (server 8.4.5), the PostgreSQL interactive terminal.

Type:  \copyright for distribution terms
       \h for help with SQL commands
       \? for help with psql commands
       \g or terminate with semicolon to execute query
       \q to quit

WARNING:  You are connected to a server with major version 8.4,
but your psql client is major version 8.1.  Some backslash commands,
such as \d, might not work properly.

bdd=> SELECT E'ceci est un test \f avec antislash f';
     ?column?     
-------------------
ceci est un test
                   avec antislash f
(1 row)


Avez-vous des éléments qui expliquent cette analyse (différences entre 8,1 et 8,4...) et comment peut-on configurer le client pour forcer l'interprétation ?

#31 Re : Général » caractères d'échappement \n \f \r retour chariot ou à la ligne » 19/01/2011 15:42:56

Si l'on demande à la commande echo de ne pas interpréter les séquences d'échappement (valeur par défaut), elle ne les interprète pas :

Par exemple, sur le serveur avec bdd :
$ echo -E "ceci est un test \f avec antislash f"

ceci est un test \f avec antislash f

$ echo -E "ceci est un test \n avec antislash n"

ceci est un test \n avec antislash n

$ echo -E "ceci est un test \r avec antislash r"

ceci est un test \r avec antislash r


De même, pour PostgreSQL, comme vous me l'avez montré, il semble que l'on peut voir le contenu binaire codé en décimal (stockage interne) des séquences d'échappement par :
bdd=> SELECT E'ceci est un test \f\r avec antislash f et r'::bytea;

                      bytea                     

-------------------------------------------------

ceci est un test \014\015 avec antislash f et r

(1 row)



Sur mon PC Linux, j'ai installé un serveur PostgreSQL  8.1 :
-bash-3.2$ psql

Bienvenue dans psql 8.1.22, l'interface interactive de PostgreSQL.



postgres=# SELECT E'ceci est un test \f\r avec antislash f et r'::bytea;

                      bytea                     

-------------------------------------------------

ceci est un test \014\015 avec antislash f et r

(1 ligne)



=> même résultat que sur le serveur.

Par contre, sur mon PC, j'obtiens bien l'interprétation des séquences d'échappement :
postgres=# SELECT E'ceci est un test \f avec antislash f qui donne bien le form feed';

     ?column?     

-------------------

ceci est un test

                   avec antislash f qui donne bien le form feed

(1 ligne)



postgres=#

postgres=# SELECT E'ceci est un test \r avec antislash r qui donne bien le carriage return';

     ?column?     

-------------------

avec antislash r qui donne bien le carriage return

(1 ligne)



Il doit donc probablement s'agir d'une configuration, environnement PostgreSQL ou système à mettre en place.

#32 Re : Général » caractères d'échappement \n \f \r retour chariot ou à la ligne » 19/01/2011 10:47:08

Effectivement (sous PostgreSQL comme sous Linux) :
\f Form feed (ASCII 12)
\n Newline (ASCII 10)
\r Carriage return (ASCII 13)
Cela provient vraisemblablement des premières machines à écrire (avec ruban).

Sur mon PC ou sur le serveur Linux qui héberge la base bdd, voilà l'affichage " correct " :
$ echo -e "ceci est un test \f avec antislash f"
ceci est un test
                  avec antislash f
$ echo -e "ceci est un test \n avec antislash n"
ceci est un test
avec antislash n
$ echo -e "ceci est un test \r avec antislash r"
avec antislash r

\f produit, à l'affichage, un saut de ligne sans retour en début de ligne,
\n un saut de ligne avec retour en début de ligne,
\r un retour en début de ligne.

#33 Re : Général » caractères d'échappement \n \f \r retour chariot ou à la ligne » 19/01/2011 09:18:34

A priori, oui,
Mais quel paramétrage, configuration, environnement adopter pour obtenir un affichage correct pour les différentes séquences d'échappement ?
Alors que \n s'affiche correctement, il est surtout surprenant que \f et \r ne s'affichent pas de la même manière (valeur hexadécimale pour l'un et séquence d'échappement pour l'autre) :

bdd=> SELECT E'ceci est un test \f avec antislash f qui donne la valeur hexadécimale';
                                ?column?                                 
-------------------------------------------------------------------------
ceci est un test \x0C avec antislash f qui donne la valeur hexadécimale
(1 row)

bdd=> SELECT E'ceci est un test \r avec antislash r qui donne la séquence d''échappement';
                                 ?column?                                 
--------------------------------------------------------------------------
ceci est un test \r avec antislash r qui donne la séquence d'échappement
(1 row)

#34 Général » caractères d'échappement \n \f \r retour chariot ou à la ligne » 18/01/2011 16:49:19

jacques
Réponses : 14

Bonjour,

Je cherche à comprendre pourquoi les caractères d'échappement \f et \r ne sont pas interprétés correctement sur ma machine avec base PostgreSQL 8.4.

Tout d'abord, depuis mon PC Linux, je me connecte avec " ssh -X -l mon_user le_serveur " sur le serveur qui héberge la base bdd.

$ locale
LANG=C
LC_CTYPE="C"
LC_NUMERIC="C"
LC_TIME="C"
LC_COLLATE="C"
LC_MONETARY="C"
LC_MESSAGES="C"
LC_PAPER="C"
LC_NAME="C"
LC_ADDRESS="C"
LC_TELEPHONE="C"
LC_MEASUREMENT="C"
LC_IDENTIFICATION="C"
LC_ALL=

$ export LANG=fr_FR.UTF-8

$ psql -d bdd
psql (8.4.5)
Saisissez « help » pour l'aide.

bdd=> show client_encoding;
client_encoding
-----------------
UTF8
(1 ligne)

bdd=> show server_encoding;
server_encoding
-----------------
UTF8
(1 ligne)

bdd=> create table table_test(
bdd(> pk numeric(2),
bdd(> a text,
bdd(> constraint pk_table_test primary key(pk)
bdd(> );
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "pk_table_test" for table "table_test"
CREATE TABLE
bdd=>
bdd=> INSERT INTO table_test VALUES (1,'ceci est un test \f avec antislash f');
WARNING:  nonstandard use of escape in a string literal
LIGNE 1 : INSERT INTO table_test VALUES (1,'ceci est un test \f avec a...
                                           ^
ASTUCE : Use the escape string syntax for escapes, e.g., E'\r\n'.
INSERT 0 1
bdd=> INSERT INTO table_test VALUES (2,E'ceci est un test \f avec antislash f');
INSERT 0 1
bdd=> INSERT INTO table_test VALUES (3,E'ceci est un test \n avec antislash n');
INSERT 0 1
bdd=> INSERT INTO table_test VALUES (4,E'ceci est un test \r avec antislash r');
INSERT 0 1
bdd=> INSERT INTO table_test VALUES (5,E'ceci est un test \f\r avec antislash f et r');
INSERT 0 1
bdd=>
bdd=> select * from table_test;
pk |                       a                       
----+-----------------------------------------------
  1 | ceci est un test \x0C avec antislash f
  2 | ceci est un test \x0C avec antislash f
  3 | ceci est un test
    :  avec antislash n
  4 | ceci est un test \r avec antislash r
  5 | ceci est un test \x0C\r avec antislash f et r
(5 lignes)


Sur cette machine et avec ma configuration, le caractère \n est bien visible mais \r ou \f ne sont pas interprétés comme on peut le souhaiter.

Avez-vous une explication ?
Bien cordialement

Pied de page des forums

Propulsé par FluxBB