RE: [HACKERS] libpq and SPI
| От | Hiroshi Inoue |
|---|---|
| Тема | RE: [HACKERS] libpq and SPI |
| Дата | |
| Msg-id | 000001be6f58$bfd58800$2801007e@cadzone.tpf.co.jp обсуждение исходный текст |
| Ответ на | RE: [HACKERS] libpq and SPI ("Hiroshi Inoue" <Inoue@tpf.co.jp>) |
| Ответы |
Re: [HACKERS] libpq and SPI
|
| Список | pgsql-hackers |
Hello all,
> -----Original Message-----
> From: owner-pgsql-hackers@postgreSQL.org
> [mailto:owner-pgsql-hackers@postgreSQL.org]On Behalf Of Hiroshi Inoue
> Sent: Monday, March 15, 1999 7:00 PM
> To: Tom Lane; Clark Evans
> Cc: pgsql-hackers@postgreSQL.org
> Subject: RE: [HACKERS] libpq and SPI
>
> >
> >
> > > What is the problem? I'll research a SPI patch.
> >
> > Check the hackers thread (last month I think) titled "libpq and SPI";
> > the problem occurs when one submits a utility statement rather than
> > a plannable query via SPI. Apparently what is happening is that the
> > backend emits a 'T' message before it invokes the called statement
> > and then emits a 'D' message afterwards --- so if the called statement
> > causes a 'C' message to come out, libpq gets unhappy. This seems
> > to be clearly a violation of the FE/BE protocol to me, so I don't think
> > it's libpq's fault.
> >
> > Reasonable fixes might be to postpone the sending of 'T' till after
> > the invoked statement is executed, or to modify the traffic cop so
> > that a utility statement invoked from SPI doesn't send 'C'.
> >
> > I know a little bit about the parts of the backend that communicate with
> > the frontend, but nothing about SPI, so I'm not well prepared to solve
> > the problem by myself.
> >
>
> Probably it's not the problem of SPI.
> Specific utility commands(CREATE USER/ALTER USER/DROP USER
> /CREATE DATABASE/DROP DATABASE) break FE/BE protocol
> when they are executed inside the PostgreSQL function call.
>
Here is a patch.
I have changed to call pg_exec_query_dest() instead of pg_exec_query().
Thanks.
Hiroshi Inoue
Inoue@tpf.co.jp
*** backend/tcop/utility.c.orig Thu Feb 18 17:01:27 1999
--- backend/tcop/utility.c Tue Mar 16 09:25:07 1999
***************
*** 57,65 **** #include "utils/syscache.h" #endif
! void DefineUser(CreateUserStmt *stmt);
! void AlterUser(AlterUserStmt *stmt);
! void RemoveUser(char *username);
/* ---------------- * CHECK_IF_ABORTED() is used to avoid doing unnecessary
--- 57,65 ---- #include "utils/syscache.h" #endif
! void DefineUser(CreateUserStmt *stmt, CommandDest);
! void AlterUser(AlterUserStmt *stmt, CommandDest);
! void RemoveUser(char *username, CommandDest);
/* ---------------- * CHECK_IF_ABORTED() is used to avoid doing unnecessary
***************
*** 558,564 ****
PS_SET_STATUS(commandTag = "CREATEDB"); CHECK_IF_ABORTED();
! createdb(stmt->dbname, stmt->dbpath, stmt->encoding); } break;
--- 558,564 ----
PS_SET_STATUS(commandTag = "CREATEDB"); CHECK_IF_ABORTED();
! createdb(stmt->dbname, stmt->dbpath, stmt->encoding, dest); } break;
***************
*** 568,574 ****
PS_SET_STATUS(commandTag = "DESTROYDB"); CHECK_IF_ABORTED();
! destroydb(stmt->dbname); } break;
--- 568,574 ----
PS_SET_STATUS(commandTag = "DESTROYDB"); CHECK_IF_ABORTED();
! destroydb(stmt->dbname, dest); } break;
***************
*** 748,754 **** PS_SET_STATUS(commandTag = "CREATE USER"); CHECK_IF_ABORTED();
! DefineUser((CreateUserStmt *) parsetree); break;
case T_AlterUserStmt:
--- 748,754 ---- PS_SET_STATUS(commandTag = "CREATE USER"); CHECK_IF_ABORTED();
! DefineUser((CreateUserStmt *) parsetree, dest); break;
case T_AlterUserStmt:
***************
*** 755,761 **** PS_SET_STATUS(commandTag = "ALTER USER"); CHECK_IF_ABORTED();
! AlterUser((AlterUserStmt *) parsetree); break;
case T_DropUserStmt:
--- 755,761 ---- PS_SET_STATUS(commandTag = "ALTER USER"); CHECK_IF_ABORTED();
! AlterUser((AlterUserStmt *) parsetree, dest); break;
case T_DropUserStmt:
***************
*** 762,768 **** PS_SET_STATUS(commandTag = "DROP USER"); CHECK_IF_ABORTED();
! RemoveUser(((DropUserStmt *) parsetree)->user); break;
case T_LockStmt:
--- 762,768 ---- PS_SET_STATUS(commandTag = "DROP USER"); CHECK_IF_ABORTED();
! RemoveUser(((DropUserStmt *) parsetree)->user, dest); break;
case T_LockStmt:
*** backend/commands/user.c.orig Thu Feb 18 17:00:38 1999
--- backend/commands/user.c Tue Mar 16 09:50:09 1999
***************
*** 46,52 **** */ static void
! UpdatePgPwdFile(char *sql) {
char *filename,
--- 46,52 ---- */ static void
! UpdatePgPwdFile(char *sql, CommandDest dest) {
char *filename,
***************
*** 71,77 **** snprintf(sql, SQL_LENGTH, "copy %s to '%s' using delimiters %s",
ShadowRelationName,tempname, CRYPT_PWD_FILE_SEPCHAR);
! pg_exec_query(sql); rename(tempname, filename); pfree((void *) tempname);
--- 71,77 ---- snprintf(sql, SQL_LENGTH, "copy %s to '%s' using delimiters %s",
ShadowRelationName,tempname, CRYPT_PWD_FILE_SEPCHAR);
! pg_exec_query_dest(sql, dest, false); rename(tempname, filename); pfree((void *) tempname);
***************
*** 92,98 **** *--------------------------------------------------------------------- */ void
! DefineUser(CreateUserStmt *stmt) {
char *pg_shadow,
--- 92,98 ---- *--------------------------------------------------------------------- */ void
! DefineUser(CreateUserStmt *stmt, CommandDest dest) {
char *pg_shadow,
***************
*** 175,187 **** stmt->password ? stmt->password : "''", stmt->validUntil ? stmt->validUntil :
"");
! pg_exec_query(sql);
/* * Add the stuff here for groups. */
! UpdatePgPwdFile(sql);
/* * This goes after the UpdatePgPwdFile to be certain that two backends
--- 175,187 ---- stmt->password ? stmt->password : "''", stmt->validUntil ? stmt->validUntil :
"");
! pg_exec_query_dest(sql, dest, false);
/* * Add the stuff here for groups. */
! UpdatePgPwdFile(sql, dest);
/* * This goes after the UpdatePgPwdFile to be certain that two backends
***************
*** 196,202 ****
extern void
! AlterUser(AlterUserStmt *stmt) {
char *pg_shadow,
--- 196,202 ----
extern void
! AlterUser(AlterUserStmt *stmt, CommandDest dest) {
char *pg_shadow,
***************
*** 282,292 ****
snprintf(sql, SQL_LENGTH, "%s where usename = '%s'", sql, stmt->user);
! pg_exec_query(sql);
/* do the pg_group stuff here */
! UpdatePgPwdFile(sql);
UnlockRelation(pg_shadow_rel, AccessExclusiveLock); heap_close(pg_shadow_rel);
--- 282,292 ----
snprintf(sql, SQL_LENGTH, "%s where usename = '%s'", sql, stmt->user);
! pg_exec_query_dest(sql, dest, false);
/* do the pg_group stuff here */
! UpdatePgPwdFile(sql, dest);
UnlockRelation(pg_shadow_rel, AccessExclusiveLock); heap_close(pg_shadow_rel);
***************
*** 297,303 ****
extern void
! RemoveUser(char *user) {
char *pg_shadow;
--- 297,303 ----
extern void
! RemoveUser(char *user, CommandDest dest) {
char *pg_shadow;
***************
*** 390,396 **** elog(NOTICE, "Dropping database %s", dbase[ndbase]); snprintf(sql, SQL_LENGTH, "drop
database%s", dbase[ndbase]); pfree((void *) dbase[ndbase]);
! pg_exec_query(sql); } if (dbase) pfree((void *) dbase);
--- 390,396 ---- elog(NOTICE, "Dropping database %s", dbase[ndbase]); snprintf(sql, SQL_LENGTH, "drop
database%s", dbase[ndbase]); pfree((void *) dbase[ndbase]);
! pg_exec_query_dest(sql, dest, false); } if (dbase) pfree((void *) dbase);
***************
*** 418,426 **** */ snprintf(sql, SQL_LENGTH, "delete from %s where usename = '%s'",
ShadowRelationName,user);
! pg_exec_query(sql);
! UpdatePgPwdFile(sql);
UnlockRelation(pg_shadow_rel, AccessExclusiveLock); heap_close(pg_shadow_rel);
--- 418,426 ---- */ snprintf(sql, SQL_LENGTH, "delete from %s where usename = '%s'",
ShadowRelationName,user);
! pg_exec_query_dest(sql, dest, false);
! UpdatePgPwdFile(sql, dest);
UnlockRelation(pg_shadow_rel, AccessExclusiveLock); heap_close(pg_shadow_rel);
*** backend/commands/dbcommands.c.orig Thu Feb 18 17:00:36 1999
--- backend/commands/dbcommands.c Tue Mar 16 09:36:33 1999
***************
*** 24,30 **** #include "catalog/catname.h" #include "catalog/pg_database.h" #include "catalog/pg_shadow.h"
- #include "commands/dbcommands.h" #include "fmgr.h" #include "miscadmin.h" /* for DataDir */ #include
"storage/bufmgr.h"
--- 24,29 ----
***************
*** 31,36 ****
--- 30,36 ---- #include "storage/fd.h" #include "storage/lmgr.h" #include "tcop/tcopprot.h"
+ #include "commands/dbcommands.h" #include "utils/rel.h" #include "utils/syscache.h"
***************
*** 42,48 **** static void stop_vacuum(char *dbpath, char *dbname);
void
! createdb(char *dbname, char *dbpath, int encoding) { Oid db_id; int4 user_id;
--- 42,48 ---- static void stop_vacuum(char *dbpath, char *dbname);
void
! createdb(char *dbname, char *dbpath, int encoding, CommandDest dest) { Oid db_id; int4
user_id;
***************
*** 87,97 **** "insert into pg_database (datname, datdba, encoding, datpath)" " values ('%s',
'%d','%d', '%s');", dbname, user_id, encoding,
loc);
! pg_exec_query(buf); }
void
! destroydb(char *dbname) { int4 user_id; Oid db_id;
--- 87,97 ---- "insert into pg_database (datname, datdba, encoding, datpath)" " values ('%s',
'%d','%d', '%s');", dbname, user_id, encoding,
loc);
! pg_exec_query_dest(buf, dest, false); }
void
! destroydb(char *dbname, CommandDest dest) { int4 user_id; Oid db_id;
***************
*** 123,129 **** */ snprintf(buf, 512, "delete from pg_database where pg_database.oid =
\'%d\'::oid",
db_id);
! pg_exec_query(buf);
/* * remove the data directory. If the DELETE above failed, this will
--- 123,129 ---- */ snprintf(buf, 512, "delete from pg_database where pg_database.oid =
\'%d\'::oid",
db_id);
! pg_exec_query_dest(buf ,dest, false);
/* * remove the data directory. If the DELETE above failed, this will
*** include/commands/user.h.orig Thu Feb 18 17:01:49 1999
--- include/commands/user.h Tue Mar 16 09:23:01 1999
***************
*** 10,17 **** #ifndef USER_H #define USER_H
! extern void DefineUser(CreateUserStmt *stmt);
! extern void AlterUser(AlterUserStmt *stmt);
! extern void RemoveUser(char *user);
#endif /* USER_H */
--- 10,17 ---- #ifndef USER_H #define USER_H
! extern void DefineUser(CreateUserStmt *stmt, CommandDest);
! extern void AlterUser(AlterUserStmt *stmt, CommandDest);
! extern void RemoveUser(char *user, CommandDest);
#endif /* USER_H */
*** include/commands/dbcommands.h.orig Thu Feb 18 17:01:48 1999
--- include/commands/dbcommands.h Tue Mar 16 09:23:52 1999
***************
*** 19,25 **** */ #define SIGKILLDAEMON1 SIGTERM
! extern void createdb(char *dbname, char *dbpath, int encoding);
! extern void destroydb(char *dbname);
#endif /* DBCOMMANDS_H */
--- 19,25 ---- */ #define SIGKILLDAEMON1 SIGTERM
! extern void createdb(char *dbname, char *dbpath, int encoding,
CommandDest);
! extern void destroydb(char *dbname, CommandDest);
#endif /* DBCOMMANDS_H */
В списке pgsql-hackers по дате отправления: