ecpg preprocessor regression in 9.0

Lists: pgsql-bugs
From: Heikki Linnakangas <heikki(dot)linnakangas(at)enterprisedb(dot)com>
To: Michael Meskes <meskes(at)postgresql(dot)org>, Zoltan Boszormenyi <zb(at)cybertec(dot)at>
Cc: PostgreSQL Bugs <pgsql-bugs(at)postgresql(dot)org>
Subject: ecpg preprocessor regression in 9.0
Date: 2010-11-01 13:31:49
Message-ID: 4CCEC145.3020409@enterprisedb.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs

This used to work in the PostgreSQL 8.4 ecpg preprocessor:

EXEC SQL EXECUTE mystmt USING 1.23;

but in 9.0 it throws an error:

floattest.pgc:39: ERROR: variable "1" is not declared

Attached is the full test case, drop it in
src/interfaces/ecpg/test/preproc and compile.

I bisected the cause to this commit:

commit b2bddc2ff22f0c3d54671e43c67a2563deed7908
Author: Michael Meskes <meskes(at)postgresql(dot)org>
Date: Thu Apr 1 08:41:01 2010 +0000

Applied Zoltan's patch to make ecpg spit out warnings if a local
variable hides a global one with the same name.

I don't immediately see why that's causing it, but it doesn't seem
intentional.

--
Heikki Linnakangas
EnterpriseDB http://www.enterprisedb.com

Attachment Content-Type Size
floattest.pgc text/plain 946 bytes

From: Heikki Linnakangas <heikki(dot)linnakangas(at)enterprisedb(dot)com>
To: Michael Meskes <meskes(at)postgresql(dot)org>, Zoltan Boszormenyi <zb(at)cybertec(dot)at>
Cc: PostgreSQL Bugs <pgsql-bugs(at)postgresql(dot)org>
Subject: Re: ecpg preprocessor regression in 9.0
Date: 2010-11-01 13:47:04
Message-ID: 4CCEC4D8.2090809@enterprisedb.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs

On 01.11.2010 15:31, Heikki Linnakangas wrote:
> This used to work in the PostgreSQL 8.4 ecpg preprocessor:
>
> EXEC SQL EXECUTE mystmt USING 1.23;
>
> but in 9.0 it throws an error:
>
> floattest.pgc:39: ERROR: variable "1" is not declared
>
> Attached is the full test case, drop it in
> src/interfaces/ecpg/test/preproc and compile.
>
> I bisected the cause to this commit:
>
> commit b2bddc2ff22f0c3d54671e43c67a2563deed7908
> Author: Michael Meskes <meskes(at)postgresql(dot)org>
> Date: Thu Apr 1 08:41:01 2010 +0000
>
> Applied Zoltan's patch to make ecpg spit out warnings if a local
> variable hides a global one with the same name.
>
> I don't immediately see why that's causing it, but it doesn't seem
> intentional.

On closer look, it's quite obvious: the code added to ECPGdump_a_type
thinks that ECPGt_const is a variable type, and tries to look up the
variable. The straightforward fix is this:

diff --git a/src/interfaces/ecpg/preproc/type.c
b/src/interfaces/ecpg/preproc/type.c
index cc668a2..a53018b 100644
--- a/src/interfaces/ecpg/preproc/type.c
+++ b/src/interfaces/ecpg/preproc/type.c
@@ -246,7 +246,7 @@ ECPGdump_a_type(FILE *o, const char *name, struct
ECPGtype * type,
struct variable *var;

if (type->type != ECPGt_descriptor && type->type != ECPGt_sqlda &&
- type->type != ECPGt_char_variable &&
+ type->type != ECPGt_char_variable && type->type != ECPGt_const &&
brace_level >= 0)
{
char *str;

But I wonder if there is a better way to identify variable-kind of
ECPGttypes than list the ones that are not. There's some special
ECPGttypes still missing from the above if-test, like
ECPGt_NO_INDICATOR, but I'm not sure if they can ever be passed to
ECPGdump_a_type. Seems a bit fragile anyway.

--
Heikki Linnakangas
EnterpriseDB http://www.enterprisedb.com


From: Michael Meskes <meskes(at)postgresql(dot)org>
To: Heikki Linnakangas <heikki(dot)linnakangas(at)enterprisedb(dot)com>
Cc: Michael Meskes <meskes(at)postgresql(dot)org>, Zoltan Boszormenyi <zb(at)cybertec(dot)at>, PostgreSQL Bugs <pgsql-bugs(at)postgresql(dot)org>
Subject: Re: ecpg preprocessor regression in 9.0
Date: 2010-11-02 17:39:13
Message-ID: 20101102173913.GA32303@hyperion.credativ.de
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs

On Mon, Nov 01, 2010 at 03:47:04PM +0200, Heikki Linnakangas wrote:
> On closer look, it's quite obvious: the code added to
> ECPGdump_a_type thinks that ECPGt_const is a variable type, and
> tries to look up the variable. The straightforward fix is this:
> ...
> But I wonder if there is a better way to identify variable-kind of
> ECPGttypes than list the ones that are not. There's some special
> ECPGttypes still missing from the above if-test, like
> ECPGt_NO_INDICATOR, but I'm not sure if they can ever be passed to
> ECPGdump_a_type. Seems a bit fragile anyway.

I agree. How about adding a macro definition explicitely checking for the real
variable types?

Michael
--
Michael Meskes
Michael at Fam-Meskes dot De, Michael at Meskes dot (De|Com|Net|Org)
Michael at BorussiaFan dot De, Meskes at (Debian|Postgresql) dot Org
Jabber: michael.meskes at googlemail dot com
VfL Borussia! Força Barça! Go SF 49ers! Use Debian GNU/Linux, PostgreSQL


From: Korry Douglas <korry(dot)douglas(at)enterprisedb(dot)com>
To: Michael Meskes <meskes(at)postgresql(dot)org>
Cc: Heikki Linnakangas <heikki(dot)linnakangas(at)enterprisedb(dot)com>, Zoltan Boszormenyi <zb(at)cybertec(dot)at>, PostgreSQL Bugs <pgsql-bugs(at)postgresql(dot)org>
Subject: Re: ecpg preprocessor regression in 9.0
Date: 2010-11-02 17:51:29
Message-ID: 2EE12379-4A35-40A8-977B-0CC43B8A7FEB@enterprisedb.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs

>> On closer look, it's quite obvious: the code added to
>> ECPGdump_a_type thinks that ECPGt_const is a variable type, and
>> tries to look up the variable. The straightforward fix is this:
>> ...
>> But I wonder if there is a better way to identify variable-kind of
>> ECPGttypes than list the ones that are not. There's some special
>> ECPGttypes still missing from the above if-test, like
>> ECPGt_NO_INDICATOR, but I'm not sure if they can ever be passed to
>> ECPGdump_a_type. Seems a bit fragile anyway.
>
> I agree. How about adding a macro definition explicitely checking
> for the real
> variable types?

Why not a function instead of a macro? You can set a breakpoint on a
function if you need to debug.

It seems unlikely that you would every see any measurable performance
gain by writing a macro instead of a function.

-- Korry


From: Heikki Linnakangas <heikki(dot)linnakangas(at)enterprisedb(dot)com>
To: Michael Meskes <meskes(at)postgresql(dot)org>
Cc: Zoltan Boszormenyi <zb(at)cybertec(dot)at>, PostgreSQL Bugs <pgsql-bugs(at)postgresql(dot)org>, Korry Douglas <korry(dot)douglas(at)enterprisedb(dot)com>
Subject: Re: ecpg preprocessor regression in 9.0
Date: 2010-11-02 19:34:40
Message-ID: 4CD067D0.6000900@enterprisedb.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs

On 02.11.2010 19:39, Michael Meskes wrote:
> On Mon, Nov 01, 2010 at 03:47:04PM +0200, Heikki Linnakangas wrote:
>> On closer look, it's quite obvious: the code added to
>> ECPGdump_a_type thinks that ECPGt_const is a variable type, and
>> tries to look up the variable. The straightforward fix is this:
>> ...
>> But I wonder if there is a better way to identify variable-kind of
>> ECPGttypes than list the ones that are not. There's some special
>> ECPGttypes still missing from the above if-test, like
>> ECPGt_NO_INDICATOR, but I'm not sure if they can ever be passed to
>> ECPGdump_a_type. Seems a bit fragile anyway.
>
> I agree. How about adding a macro definition explicitely checking for the real
> variable types?

You'd still have to list them all in the macro, but it would definitely
be better. The list would then be closer to the enums, in the same
header file, making it easier to remember to keep it up-to-date.
(Korry's suggestion of making it a function instead of a macro would not
have that advantage).

--
Heikki Linnakangas
EnterpriseDB http://www.enterprisedb.com


From: Korry Douglas <korry(dot)douglas(at)enterprisedb(dot)com>
To: Heikki Linnakangas <heikki(dot)linnakangas(at)enterprisedb(dot)com>
Cc: Michael Meskes <meskes(at)postgresql(dot)org>, Zoltan Boszormenyi <zb(at)cybertec(dot)at>, PostgreSQL Bugs <pgsql-bugs(at)postgresql(dot)org>
Subject: Re: ecpg preprocessor regression in 9.0
Date: 2010-11-02 21:20:49
Message-ID: 66079D10-FE03-487F-B79D-9649F5C67048@enterprisedb.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs

>>> On closer look, it's quite obvious: the code added to
>>> ECPGdump_a_type thinks that ECPGt_const is a variable type, and
>>> tries to look up the variable. The straightforward fix is this:
>>> ...
>>> But I wonder if there is a better way to identify variable-kind of
>>> ECPGttypes than list the ones that are not. There's some special
>>> ECPGttypes still missing from the above if-test, like
>>> ECPGt_NO_INDICATOR, but I'm not sure if they can ever be passed to
>>> ECPGdump_a_type. Seems a bit fragile anyway.
>>
>> I agree. How about adding a macro definition explicitely checking
>> for the real
>> variable types?
>
> You'd still have to list them all in the macro, but it would
> definitely be better. The list would then be closer to the enums, in
> the same header file, making it easier to remember to keep it up-to-
> date. (Korry's suggestion of making it a function instead of a macro
> would not have that advantage).

Sure it would... use a switch statement that explicitly handles each
type and include a default case that throws an error (or assertion).
Of course, you have to run into the code to find out that you forgot
to maintain the classification function. A good C compiler will even
spot the problem if you forget to handle one or more enum values in
the switch statement. A macro offers no assurances at all.

-- Korry


From: Heikki Linnakangas <heikki(dot)linnakangas(at)enterprisedb(dot)com>
To: Michael Meskes <meskes(at)postgresql(dot)org>
Cc: Zoltan Boszormenyi <zb(at)cybertec(dot)at>, PostgreSQL Bugs <pgsql-bugs(at)postgresql(dot)org>
Subject: Re: ecpg preprocessor regression in 9.0
Date: 2011-03-11 15:32:28
Message-ID: 4D7A408C.5000800@enterprisedb.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs

On 01.11.2010 15:47, Heikki Linnakangas wrote:
> On 01.11.2010 15:31, Heikki Linnakangas wrote:
>> This used to work in the PostgreSQL 8.4 ecpg preprocessor:
>>
>> EXEC SQL EXECUTE mystmt USING 1.23;
>>
>> but in 9.0 it throws an error:
>>
>> floattest.pgc:39: ERROR: variable "1" is not declared
>>
>> Attached is the full test case, drop it in
>> src/interfaces/ecpg/test/preproc and compile.
>>
>> I bisected the cause to this commit:
>>
>> commit b2bddc2ff22f0c3d54671e43c67a2563deed7908
>> Author: Michael Meskes <meskes(at)postgresql(dot)org>
>> Date: Thu Apr 1 08:41:01 2010 +0000
>>
>> Applied Zoltan's patch to make ecpg spit out warnings if a local
>> variable hides a global one with the same name.
>>
>> I don't immediately see why that's causing it, but it doesn't seem
>> intentional.
>
> On closer look, it's quite obvious: the code added to ECPGdump_a_type
> thinks that ECPGt_const is a variable type, and tries to look up the
> variable. The straightforward fix is this:
>
> diff --git a/src/interfaces/ecpg/preproc/type.c
> b/src/interfaces/ecpg/preproc/type.c
> index cc668a2..a53018b 100644
> --- a/src/interfaces/ecpg/preproc/type.c
> +++ b/src/interfaces/ecpg/preproc/type.c
> @@ -246,7 +246,7 @@ ECPGdump_a_type(FILE *o, const char *name, struct
> ECPGtype * type,
> struct variable *var;
>
> if (type->type != ECPGt_descriptor && type->type != ECPGt_sqlda &&
> - type->type != ECPGt_char_variable &&
> + type->type != ECPGt_char_variable && type->type != ECPGt_const &&
> brace_level >= 0)
> {
> char *str;
>
> But I wonder if there is a better way to identify variable-kind of
> ECPGttypes than list the ones that are not. There's some special
> ECPGttypes still missing from the above if-test, like
> ECPGt_NO_INDICATOR, but I'm not sure if they can ever be passed to
> ECPGdump_a_type. Seems a bit fragile anyway.

This really needs to be fixed, so I just committed the above patch.

The code needs some love, it took me a while to realize that
find_variable() modifies its argument, for example, which explains the
strdups() in ECPGdump_a_type(). And I wonder why we bother to put
constants to the global all_variables list at all. And I'm not sure the
above type-checks still cover everything. But at least the immediate bug
has now been fixed.

--
Heikki Linnakangas
EnterpriseDB http://www.enterprisedb.com