From: Tom Lane Date: Fri, 5 Mar 2004 01:53:59 +0000 (+0000) Subject: libpq's query to get the OIDs of large-object support functions was not X-Git-Tag: REL8_0_0BETA1~1069 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=44611f6e6d2cd11ac2c6dc1f41c13a98ec633f08;p=postgresql libpq's query to get the OIDs of large-object support functions was not schema-safe. Make it so, and improve the internal support for knowledge of server version. --- diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c index eae1b764ab..d2ad75bb23 100644 --- a/src/interfaces/libpq/fe-exec.c +++ b/src/interfaces/libpq/fe-exec.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/interfaces/libpq/fe-exec.c,v 1.156 2003/12/28 17:29:41 tgl Exp $ + * $PostgreSQL: pgsql/src/interfaces/libpq/fe-exec.c,v 1.157 2004/03/05 01:53:59 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -609,12 +609,28 @@ pqSaveParameterStatus(PGconn *conn, const char *name, const char *value) /* * Special hacks: remember client_encoding as a numeric value, and - * remember at least the first few bytes of server version. + * convert server version to a numeric form as well. */ if (strcmp(name, "client_encoding") == 0) conn->client_encoding = pg_char_to_encoding(value); - if (strcmp(name, "server_version") == 0) - StrNCpy(conn->sversion, value, sizeof(conn->sversion)); + else if (strcmp(name, "server_version") == 0) + { + int cnt; + int vmaj, + vmin, + vrev; + + cnt = sscanf(value, "%d.%d.%d", &vmaj, &vmin, &vrev); + + if (cnt < 2) + conn->sversion = 0; /* unknown */ + else + { + if (cnt == 2) + vrev = 0; + conn->sversion = (100 * vmaj + vmin) * 100 + vrev; + } + } } diff --git a/src/interfaces/libpq/fe-lobj.c b/src/interfaces/libpq/fe-lobj.c index 16d4970d9e..e9ef61358a 100644 --- a/src/interfaces/libpq/fe-lobj.c +++ b/src/interfaces/libpq/fe-lobj.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/interfaces/libpq/fe-lobj.c,v 1.47 2004/01/26 22:35:32 tgl Exp $ + * $PostgreSQL: pgsql/src/interfaces/libpq/fe-lobj.c,v 1.48 2004/03/05 01:53:59 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -534,6 +534,7 @@ lo_initialize(PGconn *conn) PGresult *res; PGlobjfuncs *lobjfuncs; int n; + const char *query; const char *fname; Oid foid; @@ -550,17 +551,34 @@ lo_initialize(PGconn *conn) MemSet((char *) lobjfuncs, 0, sizeof(PGlobjfuncs)); /* - * Execute the query to get all the functions at once + * Execute the query to get all the functions at once. In 7.3 and later + * we need to be schema-safe. */ - res = PQexec(conn, "select proname, oid from pg_proc \ - where proname = 'lo_open' \ - or proname = 'lo_close' \ - or proname = 'lo_creat' \ - or proname = 'lo_unlink' \ - or proname = 'lo_lseek' \ - or proname = 'lo_tell' \ - or proname = 'loread' \ - or proname = 'lowrite'"); + if (conn->sversion >= 70300) + query = "select proname, oid from pg_catalog.pg_proc " + "where proname in (" + "'lo_open', " + "'lo_close', " + "'lo_creat', " + "'lo_unlink', " + "'lo_lseek', " + "'lo_tell', " + "'loread', " + "'lowrite') " + "and pronamespace = (select oid from pg_catalog.pg_namespace " + "where nspname = 'pg_catalog')"; + else + query = "select proname, oid from pg_proc " + "where proname = 'lo_open' " + "or proname = 'lo_close' " + "or proname = 'lo_creat' " + "or proname = 'lo_unlink' " + "or proname = 'lo_lseek' " + "or proname = 'lo_tell' " + "or proname = 'loread' " + "or proname = 'lowrite'"; + + res = PQexec(conn, query); if (res == NULL) { free(lobjfuncs); diff --git a/src/interfaces/libpq/fe-protocol2.c b/src/interfaces/libpq/fe-protocol2.c index 8c214fa8e9..369481b338 100644 --- a/src/interfaces/libpq/fe-protocol2.c +++ b/src/interfaces/libpq/fe-protocol2.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/interfaces/libpq/fe-protocol2.c,v 1.9 2003/11/29 19:52:12 pgsql Exp $ + * $PostgreSQL: pgsql/src/interfaces/libpq/fe-protocol2.c,v 1.10 2004/03/05 01:53:59 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -178,7 +178,9 @@ pqSetenvPoll(PGconn *conn) * default in a 7.3 server. * * Note: version() exists in all - * protocol-2.0-supporting backends. + * protocol-2.0-supporting backends. In 7.3 it would + * be safer to write pg_catalog.version(), but we can't + * do that without causing problems on older versions. */ if (!PQsendQuery(conn, "begin; select version(); end")) goto error_return; @@ -258,8 +260,9 @@ pqSetenvPoll(PGconn *conn) * in 7.3 servers where we need to prevent * autocommit-off from starting a transaction anyway. */ - if (strncmp(conn->sversion, "7.3", 3) == 0) - query = "begin; select pg_client_encoding(); end"; + if (conn->sversion >= 70300 && + conn->sversion < 70400) + query = "begin; select pg_catalog.pg_client_encoding(); end"; else query = "select pg_client_encoding()"; if (!PQsendQuery(conn, query)) diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h index 97cd55eaa8..f2acf2af20 100644 --- a/src/interfaces/libpq/libpq-int.h +++ b/src/interfaces/libpq/libpq-int.h @@ -12,7 +12,7 @@ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/interfaces/libpq/libpq-int.h,v 1.84 2004/01/09 02:02:43 momjian Exp $ + * $PostgreSQL: pgsql/src/interfaces/libpq/libpq-int.h,v 1.85 2004/03/05 01:53:59 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -280,7 +280,7 @@ struct pg_conn SockAddr laddr; /* Local address */ SockAddr raddr; /* Remote address */ ProtocolVersion pversion; /* FE/BE protocol version in use */ - char sversion[8]; /* The first few bytes of server version */ + int sversion; /* server version, e.g. 70401 for 7.4.1 */ /* Transient state needed while establishing connection */ struct addrinfo *addrlist; /* list of possible backend addresses */