Thread: function attributes

function attributes

From
Andrew Dunstan
Date:
Yesterday I did a bit of work on allowing bytea values to be passed into 
and out of plperl in binary format, effectively removing the need to 
escape and de-escape them. (The work can be seen on he plperlargs branch 
of my development repo at 
<https://github.com/adunstan/postgresql-dev/commits/plperlargs/>).

At the moment the behaviour is triggered by a custom setting 
(plperl.pass_binary_bytea), but this isn't really satisfactory. We could 
turn it on  permanently, but that would break a lot of legacy code. What 
we really need is a way of marking a function with some attributes. Of 
course, we could put it in the program text like plpgsql's 
#variable_conflict, but that's really rather ugly. The grammar already 
has an attribute mechanism for functions, and ISTM we just need to 
extend that a bit to allow setting of function attributes reasonably 
flexibly, much as we can now specify format options on EXPLAIN or we'll 
soon be able to specify options for foreign tables.

Thoughts?

cheers

andrew


Re: function attributes

From
"David E. Wheeler"
Date:
On Dec 11, 2010, at 2:27 PM, Andrew Dunstan wrote:

> Yesterday I did a bit of work on allowing bytea values to be passed into and out of plperl in binary format,
effectivelyremoving the need to escape and de-escape them. (The work can be seen on he plperlargs branch of my
developmentrepo at <https://github.com/adunstan/postgresql-dev/commits/plperlargs/>). 

andrew++ # Woo!

> At the moment the behaviour is triggered by a custom setting (plperl.pass_binary_bytea), but this isn't really
satisfactory.We could turn it on  permanently, but that would break a lot of legacy code. What we really need is a way
ofmarking a function with some attributes. Of course, we could put it in the program text like plpgsql's
#variable_conflict,but that's really rather ugly. The grammar already has an attribute mechanism for functions, and
ISTMwe just need to extend that a bit to allow setting of function attributes reasonably flexibly, much as we can now
specifyformat options on EXPLAIN or we'll soon be able to specify options for foreign table 

What does the existing attribute grammar for functions look like? An example perhaps?

Best,

David



Re: function attributes

From
Andrew Dunstan
Date:

On 12/11/2010 08:01 PM, David E. Wheeler wrote:
>
>> At the moment the behaviour is triggered by a custom setting (plperl.pass_binary_bytea), but this isn't really
satisfactory.We could turn it on  permanently, but that would break a lot of legacy code. What we really need is a way
ofmarking a function with some attributes. Of course, we could put it in the program text like plpgsql's
#variable_conflict,but that's really rather ugly. The grammar already has an attribute mechanism for functions, and
ISTMwe just need to extend that a bit to allow setting of function attributes reasonably flexibly, much as we can now
specifyformat options on EXPLAIN or we'll soon be able to specify options for foreign table
 
> What does the existing attribute grammar for functions look like? An example perhaps?
>
>

create function foo(....) ..... with ( /attribute/ [, ...] )

Currently allowed attributes are isStrict and isCachable. The mechanism 
is effectively obsolete right now, but we could use it for what I have 
in mind quite nicely.

cheers

andrew


Re: function attributes

From
Robert Haas
Date:
On Sat, Dec 11, 2010 at 5:27 PM, Andrew Dunstan
<andrew.dunstan@pgexperts.com> wrote:
> Yesterday I did a bit of work on allowing bytea values to be passed into and
> out of plperl in binary format, effectively removing the need to escape and
> de-escape them. (The work can be seen on he plperlargs branch of my
> development repo at
> <https://github.com/adunstan/postgresql-dev/commits/plperlargs/>).
>
> At the moment the behaviour is triggered by a custom setting
> (plperl.pass_binary_bytea), but this isn't really satisfactory. We could
> turn it on  permanently, but that would break a lot of legacy code. What we
> really need is a way of marking a function with some attributes. Of course,
> we could put it in the program text like plpgsql's #variable_conflict, but
> that's really rather ugly. The grammar already has an attribute mechanism
> for functions, and ISTM we just need to extend that a bit to allow setting
> of function attributes reasonably flexibly, much as we can now specify
> format options on EXPLAIN or we'll soon be able to specify options for
> foreign tables.
>
> Thoughts?

Well, you could set that GUC (plperl.pass_binary_bytea) on a function
without changing any syntax on at all.

CREATE FUNCTION name (args) ... SET plperl.pass_binary_bytea = true;

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company


Re: function attributes

From
Andrew Dunstan
Date:

On 12/11/2010 09:16 PM, Robert Haas wrote:
>
> Well, you could set that GUC (plperl.pass_binary_bytea) on a function
> without changing any syntax on at all.
>
> CREATE FUNCTION name (args) ... SET plperl.pass_binary_bytea = true;

Oh, good point. I'd forgotten about that. I'll experiment and see if I 
can break it :-)

cheers

andrew


Re: function attributes

From
Robert Haas
Date:
On Sat, Dec 11, 2010 at 9:28 PM, Andrew Dunstan <andrew@dunslane.net> wrote:
> On 12/11/2010 09:16 PM, Robert Haas wrote:
>>
>> Well, you could set that GUC (plperl.pass_binary_bytea) on a function
>> without changing any syntax on at all.
>>
>> CREATE FUNCTION name (args) ... SET plperl.pass_binary_bytea = true;
>
> Oh, good point. I'd forgotten about that. I'll experiment and see if I can
> break it :-)

I guess one problem with that approach is that the scoping of the
parameter change will be dynamic rather than lexical.

-- 
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company


Re: function attributes

From
"David E. Wheeler"
Date:
On Dec 11, 2010, at 5:58 PM, Andrew Dunstan wrote:

> create function foo(....) ..... with ( /attribute/ [, ...] )
>
> Currently allowed attributes are isStrict and isCachable. The mechanism is effectively obsolete right now, but we
coulduse it for what I have in mind quite nicely. 

Makes sense, though I think I might also like some sort of global default to toggle.

David

Re: function attributes

From
Tom Lane
Date:
Andrew Dunstan <andrew.dunstan@pgexperts.com> writes:
> Yesterday I did a bit of work on allowing bytea values to be passed into 
> and out of plperl in binary format, effectively removing the need to 
> escape and de-escape them. (The work can be seen on he plperlargs branch 
> of my development repo at 
> <https://github.com/adunstan/postgresql-dev/commits/plperlargs/>).

> At the moment the behaviour is triggered by a custom setting 
> (plperl.pass_binary_bytea), but this isn't really satisfactory. We could 
> turn it on  permanently, but that would break a lot of legacy code. What 
> we really need is a way of marking a function with some attributes. Of 
> course, we could put it in the program text like plpgsql's 
> #variable_conflict, but that's really rather ugly. The grammar already 
> has an attribute mechanism for functions, and ISTM we just need to 
> extend that a bit to allow setting of function attributes reasonably 
> flexibly, much as we can now specify format options on EXPLAIN or we'll 
> soon be able to specify options for foreign tables.

I do not want to go there.  What you're proposing will soon turn into a
real mess, with arbitrary language-specific junk tagged onto pg_proc
entries.  And what's worse, it'll be mixed with non-language-specific
junk, because of the existing legacy WITH entries.

Tim Bunce seemed to think that this particular problem might be solvable
in a completely transparent way, by having byteas convert into Perl
objects that have a hook for producing a backwards-compatible text
translation.  Have you looked into that idea?
        regards, tom lane


Re: function attributes

From
Andrew Dunstan
Date:

On 12/12/2010 10:43 AM, Tom Lane wrote:
>
> Tim Bunce seemed to think that this particular problem might be solvable
> in a completely transparent way, by having byteas convert into Perl
> objects that have a hook for producing a backwards-compatible text
> translation.  Have you looked into that idea?

No. If you're referring to this sentence, which was referring to arrays, 
not to byteas:

> It's possible a blessed ref with string overloading would avoid
> backwards compatibility issues.
>

then it won't work (or at least it would be far more complex than what 
I've done, and I can't see how it would work) in the case of a bytea, 
since a bytea becomes a scalar, not a ref, and you can only bless refs.


cheers

andrew


Re: function attributes

From
Andrew Dunstan
Date:

On 12/12/2010 10:43 AM, Tom Lane wrote:
>
>> At the moment the behaviour is triggered by a custom setting
>> (plperl.pass_binary_bytea), but this isn't really satisfactory. We could
>> turn it on  permanently, but that would break a lot of legacy code. What
>> we really need is a way of marking a function with some attributes. Of
>> course, we could put it in the program text like plpgsql's
>> #variable_conflict, but that's really rather ugly. The grammar already
>> has an attribute mechanism for functions, and ISTM we just need to
>> extend that a bit to allow setting of function attributes reasonably
>> flexibly, much as we can now specify format options on EXPLAIN or we'll
>> soon be able to specify options for foreign tables.
> I do not want to go there.  What you're proposing will soon turn into a
> real mess, with arbitrary language-specific junk tagged onto pg_proc
> entries.  And what's worse, it'll be mixed with non-language-specific
> junk, because of the existing legacy WITH entries.
>

Arguably we should deprecate those legacy entries. One, isCachable,  is 
stated in the docs to be be obsolete, and has been for many releases 
now. The other, isStrict, is a non-preferred way of specifying that the 
function is strict.

But the real issue is that we have no way of specifying properties for a 
function at creation time other than those provided for in the grammar. 
We've already made a couple of fairly ugly hacks to do stuff like this 
in plpgsql. Is that really the road we want to go down? Is it less messy 
than providing some catalog support for language specific function 
properties, where they might be visible outside the function source?

In the present case, Robert's suggestion of using "create function ... 
set plperl.pass_binary_bytea = true" seems to work well enough, although 
I haven't tried very hard yet to break it.

cheers

andrew


Re: function attributes

From
Tom Lane
Date:
Andrew Dunstan <andrew@dunslane.net> writes:
> On 12/12/2010 10:43 AM, Tom Lane wrote:
>>> At the moment the behaviour is triggered by a custom setting
>>> (plperl.pass_binary_bytea), but this isn't really satisfactory.

>> I do not want to go there.

> But the real issue is that we have no way of specifying properties for a 
> function at creation time other than those provided for in the grammar. 
> We've already made a couple of fairly ugly hacks to do stuff like this 
> in plpgsql. Is that really the road we want to go down? Is it less messy 
> than providing some catalog support for language specific function 
> properties, where they might be visible outside the function source?

There might be an argument in the abstract for that, but I can't see
expending the work until we have a more pressing concrete requirement
than this one.  I don't believe that defining this particular behavior
as a function property is a good long-term solution, because it seems
practically certain that everybody will want to migrate to the new
behavior.  A GUC works well for that, because you can flip over the
default once you reach the point of having converted or marked all your
functions.  A function property doesn't work at all, unless it's just a
means of locally overriding the GUC ... and the SET clause exists for
that already.

I could be talked into function properties given a few examples of
properties that could be expected to remain in use for a long time
(like volatile/immutable for instance).  But this example is no sale.
        regards, tom lane