libpq's query to get the OIDs of large-object support functions was not
authorTom Lane <[email protected]>
Fri, 5 Mar 2004 01:54:13 +0000 (01:54 +0000)
committerTom Lane <[email protected]>
Fri, 5 Mar 2004 01:54:13 +0000 (01:54 +0000)
schema-safe.  Make it so, and improve the internal support for knowledge
of server version.

src/interfaces/libpq/fe-exec.c
src/interfaces/libpq/fe-lobj.c
src/interfaces/libpq/fe-protocol2.c
src/interfaces/libpq/libpq-int.h

index 8b22d5ef8cc6d3e682467782d151f5e7e249537c..5a6d651bcd45f4ef425bd856d7bae5b05b854c08 100644 (file)
@@ -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;
+               }
+       }
 }
 
 
index 7ed7a0c8ef621c5fb96f67d9b697b722cc492319..d2f94c11ffbf6fab7bb59017dbf359b466be223f 100644 (file)
@@ -527,6 +527,7 @@ lo_initialize(PGconn *conn)
        PGresult   *res;
        PGlobjfuncs *lobjfuncs;
        int                     n;
+       const char *query;
        const char *fname;
        Oid                     foid;
 
@@ -543,18 +544,35 @@ 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 (res == (PGresult *) NULL)
+       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);
                return -1;
index cdc089d374f94e167057b1343aa212a249c93612..6d1462655084a7b7da6737d98c1766c6f427b6a1 100644 (file)
@@ -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))
index d97bc57c122203ca8c750698a422c294a1bbddf8..18800ae1940f57fe52c71b08425d644c69f4027b 100644 (file)
@@ -277,7 +277,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 */