summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2021-02-11 20:05:55 +0000
committerTom Lane2021-02-11 20:05:55 +0000
commit62535cae9723afc48173ba1be65f1c7491813fc2 (patch)
tree44ad4a90eb6e9cb36ba56330b8ffddb2de681f8d
parent69036aafb9a8f425fb489125b5075ba7719d20d0 (diff)
Remove dead code in ECPGconnect(), and improve documentation.
The stanza in ECPGconnect() that intended to allow specification of a Unix socket directory path in place of a port has never executed since it was committed, nearly two decades ago; the preceding strrchr() already found the last colon so there cannot be another one. The lack of complaints about that is doubtless related to the fact that no user-facing documentation suggested it was possible. Rather than try to fix that up, let's just remove the unreachable code, and instead document the way that does work to write a socket directory path, namely specifying it as a "host" option. In support of that, make another pass at clarifying the syntax documentation for ECPG connection targets, particularly documenting which things are parsed as identifiers and where to use double quotes. Rearrange some things that seemed poorly ordered, and fix a couple of minor doc errors. Kyotaro Horiguchi, per gripe from Shenhao Wang (docs changes mostly by me) Discussion: https://postgr.es/m/ae52a416bbbf459c96bab30b3038e06c@G08CNEXMBPEKD06.g08.fujitsu.local
-rw-r--r--doc/src/sgml/ecpg.sgml64
-rw-r--r--src/interfaces/ecpg/ecpglib/connect.c48
2 files changed, 52 insertions, 60 deletions
diff --git a/doc/src/sgml/ecpg.sgml b/doc/src/sgml/ecpg.sgml
index 0fef9bfcbe..9310a71166 100644
--- a/doc/src/sgml/ecpg.sgml
+++ b/doc/src/sgml/ecpg.sgml
@@ -120,7 +120,7 @@ EXEC SQL CONNECT TO <replaceable>target</replaceable> <optional>AS <replaceable>
<listitem>
<simpara>
- <literal>unix:postgresql://<replaceable>hostname</replaceable><optional>:<replaceable>port</replaceable></optional><optional>/<replaceable>dbname</replaceable></optional><optional>?<replaceable>options</replaceable></optional></literal>
+ <literal>unix:postgresql://localhost<optional>:<replaceable>port</replaceable></optional><optional>/<replaceable>dbname</replaceable></optional><optional>?<replaceable>options</replaceable></optional></literal>
</simpara>
</listitem>
@@ -143,18 +143,27 @@ EXEC SQL CONNECT TO <replaceable>target</replaceable> <optional>AS <replaceable>
</listitem>
</itemizedlist>
- If you specify the connection target literally (that is, not
- through a variable reference) and you don't quote the value, then
- the case-insensitivity rules of normal SQL are applied. In that
- case you can also double-quote the individual parameters separately
- as needed. In practice, it is probably less error-prone to use a
- (single-quoted) string literal or a variable reference. The
- connection target <literal>DEFAULT</literal> initiates a connection
+ The connection target <literal>DEFAULT</literal> initiates a connection
to the default database under the default user name. No separate
user name or connection name can be specified in that case.
</para>
<para>
+ If you specify the connection target directly (that is, not as a string
+ literal or variable reference), then the components of the target are
+ passed through normal SQL parsing; this means that, for example,
+ the <replaceable>hostname</replaceable> must look like one or more SQL
+ identifiers separated by dots, and those identifiers will be
+ case-folded unless double-quoted. Values of
+ any <replaceable>options</replaceable> must be SQL identifiers,
+ integers, or variable references. Of course, you can put nearly
+ anything into an SQL identifier by double-quoting it.
+ In practice, it is probably less error-prone to use a (single-quoted)
+ string literal or a variable reference than to write the connection
+ target directly.
+ </para>
+
+ <para>
There are also different ways to specify the user name:
<itemizedlist>
@@ -202,6 +211,15 @@ EXEC SQL CONNECT TO <replaceable>target</replaceable> <optional>AS <replaceable>
</para>
<para>
+ Notice that when specifying a socket connection
+ (with the <literal>unix:</literal> prefix), the host name must be
+ exactly <literal>localhost</literal>. To select a non-default
+ socket directory, write the directory's pathname as the value of
+ a <varname>host</varname> option in
+ the <replaceable>options</replaceable> part of the target.
+ </para>
+
+ <para>
The <replaceable>connection-name</replaceable> is used to handle
multiple connections in one program. It can be omitted if a
program uses only one connection. The most recently opened
@@ -211,23 +229,11 @@ EXEC SQL CONNECT TO <replaceable>target</replaceable> <optional>AS <replaceable>
</para>
<para>
- If untrusted users have access to a database that has not adopted a
- <link linkend="ddl-schemas-patterns">secure schema usage pattern</link>,
- begin each session by removing publicly-writable schemas
- from <varname>search_path</varname>. For example,
- add <literal>options=-c search_path=</literal>
- to <literal><replaceable>options</replaceable></literal>, or
- issue <literal>EXEC SQL SELECT pg_catalog.set_config('search_path', '',
- false);</literal> after connecting. This consideration is not specific to
- ECPG; it applies to every interface for executing arbitrary SQL commands.
- </para>
-
- <para>
Here are some examples of <command>CONNECT</command> statements:
<programlisting>
EXEC SQL CONNECT TO [email protected];
-EXEC SQL CONNECT TO unix:postgresql://sql.mydomain.com/mydb AS myconnection USER john;
+EXEC SQL CONNECT TO tcp:postgresql://sql.mydomain.com/mydb AS myconnection USER john;
EXEC SQL BEGIN DECLARE SECTION;
const char *target = "[email protected]";
@@ -238,8 +244,8 @@ EXEC SQL END DECLARE SECTION;
EXEC SQL CONNECT TO :target USER :user USING :passwd;
/* or EXEC SQL CONNECT TO :target USER :user/:passwd; */
</programlisting>
- The last form makes use of the variant referred to above as
- character variable reference. You will see in later sections how C
+ The last example makes use of the feature referred to above as
+ character variable references. You will see in later sections how C
variables can be used in SQL statements when you prefix them with a
colon.
</para>
@@ -251,6 +257,18 @@ EXEC SQL CONNECT TO :target USER :user USING :passwd;
example above to encapsulate the connection target string
somewhere.
</para>
+
+ <para>
+ If untrusted users have access to a database that has not adopted a
+ <link linkend="ddl-schemas-patterns">secure schema usage pattern</link>,
+ begin each session by removing publicly-writable schemas
+ from <varname>search_path</varname>. For example,
+ add <literal>options=-c search_path=</literal>
+ to <literal><replaceable>options</replaceable></literal>, or
+ issue <literal>EXEC SQL SELECT pg_catalog.set_config('search_path', '',
+ false);</literal> after connecting. This consideration is not specific to
+ ECPG; it applies to every interface for executing arbitrary SQL commands.
+ </para>
</sect2>
<sect2 id="ecpg-set-connection">
diff --git a/src/interfaces/ecpg/ecpglib/connect.c b/src/interfaces/ecpg/ecpglib/connect.c
index 6b0a3067e6..60564b176c 100644
--- a/src/interfaces/ecpg/ecpglib/connect.c
+++ b/src/interfaces/ecpg/ecpglib/connect.c
@@ -360,8 +360,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
/*------
* new style:
- * <tcp|unix>:postgresql://server[:port|:/unixsocket/path:]
- * [/db-name][?options]
+ * <tcp|unix>:postgresql://server[:port][/db-name][?options]
*------
*/
offset += strlen("postgresql://");
@@ -385,46 +384,22 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
}
tmp = strrchr(dbname + offset, ':');
- if (tmp != NULL) /* port number or Unix socket path given */
+ if (tmp != NULL) /* port number given */
{
- char *tmp2;
-
*tmp = '\0';
- if ((tmp2 = strchr(tmp + 1, ':')) != NULL)
- {
- *tmp2 = '\0';
- host = ecpg_strdup(tmp + 1, lineno);
- connect_params++;
- if (strncmp(dbname, "unix:", 5) != 0)
- {
- ecpg_log("ECPGconnect: socketname %s given for TCP connection on line %d\n", host, lineno);
- ecpg_raise(lineno, ECPG_CONNECT, ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION, realname ? realname : ecpg_gettext("<DEFAULT>"));
- if (host)
- ecpg_free(host);
-
- /*
- * port not set yet if (port) ecpg_free(port);
- */
- if (options)
- ecpg_free(options);
- if (realname)
- ecpg_free(realname);
- if (dbname)
- ecpg_free(dbname);
- free(this);
- return false;
- }
- }
- else
- {
- port = ecpg_strdup(tmp + 1, lineno);
- connect_params++;
- }
+ port = ecpg_strdup(tmp + 1, lineno);
+ connect_params++;
}
if (strncmp(dbname, "unix:", 5) == 0)
{
- if (strcmp(dbname + offset, "localhost") != 0 && strcmp(dbname + offset, "127.0.0.1") != 0)
+ /*
+ * The alternative of using "127.0.0.1" here is deprecated
+ * and undocumented; we'll keep it for backward
+ * compatibility's sake, but not extend it to allow IPv6.
+ */
+ if (strcmp(dbname + offset, "localhost") != 0 &&
+ strcmp(dbname + offset, "127.0.0.1") != 0)
{
ecpg_log("ECPGconnect: non-localhost access via sockets on line %d\n", lineno);
ecpg_raise(lineno, ECPG_CONNECT, ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION, realname ? realname : ecpg_gettext("<DEFAULT>"));
@@ -450,7 +425,6 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
connect_params++;
}
}
-
}
}
else