Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
9ceb5d8a
Commit
9ceb5d8a
authored
Feb 07, 2000
by
Peter Eisentraut
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixed psql double quoting of SQL ids
Fixed libpq printing functions
parent
4842ef86
Changes
29
Show whitespace changes
Inline
Side-by-side
Showing
29 changed files
with
1044 additions
and
767 deletions
+1044
-767
doc/src/sgml/libpq.sgml
doc/src/sgml/libpq.sgml
+25
-25
doc/src/sgml/ref/psql-ref.sgml
doc/src/sgml/ref/psql-ref.sgml
+89
-78
src/bin/psql/command.c
src/bin/psql/command.c
+581
-363
src/bin/psql/common.c
src/bin/psql/common.c
+12
-16
src/bin/psql/create_help.pl
src/bin/psql/create_help.pl
+8
-1
src/bin/psql/describe.c
src/bin/psql/describe.c
+31
-31
src/bin/psql/help.c
src/bin/psql/help.c
+52
-63
src/bin/psql/input.c
src/bin/psql/input.c
+10
-8
src/bin/psql/input.h
src/bin/psql/input.h
+3
-3
src/bin/psql/large_obj.c
src/bin/psql/large_obj.c
+3
-3
src/bin/psql/mainloop.c
src/bin/psql/mainloop.c
+6
-4
src/bin/psql/print.c
src/bin/psql/print.c
+4
-2
src/bin/psql/prompt.c
src/bin/psql/prompt.c
+11
-8
src/bin/psql/prompt.h
src/bin/psql/prompt.h
+3
-2
src/bin/psql/startup.c
src/bin/psql/startup.c
+97
-67
src/bin/psql/stringutils.c
src/bin/psql/stringutils.c
+9
-11
src/bin/psql/stringutils.h
src/bin/psql/stringutils.h
+2
-2
src/bin/psql/tab-complete.c
src/bin/psql/tab-complete.c
+2
-4
src/interfaces/libpq/fe-auth.c
src/interfaces/libpq/fe-auth.c
+5
-1
src/interfaces/libpq/fe-connect.c
src/interfaces/libpq/fe-connect.c
+10
-9
src/interfaces/libpq/fe-exec.c
src/interfaces/libpq/fe-exec.c
+13
-13
src/interfaces/libpq/fe-lobj.c
src/interfaces/libpq/fe-lobj.c
+2
-2
src/interfaces/libpq/fe-misc.c
src/interfaces/libpq/fe-misc.c
+3
-1
src/interfaces/libpq/fe-print.c
src/interfaces/libpq/fe-print.c
+16
-5
src/interfaces/libpq/libpq-fe.h
src/interfaces/libpq/libpq-fe.h
+25
-30
src/interfaces/libpq/libpq-int.h
src/interfaces/libpq/libpq-int.h
+6
-1
src/interfaces/libpq/pqexpbuffer.c
src/interfaces/libpq/pqexpbuffer.c
+8
-8
src/interfaces/libpq/pqexpbuffer.h
src/interfaces/libpq/pqexpbuffer.h
+5
-5
src/interfaces/libpq/win32.h
src/interfaces/libpq/win32.h
+3
-1
No files found.
doc/src/sgml/libpq.sgml
View file @
9ceb5d8a
...
@@ -494,7 +494,7 @@ soon.)
...
@@ -494,7 +494,7 @@ soon.)
<function>PQdb</function>
<function>PQdb</function>
Returns the database name of the connection.
Returns the database name of the connection.
<synopsis>
<synopsis>
c
onst c
har *PQdb(const PGconn *conn)
char *PQdb(const PGconn *conn)
</synopsis>
</synopsis>
PQdb and the next several functions return the values established
PQdb and the next several functions return the values established
at connection. These values are fixed for the life of the PGconn
at connection. These values are fixed for the life of the PGconn
...
@@ -507,7 +507,7 @@ object.
...
@@ -507,7 +507,7 @@ object.
<function>PQuser</function>
<function>PQuser</function>
Returns the user name of the connection.
Returns the user name of the connection.
<synopsis>
<synopsis>
c
onst c
har *PQuser(const PGconn *conn)
char *PQuser(const PGconn *conn)
</synopsis>
</synopsis>
</para>
</para>
</listitem>
</listitem>
...
@@ -517,7 +517,7 @@ const char *PQuser(const PGconn *conn)
...
@@ -517,7 +517,7 @@ const char *PQuser(const PGconn *conn)
<function>PQpass</function>
<function>PQpass</function>
Returns the password of the connection.
Returns the password of the connection.
<synopsis>
<synopsis>
c
onst c
har *PQpass(const PGconn *conn)
char *PQpass(const PGconn *conn)
</synopsis>
</synopsis>
</para>
</para>
</listitem>
</listitem>
...
@@ -527,7 +527,7 @@ const char *PQpass(const PGconn *conn)
...
@@ -527,7 +527,7 @@ const char *PQpass(const PGconn *conn)
<function>PQhost</function>
<function>PQhost</function>
Returns the server host name of the connection.
Returns the server host name of the connection.
<synopsis>
<synopsis>
c
onst c
har *PQhost(const PGconn *conn)
char *PQhost(const PGconn *conn)
</synopsis>
</synopsis>
</para>
</para>
</listitem>
</listitem>
...
@@ -537,7 +537,7 @@ const char *PQhost(const PGconn *conn)
...
@@ -537,7 +537,7 @@ const char *PQhost(const PGconn *conn)
<function>PQport</function>
<function>PQport</function>
Returns the port of the connection.
Returns the port of the connection.
<synopsis>
<synopsis>
c
onst c
har *PQport(const PGconn *conn)
char *PQport(const PGconn *conn)
</synopsis>
</synopsis>
</para>
</para>
</listitem>
</listitem>
...
@@ -547,7 +547,7 @@ const char *PQport(const PGconn *conn)
...
@@ -547,7 +547,7 @@ const char *PQport(const PGconn *conn)
<function>PQtty</function>
<function>PQtty</function>
Returns the debug tty of the connection.
Returns the debug tty of the connection.
<synopsis>
<synopsis>
c
onst c
har *PQtty(const PGconn *conn)
char *PQtty(const PGconn *conn)
</synopsis>
</synopsis>
</para>
</para>
</listitem>
</listitem>
...
@@ -557,7 +557,7 @@ const char *PQtty(const PGconn *conn)
...
@@ -557,7 +557,7 @@ const char *PQtty(const PGconn *conn)
<function>PQoptions</function>
<function>PQoptions</function>
Returns the backend options used in the connection.
Returns the backend options used in the connection.
<synopsis>
<synopsis>
c
onst c
har *PQoptions(const PGconn *conn)
char *PQoptions(const PGconn *conn)
</synopsis>
</synopsis>
</para>
</para>
</listitem>
</listitem>
...
@@ -602,7 +602,7 @@ ConnStatusType PQstatus(const PGconn *conn)
...
@@ -602,7 +602,7 @@ ConnStatusType PQstatus(const PGconn *conn)
Returns the error message most recently generated by
Returns the error message most recently generated by
an operation on the connection.
an operation on the connection.
<synopsis>
<synopsis>
c
onst c
har *PQerrorMessage(const PGconn* conn);
char *PQerrorMessage(const PGconn* conn);
</synopsis>
</synopsis>
</para>
</para>
...
@@ -790,7 +790,7 @@ exposes a bug in the client software.
...
@@ -790,7 +790,7 @@ exposes a bug in the client software.
Converts the enumerated type returned by PQresultStatus into
Converts the enumerated type returned by PQresultStatus into
a string constant describing the status code.
a string constant describing the status code.
<synopsis>
<synopsis>
c
onst c
har *PQresStatus(ExecStatusType status);
char *PQresStatus(ExecStatusType status);
</synopsis>
</synopsis>
</para>
</para>
</listitem>
</listitem>
...
@@ -801,7 +801,7 @@ const char *PQresStatus(ExecStatusType status);
...
@@ -801,7 +801,7 @@ const char *PQresStatus(ExecStatusType status);
returns the error message associated with the query, or an empty string
returns the error message associated with the query, or an empty string
if there was no error.
if there was no error.
<synopsis>
<synopsis>
c
onst c
har *PQresultErrorMessage(const PGresult *res);
char *PQresultErrorMessage(const PGresult *res);
</synopsis>
</synopsis>
Immediately following a <function>PQexec</function> or <function>PQgetResult</function>
Immediately following a <function>PQexec</function> or <function>PQgetResult</function>
call, <function>PQerrorMessage</function> (on the connection) will return the same
call, <function>PQerrorMessage</function> (on the connection) will return the same
...
@@ -855,7 +855,7 @@ extracts data from a <acronym>BINARY</acronym> cursor.
...
@@ -855,7 +855,7 @@ extracts data from a <acronym>BINARY</acronym> cursor.
Returns the field (attribute) name associated with the given field index.
Returns the field (attribute) name associated with the given field index.
Field indices start at 0.
Field indices start at 0.
<synopsis>
<synopsis>
c
onst c
har *PQfname(const PGresult *res,
char *PQfname(const PGresult *res,
int field_index);
int field_index);
</synopsis>
</synopsis>
</para>
</para>
...
@@ -931,7 +931,7 @@ int PQfmod(const PGresult *res,
...
@@ -931,7 +931,7 @@ int PQfmod(const PGresult *res,
of a PGresult.
of a PGresult.
Tuple and field indices start at 0.
Tuple and field indices start at 0.
<synopsis>
<synopsis>
c
onst c
har* PQgetvalue(const PGresult *res,
char* PQgetvalue(const PGresult *res,
int tup_num,
int tup_num,
int field_num);
int field_num);
</synopsis>
</synopsis>
...
@@ -991,7 +991,7 @@ int PQgetisnull(const PGresult *res,
...
@@ -991,7 +991,7 @@ int PQgetisnull(const PGresult *res,
Returns the command status string from the SQL command that
Returns the command status string from the SQL command that
generated the PGresult.
generated the PGresult.
<synopsis>
<synopsis>
c
onst c
har * PQcmdStatus(const PGresult *res);
char * PQcmdStatus(const PGresult *res);
</synopsis>
</synopsis>
</para>
</para>
</listitem>
</listitem>
...
@@ -1001,7 +1001,7 @@ const char * PQcmdStatus(const PGresult *res);
...
@@ -1001,7 +1001,7 @@ const char * PQcmdStatus(const PGresult *res);
<function>PQcmdTuples</function>
<function>PQcmdTuples</function>
Returns the number of rows affected by the SQL command.
Returns the number of rows affected by the SQL command.
<synopsis>
<synopsis>
c
onst c
har * PQcmdTuples(const PGresult *res);
char * PQcmdTuples(const PGresult *res);
</synopsis>
</synopsis>
If the <acronym>SQL</acronym> command that generated the
If the <acronym>SQL</acronym> command that generated the
PGresult was INSERT, UPDATE or DELETE, this returns a
PGresult was INSERT, UPDATE or DELETE, this returns a
...
@@ -1032,7 +1032,7 @@ Oid PQoidValue(const PGresult *res);
...
@@ -1032,7 +1032,7 @@ Oid PQoidValue(const PGresult *res);
inserted, if the <acronym>SQL</acronym> command was an INSERT.
inserted, if the <acronym>SQL</acronym> command was an INSERT.
Otherwise, returns an empty string.
Otherwise, returns an empty string.
<synopsis>
<synopsis>
c
onst c
har * PQoidStatus(const PGresult *res);
char * PQoidStatus(const PGresult *res);
</synopsis>
</synopsis>
The function is deprecated in favor of <function>PQoidValue</function>
The function is deprecated in favor of <function>PQoidValue</function>
and is not thread-safe.
and is not thread-safe.
...
@@ -1050,25 +1050,25 @@ void PQprint(FILE* fout, /* output stream */
...
@@ -1050,25 +1050,25 @@ void PQprint(FILE* fout, /* output stream */
const PQprintOpt *po);
const PQprintOpt *po);
struct {
struct {
int
header; /* print output field headings and row count */
pqbool
header; /* print output field headings and row count */
int
align; /* fill align the fields */
pqbool
align; /* fill align the fields */
int
standard; /* old brain dead format */
pqbool
standard; /* old brain dead format */
int
html3; /* output html tables */
pqbool
html3; /* output html tables */
int
expanded; /* expand tables */
pqbool
expanded; /* expand tables */
int
pager; /* use pager for output if needed */
pqbool
pager; /* use pager for output if needed */
char *fieldSep; /* field separator */
char *fieldSep; /* field separator */
char *tableOpt; /* insert to HTML <table ...> */
char *tableOpt; /* insert to HTML <table ...> */
char *caption; /* HTML <caption> */
char *caption; /* HTML <caption> */
char **fieldName; /* null terminated array of replacement field names */
char **fieldName; /* null terminated array of replacement field names */
} PQprintOpt;
} PQprintOpt;
</synopsis>
</synopsis>
This function was formerly used by <application>psql</application>
This function was formerly used by <application>psql</application>
to print query results, but this is no longer the case and this
to print query results, but this is no longer the case and this
function is no longer supported.
function is no longer
actively
supported.
</para>
</para>
</listitem>
</listitem>
</listitem>
<listitem>
<listitem>
<para>
<para>
<function>PQclear</function>
<function>PQclear</function>
...
...
doc/src/sgml/ref/psql-ref.sgml
View file @
9ceb5d8a
<!--
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/psql-ref.sgml,v 1.2
2 2000/01/29 16:58:27
petere Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/psql-ref.sgml,v 1.2
3 2000/02/07 23:10:03
petere Exp $
Postgres documentation
Postgres documentation
-->
-->
...
@@ -64,8 +64,8 @@ Postgres documentation
...
@@ -64,8 +64,8 @@ Postgres documentation
<para>
<para>
<application>psql</application> is a regular <productname>PostgreSQL</productname>
<application>psql</application> is a regular <productname>PostgreSQL</productname>
client application. In order to connect to a database you need to
determin
e
client application. In order to connect to a database you need to
know th
e
name of you target database, the hostname and port number of the server
name of you
r
target database, the hostname and port number of the server
and what user name you want to connect as. <application>psql</application> can be
and what user name you want to connect as. <application>psql</application> can be
told about those parameters via command line options, namely <option>-d</option>,
told about those parameters via command line options, namely <option>-d</option>,
<option>-h</option>, <option>-p</option>, and <option>-U</option> respectively.
<option>-h</option>, <option>-p</option>, and <option>-U</option> respectively.
...
@@ -119,7 +119,7 @@ testdb=>
...
@@ -119,7 +119,7 @@ testdb=>
Ordinarily, input lines are sent to the backend when a query-terminating
Ordinarily, input lines are sent to the backend when a query-terminating
semicolon is reached. An end of line does not terminate a query! Thus queries
semicolon is reached. An end of line does not terminate a query! Thus queries
can be spread over serveral lines for clarity. If the query was sent and without
can be spread over serveral lines for clarity. If the query was sent and without
error the query results are displayed on the screen.
error
,
the query results are displayed on the screen.
</para>
</para>
<para>
<para>
...
@@ -155,31 +155,35 @@ testdb=>
...
@@ -155,31 +155,35 @@ testdb=>
</para>
</para>
<para>
<para>
To include whitespace into an argument you must quote it with either single
To include whitespace into an argument you must quote it with a single
or double quotes. Anything contained in single quotes (except for a
quote. To include a single quote into such an argument, preceed it by
backslash-escaped single quote itself) is taken literally as the argument.
a backslash. Anything contained in single quotes is furthermore subject to
Anything contained in double quotes is furthermore subject to C-like
C-like substitutions for <literal>\n</literal> (new line), <literal>\t</literal>
substitutions for <literal>\n</literal> (new line), <literal>\t</literal> (tab),
(tab), <literal>\</literal><replaceable>digits</replaceable>,
<literal>\</literal><replaceable>digits</replaceable>,
<literal>\0</literal><replaceable>digits</replaceable>, and
<literal>\0</literal><replaceable>digits</replaceable>, and
<literal>\0x</literal><replaceable>digits</replaceable>
<literal>\0x</literal><replaceable>digits</replaceable>
(the character with the given decimal, octal, or hexadecimal code).
(the character with the given decimal, octal, or hexadecimal code).
</para>
</para>
<para>
<para>
If an unquoted argument begins with a
dollar sign (<literal>$
</literal>),
If an unquoted argument begins with a
colon (<literal>:
</literal>),
it is taken as a variable and the value of the variable is taken as the
it is taken as a variable and the value of the variable is taken as the
argument instead. Inside double quotes, variable values can be substituted
argument instead.
by enclosing the name in a <literal>${...}</literal> sequence. See also under
<quote><xref linkend="APP-PSQL-variables" endterm="APP-PSQL-variables-title"></quote>.
</para>
</para>
<para>
<para>
Arguments that are quoted in <quote>back-ticks</quote> (<literal>`</literal>)
Arguments that are quoted in <quote>backticks</quote> (<literal>`</literal>)
are taken as a command line
are taken as a command line that is passed to the shell. The output of the
that is passed to the shell. The output of the command (with a trailing
command (with a trailing newline removed) is taken as the argument value.
newline removed) is taken as the argument value. Back-ticks are subject to
The above escape sequences also apply in backticks.
the same substitution rules as double-quotes.
</para>
<para>
Some commands take the name of an <acronym>SQL</acronym> identifier (such as
a table name) as argument. These arguments follow the syntax rules of
<acronym>SQL</acronym> regarding double quotes: an identifier without
double quotes is coerced to lower-case. For all other commands
double quotes are not special and will become part of the argument.
</para>
</para>
<para>
<para>
...
@@ -189,7 +193,7 @@ testdb=>
...
@@ -189,7 +193,7 @@ testdb=>
(two backslashes) marks the end of arguments and continues parsing
(two backslashes) marks the end of arguments and continues parsing
<acronym>SQL</acronym> queries, if any. That way <acronym>SQL</acronym> and
<acronym>SQL</acronym> queries, if any. That way <acronym>SQL</acronym> and
<application>psql</application> commands can be freely mixed on a line.
<application>psql</application> commands can be freely mixed on a line.
I
n any case, the arguments of a meta-command cannot continue beyond the end
But i
n any case, the arguments of a meta-command cannot continue beyond the end
of the line.
of the line.
</para>
</para>
...
@@ -246,7 +250,7 @@ testdb=>
...
@@ -246,7 +250,7 @@ testdb=>
<para>
<para>
If the connection attempt failed (wrong username, access denied, etc.) the
If the connection attempt failed (wrong username, access denied, etc.) the
previous connection will be kept
,
if and only if <application>psql</application> is
previous connection will be kept if and only if <application>psql</application> is
in interactive mode. When executing a non-interactive script, processing
in interactive mode. When executing a non-interactive script, processing
will immediately stop with an error. This distinction was chosen as a user
will immediately stop with an error. This distinction was chosen as a user
convenience against typos on the one hand, and a safety mechanism that
convenience against typos on the one hand, and a safety mechanism that
...
@@ -286,7 +290,7 @@ testdb=>
...
@@ -286,7 +290,7 @@ testdb=>
<para>
<para>
This operation is not as efficient as the <acronym>SQL</acronym>
This operation is not as efficient as the <acronym>SQL</acronym>
<command>COPY</command> command because all data must pass through the
<command>COPY</command> command because all data must pass through the
client/server IP or socket connection. For large amounts of data th
is
other
client/server IP or socket connection. For large amounts of data th
e
other
technique may be preferable.
technique may be preferable.
</para>
</para>
</tip>
</tip>
...
@@ -510,12 +514,15 @@ testdb=>
...
@@ -510,12 +514,15 @@ testdb=>
<term><literal>\echo</literal> <replaceable class="parameter">text</replaceable> [ ... ]</term>
<term><literal>\echo</literal> <replaceable class="parameter">text</replaceable> [ ... ]</term>
<listitem>
<listitem>
<para>
<para>
Prints the arguments to the standard output. This can be useful to
Prints the arguments to the standard output, separated by one space and
followed by a newline. This can be useful to
intersperse information in the output of scripts. For example:
intersperse information in the output of scripts. For example:
<programlisting>
<programlisting>
=> <userinput>\echo `date`</userinput>
=> <userinput>\echo `date`</userinput>
Tue Oct 26 21:40:57 CEST 1999
Tue Oct 26 21:40:57 CEST 1999
</programlisting>
</programlisting>
If the first argument is an unquoted <literal>-n</literal> the the trailing
newline is not written.
</para>
</para>
<tip>
<tip>
...
@@ -602,7 +609,7 @@ Tue Oct 26 21:40:57 CEST 1999
...
@@ -602,7 +609,7 @@ Tue Oct 26 21:40:57 CEST 1999
<note>
<note>
<para>
<para>
If you want to see the lines on the screen as they are read you must set
If you want to see the lines on the screen as they are read you must set
the variable <envar>
echo</envar
>.
the variable <envar>
ECHO</envar> to <literal>full</literal
>.
</para>
</para>
</note>
</note>
</listitem>
</listitem>
...
@@ -658,7 +665,7 @@ Tue Oct 26 21:40:57 CEST 1999
...
@@ -658,7 +665,7 @@ Tue Oct 26 21:40:57 CEST 1999
Stores the file into a <productname>PostgreSQL</productname> <quote>large object</quote>.
Stores the file into a <productname>PostgreSQL</productname> <quote>large object</quote>.
Optionally, it associates the given comment with the object. Example:
Optionally, it associates the given comment with the object. Example:
<programlisting>
<programlisting>
foo=> <userinput>\lo_import '/home/
me
/pictures/photo.xcf' 'a picture of me'</userinput>
foo=> <userinput>\lo_import '/home/
peter
/pictures/photo.xcf' 'a picture of me'</userinput>
lo_import 152801
lo_import 152801
</programlisting>
</programlisting>
The response indicates that the large object received object id 152801
The response indicates that the large object received object id 152801
...
@@ -1006,12 +1013,13 @@ lo_import 152801
...
@@ -1006,12 +1013,13 @@ lo_import 152801
<varlistentry>
<varlistentry>
<term><literal>\set</literal> [ <replaceable class="parameter">name</replaceable> [ <replaceable class="parameter">value</replaceable> ]]</term>
<term><literal>\set</literal> [ <replaceable class="parameter">name</replaceable> [ <replaceable class="parameter">value</replaceable>
[ ... ]
]]</term>
<listitem>
<listitem>
<para>
<para>
Sets the internal variable <replaceable class="parameter">name</replaceable>
Sets the internal variable <replaceable class="parameter">name</replaceable>
to <replaceable class="parameter">value</replaceable>. If no second argument
to <replaceable class="parameter">value</replaceable> or, if more than one
value is given, to the concatenation of all of them. If no second argument
is given, the variable is just set with not value. To unset a variable, use
is given, the variable is just set with not value. To unset a variable, use
the <command>\unset</command> command.
the <command>\unset</command> command.
</para>
</para>
...
@@ -1145,9 +1153,7 @@ Access permissions for database "test"
...
@@ -1145,9 +1153,7 @@ Access permissions for database "test"
<para>
<para>
Escapes to a separate Unix shell or executes the Unix command
Escapes to a separate Unix shell or executes the Unix command
<replaceable class="parameter">command</replaceable>. The arguments
<replaceable class="parameter">command</replaceable>. The arguments
are not further interpreted, the shell will see them as is. If you wish
are not further interpreted, the shell will see them as is.
to capture the output of a shell command and/or use <application>psql</application>'s
variable substitution features, use the backticks (<literal>`</literal>).
</para>
</para>
</listitem>
</listitem>
</varlistentry>
</varlistentry>
...
@@ -1200,7 +1206,7 @@ Access permissions for database "test"
...
@@ -1200,7 +1206,7 @@ Access permissions for database "test"
<para>
<para>
Specifies that <application>psql</application>
Specifies that <application>psql</application>
is to execute one query string, <replaceable class="parameter">query</replaceable>,
is to execute one query string, <replaceable class="parameter">query</replaceable>,
and then exit. This is useful
for
shell scripts.
and then exit. This is useful
in
shell scripts.
</para>
</para>
<para>
<para>
<replaceable class="parameter">query</replaceable> must be either a query string
<replaceable class="parameter">query</replaceable> must be either a query string
...
@@ -1208,8 +1214,8 @@ Access permissions for database "test"
...
@@ -1208,8 +1214,8 @@ Access permissions for database "test"
specific features), or it is a single backslash command. Thus
specific features), or it is a single backslash command. Thus
you cannot mix <acronym>SQL</acronym> and <application>psql</application>
you cannot mix <acronym>SQL</acronym> and <application>psql</application>
meta-commands. To achieve this you could pipe the string into
meta-commands. To achieve this you could pipe the string into
<application>psql</application>
and finish it with a a <literal>\q</literal>,
<application>psql</application>
, like so:
like so: <literal>echo "select * from foo; \q
" | psql</literal>.
<literal>echo "\x \\ select * from foo;
" | psql</literal>.
</para>
</para>
</listitem>
</listitem>
</varlistentry>
</varlistentry>
...
@@ -1260,6 +1266,16 @@ Access permissions for database "test"
...
@@ -1260,6 +1266,16 @@ Access permissions for database "test"
After the file is processed, <application>psql</application> terminates.
After the file is processed, <application>psql</application> terminates.
This in many ways equivalent to the internal command <command>\i</command>.
This in many ways equivalent to the internal command <command>\i</command>.
</para>
</para>
<para>
Using this option is subtly different from writing
<literal>psql < <replaceable class="parameter">filename</replaceable></literal>.
In general, both will do what you expect, but using <literal>-f</literal>
enables some nice features such as error messages with line numbers.
There is also a slight chance that using this option will reduce
the startup overhead. On the other hand, the variant using the shell's
input redirection is (in theory) guaranteed to yield exactly the same
output that you would have gotten had you entered everything by hand.
</para>
</listitem>
</listitem>
</varlistentry>
</varlistentry>
...
@@ -1311,16 +1327,6 @@ Access permissions for database "test"
...
@@ -1311,16 +1327,6 @@ Access permissions for database "test"
</varlistentry>
</varlistentry>
<varlistentry>
<term>-n, --no-readline</term>
<listitem>
<para>
Do not use readline for line editing and do not use the history.
</para>
</listitem>
</varlistentry>
<varlistentry>
<varlistentry>
<term>-o, --output <replaceable class="parameter">filename</replaceable></term>
<term>-o, --output <replaceable class="parameter">filename</replaceable></term>
<listitem>
<listitem>
...
@@ -1373,6 +1379,17 @@ Access permissions for database "test"
...
@@ -1373,6 +1379,17 @@ Access permissions for database "test"
</varlistentry>
</varlistentry>
<varlistentry>
<term>-R, --record-separator <replaceable class="parameter">separator</replaceable></term>
<listitem>
<para>
Use <replaceable class="parameter">separator</replaceable> as the record separator.
This is equivalent to the <command>\pset recordsep</command> command.
</para>
</listitem>
</varlistentry>
<varlistentry>
<varlistentry>
<term>-s, --single-step</term>
<term>-s, --single-step</term>
<listitem>
<listitem>
...
@@ -1492,7 +1509,7 @@ Access permissions for database "test"
...
@@ -1492,7 +1509,7 @@ Access permissions for database "test"
<para>
<para>
As of version 7.0, <application>psql</application> automatically issues a
As of version 7.0, <application>psql</application> automatically issues a
password prompt whenever the backend requests password authentication.
password prompt whenever the backend requests password authentication.
Because this is currently based on a <quote>hack</quote> the automatic
Because this is currently based on a <quote>hack</quote>
,
the automatic
recognition might mysteriously fail, hence this option to force a prompt.
recognition might mysteriously fail, hence this option to force a prompt.
If no password prompt is issued and the backend requires password authentication
If no password prompt is issued and the backend requires password authentication
the connection attempt will fail.
the connection attempt will fail.
...
@@ -1539,46 +1556,39 @@ Access permissions for database "test"
...
@@ -1539,46 +1556,39 @@ Access permissions for database "test"
<para>
<para>
<application>psql</application> provides variable substitution features
<application>psql</application> provides variable substitution features
similar to common Unix command shells. Variables are simply name/value
similar to common Unix command shells. This feature is new and not very
sophisticated, yet, but there are plans to expand it in the future.
Variables are simply name/value
pairs, where the value can be any string of any length. To set variables,
pairs, where the value can be any string of any length. To set variables,
use the <application>psql</application> meta-command <command>\set</command>:
use the <application>psql</application> meta-command <command>\set</command>:
<programlisting>
<programlisting>
testdb=> <userinput>\set foo bar</userinput>
testdb=> <userinput>\set foo bar</userinput>
</programlisting>
</programlisting>
sets the variable <quote>foo</quote> to the value <quote>bar</quote>. To retrieve
sets the variable <quote>foo</quote> to the value <quote>bar</quote>. To retrieve
the content of the variable, precede the name with a
dollar-sig
n and use it
the content of the variable, precede the name with a
colo
n and use it
as the argument of any slash command:
as the argument of any slash command:
<programlisting>
<programlisting>
testdb=> <userinput>\echo
$
foo</userinput>
testdb=> <userinput>\echo
:
foo</userinput>
bar
bar
</programlisting>
</programlisting>
Alternatively, the value can also be interpolated into a double-quoted (or backtick-quoted)
string, like so:
<programlisting>
testdb=> <userinput>\echo "foo is now ${foo}."</userinput>
foo is now bar.
</programlisting>
(The curly braces are required.) No variable substitution
will be performed in single-quoted strings or in any of the backslash commands
that have special parsing rules (e.g., <command>\copy</command>).
</para>
</para>
<note>
<note>
<para>
<para>
The arguments of <command>\set</command> are subject to the same substitution
The arguments of <command>\set</command> are subject to the same substitution
rules as with other commands. Thus you can construct interesting references
rules as with other commands. Thus you can construct interesting references
such as <literal>\set
"${foo}bar"
'something'</literal> and get <quote>soft
such as <literal>\set
:foo
'something'</literal> and get <quote>soft
links</quote> or <quote>variable variables</quote> of <productname>Perl</productname>
links</quote> or <quote>variable variables</quote> of <productname>Perl</productname>
or <productname><acronym>PHP</acronym></productname> fame, respectively.
or <productname><acronym>PHP</acronym></productname> fame, respectively.
Unfortunately (or fortunately?), there is not way to do anything useful
Unfortunately (or fortunately?), there is not way to do anything useful
with these constructs.
(<literal>\echo ${${foo}}</literal> doesn't work.)
On the
with these constructs. On the
other hand, <literal>\set bar
$
foo</literal> is a perfectly valid way to copy
other hand, <literal>\set bar
:
foo</literal> is a perfectly valid way to copy
a variable.
a variable.
</para>
</para>
</note>
</note>
<para>
<para>
If you call <command>\set</command> without a
n
argument, the variable is simply
If you call <command>\set</command> without a
second
argument, the variable is simply
set, but has no value. To unset (or delete) a variable, use the command
set, but has no value. To unset (or delete) a variable, use the command
<command>\unset</command>.
<command>\unset</command>.
</para>
</para>
...
@@ -1830,7 +1840,7 @@ foo is now bar.
...
@@ -1830,7 +1840,7 @@ foo is now bar.
<para>
<para>
An additional useful feature of <application>psql</application> variables
An additional useful feature of <application>psql</application> variables
is that you can substitute (<quote>interpolate</quote>) them into
is that you can substitute (<quote>interpolate</quote>) them into
regular <acronym>SQL</acronym> statements. The syntax for this is to prepend
regular <acronym>SQL</acronym> statements. The syntax for this is
again
to prepend
the variable name with a colon (<literal>:</literal>).
the variable name with a colon (<literal>:</literal>).
<programlisting>
<programlisting>
testdb=> <userinput>\set foo 'my_table'</userinput>
testdb=> <userinput>\set foo 'my_table'</userinput>
...
@@ -1850,8 +1860,7 @@ testdb=> <userinput>SELECT * FROM :foo;</userinput>
...
@@ -1850,8 +1860,7 @@ testdb=> <userinput>SELECT * FROM :foo;</userinput>
Another possible use of this mechanism is to copy the contents of a file
Another possible use of this mechanism is to copy the contents of a file
into a field. First load the file into a variable and then proceed as above.
into a field. First load the file into a variable and then proceed as above.
<programlisting>
<programlisting>
testdb=> <userinput>\set content `cat my_file.txt`</userinput>
testdb=> <userinput>\set content '\'' `cat my_file.txt` '\''</userinput>
testdb=> <userinput>\set content "'${content}'"</userinput>
testdb=> <userinput>INSERT INTO my_table VALUES (:content);</userinput>
testdb=> <userinput>INSERT INTO my_table VALUES (:content);</userinput>
</programlisting>
</programlisting>
One possible problem with this approach is that <filename>my_file.txt</filename>
One possible problem with this approach is that <filename>my_file.txt</filename>
...
@@ -1877,11 +1886,12 @@ testdb=> <userinput>\set content `sed -e "s/'/\\\\\\'/g" < my_file.txt`</userinp
...
@@ -1877,11 +1886,12 @@ testdb=> <userinput>\set content `sed -e "s/'/\\\\\\'/g" < my_file.txt`</userinp
<para>
<para>
Since colons may legally appear in queries, the following rule applies: If the variable
Since colons may legally appear in queries, the following rule applies: If the variable
is not set, the character sequence <quote>colon
-
name</quote> is not changed. In any
is not set, the character sequence <quote>colon
name</quote> is not changed. In any
case you can escape a colon with a backslash to protect it from interpretation.
case you can escape a colon with a backslash to protect it from interpretation.
(The colon syntax for variables is standard <acronym>SQL</acronym> for embedded
(The colon syntax for variables is standard <acronym>SQL</acronym> for embedded
query languages, such as <application>ecpg</application>. The colon syntax for
query languages, such as <application>ecpg</application>. The colon syntax for
array slices and type casts are <productname>PostgreSQL</productname> extensions.)
array slices and type casts are <productname>PostgreSQL</productname> extensions,
hence the conflict.)
</para>
</para>
</refsect2>
</refsect2>
...
@@ -1975,7 +1985,7 @@ testdb=> <userinput>\set content `sed -e "s/'/\\\\\\'/g" < my_file.txt`</userinp
...
@@ -1975,7 +1985,7 @@ testdb=> <userinput>\set content `sed -e "s/'/\\\\\\'/g" < my_file.txt`</userinp
</varlistentry>
</varlistentry>
<varlistentry>
<varlistentry>
<term><literal>%
$</literal><replaceable class="parameter">name</replaceable><literal>$
</literal></term>
<term><literal>%
:</literal><replaceable class="parameter">name</replaceable><literal>:
</literal></term>
<listitem><para>
<listitem><para>
The value of the <application>psql</application>, <quote>magic</quote>, or environment
The value of the <application>psql</application>, <quote>magic</quote>, or environment
variable <replaceable class="parameter">name</replaceable>. See the section
variable <replaceable class="parameter">name</replaceable>. See the section
...
@@ -2032,13 +2042,22 @@ testdb=> <userinput>\set content `sed -e "s/'/\\\\\\'/g" < my_file.txt`</userinp
...
@@ -2032,13 +2042,22 @@ testdb=> <userinput>\set content `sed -e "s/'/\\\\\\'/g" < my_file.txt`</userinp
<para>
<para>
<application>psql</application> supports the readline and history libraries for
<application>psql</application> supports the readline and history libraries for
convenien
en
t line editing and retrieval. The command history is stored in a file
convenient line editing and retrieval. The command history is stored in a file
named <filename>.psql_history</filename> in your home directory and is reloaded when
named <filename>.psql_history</filename> in your home directory and is reloaded when
<application>psql</application> starts up.
<application>psql</application> starts up.
Tab-completion is also supported, although
Tab-completion is also supported, although
the completion logic makes no claim to be an <acronym>SQL</acronym> parser.
the completion logic makes no claim to be an <acronym>SQL</acronym> parser.
When available, <application>psql</application> is automatically built to use these
When available, <application>psql</application> is automatically built to use these
features.
features. If for some reason you do not like the tab completion, you can turn if off
by putting this in a file named <filename>.inputrc</filename> in your
home directory:
<programlisting>
$if psql
set disable-completion on
$endif
</programlisting>
(This is not a <application>psql</application> but a <application>readline</application>
feature. Read its documentation for further details.)
</para>
</para>
<para>
<para>
...
@@ -2053,7 +2072,7 @@ testdb=> <userinput>\set content `sed -e "s/'/\\\\\\'/g" < my_file.txt`</userinp
...
@@ -2053,7 +2072,7 @@ testdb=> <userinput>\set content `sed -e "s/'/\\\\\\'/g" < my_file.txt`</userinp
you have the library and header files installed in an obscure place you
you have the library and header files installed in an obscure place you
must tell <filename>configure</filename> about them, for example:
must tell <filename>configure</filename> about them, for example:
<programlisting>
<programlisting>
$ ./configure --with-includes=/opt/gnu/include --with-lib
rarie
s=/opt/gnu/lib ...
$ ./configure --with-includes=/opt/gnu/include --with-libs=/opt/gnu/lib ...
</programlisting>
</programlisting>
Then you have to recompile <application>psql</application> (not necessarily
Then you have to recompile <application>psql</application> (not necessarily
the entire code tree).
the entire code tree).
...
@@ -2105,7 +2124,7 @@ testdb=> <userinput>\d my_table</userinput>
...
@@ -2105,7 +2124,7 @@ testdb=> <userinput>\d my_table</userinput>
At this point you decide to change the prompt to something more
At this point you decide to change the prompt to something more
interesting:
interesting:
<programlisting>
<programlisting>
testdb=> <userinput>\set
prompt
1 '%n@%m %~%R%# '</userinput>
testdb=> <userinput>\set
PROMPT
1 '%n@%m %~%R%# '</userinput>
peter@localhost testdb=>
peter@localhost testdb=>
</programlisting>
</programlisting>
Let's assume you have filled the table with data and want to take a look at it:
Let's assume you have filled the table with data and want to take a look at it:
...
@@ -2221,14 +2240,6 @@ Field separator is "oo".
...
@@ -2221,14 +2240,6 @@ Field separator is "oo".
</para>
</para>
</listitem>
</listitem>
<listitem>
<para>
The number of options for a backslash command is limited, probably to 16.
You can easily change this in the source code, and perhaps I will get around
to fixing this one day. Not that there is any command
that actually uses that many options though.
</para>
</listitem>
</itemizedlist>
</itemizedlist>
</refsect2>
</refsect2>
...
...
src/bin/psql/command.c
View file @
9ceb5d8a
...
@@ -3,12 +3,13 @@
...
@@ -3,12 +3,13 @@
*
*
* Copyright 2000 by PostgreSQL Global Development Group
* Copyright 2000 by PostgreSQL Global Development Group
*
*
* $Header: /cvsroot/pgsql/src/bin/psql/command.c,v 1.1
7 2000/02/05 12:27:56 ishii
Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/command.c,v 1.1
8 2000/02/07 23:10:04 petere
Exp $
*/
*/
#include <c.h>
#include <c.h>
#include "command.h"
#include "command.h"
#include <errno.h>
#include <errno.h>
#include <assert.h>
#include <string.h>
#include <string.h>
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
...
@@ -17,54 +18,40 @@
...
@@ -17,54 +18,40 @@
#include <sys/types.h>
/* for umask() */
#include <sys/types.h>
/* for umask() */
#include <sys/stat.h>
/* for umask(), stat() */
#include <sys/stat.h>
/* for umask(), stat() */
#include <unistd.h>
/* for geteuid(), getpid(), stat() */
#include <unistd.h>
/* for geteuid(), getpid(), stat() */
#else
#include <win32.h>
#endif
#endif
#include <assert.h>
#include <libpq-fe.h>
#include <libpq-fe.h>
#include <pqexpbuffer.h>
#include <pqexpbuffer.h>
#include "stringutils.h"
#include "common.h"
#include "mainloop.h"
#include "copy.h"
#include "copy.h"
#include "describe.h"
#include "help.h"
#include "help.h"
#include "settings.h"
#include "input.h"
#include "common.h"
#include "large_obj.h"
#include "large_obj.h"
#include "mainloop.h"
#include "print.h"
#include "print.h"
#include "describe.h"
#include "settings.h"
#include "input.h"
#include "variables.h"
#include "variables.h"
#ifdef WIN32
#include "../../interfaces/libpq/win32.h"
#define popen(x,y) _popen(x,y)
#define pclose(x) _pclose(x)
#endif
/* functions for use in this file */
/* functions for use in this file */
static
backslashResult
exec_command
(
const
char
*
cmd
,
static
backslashResult
exec_command
(
const
char
*
cmd
,
char
*
const
*
options
,
const
char
*
options_string
,
const
char
*
options_string
,
const
char
**
continue_parse
,
PQExpBuffer
query_buf
);
PQExpBuffer
query_buf
);
static
bool
do_edit
(
const
char
*
filename_arg
,
PQExpBuffer
query_buf
);
enum
option_type
{
OT_NORMAL
,
OT_SQLID
};
static
char
*
scan_option
(
char
**
string
,
enum
option_type
type
,
char
*
quote
);
static
char
*
unescape
(
const
char
*
source
);
static
char
*
unescape
(
const
unsigned
char
*
source
,
size_t
len
);
static
bool
do_connect
(
const
char
*
new_dbname
,
const
char
*
new_user
);
static
bool
do_edit
(
const
char
*
filename_arg
,
PQExpBuffer
query_buf
);
static
bool
do_connect
(
const
char
*
new_dbname
,
const
char
*
new_user
);
static
bool
do_shell
(
const
char
*
command
);
static
bool
do_shell
(
const
char
*
command
);
/*
* Perhaps this should be changed to "infinity",
* but there is no convincing reason to bother
* at this point.
*/
#define NR_OPTIONS 16
/*----------
/*----------
...
@@ -79,7 +66,7 @@ static bool do_shell(const char *command);
...
@@ -79,7 +66,7 @@ static bool do_shell(const char *command);
*
*
* 'query_buf' contains the query-so-far, which may be modified by
* 'query_buf' contains the query-so-far, which may be modified by
* execution of the backslash command (for example, \r clears it)
* execution of the backslash command (for example, \r clears it)
* query_buf can be NULL if there is no query
-so-
far.
* query_buf can be NULL if there is no query
so
far.
*
*
* Returns a status code indicating what action is desired, see command.h.
* Returns a status code indicating what action is desired, see command.h.
*----------
*----------
...
@@ -92,18 +79,13 @@ HandleSlashCmds(const char *line,
...
@@ -92,18 +79,13 @@ HandleSlashCmds(const char *line,
{
{
backslashResult
status
=
CMD_SKIP_LINE
;
backslashResult
status
=
CMD_SKIP_LINE
;
char
*
my_line
;
char
*
my_line
;
char
*
options
[
NR_OPTIONS
+
1
];
char
*
options_string
=
NULL
;
char
*
token
;
const
char
*
options_string
=
NULL
;
const
char
*
cmd
;
size_t
blank_loc
;
size_t
blank_loc
;
int
i
;
const
char
*
continue_parse
=
NULL
;
/* tell the mainloop where the
const
char
*
continue_parse
=
NULL
;
/* tell the mainloop where the
* backslash command ended */
* backslash command ended */
#ifdef USE_ASSERT_CHECKING
#ifdef USE_ASSERT_CHECKING
assert
(
line
);
assert
(
line
);
assert
(
query_buf
);
assert
(
end_of_cmd
);
assert
(
end_of_cmd
);
#endif
#endif
...
@@ -129,145 +111,37 @@ HandleSlashCmds(const char *line,
...
@@ -129,145 +111,37 @@ HandleSlashCmds(const char *line,
my_line
[
blank_loc
]
=
'\0'
;
my_line
[
blank_loc
]
=
'\0'
;
}
}
options
[
0
]
=
NULL
;
status
=
exec_command
(
my_line
,
options_string
,
&
continue_parse
,
query_buf
);
if
(
options_string
)
{
char
quote
;
unsigned
int
pos
;
options_string
=
&
options_string
[
strspn
(
options_string
,
"
\t
"
)];
/* skip leading
* whitespace */
i
=
0
;
token
=
strtokx
(
options_string
,
"
\t
"
,
"
\"
'`"
,
'\\'
,
&
quote
,
&
pos
,
pset
.
encoding
);
for
(
i
=
0
;
token
&&
i
<
NR_OPTIONS
;
i
++
)
{
switch
(
quote
)
{
case
'"'
:
options
[
i
]
=
unescape
(
token
);
break
;
case
'\''
:
options
[
i
]
=
xstrdup
(
token
);
break
;
case
'`'
:
{
bool
error
=
false
;
FILE
*
fd
=
NULL
;
char
*
file
=
unescape
(
token
);
PQExpBufferData
output
;
char
buf
[
512
];
size_t
result
;
fd
=
popen
(
file
,
"r"
);
if
(
!
fd
)
{
psql_error
(
"%s: %s
\n
"
,
file
,
strerror
(
errno
));
error
=
true
;
}
if
(
!
error
)
{
initPQExpBuffer
(
&
output
);
do
{
result
=
fread
(
buf
,
1
,
512
,
fd
);
if
(
ferror
(
fd
))
{
psql_error
(
"%s: %s
\n
"
,
file
,
strerror
(
errno
));
error
=
true
;
break
;
}
appendBinaryPQExpBuffer
(
&
output
,
buf
,
result
);
}
while
(
!
feof
(
fd
));
appendPQExpBufferChar
(
&
output
,
'\0'
);
if
(
pclose
(
fd
)
==
-
1
)
{
psql_error
(
"%s: %s
\n
"
,
file
,
strerror
(
errno
));
error
=
true
;
}
}
if
(
!
error
)
{
if
(
output
.
data
[
strlen
(
output
.
data
)
-
1
]
==
'\n'
)
output
.
data
[
strlen
(
output
.
data
)
-
1
]
=
'\0'
;
}
free
(
file
);
if
(
!
error
)
options
[
i
]
=
output
.
data
;
else
{
options
[
i
]
=
xstrdup
(
""
);
termPQExpBuffer
(
&
output
);
}
break
;
}
case
0
:
default:
if
(
token
[
0
]
==
'\\'
)
continue_parse
=
options_string
+
pos
;
else
if
(
token
[
0
]
==
'$'
)
{
const
char
*
value
=
GetVariable
(
pset
.
vars
,
token
+
1
);
if
(
!
value
)
value
=
""
;
options
[
i
]
=
xstrdup
(
value
);
}
else
options
[
i
]
=
xstrdup
(
token
);
}
if
(
continue_parse
)
break
;
token
=
strtokx
(
NULL
,
"
\t
"
,
"
\"
'`"
,
'\\'
,
&
quote
,
&
pos
,
pset
.
encoding
);
}
/* for */
options
[
i
]
=
NULL
;
}
cmd
=
my_line
;
status
=
exec_command
(
cmd
,
options
,
options_string
,
query_buf
);
if
(
status
==
CMD_UNKNOWN
)
if
(
status
==
CMD_UNKNOWN
)
{
{
/*
/*
* If the command was not recognized, try inserting a space after
* If the command was not recognized, try inserting a space after
the
* the first letter and call again. The one letter commands allow
* first letter and call again. The one letter commands allow arguments
* arguments to start immediately after the command, but that is
* to start immediately after the command, but that is no longer
* no longer
encouraged.
*
encouraged.
*/
*/
const
char
*
new_options
[
NR_OPTIONS
+
1
];
char
new_cmd
[
2
];
char
new_cmd
[
2
];
int
i
;
for
(
i
=
1
;
i
<
NR_OPTIONS
+
1
;
i
++
)
new_cmd
[
0
]
=
my_line
[
0
];
new_options
[
i
]
=
options
[
i
-
1
];
new_options
[
0
]
=
cmd
+
1
;
new_cmd
[
0
]
=
cmd
[
0
];
new_cmd
[
1
]
=
'\0'
;
new_cmd
[
1
]
=
'\0'
;
status
=
exec_command
(
new_cmd
,
(
char
*
const
*
)
new_options
,
my_line
+
2
,
query_buf
);
status
=
exec_command
(
new_cmd
,
my_line
+
1
,
&
continue_parse
,
query_buf
);
if
(
status
!=
CMD_UNKNOWN
&&
isalpha
(
new_cmd
[
0
]))
psql_error
(
"Warning: this syntax is deprecated
\n
"
);
}
}
if
(
status
==
CMD_UNKNOWN
)
if
(
status
==
CMD_UNKNOWN
)
{
{
if
(
pset
.
cur_cmd_interactive
)
if
(
pset
.
cur_cmd_interactive
)
fprintf
(
stderr
,
"Invalid command
\\
%s. Try
\\
? for help.
\n
"
,
cmd
);
fprintf
(
stderr
,
"Invalid command
\\
%s. Try
\\
? for help.
\n
"
,
my_line
);
else
else
psql_error
(
"invalid command
\\
%s
\n
"
,
cmd
);
psql_error
(
"invalid command
\\
%s
\n
"
,
my_line
);
status
=
CMD_ERROR
;
status
=
CMD_ERROR
;
}
}
if
(
continue_parse
&&
*
(
continue_parse
+
1
)
==
'\\'
)
if
(
continue_parse
&&
*
continue_parse
&&
*
(
continue_parse
+
1
)
==
'\\'
)
continue_parse
+=
2
;
continue_parse
+=
2
;
...
@@ -276,10 +150,6 @@ HandleSlashCmds(const char *line,
...
@@ -276,10 +150,6 @@ HandleSlashCmds(const char *line,
else
else
*
end_of_cmd
=
line
+
strlen
(
line
);
*
end_of_cmd
=
line
+
strlen
(
line
);
/* clean up */
for
(
i
=
0
;
i
<
NR_OPTIONS
&&
options
[
i
];
i
++
)
free
(
options
[
i
]);
free
(
my_line
);
free
(
my_line
);
return
status
;
return
status
;
...
@@ -287,19 +157,26 @@ HandleSlashCmds(const char *line,
...
@@ -287,19 +157,26 @@ HandleSlashCmds(const char *line,
static
backslashResult
static
backslashResult
exec_command
(
const
char
*
cmd
,
exec_command
(
const
char
*
cmd
,
char
*
const
*
options
,
const
char
*
options_string
,
const
char
*
options_string
,
const
char
**
continue_parse
,
PQExpBuffer
query_buf
)
PQExpBuffer
query_buf
)
{
{
bool
success
=
true
;
/* indicate here if the command ran ok or
bool
success
=
true
;
/* indicate here if the command ran ok or
* failed */
* failed */
bool
quiet
=
QUIET
();
bool
quiet
=
QUIET
();
backslashResult
status
=
CMD_SKIP_LINE
;
backslashResult
status
=
CMD_SKIP_LINE
;
char
*
string
,
*
string_cpy
;
/*
* The 'string' variable will be overwritten to point to the next token,
* hence we need an extra pointer so we can free this at the end.
*/
if
(
options_string
)
string
=
string_cpy
=
xstrdup
(
options_string
);
else
string
=
string_cpy
=
NULL
;
/* \a -- toggle field alignment This makes little sense but we keep it around. */
/* \a -- toggle field alignment This makes little sense but we keep it around. */
if
(
strcmp
(
cmd
,
"a"
)
==
0
)
if
(
strcmp
(
cmd
,
"a"
)
==
0
)
...
@@ -310,44 +187,53 @@ exec_command(const char *cmd,
...
@@ -310,44 +187,53 @@ exec_command(const char *cmd,
success
=
do_pset
(
"format"
,
"unaligned"
,
&
pset
.
popt
,
quiet
);
success
=
do_pset
(
"format"
,
"unaligned"
,
&
pset
.
popt
,
quiet
);
}
}
/* \C -- override table title (formerly change HTML caption) */
/* \C -- override table title (formerly change HTML caption) */
else
if
(
strcmp
(
cmd
,
"C"
)
==
0
)
else
if
(
strcmp
(
cmd
,
"C"
)
==
0
)
success
=
do_pset
(
"title"
,
options
[
0
],
&
pset
.
popt
,
quiet
);
{
char
*
opt
=
scan_option
(
&
string
,
OT_NORMAL
,
NULL
);
success
=
do_pset
(
"title"
,
opt
,
&
pset
.
popt
,
quiet
);
free
(
opt
);
}
/*----------
/*----------
* \c or \connect -- connect to new database or as different user
* \c or \connect -- connect to new database or as different user
*
*
* \c foo bar
:
connect to db "foo" as user "bar"
* \c foo bar
connect to db "foo" as user "bar"
* \c foo [-]
:
connect to db "foo" as current user
* \c foo [-]
connect to db "foo" as current user
* \c - bar
:
connect to current db as user "bar"
* \c - bar
connect to current db as user "bar"
* \c
:
connect to default db as default user
* \c connect to default db as default user
*----------
*----------
*/
*/
else
if
(
strcmp
(
cmd
,
"c"
)
==
0
||
strcmp
(
cmd
,
"connect"
)
==
0
)
else
if
(
strcmp
(
cmd
,
"c"
)
==
0
||
strcmp
(
cmd
,
"connect"
)
==
0
)
{
{
if
(
options
[
1
])
char
*
opt1
,
*
opt2
;
char
opt1q
,
opt2q
;
opt1
=
scan_option
(
&
string
,
OT_NORMAL
,
&
opt1q
);
opt2
=
scan_option
(
&
string
,
OT_NORMAL
,
&
opt2q
);
if
(
opt2
)
/* gave username */
/* gave username */
success
=
do_connect
(
options
[
0
],
options
[
1
]);
success
=
do_connect
(
!
opt1q
&&
(
strcmp
(
opt1
,
"-"
)
==
0
||
strcmp
(
opt1
,
""
)
==
0
)
?
""
:
opt1
,
else
!
opt2q
&&
(
strcmp
(
opt2
,
"-"
)
==
0
||
strcmp
(
opt2
,
""
)
==
0
)
?
""
:
opt2
);
{
else
if
(
opt1
)
if
(
options
[
0
])
/* gave database name */
/* gave database name */
success
=
do_connect
(
options
[
0
],
""
);
/* empty string is same
success
=
do_connect
(
!
opt1q
&&
(
strcmp
(
opt1
,
"-"
)
==
0
||
strcmp
(
opt1
,
""
)
==
0
)
?
""
:
opt1
,
""
);
* username as before,
* NULL would mean libpq
* default */
else
else
/* connect to default db as default user */
/* connect to default db as default user */
success
=
do_connect
(
NULL
,
NULL
);
success
=
do_connect
(
NULL
,
NULL
);
}
}
free
(
opt1
);
free
(
opt2
);
}
/* \copy */
/* \copy */
else
if
(
strcasecmp
(
cmd
,
"copy"
)
==
0
)
else
if
(
strcasecmp
(
cmd
,
"copy"
)
==
0
)
{
success
=
do_copy
(
options_string
);
success
=
do_copy
(
options_string
);
if
(
options_string
)
string
+=
strlen
(
string
);
}
/* \copyright */
/* \copyright */
else
if
(
strcmp
(
cmd
,
"copyright"
)
==
0
)
else
if
(
strcmp
(
cmd
,
"copyright"
)
==
0
)
...
@@ -356,38 +242,42 @@ exec_command(const char *cmd,
...
@@ -356,38 +242,42 @@ exec_command(const char *cmd,
/* \d* commands */
/* \d* commands */
else
if
(
cmd
[
0
]
==
'd'
)
else
if
(
cmd
[
0
]
==
'd'
)
{
{
bool
show_verbose
=
strchr
(
cmd
,
'+'
)
?
true
:
false
;
char
*
name
;
bool
show_verbose
;
name
=
scan_option
(
&
string
,
OT_SQLID
,
NULL
);
show_verbose
=
strchr
(
cmd
,
'+'
)
?
true
:
false
;
switch
(
cmd
[
1
])
switch
(
cmd
[
1
])
{
{
case
'\0'
:
case
'\0'
:
case
'+'
:
case
'+'
:
if
(
options
[
0
]
)
if
(
name
)
success
=
describeTableDetails
(
options
[
0
]
,
show_verbose
);
success
=
describeTableDetails
(
name
,
show_verbose
);
else
else
/* standard listing of interesting things */
/* standard listing of interesting things */
success
=
listTables
(
"tvs"
,
NULL
,
show_verbose
);
success
=
listTables
(
"tvs"
,
NULL
,
show_verbose
);
break
;
break
;
case
'a'
:
case
'a'
:
success
=
describeAggregates
(
options
[
0
]
);
success
=
describeAggregates
(
name
);
break
;
break
;
case
'd'
:
case
'd'
:
success
=
objectDescription
(
options
[
0
]
);
success
=
objectDescription
(
name
);
break
;
break
;
case
'f'
:
case
'f'
:
success
=
describeFunctions
(
options
[
0
]
,
show_verbose
);
success
=
describeFunctions
(
name
,
show_verbose
);
break
;
break
;
case
'l'
:
case
'l'
:
success
=
do_lo_list
();
success
=
do_lo_list
();
break
;
break
;
case
'o'
:
case
'o'
:
success
=
describeOperators
(
options
[
0
]
);
success
=
describeOperators
(
name
);
break
;
break
;
case
'p'
:
case
'p'
:
success
=
permissionsList
(
options
[
0
]
);
success
=
permissionsList
(
name
);
break
;
break
;
case
'T'
:
case
'T'
:
success
=
describeTypes
(
options
[
0
]
,
show_verbose
);
success
=
describeTypes
(
name
,
show_verbose
);
break
;
break
;
case
't'
:
case
't'
:
case
'v'
:
case
'v'
:
...
@@ -397,11 +287,12 @@ exec_command(const char *cmd,
...
@@ -397,11 +287,12 @@ exec_command(const char *cmd,
if
(
cmd
[
1
]
==
'S'
&&
cmd
[
2
]
==
'\0'
)
if
(
cmd
[
1
]
==
'S'
&&
cmd
[
2
]
==
'\0'
)
success
=
listTables
(
"Stvs"
,
NULL
,
show_verbose
);
success
=
listTables
(
"Stvs"
,
NULL
,
show_verbose
);
else
else
success
=
listTables
(
&
cmd
[
1
],
options
[
0
]
,
show_verbose
);
success
=
listTables
(
&
cmd
[
1
],
name
,
show_verbose
);
break
;
break
;
default:
default:
status
=
CMD_UNKNOWN
;
status
=
CMD_UNKNOWN
;
}
}
free
(
name
);
}
}
...
@@ -410,46 +301,81 @@ exec_command(const char *cmd,
...
@@ -410,46 +301,81 @@ exec_command(const char *cmd,
* the query buffer
* the query buffer
*/
*/
else
if
(
strcmp
(
cmd
,
"e"
)
==
0
||
strcmp
(
cmd
,
"edit"
)
==
0
)
else
if
(
strcmp
(
cmd
,
"e"
)
==
0
||
strcmp
(
cmd
,
"edit"
)
==
0
)
status
=
do_edit
(
options
[
0
],
query_buf
)
?
CMD_NEWEDIT
:
CMD_ERROR
;
{
char
*
fname
;
if
(
!
query_buf
)
{
psql_error
(
"no query buffer"
);
status
=
CMD_ERROR
;
}
else
{
fname
=
scan_option
(
&
string
,
OT_NORMAL
,
NULL
);
status
=
do_edit
(
fname
,
query_buf
)
?
CMD_NEWEDIT
:
CMD_ERROR
;
free
(
fname
);
}
}
/* \echo */
/* \echo
and \qecho
*/
else
if
(
strcmp
(
cmd
,
"echo"
)
==
0
)
else
if
(
strcmp
(
cmd
,
"echo"
)
==
0
||
strcmp
(
cmd
,
"qecho"
)
==
0
)
{
{
int
i
;
char
*
value
;
char
quoted
;
bool
no_newline
=
false
;
bool
first
=
true
;
FILE
*
fout
;
for
(
i
=
0
;
i
<
16
&&
options
[
i
];
i
++
)
if
(
strcmp
(
cmd
,
"qecho"
)
==
0
)
fputs
(
options
[
i
],
stdout
);
fout
=
pset
.
queryFout
;
fputs
(
"
\n
"
,
stdout
);
else
fout
=
stdout
;
while
((
value
=
scan_option
(
&
string
,
OT_NORMAL
,
&
quoted
)))
{
if
(
!
quoted
&&
strcmp
(
value
,
"-n"
)
==
0
)
no_newline
=
true
;
else
{
if
(
first
)
first
=
false
;
else
fputc
(
' '
,
fout
);
fputs
(
value
,
fout
);
}
free
(
value
);
}
if
(
!
no_newline
)
fputs
(
"
\n
"
,
fout
);
}
}
/* \f -- change field separator */
/* \f -- change field separator */
else
if
(
strcmp
(
cmd
,
"f"
)
==
0
)
else
if
(
strcmp
(
cmd
,
"f"
)
==
0
)
success
=
do_pset
(
"fieldsep"
,
options
[
0
],
&
pset
.
popt
,
quiet
);
{
char
*
fname
=
scan_option
(
&
string
,
OT_NORMAL
,
NULL
);
success
=
do_pset
(
"fieldsep"
,
fname
,
&
pset
.
popt
,
quiet
);
free
(
fname
);
}
/* \g means send query */
/* \g means send query */
else
if
(
strcmp
(
cmd
,
"g"
)
==
0
)
else
if
(
strcmp
(
cmd
,
"g"
)
==
0
)
{
{
if
(
!
options
[
0
])
char
*
fname
=
scan_option
(
&
string
,
OT_NORMAL
,
NULL
);
if
(
!
fname
)
pset
.
gfname
=
NULL
;
pset
.
gfname
=
NULL
;
else
else
pset
.
gfname
=
xstrdup
(
options
[
0
]);
pset
.
gfname
=
xstrdup
(
fname
);
free
(
fname
);
status
=
CMD_SEND
;
status
=
CMD_SEND
;
}
}
/* help */
/* help */
else
if
(
strcmp
(
cmd
,
"h"
)
==
0
||
strcmp
(
cmd
,
"help"
)
==
0
)
else
if
(
strcmp
(
cmd
,
"h"
)
==
0
||
strcmp
(
cmd
,
"help"
)
==
0
)
{
{
char
buf
[
256
]
=
""
;
helpSQL
(
options_string
?
&
options_string
[
strspn
(
options_string
,
"
\t
"
)]
:
NULL
);
int
i
;
/* set pointer to end of line */
for
(
i
=
0
;
options
&&
options
[
i
]
&&
strlen
(
buf
)
<
255
;
i
++
)
if
(
string
)
{
string
+=
strlen
(
string
);
strncat
(
buf
,
options
[
i
],
255
-
strlen
(
buf
));
if
(
strlen
(
buf
)
<
255
&&
options
[
i
+
1
])
strcat
(
buf
,
" "
);
}
buf
[
255
]
=
'\0'
;
helpSQL
(
buf
);
}
}
/* HTML mode */
/* HTML mode */
...
@@ -465,15 +391,18 @@ exec_command(const char *cmd,
...
@@ -465,15 +391,18 @@ exec_command(const char *cmd,
/* \i is include file */
/* \i is include file */
else
if
(
strcmp
(
cmd
,
"i"
)
==
0
||
strcmp
(
cmd
,
"include"
)
==
0
)
else
if
(
strcmp
(
cmd
,
"i"
)
==
0
||
strcmp
(
cmd
,
"include"
)
==
0
)
{
{
if
(
!
options
[
0
])
char
*
fname
=
scan_option
(
&
string
,
OT_NORMAL
,
NULL
);
if
(
!
fname
)
{
{
psql_error
(
"
\\
%s: missing required argument
\n
"
,
cmd
);
psql_error
(
"
\\
%s: missing required argument
\n
"
,
cmd
);
success
=
false
;
success
=
false
;
}
}
else
else
success
=
process_file
(
options
[
0
]);
{
success
=
process_file
(
fname
);
free
(
fname
);
}
}
}
/* \l is list databases */
/* \l is list databases */
else
if
(
strcmp
(
cmd
,
"l"
)
==
0
||
strcmp
(
cmd
,
"list"
)
==
0
)
else
if
(
strcmp
(
cmd
,
"l"
)
==
0
||
strcmp
(
cmd
,
"list"
)
==
0
)
...
@@ -481,30 +410,36 @@ exec_command(const char *cmd,
...
@@ -481,30 +410,36 @@ exec_command(const char *cmd,
else
if
(
strcmp
(
cmd
,
"l+"
)
==
0
||
strcmp
(
cmd
,
"list+"
)
==
0
)
else
if
(
strcmp
(
cmd
,
"l+"
)
==
0
||
strcmp
(
cmd
,
"list+"
)
==
0
)
success
=
listAllDbs
(
true
);
success
=
listAllDbs
(
true
);
/*
/* large object things */
* large object things
*/
else
if
(
strncmp
(
cmd
,
"lo_"
,
3
)
==
0
)
else
if
(
strncmp
(
cmd
,
"lo_"
,
3
)
==
0
)
{
{
char
*
opt1
,
*
opt2
;
opt1
=
scan_option
(
&
string
,
OT_NORMAL
,
NULL
);
opt2
=
scan_option
(
&
string
,
OT_NORMAL
,
NULL
);
if
(
strcmp
(
cmd
+
3
,
"export"
)
==
0
)
if
(
strcmp
(
cmd
+
3
,
"export"
)
==
0
)
{
{
if
(
!
opt
ions
[
1
]
)
if
(
!
opt
2
)
{
{
psql_error
(
"
\\
%s: missing required argument
\n
"
,
cmd
);
psql_error
(
"
\\
%s: missing required argument
\n
"
,
cmd
);
success
=
false
;
success
=
false
;
}
}
else
else
success
=
do_lo_export
(
opt
ions
[
0
],
options
[
1
]
);
success
=
do_lo_export
(
opt
1
,
opt2
);
}
}
else
if
(
strcmp
(
cmd
+
3
,
"import"
)
==
0
)
else
if
(
strcmp
(
cmd
+
3
,
"import"
)
==
0
)
{
{
if
(
!
opt
ions
[
0
]
)
if
(
!
opt
1
)
{
{
psql_error
(
"
\\
%s: missing required argument
\n
"
,
cmd
);
psql_error
(
"
\\
%s: missing required argument
\n
"
,
cmd
);
success
=
false
;
success
=
false
;
}
}
else
else
success
=
do_lo_import
(
opt
ions
[
0
],
options
[
1
]
);
success
=
do_lo_import
(
opt
1
,
opt2
);
}
}
else
if
(
strcmp
(
cmd
+
3
,
"list"
)
==
0
)
else
if
(
strcmp
(
cmd
+
3
,
"list"
)
==
0
)
...
@@ -512,23 +447,30 @@ exec_command(const char *cmd,
...
@@ -512,23 +447,30 @@ exec_command(const char *cmd,
else
if
(
strcmp
(
cmd
+
3
,
"unlink"
)
==
0
)
else
if
(
strcmp
(
cmd
+
3
,
"unlink"
)
==
0
)
{
{
if
(
!
opt
ions
[
0
]
)
if
(
!
opt
1
)
{
{
psql_error
(
"
\\
%s: missing required argument
\n
"
,
cmd
);
psql_error
(
"
\\
%s: missing required argument
\n
"
,
cmd
);
success
=
false
;
success
=
false
;
}
}
else
else
success
=
do_lo_unlink
(
opt
ions
[
0
]
);
success
=
do_lo_unlink
(
opt
1
);
}
}
else
else
status
=
CMD_UNKNOWN
;
status
=
CMD_UNKNOWN
;
free
(
opt1
);
free
(
opt2
);
}
}
/* \o -- set query output */
/* \o -- set query output */
else
if
(
strcmp
(
cmd
,
"o"
)
==
0
||
strcmp
(
cmd
,
"out"
)
==
0
)
else
if
(
strcmp
(
cmd
,
"o"
)
==
0
||
strcmp
(
cmd
,
"out"
)
==
0
)
success
=
setQFout
(
options
[
0
]);
{
char
*
fname
=
scan_option
(
&
string
,
OT_NORMAL
,
NULL
);
success
=
setQFout
(
fname
);
free
(
fname
);
}
/* \p prints the current query buffer */
/* \p prints the current query buffer */
else
if
(
strcmp
(
cmd
,
"p"
)
==
0
||
strcmp
(
cmd
,
"print"
)
==
0
)
else
if
(
strcmp
(
cmd
,
"p"
)
==
0
||
strcmp
(
cmd
,
"print"
)
==
0
)
...
@@ -543,29 +485,24 @@ exec_command(const char *cmd,
...
@@ -543,29 +485,24 @@ exec_command(const char *cmd,
/* \pset -- set printing parameters */
/* \pset -- set printing parameters */
else
if
(
strcmp
(
cmd
,
"pset"
)
==
0
)
else
if
(
strcmp
(
cmd
,
"pset"
)
==
0
)
{
{
if
(
!
options
[
0
])
char
*
opt0
=
scan_option
(
&
string
,
OT_NORMAL
,
NULL
);
char
*
opt1
=
scan_option
(
&
string
,
OT_NORMAL
,
NULL
);
if
(
!
opt0
)
{
{
psql_error
(
"
\\
%s: missing required argument
\n
"
,
cmd
);
psql_error
(
"
\\
%s: missing required argument
\n
"
,
cmd
);
success
=
false
;
success
=
false
;
}
}
else
else
success
=
do_pset
(
options
[
0
],
options
[
1
],
&
pset
.
popt
,
quiet
);
success
=
do_pset
(
opt0
,
opt1
,
&
pset
.
popt
,
quiet
);
free
(
opt0
);
free
(
opt1
);
}
}
/* \q or \quit */
/* \q or \quit */
else
if
(
strcmp
(
cmd
,
"q"
)
==
0
||
strcmp
(
cmd
,
"quit"
)
==
0
)
else
if
(
strcmp
(
cmd
,
"q"
)
==
0
||
strcmp
(
cmd
,
"quit"
)
==
0
)
status
=
CMD_TERMINATE
;
status
=
CMD_TERMINATE
;
/* \qecho */
else
if
(
strcmp
(
cmd
,
"qecho"
)
==
0
)
{
int
i
;
for
(
i
=
0
;
i
<
16
&&
options
[
i
];
i
++
)
fputs
(
options
[
i
],
pset
.
queryFout
);
fputs
(
"
\n
"
,
pset
.
queryFout
);
}
/* reset(clear) the buffer */
/* reset(clear) the buffer */
else
if
(
strcmp
(
cmd
,
"r"
)
==
0
||
strcmp
(
cmd
,
"reset"
)
==
0
)
else
if
(
strcmp
(
cmd
,
"r"
)
==
0
||
strcmp
(
cmd
,
"reset"
)
==
0
)
{
{
...
@@ -574,34 +511,31 @@ exec_command(const char *cmd,
...
@@ -574,34 +511,31 @@ exec_command(const char *cmd,
puts
(
"Query buffer reset (cleared)."
);
puts
(
"Query buffer reset (cleared)."
);
}
}
/* \s save history in a file or show it on the screen */
/* \s save history in a file or show it on the screen */
else
if
(
strcmp
(
cmd
,
"s"
)
==
0
)
else
if
(
strcmp
(
cmd
,
"s"
)
==
0
)
{
{
c
onst
char
*
fname
;
c
har
*
fname
=
scan_option
(
&
string
,
OT_NORMAL
,
NULL
)
;
if
(
!
options
[
0
])
success
=
saveHistory
(
fname
?
fname
:
"/dev/tty"
);
fname
=
"/dev/tty"
;
else
fname
=
options
[
0
];
success
=
saveHistory
(
fname
);
if
(
success
&&
!
quiet
&&
options
[
0
]
)
if
(
success
&&
!
quiet
&&
fname
)
printf
(
"Wrote history to %s.
\n
"
,
fname
);
printf
(
"Wrote history to %s.
\n
"
,
fname
);
free
(
fname
);
}
}
/* \set -- generalized set variable/option command */
/* \set -- generalized set option command */
else
if
(
strcmp
(
cmd
,
"set"
)
==
0
)
else
if
(
strcmp
(
cmd
,
"set"
)
==
0
)
{
{
if
(
!
options
[
0
])
char
*
opt0
=
scan_option
(
&
string
,
OT_NORMAL
,
NULL
);
if
(
!
opt0
)
{
{
/* list all variables */
/* list all variables */
/*
/*
* (This is in utter violation of the GetVariable abstraction,
* XXX
* but I have not dreamt up a better way.)
* This is in utter violation of the GetVariable abstraction, but I
* have not bothered to do it better.
*/
*/
struct
_variable
*
ptr
;
struct
_variable
*
ptr
;
...
@@ -611,15 +545,36 @@ exec_command(const char *cmd,
...
@@ -611,15 +545,36 @@ exec_command(const char *cmd,
}
}
else
else
{
{
const
char
*
val
=
options
[
1
];
/*
if
(
!
val
)
* Set variable to the concatenation of the arguments.
val
=
""
;
*/
if
(
!
SetVariable
(
pset
.
vars
,
options
[
0
],
val
))
char
*
newval
=
NULL
;
char
*
opt
;
opt
=
scan_option
(
&
string
,
OT_NORMAL
,
NULL
);
newval
=
xstrdup
(
opt
?
opt
:
""
);
free
(
opt
);
while
((
opt
=
scan_option
(
&
string
,
OT_NORMAL
,
NULL
)))
{
newval
=
realloc
(
newval
,
strlen
(
newval
)
+
strlen
(
opt
)
+
1
);
if
(
!
newval
)
{
psql_error
(
"out of memory"
);
exit
(
EXIT_FAILURE
);
}
strcat
(
newval
,
opt
);
free
(
opt
);
}
if
(
!
SetVariable
(
pset
.
vars
,
opt0
,
newval
))
{
{
psql_error
(
"
\\
%s: error
\n
"
,
cmd
);
psql_error
(
"
\\
%s: error
\n
"
,
cmd
);
success
=
false
;
success
=
false
;
}
}
free
(
newval
);
}
}
free
(
opt0
);
}
}
/* \t -- turn off headers and row count */
/* \t -- turn off headers and row count */
...
@@ -629,47 +584,66 @@ exec_command(const char *cmd,
...
@@ -629,47 +584,66 @@ exec_command(const char *cmd,
/* \T -- define html <table ...> attributes */
/* \T -- define html <table ...> attributes */
else
if
(
strcmp
(
cmd
,
"T"
)
==
0
)
else
if
(
strcmp
(
cmd
,
"T"
)
==
0
)
success
=
do_pset
(
"tableattr"
,
options
[
0
],
&
pset
.
popt
,
quiet
);
{
char
*
value
=
scan_option
(
&
string
,
OT_NORMAL
,
NULL
);
success
=
do_pset
(
"tableattr"
,
value
,
&
pset
.
popt
,
quiet
);
free
(
value
);
}
/* \unset */
/* \unset */
else
if
(
strcmp
(
cmd
,
"unset"
)
==
0
)
else
if
(
strcmp
(
cmd
,
"unset"
)
==
0
)
{
{
if
(
!
SetVariable
(
pset
.
vars
,
options
[
0
],
NULL
))
char
*
opt
=
scan_option
(
&
string
,
OT_NORMAL
,
NULL
);
if
(
!
opt
)
{
psql_error
(
"
\\
%s: missing required argument"
,
cmd
);
success
=
false
;
}
if
(
!
SetVariable
(
pset
.
vars
,
opt
,
NULL
))
{
{
psql_error
(
"
\\
%s: error
\n
"
,
cmd
);
psql_error
(
"
\\
%s: error
\n
"
,
cmd
);
success
=
false
;
success
=
false
;
}
}
free
(
opt
);
}
}
/* \w -- write query buffer to file */
/* \w -- write query buffer to file */
else
if
(
strcmp
(
cmd
,
"w"
)
==
0
||
strcmp
(
cmd
,
"write"
)
==
0
)
else
if
(
strcmp
(
cmd
,
"w"
)
==
0
||
strcmp
(
cmd
,
"write"
)
==
0
)
{
{
FILE
*
fd
=
NULL
;
FILE
*
fd
=
NULL
;
bool
pipe
=
false
;
bool
is_pipe
=
false
;
char
*
fname
=
NULL
;
if
(
!
options
[
0
]
)
if
(
!
query_buf
)
{
{
psql_error
(
"
\\
%s: missing required argument
\n
"
,
cmd
);
psql_error
(
"
no query buffer"
);
success
=
false
;
status
=
CMD_ERROR
;
}
}
else
else
{
{
if
(
options
[
0
][
0
]
==
'|'
)
fname
=
scan_option
(
&
string
,
OT_NORMAL
,
NULL
);
if
(
!
fname
)
{
{
pipe
=
true
;
psql_error
(
"
\\
%s: missing required argument
\n
"
,
cmd
)
;
fd
=
popen
(
&
options
[
0
][
1
],
"w"
)
;
success
=
false
;
}
}
else
else
{
{
fd
=
fopen
(
options
[
0
],
"w"
);
if
(
fname
[
0
]
==
'|'
)
{
is_pipe
=
true
;
fd
=
popen
(
&
fname
[
1
],
"w"
);
}
}
else
fd
=
fopen
(
fname
,
"w"
);
if
(
!
fd
)
if
(
!
fd
)
{
{
psql_error
(
"%s: %s
\n
"
,
options
[
0
]
,
strerror
(
errno
));
psql_error
(
"%s: %s
\n
"
,
fname
,
strerror
(
errno
));
success
=
false
;
success
=
false
;
}
}
}
}
}
if
(
fd
)
if
(
fd
)
...
@@ -679,17 +653,19 @@ exec_command(const char *cmd,
...
@@ -679,17 +653,19 @@ exec_command(const char *cmd,
if
(
query_buf
&&
query_buf
->
len
>
0
)
if
(
query_buf
&&
query_buf
->
len
>
0
)
fprintf
(
fd
,
"%s
\n
"
,
query_buf
->
data
);
fprintf
(
fd
,
"%s
\n
"
,
query_buf
->
data
);
if
(
pipe
)
if
(
is_
pipe
)
result
=
pclose
(
fd
);
result
=
pclose
(
fd
);
else
else
result
=
fclose
(
fd
);
result
=
fclose
(
fd
);
if
(
result
==
EOF
)
if
(
result
==
EOF
)
{
{
psql_error
(
"%s: %s
\n
"
,
options
[
0
]
,
strerror
(
errno
));
psql_error
(
"%s: %s
\n
"
,
fname
,
strerror
(
errno
));
success
=
false
;
success
=
false
;
}
}
}
}
free
(
fname
);
}
}
/* \x -- toggle expanded table representation */
/* \x -- toggle expanded table representation */
...
@@ -697,30 +673,43 @@ exec_command(const char *cmd,
...
@@ -697,30 +673,43 @@ exec_command(const char *cmd,
success
=
do_pset
(
"expanded"
,
NULL
,
&
pset
.
popt
,
quiet
);
success
=
do_pset
(
"expanded"
,
NULL
,
&
pset
.
popt
,
quiet
);
/* list table rights (grant/revoke) */
/*
\z --
list table rights (grant/revoke) */
else
if
(
strcmp
(
cmd
,
"z"
)
==
0
)
else
if
(
strcmp
(
cmd
,
"z"
)
==
0
)
success
=
permissionsList
(
options
[
0
]);
{
char
*
opt
=
scan_option
(
&
string
,
OT_SQLID
,
NULL
);
success
=
permissionsList
(
opt
);
free
(
opt
);
}
/* \! -- shell escape */
else
if
(
strcmp
(
cmd
,
"!"
)
==
0
)
else
if
(
strcmp
(
cmd
,
"!"
)
==
0
)
{
success
=
do_shell
(
options_string
);
success
=
do_shell
(
options_string
);
/* wind pointer to end of line */
if
(
string
)
string
+=
strlen
(
string
);
}
/* \? -- slash command help */
else
if
(
strcmp
(
cmd
,
"?"
)
==
0
)
else
if
(
strcmp
(
cmd
,
"?"
)
==
0
)
slashUsage
();
slashUsage
();
#if 1
#if 0
/*
/*
* These commands don't do anything. I just use them to test the
* These commands don't do anything. I just use them to test the
* parser.
* parser.
*/
*/
else
if
(
strcmp
(
cmd
,
"void"
)
==
0
||
strcmp
(
cmd
,
"#"
)
==
0
)
else
if
(
strcmp
(
cmd
,
"void"
)
==
0
||
strcmp
(
cmd
,
"#"
)
==
0
)
{
{
int i;
int
i
=
0
;
char
*
value
;
fprintf(stderr, "+ optline = |%s|\n", options_string);
fprintf
(
stderr
,
"+ optstr = |%s|
\n
"
,
options_string
);
for (i = 0; options[i]; i++)
while
((
value
=
scan_option
(
&
string
,
OT_NORMAL
,
NULL
)))
fprintf(stderr, "+ opt%d = |%s|\n", i, options[i]);
{
fprintf
(
stderr
,
"+ opt(%d) = |%s|
\n
"
,
i
++
,
value
);
free
(
value
);
}
}
}
#endif
#endif
...
@@ -729,23 +718,300 @@ exec_command(const char *cmd,
...
@@ -729,23 +718,300 @@ exec_command(const char *cmd,
if
(
!
success
)
if
(
!
success
)
status
=
CMD_ERROR
;
status
=
CMD_ERROR
;
/* eat the rest of the options string */
while
(
scan_option
(
&
string
,
OT_NORMAL
,
NULL
))
;
if
(
options_string
&&
continue_parse
)
*
continue_parse
=
options_string
+
(
string
-
string_cpy
);
free
(
string_cpy
);
return
status
;
return
status
;
}
}
/*
* scan_option()
*/
static
char
*
scan_option
(
char
**
string
,
enum
option_type
type
,
char
*
quote
)
{
unsigned
int
pos
=
0
;
char
*
options_string
;
char
*
return_val
;
if
(
quote
)
*
quote
=
0
;
if
(
!
string
||
!
(
*
string
))
return
NULL
;
options_string
=
*
string
;
/* skip leading whitespace */
pos
+=
strspn
(
options_string
+
pos
,
"
\t
"
);
switch
(
options_string
[
pos
])
{
/*
* Double quoted string
*/
case
'"'
:
{
unsigned
int
jj
;
unsigned
short
int
bslash_count
=
0
;
/* scan for end of quote */
for
(
jj
=
pos
+
1
;
options_string
[
jj
];
jj
+=
PQmblen
(
&
options_string
[
jj
],
pset
.
encoding
))
{
if
(
options_string
[
jj
]
==
'"'
&&
bslash_count
%
2
==
0
)
break
;
if
(
options_string
[
jj
]
==
'\\'
)
bslash_count
++
;
else
bslash_count
=
0
;
}
if
(
options_string
[
jj
]
==
0
)
{
psql_error
(
"parse error at end of line
\n
"
);
*
string
=
&
options_string
[
jj
];
return
NULL
;
}
return_val
=
malloc
(
jj
-
pos
+
2
);
if
(
!
return_val
)
{
psql_error
(
"out of memory
\n
"
);
exit
(
EXIT_FAILURE
);
}
if
(
type
==
OT_NORMAL
)
{
strncpy
(
return_val
,
&
options_string
[
pos
],
jj
-
pos
+
1
);
return_val
[
jj
-
pos
+
1
]
=
'\0'
;
}
/*
* If this is expected to be an SQL identifier like option
* then we strip out the double quotes
*/
else
if
(
type
==
OT_SQLID
)
{
unsigned
int
k
,
cc
;
bslash_count
=
0
;
cc
=
0
;
for
(
k
=
pos
+
1
;
options_string
[
k
];
k
+=
PQmblen
(
&
options_string
[
k
],
pset
.
encoding
))
{
if
(
options_string
[
k
]
==
'"'
&&
bslash_count
%
2
==
0
)
break
;
if
(
options_string
[
jj
]
==
'\\'
)
bslash_count
++
;
else
bslash_count
=
0
;
return_val
[
cc
++
]
=
options_string
[
k
];
}
return_val
[
cc
]
=
'\0'
;
}
*
string
=
options_string
+
jj
+
1
;
if
(
quote
)
*
quote
=
'"'
;
return
return_val
;
}
/*
* A single quote has a psql internal meaning, such as
* for delimiting file names, and it also allows for such
* escape sequences as \t.
*/
case
'\''
:
{
unsigned
int
jj
;
unsigned
short
int
bslash_count
=
0
;
for
(
jj
=
pos
+
1
;
options_string
[
jj
];
jj
+=
PQmblen
(
&
options_string
[
jj
],
pset
.
encoding
))
{
if
(
options_string
[
jj
]
==
'\''
&&
bslash_count
%
2
==
0
)
break
;
if
(
options_string
[
jj
]
==
'\\'
)
bslash_count
++
;
else
bslash_count
=
0
;
}
if
(
options_string
[
jj
]
==
0
)
{
psql_error
(
"parse error at end of line
\n
"
);
*
string
=
&
options_string
[
jj
];
return
NULL
;
}
return_val
=
unescape
(
&
options_string
[
pos
+
1
],
jj
-
pos
-
1
);
*
string
=
&
options_string
[
jj
+
1
];
if
(
quote
)
*
quote
=
'\''
;
return
return_val
;
}
/*
* Backticks are for command substitution, like in shells
*/
case
'`'
:
{
bool
error
=
false
;
FILE
*
fd
=
NULL
;
char
*
file
;
PQExpBufferData
output
;
char
buf
[
512
];
size_t
result
,
len
;
len
=
strcspn
(
options_string
+
pos
+
1
,
"`"
);
if
(
options_string
[
pos
+
1
+
len
]
==
0
)
{
psql_error
(
"parse error at end of line
\n
"
);
*
string
=
&
options_string
[
pos
+
1
+
len
];
return
NULL
;
}
options_string
[
pos
+
1
+
len
]
=
'\0'
;
file
=
options_string
+
pos
+
1
;
fd
=
popen
(
file
,
"r"
);
if
(
!
fd
)
{
psql_error
(
"%s: %s
\n
"
,
file
,
strerror
(
errno
));
error
=
true
;
}
if
(
!
error
)
{
initPQExpBuffer
(
&
output
);
do
{
result
=
fread
(
buf
,
1
,
512
,
fd
);
if
(
ferror
(
fd
))
{
psql_error
(
"%s: %s
\n
"
,
file
,
strerror
(
errno
));
error
=
true
;
break
;
}
appendBinaryPQExpBuffer
(
&
output
,
buf
,
result
);
}
while
(
!
feof
(
fd
));
appendPQExpBufferChar
(
&
output
,
'\0'
);
if
(
pclose
(
fd
)
==
-
1
)
{
psql_error
(
"%s: %s
\n
"
,
file
,
strerror
(
errno
));
error
=
true
;
}
}
if
(
!
error
)
{
if
(
output
.
data
[
strlen
(
output
.
data
)
-
1
]
==
'\n'
)
output
.
data
[
strlen
(
output
.
data
)
-
1
]
=
'\0'
;
}
if
(
!
error
)
return_val
=
output
.
data
;
else
{
return_val
=
xstrdup
(
""
);
termPQExpBuffer
(
&
output
);
}
options_string
[
pos
+
1
+
len
]
=
'`'
;
*
string
=
options_string
+
pos
+
len
+
2
;
if
(
quote
)
*
quote
=
'`'
;
return
return_val
;
}
/*
* end of line
*/
case
0
:
*
string
=
&
options_string
[
pos
];
return
NULL
;
/*
* Variable substitution
*/
case
':'
:
{
size_t
token_end
;
const
char
*
value
;
char
save_char
;
token_end
=
strcspn
(
&
options_string
[
pos
+
1
],
"
\t
"
);
save_char
=
options_string
[
pos
+
token_end
+
1
];
options_string
[
pos
+
token_end
+
1
]
=
'\0'
;
value
=
GetVariable
(
pset
.
vars
,
options_string
+
pos
+
1
);
if
(
!
value
)
value
=
""
;
return_val
=
xstrdup
(
value
);
options_string
[
pos
+
token_end
+
1
]
=
save_char
;
*
string
=
&
options_string
[
pos
+
token_end
+
1
];
return
return_val
;
}
/*
* Next command
*/
case
'\\'
:
*
string
=
options_string
+
pos
;
return
NULL
;
break
;
/*
* A normal word
*/
default:
{
size_t
token_end
;
char
*
cp
;
token_end
=
strcspn
(
&
options_string
[
pos
],
"
\t
"
);
return_val
=
malloc
(
token_end
+
1
);
if
(
!
return_val
)
{
psql_error
(
"out of memory
\n
"
);
exit
(
EXIT_FAILURE
);
}
strncpy
(
return_val
,
&
options_string
[
pos
],
token_end
);
return_val
[
token_end
]
=
0
;
if
(
type
==
OT_SQLID
)
for
(
cp
=
return_val
;
*
cp
;
cp
+=
PQmblen
(
cp
,
pset
.
encoding
))
if
(
isascii
(
*
cp
))
*
cp
=
tolower
(
*
cp
);
*
string
=
&
options_string
[
pos
+
token_end
];
return
return_val
;
}
}
}
/*
/*
* unescape
* unescape
*
*
* Replaces \n, \t, and the like.
* Replaces \n, \t, and the like.
* Also interpolates ${variables}.
*
*
* The return value is malloc()'ed.
* The return value is malloc()'ed.
*/
*/
static
char
*
static
char
*
unescape
(
const
char
*
source
)
unescape
(
const
unsigned
char
*
source
,
size_t
len
)
{
{
unsigned
char
*
p
;
const
unsigned
char
*
p
;
bool
esc
=
false
;
/* Last character we saw was the escape
bool
esc
=
false
;
/* Last character we saw was the escape
* character */
* character */
char
*
destination
,
char
*
destination
,
...
@@ -756,16 +1022,16 @@ unescape(const char *source)
...
@@ -756,16 +1022,16 @@ unescape(const char *source)
assert
(
source
);
assert
(
source
);
#endif
#endif
length
=
strlen
(
source
)
+
1
;
length
=
Min
(
len
,
strlen
(
source
)
)
+
1
;
tmp
=
destination
=
(
char
*
)
malloc
(
length
);
tmp
=
destination
=
malloc
(
length
);
if
(
!
tmp
)
if
(
!
tmp
)
{
{
psql_error
(
"out of memory
\n
"
);
psql_error
(
"out of memory
\n
"
);
exit
(
EXIT_FAILURE
);
exit
(
EXIT_FAILURE
);
}
}
for
(
p
=
(
char
*
)
source
;
*
p
;
p
+=
PQmblen
(
p
,
pset
.
encoding
))
for
(
p
=
source
;
p
-
source
<
len
&&
*
p
;
p
+=
PQmblen
(
p
,
pset
.
encoding
))
{
{
if
(
esc
)
if
(
esc
)
{
{
...
@@ -776,12 +1042,15 @@ unescape(const char *source)
...
@@ -776,12 +1042,15 @@ unescape(const char *source)
case
'n'
:
case
'n'
:
c
=
'\n'
;
c
=
'\n'
;
break
;
break
;
case
'r'
:
c
=
'\r'
;
break
;
case
't'
:
case
't'
:
c
=
'\t'
;
c
=
'\t'
;
break
;
break
;
case
'b'
:
c
=
'\b'
;
break
;
case
'r'
:
c
=
'\r'
;
break
;
case
'f'
:
case
'f'
:
c
=
'\f'
;
c
=
'\f'
;
break
;
break
;
...
@@ -814,44 +1083,6 @@ unescape(const char *source)
...
@@ -814,44 +1083,6 @@ unescape(const char *source)
else
if
(
*
p
==
'\\'
)
else
if
(
*
p
==
'\\'
)
esc
=
true
;
esc
=
true
;
else
if
(
*
p
==
'$'
)
{
if
(
*
(
p
+
1
)
==
'{'
)
{
unsigned
int
len
;
char
*
copy
;
const
char
*
value
;
#ifndef WIN32
void
*
new
;
#else
char
*
new
;
#endif
len
=
strcspn
(
p
+
2
,
"}"
);
copy
=
xstrdup
(
p
+
2
);
copy
[
len
]
=
'\0'
;
value
=
GetVariable
(
pset
.
vars
,
copy
);
if
(
!
value
)
value
=
""
;
length
+=
strlen
(
value
)
-
(
len
+
3
);
new
=
realloc
(
destination
,
length
);
if
(
!
new
)
{
psql_error
(
"out of memory
\n
"
);
exit
(
EXIT_FAILURE
);
}
tmp
=
new
+
(
tmp
-
destination
);
destination
=
new
;
strcpy
(
tmp
,
value
);
tmp
+=
strlen
(
value
);
p
+=
len
+
2
;
free
(
copy
);
}
else
*
tmp
++
=
'$'
;
}
else
else
{
{
*
tmp
++
=
*
p
;
*
tmp
++
=
*
p
;
...
@@ -865,7 +1096,6 @@ unescape(const char *source)
...
@@ -865,7 +1096,6 @@ unescape(const char *source)
/* do_connect
/* do_connect
* -- handler for \connect
* -- handler for \connect
*
*
...
@@ -893,8 +1123,8 @@ do_connect(const char *new_dbname, const char *new_user)
...
@@ -893,8 +1123,8 @@ do_connect(const char *new_dbname, const char *new_user)
SetVariable
(
pset
.
vars
,
"HOST"
,
NULL
);
SetVariable
(
pset
.
vars
,
"HOST"
,
NULL
);
SetVariable
(
pset
.
vars
,
"PORT"
,
NULL
);
SetVariable
(
pset
.
vars
,
"PORT"
,
NULL
);
/* If dbname is "
-
" then use old name, else new one (even if NULL) */
/* If dbname is "" then use old name, else new one (even if NULL) */
if
(
oldconn
&&
new_dbname
&&
PQdb
(
oldconn
)
&&
strcmp
(
new_dbname
,
"
-
"
)
==
0
)
if
(
oldconn
&&
new_dbname
&&
PQdb
(
oldconn
)
&&
strcmp
(
new_dbname
,
""
)
==
0
)
dbparam
=
PQdb
(
oldconn
);
dbparam
=
PQdb
(
oldconn
);
else
else
dbparam
=
new_dbname
;
dbparam
=
new_dbname
;
...
@@ -1001,7 +1231,7 @@ do_connect(const char *new_dbname, const char *new_user)
...
@@ -1001,7 +1231,7 @@ do_connect(const char *new_dbname, const char *new_user)
/*
/*
* Test if the given user is a database superuser.
* Test if the given user is a database superuser.
* (
U
sed to set up the prompt right.)
* (
Is u
sed to set up the prompt right.)
*/
*/
bool
bool
test_superuser
(
const
char
*
username
)
test_superuser
(
const
char
*
username
)
...
@@ -1037,7 +1267,7 @@ test_superuser(const char * username)
...
@@ -1037,7 +1267,7 @@ test_superuser(const char * username)
static
bool
static
bool
editFile
(
const
char
*
fname
)
editFile
(
const
char
*
fname
)
{
{
c
har
*
editorName
;
c
onst
char
*
editorName
;
char
*
sys
;
char
*
sys
;
int
result
;
int
result
;
...
@@ -1063,7 +1293,7 @@ editFile(const char *fname)
...
@@ -1063,7 +1293,7 @@ editFile(const char *fname)
sprintf
(
sys
,
"exec %s %s"
,
editorName
,
fname
);
sprintf
(
sys
,
"exec %s %s"
,
editorName
,
fname
);
result
=
system
(
sys
);
result
=
system
(
sys
);
if
(
result
==
-
1
)
if
(
result
==
-
1
)
psql_error
(
"could not start editor
\n
"
);
psql_error
(
"could not start editor
%s
\n
"
,
editorName
);
else
if
(
result
==
127
)
else
if
(
result
==
127
)
psql_error
(
"could not start /bin/sh
\n
"
);
psql_error
(
"could not start /bin/sh
\n
"
);
free
(
sys
);
free
(
sys
);
...
@@ -1087,14 +1317,6 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf)
...
@@ -1087,14 +1317,6 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf)
#endif
#endif
#ifdef USE_ASSERT_CHECKING
assert
(
query_buf
);
#else
if
(
!
query_buf
)
return
false
;
#endif
if
(
filename_arg
)
if
(
filename_arg
)
fname
=
filename_arg
;
fname
=
filename_arg
;
...
@@ -1233,11 +1455,7 @@ process_file(char *filename)
...
@@ -1233,11 +1455,7 @@ process_file(char *filename)
if
(
!
filename
)
if
(
!
filename
)
return
false
;
return
false
;
#ifdef __CYGWIN32__
fd
=
fopen
(
filename
,
"rb"
);
#else
fd
=
fopen
(
filename
,
"r"
);
fd
=
fopen
(
filename
,
"r"
);
#endif
if
(
!
fd
)
if
(
!
fd
)
{
{
...
@@ -1464,7 +1682,7 @@ do_shell(const char *command)
...
@@ -1464,7 +1682,7 @@ do_shell(const char *command)
if
(
!
command
)
if
(
!
command
)
{
{
char
*
sys
;
char
*
sys
;
c
har
*
shellName
;
c
onst
char
*
shellName
;
shellName
=
getenv
(
"SHELL"
);
shellName
=
getenv
(
"SHELL"
);
if
(
shellName
==
NULL
)
if
(
shellName
==
NULL
)
...
...
src/bin/psql/common.c
View file @
9ceb5d8a
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
*
*
* Copyright 2000 by PostgreSQL Global Development Group
* Copyright 2000 by PostgreSQL Global Development Group
*
*
* $Header: /cvsroot/pgsql/src/bin/psql/common.c,v 1.1
1 2000/01/29 16:58:48
petere Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/common.c,v 1.1
2 2000/02/07 23:10:06
petere Exp $
*/
*/
#include <c.h>
#include <c.h>
#include "common.h"
#include "common.h"
...
@@ -24,6 +24,7 @@
...
@@ -24,6 +24,7 @@
#include <unistd.h>
/* for write() */
#include <unistd.h>
/* for write() */
#else
#else
#include <io.h>
/* for _write() */
#include <io.h>
/* for _write() */
#include <win32.h>
#endif
#endif
#include <libpq-fe.h>
#include <libpq-fe.h>
...
@@ -37,18 +38,10 @@
...
@@ -37,18 +38,10 @@
#include "prompt.h"
#include "prompt.h"
#include "print.h"
#include "print.h"
#ifdef WIN32
#define popen(x,y) _popen(x,y)
#define pclose(x) _pclose(x)
#define write(a,b,c) _write(a,b,c)
#endif
/* xstrdup()
/*
*
* "Safe" wrapper around strdup()
* "Safe" wrapper around strdup()
* (Using this also avoids writing #ifdef HAVE_STRDUP in every file :)
*/
*/
char
*
char
*
xstrdup
(
const
char
*
string
)
xstrdup
(
const
char
*
string
)
...
@@ -57,7 +50,8 @@ xstrdup(const char *string)
...
@@ -57,7 +50,8 @@ xstrdup(const char *string)
if
(
!
string
)
if
(
!
string
)
{
{
fprintf
(
stderr
,
"%s: xstrdup: cannot duplicate null pointer
\n
"
,
pset
.
progname
);
fprintf
(
stderr
,
"%s: xstrdup: cannot duplicate null pointer (internal error)
\n
"
,
pset
.
progname
);
exit
(
EXIT_FAILURE
);
exit
(
EXIT_FAILURE
);
}
}
tmp
=
strdup
(
string
);
tmp
=
strdup
(
string
);
...
@@ -133,7 +127,7 @@ setQFout(const char *fname)
...
@@ -133,7 +127,7 @@ setQFout(const char *fname)
/*
/*
* Error reporting for scripts. Errors should look like
* Error reporting for scripts. Errors should look like
* filename:lineno: message
*
psql:
filename:lineno: message
*
*
*/
*/
void
void
...
@@ -152,8 +146,11 @@ psql_error(const char *fmt, ...)
...
@@ -152,8 +146,11 @@ psql_error(const char *fmt, ...)
va_end
(
ap
);
va_end
(
ap
);
}
}
/* for backend NOTICES */
/*
* for backend NOTICES
*/
void
void
NoticeProcessor
(
void
*
arg
,
const
char
*
message
)
NoticeProcessor
(
void
*
arg
,
const
char
*
message
)
{
{
...
@@ -184,7 +181,6 @@ simple_prompt(const char *prompt, int maxlen, bool echo)
...
@@ -184,7 +181,6 @@ simple_prompt(const char *prompt, int maxlen, bool echo)
#ifdef HAVE_TERMIOS_H
#ifdef HAVE_TERMIOS_H
struct
termios
t_orig
,
struct
termios
t_orig
,
t
;
t
;
#endif
#endif
destination
=
(
char
*
)
malloc
(
maxlen
+
2
);
destination
=
(
char
*
)
malloc
(
maxlen
+
2
);
...
@@ -240,8 +236,8 @@ simple_prompt(const char *prompt, int maxlen, bool echo)
...
@@ -240,8 +236,8 @@ simple_prompt(const char *prompt, int maxlen, bool echo)
* Before we start a query, we enable a SIGINT signal catcher that sends a
* Before we start a query, we enable a SIGINT signal catcher that sends a
* cancel request to the backend. Note that sending the cancel directly from
* cancel request to the backend. Note that sending the cancel directly from
* the signal handler is safe because PQrequestCancel() is written to make it
* the signal handler is safe because PQrequestCancel() is written to make it
* so. We
have to be very careful what else we do in the signal handler. This
* so. We
use write() to print to stdout because it's better to use simple
*
includes using write() for output
.
*
facilities in a signal handler
.
*/
*/
static
PGconn
*
cancelConn
;
static
PGconn
*
cancelConn
;
...
...
src/bin/psql/create_help.pl
View file @
9ceb5d8a
...
@@ -5,7 +5,7 @@
...
@@ -5,7 +5,7 @@
#
#
# Copyright 2000 by PostgreSQL Global Development Group
# Copyright 2000 by PostgreSQL Global Development Group
#
#
# $Header: /cvsroot/pgsql/src/bin/psql/create_help.pl,v 1.
3 2000/01/29 16:58:48
petere Exp $
# $Header: /cvsroot/pgsql/src/bin/psql/create_help.pl,v 1.
4 2000/02/07 23:10:06
petere Exp $
#################################################################
#################################################################
#
#
...
@@ -56,6 +56,8 @@ struct _helpStruct
...
@@ -56,6 +56,8 @@ struct _helpStruct
static struct _helpStruct QL_HELP[] = {
static struct _helpStruct QL_HELP[] = {
";
";
$count
=
0
;
foreach
$file
(
sort
readdir
DIR
)
{
foreach
$file
(
sort
readdir
DIR
)
{
my
(
$cmdname
,
$cmddesc
,
$cmdsynopsis
);
my
(
$cmdname
,
$cmddesc
,
$cmdsynopsis
);
$file
=~
/\.sgml$/
||
next
;
$file
=~
/\.sgml$/
||
next
;
...
@@ -84,6 +86,7 @@ foreach $file (sort readdir DIR) {
...
@@ -84,6 +86,7 @@ foreach $file (sort readdir DIR) {
$cmdsynopsis
=~
s/\"/\\"/g
;
$cmdsynopsis
=~
s/\"/\\"/g
;
print
OUT
"
{
\"
$cmdname
\"
,
\n
\"
$cmddesc
\"
,
\n
\"
$cmdsynopsis
\"
},
\n\n
";
print
OUT
"
{
\"
$cmdname
\"
,
\n
\"
$cmddesc
\"
,
\n
\"
$cmdsynopsis
\"
},
\n\n
";
$count
++
;
}
}
else
{
else
{
print
STDERR
"
$0: parsing file '
$file
' failed at or near line $. (N='
$cmdname
' D='
$cmddesc
')
\n
";
print
STDERR
"
$0: parsing file '
$file
' failed at or near line $. (N='
$cmdname
' D='
$cmddesc
')
\n
";
...
@@ -94,6 +97,10 @@ print OUT "
...
@@ -94,6 +97,10 @@ print OUT "
{ NULL, NULL, NULL } /* End of list marker */
{ NULL, NULL, NULL } /* End of list marker */
};
};
#define QL_HELP_COUNT
$count
#endif /*
$define
*/
#endif /*
$define
*/
";
";
...
...
src/bin/psql/describe.c
View file @
9ceb5d8a
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
*
*
* Copyright 2000 by PostgreSQL Global Development Group
* Copyright 2000 by PostgreSQL Global Development Group
*
*
* $Header: /cvsroot/pgsql/src/bin/psql/describe.c,v 1.1
5 2000/01/29 16:58:48
petere Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/describe.c,v 1.1
6 2000/02/07 23:10:06
petere Exp $
*/
*/
#include <c.h>
#include <c.h>
#include "describe.h"
#include "describe.h"
...
@@ -56,7 +56,7 @@ describeAggregates(const char *name)
...
@@ -56,7 +56,7 @@ describeAggregates(const char *name)
if
(
name
)
if
(
name
)
{
{
strcat
(
buf
,
" AND a.aggname ~* '"
);
strcat
(
buf
,
" AND a.aggname ~* '
^
"
);
strncat
(
buf
,
name
,
REGEXP_CUTOFF
);
strncat
(
buf
,
name
,
REGEXP_CUTOFF
);
strcat
(
buf
,
"'
\n
"
);
strcat
(
buf
,
"'
\n
"
);
}
}
...
@@ -71,7 +71,7 @@ describeAggregates(const char *name)
...
@@ -71,7 +71,7 @@ describeAggregates(const char *name)
if
(
name
)
if
(
name
)
{
{
strcat
(
buf
,
" AND a.aggname ~* '"
);
strcat
(
buf
,
" AND a.aggname ~* '
^
"
);
strncat
(
buf
,
name
,
REGEXP_CUTOFF
);
strncat
(
buf
,
name
,
REGEXP_CUTOFF
);
strcat
(
buf
,
"'
\n
"
);
strcat
(
buf
,
"'
\n
"
);
}
}
...
@@ -125,7 +125,7 @@ describeFunctions(const char *name, bool verbose)
...
@@ -125,7 +125,7 @@ describeFunctions(const char *name, bool verbose)
if
(
name
)
if
(
name
)
{
{
strcat
(
buf
,
" AND p.proname ~* '"
);
strcat
(
buf
,
" AND p.proname ~* '
^
"
);
strncat
(
buf
,
name
,
REGEXP_CUTOFF
);
strncat
(
buf
,
name
,
REGEXP_CUTOFF
);
strcat
(
buf
,
"'
\n
"
);
strcat
(
buf
,
"'
\n
"
);
}
}
...
@@ -169,7 +169,7 @@ describeTypes(const char *name, bool verbose)
...
@@ -169,7 +169,7 @@ describeTypes(const char *name, bool verbose)
if
(
name
)
if
(
name
)
{
{
strcat
(
buf
,
" AND t.typname ~* '"
);
strcat
(
buf
,
" AND t.typname ~* '
^
"
);
strncat
(
buf
,
name
,
REGEXP_CUTOFF
);
strncat
(
buf
,
name
,
REGEXP_CUTOFF
);
strcat
(
buf
,
"' "
);
strcat
(
buf
,
"' "
);
}
}
...
@@ -215,7 +215,7 @@ describeOperators(const char *name)
...
@@ -215,7 +215,7 @@ describeOperators(const char *name)
" o.oprright = t2.oid
\n
"
);
" o.oprright = t2.oid
\n
"
);
if
(
name
)
if
(
name
)
{
{
strcat
(
buf
,
" AND o.oprname ~ '"
);
strcat
(
buf
,
" AND o.oprname ~ '
^
"
);
strncat
(
buf
,
name
,
REGEXP_CUTOFF
);
strncat
(
buf
,
name
,
REGEXP_CUTOFF
);
strcat
(
buf
,
"'
\n
"
);
strcat
(
buf
,
"'
\n
"
);
}
}
...
@@ -233,7 +233,7 @@ describeOperators(const char *name)
...
@@ -233,7 +233,7 @@ describeOperators(const char *name)
" o.oprright = t1.oid
\n
"
);
" o.oprright = t1.oid
\n
"
);
if
(
name
)
if
(
name
)
{
{
strcat
(
buf
,
"AND o.oprname ~ '"
);
strcat
(
buf
,
"AND o.oprname ~ '
^
"
);
strncat
(
buf
,
name
,
REGEXP_CUTOFF
);
strncat
(
buf
,
name
,
REGEXP_CUTOFF
);
strcat
(
buf
,
"'
\n
"
);
strcat
(
buf
,
"'
\n
"
);
}
}
...
@@ -251,7 +251,7 @@ describeOperators(const char *name)
...
@@ -251,7 +251,7 @@ describeOperators(const char *name)
" o.oprleft = t1.oid
\n
"
);
" o.oprleft = t1.oid
\n
"
);
if
(
name
)
if
(
name
)
{
{
strcat
(
buf
,
"AND o.oprname ~ '"
);
strcat
(
buf
,
"AND o.oprname ~ '
^
"
);
strncat
(
buf
,
name
,
REGEXP_CUTOFF
);
strncat
(
buf
,
name
,
REGEXP_CUTOFF
);
strcat
(
buf
,
"'
\n
"
);
strcat
(
buf
,
"'
\n
"
);
}
}
...
@@ -346,7 +346,7 @@ permissionsList(const char *name)
...
@@ -346,7 +346,7 @@ permissionsList(const char *name)
" relname !~ '^pg_'
\n
"
);
" relname !~ '^pg_'
\n
"
);
if
(
name
)
if
(
name
)
{
{
strcat
(
descbuf
,
" AND relname ~ '"
);
strcat
(
descbuf
,
" AND relname ~ '
^
"
);
strncat
(
descbuf
,
name
,
REGEXP_CUTOFF
);
strncat
(
descbuf
,
name
,
REGEXP_CUTOFF
);
strcat
(
descbuf
,
"'
\n
"
);
strcat
(
descbuf
,
"'
\n
"
);
}
}
...
@@ -391,7 +391,7 @@ objectDescription(const char *object)
...
@@ -391,7 +391,7 @@ objectDescription(const char *object)
"WHERE a.oid = d.objoid
\n
"
);
"WHERE a.oid = d.objoid
\n
"
);
if
(
object
)
if
(
object
)
{
{
strcat
(
descbuf
,
" AND a.aggname ~* '"
);
strcat
(
descbuf
,
" AND a.aggname ~* '
^
"
);
strncat
(
descbuf
,
object
,
REGEXP_CUTOFF
);
strncat
(
descbuf
,
object
,
REGEXP_CUTOFF
);
strcat
(
descbuf
,
"'
\n
"
);
strcat
(
descbuf
,
"'
\n
"
);
}
}
...
@@ -403,7 +403,7 @@ objectDescription(const char *object)
...
@@ -403,7 +403,7 @@ objectDescription(const char *object)
"WHERE p.oid = d.objoid AND (p.pronargs = 0 or oidvectortypes(p.proargtypes) != '')
\n
"
);
"WHERE p.oid = d.objoid AND (p.pronargs = 0 or oidvectortypes(p.proargtypes) != '')
\n
"
);
if
(
object
)
if
(
object
)
{
{
strcat
(
descbuf
,
" AND p.proname ~* '"
);
strcat
(
descbuf
,
" AND p.proname ~* '
^
"
);
strncat
(
descbuf
,
object
,
REGEXP_CUTOFF
);
strncat
(
descbuf
,
object
,
REGEXP_CUTOFF
);
strcat
(
descbuf
,
"'
\n
"
);
strcat
(
descbuf
,
"'
\n
"
);
}
}
...
@@ -416,7 +416,7 @@ objectDescription(const char *object)
...
@@ -416,7 +416,7 @@ objectDescription(const char *object)
"WHERE RegprocToOid(o.oprcode) = d.objoid
\n
"
);
"WHERE RegprocToOid(o.oprcode) = d.objoid
\n
"
);
if
(
object
)
if
(
object
)
{
{
strcat
(
descbuf
,
" AND o.oprname ~ '"
);
strcat
(
descbuf
,
" AND o.oprname ~ '
^
"
);
strncat
(
descbuf
,
object
,
REGEXP_CUTOFF
);
strncat
(
descbuf
,
object
,
REGEXP_CUTOFF
);
strcat
(
descbuf
,
"'
\n
"
);
strcat
(
descbuf
,
"'
\n
"
);
}
}
...
@@ -428,7 +428,7 @@ objectDescription(const char *object)
...
@@ -428,7 +428,7 @@ objectDescription(const char *object)
"WHERE t.oid = d.objoid
\n
"
);
"WHERE t.oid = d.objoid
\n
"
);
if
(
object
)
if
(
object
)
{
{
strcat
(
descbuf
,
" AND t.typname ~* '"
);
strcat
(
descbuf
,
" AND t.typname ~* '
^
"
);
strncat
(
descbuf
,
object
,
REGEXP_CUTOFF
);
strncat
(
descbuf
,
object
,
REGEXP_CUTOFF
);
strcat
(
descbuf
,
"'
\n
"
);
strcat
(
descbuf
,
"'
\n
"
);
}
}
...
@@ -440,7 +440,7 @@ objectDescription(const char *object)
...
@@ -440,7 +440,7 @@ objectDescription(const char *object)
"WHERE c.oid = d.objoid
\n
"
);
"WHERE c.oid = d.objoid
\n
"
);
if
(
object
)
if
(
object
)
{
{
strcat
(
descbuf
,
" AND c.relname ~* '"
);
strcat
(
descbuf
,
" AND c.relname ~* '
^
"
);
strncat
(
descbuf
,
object
,
REGEXP_CUTOFF
);
strncat
(
descbuf
,
object
,
REGEXP_CUTOFF
);
strcat
(
descbuf
,
"'
\n
"
);
strcat
(
descbuf
,
"'
\n
"
);
}
}
...
@@ -452,7 +452,7 @@ objectDescription(const char *object)
...
@@ -452,7 +452,7 @@ objectDescription(const char *object)
"WHERE r.oid = d.objoid AND r.rulename !~ '^_RET'
\n
"
);
"WHERE r.oid = d.objoid AND r.rulename !~ '^_RET'
\n
"
);
if
(
object
)
if
(
object
)
{
{
strcat
(
descbuf
,
" AND r.rulename ~* '"
);
strcat
(
descbuf
,
" AND r.rulename ~* '
^
"
);
strncat
(
descbuf
,
object
,
REGEXP_CUTOFF
);
strncat
(
descbuf
,
object
,
REGEXP_CUTOFF
);
strcat
(
descbuf
,
"'
\n
"
);
strcat
(
descbuf
,
"'
\n
"
);
}
}
...
@@ -464,7 +464,7 @@ objectDescription(const char *object)
...
@@ -464,7 +464,7 @@ objectDescription(const char *object)
"WHERE t.oid = d.objoid
\n
"
);
"WHERE t.oid = d.objoid
\n
"
);
if
(
object
)
if
(
object
)
{
{
strcat
(
descbuf
,
" AND t.tgname ~* '"
);
strcat
(
descbuf
,
" AND t.tgname ~* '
^
"
);
strncat
(
descbuf
,
object
,
REGEXP_CUTOFF
);
strncat
(
descbuf
,
object
,
REGEXP_CUTOFF
);
strcat
(
descbuf
,
"'
\n
"
);
strcat
(
descbuf
,
"'
\n
"
);
}
}
...
@@ -504,7 +504,7 @@ xmalloc(size_t size)
...
@@ -504,7 +504,7 @@ xmalloc(size_t size)
tmp
=
malloc
(
size
);
tmp
=
malloc
(
size
);
if
(
!
tmp
)
if
(
!
tmp
)
{
{
psql_error
(
"out of memory"
);
psql_error
(
"out of memory
\n
"
);
exit
(
EXIT_FAILURE
);
exit
(
EXIT_FAILURE
);
}
}
return
tmp
;
return
tmp
;
...
@@ -626,7 +626,7 @@ describeTableDetails(const char *name, bool desc)
...
@@ -626,7 +626,7 @@ describeTableDetails(const char *name, bool desc)
bool
isarray
=
false
;
bool
isarray
=
false
;
/* Name */
/* Name */
cells
[
i
*
cols
+
0
]
=
(
char
*
)
PQgetvalue
(
res
,
i
,
0
);
/* don't free this afterwards */
cells
[
i
*
cols
+
0
]
=
PQgetvalue
(
res
,
i
,
0
);
/* don't free this afterwards */
/* Type */
/* Type */
if
(
attype
[
0
]
==
'_'
)
if
(
attype
[
0
]
==
'_'
)
...
@@ -701,7 +701,7 @@ describeTableDetails(const char *name, bool desc)
...
@@ -701,7 +701,7 @@ describeTableDetails(const char *name, bool desc)
/* Description */
/* Description */
if
(
desc
)
if
(
desc
)
cells
[
i
*
cols
+
cols
-
1
]
=
(
char
*
)
PQgetvalue
(
res
,
i
,
7
);
cells
[
i
*
cols
+
cols
-
1
]
=
PQgetvalue
(
res
,
i
,
7
);
}
}
/* Make title */
/* Make title */
...
@@ -960,7 +960,7 @@ listTables(const char *infotype, const char *name, bool desc)
...
@@ -960,7 +960,7 @@ listTables(const char *infotype, const char *name, bool desc)
strcat
(
buf
,
showSystem
?
" AND c.relname ~ '^pg_'
\n
"
:
" AND c.relname !~ '^pg_'
\n
"
);
strcat
(
buf
,
showSystem
?
" AND c.relname ~ '^pg_'
\n
"
:
" AND c.relname !~ '^pg_'
\n
"
);
if
(
name
)
if
(
name
)
{
{
strcat
(
buf
,
" AND c.relname ~ '"
);
strcat
(
buf
,
" AND c.relname ~ '
^
"
);
strncat
(
buf
,
name
,
REGEXP_CUTOFF
);
strncat
(
buf
,
name
,
REGEXP_CUTOFF
);
strcat
(
buf
,
"'
\n
"
);
strcat
(
buf
,
"'
\n
"
);
}
}
...
@@ -976,7 +976,7 @@ listTables(const char *infotype, const char *name, bool desc)
...
@@ -976,7 +976,7 @@ listTables(const char *infotype, const char *name, bool desc)
strcat
(
buf
,
showSystem
?
" AND c.relname ~ '^pg_'
\n
"
:
" AND c.relname !~ '^pg_'
\n
"
);
strcat
(
buf
,
showSystem
?
" AND c.relname ~ '^pg_'
\n
"
:
" AND c.relname !~ '^pg_'
\n
"
);
if
(
name
)
if
(
name
)
{
{
strcat
(
buf
,
" AND c.relname ~ '"
);
strcat
(
buf
,
" AND c.relname ~ '
^
"
);
strncat
(
buf
,
name
,
REGEXP_CUTOFF
);
strncat
(
buf
,
name
,
REGEXP_CUTOFF
);
strcat
(
buf
,
"'
\n
"
);
strcat
(
buf
,
"'
\n
"
);
}
}
...
@@ -997,7 +997,7 @@ listTables(const char *infotype, const char *name, bool desc)
...
@@ -997,7 +997,7 @@ listTables(const char *infotype, const char *name, bool desc)
strcat
(
buf
,
showSystem
?
" AND c.relname ~ '^pg_'
\n
"
:
" AND c.relname !~ '^pg_'
\n
"
);
strcat
(
buf
,
showSystem
?
" AND c.relname ~ '^pg_'
\n
"
:
" AND c.relname !~ '^pg_'
\n
"
);
if
(
name
)
if
(
name
)
{
{
strcat
(
buf
,
" AND c.relname ~ '"
);
strcat
(
buf
,
" AND c.relname ~ '
^
"
);
strncat
(
buf
,
name
,
REGEXP_CUTOFF
);
strncat
(
buf
,
name
,
REGEXP_CUTOFF
);
strcat
(
buf
,
"'
\n
"
);
strcat
(
buf
,
"'
\n
"
);
}
}
...
@@ -1013,7 +1013,7 @@ listTables(const char *infotype, const char *name, bool desc)
...
@@ -1013,7 +1013,7 @@ listTables(const char *infotype, const char *name, bool desc)
strcat
(
buf
,
showSystem
?
" AND c.relname ~ '^pg_'
\n
"
:
" AND c.relname !~ '^pg_'
\n
"
);
strcat
(
buf
,
showSystem
?
" AND c.relname ~ '^pg_'
\n
"
:
" AND c.relname !~ '^pg_'
\n
"
);
if
(
name
)
if
(
name
)
{
{
strcat
(
buf
,
" AND c.relname ~ '"
);
strcat
(
buf
,
" AND c.relname ~ '
^
"
);
strncat
(
buf
,
name
,
REGEXP_CUTOFF
);
strncat
(
buf
,
name
,
REGEXP_CUTOFF
);
strcat
(
buf
,
"'
\n
"
);
strcat
(
buf
,
"'
\n
"
);
}
}
...
@@ -1049,7 +1049,7 @@ listTables(const char *infotype, const char *name, bool desc)
...
@@ -1049,7 +1049,7 @@ listTables(const char *infotype, const char *name, bool desc)
strcat
(
buf
,
showSystem
?
" AND c.relname ~ '^pg_'
\n
"
:
" AND c.relname !~ '^pg_'
\n
"
);
strcat
(
buf
,
showSystem
?
" AND c.relname ~ '^pg_'
\n
"
:
" AND c.relname !~ '^pg_'
\n
"
);
if
(
name
)
if
(
name
)
{
{
strcat
(
buf
,
" AND c.relname ~ '"
);
strcat
(
buf
,
" AND c.relname ~ '
^
"
);
strncat
(
buf
,
name
,
REGEXP_CUTOFF
);
strncat
(
buf
,
name
,
REGEXP_CUTOFF
);
strcat
(
buf
,
"'
\n
"
);
strcat
(
buf
,
"'
\n
"
);
}
}
...
@@ -1079,7 +1079,7 @@ listTables(const char *infotype, const char *name, bool desc)
...
@@ -1079,7 +1079,7 @@ listTables(const char *infotype, const char *name, bool desc)
strcat
(
buf
,
showSystem
?
" AND c.relname ~ '^pg_'
\n
"
:
" AND c.relname !~ '^pg_'
\n
"
);
strcat
(
buf
,
showSystem
?
" AND c.relname ~ '^pg_'
\n
"
:
" AND c.relname !~ '^pg_'
\n
"
);
if
(
name
)
if
(
name
)
{
{
strcat
(
buf
,
" AND c.relname ~ '"
);
strcat
(
buf
,
" AND c.relname ~ '
^
"
);
strncat
(
buf
,
name
,
REGEXP_CUTOFF
);
strncat
(
buf
,
name
,
REGEXP_CUTOFF
);
strcat
(
buf
,
"'
\n
"
);
strcat
(
buf
,
"'
\n
"
);
}
}
...
@@ -1098,7 +1098,7 @@ listTables(const char *infotype, const char *name, bool desc)
...
@@ -1098,7 +1098,7 @@ listTables(const char *infotype, const char *name, bool desc)
"WHERE c.relowner = u.usesysid AND c.relkind = 's'
\n
"
);
"WHERE c.relowner = u.usesysid AND c.relkind = 's'
\n
"
);
if
(
name
)
if
(
name
)
{
{
strcat
(
buf
,
" AND c.relname ~ '"
);
strcat
(
buf
,
" AND c.relname ~ '
^
"
);
strncat
(
buf
,
name
,
REGEXP_CUTOFF
);
strncat
(
buf
,
name
,
REGEXP_CUTOFF
);
strcat
(
buf
,
"'
\n
"
);
strcat
(
buf
,
"'
\n
"
);
}
}
...
@@ -1112,7 +1112,7 @@ listTables(const char *infotype, const char *name, bool desc)
...
@@ -1112,7 +1112,7 @@ listTables(const char *infotype, const char *name, bool desc)
" AND not exists (select 1 from pg_user where usesysid = c.relowner)"
);
" AND not exists (select 1 from pg_user where usesysid = c.relowner)"
);
if
(
name
)
if
(
name
)
{
{
strcat
(
buf
,
" AND c.relname ~ '"
);
strcat
(
buf
,
" AND c.relname ~ '
^
"
);
strncat
(
buf
,
name
,
REGEXP_CUTOFF
);
strncat
(
buf
,
name
,
REGEXP_CUTOFF
);
strcat
(
buf
,
"'
\n
"
);
strcat
(
buf
,
"'
\n
"
);
}
}
...
...
src/bin/psql/help.c
View file @
9ceb5d8a
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
*
*
* Copyright 2000 by PostgreSQL Global Development Group
* Copyright 2000 by PostgreSQL Global Development Group
*
*
* $Header: /cvsroot/pgsql/src/bin/psql/help.c,v 1.1
5 2000/01/29 16:58:48
petere Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/help.c,v 1.1
6 2000/02/07 23:10:06
petere Exp $
*/
*/
#include <c.h>
#include <c.h>
#include "help.h"
#include "help.h"
...
@@ -11,6 +11,7 @@
...
@@ -11,6 +11,7 @@
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <signal.h>
#include <signal.h>
#include <errno.h>
#ifndef WIN32
#ifndef WIN32
#include <sys/ioctl.h>
/* for ioctl() */
#include <sys/ioctl.h>
/* for ioctl() */
...
@@ -20,9 +21,7 @@
...
@@ -20,9 +21,7 @@
#include <sys/types.h>
/* (ditto) */
#include <sys/types.h>
/* (ditto) */
#include <unistd.h>
/* for getuid() */
#include <unistd.h>
/* for getuid() */
#else
#else
#define strcasecmp(x,y) stricmp(x,y)
#include <win32.h>
#define popen(x,y) _popen(x,y)
#define pclose(x) _pclose(x)
#endif
#endif
#include <pqsignal.h>
#include <pqsignal.h>
...
@@ -48,7 +47,6 @@ usage(void)
...
@@ -48,7 +47,6 @@ usage(void)
#ifndef WIN32
#ifndef WIN32
struct
passwd
*
pw
=
NULL
;
struct
passwd
*
pw
=
NULL
;
#endif
#endif
/* Find default user, in case we need it. */
/* Find default user, in case we need it. */
...
@@ -61,7 +59,7 @@ usage(void)
...
@@ -61,7 +59,7 @@ usage(void)
user
=
pw
->
pw_name
;
user
=
pw
->
pw_name
;
else
else
{
{
p
error
(
"getpwuid()"
);
p
sql_error
(
"could not get current user name: %s"
,
strerror
(
errno
)
);
exit
(
EXIT_FAILURE
);
exit
(
EXIT_FAILURE
);
}
}
#else
#else
...
@@ -70,10 +68,11 @@ usage(void)
...
@@ -70,10 +68,11 @@ usage(void)
}
}
/* If this " is the start of the string then it ought to end there to fit in 80 columns >> " */
/* If this " is the start of the string then it ought to end there to fit in 80 columns >> " */
puts
(
"This is psql, the PostgreSQL interactive terminal."
);
puts
(
"This is psql, the PostgreSQL interactive terminal.
\n
"
);
puts
(
"
\n
Usage:"
);
puts
(
"Usage:"
);
puts
(
" psql [options] [dbname [username]]"
);
puts
(
" psql [options] [dbname [username]]
\n
"
);
puts
(
"
\n
Options:"
);
puts
(
"Options:"
);
/* puts( " -a Echo all input from script");*/
puts
(
" -A Unaligned table output mode (-P format=unaligned)"
);
puts
(
" -A Unaligned table output mode (-P format=unaligned)"
);
puts
(
" -c <query> Run only single query (or slash command) and exit"
);
puts
(
" -c <query> Run only single query (or slash command) and exit"
);
...
@@ -83,7 +82,7 @@ usage(void)
...
@@ -83,7 +82,7 @@ usage(void)
env
=
user
;
env
=
user
;
printf
(
" -d <dbname> Specify database name to connect to (default: %s)
\n
"
,
env
);
printf
(
" -d <dbname> Specify database name to connect to (default: %s)
\n
"
,
env
);
puts
(
" -e Echo all input in non-interactive mode
"
);
puts
(
" -e Echo queries sent to backend
"
);
puts
(
" -E Display queries that internal commands generate"
);
puts
(
" -E Display queries that internal commands generate"
);
puts
(
" -f <filename> Execute queries from file, then exit"
);
puts
(
" -f <filename> Execute queries from file, then exit"
);
puts
(
" -F <string> Set field separator (default:
\"
"
DEFAULT_FIELD_SEP
"
\"
) (-P fieldsep=)"
);
puts
(
" -F <string> Set field separator (default:
\"
"
DEFAULT_FIELD_SEP
"
\"
) (-P fieldsep=)"
);
...
@@ -99,7 +98,6 @@ usage(void)
...
@@ -99,7 +98,6 @@ usage(void)
puts
(
" -H HTML table output mode (-P format=html)"
);
puts
(
" -H HTML table output mode (-P format=html)"
);
puts
(
" -l List available databases, then exit"
);
puts
(
" -l List available databases, then exit"
);
puts
(
" -n Do not use readline or history"
);
puts
(
" -o <filename> Send query output to filename (or |pipe)"
);
puts
(
" -o <filename> Send query output to filename (or |pipe)"
);
/* Display default port */
/* Display default port */
...
@@ -109,6 +107,7 @@ usage(void)
...
@@ -109,6 +107,7 @@ usage(void)
puts
(
" -P var[=arg] Set printing option 'var' to 'arg' (see
\\
pset command)"
);
puts
(
" -P var[=arg] Set printing option 'var' to 'arg' (see
\\
pset command)"
);
puts
(
" -q Run quietly (no messages, only query output)"
);
puts
(
" -q Run quietly (no messages, only query output)"
);
puts
(
" -R <string> Set record separator (default: newline) (-P recordsep=)"
);
puts
(
" -s Single step mode (confirm each query)"
);
puts
(
" -s Single step mode (confirm each query)"
);
puts
(
" -S Single line mode (newline terminates query)"
);
puts
(
" -S Single line mode (newline terminates query)"
);
puts
(
" -t Don't print headings and row count (-P tuples_only)"
);
puts
(
" -t Don't print headings and row count (-P tuples_only)"
);
...
@@ -118,7 +117,7 @@ usage(void)
...
@@ -118,7 +117,7 @@ usage(void)
env
=
getenv
(
"PGUSER"
);
env
=
getenv
(
"PGUSER"
);
if
(
!
env
)
if
(
!
env
)
env
=
user
;
env
=
user
;
printf
(
" -U <username> Specif
iy username,
\"
?
\"
=prompt (default user
: %s)
\n
"
,
env
);
printf
(
" -U <username> Specif
y database username (default
: %s)
\n
"
,
env
);
puts
(
" -x Turn on expanded table output (-P expanded)"
);
puts
(
" -x Turn on expanded table output (-P expanded)"
);
puts
(
" -v name=val Set psql variable 'name' to 'value'"
);
puts
(
" -v name=val Set psql variable 'name' to 'value'"
);
...
@@ -190,10 +189,9 @@ slashUsage(void)
...
@@ -190,10 +189,9 @@ slashUsage(void)
fout
=
stdout
;
fout
=
stdout
;
/* if you add/remove a line here, change the row test above */
/* if you add/remove a line here, change the row test above */
fprintf
(
fout
,
"
\\
? help
\n
"
);
fprintf
(
fout
,
"
\\
c[onnect] [dbname|- [user]]
\n
"
fprintf
(
fout
,
"
\\
c[onnect] [dbname|- [user|?]]
\n
"
" connect to new database (currently '%s')
\n
"
,
PQdb
(
pset
.
db
));
" connect to new database (currently '%s')
\n
"
,
PQdb
(
pset
.
db
));
fprintf
(
fout
,
"
\\
copy ... perform SQL COPY with data stream to the client machine"
);
fprintf
(
fout
,
"
\\
copy ... perform SQL COPY with data stream to the client machine
\n
"
);
fprintf
(
fout
,
"
\\
copyright show PostgreSQL usage and distribution terms
\n
"
);
fprintf
(
fout
,
"
\\
copyright show PostgreSQL usage and distribution terms
\n
"
);
fprintf
(
fout
,
"
\\
d <table> describe table (or view, index, sequence)
\n
"
);
fprintf
(
fout
,
"
\\
d <table> describe table (or view, index, sequence)
\n
"
);
fprintf
(
fout
,
"
\\
d{i|s|t|v|S} list only indices/sequences/tables/views/system tables
\n
"
);
fprintf
(
fout
,
"
\\
d{i|s|t|v|S} list only indices/sequences/tables/views/system tables
\n
"
);
...
@@ -212,7 +210,8 @@ slashUsage(void)
...
@@ -212,7 +210,8 @@ slashUsage(void)
" large object operations
\n
"
);
" large object operations
\n
"
);
fprintf
(
fout
,
"
\\
o [fname] send all query results to <fname>, or |pipe
\n
"
);
fprintf
(
fout
,
"
\\
o [fname] send all query results to <fname>, or |pipe
\n
"
);
fprintf
(
fout
,
"
\\
p show the content of the current query buffer
\n
"
);
fprintf
(
fout
,
"
\\
p show the content of the current query buffer
\n
"
);
fprintf
(
fout
,
"
\\
pset [opt] set table output options
\n
"
);
fprintf
(
fout
,
"
\\
pset {format|border|expanded|fieldsep|recordsep|tuples_only|title|tableattr
\n
"
" |pager} set table output options
\n
"
);
fprintf
(
fout
,
"
\\
q quit psql
\n
"
);
fprintf
(
fout
,
"
\\
q quit psql
\n
"
);
fprintf
(
fout
,
"
\\
qecho <text> write text to query output stream (see
\\
o)
\n
"
);
fprintf
(
fout
,
"
\\
qecho <text> write text to query output stream (see
\\
o)
\n
"
);
fprintf
(
fout
,
"
\\
r reset (clear) the query buffer
\n
"
);
fprintf
(
fout
,
"
\\
r reset (clear) the query buffer
\n
"
);
...
@@ -243,36 +242,24 @@ slashUsage(void)
...
@@ -243,36 +242,24 @@ slashUsage(void)
void
void
helpSQL
(
const
char
*
topic
)
helpSQL
(
const
char
*
topic
)
{
{
#define VALUE_OR_NULL(a) ((a) ? (a) : "")
if
(
!
topic
||
strlen
(
topic
)
==
0
)
if
(
!
topic
||
strlen
(
topic
)
==
0
)
{
{
char
left_center_right
;
/* Which column we're displaying */
int
i
;
int
i
;
/* Index into QL_HELP[] */
int
items_per_column
=
(
QL_HELP_COUNT
+
2
)
/
3
;
puts
(
"Available help:"
);
puts
(
"Available help:"
);
left_center_right
=
'L'
;
/* Start with left column */
for
(
i
=
0
;
i
<
items_per_column
;
i
++
)
i
=
0
;
while
(
QL_HELP
[
i
].
cmd
!=
NULL
)
{
{
switch
(
left_center_right
)
printf
(
" %-25s%-25s%-25s
\n
"
,
{
VALUE_OR_NULL
(
QL_HELP
[
i
].
cmd
),
case
'L'
:
VALUE_OR_NULL
(
QL_HELP
[
i
+
items_per_column
].
cmd
),
printf
(
" %-25s"
,
QL_HELP
[
i
].
cmd
);
VALUE_OR_NULL
(
QL_HELP
[
i
+
2
*
items_per_column
].
cmd
)
left_center_right
=
'C'
;
);
break
;
case
'C'
:
printf
(
"%-25s"
,
QL_HELP
[
i
].
cmd
);
left_center_right
=
'R'
;
break
;
case
'R'
:
printf
(
"%-25s
\n
"
,
QL_HELP
[
i
].
cmd
);
left_center_right
=
'L'
;
break
;
}
i
++
;
}
}
if
(
left_center_right
!=
'L'
)
putc
(
'\n'
,
stdout
);
puts
(
"
\n
"
);
}
}
else
else
...
@@ -286,7 +273,9 @@ helpSQL(const char *topic)
...
@@ -286,7 +273,9 @@ helpSQL(const char *topic)
strcmp
(
topic
,
"*"
)
==
0
)
strcmp
(
topic
,
"*"
)
==
0
)
{
{
help_found
=
true
;
help_found
=
true
;
printf
(
"Command: %s
\n
Description: %s
\n
Syntax:
\n
%s
\n\n
"
,
printf
(
"Command: %s
\n
"
"Description: %s
\n
"
"Syntax:
\n
%s
\n\n
"
,
QL_HELP
[
i
].
cmd
,
QL_HELP
[
i
].
help
,
QL_HELP
[
i
].
syntax
);
QL_HELP
[
i
].
cmd
,
QL_HELP
[
i
].
help
,
QL_HELP
[
i
].
syntax
);
}
}
}
}
...
@@ -298,7 +287,6 @@ helpSQL(const char *topic)
...
@@ -298,7 +287,6 @@ helpSQL(const char *topic)
void
void
print_copyright
(
void
)
print_copyright
(
void
)
{
{
...
@@ -321,5 +309,6 @@ print_copyright(void)
...
@@ -321,5 +309,6 @@ print_copyright(void)
"BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
\n
"
"BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
\n
"
"PARTICULAR PURPOSE.THE SOFTWARE PROVIDED HEREUNDER IS ON AN
\"
AS IS
\"
BASIS,
\n
"
"PARTICULAR PURPOSE.THE SOFTWARE PROVIDED HEREUNDER IS ON AN
\"
AS IS
\"
BASIS,
\n
"
"AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE,
\n
"
"AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE,
\n
"
"SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
);
"SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
);
}
}
src/bin/psql/input.c
View file @
9ceb5d8a
...
@@ -3,15 +3,18 @@
...
@@ -3,15 +3,18 @@
*
*
* Copyright 2000 by PostgreSQL Global Development Group
* Copyright 2000 by PostgreSQL Global Development Group
*
*
* $Header: /cvsroot/pgsql/src/bin/psql/input.c,v 1.
8 2000/01/29 16:58:48
petere Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/input.c,v 1.
9 2000/02/07 23:10:06
petere Exp $
*/
*/
#include <c.h>
#include <c.h>
#include "input.h"
#include "input.h"
#include <errno.h>
#include <pqexpbuffer.h>
#include <pqexpbuffer.h>
#include "settings.h"
#include "settings.h"
#include "tab-complete.h"
#include "tab-complete.h"
#include "common.h"
/* Runtime options for turning off readline and history */
/* Runtime options for turning off readline and history */
/* (of course there is no runtime command for doing that :) */
/* (of course there is no runtime command for doing that :) */
...
@@ -32,7 +35,7 @@ static bool useHistory;
...
@@ -32,7 +35,7 @@ static bool useHistory;
* The result is malloced.
* The result is malloced.
*/
*/
char
*
char
*
gets_interactive
(
c
onst
c
har
*
prompt
)
gets_interactive
(
char
*
prompt
)
{
{
char
*
s
;
char
*
s
;
#ifdef USE_HISTORY
#ifdef USE_HISTORY
...
@@ -42,7 +45,7 @@ gets_interactive(const char *prompt)
...
@@ -42,7 +45,7 @@ gets_interactive(const char *prompt)
#ifdef USE_READLINE
#ifdef USE_READLINE
if
(
useReadline
)
if
(
useReadline
)
s
=
readline
(
(
char
*
)
prompt
);
s
=
readline
(
prompt
);
else
else
{
{
#endif
#endif
...
@@ -120,7 +123,6 @@ initializeInput(int flags)
...
@@ -120,7 +123,6 @@ initializeInput(int flags)
if
(
flags
==
1
)
if
(
flags
==
1
)
{
{
useReadline
=
true
;
useReadline
=
true
;
rl_readline_name
=
"psql"
;
initialize_readline
();
initialize_readline
();
}
}
#endif
#endif
...
@@ -152,14 +154,14 @@ initializeInput(int flags)
...
@@ -152,14 +154,14 @@ initializeInput(int flags)
bool
bool
saveHistory
(
c
onst
c
har
*
fname
)
saveHistory
(
char
*
fname
)
{
{
#ifdef USE_HISTORY
#ifdef USE_HISTORY
if
(
useHistory
)
if
(
useHistory
&&
fname
)
{
{
if
(
write_history
(
(
char
*
)
fname
)
!=
0
)
if
(
write_history
(
fname
)
!=
0
)
{
{
p
error
(
fname
);
p
sql_error
(
"could not save history to %s: %s"
,
fname
,
strerror
(
errno
)
);
return
false
;
return
false
;
}
}
return
true
;
return
true
;
...
...
src/bin/psql/input.h
View file @
9ceb5d8a
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
*
*
* Copyright 2000 by PostgreSQL Global Development Group
* Copyright 2000 by PostgreSQL Global Development Group
*
*
* $Header: /cvsroot/pgsql/src/bin/psql/input.h,v 1.
6 2000/01/29 16:58:48
petere Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/input.h,v 1.
7 2000/02/07 23:10:06
petere Exp $
*/
*/
#ifndef INPUT_H
#ifndef INPUT_H
#define INPUT_H
#define INPUT_H
...
@@ -37,11 +37,11 @@
...
@@ -37,11 +37,11 @@
# endif
# endif
#endif
#endif
char
*
gets_interactive
(
c
onst
c
har
*
prompt
);
char
*
gets_interactive
(
char
*
prompt
);
char
*
gets_fromFile
(
FILE
*
source
);
char
*
gets_fromFile
(
FILE
*
source
);
void
initializeInput
(
int
flags
);
void
initializeInput
(
int
flags
);
bool
saveHistory
(
c
onst
c
har
*
fname
);
bool
saveHistory
(
char
*
fname
);
void
finishInput
(
void
);
void
finishInput
(
void
);
#endif
/* INPUT_H */
#endif
/* INPUT_H */
src/bin/psql/large_obj.c
View file @
9ceb5d8a
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
*
*
* Copyright 2000 by PostgreSQL Global Development Group
* Copyright 2000 by PostgreSQL Global Development Group
*
*
* $Header: /cvsroot/pgsql/src/bin/psql/large_obj.c,v 1.
7 2000/01/29 16:58:48
petere Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/large_obj.c,v 1.
8 2000/02/07 23:10:06
petere Exp $
*/
*/
#include <c.h>
#include <c.h>
#include "large_obj.h"
#include "large_obj.h"
...
@@ -113,7 +113,7 @@ do_lo_export(const char *loid_arg, const char *filename_arg)
...
@@ -113,7 +113,7 @@ do_lo_export(const char *loid_arg, const char *filename_arg)
PQclear
(
res
);
PQclear
(
res
);
}
}
status
=
lo_export
(
pset
.
db
,
atol
(
loid_arg
),
(
char
*
)
filename_arg
);
status
=
lo_export
(
pset
.
db
,
atol
(
loid_arg
),
filename_arg
);
if
(
status
!=
1
)
if
(
status
!=
1
)
{
/* of course this status is documented
{
/* of course this status is documented
* nowhere :( */
* nowhere :( */
...
@@ -182,7 +182,7 @@ do_lo_import(const char *filename_arg, const char *comment_arg)
...
@@ -182,7 +182,7 @@ do_lo_import(const char *filename_arg, const char *comment_arg)
PQclear
(
res
);
PQclear
(
res
);
}
}
loid
=
lo_import
(
pset
.
db
,
(
char
*
)
filename_arg
);
loid
=
lo_import
(
pset
.
db
,
filename_arg
);
if
(
loid
==
InvalidOid
)
if
(
loid
==
InvalidOid
)
{
{
fputs
(
PQerrorMessage
(
pset
.
db
),
stderr
);
fputs
(
PQerrorMessage
(
pset
.
db
),
stderr
);
...
...
src/bin/psql/mainloop.c
View file @
9ceb5d8a
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
*
*
* Copyright 2000 by PostgreSQL Global Development Group
* Copyright 2000 by PostgreSQL Global Development Group
*
*
* $Header: /cvsroot/pgsql/src/bin/psql/mainloop.c,v 1.1
6 2000/01/24 19:34:17
petere Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/mainloop.c,v 1.1
7 2000/02/07 23:10:06
petere Exp $
*/
*/
#include <c.h>
#include <c.h>
#include "mainloop.h"
#include "mainloop.h"
...
@@ -47,10 +47,10 @@ MainLoop(FILE *source)
...
@@ -47,10 +47,10 @@ MainLoop(FILE *source)
bool
xcomment
;
/* in extended comment */
bool
xcomment
;
/* in extended comment */
int
paren_level
;
int
paren_level
;
unsigned
int
query_start
;
unsigned
int
query_start
;
int
count_eof
;
int
count_eof
=
0
;
const
char
*
var
;
const
char
*
var
;
bool
was_bslash
;
bool
was_bslash
;
unsigned
int
bslash_count
;
unsigned
int
bslash_count
=
0
;
int
i
,
int
i
,
prevlen
,
prevlen
,
...
@@ -123,6 +123,8 @@ MainLoop(FILE *source)
...
@@ -123,6 +123,8 @@ MainLoop(FILE *source)
prompt_status
=
PROMPT_DOUBLEQUOTE
;
prompt_status
=
PROMPT_DOUBLEQUOTE
;
else
if
(
xcomment
)
else
if
(
xcomment
)
prompt_status
=
PROMPT_COMMENT
;
prompt_status
=
PROMPT_COMMENT
;
else
if
(
paren_level
)
prompt_status
=
PROMPT_PAREN
;
else
if
(
query_buf
->
len
>
0
)
else
if
(
query_buf
->
len
>
0
)
prompt_status
=
PROMPT_CONTINUE
;
prompt_status
=
PROMPT_CONTINUE
;
else
else
...
@@ -251,7 +253,7 @@ MainLoop(FILE *source)
...
@@ -251,7 +253,7 @@ MainLoop(FILE *source)
}
}
/* start of quote */
/* start of quote */
else
if
(
line
[
i
]
==
'\''
||
line
[
i
]
==
'"'
)
else
if
(
!
was_bslash
&&
(
line
[
i
]
==
'\''
||
line
[
i
]
==
'"'
)
)
in_quote
=
line
[
i
];
in_quote
=
line
[
i
];
/* in extended comment? */
/* in extended comment? */
...
...
src/bin/psql/print.c
View file @
9ceb5d8a
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
*
*
* Copyright 2000 by PostgreSQL Global Development Group
* Copyright 2000 by PostgreSQL Global Development Group
*
*
* $Header: /cvsroot/pgsql/src/bin/psql/print.c,v 1.
9 2000/01/29 16:58:49
petere Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/print.c,v 1.
10 2000/02/07 23:10:06
petere Exp $
*/
*/
#include <c.h>
#include <c.h>
#include "print.h"
#include "print.h"
...
@@ -266,7 +266,9 @@ print_aligned_text(const char *title, const char * const * headers,
...
@@ -266,7 +266,9 @@ print_aligned_text(const char *title, const char * const * headers,
for
(
i
=
0
;
i
<
col_count
;
i
++
)
for
(
i
=
0
;
i
<
col_count
;
i
++
)
{
{
/* centered */
/* centered */
fprintf
(
fout
,
"%-*s%s%-*s"
,
(
int
)
floor
((
widths
[
i
]
-
strlen
(
headers
[
i
]))
/
2
.
0
),
""
,
headers
[
i
],
(
int
)
ceil
((
widths
[
i
]
-
strlen
(
headers
[
i
]))
/
2
.
0
),
""
);
fprintf
(
fout
,
"%-*s%s%-*s"
,
(
int
)
floor
((
widths
[
i
]
-
strlen
(
headers
[
i
]))
/
2
.
0
),
""
,
headers
[
i
],
(
int
)
ceil
((
widths
[
i
]
-
strlen
(
headers
[
i
]))
/
2
.
0
),
""
);
if
(
i
<
col_count
-
1
)
if
(
i
<
col_count
-
1
)
{
{
...
...
src/bin/psql/prompt.c
View file @
9ceb5d8a
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
*
*
* Copyright 2000 by PostgreSQL Global Development Group
* Copyright 2000 by PostgreSQL Global Development Group
*
*
* $Header: /cvsroot/pgsql/src/bin/psql/prompt.c,v 1.
7 2000/01/29 16:58:49
petere Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/prompt.c,v 1.
8 2000/02/07 23:10:06
petere Exp $
*/
*/
#include <c.h>
#include <c.h>
#include "prompt.h"
#include "prompt.h"
...
@@ -19,8 +19,8 @@
...
@@ -19,8 +19,8 @@
#include "variables.h"
#include "variables.h"
#ifdef WIN32
#ifdef WIN32
#
define popen(x,y) _popen(x,y)
#
include <io.h>
#
define pclose(x) _pclose(x)
#
include <win32.h>
#endif
#endif
...
@@ -53,14 +53,14 @@
...
@@ -53,14 +53,14 @@
*
*
* %`command` - The result of executing command in /bin/sh with trailing
* %`command` - The result of executing command in /bin/sh with trailing
* newline stripped.
* newline stripped.
* %
$name$
- The value of the psql variable 'name'
* %
:name:
- The value of the psql variable 'name'
* (those will not be rescanned for more escape sequences!)
* (those will not be rescanned for more escape sequences!)
*
*
* If the application-wide prompts became NULL somehow, the returned string
* If the application-wide prompts became NULL somehow, the returned string
* will be empty (not NULL!).
* will be empty (not NULL!).
*--------------------------
*--------------------------
*/
*/
c
onst
c
har
*
char
*
get_prompt
(
promptStatus_t
status
)
get_prompt
(
promptStatus_t
status
)
{
{
#define MAX_PROMPT_SIZE 256
#define MAX_PROMPT_SIZE 256
...
@@ -72,7 +72,7 @@ get_prompt(promptStatus_t status)
...
@@ -72,7 +72,7 @@ get_prompt(promptStatus_t status)
if
(
status
==
PROMPT_READY
)
if
(
status
==
PROMPT_READY
)
prompt_string
=
GetVariable
(
pset
.
vars
,
"PROMPT1"
);
prompt_string
=
GetVariable
(
pset
.
vars
,
"PROMPT1"
);
else
if
(
status
==
PROMPT_CONTINUE
||
status
==
PROMPT_SINGLEQUOTE
||
status
==
PROMPT_DOUBLEQUOTE
||
status
==
PROMPT_COMMENT
)
else
if
(
status
==
PROMPT_CONTINUE
||
status
==
PROMPT_SINGLEQUOTE
||
status
==
PROMPT_DOUBLEQUOTE
||
status
==
PROMPT_COMMENT
||
status
==
PROMPT_PAREN
)
prompt_string
=
GetVariable
(
pset
.
vars
,
"PROMPT2"
);
prompt_string
=
GetVariable
(
pset
.
vars
,
"PROMPT2"
);
else
if
(
status
==
PROMPT_COPY
)
else
if
(
status
==
PROMPT_COPY
)
prompt_string
=
GetVariable
(
pset
.
vars
,
"PROMPT3"
);
prompt_string
=
GetVariable
(
pset
.
vars
,
"PROMPT3"
);
...
@@ -183,6 +183,9 @@ get_prompt(promptStatus_t status)
...
@@ -183,6 +183,9 @@ get_prompt(promptStatus_t status)
case
PROMPT_COMMENT
:
case
PROMPT_COMMENT
:
buf
[
0
]
=
'*'
;
buf
[
0
]
=
'*'
;
break
;
break
;
case
PROMPT_PAREN
:
buf
[
0
]
=
'('
;
break
;
default:
default:
buf
[
0
]
=
'\0'
;
buf
[
0
]
=
'\0'
;
break
;
break
;
...
@@ -226,14 +229,14 @@ get_prompt(promptStatus_t status)
...
@@ -226,14 +229,14 @@ get_prompt(promptStatus_t status)
}
}
/* interpolate variable */
/* interpolate variable */
case
'
$
'
:
case
'
:
'
:
{
{
char
*
name
;
char
*
name
;
const
char
*
val
;
const
char
*
val
;
int
nameend
;
int
nameend
;
name
=
strdup
(
p
+
1
);
name
=
strdup
(
p
+
1
);
nameend
=
strcspn
(
name
,
"
$
"
);
nameend
=
strcspn
(
name
,
"
:
"
);
name
[
nameend
]
=
'\0'
;
name
[
nameend
]
=
'\0'
;
val
=
GetVariable
(
pset
.
vars
,
name
);
val
=
GetVariable
(
pset
.
vars
,
name
);
if
(
val
)
if
(
val
)
...
...
src/bin/psql/prompt.h
View file @
9ceb5d8a
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
*
*
* Copyright 2000 by PostgreSQL Global Development Group
* Copyright 2000 by PostgreSQL Global Development Group
*
*
* $Header: /cvsroot/pgsql/src/bin/psql/prompt.h,v 1.
5 2000/01/29 16:58:49
petere Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/prompt.h,v 1.
6 2000/02/07 23:10:06
petere Exp $
*/
*/
#ifndef PROMPT_H
#ifndef PROMPT_H
#define PROMPT_H
#define PROMPT_H
...
@@ -17,9 +17,10 @@ typedef enum _promptStatus
...
@@ -17,9 +17,10 @@ typedef enum _promptStatus
PROMPT_COMMENT
,
PROMPT_COMMENT
,
PROMPT_SINGLEQUOTE
,
PROMPT_SINGLEQUOTE
,
PROMPT_DOUBLEQUOTE
,
PROMPT_DOUBLEQUOTE
,
PROMPT_PAREN
,
PROMPT_COPY
PROMPT_COPY
}
promptStatus_t
;
}
promptStatus_t
;
c
onst
c
har
*
get_prompt
(
promptStatus_t
status
);
char
*
get_prompt
(
promptStatus_t
status
);
#endif
/* PROMPT_H */
#endif
/* PROMPT_H */
src/bin/psql/startup.c
View file @
9ceb5d8a
...
@@ -3,53 +3,48 @@
...
@@ -3,53 +3,48 @@
*
*
* Copyright 2000 by PostgreSQL Global Development Group
* Copyright 2000 by PostgreSQL Global Development Group
*
*
* $Header: /cvsroot/pgsql/src/bin/psql/startup.c,v 1.2
1 2000/02/05 12:27:56 ishii
Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/startup.c,v 1.2
2 2000/02/07 23:10:06 petere
Exp $
*/
*/
#include <c.h>
#include <c.h>
#include <signal.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/types.h>
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
#include <stdio.h>
#include <stdio.h>
#include <assert.h>
#ifdef WIN32
#ifndef WIN32
#include <unistd.h>
#else
/* WIN32 */
#include <io.h>
#include <io.h>
#include <windows.h>
#include <windows.h>
#else
#include <win32.h>
#include <unistd.h>
#endif
/* WIN32 */
#endif
#ifdef HAVE_GETOPT_H
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#include <getopt.h>
#endif
#endif
#include <libpq-fe.h>
#include <libpq-fe.h>
#include <pqsignal.h>
#include <version.h>
#include <version.h>
#include "settings.h"
#include "command.h"
#include "command.h"
#include "help.h"
#include "mainloop.h"
#include "common.h"
#include "common.h"
#include "describe.h"
#include "help.h"
#include "input.h"
#include "input.h"
#include "
variables
.h"
#include "
mainloop
.h"
#include "print.h"
#include "print.h"
#include "describe.h"
#include "settings.h"
#include "variables.h"
/*
* Global psql options
*/
PsqlSettings
pset
;
PsqlSettings
pset
;
static
void
process_psqlrc
(
void
);
static
void
showVersion
(
void
);
/* Structures to pass information between the option parsing routine
/*
* Structures to pass information between the option parsing routine
* and the main function
* and the main function
*/
*/
enum
_actions
enum
_actions
...
@@ -75,15 +70,21 @@ struct adhoc_opts
...
@@ -75,15 +70,21 @@ struct adhoc_opts
static
void
static
void
parse_options
(
int
argc
,
char
*
argv
[],
struct
adhoc_opts
*
options
);
parse_options
(
int
argc
,
char
*
argv
[],
struct
adhoc_opts
*
options
);
static
void
process_psqlrc
(
void
);
static
void
showVersion
(
void
);
/*
/*
*
*
* main
()
* main
*
*
*/
*/
int
int
main
(
int
argc
,
char
*
*
argv
)
main
(
int
argc
,
char
*
argv
[]
)
{
{
struct
adhoc_opts
options
;
struct
adhoc_opts
options
;
int
successResult
;
int
successResult
;
...
@@ -92,8 +93,6 @@ main(int argc, char **argv)
...
@@ -92,8 +93,6 @@ main(int argc, char **argv)
char
*
password
=
NULL
;
char
*
password
=
NULL
;
bool
need_pass
;
bool
need_pass
;
memset
(
&
pset
,
0
,
sizeof
pset
);
if
(
!
strrchr
(
argv
[
0
],
SEP_CHAR
))
if
(
!
strrchr
(
argv
[
0
],
SEP_CHAR
))
pset
.
progname
=
argv
[
0
];
pset
.
progname
=
argv
[
0
];
else
else
...
@@ -104,21 +103,21 @@ main(int argc, char **argv)
...
@@ -104,21 +103,21 @@ main(int argc, char **argv)
pset
.
encoding
=
PQenv2encoding
();
pset
.
encoding
=
PQenv2encoding
();
pset
.
vars
=
CreateVariableSpace
();
pset
.
vars
=
CreateVariableSpace
();
if
(
!
pset
.
vars
)
{
fprintf
(
stderr
,
"%s: out of memory
\n
"
,
pset
.
progname
);
exit
(
EXIT_FAILURE
);
}
pset
.
popt
.
topt
.
format
=
PRINT_ALIGNED
;
pset
.
popt
.
topt
.
format
=
PRINT_ALIGNED
;
pset
.
queryFout
=
stdout
;
pset
.
queryFout
=
stdout
;
pset
.
popt
.
topt
.
fieldSep
=
xstrdup
(
DEFAULT_FIELD_SEP
);
pset
.
popt
.
topt
.
recordSep
=
xstrdup
(
DEFAULT_RECORD_SEP
);
pset
.
popt
.
topt
.
border
=
1
;
pset
.
popt
.
topt
.
border
=
1
;
pset
.
popt
.
topt
.
pager
=
true
;
pset
.
popt
.
topt
.
pager
=
true
;
SetVariable
(
pset
.
vars
,
"PROMPT1"
,
DEFAULT_PROMPT1
);
SetVariable
(
pset
.
vars
,
"PROMPT2"
,
DEFAULT_PROMPT2
);
SetVariable
(
pset
.
vars
,
"PROMPT3"
,
DEFAULT_PROMPT3
);
SetVariable
(
pset
.
vars
,
"VERSION"
,
PG_VERSION_STR
);
SetVariable
(
pset
.
vars
,
"VERSION"
,
PG_VERSION_STR
);
pset
.
notty
=
(
!
isatty
(
fileno
(
stdin
))
||
!
isatty
(
fileno
(
stdout
)));
pset
.
notty
=
(
!
isatty
(
fileno
(
stdin
))
||
!
isatty
(
fileno
(
stdout
)));
/* This is obsolete and
will be removed very soon
. */
/* This is obsolete and
should be removed sometime
. */
#ifdef PSQL_ALWAYS_GET_PASSWORDS
#ifdef PSQL_ALWAYS_GET_PASSWORDS
pset
.
getPassword
=
true
;
pset
.
getPassword
=
true
;
#else
#else
...
@@ -127,11 +126,18 @@ main(int argc, char **argv)
...
@@ -127,11 +126,18 @@ main(int argc, char **argv)
parse_options
(
argc
,
argv
,
&
options
);
parse_options
(
argc
,
argv
,
&
options
);
if
(
options
.
action
==
ACT_LIST_DB
)
if
(
!
pset
.
popt
.
topt
.
fieldSep
)
options
.
dbname
=
"template1"
;
pset
.
popt
.
topt
.
fieldSep
=
xstrdup
(
DEFAULT_FIELD_SEP
);
if
(
!
pset
.
popt
.
topt
.
recordSep
)
pset
.
popt
.
topt
.
recordSep
=
xstrdup
(
DEFAULT_RECORD_SEP
);
if
(
options
.
username
)
if
(
options
.
username
)
{
{
/*
* The \001 is a hack to support the deprecated -u option which issues
* a username prompt. The recommended option is -U followed by the name
* on the command line.
*/
if
(
strcmp
(
options
.
username
,
"
\001
"
)
==
0
)
if
(
strcmp
(
options
.
username
,
"
\001
"
)
==
0
)
username
=
simple_prompt
(
"Username: "
,
100
,
true
);
username
=
simple_prompt
(
"Username: "
,
100
,
true
);
else
else
...
@@ -145,7 +151,9 @@ main(int argc, char **argv)
...
@@ -145,7 +151,9 @@ main(int argc, char **argv)
do
do
{
{
need_pass
=
false
;
need_pass
=
false
;
pset
.
db
=
PQsetdbLogin
(
options
.
host
,
options
.
port
,
NULL
,
NULL
,
options
.
dbname
,
username
,
password
);
pset
.
db
=
PQsetdbLogin
(
options
.
host
,
options
.
port
,
NULL
,
NULL
,
options
.
action
==
ACT_LIST_DB
?
"template1"
:
options
.
dbname
,
username
,
password
);
if
(
PQstatus
(
pset
.
db
)
==
CONNECTION_BAD
&&
if
(
PQstatus
(
pset
.
db
)
==
CONNECTION_BAD
&&
strcmp
(
PQerrorMessage
(
pset
.
db
),
"fe_sendauth: no password supplied
\n
"
)
==
0
)
strcmp
(
PQerrorMessage
(
pset
.
db
),
"fe_sendauth: no password supplied
\n
"
)
==
0
)
...
@@ -162,8 +170,7 @@ main(int argc, char **argv)
...
@@ -162,8 +170,7 @@ main(int argc, char **argv)
if
(
PQstatus
(
pset
.
db
)
==
CONNECTION_BAD
)
if
(
PQstatus
(
pset
.
db
)
==
CONNECTION_BAD
)
{
{
fprintf
(
stderr
,
"%s: %s"
,
fprintf
(
stderr
,
"%s: %s"
,
pset
.
progname
,
PQerrorMessage
(
pset
.
db
));
pset
.
progname
,
PQerrorMessage
(
pset
.
db
));
PQfinish
(
pset
.
db
);
PQfinish
(
pset
.
db
);
exit
(
EXIT_BADCONN
);
exit
(
EXIT_BADCONN
);
}
}
...
@@ -188,43 +195,61 @@ main(int argc, char **argv)
...
@@ -188,43 +195,61 @@ main(int argc, char **argv)
SetVariable
(
pset
.
vars
,
"HOST"
,
PQhost
(
pset
.
db
));
SetVariable
(
pset
.
vars
,
"HOST"
,
PQhost
(
pset
.
db
));
SetVariable
(
pset
.
vars
,
"PORT"
,
PQport
(
pset
.
db
));
SetVariable
(
pset
.
vars
,
"PORT"
,
PQport
(
pset
.
db
));
pset
.
issuper
=
test_superuser
(
PQuser
(
pset
.
db
));
/*
* Now find something to do
if
(
!
QUIET
()
&&
!
pset
.
notty
&&
!
options
.
action
)
*/
{
printf
(
"Welcome to %s, the PostgreSQL interactive terminal.
\n\n
"
"Type:
\\
copyright for distribution terms
\n
"
"
\\
h for help with SQL commands
\n
"
"
\\
? for help on internal slash commands
\n
"
"
\\
g or terminate with semicolon to execute query
\n
"
"
\\
q to quit
\n
"
,
pset
.
progname
);
}
/* Now find something to do */
/* process file given by -f */
/*
* process file given by -f
*/
if
(
options
.
action
==
ACT_FILE
)
if
(
options
.
action
==
ACT_FILE
)
successResult
=
process_file
(
options
.
action_string
)
?
0
:
1
;
successResult
=
process_file
(
options
.
action_string
)
?
0
:
1
;
/* process slash command if one was given to -c */
/*
* process slash command if one was given to -c
*/
else
if
(
options
.
action
==
ACT_SINGLE_SLASH
)
else
if
(
options
.
action
==
ACT_SINGLE_SLASH
)
{
{
if
(
GetVariable
(
pset
.
vars
,
"ECHO"
)
&&
strcmp
(
GetVariable
(
pset
.
vars
,
"ECHO"
),
"full"
)
==
0
)
const
char
*
value
;
if
((
value
=
GetVariable
(
pset
.
vars
,
"ECHO"
))
&&
strcmp
(
value
,
"full"
)
==
0
)
puts
(
options
.
action_string
);
puts
(
options
.
action_string
);
successResult
=
HandleSlashCmds
(
options
.
action_string
,
NULL
,
NULL
)
!=
CMD_ERROR
?
0
:
1
;
successResult
=
HandleSlashCmds
(
options
.
action_string
,
NULL
,
NULL
)
!=
CMD_ERROR
?
0
:
1
;
}
}
/* If the query given to -c was a normal one, send it */
/*
* If the query given to -c was a normal one, send it
*/
else
if
(
options
.
action
==
ACT_SINGLE_QUERY
)
else
if
(
options
.
action
==
ACT_SINGLE_QUERY
)
{
{
if
(
GetVariable
(
pset
.
vars
,
"ECHO"
)
&&
strcmp
(
GetVariable
(
pset
.
vars
,
"ECHO"
),
"full"
)
==
0
)
const
char
*
value
;
if
((
value
=
GetVariable
(
pset
.
vars
,
"ECHO"
))
&&
strcmp
(
value
,
"full"
)
==
0
)
puts
(
options
.
action_string
);
puts
(
options
.
action_string
);
successResult
=
SendQuery
(
options
.
action_string
)
?
0
:
1
;
successResult
=
SendQuery
(
options
.
action_string
)
?
0
:
1
;
}
}
/* or otherwise enter interactive main loop */
/*
* or otherwise enter interactive main loop
*/
else
else
{
{
pset
.
issuper
=
test_superuser
(
PQuser
(
pset
.
db
));
if
(
!
QUIET
()
&&
!
pset
.
notty
)
{
printf
(
"Welcome to %s, the PostgreSQL interactive terminal.
\n\n
"
"Type:
\\
copyright for distribution terms
\n
"
"
\\
h for help with SQL commands
\n
"
"
\\
? for help on internal slash commands
\n
"
"
\\
g or terminate with semicolon to execute query
\n
"
"
\\
q to quit
\n\n
"
,
pset
.
progname
);
}
SetVariable
(
pset
.
vars
,
"PROMPT1"
,
DEFAULT_PROMPT1
);
SetVariable
(
pset
.
vars
,
"PROMPT2"
,
DEFAULT_PROMPT2
);
SetVariable
(
pset
.
vars
,
"PROMPT3"
,
DEFAULT_PROMPT3
);
process_psqlrc
();
process_psqlrc
();
if
(
!
pset
.
notty
)
initializeInput
(
options
.
no_readline
?
0
:
1
);
initializeInput
(
options
.
no_readline
?
0
:
1
);
successResult
=
MainLoop
(
stdin
);
successResult
=
MainLoop
(
stdin
);
if
(
!
pset
.
notty
)
finishInput
();
finishInput
();
}
}
...
@@ -253,7 +278,8 @@ static void
...
@@ -253,7 +278,8 @@ static void
parse_options
(
int
argc
,
char
*
argv
[],
struct
adhoc_opts
*
options
)
parse_options
(
int
argc
,
char
*
argv
[],
struct
adhoc_opts
*
options
)
{
{
#ifdef HAVE_GETOPT_LONG
#ifdef HAVE_GETOPT_LONG
static
struct
option
long_options
[]
=
{
static
struct
option
long_options
[]
=
{
{
"no-align"
,
no_argument
,
NULL
,
'A'
},
{
"no-align"
,
no_argument
,
NULL
,
'A'
},
{
"command"
,
required_argument
,
NULL
,
'c'
},
{
"command"
,
required_argument
,
NULL
,
'c'
},
{
"dbname"
,
required_argument
,
NULL
,
'd'
},
{
"dbname"
,
required_argument
,
NULL
,
'd'
},
...
@@ -269,6 +295,7 @@ parse_options(int argc, char *argv[], struct adhoc_opts * options)
...
@@ -269,6 +295,7 @@ parse_options(int argc, char *argv[], struct adhoc_opts * options)
{
"port"
,
required_argument
,
NULL
,
'p'
},
{
"port"
,
required_argument
,
NULL
,
'p'
},
{
"pset"
,
required_argument
,
NULL
,
'P'
},
{
"pset"
,
required_argument
,
NULL
,
'P'
},
{
"quiet"
,
no_argument
,
NULL
,
'q'
},
{
"quiet"
,
no_argument
,
NULL
,
'q'
},
{
"record-separator"
,
required_argument
,
NULL
,
'R'
},
{
"single-step"
,
no_argument
,
NULL
,
's'
},
{
"single-step"
,
no_argument
,
NULL
,
's'
},
{
"single-line"
,
no_argument
,
NULL
,
'S'
},
{
"single-line"
,
no_argument
,
NULL
,
'S'
},
{
"tuples-only"
,
no_argument
,
NULL
,
't'
},
{
"tuples-only"
,
no_argument
,
NULL
,
't'
},
...
@@ -283,7 +310,7 @@ parse_options(int argc, char *argv[], struct adhoc_opts * options)
...
@@ -283,7 +310,7 @@ parse_options(int argc, char *argv[], struct adhoc_opts * options)
};
};
int
optindex
;
int
optindex
;
#endif
#endif
/* HAVE_GETOPT_LONG */
extern
char
*
optarg
;
extern
char
*
optarg
;
extern
int
optind
;
extern
int
optind
;
...
@@ -293,15 +320,15 @@ parse_options(int argc, char *argv[], struct adhoc_opts * options)
...
@@ -293,15 +320,15 @@ parse_options(int argc, char *argv[], struct adhoc_opts * options)
memset
(
options
,
0
,
sizeof
*
options
);
memset
(
options
,
0
,
sizeof
*
options
);
#ifdef HAVE_GETOPT_LONG
#ifdef HAVE_GETOPT_LONG
while
((
c
=
getopt_long
(
argc
,
argv
,
"Ac:d:eEf:F:lh:Hno:p:P:qsStT:uU:v:VWx?"
,
long_options
,
&
optindex
))
!=
-
1
)
while
((
c
=
getopt_long
(
argc
,
argv
,
"Ac:d:eEf:F:lh:Hno:p:P:q
R
sStT:uU:v:VWx?"
,
long_options
,
&
optindex
))
!=
-
1
)
#else
#else
/* not HAVE_GETOPT_LONG */
/*
/*
* Be sure to leave the '-' in here, so we can catch accidental long
* Be sure to leave the '-' in here, so we can catch accidental long
* options.
* options.
*/
*/
while
((
c
=
getopt
(
argc
,
argv
,
"Ac:d:eEf:F:lh:Hno:p:P:qsStT:uU:v:VWx?-"
))
!=
-
1
)
while
((
c
=
getopt
(
argc
,
argv
,
"Ac:d:eEf:F:lh:Hno:p:P:q
R
sStT:uU:v:VWx?-"
))
!=
-
1
)
#endif
#endif
/* not HAVE_GETOPT_LONG */
{
{
switch
(
c
)
switch
(
c
)
{
{
...
@@ -329,7 +356,7 @@ parse_options(int argc, char *argv[], struct adhoc_opts * options)
...
@@ -329,7 +356,7 @@ parse_options(int argc, char *argv[], struct adhoc_opts * options)
options
->
action_string
=
optarg
;
options
->
action_string
=
optarg
;
break
;
break
;
case
'F'
:
case
'F'
:
pset
.
popt
.
topt
.
fieldSep
=
strdup
(
optarg
);
pset
.
popt
.
topt
.
fieldSep
=
x
strdup
(
optarg
);
break
;
break
;
case
'h'
:
case
'h'
:
options
->
host
=
optarg
;
options
->
host
=
optarg
;
...
@@ -377,6 +404,9 @@ parse_options(int argc, char *argv[], struct adhoc_opts * options)
...
@@ -377,6 +404,9 @@ parse_options(int argc, char *argv[], struct adhoc_opts * options)
case
'q'
:
case
'q'
:
SetVariable
(
pset
.
vars
,
"QUIET"
,
""
);
SetVariable
(
pset
.
vars
,
"QUIET"
,
""
);
break
;
break
;
case
'R'
:
pset
.
popt
.
topt
.
recordSep
=
xstrdup
(
optarg
);
break
;
case
's'
:
case
's'
:
SetVariable
(
pset
.
vars
,
"SINGLESTEP"
,
""
);
SetVariable
(
pset
.
vars
,
"SINGLESTEP"
,
""
);
break
;
break
;
...
@@ -507,7 +537,7 @@ process_psqlrc(void)
...
@@ -507,7 +537,7 @@ process_psqlrc(void)
if
(
home
)
if
(
home
)
{
{
psqlrc
=
(
char
*
)
malloc
(
strlen
(
home
)
+
20
);
psqlrc
=
malloc
(
strlen
(
home
)
+
20
);
if
(
!
psqlrc
)
if
(
!
psqlrc
)
{
{
fprintf
(
stderr
,
"%s: out of memory
\n
"
,
pset
.
progname
);
fprintf
(
stderr
,
"%s: out of memory
\n
"
,
pset
.
progname
);
...
@@ -570,7 +600,7 @@ showVersion(void)
...
@@ -570,7 +600,7 @@ showVersion(void)
#endif
#endif
puts
(
"Portions Copyright (c) 1996-2000, PostgreSQL, Inc"
);
puts
(
"Portions Copyright (c) 1996-2000, PostgreSQL, Inc"
);
puts
(
"Portions Copyright (
C
) 1996 Regents of the University of California"
);
puts
(
"Portions Copyright (
c
) 1996 Regents of the University of California"
);
puts
(
"Read the file COPYRIGHT or use the command
\\
copyright to see the"
);
puts
(
"Read the file COPYRIGHT or use the command
\\
copyright to see the"
);
puts
(
"usage and distribution terms."
);
puts
(
"usage and distribution terms."
);
}
}
src/bin/psql/stringutils.c
View file @
9ceb5d8a
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
*
*
* Copyright 2000 by PostgreSQL Global Development Group
* Copyright 2000 by PostgreSQL Global Development Group
*
*
* $Header: /cvsroot/pgsql/src/bin/psql/stringutils.c,v 1.2
3 2000/01/29 16:58:49
petere Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/stringutils.c,v 1.2
4 2000/02/07 23:10:06
petere Exp $
*/
*/
#include <c.h>
#include <c.h>
#include "stringutils.h"
#include "stringutils.h"
...
@@ -12,19 +12,13 @@
...
@@ -12,19 +12,13 @@
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
#include <assert.h>
#include <assert.h>
#include <stdio.h>
#include <stdio.h>
#include <postgres.h>
#ifndef HAVE_STRDUP
#include <strdup.h>
#endif
#include <libpq-fe.h>
#include <libpq-fe.h>
static
void
static
void
unescape_quotes
(
char
*
source
,
int
quote
,
int
escape
);
unescape_quotes
(
char
*
source
,
char
quote
,
char
escape
);
/*
/*
...
@@ -45,7 +39,7 @@ char *
...
@@ -45,7 +39,7 @@ char *
strtokx
(
const
char
*
s
,
strtokx
(
const
char
*
s
,
const
char
*
delim
,
const
char
*
delim
,
const
char
*
quote
,
const
char
*
quote
,
char
escape
,
int
escape
,
char
*
was_quoted
,
char
*
was_quoted
,
unsigned
int
*
token_pos
,
unsigned
int
*
token_pos
,
int
encoding
)
int
encoding
)
...
@@ -60,6 +54,10 @@ strtokx(const char *s,
...
@@ -60,6 +54,10 @@ strtokx(const char *s,
char
*
start
;
char
*
start
;
char
*
cp
=
NULL
;
char
*
cp
=
NULL
;
#ifndef MULTIBYTE
(
void
)
encoding
;
/*not used*/
#endif
if
(
s
)
if
(
s
)
{
{
free
(
storage
);
free
(
storage
);
...
@@ -160,7 +158,7 @@ strtokx(const char *s,
...
@@ -160,7 +158,7 @@ strtokx(const char *s,
* Resolves escaped quotes. Used by strtokx above.
* Resolves escaped quotes. Used by strtokx above.
*/
*/
static
void
static
void
unescape_quotes
(
char
*
source
,
char
quote
,
char
escape
)
unescape_quotes
(
char
*
source
,
int
quote
,
int
escape
)
{
{
char
*
p
;
char
*
p
;
char
*
destination
,
char
*
destination
,
...
@@ -170,7 +168,7 @@ unescape_quotes(char *source, char quote, char escape)
...
@@ -170,7 +168,7 @@ unescape_quotes(char *source, char quote, char escape)
assert
(
source
);
assert
(
source
);
#endif
#endif
destination
=
(
char
*
)
calloc
(
1
,
strlen
(
source
)
+
1
);
destination
=
calloc
(
1
,
strlen
(
source
)
+
1
);
if
(
!
destination
)
if
(
!
destination
)
{
{
perror
(
"calloc"
);
perror
(
"calloc"
);
...
...
src/bin/psql/stringutils.h
View file @
9ceb5d8a
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
*
*
* Copyright 2000 by PostgreSQL Global Development Group
* Copyright 2000 by PostgreSQL Global Development Group
*
*
* $Header: /cvsroot/pgsql/src/bin/psql/stringutils.h,v 1.1
3 2000/01/29 16:58:49
petere Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/stringutils.h,v 1.1
4 2000/02/07 23:10:07
petere Exp $
*/
*/
#ifndef STRINGUTILS_H
#ifndef STRINGUTILS_H
#define STRINGUTILS_H
#define STRINGUTILS_H
...
@@ -13,7 +13,7 @@
...
@@ -13,7 +13,7 @@
extern
char
*
strtokx
(
const
char
*
s
,
extern
char
*
strtokx
(
const
char
*
s
,
const
char
*
delim
,
const
char
*
delim
,
const
char
*
quote
,
const
char
*
quote
,
char
escape
,
int
escape
,
char
*
was_quoted
,
char
*
was_quoted
,
unsigned
int
*
token_pos
,
unsigned
int
*
token_pos
,
int
encoding
);
int
encoding
);
...
...
src/bin/psql/tab-complete.c
View file @
9ceb5d8a
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
*
*
* Copyright 2000 by PostgreSQL Global Development Group
* Copyright 2000 by PostgreSQL Global Development Group
*
*
* $Header: /cvsroot/pgsql/src/bin/psql/tab-complete.c,v 1.
9 2000/01/29 16:58:49
petere Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/tab-complete.c,v 1.
10 2000/02/07 23:10:07
petere Exp $
*/
*/
/*-----------
/*-----------
...
@@ -121,9 +121,7 @@ pgsql_thing_t words_after_create[] = {
...
@@ -121,9 +121,7 @@ pgsql_thing_t words_after_create[] = {
{
"TYPE"
,
"SELECT typname FROM pg_type WHERE substr(typname,1,%d)='%s'"
},
{
"TYPE"
,
"SELECT typname FROM pg_type WHERE substr(typname,1,%d)='%s'"
},
{
"UNIQUE"
,
NULL
},
/* for CREATE UNIQUE INDEX ... */
{
"UNIQUE"
,
NULL
},
/* for CREATE UNIQUE INDEX ... */
{
"USER"
,
"SELECT usename FROM pg_user WHERE substr(usename,1,%d)='%s'"
},
{
"USER"
,
"SELECT usename FROM pg_user WHERE substr(usename,1,%d)='%s'"
},
{
"VIEW"
,
NULL
},
/* Telling a view from a table is not the easiest
{
"VIEW"
,
"SELECT viewname FROM pg_views WHERE substr(viewname,1,%d)='%s'"
},
thing in the world, and the solutions I've seen
don't really work, so I'll wait on this. */
{
NULL
,
NULL
}
/* end of list */
{
NULL
,
NULL
}
/* end of list */
};
};
...
...
src/interfaces/libpq/fe-auth.c
View file @
9ceb5d8a
...
@@ -10,7 +10,7 @@
...
@@ -10,7 +10,7 @@
* exceed INITIAL_EXPBUFFER_SIZE (currently 256 bytes).
* exceed INITIAL_EXPBUFFER_SIZE (currently 256 bytes).
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-auth.c,v 1.3
6 2000/01/26 05:58:45 momjian
Exp $
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-auth.c,v 1.3
7 2000/02/07 23:10:08 petere
Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -474,6 +474,10 @@ int
...
@@ -474,6 +474,10 @@ int
fe_sendauth
(
AuthRequest
areq
,
PGconn
*
conn
,
const
char
*
hostname
,
fe_sendauth
(
AuthRequest
areq
,
PGconn
*
conn
,
const
char
*
hostname
,
const
char
*
password
,
char
*
PQerrormsg
)
const
char
*
password
,
char
*
PQerrormsg
)
{
{
#if !defined(KRB4) && !defined(KRB5)
(
void
)
hostname
;
/*not used*/
#endif
switch
(
areq
)
switch
(
areq
)
{
{
case
AUTH_REQ_OK
:
case
AUTH_REQ_OK
:
...
...
src/interfaces/libpq/fe-connect.c
View file @
9ceb5d8a
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.11
7 2000/02/05 12:33:22 ishii
Exp $
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.11
8 2000/02/07 23:10:09 petere
Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -2291,7 +2291,7 @@ conninfo_free()
...
@@ -2291,7 +2291,7 @@ conninfo_free()
}
}
/* =========== accessor functions for PGconn ========= */
/* =========== accessor functions for PGconn ========= */
c
onst
c
har
*
char
*
PQdb
(
const
PGconn
*
conn
)
PQdb
(
const
PGconn
*
conn
)
{
{
if
(
!
conn
)
if
(
!
conn
)
...
@@ -2299,7 +2299,7 @@ PQdb(const PGconn *conn)
...
@@ -2299,7 +2299,7 @@ PQdb(const PGconn *conn)
return
conn
->
dbName
;
return
conn
->
dbName
;
}
}
c
onst
c
har
*
char
*
PQuser
(
const
PGconn
*
conn
)
PQuser
(
const
PGconn
*
conn
)
{
{
if
(
!
conn
)
if
(
!
conn
)
...
@@ -2307,7 +2307,7 @@ PQuser(const PGconn *conn)
...
@@ -2307,7 +2307,7 @@ PQuser(const PGconn *conn)
return
conn
->
pguser
;
return
conn
->
pguser
;
}
}
c
onst
c
har
*
char
*
PQpass
(
const
PGconn
*
conn
)
PQpass
(
const
PGconn
*
conn
)
{
{
if
(
!
conn
)
if
(
!
conn
)
...
@@ -2315,7 +2315,7 @@ PQpass(const PGconn *conn)
...
@@ -2315,7 +2315,7 @@ PQpass(const PGconn *conn)
return
conn
->
pgpass
;
return
conn
->
pgpass
;
}
}
c
onst
c
har
*
char
*
PQhost
(
const
PGconn
*
conn
)
PQhost
(
const
PGconn
*
conn
)
{
{
if
(
!
conn
)
if
(
!
conn
)
...
@@ -2323,7 +2323,7 @@ PQhost(const PGconn *conn)
...
@@ -2323,7 +2323,7 @@ PQhost(const PGconn *conn)
return
conn
->
pghost
;
return
conn
->
pghost
;
}
}
c
onst
c
har
*
char
*
PQport
(
const
PGconn
*
conn
)
PQport
(
const
PGconn
*
conn
)
{
{
if
(
!
conn
)
if
(
!
conn
)
...
@@ -2331,7 +2331,7 @@ PQport(const PGconn *conn)
...
@@ -2331,7 +2331,7 @@ PQport(const PGconn *conn)
return
conn
->
pgport
;
return
conn
->
pgport
;
}
}
c
onst
c
har
*
char
*
PQtty
(
const
PGconn
*
conn
)
PQtty
(
const
PGconn
*
conn
)
{
{
if
(
!
conn
)
if
(
!
conn
)
...
@@ -2339,7 +2339,7 @@ PQtty(const PGconn *conn)
...
@@ -2339,7 +2339,7 @@ PQtty(const PGconn *conn)
return
conn
->
pgtty
;
return
conn
->
pgtty
;
}
}
c
onst
c
har
*
char
*
PQoptions
(
const
PGconn
*
conn
)
PQoptions
(
const
PGconn
*
conn
)
{
{
if
(
!
conn
)
if
(
!
conn
)
...
@@ -2355,7 +2355,7 @@ PQstatus(const PGconn *conn)
...
@@ -2355,7 +2355,7 @@ PQstatus(const PGconn *conn)
return
conn
->
status
;
return
conn
->
status
;
}
}
c
onst
c
har
*
char
*
PQerrorMessage
(
const
PGconn
*
conn
)
PQerrorMessage
(
const
PGconn
*
conn
)
{
{
static
char
noConn
[]
=
"PQerrorMessage: conn pointer is NULL
\n
"
;
static
char
noConn
[]
=
"PQerrorMessage: conn pointer is NULL
\n
"
;
...
@@ -2478,6 +2478,7 @@ PQsetNoticeProcessor(PGconn *conn, PQnoticeProcessor proc, void *arg)
...
@@ -2478,6 +2478,7 @@ PQsetNoticeProcessor(PGconn *conn, PQnoticeProcessor proc, void *arg)
static
void
static
void
defaultNoticeProcessor
(
void
*
arg
,
const
char
*
message
)
defaultNoticeProcessor
(
void
*
arg
,
const
char
*
message
)
{
{
(
void
)
arg
;
/*not used*/
/* Note: we expect the supplied string to end with a newline already. */
/* Note: we expect the supplied string to end with a newline already. */
fprintf
(
stderr
,
"%s"
,
message
);
fprintf
(
stderr
,
"%s"
,
message
);
}
}
src/interfaces/libpq/fe-exec.c
View file @
9ceb5d8a
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.
89 2000/01/26 05:58:45 momjian
Exp $
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.
90 2000/02/07 23:10:10 petere
Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -27,7 +27,7 @@
...
@@ -27,7 +27,7 @@
#endif
#endif
/* keep this in same order as ExecStatusType in libpq-fe.h */
/* keep this in same order as ExecStatusType in libpq-fe.h */
c
onst
char
*
const
pgresStatus
[]
=
{
c
har
*
const
pgresStatus
[]
=
{
"PGRES_EMPTY_QUERY"
,
"PGRES_EMPTY_QUERY"
,
"PGRES_COMMAND_OK"
,
"PGRES_COMMAND_OK"
,
"PGRES_TUPLES_OK"
,
"PGRES_TUPLES_OK"
,
...
@@ -1760,15 +1760,15 @@ PQresultStatus(const PGresult *res)
...
@@ -1760,15 +1760,15 @@ PQresultStatus(const PGresult *res)
return
res
->
resultStatus
;
return
res
->
resultStatus
;
}
}
c
onst
c
har
*
char
*
PQresStatus
(
ExecStatusType
status
)
PQresStatus
(
ExecStatusType
status
)
{
{
if
(
(
int
)
status
<
0
||
(
size_t
)
status
>=
sizeof
pgresStatus
/
sizeof
pgresStatus
[
0
])
if
(
status
<
0
||
status
>=
sizeof
pgresStatus
/
sizeof
pgresStatus
[
0
])
return
"Invalid ExecStatusType code"
;
return
"Invalid ExecStatusType code"
;
return
pgresStatus
[
status
];
return
pgresStatus
[
status
];
}
}
c
onst
c
har
*
char
*
PQresultErrorMessage
(
const
PGresult
*
res
)
PQresultErrorMessage
(
const
PGresult
*
res
)
{
{
if
(
!
res
||
!
res
->
errMsg
)
if
(
!
res
||
!
res
->
errMsg
)
...
@@ -1862,7 +1862,7 @@ check_tuple_field_number(const char *routineName, const PGresult *res,
...
@@ -1862,7 +1862,7 @@ check_tuple_field_number(const char *routineName, const PGresult *res,
/*
/*
returns NULL if the field_num is invalid
returns NULL if the field_num is invalid
*/
*/
c
onst
c
har
*
char
*
PQfname
(
const
PGresult
*
res
,
int
field_num
)
PQfname
(
const
PGresult
*
res
,
int
field_num
)
{
{
if
(
!
check_field_number
(
"PQfname"
,
res
,
field_num
))
if
(
!
check_field_number
(
"PQfname"
,
res
,
field_num
))
...
@@ -1947,8 +1947,8 @@ PQfmod(const PGresult *res, int field_num)
...
@@ -1947,8 +1947,8 @@ PQfmod(const PGresult *res, int field_num)
return
0
;
return
0
;
}
}
c
onst
c
har
*
char
*
PQcmdStatus
(
const
PGresult
*
res
)
PQcmdStatus
(
PGresult
*
res
)
{
{
if
(
!
res
)
if
(
!
res
)
return
NULL
;
return
NULL
;
...
@@ -1960,7 +1960,7 @@ PQcmdStatus(const PGresult *res)
...
@@ -1960,7 +1960,7 @@ PQcmdStatus(const PGresult *res)
if the last command was an INSERT, return the oid string
if the last command was an INSERT, return the oid string
if not, return ""
if not, return ""
*/
*/
c
onst
c
har
*
char
*
PQoidStatus
(
const
PGresult
*
res
)
PQoidStatus
(
const
PGresult
*
res
)
{
{
/*
/*
...
@@ -2011,8 +2011,8 @@ PQoidValue(const PGresult *res)
...
@@ -2011,8 +2011,8 @@ PQoidValue(const PGresult *res)
if the last command was an INSERT/UPDATE/DELETE, return number
if the last command was an INSERT/UPDATE/DELETE, return number
of inserted/affected tuples, if not, return ""
of inserted/affected tuples, if not, return ""
*/
*/
c
onst
c
har
*
char
*
PQcmdTuples
(
const
PGresult
*
res
)
PQcmdTuples
(
PGresult
*
res
)
{
{
char
noticeBuf
[
128
];
char
noticeBuf
[
128
];
...
@@ -2023,7 +2023,7 @@ PQcmdTuples(const PGresult *res)
...
@@ -2023,7 +2023,7 @@ PQcmdTuples(const PGresult *res)
strncmp
(
res
->
cmdStatus
,
"DELETE"
,
6
)
==
0
||
strncmp
(
res
->
cmdStatus
,
"DELETE"
,
6
)
==
0
||
strncmp
(
res
->
cmdStatus
,
"UPDATE"
,
6
)
==
0
)
strncmp
(
res
->
cmdStatus
,
"UPDATE"
,
6
)
==
0
)
{
{
c
onst
c
har
*
p
=
res
->
cmdStatus
+
6
;
char
*
p
=
res
->
cmdStatus
+
6
;
if
(
*
p
==
0
)
if
(
*
p
==
0
)
{
{
...
@@ -2067,7 +2067,7 @@ PQcmdTuples(const PGresult *res)
...
@@ -2067,7 +2067,7 @@ PQcmdTuples(const PGresult *res)
if res is not binary, a null-terminated ASCII string is returned.
if res is not binary, a null-terminated ASCII string is returned.
*/
*/
c
onst
c
har
*
char
*
PQgetvalue
(
const
PGresult
*
res
,
int
tup_num
,
int
field_num
)
PQgetvalue
(
const
PGresult
*
res
,
int
tup_num
,
int
field_num
)
{
{
if
(
!
check_tuple_field_number
(
"PQgetvalue"
,
res
,
tup_num
,
field_num
))
if
(
!
check_tuple_field_number
(
"PQgetvalue"
,
res
,
tup_num
,
field_num
))
...
...
src/interfaces/libpq/fe-lobj.c
View file @
9ceb5d8a
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-lobj.c,v 1.2
7 2000/01/26 05:58:45 momjian
Exp $
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-lobj.c,v 1.2
8 2000/02/07 23:10:11 petere
Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -168,7 +168,7 @@ lo_read(PGconn *conn, int fd, char *buf, size_t len)
...
@@ -168,7 +168,7 @@ lo_read(PGconn *conn, int fd, char *buf, size_t len)
*
*
*/
*/
int
int
lo_write
(
PGconn
*
conn
,
int
fd
,
c
onst
c
har
*
buf
,
size_t
len
)
lo_write
(
PGconn
*
conn
,
int
fd
,
char
*
buf
,
size_t
len
)
{
{
PQArgBlock
argv
[
2
];
PQArgBlock
argv
[
2
];
PGresult
*
res
;
PGresult
*
res
;
...
...
src/interfaces/libpq/fe-misc.c
View file @
9ceb5d8a
...
@@ -25,7 +25,7 @@
...
@@ -25,7 +25,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.3
8 2000/01/29 16:58:5
1 petere Exp $
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.3
9 2000/02/07 23:10:1
1 petere Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -782,6 +782,8 @@ PQenv2encoding(void)
...
@@ -782,6 +782,8 @@ PQenv2encoding(void)
int
int
PQmblen
(
const
unsigned
char
*
s
,
int
encoding
)
PQmblen
(
const
unsigned
char
*
s
,
int
encoding
)
{
{
(
void
)
s
;
(
void
)
encoding
;
return
1
;
return
1
;
}
}
int
int
...
...
src/interfaces/libpq/fe-print.c
View file @
9ceb5d8a
...
@@ -10,7 +10,7 @@
...
@@ -10,7 +10,7 @@
* didn't really belong there.
* didn't really belong there.
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-print.c,v 1.3
4 2000/02/05 12:33:22 ishii
Exp $
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-print.c,v 1.3
5 2000/02/07 23:10:11 petere
Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -59,7 +59,7 @@ static char *do_header(FILE *fout, const PQprintOpt *po, const int nFields,
...
@@ -59,7 +59,7 @@ static char *do_header(FILE *fout, const PQprintOpt *po, const int nFields,
static
void
output_row
(
FILE
*
fout
,
const
PQprintOpt
*
po
,
const
int
nFields
,
char
**
fields
,
static
void
output_row
(
FILE
*
fout
,
const
PQprintOpt
*
po
,
const
int
nFields
,
char
**
fields
,
unsigned
char
*
fieldNotNum
,
int
*
fieldMax
,
char
*
border
,
unsigned
char
*
fieldNotNum
,
int
*
fieldMax
,
char
*
border
,
const
int
row_index
);
const
int
row_index
);
static
void
fill
(
int
length
,
int
max
,
char
filler
,
FILE
*
fp
);
/*
/*
* PQprint()
* PQprint()
...
@@ -440,7 +440,6 @@ do_header(FILE *fout, const PQprintOpt *po, const int nFields, int *fieldMax,
...
@@ -440,7 +440,6 @@ do_header(FILE *fout, const PQprintOpt *po, const int nFields, int *fieldMax,
fputs
(
"<tr>"
,
fout
);
fputs
(
"<tr>"
,
fout
);
else
else
{
{
int
j
;
/* for loop index */
int
tot
=
0
;
int
tot
=
0
;
int
n
=
0
;
int
n
=
0
;
char
*
p
=
NULL
;
char
*
p
=
NULL
;
...
@@ -557,7 +556,6 @@ output_row(FILE *fout, const PQprintOpt *po, const int nFields, char **fields,
...
@@ -557,7 +556,6 @@ output_row(FILE *fout, const PQprintOpt *po, const int nFields, char **fields,
#if 0
/*
/*
* really old printing routines
* really old printing routines
*/
*/
...
@@ -728,4 +726,17 @@ PQprintTuples(const PGresult *res,
...
@@ -728,4 +726,17 @@ PQprintTuples(const PGresult *res,
}
}
}
}
}
}
#endif
/* simply send out max-length number of filler characters to fp */
static
void
fill
(
int
length
,
int
max
,
char
filler
,
FILE
*
fp
)
{
int
count
;
count
=
max
-
length
;
while
(
count
--
>=
0
)
putc
(
filler
,
fp
);
}
src/interfaces/libpq/libpq-fe.h
View file @
9ceb5d8a
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* $Id: libpq-fe.h,v 1.
59 2000/02/05 12:33:22 ishii
Exp $
* $Id: libpq-fe.h,v 1.
60 2000/02/07 23:10:11 petere
Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -74,11 +74,6 @@ extern "C"
...
@@ -74,11 +74,6 @@ extern "C"
PGRES_FATAL_ERROR
PGRES_FATAL_ERROR
}
ExecStatusType
;
}
ExecStatusType
;
/* String descriptions of the ExecStatusTypes.
* NB: direct use of this array is now deprecated; call PQresStatus() instead.
*/
extern
const
char
*
const
pgresStatus
[];
/* PGconn encapsulates a connection to the backend.
/* PGconn encapsulates a connection to the backend.
* The contents of this struct are not supposed to be known to applications.
* The contents of this struct are not supposed to be known to applications.
*/
*/
...
@@ -115,16 +110,17 @@ extern "C"
...
@@ -115,16 +110,17 @@ extern "C"
typedef
void
(
*
PQnoticeProcessor
)
(
void
*
arg
,
const
char
*
message
);
typedef
void
(
*
PQnoticeProcessor
)
(
void
*
arg
,
const
char
*
message
);
/* Print options for PQprint() */
/* Print options for PQprint() */
typedef
char
pqbool
;
typedef
struct
_PQprintOpt
typedef
struct
_PQprintOpt
{
{
int
header
;
/* print output field headings and row
pqbool
header
;
/* print output field headings and row
* count */
* count */
int
align
;
/* fill align the fields */
pqbool
align
;
/* fill align the fields */
int
standard
;
/* old brain dead format */
pqbool
standard
;
/* old brain dead format */
int
html3
;
/* output html tables */
pqbool
html3
;
/* output html tables */
int
expanded
;
/* expand tables */
pqbool
expanded
;
/* expand tables */
int
pager
;
/* use pager for output if needed */
pqbool
pager
;
/* use pager for output if needed */
char
*
fieldSep
;
/* field separator */
char
*
fieldSep
;
/* field separator */
char
*
tableOpt
;
/* insert to HTML <table ...> */
char
*
tableOpt
;
/* insert to HTML <table ...> */
char
*
caption
;
/* HTML <caption> */
char
*
caption
;
/* HTML <caption> */
...
@@ -207,15 +203,15 @@ extern "C"
...
@@ -207,15 +203,15 @@ extern "C"
extern
int
PQrequestCancel
(
PGconn
*
conn
);
extern
int
PQrequestCancel
(
PGconn
*
conn
);
/* Accessor functions for PGconn objects */
/* Accessor functions for PGconn objects */
extern
c
onst
c
har
*
PQdb
(
const
PGconn
*
conn
);
extern
char
*
PQdb
(
const
PGconn
*
conn
);
extern
c
onst
c
har
*
PQuser
(
const
PGconn
*
conn
);
extern
char
*
PQuser
(
const
PGconn
*
conn
);
extern
c
onst
c
har
*
PQpass
(
const
PGconn
*
conn
);
extern
char
*
PQpass
(
const
PGconn
*
conn
);
extern
c
onst
c
har
*
PQhost
(
const
PGconn
*
conn
);
extern
char
*
PQhost
(
const
PGconn
*
conn
);
extern
c
onst
c
har
*
PQport
(
const
PGconn
*
conn
);
extern
char
*
PQport
(
const
PGconn
*
conn
);
extern
c
onst
c
har
*
PQtty
(
const
PGconn
*
conn
);
extern
char
*
PQtty
(
const
PGconn
*
conn
);
extern
c
onst
c
har
*
PQoptions
(
const
PGconn
*
conn
);
extern
char
*
PQoptions
(
const
PGconn
*
conn
);
extern
ConnStatusType
PQstatus
(
const
PGconn
*
conn
);
extern
ConnStatusType
PQstatus
(
const
PGconn
*
conn
);
extern
c
onst
c
har
*
PQerrorMessage
(
const
PGconn
*
conn
);
extern
char
*
PQerrorMessage
(
const
PGconn
*
conn
);
extern
int
PQsocket
(
const
PGconn
*
conn
);
extern
int
PQsocket
(
const
PGconn
*
conn
);
extern
int
PQbackendPID
(
const
PGconn
*
conn
);
extern
int
PQbackendPID
(
const
PGconn
*
conn
);
extern
int
PQclientEncoding
(
const
PGconn
*
conn
);
extern
int
PQclientEncoding
(
const
PGconn
*
conn
);
...
@@ -279,21 +275,21 @@ extern "C"
...
@@ -279,21 +275,21 @@ extern "C"
/* Accessor functions for PGresult objects */
/* Accessor functions for PGresult objects */
extern
ExecStatusType
PQresultStatus
(
const
PGresult
*
res
);
extern
ExecStatusType
PQresultStatus
(
const
PGresult
*
res
);
extern
c
onst
c
har
*
PQresStatus
(
ExecStatusType
status
);
extern
char
*
PQresStatus
(
ExecStatusType
status
);
extern
c
onst
c
har
*
PQresultErrorMessage
(
const
PGresult
*
res
);
extern
char
*
PQresultErrorMessage
(
const
PGresult
*
res
);
extern
int
PQntuples
(
const
PGresult
*
res
);
extern
int
PQntuples
(
const
PGresult
*
res
);
extern
int
PQnfields
(
const
PGresult
*
res
);
extern
int
PQnfields
(
const
PGresult
*
res
);
extern
int
PQbinaryTuples
(
const
PGresult
*
res
);
extern
int
PQbinaryTuples
(
const
PGresult
*
res
);
extern
c
onst
c
har
*
PQfname
(
const
PGresult
*
res
,
int
field_num
);
extern
char
*
PQfname
(
const
PGresult
*
res
,
int
field_num
);
extern
int
PQfnumber
(
const
PGresult
*
res
,
const
char
*
field_name
);
extern
int
PQfnumber
(
const
PGresult
*
res
,
const
char
*
field_name
);
extern
Oid
PQftype
(
const
PGresult
*
res
,
int
field_num
);
extern
Oid
PQftype
(
const
PGresult
*
res
,
int
field_num
);
extern
int
PQfsize
(
const
PGresult
*
res
,
int
field_num
);
extern
int
PQfsize
(
const
PGresult
*
res
,
int
field_num
);
extern
int
PQfmod
(
const
PGresult
*
res
,
int
field_num
);
extern
int
PQfmod
(
const
PGresult
*
res
,
int
field_num
);
extern
c
onst
char
*
PQcmdStatus
(
const
PGresult
*
res
);
extern
c
har
*
PQcmdStatus
(
PGresult
*
res
);
extern
c
onst
c
har
*
PQoidStatus
(
const
PGresult
*
res
);
/* old and ugly */
extern
char
*
PQoidStatus
(
const
PGresult
*
res
);
/* old and ugly */
extern
Oid
PQoidValue
(
const
PGresult
*
res
);
/* new and improved */
extern
Oid
PQoidValue
(
const
PGresult
*
res
);
/* new and improved */
extern
c
onst
char
*
PQcmdTuples
(
const
PGresult
*
res
);
extern
c
har
*
PQcmdTuples
(
PGresult
*
res
);
extern
c
onst
c
har
*
PQgetvalue
(
const
PGresult
*
res
,
int
tup_num
,
int
field_num
);
extern
char
*
PQgetvalue
(
const
PGresult
*
res
,
int
tup_num
,
int
field_num
);
extern
int
PQgetlength
(
const
PGresult
*
res
,
int
tup_num
,
int
field_num
);
extern
int
PQgetlength
(
const
PGresult
*
res
,
int
tup_num
,
int
field_num
);
extern
int
PQgetisnull
(
const
PGresult
*
res
,
int
tup_num
,
int
field_num
);
extern
int
PQgetisnull
(
const
PGresult
*
res
,
int
tup_num
,
int
field_num
);
...
@@ -313,7 +309,6 @@ extern "C"
...
@@ -313,7 +309,6 @@ extern "C"
const
PGresult
*
res
,
const
PGresult
*
res
,
const
PQprintOpt
*
ps
);
/* option structure */
const
PQprintOpt
*
ps
);
/* option structure */
#if 0
/*
/*
* really old printing routines
* really old printing routines
*/
*/
...
@@ -330,7 +325,7 @@ extern "C"
...
@@ -330,7 +325,7 @@ extern "C"
int
terseOutput
,
/* delimiter bars */
int
terseOutput
,
/* delimiter bars */
int
width
);
/* width of column, if
int
width
);
/* width of column, if
* 0, use variable width */
* 0, use variable width */
#endif
/* === in fe-lobj.c === */
/* === in fe-lobj.c === */
...
@@ -338,7 +333,7 @@ extern "C"
...
@@ -338,7 +333,7 @@ extern "C"
extern
int
lo_open
(
PGconn
*
conn
,
Oid
lobjId
,
int
mode
);
extern
int
lo_open
(
PGconn
*
conn
,
Oid
lobjId
,
int
mode
);
extern
int
lo_close
(
PGconn
*
conn
,
int
fd
);
extern
int
lo_close
(
PGconn
*
conn
,
int
fd
);
extern
int
lo_read
(
PGconn
*
conn
,
int
fd
,
char
*
buf
,
size_t
len
);
extern
int
lo_read
(
PGconn
*
conn
,
int
fd
,
char
*
buf
,
size_t
len
);
extern
int
lo_write
(
PGconn
*
conn
,
int
fd
,
c
onst
c
har
*
buf
,
size_t
len
);
extern
int
lo_write
(
PGconn
*
conn
,
int
fd
,
char
*
buf
,
size_t
len
);
extern
int
lo_lseek
(
PGconn
*
conn
,
int
fd
,
int
offset
,
int
whence
);
extern
int
lo_lseek
(
PGconn
*
conn
,
int
fd
,
int
offset
,
int
whence
);
extern
Oid
lo_creat
(
PGconn
*
conn
,
int
mode
);
extern
Oid
lo_creat
(
PGconn
*
conn
,
int
mode
);
extern
int
lo_tell
(
PGconn
*
conn
,
int
fd
);
extern
int
lo_tell
(
PGconn
*
conn
,
int
fd
);
...
...
src/interfaces/libpq/libpq-int.h
View file @
9ceb5d8a
...
@@ -12,7 +12,7 @@
...
@@ -12,7 +12,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* $Id: libpq-int.h,v 1.1
8 2000/01/26 05:58:46 momjian
Exp $
* $Id: libpq-int.h,v 1.1
9 2000/02/07 23:10:11 petere
Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -244,6 +244,11 @@ struct pg_conn
...
@@ -244,6 +244,11 @@ struct pg_conn
int
client_encoding
;
/* encoding id */
int
client_encoding
;
/* encoding id */
};
};
/* String descriptions of the ExecStatusTypes.
* direct use of this array is deprecated; call PQresStatus() instead.
*/
extern
char
*
const
pgresStatus
[];
/* ----------------
/* ----------------
* Internal functions of libpq
* Internal functions of libpq
* Functions declared here need to be visible across files of libpq,
* Functions declared here need to be visible across files of libpq,
...
...
src/interfaces/libpq/pqexpbuffer.c
View file @
9ceb5d8a
...
@@ -17,7 +17,7 @@
...
@@ -17,7 +17,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* $Header: /cvsroot/pgsql/src/interfaces/libpq/pqexpbuffer.c,v 1.
4 2000/01/26 05:58:46 momjian
Exp $
* $Header: /cvsroot/pgsql/src/interfaces/libpq/pqexpbuffer.c,v 1.
5 2000/02/07 23:10:11 petere
Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -124,9 +124,9 @@ resetPQExpBuffer(PQExpBuffer str)
...
@@ -124,9 +124,9 @@ resetPQExpBuffer(PQExpBuffer str)
* Returns 1 if OK, 0 if failed to enlarge buffer.
* Returns 1 if OK, 0 if failed to enlarge buffer.
*/
*/
int
int
enlargePQExpBuffer
(
PQExpBuffer
str
,
in
t
needed
)
enlargePQExpBuffer
(
PQExpBuffer
str
,
size_
t
needed
)
{
{
int
newlen
;
size_t
newlen
;
char
*
newdata
;
char
*
newdata
;
needed
+=
str
->
len
+
1
;
/* total space required now */
needed
+=
str
->
len
+
1
;
/* total space required now */
...
@@ -164,8 +164,8 @@ void
...
@@ -164,8 +164,8 @@ void
printfPQExpBuffer
(
PQExpBuffer
str
,
const
char
*
fmt
,...)
printfPQExpBuffer
(
PQExpBuffer
str
,
const
char
*
fmt
,...)
{
{
va_list
args
;
va_list
args
;
int
avail
,
size_t
avail
;
nprinted
;
int
nprinted
;
resetPQExpBuffer
(
str
);
resetPQExpBuffer
(
str
);
...
@@ -214,8 +214,8 @@ void
...
@@ -214,8 +214,8 @@ void
appendPQExpBuffer
(
PQExpBuffer
str
,
const
char
*
fmt
,...)
appendPQExpBuffer
(
PQExpBuffer
str
,
const
char
*
fmt
,...)
{
{
va_list
args
;
va_list
args
;
int
avail
,
size_t
avail
;
nprinted
;
int
nprinted
;
for
(;;)
for
(;;)
{
{
...
@@ -286,7 +286,7 @@ appendPQExpBufferChar(PQExpBuffer str, char ch)
...
@@ -286,7 +286,7 @@ appendPQExpBufferChar(PQExpBuffer str, char ch)
* if necessary.
* if necessary.
*/
*/
void
void
appendBinaryPQExpBuffer
(
PQExpBuffer
str
,
const
char
*
data
,
in
t
datalen
)
appendBinaryPQExpBuffer
(
PQExpBuffer
str
,
const
char
*
data
,
size_
t
datalen
)
{
{
/* Make more room if needed */
/* Make more room if needed */
if
(
!
enlargePQExpBuffer
(
str
,
datalen
))
if
(
!
enlargePQExpBuffer
(
str
,
datalen
))
...
...
src/interfaces/libpq/pqexpbuffer.h
View file @
9ceb5d8a
...
@@ -18,7 +18,7 @@
...
@@ -18,7 +18,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* $Id: pqexpbuffer.h,v 1.
3 2000/01/26 05:58:46 momjian
Exp $
* $Id: pqexpbuffer.h,v 1.
4 2000/02/07 23:10:11 petere
Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -40,8 +40,8 @@
...
@@ -40,8 +40,8 @@
typedef
struct
PQExpBufferData
typedef
struct
PQExpBufferData
{
{
char
*
data
;
char
*
data
;
int
len
;
size_t
len
;
int
maxlen
;
size_t
maxlen
;
}
PQExpBufferData
;
}
PQExpBufferData
;
typedef
PQExpBufferData
*
PQExpBuffer
;
typedef
PQExpBufferData
*
PQExpBuffer
;
...
@@ -113,7 +113,7 @@ extern void resetPQExpBuffer(PQExpBuffer str);
...
@@ -113,7 +113,7 @@ extern void resetPQExpBuffer(PQExpBuffer str);
*
*
* Returns 1 if OK, 0 if failed to enlarge buffer.
* Returns 1 if OK, 0 if failed to enlarge buffer.
*/
*/
extern
int
enlargePQExpBuffer
(
PQExpBuffer
str
,
in
t
needed
);
extern
int
enlargePQExpBuffer
(
PQExpBuffer
str
,
size_
t
needed
);
/*------------------------
/*------------------------
* printfPQExpBuffer
* printfPQExpBuffer
...
@@ -153,6 +153,6 @@ extern void appendPQExpBufferChar(PQExpBuffer str, char ch);
...
@@ -153,6 +153,6 @@ extern void appendPQExpBufferChar(PQExpBuffer str, char ch);
* if necessary.
* if necessary.
*/
*/
extern
void
appendBinaryPQExpBuffer
(
PQExpBuffer
str
,
extern
void
appendBinaryPQExpBuffer
(
PQExpBuffer
str
,
const
char
*
data
,
in
t
datalen
);
const
char
*
data
,
size_
t
datalen
);
#endif
/* PQEXPBUFFER_H */
#endif
/* PQEXPBUFFER_H */
src/interfaces/libpq/win32.h
View file @
9ceb5d8a
...
@@ -11,9 +11,11 @@
...
@@ -11,9 +11,11 @@
* Some compat functions
* Some compat functions
*/
*/
#define open(a,b,c) _open(a,b,c)
#define open(a,b,c) _open(a,b,c)
#define close(a) _close(a)
#define read(a,b,c) _read(a,b,c)
#define read(a,b,c) _read(a,b,c)
#define write(a,b,c) _write(a,b,c)
#define write(a,b,c) _write(a,b,c)
#define popen(a,b) _popen(a,b)
#define pclose(a) _pclose(a)
/*
/*
* crypt not available (yet)
* crypt not available (yet)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment