Re: Additional accessors via the Extension API ?

2022-02-20 Thread Tom Lane
Julien Rouhaud  writes:
> On Sun, Feb 20, 2022 at 12:31:22PM +0200, Markur Sens wrote:
>> Is this documented & expected behavior or it’s just happens to work?

> I don't think it's documented but it's an expected behavior, see
> https://github.com/postgres/postgres/blob/master/src/backend/parser/parse_func.c#L57-L88

It is documented, near the bottom of this section:

https://www.postgresql.org/docs/current/rowtypes.html#ROWTYPES-USAGE

Other relevant oddities are mentioned in

https://www.postgresql.org/docs/current/xfunc-sql.html#XFUNC-SQL-COMPOSITE-FUNCTIONS

regards, tom lane




Re: Additional accessors via the Extension API ?

2022-02-20 Thread Markur Sens


> On 20 Feb 2022, at 12:35 PM, Julien Rouhaud  wrote:
> 
> On Sun, Feb 20, 2022 at 12:31:22PM +0200, Markur Sens wrote:
>>> 
>>> Maybe you could rely on some old grammar hack to have something a bit 
>>> similar,
>>> as (expr).funcname is an alias for funcname(expr).  For instance:
>> 
>> Is this documented & expected behavior or it’s just happens to work?
> 
> I don't think it's documented but it's an expected behavior, see
> 
> https://github.com/postgres/postgres/blob/master/src/backend/parser/parse_func.c#L57-L88
> 

Ah thanks for this

> /*
> * Parse a function call
> *
> * For historical reasons, Postgres tries to treat the notations tab.col
> * and col(tab) as equivalent: if a single-argument function call has an
> * argument of complex type and the (unqualified) function name matches
> * any attribute of the type, we can interpret it as a column projection.

and the (unqualified) function name matches
*   any attribute of the type, we can interpret it as a column projection.


> * Conversely a function of a single complex-type argument can be written
> * like a column reference, allowing functions to act like computed 
> columns.
> *
> * If both interpretations are possible, we prefer the one matching the
> * syntactic form, but otherwise the form does not matter.
> *
> * Hence, both cases come through here.  If fn is null, we're dealing with
> * column syntax not function syntax.  In the function-syntax case,
> * the FuncCall struct is needed to carry various decoration that applies
> * to aggregate and window functions.
> [...]





Re: Additional accessors via the Extension API ?

2022-02-20 Thread Julien Rouhaud
On Sun, Feb 20, 2022 at 12:31:22PM +0200, Markur Sens wrote:
> >
> > Maybe you could rely on some old grammar hack to have something a bit 
> > similar,
> > as (expr).funcname is an alias for funcname(expr).  For instance:
> 
> Is this documented & expected behavior or it’s just happens to work?

I don't think it's documented but it's an expected behavior, see

https://github.com/postgres/postgres/blob/master/src/backend/parser/parse_func.c#L57-L88

/*
 *  Parse a function call
 *
 *  For historical reasons, Postgres tries to treat the notations tab.col
 *  and col(tab) as equivalent: if a single-argument function call has an
 *  argument of complex type and the (unqualified) function name matches
 *  any attribute of the type, we can interpret it as a column projection.
 *  Conversely a function of a single complex-type argument can be written
 *  like a column reference, allowing functions to act like computed 
columns.
 *
 *  If both interpretations are possible, we prefer the one matching the
 *  syntactic form, but otherwise the form does not matter.
 *
 *  Hence, both cases come through here.  If fn is null, we're dealing with
 *  column syntax not function syntax.  In the function-syntax case,
 *  the FuncCall struct is needed to carry various decoration that applies
 *  to aggregate and window functions.
[...]




Re: Additional accessors via the Extension API ?

2022-02-20 Thread Markur Sens



> On 20 Feb 2022, at 12:12 PM, Julien Rouhaud  wrote:
> 
> Hi,
> 
> On Sun, Feb 20, 2022 at 08:07:20AM +0200, Markur Sens wrote:
>> Suppose  I have defined an additional type in a PG extension.
>> 
>> Is it possible to add custom accessors to that type -much like jsonb does-
>> but use an API/hook without touching the core PG grammar & parser?
> 
> Unfortunately no.
> 
>> Hypothetical Examples:
>> 
>> Assuming I have a TextFile type I’d like to implement syntax like:
>> 
>> (‘/home/me/a.txt’::TextFile).firstline
>> (‘/home/me/a.txt’::TextFile).lastline
>> (‘/home/me/a.txt’::TextFile).countlines()
>> (‘/home/me/a.txt’::TextFile).size()
>> (‘/home/me/a.txt’::TextFile).datemodified()
> 
> Maybe you could rely on some old grammar hack to have something a bit similar,
> as (expr).funcname is an alias for funcname(expr).  For instance:

Is this documented & expected behavior or it’s just happens to work?

> 
> # create function f1(int) returns text as $$
> begin
> return 'val: ' || $1::text;
> end;
> $$ language plpgsql;
> 
> # create table t as select 1 as id;
> 
> # select (5).f1, (id).f1 from t;
>   f1   |   f1
> +
> val: 5 | val: 1
> (1 row)
> 
> I don't know if that would be enough for you needs.  Otherwise, the only 
> option
> would be tocreate an operator instead, like mytype -> 'myaccessor' or 
> something
> like that.


Yes, that’s what I’m doing at the moment:
Syntax like type -> ‘accessor’ is pretty straight forward to implement as an 
operator as the rightarg is text.

Things get more complicating as I’m adding support for
mytype -> function(arg=1) 

for that case I have to create an intermediate type of function(arg) so that I 
can then define the left and right args for the -> operator.
But it’s a lot of boilerplate code.






Re: Additional accessors via the Extension API ?

2022-02-20 Thread Julien Rouhaud
Hi,

On Sun, Feb 20, 2022 at 08:07:20AM +0200, Markur Sens wrote:
> Suppose  I have defined an additional type in a PG extension.
>
> Is it possible to add custom accessors to that type -much like jsonb does-
> but use an API/hook without touching the core PG grammar & parser?

Unfortunately no.

> Hypothetical Examples:
>
> Assuming I have a TextFile type I’d like to implement syntax like:
>
> (‘/home/me/a.txt’::TextFile).firstline
> (‘/home/me/a.txt’::TextFile).lastline
> (‘/home/me/a.txt’::TextFile).countlines()
> (‘/home/me/a.txt’::TextFile).size()
> (‘/home/me/a.txt’::TextFile).datemodified()

Maybe you could rely on some old grammar hack to have something a bit similar,
as (expr).funcname is an alias for funcname(expr).  For instance:

# create function f1(int) returns text as $$
begin
return 'val: ' || $1::text;
end;
$$ language plpgsql;

# create table t as select 1 as id;

# select (5).f1, (id).f1 from t;
   f1   |   f1
+
 val: 5 | val: 1
(1 row)

I don't know if that would be enough for you needs.  Otherwise, the only option
would be tocreate an operator instead, like mytype -> 'myaccessor' or something
like that.




Aw: Additional accessors via the Extension API ?

2022-02-20 Thread Karsten Hilbert
> Suppose  I have defined an additional type in a PG extension.
> 
> Is it possible to add custom accessors to that type -much like jsonb does- 
> but use an API/hook without touching the core PG grammar & parser? 
> 
> Hypothetical Examples: 
> 
> Assuming I have a TextFile type I’d like to implement syntax like:
> 
> (‘/home/me/a.txt’::TextFile).firstline
> (‘/home/me/a.txt’::TextFile).lastline
> (‘/home/me/a.txt’::TextFile).countlines()
> (‘/home/me/a.txt’::TextFile).size()
> (‘/home/me/a.txt’::TextFile).datemodified()

Off on a tangent but would file_fdw help in any way ?

Karsten




Additional accessors via the Extension API ?

2022-02-19 Thread Markur Sens
Suppose  I have defined an additional type in a PG extension.

Is it possible to add custom accessors to that type -much like jsonb does- but 
use an API/hook without touching the core PG grammar & parser? 

Hypothetical Examples: 

Assuming I have a TextFile type I’d like to implement syntax like:

(‘/home/me/a.txt’::TextFile).firstline
(‘/home/me/a.txt’::TextFile).lastline
(‘/home/me/a.txt’::TextFile).countlines()
(‘/home/me/a.txt’::TextFile).size()
(‘/home/me/a.txt’::TextFile).datemodified()


The only relevant patch I could find is [1] but it’s a dead-end

[1] https://www.postgresql.org/message-id/20210501072458.adqjoaqnmhg4l34l%40nol