Обсуждение: Is querying SPITupleTable with SQL possible?

Поиск
Список
Период
Сортировка

Is querying SPITupleTable with SQL possible?

От
Tom Mercha
Дата:
Dear Hackers

I am using PostgreSQL's SPI to execute a simple SQL query (SELECT * FROM 
...) via SPI_exec. As a a result, I get an SPITupleTable with the 
results of my query.

Now that I have the SPITupleTable, I was wondering if it would be 
possible to later query over it further in my SQL statements using SPI, 
for example, something a bit similar to SPI_Exec ("Select * FROM 
:mySPITupleTable", 0);

My motivation is to treat, and use the SPITupleTable as 'intermediate' 
or 'temporary' tables which I would discard early - I want to apply a 
series of manipulations to my SPITupleTable before I would finally store 
it in the tablespace. Therefore, minimization of any overheads is also 
very important. I understand that I could introduce a CREATE TABLE to my 
SQL query and reference a table in that way, but I am under the 
impression that it would incur unnecessary overheads?

So, I would be grateful if anyone could help me understand how to 
manipulate the SPITupleTable further with SQL or indicate if it is at 
all possible. In the case that it is not possible, I would also be 
interested in alternatives and discussion on overheads.

Thanks in advance.

Best,
Tom

Re: Is querying SPITupleTable with SQL possible?

От
Tom Lane
Дата:
Tom Mercha <mercha_t@hotmail.com> writes:
> I am using PostgreSQL's SPI to execute a simple SQL query (SELECT * FROM 
> ...) via SPI_exec. As a a result, I get an SPITupleTable with the 
> results of my query.
> Now that I have the SPITupleTable, I was wondering if it would be 
> possible to later query over it further in my SQL statements using SPI, 
> for example, something a bit similar to SPI_Exec ("Select * FROM 
> :mySPITupleTable", 0);

It's possible you could use the "transition table" (aka
EphemeralNamedRelation) infrastructure for this, though I'm not sure
if it's really a close fit, or whether it's been built out enough to
support this usage.  From memory, it wants to work with tuplestores,
which are a bit heavier-weight than SPITupleTables.

            regards, tom lane



Re: Is querying SPITupleTable with SQL possible?

От
Tom Mercha
Дата:
On 02/10/2019 16:11, Tom Lane wrote:
> Tom Mercha <mercha_t@hotmail.com> writes:
>> I am using PostgreSQL's SPI to execute a simple SQL query (SELECT * FROM
>> ...) via SPI_exec. As a a result, I get an SPITupleTable with the
>> results of my query.
>> Now that I have the SPITupleTable, I was wondering if it would be
>> possible to later query over it further in my SQL statements using SPI,
>> for example, something a bit similar to SPI_Exec ("Select * FROM
>> :mySPITupleTable", 0);
> 
> It's possible you could use the "transition table" (aka
> EphemeralNamedRelation) infrastructure for this, though I'm not sure
> if it's really a close fit, or whether it's been built out enough to
> support this usage.  From memory, it wants to work with tuplestores,
> which are a bit heavier-weight than SPITupleTables.
> 
>             regards, tom lane
> 

Thanks for this feedback! The EphemeralNamedRelation seems that it could 
be a good fit for what I'm looking for.

However, I'm not quite so sure how I can query over the 
EphemeralNamedRelation using SQL? Could someone indicate where I can 
find an example?

Regards
Tom

Re: Is querying SPITupleTable with SQL possible?

От
Chapman Flack
Дата:
On 10/2/19 2:53 PM, Tom Mercha wrote:

> However, I'm not quite so sure how I can query over the 
> EphemeralNamedRelation using SQL? Could someone indicate where I can 
> find an example?

You could look in the documentation for CREATE TRIGGER in PG 10
or later, specifically the clauses like REFERENCING NEW TABLE AS foo.

https://www.postgresql.org/docs/10/sql-createtrigger.html

While the trigger function is executing, it can do SPI SQL
queries exactly as if there is a table named 'foo' sitting there,
but it only "exists" for that function and only until it returns.

Regards,
-Chap



RE: Is querying SPITupleTable with SQL possible?

От
"Wu, Fei"
Дата:
Hi,
I have had see your discussion about node EphemeralNamedRelation with the Community.
Now, I want to use this node in SQL(for test), I have saw the manual but could not understand,
can you show me a example on how to use it in SQL?

Thanks a lot~

Regards, wu fei

-----Original Message-----
From: Tom Mercha [mailto:mercha_t@hotmail.com] 
Sent: 2019年10月3日 2:53
To: Tom Lane <tgl@sss.pgh.pa.us>
Cc: pgsql-hackers@postgresql.org
Subject: Re: Is querying SPITupleTable with SQL possible?

On 02/10/2019 16:11, Tom Lane wrote:
> Tom Mercha <mercha_t@hotmail.com> writes:
>> I am using PostgreSQL's SPI to execute a simple SQL query (SELECT * 
>> FROM
>> ...) via SPI_exec. As a a result, I get an SPITupleTable with the 
>> results of my query.
>> Now that I have the SPITupleTable, I was wondering if it would be 
>> possible to later query over it further in my SQL statements using 
>> SPI, for example, something a bit similar to SPI_Exec ("Select * FROM 
>> :mySPITupleTable", 0);
> 
> It's possible you could use the "transition table" (aka
> EphemeralNamedRelation) infrastructure for this, though I'm not sure 
> if it's really a close fit, or whether it's been built out enough to 
> support this usage.  From memory, it wants to work with tuplestores, 
> which are a bit heavier-weight than SPITupleTables.
> 
>             regards, tom lane
> 

Thanks for this feedback! The EphemeralNamedRelation seems that it could be a good fit for what I'm looking for.

However, I'm not quite so sure how I can query over the EphemeralNamedRelation using SQL? Could someone indicate where
Ican find an example?
 

Regards
Tom





Re: Is querying SPITupleTable with SQL possible?

От
Thomas Munro
Дата:
[un-top-postifying]

On Fri, Dec 20, 2019 at 2:53 PM Wu, Fei <wufei.fnst@cn.fujitsu.com> wrote:
>> On 02/10/2019 16:11, Tom Lane wrote:
>> > Tom Mercha <mercha_t@hotmail.com> writes:
>> >> I am using PostgreSQL's SPI to execute a simple SQL query (SELECT *
>> >> FROM
>> >> ...) via SPI_exec. As a a result, I get an SPITupleTable with the
>> >> results of my query.
>> >> Now that I have the SPITupleTable, I was wondering if it would be
>> >> possible to later query over it further in my SQL statements using
>> >> SPI, for example, something a bit similar to SPI_Exec ("Select * FROM
>> >> :mySPITupleTable", 0);
>> >
>> > It's possible you could use the "transition table" (aka
>> > EphemeralNamedRelation) infrastructure for this, though I'm not sure
>> > if it's really a close fit, or whether it's been built out enough to
>> > support this usage.  From memory, it wants to work with tuplestores,
>> > which are a bit heavier-weight than SPITupleTables.
>>
>> Thanks for this feedback! The EphemeralNamedRelation seems that it could be a good fit for what I'm looking for.
>>
>> However, I'm not quite so sure how I can query over the EphemeralNamedRelation using SQL? Could someone indicate
whereI can find an example?
 
>
> I have had see your discussion about node EphemeralNamedRelation with the Community.
> Now, I want to use this node in SQL(for test), I have saw the manual but could not understand,
> can you show me a example on how to use it in SQL?

I missed this thread before.  If you want to expose an ENR to SQL
you'll need to write some C code for now (unless someone has added
support for other languages?).  Try something like this (not tested):

EphemeralNamedRelation enr = palloc0(sizeof(*enr));

enr->md.name = "my_magic_table";
enr->md.reliddesc = InvalidOid;
enr->md.tupdesc = my_magic_table_tuple_descriptor;
enr->md.enrtype = ENR_NAMED_TUPLESTORE;
enr->md.enrtuples = how_many_tuples_to_tell_the_planner_we_have;
enr->reldata = my_tupestorestate;
rc = SPI_register_relation(enr);
if (rc != SPI_OK_REL_REGISTER)
  explode();

You will need to come up with a TupleDesc that describes the columns
in your magic table, and a Tuplestorestate that holds the tuples.
After that you should be able to plan and execute read-only SQL
queries against that tuplestore using that name, via the usual
SPI_xxx() interfaces.  I'm not sure how you'd really do this though:
you might need to make a function that takes a query as a string, then
does the above setup in a new SPI connection, and then executes the
query.  This would probably be a lot more fun from a PL like Python.
(If you wanted to create ENRs that are available to your top level
connection, I haven't looked into it but I suspect that'd require more
machinery than we have right now, and I'm not sure if it'd be a good
idea.)

In theory, there could be a new type ENR_SPI_TUPLE_TABLE that could
work with SPITupleTable instead of Tuplestore.  The idea was that we
might be able to do more clever things like that in the future, which
is why we tried to make it at least a little bit general.  One thing
that could be nice would be SQL Server style table variables; you
could have a functions that receive them as parameters, return them,
and be able to insert/update/delete.  That's a bit far fetched, but
gives some idea of the reason we invented QueryEnvironment and passed
to all the right places in the planner and executor (or perhaps not
enough yet, we do occasionally find places that we forgot to pass
it...).  So yeah, to use an SPITupleTable now you'd need to insert its
contents into a Tuplestorestate.

As mentioned, this is the mechanism that is used to support SQL
standard "transition tables" in triggers.  You can see that the
function SPI_register_trigger_data() just does what I showed above to
expose all the transition tables to your trigger's SQL statements.
That part even works in Perl, Python, TCL triggers, but to make your
own tables in higher level languages you'd need to expose more
interfaces and figure out sane ways to get TupleDescriptor and
interact with Tuplestore.  If you want to see examples of SQL queries
inside triggers that access transition tables, check out
src/test/regress/expected/triggers.out and
src/pl/plpython/expected/plpython_trigger.out.