Re: [HACKERS] libpq and SPI - Mailing list pgsql-hackers

From Gerald L. Gay
Subject Re: [HACKERS] libpq and SPI
Date
Msg-id 006b01be6123$4f98b4b0$9a028a8f@2isdt54.korea.army.mil
Whole thread Raw
List pgsql-hackers

>"Gerald L. Gay" <glgay@pass.korea.army.mil> writes:
>>     I have seen what I concider to be a bug in either the libpq library
or
>> in the backend.  To see the effects, first, install the execq() function
>> from the SPI section of the Programmers Guide.  Then do this in psql:
>
>> template1=> select execq('create user fred', 1);
>> Backend sent D message without prior T
>
>That would be a backend bug, for sure.  It's a violation of the FE/BE
>protocol to send data row(s) without sending a row description first.
>
>>     At this point psql will hang.  I have a patch for libpq that fixes
this
>> but I am not sure if this is the right place for it.
>
>I do not believe it is really possible to "ignore" this error inside
>libpq.  Without the initial T message you have no idea how many fields
>are in a row, and thus you cannot even parse a D message to skip over
>it --- there's no way to know the length of the null-fields bitmap.

What I did in libpq was not to ignore the T message.  Instead, if I get a T
message, I remember it and ignore any intervening C messages until I either
get a D to satisfy the T, or I get a C message of type "SELECT."  This
happens if the select returns no rows.

>
>> Is it not reasonable to run "utility" queries from inside SPI?
>
>Seems reasonable offhand, but I have no idea whether it really is or
>not.  If the context that the SPI procedure is executing from is a
>SELECT, as you illustrate above, then I could see where it would be
>a bad idea to allow utility statements to execute before the SELECT
>finishes.  (Examples of no-nos: altering or dropping tables that the
>SELECT has already started using; VACUUM; perhaps other stuff.)

What I have seen is:  Any internal select/insert/update/delete calls that
are performed inside the SPI function get suppressed but any utility
functions get their status sent to the front end.  So the T message is
generated for the return type of the SPI function, then the C messages for
any utility functions called, and then the D message for the actual return
values.

The reason I discovered this in the first place was because the create user
.... in group thing doesn't work yet.  I am porting an application from
Sybase to Postgres and I need to ensure that the group stuff gets created.
So I wrote a create_user SPI function that creates the user and then updates
pg_group appropriately.  This is when I saw this bug.  Off-hand, I can't
think of anything else you might need this for.  But I can envision
site-specific triggers on things like create user/drop user that may be tied
to groups. Or maybe something like this:  Deleting a group causes all the
users in that group to also get deleted.  In that case you would have quite
a few "drop user" calls.

Another alternative might be something like Sybase.  In Sybase, when you
create a server-side procedure, you don't call it via SELECT.  You just type
it's name (they normally start with sp_, i.e., sp_spaceused - shows how much
space is available in a database).  So the current paradigm in Postgres
requires the SELECT protocol.  I personally like this because it works
nicely for getting the return status.  But it doesn't necessarily have to be
SELECT.  It could be something like EXEC or CALL or something.

>
>But either way it's definitely a backend bug: the SPI interface
>should either handle utility statements or reject them cleanly.
>
> regards, tom lane

I don't think it would be good to reject utility functions.  This seems to
me to fall into the category of "what if I need to ....."

Jerry




pgsql-hackers by date:

Previous
From: Tom Lane
Date:
Subject: Re: [HACKERS] shouldn't pg_dumpall...
Next
From: Tom Ivar Helbekkmo
Date:
Subject: Re: [HACKERS] postmaster failure with 2-23 snapshot