Discussion:
[BUGS] BUG #14267: ecpg bug causes hanging for certain data types
(too old to reply)
n***@gmail.com
2016-07-27 19:30:42 UTC
Permalink
The following bug has been logged on the website:

Bug reference: 14267
Logged by: Niles Oien
Email address: ***@gmail.com
PostgreSQL version: 9.5.3
Operating system: CentOS release 6.7 (Final)
Description:


Hi,

We have a program that compiles with ecpg that seemed to hang until we
changed the type of a variable from "unsigned long long" to be simply "long
long int".

We think we've tracked this down somewhat.

It appears that there might be a defect in the guard statement that appears
on lines 377 and 378 of data.c (in the ECPG C preprocessor in PG version
9.5.3, see the first snippet below). isarray is defined as a C enum, however
the condition used in the guard appears to be treating isarray like a
Boolean variable. A cursory examination of other conditions involving
isarray suggest that perhaps isarray should be replaced with
ECPG_IS_ARRAY(isarray). The other snippets included below in this message
(lines 392 - 399, 599-605, ...) also use isarray like a Boolean variable,
however this may be by design since the integer value of the enum value
ECPG_ARRAY_ERROR is 0 (so !isarray implies no array error).

The code from data.c :

375 #ifdef HAVE_STRTOULL
376 case ECPGt_unsigned_long_long:
377 *((unsigned long long int *) (var + offset *
act_tuple)) = strtoull(pval, &scan_length, 10);
378 if ((isarray && *scan_length != ',' &&
*scan_length != '}')
379 || (!isarray && !(INFORMIX_MODE(compat) &&
*scan_length == '.') && *scan_length != '\0' && *scan_length != ' '))
/* Garbage left */
380 {
381 ecpg_raise(lineno, ECPG_UINT_FORMAT,
ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
382 return (false);
383 }
384 pval = scan_length;
385
386 break;
387 #endif /* HAVE_STRTOULL */

392 case ECPGt_double:
392 if (isarray && *pval == '"')
393 pval++;
394
395 if (!check_special_value(pval, &dres,
&scan_length))
396 dres = strtod(pval, &scan_length);
397
398 if (isarray && *scan_length == '"')
399 scan_length++;

599 if (!isarray && garbage_left(isarray,
scan_length, compat))
600 {
601 free(nres);
602 ecpg_raise(lineno, ECPG_NUMERIC_FORMAT,
603
ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
604 return (false);
605 }

657 if (!isarray && garbage_left(isarray,
scan_length, compat))
658 {
659 free(ires);
660 ecpg_raise(lineno, ECPG_INTERVAL_FORMAT,
661
ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
662 return (false);
663 }

707 if (!isarray && garbage_left(isarray,
scan_length, compat))
708 {
709 ecpg_raise(lineno, ECPG_DATE_FORMAT,
710
ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
711 return (false);
712 }

755 if (!isarray && garbage_left(isarray,
scan_length, compat))
756 {
757 ecpg_raise(lineno,
ECPG_TIMESTAMP_FORMAT,
758
ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
759 return (false);
760 }


It could be that the type "unsigned long long" is simply not supported,
however I'd still suggest that if that's the case then use of that type
should be a compile time error rather than a runtime hang?

There are two of us who tracked this down, myself and an Art Amezcua. If
this explanation isn't clear do please get back to me and I'll try to
explain it, Art frankly understands it much better than I do.

Here are the details of what version I have, although in fact we've seen
this for several versions of postgres (but not before 8.4 inclusive) and Art
has 9.5.3 while I'm back at 9.5.2 :

select version();

PostgreSQL 9.5.2 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.4.7
20120313 (Red Hat 4.4.7-16), 64-bit

$ ecpg --version
ecpg (PostgreSQL 9.5.2) 4.11.0

And the operating system :

$ cat /etc/issue
CentOS release 6.7 (Final)
Kernel \r on an \m


Thanks for considering this!

Niles Oien
National Solar Observatory
Boulder Colorado
--
Sent via pgsql-bugs mailing list (pgsql-***@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpr
Michael Meskes
2016-08-01 05:15:51 UTC
Permalink
Post by n***@gmail.com
...
We have a program that compiles with ecpg that seemed to hang until we
changed the type of a variable from "unsigned long long" to be simply "long
long int".
Thanks for finding this.
Post by n***@gmail.com
We think we've tracked this down somewhat.
It appears that there might be a defect in the guard statement that appears
on lines 377 and 378 of data.c (in the ECPG C preprocessor in PG version
...
And more thanks for tracking it down. I have no idea why this ages old code is
still in there. Apparently not many people use unsigned long long. Anyway, a
fix will be pushed as soon as I'm online again.

Michael
--
Michael Meskes
Michael at Fam-Meskes dot De, Michael at Meskes dot (De|Com|Net|Org)
Meskes at (Debian|Postgresql) dot Org
Jabber: michael at xmpp dot meskes dot org
VfL Borussia! Força Barça! Go SF 49ers! Use Debian GNU/Linux, PostgreSQL
--
Sent via pgsql-bugs mailing list (pgsql-***@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-bugs
Loading...