Skip to content

Commit

Permalink
Rework datetime/date conversion routines.
Browse files Browse the repository at this point in the history
The former coding was far too careless while converting PostgreSQL
temporal values into Informix datum like date or datetime.

The biggest problem was that the former coding treated Informix DATE
and DATETIME nearly identical during conversion and fails to distinguish
their different binary representation at ESQL/C level. This lead to various
confusion, including scribbling beyond allocated memory. Fix this by introducing
a routine ifxSetDate() which handles Informix DATE only and leave the work
for DATETIME target types to setIfxDateTimestamp(), but preserve the possibility
to transform PostgreSQL DATE to Informix DATETIME as well.

Another issue was the treatment of microseconds during conversion
from a PostgreSQL TIMESTAMP to its ISO string representation. PostgreSQL
uses a 6 digit microsecond precision, while Informix only accepts 5 digits.
This is a problem when passing a converted ISO string into an Informix
conversion routine. We always claimed to *not* support fractions when retrieving
temporal values, so omit microseconds fractions from a converted timestamp
value and just pass up to milliseconds fractions only.
  • Loading branch information
Bernd Helmle committed Dec 8, 2015
1 parent 19e6af2 commit 11de42b
Show file tree
Hide file tree
Showing 6 changed files with 323 additions and 135 deletions.
44 changes: 44 additions & 0 deletions ifx_connection.ec
Expand Up @@ -1419,6 +1419,50 @@ void ifxSetTimestampFromString(IfxStatementInfo *info, int ifx_attnum,
}
}

/*
* Converts a date string into a
* DATE value and stores them in the SQLDA structure.
*
* We use rstrdate() internally which relies on DBDATE
* format strings. Since we automatically set an explicit value
* here, we expect the input string always being in the format
* YYYY-MM-DD.
*
* datestr must be a valid null terminated C string referencing
* the date string.
*/
void ifxSetDateFromString(IfxStatementInfo *info,
int ifx_attnum,
char *datestr)
{
struct sqlda *ifx_sqlda;
struct sqlvar_struct *ifx_value;
mint converrcode;

/*
* Set NULL indicator
*/
if (ifxSetSqlVarIndicator(info,
ifx_attnum,
info->ifxAttrDefs[ifx_attnum].indicator) != INDICATOR_NOT_NULL)
return;

ifx_sqlda = (struct sqlda *)info->sqlda;
ifx_value = ifx_sqlda->sqlvar + ifx_attnum;

/*
* We get the DATE value as an ANSI string formatted value
*/
if ((converrcode = rstrdate(datestr,
(int *)ifx_value->sqldata)) < 0)
{
/* An error ocurred, tell the caller something went wrong
* with this conversion */
info->ifxAttrDefs[ifx_attnum].indicator = INDICATOR_NOT_VALID;
info->ifxAttrDefs[ifx_attnum].converrcode = converrcode;
}
}

/*
* Convert a time string given in the format
* hh24:mi:ss into an Informix DATETIME value.
Expand Down

0 comments on commit 11de42b

Please sign in to comment.