]> granicus.if.org Git - postgresql/commitdiff
Fix libpq startup code to work correctly in autocommit off mode.
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 15 Oct 2002 01:48:25 +0000 (01:48 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 15 Oct 2002 01:48:25 +0000 (01:48 +0000)
In passing, fix breakage for case where PGCLIENTENCODING is set in
environment.

src/interfaces/libpq/fe-connect.c

index 53d79f632c794a99f04f536a8445c00c4124940f..0104057584645b8a39dceb263470b6250111c5e4 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.209 2002/10/14 17:15:11 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.210 2002/10/15 01:48:25 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1583,8 +1583,6 @@ PQsetenvPoll(PGconn *conn)
 {
        PGresult   *res;
 
-       static const char envname[] = "PGCLIENTENCODING";
-
        if (conn == NULL || conn->status == CONNECTION_BAD)
                return PGRES_POLLING_FAILED;
 
@@ -1625,25 +1623,23 @@ PQsetenvPoll(PGconn *conn)
                        goto error_return;
        }
 
-
-keep_going:                                            /* We will come back to here until there
-                                                                * is nothing left to parse. */
-       switch (conn->setenv_state)
+       /* We will loop here until there is nothing left to do in this call. */
+       for (;;)
        {
-
-               case SETENV_STATE_ENCODINGS_SEND:
+               switch (conn->setenv_state)
+               {
+                       case SETENV_STATE_ENCODINGS_SEND:
                        {
-                               const char *env;
+                               const char *env = getenv("PGCLIENTENCODING");
 
-                               env = getenv(envname);
                                if (!env || *env == '\0')
                                {
                                        /*
-                                        * query server encoding if PGCLIENTENCODING is not
-                                        * specified
+                                        * PGCLIENTENCODING is not specified, so query server
+                                        * for it.  We must use begin/commit in case autocommit
+                                        * is off by default.
                                         */
-                                       if (!PQsendQuery(conn,
-                                                                        "select getdatabaseencoding()"))
+                                       if (!PQsendQuery(conn, "begin; select getdatabaseencoding(); commit"))
                                                goto error_return;
 
                                        conn->setenv_state = SETENV_STATE_ENCODINGS_WAIT;
@@ -1662,11 +1658,14 @@ keep_going:                                             /* We will come back to here until there
                                                goto error_return;
                                        }
                                        conn->client_encoding = encoding;
-                               }
 
+                                       /* Move on to setting the environment options */
+                                       conn->setenv_state = SETENV_STATE_OPTION_SEND;
+                               }
+                               break;
                        }
 
-               case SETENV_STATE_ENCODINGS_WAIT:
+                       case SETENV_STATE_ENCODINGS_WAIT:
                        {
                                if (PQisBusy(conn))
                                        return PGRES_POLLING_READING;
@@ -1675,37 +1674,35 @@ keep_going:                                             /* We will come back to here until there
 
                                if (res)
                                {
-                                       char       *encoding;
+                                       if (PQresultStatus(res) == PGRES_TUPLES_OK)
+                                       {
+                                               /* set client encoding in pg_conn struct */
+                                               char       *encoding;
 
-                                       if (PQresultStatus(res) != PGRES_TUPLES_OK)
+                                               encoding = PQgetvalue(res, 0, 0);
+                                               if (!encoding)          /* this should not happen */
+                                                       conn->client_encoding = PG_SQL_ASCII;
+                                               else
+                                                       conn->client_encoding = pg_char_to_encoding(encoding);
+                                       }
+                                       else if (PQresultStatus(res) != PGRES_COMMAND_OK)
                                        {
                                                PQclear(res);
                                                goto error_return;
                                        }
-
-                                       /* set client encoding in pg_conn struct */
-                                       encoding = PQgetvalue(res, 0, 0);
-                                       if (!encoding)          /* this should not happen */
-                                               conn->client_encoding = PG_SQL_ASCII;
-                                       else
-                                               conn->client_encoding = pg_char_to_encoding(encoding);
                                        PQclear(res);
-
-                                       /*
-                                        * We have to keep going in order to clear up the
-                                        * query
-                                        */
-                                       goto keep_going;
+                                       /* Keep reading until PQgetResult returns NULL */
                                }
-
-                               /* NULL result indicates that the query is finished */
-
-                               /* Move on to setting the environment options */
-                               conn->setenv_state = SETENV_STATE_OPTION_SEND;
-                               goto keep_going;
+                               else
+                               {
+                                       /* NULL result indicates that the query is finished */
+                                       /* Move on to setting the environment options */
+                                       conn->setenv_state = SETENV_STATE_OPTION_SEND;
+                               }
+                               break;
                        }
 
-               case SETENV_STATE_OPTION_SEND:
+                       case SETENV_STATE_OPTION_SEND:
                        {
                                /* Send an Environment Option */
                                char            setQuery[100];          /* note length limits in
@@ -1740,11 +1737,10 @@ keep_going:                                             /* We will come back to here until there
                                        /* No more options to send, so we are done. */
                                        conn->setenv_state = SETENV_STATE_IDLE;
                                }
-
-                               goto keep_going;
+                               break;
                        }
 
-               case SETENV_STATE_OPTION_WAIT:
+                       case SETENV_STATE_OPTION_WAIT:
                        {
                                if (PQisBusy(conn))
                                        return PGRES_POLLING_READING;
@@ -1758,33 +1754,29 @@ keep_going:                                             /* We will come back to here until there
                                                PQclear(res);
                                                goto error_return;
                                        }
-                                       /* Don't need the result */
                                        PQclear(res);
-
-                                       /*
-                                        * We have to keep going in order to clear up the
-                                        * query
-                                        */
-                                       goto keep_going;
+                                       /* Keep reading until PQgetResult returns NULL */
                                }
-
-                               /* NULL result indicates that the query is finished */
-
-                               /* Send the next option */
-                               conn->next_eo++;
-                               conn->setenv_state = SETENV_STATE_OPTION_SEND;
-                               goto keep_going;
+                               else
+                               {
+                                       /* NULL result indicates that the query is finished */
+                                       /* Send the next option */
+                                       conn->next_eo++;
+                                       conn->setenv_state = SETENV_STATE_OPTION_SEND;
+                               }
+                               break;
                        }
 
-               case SETENV_STATE_IDLE:
-                       return PGRES_POLLING_OK;
+                       case SETENV_STATE_IDLE:
+                               return PGRES_POLLING_OK;
 
-               default:
-                       printfPQExpBuffer(&conn->errorMessage,
-                                                         libpq_gettext("invalid state %c, "
-                                                  "probably indicative of memory corruption\n"),
-                                                         conn->setenv_state);
-                       goto error_return;
+                       default:
+                               printfPQExpBuffer(&conn->errorMessage,
+                                                                 libpq_gettext("invalid state %c, "
+                                                                                               "probably indicative of memory corruption\n"),
+                                                                 conn->setenv_state);
+                               goto error_return;
+               }
        }
 
        /* Unreachable */