Received: from localhost (unknown [200.46.208.211]) by mail.postgresql.org (Postfix) with ESMTP id D26B6634ECC for ; Tue, 19 May 2009 05:12:22 -0300 (ADT) Received: from mail.postgresql.org ([200.46.204.86]) by localhost (mx1.hub.org [200.46.208.211]) (amavisd-maia, port 10024) with ESMTP id 17605-01 for ; Tue, 19 May 2009 05:12:09 -0300 (ADT) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from mail2007.strasbourg.4js.com (mail2007.strasbourg.4js.com [84.14.60.197]) by mail.postgresql.org (Postfix) with ESMTP id D3F5C6349B6 for ; Tue, 19 May 2009 05:12:09 -0300 (ADT) Received: from fox.strasbourg.4js.com (fox.strasbourg.4js.com [10.0.0.196]) (authenticated bits=0) by mail2007.strasbourg.4js.com (8.13.8/8.13.8/Debian-3) with ESMTP id n4J8C8c2003981 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT) for ; Tue, 19 May 2009 10:12:08 +0200 Message-ID: <4A1269E4.1060708@4js.com> Date: Tue, 19 May 2009 10:12:20 +0200 From: Sebastien FLAESCH Organization: Four J's Development Tools User-Agent: Thunderbird 2.0.0.9 (X11/20071031) MIME-Version: 1.0 To: pgsql-interfaces@postgresql.org Subject: INTERVAL data type and libpq - what format? Content-Type: multipart/mixed; boundary="------------070407080205070508030302" X-Virus-Scanned: ClamAV 0.94/9369/Tue May 19 05:46:18 2009 on mail2007.strasbourg.4js.com X-Virus-Status: Clean X-Greylist: Sender succeeded SMTP AUTH, not delayed by milter-greylist-4.0 (mail2007.strasbourg.4js.com [10.10.0.1]); Tue, 19 May 2009 10:12:08 +0200 (CEST) X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=0 tagged_above=0 required=5 tests=none X-Spam-Level: X-Archive-Number: 200905/1 X-Sequence-Number: 6867 This is a multi-part message in MIME format. --------------070407080205070508030302 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Hello, I try to use the new 8.4 INTERVAL type with libpq, but get crazy with the input formatting rules... I use PQprepare() / PQexecPrepared() with parameter list, binding the INTERVAL values with the 1186 pg_type and passing a string buffer with values like: "12345" for an INTERVAL YEAR The INSERT works without error, but when selecting rows from the table in psql, I get "00:00:00" values ?!?! When inserting the value "12345" from the psql command tool it works... I must be doing something wrong, but I could not find any documentation on using INTERVAL in libpq... Can someone from the hackers just tell me if it's supposed to work and if yes what format is expected by the client library? Attached, you have a test case to reproduce the problem. Thanks a lot! Seb --------------070407080205070508030302 Content-Type: text/plain; name="libpqtest1.c" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="libpqtest1.c" /* Version: 8.4.beta1 Created by: sf@4js.com Problem with INTERVAL input format ---------------------------------- After executing this program, 2 rows are present in the table. Only the first has the expected values... Why does the second insert fail to insert "123 11" in INTERVAL DAY TO HOUR? Diagnostic info: SQL State: 22007 Message : invalid input syntax for type interval: " 123 11" Why does the third row show "00:00:00" in first INTERVAL YEAR column? [sf@fox problems]$ psql test1 -U pgsuser psql (8.4beta1) Type "help" for help. test1=> select * from t1; k | i1 | i2 ---+--------------+------------------- 1 | -12345 years | 123 days 11:00:00 3 | 00:00:00 | 123 days 11:00:00 (2 rows) When inserting rows with psql, the format used by the C program are supported: test1=> insert into t1 values ( 4, '-12345', '123 11' ); INSERT 0 1 test1=> select * from t1 where k=4; k | i1 | i2 ---+--------------+------------------- 4 | -12345 years | 123 days 11:00:00 (1 row) So what am I doing wrong here? */ #include #include static int checkResult(PGresult * r) { if (r == NULL) return 0; switch (PQresultStatus(r)) { case PGRES_COMMAND_OK: case PGRES_TUPLES_OK: return 1; default: return 0; } } static void getErrorInfo(PGresult * r) { if (r == NULL) return; fprintf(stderr, "Diagnostic info:\n"); fprintf(stderr, " SQL State: %s\n", PQresultErrorField(r, PG_DIAG_SQLSTATE)); fprintf(stderr, " Message : %s\n", PQresultErrorField(r, PG_DIAG_MESSAGE_PRIMARY)); } int main(int argc, char **argv) { PGresult *r; PGconn *c; Oid paramTypes[10]; const char *paramValues[10]; fprintf(stdout,"++ Connecting...\n"); c = PQconnectdb("dbname='test1' user='pgsuser' password='fourjs'"); if (c == NULL) { fprintf(stderr,">> Could not connect.\n"); exit(1); } fprintf(stdout,"++ Creating table t1 ...\n"); r = PQexec(c, "DROP TABLE t1"); PQclear(r); r = PQexec(c, "CREATE TABLE t1 ( k INT, i1 INTERVAL YEAR, i2 INTERVAL DAY TO HOUR)"); if (!checkResult(r)) { fprintf(stderr,">> Could not create table 1.\n"); getErrorInfo(r); exit(1); } PQclear(r); fprintf(stdout,"++ Preparing INSERT ...\n"); paramTypes[0] = 23; /* INT4 */ paramTypes[1] = 1186; /* INTERVAL */ paramTypes[2] = 1186; /* INTERVAL */ r = PQprepare(c, "s1", "INSERT INTO t1 VALUES ( $1, $2, $3 )", 3, (const Oid *) paramTypes); if (!checkResult(r)) { fprintf(stderr,">> Could not prepare stmt 1.\n"); getErrorInfo(r); exit(1); } PQclear(r); /* This is working */ fprintf(stdout,"++ Executing INSERT (1) ...\n"); paramValues[0] = "1"; paramValues[1] = "-12345 years"; paramValues[2] = " 123 11:00"; r = PQexecPrepared(c, "s1", 3, paramValues, NULL, NULL, 0); if (!checkResult(r)) { fprintf(stderr,">> Could not exec stmt 1.\n"); getErrorInfo(r); exit(1); } PQclear(r); /* This is NOT working */ fprintf(stdout,"++ Executing INSERT (2) ...\n"); paramValues[0] = "2"; paramValues[1] = "-12345"; paramValues[2] = " 123 11"; r = PQexecPrepared(c, "s1", 3, paramValues, NULL, NULL, 0); if (!checkResult(r)) { fprintf(stderr,">> Could not exec stmt 2.\n"); getErrorInfo(r); /*exit(1);*/ } PQclear(r); /* This is NOT working */ fprintf(stdout,"++ Executing INSERT (3) ...\n"); paramValues[0] = "3"; paramValues[1] = "-12345"; paramValues[2] = " 123 11:00"; r = PQexecPrepared(c, "s1", 3, paramValues, NULL, NULL, 0); if (!checkResult(r)) { fprintf(stderr,">> Could not exec stmt 3.\n"); getErrorInfo(r); exit(1); } PQclear(r); PQfinish(c); } --------------070407080205070508030302--