another set of cleanups

This commit is contained in:
Peter Eisentraut 2000-01-18 23:30:24 +00:00
parent 80c5fea99d
commit f565cf41ab
30 changed files with 588 additions and 370 deletions

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/psql-ref.sgml,v 1.20 2000/01/14 22:18:01 petere Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/psql-ref.sgml,v 1.21 2000/01/18 23:30:19 petere Exp $
Postgres documentation
-->
@ -851,6 +851,16 @@ lo_import 152801
</listitem>
</varlistentry>
<varlistentry>
<term><literal>recordsep</literal></term>
<listitem>
<para>
Specifies the record (line) separator to use in unaligned output mode. The default
is a newline character.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>tuples_only</literal> (or <literal>t</literal>)</term>
<listitem>
@ -1900,12 +1910,14 @@ testdb=> <userinput>\set content `sed -e "s/'/\\\\\\'/g" < my_file.txt`</userinp
<variablelist>
<varlistentry>
<term><literal>%M</literal></term>
<listitem><para>The hostname of the database server (or <quote>.</quote> if Unix domain socket).</para></listitem>
<listitem><para>The hostname of the database server (or <quote>.</quote>
if Unix domain socket).</para></listitem>
</varlistentry>
<varlistentry>
<term><literal>%m</literal></term>
<listitem><para>The hostname of the database server truncated after the first dot.</para></listitem>
<listitem><para>The hostname of the database server truncated after the
first dot.</para></listitem>
</varlistentry>
<varlistentry>
@ -1915,7 +1927,8 @@ testdb=> <userinput>\set content `sed -e "s/'/\\\\\\'/g" < my_file.txt`</userinp
<varlistentry>
<term><literal>%n</literal></term>
<listitem><para>The username you are connected as (not your local system user name).</para></listitem>
<listitem><para>The username you are connected as (not your local system
user name).</para></listitem>
</varlistentry>
<varlistentry>
@ -1925,37 +1938,39 @@ testdb=> <userinput>\set content `sed -e "s/'/\\\\\\'/g" < my_file.txt`</userinp
<varlistentry>
<term><literal>%~</literal></term>
<listitem><para>Like <literal>%/</literal>, but the output is <quote>~</quote> (tilde) if the database
is your default database.</para></listitem>
<listitem><para>Like <literal>%/</literal>, but the output is <quote>~</quote>
(tilde) if the database is your default database.</para></listitem>
</varlistentry>
<varlistentry>
<term><literal>%#</literal></term>
<listitem><para>If the username is <literal>postgres</literal>, a <quote>#</quote>, otherwise a <quote>&gt;</quote>.</para></listitem>
<listitem><para>If the username is <literal>postgres</literal>, a
<quote>#</quote>, otherwise a <quote>&gt;</quote>.</para></listitem>
</varlistentry>
<varlistentry>
<term><literal>%R</literal></term>
<listitem><para>
In prompt 1 normally <quote>=</quote>, but <quote>^</quote> if in single-line mode, and
<quote>!</quote> if the session is disconnected from the database (which can only
happen if <command>\connect</command> fails).
In prompt 2 the sequence is replaced by <quote>-</quote>, <quote>*</quote>, a single quote,
or a double quote, depending on whether <application>psql</application> expects more input
because the query wasn't terminated yet, because you are inside a <literal>/* ... */</literal>
comment, or because you are inside a quote.
In prompt 3 the sequence doesn't resolve to anything.</para>
In prompt 1 normally <quote>=</quote>, but <quote>^</quote> if in single-line
mode, and <quote>!</quote> if the session is disconnected from the database
(which can happen if <command>\connect</command> fails). In prompt 2 the
sequence is replaced by <quote>-</quote>, <quote>*</quote>, a single quote,
or a double quote, depending on whether <application>psql</application>
expects more input because the query wasn't terminated yet, because you are
inside a <literal>/* ... */</literal> comment, or because you are inside
a quote. In prompt 3 the sequence doesn't resolve to anything.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>%</literal><replaceable class="parameter">digits</replaceable></term>
<listitem><para>
If <replaceable class="parameter">digits</replaceable> starts with <literal>0x</literal>
the rest of the characters are interpreted at a hexadecimal digit and the
character with the corresponding code is subsituted. If the first digit is <literal>0</literal>
the characters are interpreted as on octal number and the corresponding character
is substituted. Otherwise a decimal number is assumed.</para>
If <replaceable class="parameter">digits</replaceable> starts with
<literal>0x</literal> the rest of the characters are interpreted at a
hexadecimal digit and the character with the corresponding code is
subsituted. If the first digit is <literal>0</literal> the characters are
interpreted as on octal number and the corresponding character is
substituted. Otherwise a decimal number is assumed.</para>
</listitem>
</varlistentry>

View File

@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.130 2000/01/18 19:08:13 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.131 2000/01/18 23:30:20 petere Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@ -854,6 +854,7 @@ AlterTableStmt:
| ALTER TABLE relation_name opt_inh_star DROP CONSTRAINT name drop_behavior
{
AlterTableStmt *n = makeNode(AlterTableStmt);
n->subtype = 'X';
n->relname = $3;
n->inh = $4;
n->name = $7;

View File

@ -1,6 +1,14 @@
/*
* psql - the PostgreSQL interactive terminal
*
* Copyright 2000 by PostgreSQL Global Development Team
*
* $Header: /cvsroot/pgsql/src/bin/psql/command.c,v 1.13 2000/01/18 23:30:22 petere Exp $
*/
#include <c.h>
#include "command.h"
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
@ -39,12 +47,11 @@
static backslashResult exec_command(const char *cmd,
char *const * options,
const char *options_string,
PQExpBuffer query_buf,
int encoding);
PQExpBuffer query_buf);
static bool do_edit(const char *filename_arg, PQExpBuffer query_buf);
static char * unescape(const char *source, int encoding);
static char * unescape(const char *source);
static bool do_connect(const char *new_dbname,
const char *new_user);
@ -81,8 +88,7 @@ static bool do_shell(const char *command);
backslashResult
HandleSlashCmds(const char *line,
PQExpBuffer query_buf,
const char **end_of_cmd,
int encoding)
const char **end_of_cmd)
{
backslashResult status = CMD_SKIP_LINE;
char *my_line;
@ -134,14 +140,14 @@ HandleSlashCmds(const char *line,
* whitespace */
i = 0;
token = strtokx(options_string, " \t", "\"'`", '\\', &quote, &pos, encoding);
token = strtokx(options_string, " \t", "\"'`", '\\', &quote, &pos, pset.encoding);
for (i = 0; token && i < NR_OPTIONS; i++)
{
switch (quote)
{
case '"':
options[i] = unescape(token, encoding);
options[i] = unescape(token);
break;
case '\'':
options[i] = xstrdup(token);
@ -150,7 +156,7 @@ HandleSlashCmds(const char *line,
{
bool error = false;
FILE *fd = NULL;
char *file = unescape(token, encoding);
char *file = unescape(token);
PQExpBufferData output;
char buf[512];
size_t result;
@ -158,7 +164,7 @@ HandleSlashCmds(const char *line,
fd = popen(file, "r");
if (!fd)
{
perror(file);
psql_error("%s: %s\n", file, strerror(errno));
error = true;
}
@ -171,7 +177,7 @@ HandleSlashCmds(const char *line,
result = fread(buf, 1, 512, fd);
if (ferror(fd))
{
perror(file);
psql_error("%s: %s\n", file, strerror(errno));
error = true;
break;
}
@ -181,7 +187,7 @@ HandleSlashCmds(const char *line,
if (pclose(fd) == -1)
{
perror(file);
psql_error("%s: %s\n", file, strerror(errno));
error = true;
}
}
@ -220,14 +226,14 @@ HandleSlashCmds(const char *line,
if (continue_parse)
break;
token = strtokx(NULL, " \t", "\"'`", '\\', &quote, &pos, encoding);
token = strtokx(NULL, " \t", "\"'`", '\\', &quote, &pos, pset.encoding);
} /* for */
options[i] = NULL;
}
cmd = my_line;
status = exec_command(cmd, options, options_string, query_buf, encoding);
status = exec_command(cmd, options, options_string, query_buf);
if (status == CMD_UNKNOWN)
{
@ -249,7 +255,7 @@ HandleSlashCmds(const char *line,
new_cmd[0] = cmd[0];
new_cmd[1] = '\0';
status = exec_command(new_cmd, (char *const *) new_options, my_line + 2, query_buf, encoding);
status = exec_command(new_cmd, (char *const *) new_options, my_line + 2, query_buf);
}
if (status == CMD_UNKNOWN)
@ -257,7 +263,7 @@ HandleSlashCmds(const char *line,
if (pset.cur_cmd_interactive)
fprintf(stderr, "Invalid command \\%s. Try \\? for help.\n", cmd);
else
fprintf(stderr, "%s: invalid command \\%s", pset.progname, cmd);
psql_error("invalid command \\%s\n", cmd);
status = CMD_ERROR;
}
@ -286,8 +292,7 @@ static backslashResult
exec_command(const char *cmd,
char *const * options,
const char *options_string,
PQExpBuffer query_buf,
int encoding)
PQExpBuffer query_buf)
{
bool success = true; /* indicate here if the command ran ok or
* failed */
@ -342,7 +347,7 @@ exec_command(const char *cmd,
/* \copy */
else if (strcasecmp(cmd, "copy") == 0)
success = do_copy(options_string, encoding);
success = do_copy(options_string);
/* \copyright */
else if (strcmp(cmd, "copyright") == 0)
@ -461,15 +466,12 @@ exec_command(const char *cmd,
else if (strcmp(cmd, "i") == 0 || strcmp(cmd, "include") == 0)
{
if (!options[0])
{
if (pset.cur_cmd_interactive)
fprintf(stderr, "\\%s: missing required argument\n", cmd);
else
fprintf(stderr, "%s: \\%s: missing required argument", pset.progname, cmd);
{
psql_error("\\%s: missing required argument\n", cmd);
success = false;
}
else
success = process_file(options[0], encoding);
success = process_file(options[0]);
}
@ -487,10 +489,7 @@ exec_command(const char *cmd,
{
if (!options[1])
{
if (pset.cur_cmd_interactive)
fprintf(stderr, "\\%s: missing required argument", cmd);
else
fprintf(stderr, "%s: \\%s: missing required argument", pset.progname, cmd);
psql_error("\\%s: missing required argument\n", cmd);
success = false;
}
else
@ -501,10 +500,7 @@ exec_command(const char *cmd,
{
if (!options[0])
{
if (pset.cur_cmd_interactive)
fprintf(stderr, "\\%s: missing required argument", cmd);
else
fprintf(stderr, "%s: \\%s: missing required argument", pset.progname, cmd);
psql_error("\\%s: missing required argument\n", cmd);
success = false;
}
else
@ -518,10 +514,7 @@ exec_command(const char *cmd,
{
if (!options[0])
{
if (pset.cur_cmd_interactive)
fprintf(stderr, "\\%s: missing required argument", cmd);
else
fprintf(stderr, "%s: \\%s: missing required argument", pset.progname, cmd);
psql_error("\\%s: missing required argument\n", cmd);
success = false;
}
else
@ -552,10 +545,7 @@ exec_command(const char *cmd,
{
if (!options[0])
{
if (pset.cur_cmd_interactive)
fprintf(stderr, "\\%s: missing required argument", cmd);
else
fprintf(stderr, "%s: \\%s: missing required argument", pset.progname, cmd);
psql_error("\\%s: missing required argument\n", cmd);
success = false;
}
else
@ -626,11 +616,7 @@ exec_command(const char *cmd,
val = "";
if (!SetVariable(pset.vars, options[0], val))
{
if (pset.cur_cmd_interactive)
fprintf(stderr, "\\%s: error\n", cmd);
else
fprintf(stderr, "%s: \\%s: error\n", pset.progname, cmd);
psql_error("\\%s: error\n", cmd);
success = false;
}
}
@ -650,10 +636,7 @@ exec_command(const char *cmd,
{
if (!SetVariable(pset.vars, options[0], NULL))
{
if (pset.cur_cmd_interactive)
fprintf(stderr, "\\%s: error\n", cmd);
else
fprintf(stderr, "%s: \\%s: error\n", pset.progname, cmd);
psql_error("\\%s: error\n", cmd);
success = false;
}
@ -667,10 +650,7 @@ exec_command(const char *cmd,
if (!options[0])
{
if (pset.cur_cmd_interactive)
fprintf(stderr, "\\%s: missing required argument", cmd);
else
fprintf(stderr, "%s: \\%s: missing required argument", pset.progname, cmd);
psql_error("\\%s: missing required argument\n", cmd);
success = false;
}
else
@ -678,24 +658,16 @@ exec_command(const char *cmd,
if (options[0][0] == '|')
{
pipe = true;
#ifndef __CYGWIN32__
fd = popen(&options[0][1], "w");
#else
fd = popen(&options[0][1], "wb");
#endif
}
else
{
#ifndef __CYGWIN32__
fd = fopen(options[0], "w");
#else
fd = fopen(options[0], "wb");
#endif
}
if (!fd)
{
perror(options[0]);
psql_error("%s: %s\n", options[0], strerror(errno));
success = false;
}
}
@ -714,7 +686,7 @@ exec_command(const char *cmd,
if (result == EOF)
{
perror("close");
psql_error("%s: %s\n", options[0], strerror(errno));
success = false;
}
}
@ -737,9 +709,8 @@ exec_command(const char *cmd,
slashUsage();
#ifdef NOT_USED
/*
#if 0
/*
* These commands don't do anything. I just use them to test the
* parser.
*/
@ -772,7 +743,7 @@ exec_command(const char *cmd,
* The return value is malloc()'ed.
*/
static char *
unescape(const char *source, int encoding)
unescape(const char *source)
{
unsigned char *p;
bool esc = false; /* Last character we saw was the escape
@ -790,11 +761,11 @@ unescape(const char *source, int encoding)
tmp = destination = (char *) malloc(length);
if (!tmp)
{
perror("malloc");
psql_error("out of memory\n");
exit(EXIT_FAILURE);
}
for (p = (char *) source; *p; p += PQmblen(p, encoding))
for (p = (char *) source; *p; p += PQmblen(p, pset.encoding))
{
if (esc)
{
@ -866,7 +837,7 @@ unescape(const char *source, int encoding)
new = realloc(destination, length);
if (!new)
{
perror("realloc");
psql_error("out of memory\n");
exit(EXIT_FAILURE);
}
tmp = new + (tmp - destination);
@ -946,20 +917,6 @@ do_connect(const char *new_dbname, const char *new_user)
if (!pwparam && oldconn)
pwparam = PQpass(oldconn);
#ifdef MULTIBYTE
/*
* PGCLIENTENCODING may be set by the previous connection. if a user
* does not explicitly set PGCLIENTENCODING, we should discard
* PGCLIENTENCODING so that libpq could get the backend encoding as
* the default PGCLIENTENCODING value. -- 1998/12/12 Tatsuo Ishii
*/
if (!pset.has_client_encoding)
putenv("PGCLIENTENCODING=");
#endif
do
{
need_pass = false;
@ -986,7 +943,7 @@ do_connect(const char *new_dbname, const char *new_user)
{
if (pset.cur_cmd_interactive)
{
fprintf(stderr, "%s", PQerrorMessage(pset.db));
psql_error("%s", PQerrorMessage(pset.db));
PQfinish(pset.db);
if (oldconn)
{
@ -1000,7 +957,7 @@ do_connect(const char *new_dbname, const char *new_user)
{
/* we don't want unpredictable things to
* happen in scripting mode */
fprintf(stderr, "%s: \\connect: %s", pset.progname, PQerrorMessage(pset.db));
psql_error("\\connect: %s", PQerrorMessage(pset.db));
PQfinish(pset.db);
if (oldconn)
PQfinish(oldconn);
@ -1026,6 +983,9 @@ do_connect(const char *new_dbname, const char *new_user)
success = true;
}
PQsetNoticeProcessor(pset.db, NoticeProcessor, NULL);
pset.encoding = PQclientencoding(pset.db);
/* Update variables */
SetVariable(pset.vars, "DBNAME", PQdb(pset.db));
SetVariable(pset.vars, "USER", PQuser(pset.db));
@ -1072,8 +1032,10 @@ editFile(const char *fname)
return false;
sprintf(sys, "exec %s %s", editorName, fname);
result = system(sys);
if (result == -1 || result == 127)
perror(sys);
if (result == -1)
psql_error("could not start editor\n");
else if (result == 127)
psql_error("could not start /bin/sh\n");
free(sys);
return result == 0;
@ -1131,7 +1093,7 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf)
if (!stream)
{
perror(fname);
psql_error("couldn't open temp file %s: %s\n", fname, strerror(errno));
error = true;
}
else
@ -1146,7 +1108,7 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf)
if (fwrite(query_buf->data, 1, ql, stream) != ql)
{
perror(fname);
psql_error("%s: %s\n", fname, strerror(errno));
fclose(stream);
remove(fname);
error = true;
@ -1159,7 +1121,7 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf)
#ifndef WIN32
if (!error && stat(fname, &before) != 0)
{
perror(fname);
psql_error("%s: %s\n", fname, strerror(errno));
error = true;
}
#endif
@ -1171,7 +1133,7 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf)
#ifndef WIN32
if (!error && stat(fname, &after) != 0)
{
perror(fname);
psql_error("%s: %s\n", fname, strerror(errno));
error = true;
}
@ -1184,7 +1146,7 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf)
stream = fopen(fname, "r");
if (!stream)
{
perror(fname);
psql_error("%s: %s\n", fname, strerror(errno));
error = true;
}
else
@ -1199,7 +1161,7 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf)
result = fread(line, 1, 1024, stream);
if (ferror(stream))
{
perror(fname);
psql_error("%s: %s\n", fname, strerror(errno));
error = true;
break;
}
@ -1212,9 +1174,14 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf)
/* remove temp file */
if (!filename_arg)
remove(fname);
}
{
if (remove(fname)==-1)
{
psql_error("%s: %s\n", fname, strerror(errno));
error=true;
}
}
}
return !error;
}
@ -1227,7 +1194,7 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf)
* Handler for \i, but can be used for other things as well.
*/
bool
process_file(const char *filename, int encoding)
process_file(char *filename)
{
FILE *fd;
int result;
@ -1243,13 +1210,12 @@ process_file(const char *filename, int encoding)
if (!fd)
{
if (!pset.cur_cmd_interactive)
fprintf(stderr, "%s: ", pset.progname);
perror(filename);
psql_error("%s: %s\n", filename, strerror(errno));
return false;
}
result = MainLoop(fd, encoding);
pset.inputfile = filename;
result = MainLoop(fd);
fclose(fd);
return (result == EXIT_SUCCESS);
}
@ -1315,7 +1281,7 @@ do_pset(const char *param, const char *value, printQueryOpt * popt, bool quiet)
popt->topt.format = PRINT_LATEX;
else
{
fprintf(stderr, "Allowed formats are unaligned, aligned, html, latex.\n");
psql_error("\\pset: allowed formats are unaligned, aligned, html, latex\n");
return false;
}
@ -1362,7 +1328,23 @@ do_pset(const char *param, const char *value, printQueryOpt * popt, bool quiet)
popt->topt.fieldSep = xstrdup(value);
}
if (!quiet)
printf("Field separator is \"%s\".\n", popt->topt.fieldSep);
printf("Field separator is '%s'.\n", popt->topt.fieldSep);
}
/* record separator for unaligned text */
else if (strcmp(param, "recordsep") == 0)
{
if (value)
{
free(popt->topt.recordSep);
popt->topt.recordSep = xstrdup(value);
}
if (!quiet) {
if (strcmp(popt->topt.recordSep, "\n")==0)
printf("Record separator is <newline>.");
else
printf("Record separator is '%s'.\n", popt->topt.recordSep);
}
}
/* toggle between full and barebones format */
@ -1430,7 +1412,7 @@ do_pset(const char *param, const char *value, printQueryOpt * popt, bool quiet)
else
{
fprintf(stderr, "Unknown option: %s\n", param);
psql_error("\\pset: unknown option: %s\n", param);
return false;
}
@ -1456,8 +1438,13 @@ do_shell(const char *command)
shellName = DEFAULT_SHELL;
sys = malloc(strlen(shellName) + 16);
if (!sys)
return false;
if (!sys) {
psql_error("out of memory\n");
if (pset.cur_cmd_interactive)
return false;
else
exit(EXIT_FAILURE);
}
sprintf(sys, "exec %s", shellName);
result = system(sys);
free(sys);
@ -1467,7 +1454,7 @@ do_shell(const char *command)
if (result == 127 || result == -1)
{
perror("system");
psql_error("\\!: failed\n");
return false;
}
return true;

View File

@ -1,7 +1,13 @@
/*
* psql - the PostgreSQL interactive terminal
*
* Copyright 2000 by PostgreSQL Global Development Team
*
* $Header: /cvsroot/pgsql/src/bin/psql/command.h,v 1.6 2000/01/18 23:30:23 petere Exp $
*/
#ifndef COMMAND_H
#define COMMAND_H
#include <config.h>
#include <c.h>
#include <pqexpbuffer.h>
@ -10,7 +16,6 @@
#include "print.h"
typedef enum _backslashResult
{
CMD_UNKNOWN = 0, /* not done parsing yet (internal only) */
@ -23,14 +28,13 @@ typedef enum _backslashResult
} backslashResult;
backslashResult
HandleSlashCmds(const char *line,
PQExpBuffer query_buf,
const char **end_of_cmd, int encoding);
const char **end_of_cmd);
bool
process_file(const char *filename, int encoding);
process_file(char *filename);
bool
do_pset(const char *param,
@ -38,4 +42,4 @@ do_pset(const char *param,
printQueryOpt * popt,
bool quiet);
#endif
#endif /* COMMAND_H */

View File

@ -1,3 +1,10 @@
/*
* psql - the PostgreSQL interactive terminal
*
* Copyright 2000 by PostgreSQL Global Development Team
*
* $Header: /cvsroot/pgsql/src/bin/psql/common.c,v 1.9 2000/01/18 23:30:23 petere Exp $
*/
#include <c.h>
#include "common.h"
@ -5,6 +12,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#ifdef HAVE_TERMIOS_H
#include <termios.h>
#endif
@ -49,13 +57,13 @@ xstrdup(const char *string)
if (!string)
{
fprintf(stderr, "xstrdup: Cannot duplicate null pointer.\n");
fprintf(stderr, "%s: xstrdup: cannot duplicate null pointer\n", pset.progname);
exit(EXIT_FAILURE);
}
tmp = strdup(string);
if (!tmp)
{
perror("strdup");
psql_error("out of memory\n");
exit(EXIT_FAILURE);
}
return tmp;
@ -104,7 +112,7 @@ setQFout(const char *fname)
if (!(pset.queryFout))
{
fprintf(stderr, "%s: %s: %s\n", pset.progname, fname, strerror(errno));
psql_error("%s: %s\n", fname, strerror(errno));
pset.queryFout = stdout;
pset.queryFoutPipe = false;
status = false;
@ -123,6 +131,38 @@ setQFout(const char *fname)
/*
* Error reporting for scripts. Errors should look like
* filename:lineno: message
*
*/
void
psql_error(const char *fmt, ...)
{
va_list ap;
fflush(stdout);
if (pset.queryFout!=stdout)
fflush(pset.queryFout);
if (pset.inputfile)
fprintf(stderr, "%s:%u: ", pset.inputfile ? pset.inputfile : pset.progname, pset.lineno);
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
}
/* for backend NOTICES */
void
NoticeProcessor(void * arg, const char * message)
{
(void)arg; /* not used */
psql_error("%s", message);
}
/*
* simple_prompt
*
@ -239,7 +279,7 @@ PSQLexec(const char *query)
if (!pset.db)
{
fputs("You are currently not connected to a database.\n", stderr);
psql_error("You are currently not connected to a database.\n");
return NULL;
}
@ -268,7 +308,7 @@ PSQLexec(const char *query)
{
if (!pset.cur_cmd_interactive)
{
fprintf(stderr, "%s: connection to server was lost", pset.progname);
psql_error("connection to server was lost");
exit(EXIT_BADCONN);
}
fputs("The connection to the server was lost. Attempting reset: ", stderr);
@ -297,7 +337,7 @@ PSQLexec(const char *query)
return res;
else
{
fputs(PQerrorMessage(pset.db), stderr);
psql_error("%s", PQerrorMessage(pset.db));
PQclear(res);
return NULL;
}
@ -326,7 +366,7 @@ SendQuery(const char *query)
if (!pset.db)
{
fputs("You are currently not connected to a database.\n", stderr);
psql_error("you are currently not connected to a database.\n");
return false;
}
@ -436,7 +476,7 @@ SendQuery(const char *query)
case PGRES_FATAL_ERROR:
case PGRES_BAD_RESPONSE:
success = false;
fputs(PQerrorMessage(pset.db), stderr);
psql_error("%s", PQerrorMessage(pset.db));
break;
}
@ -446,7 +486,7 @@ SendQuery(const char *query)
{
if (!pset.cur_cmd_interactive)
{
fprintf(stderr, "%s: connection to server was lost", pset.progname);
psql_error("connection to server was lost");
exit(EXIT_BADCONN);
}
fputs("The connection to the server was lost. Attempting reset: ", stderr);

View File

@ -1,22 +1,33 @@
/*
* psql - the PostgreSQL interactive terminal
*
* Copyright 2000 by PostgreSQL Global Development Team
*
* $Header: /cvsroot/pgsql/src/bin/psql/common.h,v 1.4 2000/01/18 23:30:23 petere Exp $
*/
#ifndef COMMON_H
#define COMMON_H
#include <c.h>
#include "settings.h"
#include <libpq-fe.h>
char *
xstrdup(const char *string);
char * xstrdup(const char *string);
bool
setQFout(const char *fname);
bool setQFout(const char *fname);
char *
simple_prompt(const char *prompt, int maxlen, bool echo);
#ifndef __GNUC__
void psql_error(const char *fmt, ...);
#else
/* This checks the format string for consistency. */
void psql_error(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
#endif
PGresult *
PSQLexec(const char *query);
void NoticeProcessor(void * arg, const char * message);
bool
SendQuery(const char *query);
char * simple_prompt(const char *prompt, int maxlen, bool echo);
PGresult * PSQLexec(const char *query);
bool SendQuery(const char *query);
#endif /* COMMON_H */

View File

@ -1,3 +1,10 @@
/*
* psql - the PostgreSQL interactive terminal
*
* Copyright 2000 by PostgreSQL Global Development Team
*
* $Header: /cvsroot/pgsql/src/bin/psql/copy.c,v 1.6 2000/01/18 23:30:23 petere Exp $
*/
#include <c.h>
#include "copy.h"
@ -58,7 +65,7 @@ free_copy_options(struct copy_options * ptr)
static struct copy_options *
parse_slash_copy(const char *args, int encoding)
parse_slash_copy(const char *args)
{
struct copy_options *result;
char *line;
@ -70,11 +77,11 @@ parse_slash_copy(const char *args, int encoding)
if (!(result = calloc(1, sizeof(struct copy_options))))
{
perror("calloc");
psql_error("out of memory\n");
exit(EXIT_FAILURE);
}
token = strtokx(line, " \t", "\"", '\\', &quote, NULL, encoding);
token = strtokx(line, " \t", "\"", '\\', &quote, NULL, pset.encoding);
if (!token)
error = true;
else
@ -84,7 +91,7 @@ parse_slash_copy(const char *args, int encoding)
if (!quote && strcasecmp(token, "binary") == 0)
{
result->binary = true;
token = strtokx(NULL, " \t", "\"", '\\', &quote, NULL, encoding);
token = strtokx(NULL, " \t", "\"", '\\', &quote, NULL, pset.encoding);
if (!token)
error = true;
}
@ -99,14 +106,14 @@ parse_slash_copy(const char *args, int encoding)
if (!error)
{
token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL, encoding);
token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL, pset.encoding);
if (!token)
error = true;
else
{
if (strcasecmp(token, "with") == 0)
{
token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL, encoding);
token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL, pset.encoding);
if (!token || strcasecmp(token, "oids") != 0)
error = true;
else
@ -114,7 +121,7 @@ parse_slash_copy(const char *args, int encoding)
if (!error)
{
token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL, encoding);
token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL, pset.encoding);
if (!token)
error = true;
}
@ -131,7 +138,7 @@ parse_slash_copy(const char *args, int encoding)
if (!error)
{
token = strtokx(NULL, " \t", "'", '\\', &quote, NULL, encoding);
token = strtokx(NULL, " \t", "'", '\\', &quote, NULL, pset.encoding);
if (!token)
error = true;
else if (!quote && (strcasecmp(token, "stdin")==0 || strcasecmp(token, "stdout")==0))
@ -142,21 +149,21 @@ parse_slash_copy(const char *args, int encoding)
if (!error)
{
token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL, encoding);
token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL, pset.encoding);
if (token)
{
if (strcasecmp(token, "using") == 0)
{
token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL, encoding);
token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL, pset.encoding);
if (!token || strcasecmp(token, "delimiters") != 0)
error = true;
else
{
token = strtokx(NULL, " \t", "'", '\\', NULL, NULL, encoding);
token = strtokx(NULL, " \t", "'", '\\', NULL, NULL, pset.encoding);
if (token)
{
result->delim = xstrdup(token);
token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL, encoding);
token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL, pset.encoding);
}
else
error = true;
@ -167,17 +174,17 @@ parse_slash_copy(const char *args, int encoding)
{
if (strcasecmp(token, "with") == 0)
{
token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL, encoding);
token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL, pset.encoding);
if (!token || strcasecmp(token, "null") != 0)
error = true;
else
{
token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL, encoding);
token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL, pset.encoding);
if (!token || strcasecmp(token, "as") != 0)
error = true;
else
{
token = strtokx(NULL, " \t", "'", '\\', NULL, NULL, encoding);
token = strtokx(NULL, " \t", "'", '\\', NULL, NULL, pset.encoding);
if (token)
result->null = xstrdup(token);
}
@ -191,15 +198,11 @@ parse_slash_copy(const char *args, int encoding)
if (error)
{
if (!pset.cur_cmd_interactive)
fprintf(stderr, "%s: ", pset.progname);
fputs("\\copy: parse error at ", stderr);
if (!token)
fputs("end of line", stderr);
else
fprintf(stderr, "'%s'", token);
fputs("\n", stderr);
free(result);
psql_error("\\copy: parse error at %s%s%s\n",
token ? "'" : "",
token ? token : "end of line",
token ? "'" : "");
free_copy_options(result);
return NULL;
}
else
@ -214,7 +217,7 @@ parse_slash_copy(const char *args, int encoding)
* file or route its response into the file.
*/
bool
do_copy(const char *args, int encoding)
do_copy(const char *args)
{
char query[128 + NAMEDATALEN];
FILE *copystream;
@ -223,7 +226,7 @@ do_copy(const char *args, int encoding)
bool success;
/* parse options */
options = parse_slash_copy(args, encoding);
options = parse_slash_copy(args);
if (!options)
return false;
@ -275,11 +278,8 @@ do_copy(const char *args, int encoding)
if (!copystream)
{
if (!pset.cur_cmd_interactive)
fprintf(stderr, "%s: ", pset.progname);
fprintf(stderr,
"unable to open file %s: %s\n",
options->file, strerror(errno));
psql_error("%s: %s\n",
options->file, strerror(errno));
free_copy_options(options);
return false;
}
@ -298,24 +298,15 @@ do_copy(const char *args, int encoding)
case PGRES_FATAL_ERROR:
case PGRES_BAD_RESPONSE:
success = false;
fputs(PQerrorMessage(pset.db), stderr);
psql_error("\\copy: %s", PQerrorMessage(pset.db));
break;
default:
success = false;
if (!pset.cur_cmd_interactive)
fprintf(stderr, "%s: ", pset.progname);
fprintf(stderr, "\\copy: unexpected response (%d)\n", PQresultStatus(result));
psql_error("\\copy: unexpected response (%d)\n", PQresultStatus(result));
}
PQclear(result);
if (!success)
{
if (!pset.cur_cmd_interactive)
fprintf(stderr, "%s: ", pset.progname);
fprintf(stderr, "\\copy failed\n");
}
if (copystream != stdout && copystream != stdin)
fclose(copystream);
free_copy_options(options);

View File

@ -1,22 +1,23 @@
/*
* psql - the PostgreSQL interactive terminal
*
* Copyright 2000 by PostgreSQL Global Development Team
*
* $Header: /cvsroot/pgsql/src/bin/psql/copy.h,v 1.5 2000/01/18 23:30:23 petere Exp $
*/
#ifndef COPY_H
#define COPY_H
#include <c.h>
#include <stdio.h>
#include <libpq-fe.h>
#include "settings.h"
/* handler for \copy */
bool
do_copy(const char *args, int encoding);
bool do_copy(const char *args);
/* lower level processors for copy in/out streams */
bool
handleCopyOut(PGconn *conn, FILE *copystream);
bool
handleCopyIn(PGconn *conn, FILE *copystream, const char *prompt);
bool handleCopyOut(PGconn *conn, FILE *copystream);
bool handleCopyIn(PGconn *conn, FILE *copystream, const char *prompt);
#endif

View File

@ -1,4 +1,10 @@
#include <config.h>
/*
* psql - the PostgreSQL interactive terminal
*
* Copyright 2000 by PostgreSQL Global Development Team
*
* $Header: /cvsroot/pgsql/src/bin/psql/describe.c,v 1.13 2000/01/18 23:30:23 petere Exp $
*/
#include <c.h>
#include "describe.h"
@ -470,7 +476,6 @@ objectDescription(const char *object)
if (!res)
return false;
myopt.topt.tuples_only = false;
myopt.nullPrint = NULL;
myopt.title = "Object descriptions";
@ -861,10 +866,8 @@ describeTableDetails(const char *name, bool desc)
PQclear(result4);
}
if (!error) {
myopt.tuples_only = false;
printTable(title, headers, (const char**)cells, (const char**)footers, "llll", &myopt, pset.queryFout);
}
if (!error)
printTable(title, headers, (const char**)cells, (const char**)footers, "llll", &myopt, pset.queryFout);
/* clean up */
free(title);
@ -1106,7 +1109,6 @@ listTables(const char *infotype, const char *name, bool desc)
}
else
{
myopt.topt.tuples_only = false;
myopt.nullPrint = NULL;
myopt.title = "List of relations";

View File

@ -1,3 +1,10 @@
/*
* psql - the PostgreSQL interactive terminal
*
* Copyright 2000 by PostgreSQL Global Development Team
*
* $Header: /cvsroot/pgsql/src/bin/psql/describe.h,v 1.6 2000/01/18 23:30:23 petere Exp $
*/
#ifndef DESCRIBE_H
#define DESCRIBE_H

View File

@ -1,4 +1,10 @@
#include <config.h>
/*
* psql - the PostgreSQL interactive terminal
*
* Copyright 2000 by PostgreSQL Global Development Team
*
* $Header: /cvsroot/pgsql/src/bin/psql/help.c,v 1.11 2000/01/18 23:30:23 petere Exp $
*/
#include <c.h>
#include "help.h"
@ -68,23 +74,23 @@ usage(void)
puts( "\nUsage:");
puts( " psql [options] [dbname [username]]");
puts( "\nOptions:");
puts( " -A Unaligned table output mode (-P format=unaligned");
puts( " -c query Run only single query (or slash command) and exit");
puts( " -A Unaligned table output mode (-P format=unaligned)");
puts( " -c <query> Run only single query (or slash command) and exit");
/* Display default database */
env = getenv("PGDATABASE");
if (!env)
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 Display queries that internal commands generate");
puts( " -f filename Execute queries from file, then exit");
puts( " -F sep Set field separator (default: \"" DEFAULT_FIELD_SEP "\") (-P fieldsep=)");
puts( " -f <filename> Execute queries from file, then exit");
puts( " -F <string> Set field separator (default: \"" DEFAULT_FIELD_SEP "\") (-P fieldsep=)");
/* Display default host */
env = getenv("PGHOST");
printf(" -h host Specify database server host (default: ");
printf(" -h <host> Specify database server host (default: ");
if (env)
fputs(env, stdout);
else
@ -94,11 +100,11 @@ usage(void)
puts( " -H HTML table output mode (-P format=html)");
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 */
env = getenv("PGPORT");
printf(" -p port Specify database server port (default: %s)\n",
printf(" -p <port> Specify database server port (default: %s)\n",
env ? env : "hardwired");
puts( " -P var[=arg] Set printing option 'var' to 'arg' (see \\pset command)");
@ -112,7 +118,7 @@ usage(void)
env = getenv("PGUSER");
if (!env)
env = user;
printf(" -U [username] Specifiy username, \"?\"=prompt (default user: %s)\n", env);
printf(" -U <username> Specifiy username, \"?\"=prompt (default user: %s)\n", env);
puts( " -x Turn on expanded table output (-P expanded)");
puts( " -v name=val Set psql variable 'name' to 'value'");
@ -120,9 +126,9 @@ usage(void)
puts( " -W Prompt for password (should happen automatically)");
puts( "\nFor more information, type \"\\?\" (for internal commands) or \"\\help\"");
puts( "(for SQL commands) from within psql, or consult the psql section in the");
puts( "PostgreSQL manual, which accompanies the distribution and is also available at");
puts( "<http://www.postgresql.org>.");
puts( "(for SQL commands) from within psql, or consult the psql section in");
puts( "the PostgreSQL manual, which accompanies the distribution and is also");
puts( "available at <http://www.postgresql.org>.");
puts( "Report bugs to <bugs@postgresql.org>.");
#ifndef WIN32

View File

@ -1,7 +1,14 @@
/*
* psql - the PostgreSQL interactive terminal
*
* Copyright 2000 by PostgreSQL Global Development Team
*
* $Header: /cvsroot/pgsql/src/bin/psql/help.h,v 1.4 2000/01/18 23:30:23 petere Exp $
*/
#ifndef HELP_H
#define HELP_H
#include "settings.h"
#include <c.h>
void usage(void);
@ -11,5 +18,4 @@ void helpSQL(const char *topic);
void print_copyright(void);
#endif

View File

@ -1,4 +1,10 @@
#include <config.h>
/*
* psql - the PostgreSQL interactive terminal
*
* Copyright 2000 by PostgreSQL Global Development Team
*
* $Header: /cvsroot/pgsql/src/bin/psql/input.c,v 1.7 2000/01/18 23:30:23 petere Exp $
*/
#include <c.h>
#include "input.h"
@ -115,7 +121,7 @@ initializeInput(int flags)
{
useReadline = true;
rl_readline_name = "psql";
initialize_readline(&(pset.db));
initialize_readline();
}
#endif

View File

@ -1,51 +1,47 @@
/*
* psql - the PostgreSQL interactive terminal
*
* Copyright 2000 by PostgreSQL Global Development Team
*
* $Header: /cvsroot/pgsql/src/bin/psql/input.h,v 1.5 2000/01/18 23:30:23 petere Exp $
*/
#ifndef INPUT_H
#define INPUT_H
#include <config.h>
#include <c.h>
#include <stdio.h>
#include "settings.h"
/* If some other file needs to have access to readline/history, include this
/*
* If some other file needs to have access to readline/history, include this
* file and save yourself all this work.
*
* USE_READLINE and USE_HISTORY are the definite pointers regarding existence or not.
*/
#ifdef HAVE_LIBREADLINE
#ifdef HAVE_READLINE_H
#include <readline.h>
#define USE_READLINE 1
#else
#if defined(HAVE_READLINE_READLINE_H)
#include <readline/readline.h>
#define USE_READLINE 1
#endif
#endif
# ifdef HAVE_READLINE_H
# include <readline.h>
# define USE_READLINE 1
# elif defined(HAVE_READLINE_READLINE_H)
# include <readline/readline.h>
# define USE_READLINE 1
# endif
#endif
#if defined(HAVE_LIBHISTORY) || (defined(HAVE_LIBREADLINE) && defined(HAVE_HISTORY_IN_READLINE))
#if defined(HAVE_HISTORY_H)
#include <history.h>
#define USE_HISTORY 1
#else
#if defined(HAVE_READLINE_HISTORY_H)
#include <readline/history.h>
#define USE_HISTORY 1
# ifdef HAVE_HISTORY_H
# include <history.h>
# define USE_HISTORY 1
# elif defined(HAVE_READLINE_HISTORY_H)
# include <readline/history.h>
# define USE_HISTORY 1
# endif
#endif
#endif
#endif
char * gets_interactive(const char *prompt);
char * gets_fromFile(FILE *source);
void initializeInput(int flags);
bool saveHistory(const char *fname);
void finishInput(void);
#endif
#endif /* INPUT_H */

View File

@ -1,3 +1,10 @@
/*
* psql - the PostgreSQL interactive terminal
*
* Copyright 2000 by PostgreSQL Global Development Team
*
* $Header: /cvsroot/pgsql/src/bin/psql/large_obj.c,v 1.6 2000/01/18 23:30:23 petere Exp $
*/
#include <c.h>
#include "large_obj.h"

View File

@ -1,3 +1,10 @@
/*
* psql - the PostgreSQL interactive terminal
*
* Copyright 2000 by PostgreSQL Global Development Team
*
* $Header: /cvsroot/pgsql/src/bin/psql/large_obj.h,v 1.6 2000/01/18 23:30:23 petere Exp $
*/
#ifndef LARGE_OBJ_H
#define LARGE_OBJ_H

View File

@ -1,3 +1,10 @@
/*
* psql - the PostgreSQL interactive terminal
*
* Copyright 2000 by PostgreSQL Global Development Team
*
* $Header: /cvsroot/pgsql/src/bin/psql/mainloop.c,v 1.15 2000/01/18 23:30:23 petere Exp $
*/
#include <c.h>
#include "mainloop.h"
@ -25,7 +32,7 @@
* FIXME: rewrite this whole thing with flex
*/
int
MainLoop(FILE *source, int encoding)
MainLoop(FILE *source)
{
PQExpBuffer query_buf; /* buffer for query being accumulated */
PQExpBuffer previous_buf; /* if there isn't anything in the new buffer
@ -52,6 +59,7 @@ MainLoop(FILE *source, int encoding)
FILE *prev_cmd_source;
bool prev_cmd_interactive;
unsigned int prev_lineno;
bool die_on_error;
@ -68,7 +76,7 @@ MainLoop(FILE *source, int encoding)
previous_buf = createPQExpBuffer();
if (!query_buf || !previous_buf)
{
perror("createPQExpBuffer");
psql_error("out of memory");
exit(EXIT_FAILURE);
}
@ -76,6 +84,8 @@ MainLoop(FILE *source, int encoding)
in_quote = 0;
paren_level = 0;
slashCmdStatus = CMD_UNKNOWN; /* set default */
prev_lineno = pset.lineno;
pset.lineno = 0;
/* main loop to get queries and execute them */
@ -163,7 +173,10 @@ MainLoop(FILE *source, int encoding)
if (getout)
{
putc('\n', stdout); /* just newline */
if (QUIET())
putc('\n', stdout);
else
puts("\\q");
break;
}
else
@ -179,6 +192,8 @@ MainLoop(FILE *source, int encoding)
else
count_eof = 0;
pset.lineno++;
/* strip trailing backslashes, they don't have a clear meaning */
while (1)
{
@ -201,7 +216,7 @@ MainLoop(FILE *source, int encoding)
var = GetVariable(pset.vars, "ECHO");
if (var && strcmp(var, "full")==0)
puts(line);
fflush(stdout);
fflush(stdout);
len = strlen(line);
query_start = 0;
@ -212,10 +227,10 @@ MainLoop(FILE *source, int encoding)
* The current character is at line[i], the prior character at line[i
* - prevlen], the next character at line[i + thislen].
*/
#define ADVANCE_1 (prevlen = thislen, i += thislen, thislen = PQmblen(line+i, encoding))
#define ADVANCE_1 (prevlen = thislen, i += thislen, thislen = PQmblen(line+i, pset.encoding))
success = true;
for (i = 0, prevlen = 0, thislen = (len > 0) ? PQmblen(line, encoding) : 0;
for (i = 0, prevlen = 0, thislen = (len > 0) ? PQmblen(line, pset.encoding) : 0;
i < len;
ADVANCE_1)
{
@ -293,7 +308,7 @@ MainLoop(FILE *source, int encoding)
new = malloc(len + out_length - (1 + in_length) + 1);
if (!new)
{
perror("malloc");
psql_error("out of memory");
exit(EXIT_FAILURE);
}
@ -374,7 +389,7 @@ MainLoop(FILE *source, int encoding)
/* handle backslash command */
slashCmdStatus = HandleSlashCmds(&line[i],
query_buf->len>0 ? query_buf : previous_buf,
&end_of_cmd, encoding);
&end_of_cmd);
success = slashCmdStatus != CMD_ERROR;
@ -456,6 +471,7 @@ MainLoop(FILE *source, int encoding)
pset.cur_cmd_source = prev_cmd_source;
pset.cur_cmd_interactive = prev_cmd_interactive;
pset.lineno = prev_lineno;
return successResult;
} /* MainLoop() */

View File

@ -1,8 +1,15 @@
/*
* psql - the PostgreSQL interactive terminal
*
* Copyright 2000 by PostgreSQL Global Development Team
*
* $Header: /cvsroot/pgsql/src/bin/psql/mainloop.h,v 1.5 2000/01/18 23:30:24 petere Exp $
*/
#ifndef MAINLOOP_H
#define MAINLOOP_H
#include <stdio.h>
int MainLoop(FILE *source, int encoding);
int MainLoop(FILE *source);
#endif /* MAINLOOP_H */

View File

@ -1,4 +1,10 @@
#include <config.h>
/*
* psql - the PostgreSQL interactive terminal
*
* Copyright 2000 by PostgreSQL Global Development Team
*
* $Header: /cvsroot/pgsql/src/bin/psql/print.c,v 1.8 2000/01/18 23:30:24 petere Exp $
*/
#include <c.h>
#include "print.h"
@ -30,19 +36,22 @@
static void
print_unaligned_text(const char *title, const char * const * headers,
const char * const * cells, const char * const * footers,
const char *opt_fieldsep, bool opt_barebones,
const char *opt_fieldsep, const char *opt_recordsep, bool opt_barebones,
FILE *fout)
{
unsigned int col_count = 0;
unsigned int i;
const char * const * ptr;
bool need_recordsep = false;
if (!opt_fieldsep)
opt_fieldsep = "";
if (!opt_recordsep)
opt_recordsep = "";
/* print title */
if (!opt_barebones && title)
fprintf(fout, "%s\n", title);
fprintf(fout, "%s%s", title, opt_recordsep);
/* print headers and count columns */
for (ptr = headers; *ptr; ptr++)
@ -56,17 +65,22 @@ print_unaligned_text(const char *title, const char * const * headers,
}
}
if (!opt_barebones)
fputs("\n", fout);
need_recordsep = true;
/* print cells */
i = 0;
for (ptr = cells; *ptr; ptr++)
{
if (need_recordsep)
{
fputs(opt_recordsep, fout);
need_recordsep = false;
}
fputs(*ptr, fout);
if ((i + 1) % col_count)
fputs(opt_fieldsep, fout);
else
fputs("\n", fout);
need_recordsep = true;
i++;
}
@ -74,8 +88,19 @@ print_unaligned_text(const char *title, const char * const * headers,
if (!opt_barebones && footers)
for (ptr = footers; *ptr; ptr++)
fprintf(fout, "%s\n", *ptr);
{
if (need_recordsep)
{
fputs(opt_recordsep, fout);
need_recordsep = false;
}
fputs(*ptr, fout);
need_recordsep = true;
}
/* the last record needs to be concluded with a newline */
if (need_recordsep)
fputc('\n', fout);
}
@ -83,20 +108,21 @@ print_unaligned_text(const char *title, const char * const * headers,
static void
print_unaligned_vertical(const char *title, const char * const * headers,
const char * const * cells, const char * const * footers,
const char *opt_fieldsep, bool opt_barebones,
const char *opt_fieldsep, const char *opt_recordsep, bool opt_barebones,
FILE *fout)
{
unsigned int col_count = 0;
unsigned int i;
unsigned int record = 1;
const char * const * ptr;
if (!opt_fieldsep)
opt_fieldsep = "";
if (!opt_recordsep)
opt_recordsep = "";
/* print title */
if (!opt_barebones && title)
fprintf(fout, "%s\n", title);
fputs(title, fout);
/* count columns */
for (ptr = headers; *ptr; ptr++)
@ -105,24 +131,30 @@ print_unaligned_vertical(const char *title, const char * const * headers,
/* print records */
for (i = 0, ptr = cells; *ptr; i++, ptr++)
{
if (i % col_count == 0)
{
if (!opt_barebones)
fprintf(fout, "-- RECORD %d\n", record++);
else
fputc('\n', fout);
}
fprintf(fout, "%s%s%s\n", headers[i % col_count], opt_fieldsep, *ptr);
if (i!=0 || (!opt_barebones && title))
{
fputs(opt_recordsep, fout);
if (i % col_count == 0)
fputs(opt_recordsep, fout); /* another one */
}
fputs(headers[i % col_count], fout);
fputs(opt_fieldsep, fout);
fputs(*ptr, fout);
}
/* print footers */
if (!opt_barebones && footers)
if (!opt_barebones && footers && *footers)
{
fputs("--- END ---\n", fout);
fputs(opt_recordsep, fout);
for (ptr = footers; *ptr; ptr++)
fprintf(fout, "%s\n", *ptr);
{
fputs(opt_recordsep, fout);
fputs(*ptr, fout);
}
}
fputc('\n', fout);
}
@ -679,9 +711,9 @@ print_latex_text(const char *title, const char * const * headers,
/* print title */
if (!opt_barebones && title)
{
fputs("\begin{center}\n", fout);
fputs("\\begin{center}\n", fout);
latex_escaped_print(title, fout);
fputs("\n\end{center}\n\n", fout);
fputs("\n\\end{center}\n\n", fout);
}
/* begin environment and set alignments and borders */
@ -776,9 +808,9 @@ print_latex_vertical(const char *title, const char * const * headers,
/* print title */
if (!opt_barebones && title)
{
fputs("\begin{center}\n", fout);
fputs("\\begin{center}\n", fout);
latex_escaped_print(title, fout);
fputs("\n\end{center}\n\n", fout);
fputs("\n\\end{center}\n\n", fout);
}
/* begin environment and set alignments and borders */
@ -936,9 +968,9 @@ printTable(const char *title,
{
case PRINT_UNALIGNED:
if (opt->expanded)
print_unaligned_vertical(title, headers, cells, footers, opt->fieldSep, opt->tuples_only, output);
print_unaligned_vertical(title, headers, cells, footers, opt->fieldSep, opt->recordSep, opt->tuples_only, output);
else
print_unaligned_text(title, headers, cells, footers, opt->fieldSep, opt->tuples_only, output);
print_unaligned_text(title, headers, cells, footers, opt->fieldSep, opt->recordSep, opt->tuples_only, output);
break;
case PRINT_ALIGNED:
if (opt->expanded)

View File

@ -1,3 +1,10 @@
/*
* psql - the PostgreSQL interactive terminal
*
* Copyright 2000 by PostgreSQL Global Development Team
*
* $Header: /cvsroot/pgsql/src/bin/psql/print.h,v 1.5 2000/01/18 23:30:24 petere Exp $
*/
#ifndef PRINT_H
#define PRINT_H
@ -29,6 +36,7 @@ typedef struct _printTableOpt
unsigned short int border; /* Print a border around the table.
* 0=none, 1=dividing lines, 2=full */
char *fieldSep; /* field separator for unaligned text mode */
char *recordSep; /* record separator for unaligned text mode */
char *tableAttr; /* attributes for HTML <table ...> */
} printTableOpt;

View File

@ -1,3 +1,10 @@
/*
* psql - the PostgreSQL interactive terminal
*
* Copyright 2000 by PostgreSQL Global Development Team
*
* $Header: /cvsroot/pgsql/src/bin/psql/prompt.c,v 1.6 2000/01/18 23:30:24 petere Exp $
*/
#include <c.h>
#include "prompt.h"
@ -22,7 +29,7 @@
* get_prompt
*
* Returns a statically allocated prompt made by interpolating certain
* tcsh style escape sequences into pset->vars "PROMPT1|2|3".
* tcsh style escape sequences into pset.vars "PROMPT1|2|3".
* (might not be completely multibyte safe)
*
* Defined interpolations are:
@ -49,7 +56,6 @@
* %$name$ - The value of the psql variable 'name'
* (those will not be rescanned for more escape sequences!)
*
*
* If the application-wide prompts became NULL somehow, the returned string
* will be empty (not NULL!).
*--------------------------

View File

@ -1,7 +1,14 @@
/*
* psql - the PostgreSQL interactive terminal
*
* Copyright 2000 by PostgreSQL Global Development Team
*
* $Header: /cvsroot/pgsql/src/bin/psql/prompt.h,v 1.4 2000/01/18 23:30:24 petere Exp $
*/
#ifndef PROMPT_H
#define PROMPT_H
#include "settings.h"
#include <c.h>
typedef enum _promptStatus
{
@ -13,8 +20,6 @@ typedef enum _promptStatus
PROMPT_COPY
} promptStatus_t;
const char *
get_prompt(promptStatus_t status);
const char *get_prompt(promptStatus_t status);
#endif /* PROMPT_H */

View File

@ -1,6 +1,13 @@
/*
* psql - the PostgreSQL interactive terminal
*
* Copyright 2000 by PostgreSQL Global Development Team
*
* $Header: /cvsroot/pgsql/src/bin/psql/settings.h,v 1.7 2000/01/18 23:30:24 petere Exp $
*/
#ifndef SETTINGS_H
#define SETTINGS_H
#include <config.h>
#include <c.h>
#include <stdio.h>
@ -13,6 +20,7 @@
#include "print.h"
#define DEFAULT_FIELD_SEP "|"
#define DEFAULT_RECORD_SEP "\n"
#define DEFAULT_EDITOR "vi"
#define DEFAULT_PROMPT1 "%/%R%# "
@ -23,6 +31,7 @@
typedef struct _psqlSettings
{
PGconn *db; /* connection to backend */
int encoding;
FILE *queryFout; /* where to send the query results */
bool queryFoutPipe; /* queryFout is from a popen() */
@ -41,9 +50,9 @@ typedef struct _psqlSettings
* loop */
bool cur_cmd_interactive;
bool has_client_encoding; /* was PGCLIENTENCODING set on
* startup? */
char *progname; /* in case you renamed psql */
char *inputfile; /* for error reporting */
unsigned lineno; /* also for error reporting */
} PsqlSettings;
extern PsqlSettings pset;

View File

@ -1,3 +1,10 @@
/*
* psql - the PostgreSQL interactive terminal
*
* Copyright 2000 by PostgreSQL Global Development Team
*
* $Header: /cvsroot/pgsql/src/bin/psql/startup.c,v 1.16 2000/01/18 23:30:24 petere Exp $
*/
#include <c.h>
#include <signal.h>
@ -94,13 +101,15 @@ main(int argc, char **argv)
pset.cur_cmd_source = stdin;
pset.cur_cmd_interactive = false;
pset.encoding = PQenv2encoding();
pset.vars = CreateVariableSpace();
pset.popt.topt.format = PRINT_ALIGNED;
pset.queryFout = stdout;
pset.popt.topt.fieldSep = strdup(DEFAULT_FIELD_SEP);
pset.popt.topt.fieldSep = xstrdup(DEFAULT_FIELD_SEP);
pset.popt.topt.recordSep = xstrdup(DEFAULT_RECORD_SEP);
pset.popt.topt.border = 1;
pset.popt.topt.pager = 1;
pset.popt.topt.pager = true;
SetVariable(pset.vars, "PROMPT1", DEFAULT_PROMPT1);
SetVariable(pset.vars, "PROMPT2", DEFAULT_PROMPT2);
@ -116,10 +125,6 @@ main(int argc, char **argv)
pset.getPassword = false;
#endif
#ifdef MULTIBYTE
pset.has_client_encoding = (getenv("PGCLIENTENCODING") != NULL);
#endif
parse_options(argc, argv, &options);
if (options.action == ACT_LIST_DB)
@ -157,12 +162,19 @@ main(int argc, char **argv)
if (PQstatus(pset.db) == CONNECTION_BAD)
{
fprintf(stderr, "%s: connection to database '%s' failed.\n%s",
pset.progname, PQdb(pset.db), PQerrorMessage(pset.db));
fprintf(stderr, "%s: connection to database \"%s\" failed - %s",
pset.progname, PQdb(pset.db), PQerrorMessage(pset.db));
PQfinish(pset.db);
exit(EXIT_BADCONN);
}
PQsetNoticeProcessor(pset.db, NoticeProcessor, NULL);
/*
* We need to save the encoding because we want to have it
* available even if the database connection goes bad.
*/
pset.encoding = PQclientencoding(pset.db);
if (options.action == ACT_LIST_DB)
{
int success = listAllDbs(false);
@ -190,10 +202,10 @@ main(int argc, char **argv)
/* process file given by -f */
if (options.action == ACT_FILE)
successResult = process_file(options.action_string, PQclientencoding(pset.db)) ? 0 : 1;
successResult = process_file(options.action_string) ? 0 : 1;
/* process slash command if one was given to -c */
else if (options.action == ACT_SINGLE_SLASH)
successResult = HandleSlashCmds(options.action_string, NULL, NULL, PQclientencoding(pset.db)) != 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 */
else if (options.action == ACT_SINGLE_QUERY)
successResult = SendQuery( options.action_string) ? 0 : 1;
@ -202,7 +214,7 @@ main(int argc, char **argv)
{
process_psqlrc();
initializeInput(options.no_readline ? 0 : 1);
successResult = MainLoop(stdin, PQclientencoding(pset.db));
successResult = MainLoop(stdin);
finishInput();
}
@ -234,7 +246,6 @@ parse_options(int argc, char *argv[], struct adhoc_opts * options)
static struct option long_options[] = {
{"no-align", no_argument, NULL, 'A'},
{"command", required_argument, NULL, 'c'},
{"database", required_argument, NULL, 'd'},
{"dbname", required_argument, NULL, 'd'},
{"echo", no_argument, NULL, 'e'},
{"echo-hidden", no_argument, NULL, 'E'},
@ -417,8 +428,16 @@ parse_options(int argc, char *argv[], struct adhoc_opts * options)
pset.getPassword = true;
break;
case '?':
usage();
exit(EXIT_SUCCESS);
if (strcmp(argv[optind-1], "-?")==0)
{
usage();
exit(EXIT_SUCCESS);
}
else
{
fputs("Try -? for help.\n", stderr);
exit(EXIT_FAILURE);
}
break;
#ifndef HAVE_GETOPT_LONG
case '-':
@ -428,7 +447,7 @@ parse_options(int argc, char *argv[], struct adhoc_opts * options)
break;
#endif
default:
usage();
fputs("Try -? for help.\n", stderr);
exit(EXIT_FAILURE);
break;
}
@ -466,20 +485,16 @@ process_psqlrc(void)
{
char *psqlrc;
char *home;
int encoding;
#ifdef WIN32
#define R_OK 0
#endif
/* get client side encoding from envrionment variable if any */
encoding = PQenv2encoding();
/* System-wide startup file */
if (access("/etc/psqlrc-" PG_RELEASE "." PG_VERSION "." PG_SUBVERSION, R_OK) == 0)
process_file("/etc/psqlrc-" PG_RELEASE "." PG_VERSION "." PG_SUBVERSION, encoding);
process_file("/etc/psqlrc-" PG_RELEASE "." PG_VERSION "." PG_SUBVERSION);
else if (access("/etc/psqlrc", R_OK) == 0)
process_file("/etc/psqlrc", encoding);
process_file("/etc/psqlrc");
/* Look for one in the home dir */
home = getenv("HOME");
@ -489,18 +504,18 @@ process_psqlrc(void)
psqlrc = (char *) malloc(strlen(home) + 20);
if (!psqlrc)
{
perror("malloc");
fprintf(stderr, "%s: out of memory\n", pset.progname);
exit(EXIT_FAILURE);
}
sprintf(psqlrc, "%s/.psqlrc-" PG_RELEASE "." PG_VERSION "." PG_SUBVERSION, home);
if (access(psqlrc, R_OK) == 0)
process_file(psqlrc, encoding);
process_file(psqlrc);
else
{
sprintf(psqlrc, "%s/.psqlrc", home);
if (access(psqlrc, R_OK) == 0)
process_file(psqlrc, encoding);
process_file(psqlrc);
}
free(psqlrc);
}

View File

@ -1,4 +1,10 @@
#include <config.h>
/*
* psql - the PostgreSQL interactive terminal
*
* Copyright 2000 by PostgreSQL Global Development Team
*
* $Header: /cvsroot/pgsql/src/bin/psql/stringutils.c,v 1.22 2000/01/18 23:30:24 petere Exp $
*/
#include <c.h>
#include "stringutils.h"

View File

@ -1,3 +1,10 @@
/*
* psql - the PostgreSQL interactive terminal
*
* Copyright 2000 by PostgreSQL Global Development Team
*
* $Header: /cvsroot/pgsql/src/bin/psql/stringutils.h,v 1.12 2000/01/18 23:30:24 petere Exp $
*/
#ifndef STRINGUTILS_H
#define STRINGUTILS_H

View File

@ -1,3 +1,11 @@
/*
* psql - the PostgreSQL interactive terminal
*
* Copyright 2000 by PostgreSQL Global Development Team
*
* $Header: /cvsroot/pgsql/src/bin/psql/tab-complete.c,v 1.7 2000/01/18 23:30:24 petere Exp $
*/
/*-----------
This file implements a somewhat more sophisticated readline "TAB completion"
in psql. It is not intended to be AI, to replace learning SQL, or to relieve
@ -24,7 +32,6 @@
gracefully.
-------------*/
#include <config.h>
#include <c.h>
#include "tab-complete.h"
@ -44,17 +51,11 @@
#include <libpq-fe.h>
#include "common.h"
#include "settings.h"
#define BUF_SIZE 2048
#define ERROR_QUERY_TOO_LONG /* empty */
/* This pointer saves the place where psql stores its own pointer to the
currently active database connection. This is probably a less than ideal way
of passing this around, but this way I only had to make minimal changes to
psql.c. */
static PGconn ** database_connection;
/* Forward declaration of functions */
static char ** psql_completion(char *text, int start, int end);
@ -80,21 +81,10 @@ char * completion_info_charp; /* if you need to pass another string */
static int completion_max_records;
static void * xmalloc(size_t length)
{
void *tmp = malloc(length);
if (!tmp) {
perror("malloc");
exit(EXIT_FAILURE);
}
return tmp;
}
/* Initialize the readline library for our purposes. */
void initialize_readline(PGconn ** conn)
void initialize_readline(void)
{
rl_readline_name = "psql";
rl_readline_name = pset.progname;
rl_attempted_completion_function = psql_completion;
rl_special_prefixes = "()'";
@ -103,8 +93,6 @@ void initialize_readline(PGconn ** conn)
completion_max_records = 100;
/* There is a variable rl_completion_query_items for this but apparently
it's not defined everywhere. */
database_connection = conn;
}
@ -511,7 +499,8 @@ char ** psql_completion(char *text, int start, int end)
COMPLETE_WITH_LIST(sql_commands);
else if (strcmp(prev_wd, "\\pset")==0) {
char * my_list[] = { "format", "border", "expanded", "null", "fieldsep",
"tuples_only", "title", "tableattr", "pager", NULL };
"tuples_only", "title", "tableattr", "pager",
"recordsep", NULL };
COMPLETE_WITH_LIST(my_list);
}
else if( strcmp(prev_wd, "\\e")==0 || strcmp(prev_wd, "\\edit")==0 ||
@ -703,7 +692,7 @@ PGresult * exec_query(char * query)
PGresult * result;
char query_buffer[BUF_SIZE];
if (query == NULL || PQstatus(*database_connection) != CONNECTION_OK)
if (query == NULL || !pset.db || PQstatus(pset.db) != CONNECTION_OK)
return NULL;
#ifdef USE_ASSERT_CHECKING
assert( query[strlen(query)-1] != ';' );
@ -714,12 +703,12 @@ PGresult * exec_query(char * query)
return NULL;
}
result = PQexec(*database_connection, query);
result = PQexec(pset.db, query);
if (result != NULL && PQresultStatus(result) != PGRES_TUPLES_OK) {
#ifdef NOT_USED
fprintf(stderr, "\nThe completion query \"%s\" failed thus: %s\n",
query, PQresStatus(PQresultStatus(result)));
#if 0
psql_error("tab completion: %s failed - %s",
query, PQresStatus(PQresultStatus(result)));
#endif
PQclear(result);
result = NULL;
@ -767,7 +756,16 @@ char * previous_word(int point, int skip) {
}
/* make a copy */
s = (char *)xmalloc(end-start+2);
s = (char *)malloc(end-start+2);
if (!s)
{
psql_error("out of memory\n");
if (!pset.cur_cmd_interactive)
exit(EXIT_FAILURE);
else
return NULL;
}
strncpy(s, &rl_line_buffer[start], end-start+1);
s[end-start+1] = '\0';
@ -776,11 +774,13 @@ char * previous_word(int point, int skip) {
#ifdef NOT_USED
#if 0
/* Surround a string with single quotes. This works for both SQL and
psql internal. Doesn't work so well yet.
*/
/*
* Surround a string with single quotes. This works for both SQL and
* psql internal. Currently disable because it is reported not to
* cooperate with certain versions of readline.
*/
char * quote_file_name(char *text, int match_type, char * quote_pointer)
{
char *s;
@ -789,7 +789,7 @@ char * quote_file_name(char *text, int match_type, char * quote_pointer)
(void)quote_pointer; /* not used */
length = strlen(text) + ( match_type==SINGLE_MATCH ? 3 : 2 );
s = xmalloc(length);
s = malloc(length);
s[0] = '\'';
strcpy(s+1, text);
if (match_type==SINGLE_MATCH)
@ -809,13 +809,13 @@ static char * dequote_file_name(char *text, char quote_char)
return xstrdup(text);
length = strlen(text);
s = xmalloc(length-2+1);
s = malloc(length-2+1);
strncpy(s, text+1, length-2);
s[length] = '\0';
return s;
}
#endif /* NOT_USED */
#endif /* 0 */
#endif /* USE_READLINE */

View File

@ -1,8 +1,13 @@
/*
* psql - the PostgreSQL interactive terminal
*
* Copyright 2000 by PostgreSQL Global Development Team
*
* $Header: /cvsroot/pgsql/src/bin/psql/tab-complete.h,v 1.2 2000/01/18 23:30:24 petere Exp $
*/
#ifndef TAB_COMPLETE_H
#define TAB_COMPLETE_H
#include <libpq-fe.h>
void initialize_readline(PGconn ** conn);
void initialize_readline(void);
#endif

View File

@ -1,4 +1,10 @@
#include <config.h>
/*
* psql - the PostgreSQL interactive terminal
*
* Copyright 2000 by PostgreSQL Global Development Team
*
* $Header: /cvsroot/pgsql/src/bin/psql/variables.c,v 1.4 2000/01/18 23:30:24 petere Exp $
*/
#include <c.h>
#include "variables.h"

View File

@ -1,4 +1,13 @@
/* This implements a sort of variable repository. One could also think of it
/*
* psql - the PostgreSQL interactive terminal
*
* Copyright 2000 by PostgreSQL Global Development Team
*
* $Header: /cvsroot/pgsql/src/bin/psql/variables.h,v 1.4 2000/01/18 23:30:24 petere Exp $
*/
/*
* This implements a sort of variable repository. One could also think of it
* as cheap version of an associative array. In each one of these
* datastructures you can store name/value pairs.
*