\if, \elseif, \else, \endif (was Re: PSQL commands: \quit_if, \quit_unless)

Started by Corey Huinkerabout 9 years ago232 messageshackers
Jump to latest
#1Corey Huinker
corey.huinker@gmail.com

Fabien is pressed for time, so I've been speaking with him out-of-thread
about how I should go about implementing it.

The v1 patch will be \if <expr>, \elseif <expr>, \else, \endif, where
<expr> will be naively evaluated via ParseVariableBool().

\ifs and \endifs must be in the same "file" (each MainLoop will start a
new if-stack). This is partly for sanity (you can see the pairings unless
the programmer is off in \gset meta-land), partly for ease of design (data
structures live in MainLoop), but mostly because it would an absolute
requirement if we ever got around to doing \while.

I hope to have something ready for the next commitfest.

As for the fate of \quit_if, I can see it both ways. On the one hand,
it's super-simple, already written, and handy.

On the other hand, it's easily replaced by

\if <expr>
\q
\endif

So I'll leave that as a separate reviewable patch.

As for loops, I don't think anyone was pushing for implementing \while
now, only to have a decision about what it would look like and how it would
work. There's a whole lot of recording infrastructure (the input could be a
stream) needed to make it happen. Moreover, I think \gexec scratched a
lot of the itches that would have been solved via a psql looping structure.

And here's the patch. I've changed the subject line and will be submitting
a new entry to the commitfest.

Attachments:

0001.if_endif.difftext/plain; charset=US-ASCII; name=0001.if_endif.diffDownload+456-24
#2Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#1)
Re: \if, \elseif, \else, \endif (was Re: PSQL commands: \quit_if, \quit_unless)

And here's the patch. I've changed the subject line and will be submitting
a new entry to the commitfest.

A few comments:

Patch applies, make check is ok, but currently really too partial.

I do not like the choice of "elseif", which exists in PHP & VB. PL/pgSQL
has "ELSIF" like perl, that I do not like much, though. Given the syntax
and behavioral proximity with cpp, I suggest that "elif" would be a better
choice.

Documentation: I do not think that the systematic test-like example in the
documentation is relevant, a better example should be shown. The list of
what is considered true or false should be told explicitely, not end with
"etc" that is everyone to guess.

Tests: On principle they should include echos in all non executed branches
to reassure that they are indeed not executed.

Also, no error cases are tested. They should be. Maybe it is not very easy
to test some cases which expect to make psql generate errors, but I feel
they are absolutely necessary for such a feature.

1: unrecognized value "whatever" for "\if"; assuming "on"

I do not think that the script should continue with such an assumption.

2: encountered \else after \else ... "# ERROR BEFORE"

Even with ON_ERROR_STOP activated the execution continues.

3: no \endif

Error reported, but it does not stop even with ON_ERROR_STOP.

4: include with bad nesting...

Again, even with ON_ERROR_STOP, the execution continues...

Code:

   -       if (status != PSQL_CMD_ERROR)
   +       if ((status != PSQL_CMD_ERROR) && psqlscan_branch_active(scan_state))

Why the added parenthesis?

case ...: case ...:

The project rules are to add explicit /* PASSTHROUGH */ comment.

There are spaces at the end of one line in a comment about
psqlscan_branch_end_state.

There are multiple "TODO" comments in the file... Is it done or work in
progress?

Usually in pg comments about a function do not repeat the function name.
For very short comment, they are /* inlined */ on one line. Use pg comment
style.

--
Fabien.

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#3Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Fabien COELHO (#2)
Re: \if, \elseif, \else, \endif (was Re: PSQL commands: \quit_if, \quit_unless)

A few comments:

Argh, better with the attachements:-(

--
Fabien.

Attachments:

if-error-1.sqlapplication/x-sql; name=if-error-1.sqlDownload
if-error-2.sqlapplication/x-sql; name=if-error-2.sqlDownload
if-error-3.sqlapplication/x-sql; name=if-error-3.sqlDownload
if-error-4.sqlapplication/x-sql; name=if-error-4.sqlDownload
#4Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#2)
Re: \if, \elseif, \else, \endif (was Re: PSQL commands: \quit_if, \quit_unless)

I do not like the choice of "elseif", which exists in PHP & VB. PL/pgSQL
has "ELSIF" like perl, that I do not like much, though. Given the syntax
and behavioral proximity with cpp, I suggest that "elif" would be a better
choice.

I'm personally indifferent to elif vs elsif vs elseif, but I think elseif
was the consensus. It's easy enough to change.

Documentation: I do not think that the systematic test-like example in the
documentation is relevant, a better example should be shown. The list of
what is considered true or false should be told explicitely, not end with
"etc" that is everyone to guess.

It was copied from the regression test. I knew there would be follow-up
suggestions for what should be shown.

Tests: On principle they should include echos in all non executed branches
to reassure that they are indeed not executed.

Will do.

Also, no error cases are tested. They should be. Maybe it is not very easy
to test some cases which expect to make psql generate errors, but I feel
they are absolutely necessary for such a feature.

Will do.

1: unrecognized value "whatever" for "\if"; assuming "on"

I do not think that the script should continue with such an assumption.

I agree, and this means we can't use ParseVariableBool() as-is. I already
broke out argument reading to it's own function, knowing that it'd be the
stub for expressions. So I guess we start that now. What subset of true-ish
values do you think we should support? If we think that real expressions
are possible soon, we could only allow 'true' and 'false' for now, but if
we expect that expressions might not make it into v10, then perhaps we
should support the same text values that coerce to booleans on the server
side.

2: encountered \else after \else ... "# ERROR BEFORE"

Even with ON_ERROR_STOP activated the execution continues.

3: no \endif

Error reported, but it does not stop even with ON_ERROR_STOP.

4: include with bad nesting...

Again, even with ON_ERROR_STOP, the execution continues...

All valid issues. Will add those to the regression as well (with
ON_ERROR_STOP disabled, obviously).

Code:

-       if (status != PSQL_CMD_ERROR)
+       if ((status != PSQL_CMD_ERROR) && psqlscan_branch_active(scan_st
ate))

Why the added parenthesis?

Will fix.

case ...: case ...:

The project rules are to add explicit /* PASSTHROUGH */ comment.

Will do.

There are spaces at the end of one line in a comment about
psqlscan_branch_end_state.

There are multiple "TODO" comments in the file... Is it done or work in
progress?

I forgot to remove them. But it would be wildly optimistic of me to think
there would be no more work for me after the first patch submission.

Usually in pg comments about a function do not repeat the function name.
For very short comment, they are /* inlined */ on one line. Use pg comment
style.

In that case, I was copying the style found in other functions psqlscan.l -
I'm happy to remove it.

#5Corey Huinker
corey.huinker@gmail.com
In reply to: Corey Huinker (#4)
Re: \if, \elseif, \else, \endif (was Re: PSQL commands: \quit_if, \quit_unless)

On Mon, Jan 23, 2017 at 4:12 PM, Corey Huinker <corey.huinker@gmail.com>
wrote:

I do not like the choice of "elseif", which exists in PHP & VB. PL/pgSQL

has "ELSIF" like perl, that I do not like much, though. Given the syntax
and behavioral proximity with cpp, I suggest that "elif" would be a better
choice.

I'm personally indifferent to elif vs elsif vs elseif, but I think elseif
was the consensus. It's easy enough to change.

Went with elsif to follow pl/pgsql. In reviewing the original thread it
seemed that "elif" was linked to "fi" and that got some negative feedback.

Documentation: I do not think that the systematic test-like example in
the documentation is relevant, a better example should be shown. The list
of what is considered true or false should be told explicitely, not end
with "etc" that is everyone to guess.

It was copied from the regression test. I knew there would be follow-up
suggestions for what should be shown.

Work on this is pending discussion of what true/false values we should
allow, and if values outside of those is an error.

case ...: case ...:

The project rules are to add explicit /* PASSTHROUGH */ comment.

Will do.

I went looking for other examples of explicit /* PASSTHROUGH */ comments
and could find none. Could you explain what it is you want me to fix with
the switch statements?

#6Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#5)
Re: \if, \elseif, \else, \endif (was Re: PSQL commands: \quit_if, \quit_unless)

Hello,

I'm personally indifferent to elif vs elsif vs elseif, but I think elseif
was the consensus. It's easy enough to change.

Went with elsif to follow pl/pgsql. In reviewing the original thread it
seemed that "elif" was linked to "fi" and that got some negative feedback.

As I understood it, the negative feeback was really about sh inspiration
"if/fi", not about elif/elsif/elseif. I do not think that there was an
expressed consensus about the later.

Else-if variants from different languages include:

VB: If ElseIf Else End If (with optional Then)
PHP: if {} elseif {} else {}
Tcl: if {} elseif {} else {}

PL/pgSQL: IF ... THEN ... ELSIF ... ELSE ... END IF;
Perl: if {} elsif {} else {}
Ruby: if elsif else end

CPP: #if #elif #else #endif
Python: if : elif: else:
bash: if [] then ... elif ... else ... fi

The closest case is CPP with its line-oriented #-prefix syntax, and I
still think that we should do it like that.

I went looking for other examples of explicit /* PASSTHROUGH */ comments
and could find none. Could you explain what it is you want me to fix with
the switch statements?

Sorry, I got it wrong. The comment (which is FALLTHROUGH or FALL THROUGH,
not PASSTHROUGH) is required if there is specific code in a case and the
case is expected to continue with executing the next case code as well.
This is quite rare, and it is not the case for your code, which just has
some comments in one case.

--
Fabien

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#7Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#4)
Re: \if, \elseif, \else, \endif (was Re: PSQL commands: \quit_if, \quit_unless)

1: unrecognized value "whatever" for "\if"; assuming "on"

I do not think that the script should continue with such an assumption.

I agree, and this means we can't use ParseVariableBool() as-is. I
already broke out argument reading to it's own function, knowing that
it'd be the stub for expressions. So I guess we start that now. What
subset of true-ish values do you think we should support? If we think
that real expressions are possible soon, we could only allow 'true' and
'false' for now, but if we expect that expressions might not make it
into v10, then perhaps we should support the same text values that
coerce to booleans on the server side.

Hmmm. I would text value that coerce to true? I would also accept non-zero
integers (eg SELECT 1::BOOL; -- t).

I would suggest to assume false on everything else, and/or maybe to ignore
the whole if/endif section in such cases.

All valid issues. Will add those to the regression as well (with
ON_ERROR_STOP disabled, obviously).

ISTM that with TAP test you can check for error returns, so maybe this can
be done.

--
Fabien.

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#8Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#6)
Re: \if, \elseif, \else, \endif (was Re: PSQL commands: \quit_if, \quit_unless)

As I understood it, the negative feeback was really about sh inspiration
"if/fi", not about elif/elsif/elseif. I do not think that there was an
expressed consensus about the later.

True

The closest case is CPP with its line-oriented #-prefix syntax, and I
still think that we should do it like that.

Given that the pl/pgsql syntax has a space between "end" and "if", I have
to agree. It's easy enough to change back if others can make a convincing
argument for something else.

#9Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#7)
Re: \if, \elseif, \else, \endif (was Re: PSQL commands: \quit_if, \quit_unless)

On Tue, Jan 24, 2017 at 1:15 AM, Fabien COELHO <coelho@cri.ensmp.fr> wrote:

1: unrecognized value "whatever" for "\if"; assuming "on"

I do not think that the script should continue with such an assumption.

I agree, and this means we can't use ParseVariableBool() as-is. I already
broke out argument reading to it's own function, knowing that it'd be the
stub for expressions. So I guess we start that now. What subset of true-ish
values do you think we should support? If we think that real expressions
are possible soon, we could only allow 'true' and 'false' for now, but if
we expect that expressions might not make it into v10, then perhaps we
should support the same text values that coerce to booleans on the server
side.

Hmmm. I would text value that coerce to true? I would also accept non-zero
integers (eg SELECT 1::BOOL; -- t).

The docs (doc/src/sgml/datatype.sgml) list TRUE 't' 'true' 'y' 'yes' 'on'
'1' vs FALSE 'f' 'false' 'n' 'no' 'off' '0'

However, src/test/regress/expected/boolean.out shows that there's some
flexiblity there with spaces, even before you inspect parse_bool_with_len()
in src/backend/utils/adt/bool.c.

If we could bring src/backend/utils/adt/bool.c across the server/client
wall, I would just use parse_bool_with_len as-is.

As it is, given that whatever I do is temporary until real expressions come
into place, that wouldn't be a terrible amount of code copying, and we'd
still have a proto-expression that probably isn't going to conflict with
whatever expression syntax we do chose. Having said that, if anyone can see
ANY reason that some subset of the existing bool-friendly strings would
cause a problem with the expression syntax we do hope to use, speak now and
we can restrict the accepted values.

I would suggest to assume false on everything else, and/or maybe to ignore
the whole if/endif section in such cases.

+1, it also halves the number of values we have to support later.

ISTM that with TAP test you can check for error returns, so maybe this can
be done.

I'll have to educate myself on TAP tests.

#10Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#9)
Re: \if, \elseif, \else, \endif (was Re: PSQL commands: \quit_if, \quit_unless)

I would suggest to assume false on everything else, and/or maybe to ignore
the whole if/endif section in such cases.

+1, it also halves the number of values we have to support later.

After giving it some thought, I revise a little bit my opinion:

I think that if the value is evaluated to TRUE or FALSE, then fine. If it
is anything else, then an error is raised (error message shown), which
should also stop the script on "ON_ERROR_STOP", and if not the script
continues with assuming the value was FALSE.

--
Fabien.

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#11Daniel Verite
daniel@manitou-mail.org
In reply to: Corey Huinker (#4)
Re: \if, \elseif, \else, \endif (was Re: PSQL commands: \quit_if, \quit_unless)

Corey Huinker wrote:

1: unrecognized value "whatever" for "\if"; assuming "on"

I do not think that the script should continue with such an assumption.

I agree, and this means we can't use ParseVariableBool() as-is

The patch at https://commitfest.postgresql.org/12/799/
in the ongoing CF already changes ParseVariableBool()
to not assume that unrecognizable values should be set to
"on".

There's also the fact that ParseVariableBool() in HEAD assumes
that an empty value is valid and true, which I think leads to this
inconsistency in the current patch:

\set empty
\if :empty
select 1 as result \gset
\else
select 2 as result \gset
\endif
\echo 'result is' :result

produces: result is 1 (so an empty string evaluates to true)

Yet this sequence:

\if
select 1 as result \gset
\else
select 2 as result \gset
\endif
\echo 'result is' :result

produces: result is 2 (so an empty \if evaluates to false)

The equivalence between empty value and true in
ParseVariableBool() is also suppressed in the above-mentioned
patch.

ISTM that it's important that eventually ParseVariableBool()
and \if agree on what evaluates to true and false (and the
more straightforward way to achieve that is by \if calling
directly ParseVariableBool), but that it's not productive that we
discuss /if issues relatively to the behavior of ParseVariableBool()
in HEAD at the moment, as it's likely to change.

Best regards,
--
Daniel Vérité
PostgreSQL-powered mailer: http://www.manitou-mail.org
Twitter: @DanielVerite

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#12Corey Huinker
corey.huinker@gmail.com
In reply to: Daniel Verite (#11)
Re: \if, \elseif, \else, \endif (was Re: PSQL commands: \quit_if, \quit_unless)

ISTM that it's important that eventually ParseVariableBool()
and \if agree on what evaluates to true and false (and the
more straightforward way to achieve that is by \if calling
directly ParseVariableBool), but that it's not productive that we
discuss /if issues relatively to the behavior of ParseVariableBool()
in HEAD at the moment, as it's likely to change.

I'd like to keep in sync with ParseVariableBoolean(), but

Also, Fabien has made a good case for invalid parsed values being an
ON_ERROR_STOP-able error, and not defaulted to either true or false.

This might be asking a lot, but could we make a "strict" mode for
ParseVariableBool() that returns a success boolean, and have the existing
ParseVariableBool() signature call that new function, and issue the
"assuming " warning if the strict function failed?

#13Corey Huinker
corey.huinker@gmail.com
In reply to: Corey Huinker (#12)
Re: \if, \elseif, \else, \endif (was Re: PSQL commands: \quit_if, \quit_unless)

On Tue, Jan 24, 2017 at 1:25 PM, Corey Huinker <corey.huinker@gmail.com>
wrote:

This might be asking a lot, but could we make a "strict" mode for
ParseVariableBool() that returns a success boolean, and have the existing
ParseVariableBool() signature call that new function, and issue the
"assuming " warning if the strict function failed?

Nevermind. Looking at the v7 patch I see that it does everything I need and
more. I should have looked first.

#14Tom Lane
tgl@sss.pgh.pa.us
In reply to: Daniel Verite (#11)
Re: \if, \elseif, \else, \endif (was Re: PSQL commands: \quit_if, \quit_unless)

"Daniel Verite" <daniel@manitou-mail.org> writes:

ISTM that it's important that eventually ParseVariableBool()
and \if agree on what evaluates to true and false (and the
more straightforward way to achieve that is by \if calling
directly ParseVariableBool), but that it's not productive that we
discuss /if issues relatively to the behavior of ParseVariableBool()
in HEAD at the moment, as it's likely to change.

AFAIK we do have consensus on changing its behavior to disallow
assignment of invalid values. It's just a matter of getting the
patch to be stylistically nice.

regards, tom lane

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#15Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#10)
Re: \if, \elseif, \else, \endif (was Re: PSQL commands: \quit_if, \quit_unless)

Revised patch, with one caveat: It contains copy/pasted code from
variable.c intended to bridge the gap until https://commitfest.postgresql.
org/12/799/ (changing ParseVariableBool to detect invalid boolean-ish
strings) is merged. We may want to pause full-review of this patch pending
resolution of that one. I'm happy to continue with the stop-gap in place.

Changes made:
- \elseif is now \elif
- Invalid boolean values now return an error
- ON_ERROR_STOP is respected in all errors raided by \if, \elsif, \else,
\endif commands.
- Documentation gives a more real-world example of usage.
- Documentation gives a more explicit list of valid boolean values
- Regression tests for out-of-place \endif, \else, and \endif
- Regression test for invalid boolean values
- Removal of debug detritus.

Changes not(yet) made:
- No TAP test for errors respecting ON_ERROR_STOP
- function comments in psqlscan.l follow the style found in other comments
there, which goes counter to global style.

On Tue, Jan 24, 2017 at 3:58 AM, Fabien COELHO <coelho@cri.ensmp.fr> wrote:

Show quoted text

I would suggest to assume false on everything else, and/or maybe to ignore

the whole if/endif section in such cases.

+1, it also halves the number of values we have to support later.

After giving it some thought, I revise a little bit my opinion:

I think that if the value is evaluated to TRUE or FALSE, then fine. If it
is anything else, then an error is raised (error message shown), which
should also stop the script on "ON_ERROR_STOP", and if not the script
continues with assuming the value was FALSE.

--
Fabien.

Attachments:

0001.if_endif.v2.difftext/plain; charset=US-ASCII; name=0001.if_endif.v2.diffDownload+579-24
#16Daniel Verite
daniel@manitou-mail.org
In reply to: Corey Huinker (#15)
Re: \if, \elseif, \else, \endif (was Re: PSQL commands: \quit_if, \quit_unless)

Corey Huinker wrote:

Revised patch

A comment about control flow and variables:
in branches that are not taken, variables are expanded
nonetheless, in a way that can be surprising.
Case in point:

\set var 'ab''cd'
-- select :var;
\if false
select :var ;
\else
select 1;
\endif

The 2nd reference to :var has a quoting hazard, but since it's within
an "\if false" branch, at a glance it seems like this script might work.
In fact it barfs with:
psql:script.sql:0: found EOF before closing \endif(s)

AFAICS what happens is that :var gets injected and starts a
runaway string, so that as far as the parser is concerned
the \else ..\endif block slips into the untaken branch, as a part of
that unfinished string.

This contrasts with line 2: -- select :var
where the reference to :var is inoffensive.

To avoid that kind of trouble, would it make sense not to expand
variables in untaken branches?

Best regards,
--
Daniel Vérité
PostgreSQL-powered mailer: http://www.manitou-mail.org
Twitter: @DanielVerite

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#17Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Daniel Verite (#16)
Re: \if, \elseif, \else, \endif (was Re: PSQL commands: \quit_if, \quit_unless)

Hello Daniel,

A comment about control flow and variables: in branches that are not
taken, variables are expanded nonetheless, in a way that can be
surprising. Case in point:

\set var 'ab''cd'
-- select :var;
\if false
select :var ;
\else
select 1;
\endif

To avoid that kind of trouble, would it make sense not to expand
variables in untaken branches?

Hmmm. This case is somehow contrived (for a string, :'var' could be used,
in which case escaping would avoid the hazard), but I think that what you
suggest is a better behavior, if easy to implement.

--
Fabien.

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#18Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#17)
Re: \if, \elseif, \else, \endif (was Re: PSQL commands: \quit_if, \quit_unless)

On Thu, Jan 26, 2017 at 3:55 PM, Fabien COELHO <coelho@cri.ensmp.fr> wrote:

Hello Daniel,

A comment about control flow and variables: in branches that are not

taken, variables are expanded nonetheless, in a way that can be surprising.
Case in point:

\set var 'ab''cd'
-- select :var;
\if false
select :var ;
\else
select 1;
\endif

To avoid that kind of trouble, would it make sense not to expand
variables in untaken branches?

Hmmm. This case is somehow contrived (for a string, :'var' could be used,
in which case escaping would avoid the hazard), but I think that what you
suggest is a better behavior, if easy to implement.

--
Fabien.

Good question, Daniel. Variable expansion seems to be done via
psql_get_variable which is invoked via callback, which means that I might
have to move branch_block_active into PsqlSettings. That's slightly
different because the existing boolean is scoped with MainLoop(), but
there's no way to get to a new MainLoop unless you're in an executing
branch, and no way to legally exit a MainLoop with an unbalanced if-endif
state. In short, I think it's better behavior. It does prevent someone from
setting a variable to '\endif' and expecting that to work, like this:

select case
when random() < 0.5 then '\endif'
else E'\else\n\echo fooled you\n\endif'
end as contrived_metaprogramming
\gset

\if false
:contrived_metaprogramming

I'm sure someone will argue that preventing that is a good thing. Unless
someone sees a good reason not to move that PsqlSettings, I'll make that
change.

#19Corey Huinker
corey.huinker@gmail.com
In reply to: Corey Huinker (#18)
Re: \if, \elseif, \else, \endif (was Re: PSQL commands: \quit_if, \quit_unless)

On Thu, Jan 26, 2017 at 4:06 PM, Corey Huinker <corey.huinker@gmail.com>
wrote:

On Thu, Jan 26, 2017 at 3:55 PM, Fabien COELHO <coelho@cri.ensmp.fr>
wrote:

Hello Daniel,

A comment about control flow and variables: in branches that are not

taken, variables are expanded nonetheless, in a way that can be surprising.
Case in point:

\set var 'ab''cd'
-- select :var;
\if false
select :var ;
\else
select 1;
\endif

To avoid that kind of trouble, would it make sense not to expand
variables in untaken branches?

Hmmm. This case is somehow contrived (for a string, :'var' could be used,
in which case escaping would avoid the hazard), but I think that what you
suggest is a better behavior, if easy to implement.

--
Fabien.

Good question, Daniel. Variable expansion seems to be done via
psql_get_variable which is invoked via callback, which means that I might
have to move branch_block_active into PsqlSettings. That's slightly
different because the existing boolean is scoped with MainLoop(), but
there's no way to get to a new MainLoop unless you're in an executing
branch, and no way to legally exit a MainLoop with an unbalanced if-endif
state. In short, I think it's better behavior. It does prevent someone from
setting a variable to '\endif' and expecting that to work, like this:

select case
when random() < 0.5 then '\endif'
else E'\else\n\echo fooled you\n\endif'
end as contrived_metaprogramming
\gset

\if false
:contrived_metaprogramming

I'm sure someone will argue that preventing that is a good thing. Unless
someone sees a good reason not to move that PsqlSettings, I'll make that
change.

And here it is

Attachments:

0001.if_endif.v3.difftext/plain; charset=US-ASCII; name=0001.if_endif.v3.diffDownload+618-24
#20Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#19)
Re: \if, \elseif, \else, \endif (was Re: PSQL commands: \quit_if, \quit_unless)

Hello Corey,

And here it is

About the patch v3:

## DOCUMENTATION

I'm wondering what pg would do on "EXISTS(SELECT 1 FROM customer)" if
there are many employees. EXPLAIN suggests a seq_scan, which seems bad.
With "(SELECT COUNT(*) FROM pgbench_accounts) <> 0" pg seems to generate
an index only scan on a large table, so maybe it is a better way to do it.
It seems strange that there is no better way to do that in a relational
tool, the relational model being an extension of set theory... and there
is no easy way (?) to check whether a set is empty.

"""If an EOF is reached on the main file or an
<command>\include</command>-ed file before all
<command>\if</command>-<command>\endif</command> are matched, then psql
will raise an error."""

In sentence above: "before all" -> "before all local"? "then" -> ""?

"other options booleans" -> "other booleans of options"? or "options'
booleans" maybe, but that is for people?

"unabigous" -> "unambiguous"

I think that the three paragraph explanation about non evaluation could be
factor into one, maybe something like: """Lines within false branches are
not evaluated in any way: queries are not sent to the server, non
conditional commands are not evaluated but bluntly ignored, nested if
expressions in such branches are also not evaluated but are tallied to
check for nesting."""

I would suggest to merge elif/else constraints by describing what is
expected rather than what is not expected. """An \if command may contain
any number of \elif clauses and may end with one \else clause""".

## CODE

In "read_boolean_expression":

+ if (value)

"if (value != NULL)" is usually used, I think.

  + if (value == NULL)
  +   return false; /* not set -> assume "off" */

This is dead code, because value has been checked to be non NULL a few
lines above.

  + (pg_strncasecmp(value, "on", (len > 2 ? len : 2)) == 0)
  + (pg_strncasecmp(value, "off", (len > 2 ? len : 2)) == 0)

Hmmm, not easy to parse. Maybe it deserves a comment?
"check at least two chars to distinguish on & off"

",action" -> ", action" (space after commas).

The "result" is not set on errors, but maybe it should be set to false
anyway and explicitely, instead of relying on some prior initialization?
Or document that the result is not set on errors.

if command:

if (is active) {
success = ...
if (success) {
...
}
}
if (success) {
...
}

The second test on success may not rely on the value set above. That looks
very strange. ISTM that the state should be pushed whether parsing
succeeded or not. Moreover, it results in:

\if ERROR
\echo X
\else
\echo Y
\endif

having both X & Y printed and error reported on else and endif. I think
that an expression error should just put the stuff in ignore state.

On "else" when in state ignored, ISTM that it should remain in state
ignore, not switch to else-false.

Comment about "IFSTATE_FALSE" talks about the state being true, maybe a
copy-paste error?

In comments: "... variables the branch" -> "variables if the branch"

The "if_endifs_balanced" variable is not very useful. Maybe just the test
and error reporting in the right place:

if (... && !psqlscan_branch_empty(scan_state))
psql_error("found EOF before closing \\endif(s)\n");

+
#endif /* MAINLOOP_H */

-
/*
* Main processing loop for reading lines of input
* and sending them to the backend.

Do not add/remove empty lines in places unrelated to the patch?

History saving: I'm wondering whether all read line should be put into
history, whether executed or not.

Is it possible to make some of the added functions static? If so, do it.

I checked that it does stop on errors with -v ON_ERROR_STOP=1. However I
would be more at ease if this was tested somewhere.

--
Fabien.

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#21Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#20)
#22Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#21)
#23Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#22)
#24Jim Nasby
Jim.Nasby@BlueTreble.com
In reply to: Fabien COELHO (#22)
#25Daniel Verite
daniel@manitou-mail.org
In reply to: Corey Huinker (#21)
#26Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Daniel Verite (#25)
#27Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Fabien COELHO (#22)
#28Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#27)
#29Tom Lane
tgl@sss.pgh.pa.us
In reply to: Corey Huinker (#28)
#30Corey Huinker
corey.huinker@gmail.com
In reply to: Tom Lane (#29)
#31Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#30)
#32Erik Rijkers
er@xs4all.nl
In reply to: Corey Huinker (#30)
#33Corey Huinker
corey.huinker@gmail.com
In reply to: Erik Rijkers (#32)
#34Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#31)
#35Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#33)
#36Fabien COELHO
fabien.coelho@mines-paristech.fr
In reply to: Corey Huinker (#34)
#37Erik Rijkers
er@xs4all.nl
In reply to: Corey Huinker (#34)
#38Corey Huinker
corey.huinker@gmail.com
In reply to: Erik Rijkers (#37)
#39Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#38)
#40Tom Lane
tgl@sss.pgh.pa.us
In reply to: Corey Huinker (#34)
#41Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Fabien COELHO (#36)
#42Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#35)
#43Corey Huinker
corey.huinker@gmail.com
In reply to: Corey Huinker (#38)
#44Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#39)
#45Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#42)
#46Jim Nasby
Jim.Nasby@BlueTreble.com
In reply to: Fabien COELHO (#45)
#47Corey Huinker
corey.huinker@gmail.com
In reply to: Jim Nasby (#46)
#48Corey Huinker
corey.huinker@gmail.com
In reply to: Corey Huinker (#47)
#49Tom Lane
tgl@sss.pgh.pa.us
In reply to: Corey Huinker (#48)
#50Corey Huinker
corey.huinker@gmail.com
In reply to: Tom Lane (#49)
#51Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#50)
#52Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#51)
#53Erik Rijkers
er@xs4all.nl
In reply to: Corey Huinker (#52)
#54Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Erik Rijkers (#53)
#55Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Fabien COELHO (#54)
#56Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#54)
#57Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#56)
#58Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#57)
#59Tom Lane
tgl@sss.pgh.pa.us
In reply to: Corey Huinker (#58)
#60Daniel Verite
daniel@manitou-mail.org
In reply to: Corey Huinker (#58)
#61Corey Huinker
corey.huinker@gmail.com
In reply to: Daniel Verite (#60)
#62Robert Haas
robertmhaas@gmail.com
In reply to: Corey Huinker (#56)
#63Corey Huinker
corey.huinker@gmail.com
In reply to: Robert Haas (#62)
#64Robert Haas
robertmhaas@gmail.com
In reply to: Corey Huinker (#63)
#65Jim Nasby
Jim.Nasby@BlueTreble.com
In reply to: Corey Huinker (#47)
#66Corey Huinker
corey.huinker@gmail.com
In reply to: Jim Nasby (#65)
#67Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#52)
#68Daniel Verite
daniel@manitou-mail.org
In reply to: Corey Huinker (#61)
#69Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#67)
#70Corey Huinker
corey.huinker@gmail.com
In reply to: Daniel Verite (#68)
#71Corey Huinker
corey.huinker@gmail.com
In reply to: Corey Huinker (#70)
#72Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#71)
#73Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#72)
#74Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#73)
#75Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Fabien COELHO (#74)
#76Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#75)
#77Corey Huinker
corey.huinker@gmail.com
In reply to: Corey Huinker (#76)
#78Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#76)
#79Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#78)
#80Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#79)
#81Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#80)
#82Corey Huinker
corey.huinker@gmail.com
In reply to: Corey Huinker (#81)
#83Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#82)
#84Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#83)
#85Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#84)
#86Robert Haas
robertmhaas@gmail.com
In reply to: Corey Huinker (#82)
#87Tom Lane
tgl@sss.pgh.pa.us
In reply to: Robert Haas (#86)
#88Corey Huinker
corey.huinker@gmail.com
In reply to: Tom Lane (#87)
#89Tom Lane
tgl@sss.pgh.pa.us
In reply to: Corey Huinker (#88)
#90Robert Haas
robertmhaas@gmail.com
In reply to: Tom Lane (#89)
#91Erik Rijkers
er@xs4all.nl
In reply to: Tom Lane (#89)
#92Corey Huinker
corey.huinker@gmail.com
In reply to: Erik Rijkers (#91)
#93Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#92)
#94Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#93)
#95Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#94)
#96Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#95)
#97Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#96)
#98Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#97)
#99Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#98)
#100Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#99)
#101Bruce Momjian
bruce@momjian.us
In reply to: Fabien COELHO (#95)
#102Corey Huinker
corey.huinker@gmail.com
In reply to: Bruce Momjian (#101)
#103Bruce Momjian
bruce@momjian.us
In reply to: Corey Huinker (#102)
#104Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Bruce Momjian (#103)
#105Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#104)
#106Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#105)
#107Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#106)
#108Robert Haas
robertmhaas@gmail.com
In reply to: Fabien COELHO (#97)
#109Corey Huinker
corey.huinker@gmail.com
In reply to: Corey Huinker (#107)
#110Corey Huinker
corey.huinker@gmail.com
In reply to: Corey Huinker (#109)
#111Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#110)
#112Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#111)
#113Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Robert Haas (#108)
#114Corey Huinker
corey.huinker@gmail.com
In reply to: Robert Haas (#108)
#115Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#112)
#116Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#113)
#117Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#116)
#118Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#117)
#119Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#118)
#120Robert Haas
robertmhaas@gmail.com
In reply to: Fabien COELHO (#113)
#121Tom Lane
tgl@sss.pgh.pa.us
In reply to: Corey Huinker (#109)
#122Corey Huinker
corey.huinker@gmail.com
In reply to: Tom Lane (#121)
#123Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Tom Lane (#121)
#124Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#123)
#125Tom Lane
tgl@sss.pgh.pa.us
In reply to: Corey Huinker (#124)
#126Corey Huinker
corey.huinker@gmail.com
In reply to: Tom Lane (#125)
#127Tom Lane
tgl@sss.pgh.pa.us
In reply to: Corey Huinker (#126)
#128Corey Huinker
corey.huinker@gmail.com
In reply to: Tom Lane (#127)
#129Corey Huinker
corey.huinker@gmail.com
In reply to: Corey Huinker (#128)
#130Tom Lane
tgl@sss.pgh.pa.us
In reply to: Corey Huinker (#129)
#131Corey Huinker
corey.huinker@gmail.com
In reply to: Tom Lane (#130)
#132Corey Huinker
corey.huinker@gmail.com
In reply to: Corey Huinker (#131)
#133Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#132)
#134Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#133)
#135Daniel Verite
daniel@manitou-mail.org
In reply to: Tom Lane (#130)
#136Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Daniel Verite (#135)
#137Pavel Stehule
pavel.stehule@gmail.com
In reply to: Fabien COELHO (#136)
#138Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#134)
#139Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#138)
#140Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#139)
#141Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#140)
#142Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#141)
#143Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#142)
#144Corey Huinker
corey.huinker@gmail.com
In reply to: Corey Huinker (#143)
#145Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#144)
#146Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#145)
#147Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#146)
#148Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#147)
#149Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#148)
#150Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#149)
#151Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#150)
#152Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#151)
#153Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#152)
#154Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Fabien COELHO (#153)
#155Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#154)
#156Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#155)
#157Tom Lane
tgl@sss.pgh.pa.us
In reply to: Corey Huinker (#155)
#158Corey Huinker
corey.huinker@gmail.com
In reply to: Tom Lane (#157)
#159Tom Lane
tgl@sss.pgh.pa.us
In reply to: Corey Huinker (#155)
#160Robert Haas
robertmhaas@gmail.com
In reply to: Fabien COELHO (#156)
#161Tom Lane
tgl@sss.pgh.pa.us
In reply to: Robert Haas (#160)
#162Robert Haas
robertmhaas@gmail.com
In reply to: Tom Lane (#161)
#163David G. Johnston
david.g.johnston@gmail.com
In reply to: Tom Lane (#159)
#164Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Tom Lane (#157)
#165Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Tom Lane (#159)
#166Corey Huinker
corey.huinker@gmail.com
In reply to: David G. Johnston (#163)
#167Tom Lane
tgl@sss.pgh.pa.us
In reply to: Corey Huinker (#166)
#168Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#165)
#169David G. Johnston
david.g.johnston@gmail.com
In reply to: Tom Lane (#167)
#170Tom Lane
tgl@sss.pgh.pa.us
In reply to: David G. Johnston (#169)
#171Tom Lane
tgl@sss.pgh.pa.us
In reply to: Tom Lane (#159)
#172Corey Huinker
corey.huinker@gmail.com
In reply to: Tom Lane (#171)
#173Daniel Verite
daniel@manitou-mail.org
In reply to: Tom Lane (#170)
#174Tom Lane
tgl@sss.pgh.pa.us
In reply to: Corey Huinker (#172)
#175Tom Lane
tgl@sss.pgh.pa.us
In reply to: Daniel Verite (#173)
#176Corey Huinker
corey.huinker@gmail.com
In reply to: Tom Lane (#175)
#177Tom Lane
tgl@sss.pgh.pa.us
In reply to: Corey Huinker (#176)
#178Corey Huinker
corey.huinker@gmail.com
In reply to: Tom Lane (#177)
#179Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#178)
#180Erik Rijkers
er@xs4all.nl
In reply to: Corey Huinker (#178)
#181Daniel Verite
daniel@manitou-mail.org
In reply to: Tom Lane (#177)
#182Tom Lane
tgl@sss.pgh.pa.us
In reply to: Daniel Verite (#181)
#183Tom Lane
tgl@sss.pgh.pa.us
In reply to: Fabien COELHO (#179)
#184Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Tom Lane (#183)
#185Corey Huinker
corey.huinker@gmail.com
In reply to: Erik Rijkers (#180)
#186Tom Lane
tgl@sss.pgh.pa.us
In reply to: Fabien COELHO (#184)
#187Corey Huinker
corey.huinker@gmail.com
In reply to: Tom Lane (#186)
#188Tom Lane
tgl@sss.pgh.pa.us
In reply to: Corey Huinker (#187)
#189Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Tom Lane (#186)
#190Corey Huinker
corey.huinker@gmail.com
In reply to: Tom Lane (#188)
#191Tom Lane
tgl@sss.pgh.pa.us
In reply to: Corey Huinker (#190)
#192Corey Huinker
corey.huinker@gmail.com
In reply to: Tom Lane (#191)
#193Corey Huinker
corey.huinker@gmail.com
In reply to: Corey Huinker (#192)
#194Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#193)
#195Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Fabien COELHO (#194)
#196Tom Lane
tgl@sss.pgh.pa.us
In reply to: Alvaro Herrera (#195)
#197Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Tom Lane (#196)
#198Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Tom Lane (#196)
#199Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#198)
#200Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#194)
#201Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#193)
#202Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#201)
#203Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#202)
#204Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#203)
#205Corey Huinker
corey.huinker@gmail.com
In reply to: Corey Huinker (#204)
#206Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#205)
#207Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#204)
#208Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#207)
#209Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#208)
#210Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#209)
#211Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#210)
#212Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#211)
#213Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#212)
#214Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#213)
#215Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#214)
#216Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#215)
#217Corey Huinker
corey.huinker@gmail.com
In reply to: Corey Huinker (#216)
#218Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#217)
#219Tom Lane
tgl@sss.pgh.pa.us
In reply to: Corey Huinker (#217)
#220Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Tom Lane (#219)
#221Tom Lane
tgl@sss.pgh.pa.us
In reply to: Fabien COELHO (#220)
#222Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Tom Lane (#221)
#223Corey Huinker
corey.huinker@gmail.com
In reply to: Fabien COELHO (#222)
#224Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Corey Huinker (#223)
#225Tom Lane
tgl@sss.pgh.pa.us
In reply to: Fabien COELHO (#224)
#226Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Tom Lane (#225)
#227Tom Lane
tgl@sss.pgh.pa.us
In reply to: Fabien COELHO (#226)
#228Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Tom Lane (#227)
#229Tom Lane
tgl@sss.pgh.pa.us
In reply to: Fabien COELHO (#228)
#230Daniel Verite
daniel@manitou-mail.org
In reply to: Tom Lane (#225)
#231Robert Haas
robertmhaas@gmail.com
In reply to: Daniel Verite (#230)
#232Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Robert Haas (#231)