Re: Documentation about PL transforms

2022-04-07 Thread chap

On 2022-02-22 12:59, Chapman Flack wrote:

It would have been painful to write documentation of get_func_trftypes
saying its result isn't what get_transform_{from.to}sql expect, so
patch 1 does add a get_call_trftypes that returns a List *.

Patch 2 then updates the docs as discussed in this thread. It turned 
out

plhandler.sgml was kind of a long monolith of text even before adding
transform information, so I broke it into sections first. This patch 
adds

the section markup without reindenting, so the changes aren't obscured.

The chapter had also fallen behind the introduction of procedures, so
I have changed many instances of 'function' to the umbrella term
'routine'.

Patch 3 simply reindents for the new section markup and rewraps.
Whitespace only.

Patch 4 updates src/test/modules/plsample to demonstrate handling of
transforms (and to add some more comments generally).


Here is a rebase.From 9c726423d47a114a82ca703c0e03a62e3d74f1f6 Mon Sep 17 00:00:00 2001
From: Chapman Flack 
Date: Mon, 21 Feb 2022 20:56:28 -0500
Subject: [PATCH v2 1/4] Warmup: add a get_call_trftypes function

The existing get_func_trftypes function produces an Oid[], where
both existing get_transform_{from,to}sql functions that depend
on the result expect a List*.

Rather than writing documentation awkwardly describing functions
that won't play together, add a get_call_trftypes function that
returns List*. (The name get_call_... to distinguish from
get_func_... follows the naming used in funcapi.h for a function
returning information about either a function or a procedure.)
---
 src/backend/utils/cache/lsyscache.c | 18 ++
 src/include/funcapi.h   |  5 +
 src/include/utils/lsyscache.h   |  1 +
 3 files changed, 24 insertions(+)

diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 1b7e11b..3cd94db 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2117,6 +2117,24 @@ get_transform_tosql(Oid typid, Oid langid, List *trftypes)
 		return InvalidOid;
 }
 
+/*
+ * get_call_trftypes
+ *
+ *		A helper function that does not itself query the transform cache, but
+ *		constructs the transform-type List expected by the functions above.
+ */
+List *
+get_call_trftypes(HeapTuple procTup)
+{
+	Datum		protrftypes;
+	bool		isNull;
+
+	protrftypes = SysCacheGetAttr(PROCOID, procTup,
+  Anum_pg_proc_protrftypes,
+  &isNull);
+	return isNull ?  NIL : oid_array_to_list(protrftypes);
+}
+
 
 /*-- TYPE CACHE --		 */
 
diff --git a/src/include/funcapi.h b/src/include/funcapi.h
index dc3d819..70c3e13 100644
--- a/src/include/funcapi.h
+++ b/src/include/funcapi.h
@@ -175,7 +175,12 @@ extern int	get_func_arg_info(HeapTuple procTup,
 extern int	get_func_input_arg_names(Datum proargnames, Datum proargmodes,
 	 char ***arg_names);
 
+/*
+ * A deprecated earlier version of get_call_trftypes (in lsyscache.h).
+ * That version produces a List, which is the form downstream functions expect.
+ */
 extern int	get_func_trftypes(HeapTuple procTup, Oid **p_trftypes);
+
 extern char *get_func_result_name(Oid functionId);
 
 extern TupleDesc build_function_result_tupdesc_d(char prokind,
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index b8dd27d..93b19e7 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -139,6 +139,7 @@ extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
+extern List *get_call_trftypes(HeapTuple procTup);
 extern Oid	get_transform_fromsql(Oid typid, Oid langid, List *trftypes);
 extern Oid	get_transform_tosql(Oid typid, Oid langid, List *trftypes);
 extern bool get_typisdefined(Oid typid);
-- 
2.7.3

From 7fb3f8971c4c573903b1d08bcbeb126e31a6544c Mon Sep 17 00:00:00 2001
From: Chapman Flack 
Date: Mon, 21 Feb 2022 20:59:32 -0500
Subject: [PATCH v2 2/4] Update PL handler implementation docs

The original purpose was to add information on support for
CREATE TRANSFORM (which must be explicitly coded in any PL
implementation intending to support it). But the plhandler
section was about as long as a monolith of text ought to be,
even before adding transform information, so reorganized
first into sections.

Front-loaded with short descriptions of the three possible
functions (call handler, validator, inline handler) registered
with CREATE LANGUAGE. The latter two were afterthoughts in historical
sequence, but the docs don't need to present them that way.

The section had also fallen behind the introduction of procedures,
so updated to generally use the umbrella term 'routine' in place
of 'function'.

New section markup added here without indentation change, to avoid
obscuring changes. A follow-on commit will reindent and rewrap.
---
 doc/src/sgml/event-trigger.sgml|  16 ++
 doc/src/sgml/plhandler.sgml   

Re: Documentation about PL transforms

2022-02-07 Thread Peter Eisentraut

On 05.02.22 00:55, Chapman Flack wrote:

I'm thinking plhandler.sgml is the only place that really needs to be
said; readers looking up CREATE TRANSFORM and using an existing PL that
supports it don't need to know how the sausage is made. (Maybe it is
worth mentioning there, though, that it isn't possible to develop
transforms for an arbitrary PL unless that PL applies transforms.)


makes sense


I noticed the CREATE TRANSFORM docs show the argument list as
(argument_type [, ...]) even though check_transform_function will reject
any argument list of length other than 1 or with type other than internal.
Is that an overly-generic way to show the syntax, or is that a style
with precedent elsewhere in the docs?


That could be corrected.


As long as a PL handler has the sole responsibility for invoking
its transforms, I wonder if it would make sense to allow a PL to
define what its transforms should look like, maybe replacing
check_transform_function with a transform_validator for the PL.
I'm not proposing such a patch here, but I am willing to prepare
one for plhandler.sgml and maybe pltemplate.c documenting the current
situation, if nobody tells me I'm wrong about something here.


Maybe.  This kind of thing would mostly be driven what a PL wants in 
actual practice, and then how that could be generalized to many/all PLs.





Re: Documentation about PL transforms

2022-02-07 Thread Chapman Flack
On 02/07/22 10:59, Peter Eisentraut wrote:
> On 05.02.22 00:55, Chapman Flack wrote:
>> I'm thinking plhandler.sgml is the only place that really needs to be
>> ...
>> worth mentioning there, though, that it isn't possible to develop
>> transforms for an arbitrary PL unless that PL applies transforms.)
> 
> makes sense
> 
>> (argument_type [, ...]) even though check_transform_function will reject
>> any argument list of length other than 1 or with type other than internal.
> 
> That could be corrected.

I'll work on some doc patches.

>> As long as a PL handler has the sole responsibility for invoking
>> its transforms, I wonder if it would make sense to allow a PL to
>> define what its transforms should look like, maybe replacing
>> check_transform_function with a transform_validator for the PL.
> 
> Maybe.  This kind of thing would mostly be driven what a PL wants in actual
> practice, and then how that could be generalized to many/all PLs.

It has since occurred to me that another benefit of having a
transform_validator per PL would be immediate error reporting
if someone, for whatever reason, tries out CREATE TRANSFORM
for a PL that doesn't grok transforms.

Regards,
-Chap




Re: Documentation about PL transforms

2022-02-08 Thread Chapman Flack
On 02/07/22 15:14, Chapman Flack wrote:
> It has since occurred to me that another benefit of having a
> transform_validator per PL would be immediate error reporting
> if someone, for whatever reason, tries out CREATE TRANSFORM
> for a PL that doesn't grok transforms.

The same could be achieved, I guess, by an event trigger, though that
would take positive effort to set up, where the benefit of a per-PL
transform_validator would be that if a given PL does not bother to
provide one, CREATE TRANSFORM for it would automatically fail. (And
such a validator would not have to spend most of its life ignoring
other DDL.)

That does reveal another documentation gap: table 40.1 does not show
CREATE or DROP TRANSFORM being supported for event triggers. I've
confirmed they work, though. I'll tack that onto the doc patch.

I notice our transforms lack the named groups of 9075-2. With those
(plus our LANGUAGE clause), I could write, for a made-up example:

CREATE TRANSFORM FOR hstore LANGUAGE plpython3u
  asdict (
FROM SQL WITH FUNCTION hstore_to_plpython3dict,
TO SQL WITH FUNCTION plpython3dict_to_hstore)
  asnamedtuple (
FROM SQL WITH FUNCTION hstore_to_plpython3namedtup,
TO SQL WITH FUNCTION plpython3namedtup_to_hstore);

CREATE FUNCTION f1(val hstore) RETURNS int
LANGUAGE plpython3u
TRANSFORM GROUP asdict FOR TYPE hstore
...

CREATE FUNCTION f2(val hstore) RETURNS int
LANGUAGE plpython3u
TRANSFORM GROUP asnamedtuple FOR TYPE hstore
...

It seems to me that could be useful, in cases where a PL offers
more than one good choice for representing a PostgreSQL type and
the preferred one could depend on the function.

Was that considered and rejected for our transforms, or were ours
just based on an earlier 9075-2 without the named groups?


Also, I am doubtful of our Compatibility note, "There is a CREATE
TRANSFORM command in the SQL standard, but it is for adapting data
types to client languages."

In my reading of 9075-2, I do see the transforms used for client
languages (all the s), but I also see
the to-sql and from-sql functions being applied in 
whenever "R is an external routine" and the type "is a user-defined type".
The latter doesn't seem much different from our usage. The differences
I see are (1) our LANGUAGE clause, (2) we don't have a special
"user-defined type" category limiting what types can have transforms
(and (3), we don't have the named groups). And we are applying them
/only/ for server-side routines, rather than for server and client code.

The ISO transforms work by mapping the ("user-defined") type to some
existing SQL type for which the PL has a standard mapping already. Ours
work by mapping the type directly to some suitable type in the PL.

Am I reading this accurately?

Regards,
-Chap




Re: Documentation about PL transforms

2022-02-21 Thread Chapman Flack
On 02/07/22 15:14, Chapman Flack wrote:
> I'll work on some doc patches.

It seems a bit of an impedance mismatch that there is a get_func_trftypes
producing a C Oid[] (with its length returned separately), while
get_transform_fromsql and get_transform_tosql both expect a List.

There is only one in-core caller of get_func_trftypes (it is
print_function_trftypes in ruleutils.c), while both in-core PLs that
currently support transforms are reduced to rolling their own List by
grabbing the protrftypes Datum and hitting it with oid_array_to_list.

Would it be reasonable to deprecate get_func_trftypes and instead
provide a get_call_trftypes (following the naming of get_call_result_type
where _call_ encompasses functions and procedures) that returns a List,
and use that consistently?

Regards,
-Chap




Re: Documentation about PL transforms

2022-02-22 Thread Chapman Flack
On 02/21/22 16:09, Chapman Flack wrote:
> On 02/07/22 15:14, Chapman Flack wrote:
>> I'll work on some doc patches.
> 
> It seems a bit of an impedance mismatch that there is a get_func_trftypes
> producing a C Oid[] (with its length returned separately), while
> get_transform_fromsql and get_transform_tosql both expect a List.
> ...
> Would it be reasonable to deprecate get_func_trftypes and instead
> provide a get_call_trftypes

It would have been painful to write documentation of get_func_trftypes
saying its result isn't what get_transform_{from.to}sql expect, so
patch 1 does add a get_call_trftypes that returns a List *.

Patch 2 then updates the docs as discussed in this thread. It turned out
plhandler.sgml was kind of a long monolith of text even before adding
transform information, so I broke it into sections first. This patch adds
the section markup without reindenting, so the changes aren't obscured.

The chapter had also fallen behind the introduction of procedures, so
I have changed many instances of 'function' to the umbrella term
'routine'.

Patch 3 simply reindents for the new section markup and rewraps.
Whitespace only.

Patch 4 updates src/test/modules/plsample to demonstrate handling of
transforms (and to add some more comments generally).

I'll add this to the CF.

Regards,
-Chap
>From 7e6027cdcf1dbf7a10c0bad5059816cef762b1b9 Mon Sep 17 00:00:00 2001
From: Chapman Flack 
Date: Mon, 21 Feb 2022 20:56:28 -0500
Subject: [PATCH 1/4] Warmup: add a get_call_trftypes function

The existing get_func_trftypes function produces an Oid[], where
both existing get_transform_{from,to}sql functions that depend
on the result expect a List*.

Rather than writing documentation awkwardly describing functions
that won't play together, add a get_call_trftypes function that
returns List*. (The name get_call_... to distinguish from
get_func_... follows the naming used in funcapi.h for a function
returning information about either a function or a procedure.)
---
 src/backend/utils/cache/lsyscache.c | 18 ++
 src/include/funcapi.h   |  5 +
 src/include/utils/lsyscache.h   |  1 +
 3 files changed, 24 insertions(+)

diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index feef999..a49ccad 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2107,6 +2107,24 @@ get_transform_tosql(Oid typid, Oid langid, List *trftypes)
 		return InvalidOid;
 }
 
+/*
+ * get_call_trftypes
+ *
+ *		A helper function that does not itself query the transform cache, but
+ *		constructs the transform-type List expected by the functions above.
+ */
+List *
+get_call_trftypes(HeapTuple procTup)
+{
+	Datum		protrftypes;
+	bool		isNull;
+
+	protrftypes = SysCacheGetAttr(PROCOID, procTup,
+  Anum_pg_proc_protrftypes,
+  &isNull);
+	return isNull ?  NIL : oid_array_to_list(protrftypes);
+}
+
 
 /*-- TYPE CACHE --		 */
 
diff --git a/src/include/funcapi.h b/src/include/funcapi.h
index ba927c2..7c61560 100644
--- a/src/include/funcapi.h
+++ b/src/include/funcapi.h
@@ -175,7 +175,12 @@ extern int	get_func_arg_info(HeapTuple procTup,
 extern int	get_func_input_arg_names(Datum proargnames, Datum proargmodes,
 	 char ***arg_names);
 
+/*
+ * A deprecated earlier version of get_call_trftypes (in lsyscache.h).
+ * That version produces a List, which is the form downstream functions expect.
+ */
 extern int	get_func_trftypes(HeapTuple procTup, Oid **p_trftypes);
+
 extern char *get_func_result_name(Oid functionId);
 
 extern TupleDesc build_function_result_tupdesc_d(char prokind,
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index b8dd27d..93b19e7 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -139,6 +139,7 @@ extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
+extern List *get_call_trftypes(HeapTuple procTup);
 extern Oid	get_transform_fromsql(Oid typid, Oid langid, List *trftypes);
 extern Oid	get_transform_tosql(Oid typid, Oid langid, List *trftypes);
 extern bool get_typisdefined(Oid typid);
-- 
2.7.3

>From 447a4aaecdf3a23a47c11ad741b49f81475e34e3 Mon Sep 17 00:00:00 2001
From: Chapman Flack 
Date: Mon, 21 Feb 2022 20:59:32 -0500
Subject: [PATCH 2/4] Update PL handler implementation docs

The original purpose was to add information on support for
CREATE TRANSFORM (which must be explicitly coded in any PL
implementation intending to support it). But the plhandler
section was about as long as a monolith of text ought to be,
even before adding transform information, so reorganized
first into sections.

Front-loaded with short descriptions of the three possible
functions (call handler, validator, inline handler) registered
with CREATE LANGUAGE. The latter two were afterthoughts in historical
sequence, but the 

Re: Documentation about PL transforms

2022-07-12 Thread Pavel Stehule
Hi

I am doing an review of this patch and I have two comments

1. I am not sure if get_call_trftypes is a good name - the prefix get_call
is used when some runtime data is processed. This function just returns
reformatted data from the system catalogue. Maybe get_func_trftypes_list,
or just replace function get_func_trftypes (now, the list is an array, so
there should not be performance issues). For consistency, the new function
should be used in plperl and plpython too. Probably this function is not
widely used, so I don't see why we need to have two almost equal functions
in code.

2.

+It also contains the OID of the intended procedural language and
whether
+that procedural language is declared as TRUSTED,
useful
+if a single inline handler is supporting more than one procedural
language.

I am not sure if this sentence is in the correct place. Maybe can be
mentioned separately,
so generally handlers can be used by more than one procedural language. But
maybe
I don't understand this sentence.

Regards

Pavel


Re: Documentation about PL transforms

2022-07-27 Thread chap

On 2022-07-13 00:26, Pavel Stehule wrote:

1. I am not sure if get_call_trftypes is a good name - the prefix 
get_call

is used when some runtime data is processed.


I guess I hadn't caught on that the prefix carried that meaning.
To me, it appeared to be a prefix used to avoid being specific to
'function' or 'procedure'.


This function just returns
reformatted data from the system catalogue. Maybe 
get_func_trftypes_list,
or just replace function get_func_trftypes (now, the list is an array, 
so
there should not be performance issues). For consistency, the new 
function
should be used in plperl and plpython too. Probably this function is 
not


If it is acceptable to replace get_func_trftypes like that, I can 
produce

such a patch.


2.

+It also contains the OID of the intended procedural language and
whether
+that procedural language is declared as 
TRUSTED,

useful
+if a single inline handler is supporting more than one procedural
language.

I am not sure if this sentence is in the correct place. Maybe can be
mentioned separately,
so generally handlers can be used by more than one procedural language. 
But

maybe
I don't understand this sentence.


My point was that, if the structure did /not/ include the OID of
the PL and its TRUSTED property, then it would not be possible
for a single inline handler to support more than one PL. So that
is why it is a good thing that those are included in the structure,
and why it would be a bad thing if they were not.

Would it be clearer to say:

It also contains the OID of the intended procedural language and whether
that procedural language is declared as TRUSTED.
While these values are redundant if the inline handler is serving only
a single procedural language, they are necessary to allow one inline
handler to serve more than one PL.

Regards,
-Chap




Re: Documentation about PL transforms

2022-07-27 Thread Pavel Stehule
čt 28. 7. 2022 v 4:06 odesílatel  napsal:

> On 2022-07-13 00:26, Pavel Stehule wrote:
>
> > 1. I am not sure if get_call_trftypes is a good name - the prefix
> > get_call
> > is used when some runtime data is processed.
>
> I guess I hadn't caught on that the prefix carried that meaning.
> To me, it appeared to be a prefix used to avoid being specific to
> 'function' or 'procedure'.
>

I am sure this function is in Postgres significantly longer than Postgres
has support for 'procedures'.


>
> > This function just returns
> > reformatted data from the system catalogue. Maybe
> > get_func_trftypes_list,
> > or just replace function get_func_trftypes (now, the list is an array,
> > so
> > there should not be performance issues). For consistency, the new
> > function
> > should be used in plperl and plpython too. Probably this function is
> > not
>
> If it is acceptable to replace get_func_trftypes like that, I can
> produce
> such a patch.
>
> > 2.
> >
> > +It also contains the OID of the intended procedural language and
> > whether
> > +that procedural language is declared as
> > TRUSTED,
> > useful
> > +if a single inline handler is supporting more than one procedural
> > language.
> >
> > I am not sure if this sentence is in the correct place. Maybe can be
> > mentioned separately,
> > so generally handlers can be used by more than one procedural language.
> > But
> > maybe
> > I don't understand this sentence.
>
> My point was that, if the structure did /not/ include the OID of
> the PL and its TRUSTED property, then it would not be possible
> for a single inline handler to support more than one PL. So that
> is why it is a good thing that those are included in the structure,
> and why it would be a bad thing if they were not.
>
> Would it be clearer to say:
>
> It also contains the OID of the intended procedural language and whether
> that procedural language is declared as TRUSTED.
> While these values are redundant if the inline handler is serving only
> a single procedural language, they are necessary to allow one inline
> handler to serve more than one PL.
>

ok

Regards

Pavel

>
> Regards,
> -Chap
>


Re: Documentation about PL transforms

2022-07-29 Thread chap

On 2022-07-28 01:51, Pavel Stehule wrote:

Would it be clearer to say:

It also contains the OID of the intended procedural language and 
whether

that procedural language is declared as TRUSTED.
While these values are redundant if the inline handler is serving only
a single procedural language, they are necessary to allow one inline
handler to serve more than one PL.


ok


I will probably be unable to produce a new patch for this CF.
Family obligation.

Regards,
-Chap




Re: Documentation about PL transforms

2022-07-29 Thread Pavel Stehule
pá 29. 7. 2022 v 18:35 odesílatel  napsal:

> On 2022-07-28 01:51, Pavel Stehule wrote:
> >> Would it be clearer to say:
> >>
> >> It also contains the OID of the intended procedural language and
> >> whether
> >> that procedural language is declared as TRUSTED.
> >> While these values are redundant if the inline handler is serving only
> >> a single procedural language, they are necessary to allow one inline
> >> handler to serve more than one PL.
> >
> > ok
>
> I will probably be unable to produce a new patch for this CF.
> Family obligation.
>

ok

Regards

Pavel



>
> Regards,
> -Chap
>