Thread: Doc patch--clarifying $1 in PL/PgSQL

Doc patch--clarifying $1 in PL/PgSQL

From
David Fetter
Date:
Kind people,

Please find enclosed this patch from Alex J. Avriette :)

Cheers,
D
--
David Fetter david@fetter.org http://fetter.org/
phone: +1 510 893 6100    cell: +1 415 235 3778

Attachment

Re: Doc patch--clarifying $1 in PL/PgSQL

From
Tom Lane
Date:
David Fetter <david@fetter.org> writes:
> +      Note that it is not possible to assign function arguments during
> +      a <literal>DECLARE</> block.

Seems to me this is a bug that should be fixed, not documented.

            regards, tom lane

Re: Doc patch--clarifying $1 in PL/PgSQL

From
David Fetter
Date:
On Mon, Dec 22, 2003 at 05:50:12PM -0500, Tom Lane wrote:
> David Fetter <david@fetter.org> writes:
> > +      Note that it is not possible to assign function arguments during
> > +      a <literal>DECLARE</> block.
>
> Seems to me this is a bug that should be fixed, not documented.

I got the impression from Jan Wieck that it wasn't fixable, or at
least not without a major rewrite of the plpgsql engine.  I'm sure
somebody will correct me if I got a mistaken impression, though :)

Cheers,
D
--
David Fetter david@fetter.org http://fetter.org/
phone: +1 510 893 6100    cell: +1 415 235 3778

Re: Doc patch--clarifying $1 in PL/PgSQL

From
Tom Lane
Date:
David Fetter <david@fetter.org> writes:
> On Mon, Dec 22, 2003 at 05:50:12PM -0500, Tom Lane wrote:
>> David Fetter <david@fetter.org> writes:
> +      Note that it is not possible to assign function arguments during
> +      a <literal>DECLARE</> block.
>>
>> Seems to me this is a bug that should be fixed, not documented.

> I got the impression from Jan Wieck that it wasn't fixable, or at
> least not without a major rewrite of the plpgsql engine.  I'm sure
> somebody will correct me if I got a mistaken impression, though :)

Not that hard ... just requires replacing some special-purpose code with
general-purpose code ...

            regards, tom lane


*** src/pl/plpgsql/src/gram.y.orig    Sat Nov 29 14:52:12 2003
--- src/pl/plpgsql/src/gram.y    Mon Dec 22 18:50:35 2003
***************
*** 628,679 ****
                      { $$ = NULL; }
                  | decl_defkey
                      {
!                         int                tok;
!                         int                lno;
!                         PLpgSQL_dstring ds;
!                         PLpgSQL_expr    *expr;
!
!                         lno = plpgsql_scanner_lineno();
!                         expr = malloc(sizeof(PLpgSQL_expr));
!                         plpgsql_dstring_init(&ds);
!                         plpgsql_dstring_append(&ds, "SELECT ");
!
!                         expr->dtype   = PLPGSQL_DTYPE_EXPR;
!                         expr->plan      = NULL;
!                         expr->nparams = 0;
!
!                         tok = yylex();
!                         switch (tok)
!                         {
!                             case 0:
!                                 yyerror("unexpected end of function");
!                             case K_NULL:
!                                 if (yylex() != ';')
!                                     yyerror("expected \";\" after \"NULL\"");
!
!                                 free(expr);
!                                 plpgsql_dstring_free(&ds);
!
!                                 $$ = NULL;
!                                 break;
!
!                             default:
!                                 plpgsql_dstring_append(&ds, yytext);
!                                 while ((tok = yylex()) != ';')
!                                 {
!                                     if (tok == 0)
!                                         yyerror("unterminated default value");
!
!                                     if (plpgsql_SpaceScanned)
!                                         plpgsql_dstring_append(&ds, " ");
!                                     plpgsql_dstring_append(&ds, yytext);
!                                 }
!                                 expr->query = strdup(plpgsql_dstring_get(&ds));
!                                 plpgsql_dstring_free(&ds);
!
!                                 $$ = expr;
!                                 break;
!                         }
                      }
                  ;

--- 628,636 ----
                      { $$ = NULL; }
                  | decl_defkey
                      {
!                         plpgsql_ns_setlocal(false);
!                         $$ = plpgsql_read_expression(';', ";");
!                         plpgsql_ns_setlocal(true);
                      }
                  ;


Re: Doc patch--clarifying $1 in PL/PgSQL

From
Jan Wieck
Date:
Tom Lane wrote:

> David Fetter <david@fetter.org> writes:
>> On Mon, Dec 22, 2003 at 05:50:12PM -0500, Tom Lane wrote:
>>> David Fetter <david@fetter.org> writes:
>> +      Note that it is not possible to assign function arguments during
>> +      a <literal>DECLARE</> block.
>>>
>>> Seems to me this is a bug that should be fixed, not documented.
>
>> I got the impression from Jan Wieck that it wasn't fixable, or at
>> least not without a major rewrite of the plpgsql engine.  I'm sure
>> somebody will correct me if I got a mistaken impression, though :)
>
> Not that hard ... just requires replacing some special-purpose code with
> general-purpose code ...

Does that code cause the variables value to change from function call to
function call (what most users would expect if they give it a default
value based on a call argument), or will remember the value from the
first function call for the lifetime of the backend?


Jan

>
>             regards, tom lane
>
>
> *** src/pl/plpgsql/src/gram.y.orig    Sat Nov 29 14:52:12 2003
> --- src/pl/plpgsql/src/gram.y    Mon Dec 22 18:50:35 2003
> ***************
> *** 628,679 ****
>                       { $$ = NULL; }
>                   | decl_defkey
>                       {
> !                         int                tok;
> !                         int                lno;
> !                         PLpgSQL_dstring ds;
> !                         PLpgSQL_expr    *expr;
> !
> !                         lno = plpgsql_scanner_lineno();
> !                         expr = malloc(sizeof(PLpgSQL_expr));
> !                         plpgsql_dstring_init(&ds);
> !                         plpgsql_dstring_append(&ds, "SELECT ");
> !
> !                         expr->dtype   = PLPGSQL_DTYPE_EXPR;
> !                         expr->plan      = NULL;
> !                         expr->nparams = 0;
> !
> !                         tok = yylex();
> !                         switch (tok)
> !                         {
> !                             case 0:
> !                                 yyerror("unexpected end of function");
> !                             case K_NULL:
> !                                 if (yylex() != ';')
> !                                     yyerror("expected \";\" after \"NULL\"");
> !
> !                                 free(expr);
> !                                 plpgsql_dstring_free(&ds);
> !
> !                                 $$ = NULL;
> !                                 break;
> !
> !                             default:
> !                                 plpgsql_dstring_append(&ds, yytext);
> !                                 while ((tok = yylex()) != ';')
> !                                 {
> !                                     if (tok == 0)
> !                                         yyerror("unterminated default value");
> !
> !                                     if (plpgsql_SpaceScanned)
> !                                         plpgsql_dstring_append(&ds, " ");
> !                                     plpgsql_dstring_append(&ds, yytext);
> !                                 }
> !                                 expr->query = strdup(plpgsql_dstring_get(&ds));
> !                                 plpgsql_dstring_free(&ds);
> !
> !                                 $$ = expr;
> !                                 break;
> !                         }
>                       }
>                   ;
>
> --- 628,636 ----
>                       { $$ = NULL; }
>                   | decl_defkey
>                       {
> !                         plpgsql_ns_setlocal(false);
> !                         $$ = plpgsql_read_expression(';', ";");
> !                         plpgsql_ns_setlocal(true);
>                       }
>                   ;
>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 3: if posting/reading through Usenet, please send an appropriate
>       subscribe-nomail command to majordomo@postgresql.org so that your
>       message can get through to the mailing list cleanly


--
#======================================================================#
# It's easier to get forgiveness for being wrong than for being right. #
# Let's break this rule - forgive me.                                  #
#================================================== JanWieck@Yahoo.com #


Re: Doc patch--clarifying $1 in PL/PgSQL

From
Tom Lane
Date:
Jan Wieck <JanWieck@Yahoo.com> writes:
> Tom Lane wrote:
>> Not that hard ... just requires replacing some special-purpose code with
>> general-purpose code ...

> Does that code cause the variables value to change from function call to
> function call (what most users would expect if they give it a default
> value based on a call argument), or will remember the value from the
> first function call for the lifetime of the backend?

I believe it will evaluate the DEFAULT expression on each entry to the
block, using the current values of outer-block variables (and also
variables declared earlier in the same block, if anyone cared to use
that behavior).  The code was already designed and documented to
evaluate DEFAULT expressions on each block entry --- what it was missing
was the ability to reference variables in these expressions.

Do you see something wrong with it?

            regards, tom lane

Re: Doc patch--clarifying $1 in PL/PgSQL

From
Jan Wieck
Date:
Tom Lane wrote:
> Jan Wieck <JanWieck@Yahoo.com> writes:
>> Tom Lane wrote:
>>> Not that hard ... just requires replacing some special-purpose code with
>>> general-purpose code ...
>
>> Does that code cause the variables value to change from function call to
>> function call (what most users would expect if they give it a default
>> value based on a call argument), or will remember the value from the
>> first function call for the lifetime of the backend?
>
> I believe it will evaluate the DEFAULT expression on each entry to the
> block, using the current values of outer-block variables (and also
> variables declared earlier in the same block, if anyone cared to use
> that behavior).  The code was already designed and documented to
> evaluate DEFAULT expressions on each block entry --- what it was missing
> was the ability to reference variables in these expressions.
>
> Do you see something wrong with it?

No, I just didn't test it yet. My only concern was that it could be
another unexpected behaviour related to caching values/plans. Unexpected
caching is what most likely becomes FAQ's and I think we have enough of
those.


Jan

--
#======================================================================#
# It's easier to get forgiveness for being wrong than for being right. #
# Let's break this rule - forgive me.                                  #
#================================================== JanWieck@Yahoo.com #