diff options
author | Peter Eisentraut <peter_e@gmx.net> | 2000-01-29 16:58:54 +0000 |
---|---|---|
committer | Peter Eisentraut <peter_e@gmx.net> | 2000-01-29 16:58:54 +0000 |
commit | 2b84cbb60f6ff6cb58d42dff026aaf0b2e9ca8ab (patch) | |
tree | dcd592dcfdebbc799bd225ac8bf50c0dfe1e61eb /src | |
parent | 7e7416bd4e221fd95701a048eaf2893ab379d9a5 (diff) | |
download | postgresql-2b84cbb60f6ff6cb58d42dff026aaf0b2e9ca8ab.tar.gz postgresql-2b84cbb60f6ff6cb58d42dff026aaf0b2e9ca8ab.zip |
A few minor psql enhancements
Initdb help correction
Changed end/abort to commit/rollback and changed related notices
Commented out way old printing functions in libpq
Fixed a typo in alter table / alter column
Diffstat (limited to 'src')
40 files changed, 722 insertions, 678 deletions
diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index 83be1643899..58e17445586 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.59 2000/01/26 05:56:04 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.60 2000/01/29 16:58:29 petere Exp $ * * NOTES * Transaction aborts can now occur two ways: @@ -1331,7 +1331,7 @@ BeginTransactionBlock(void) return; if (s->blockState != TBLOCK_DEFAULT) - elog(NOTICE, "BeginTransactionBlock and not in default state "); + elog(NOTICE, "BEGIN: already a transaction in progress"); /* ---------------- * set the current transaction block state information @@ -1404,7 +1404,7 @@ EndTransactionBlock(void) * default state. * ---------------- */ - elog(NOTICE, "EndTransactionBlock and not inprogress/abort state "); + elog(NOTICE, "COMMIT: no transaction in progress"); s->blockState = TBLOCK_ENDABORT; } @@ -1516,13 +1516,13 @@ UserAbortTransactionBlock() /* ---------------- * this case should not be possible, because it would mean - * the user entered an "abort" from outside a transaction block. + * the user entered a "rollback" from outside a transaction block. * So we print an error message, abort the transaction and * enter the "ENDABORT" state so we will end up in the default * state after the upcoming CommitTransactionCommand(). * ---------------- */ - elog(NOTICE, "UserAbortTransactionBlock and not in in-progress state"); + elog(NOTICE, "ROLLBACK: no transaction in progress"); AbortTransaction(); s->blockState = TBLOCK_ENDABORT; } diff --git a/src/backend/commands/command.c b/src/backend/commands/command.c index 745eae08322..ef6b66d9c33 100644 --- a/src/backend/commands/command.c +++ b/src/backend/commands/command.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.66 2000/01/26 05:56:13 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.67 2000/01/29 16:58:34 petere Exp $ * * NOTES * The PortalExecutorHeapMemory crap needs to be eliminated @@ -301,7 +301,6 @@ AlterTableAddColumn(const char *relationName, Relation idescs[Num_pg_attr_indices]; Relation ridescs[Num_pg_class_indices]; bool hasindex; -// List *rawDefaults = NIL; /* * permissions checking. this would normally be done in utility.c, @@ -386,9 +385,9 @@ AlterTableAddColumn(const char *relationName, /* * XXX is the following check sufficient? */ - if (((Form_pg_class) GETSTRUCT(reltup))->relkind == RELKIND_INDEX) + if (((Form_pg_class) GETSTRUCT(reltup))->relkind != RELKIND_RELATION) { - elog(ERROR, "ALTER TABLE: index relation \"%s\" not changed", + elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table", relationName); } @@ -429,7 +428,7 @@ AlterTableAddColumn(const char *relationName, 0, 0); if (HeapTupleIsValid(tup)) - elog(ERROR, "ALTER TABLE: column name \"%s\" already exists in relation \"%s\"", + elog(ERROR, "ALTER TABLE: column name \"%s\" already exists in table \"%s\"", colDef->colname, relationName); /* @@ -627,14 +626,12 @@ AlterTableAlterColumn(const char *relationName, /* keep the system catalog indices current */ CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, irelations); CatalogIndexInsert(irelations, Num_pg_attr_indices, attr_rel, newtuple); - CatalogCloseIndices(Num_pg_attrdef_indices, irelations); + CatalogCloseIndices(Num_pg_attr_indices, irelations); /* get rid of actual default definition */ drop_default(myrelid, attnum); } - else - elog(NOTICE, "ALTER TABLE: there was no default on column \"%s\" of relation \"%s\"", - colName, relationName); + heap_endscan(scan); heap_close(attr_rel, NoLock); } diff --git a/src/backend/commands/creatinh.c b/src/backend/commands/creatinh.c index a90019974ef..da0fcd479ed 100644 --- a/src/backend/commands/creatinh.c +++ b/src/backend/commands/creatinh.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.55 2000/01/26 05:56:13 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.56 2000/01/29 16:58:34 petere Exp $ * *------------------------------------------------------------------------- */ @@ -31,8 +31,8 @@ * ---------------- */ -static int checkAttrExists(char *attributeName, - char *attributeType, List *schema); +static bool checkAttrExists(const char *attributeName, + const char *attributeType, List *schema); static List *MergeAttributes(List *schema, List *supers, List **supconstr); static void StoreCatalogInheritance(Oid relationId, List *supers); @@ -291,7 +291,7 @@ MergeAttributes(List *schema, List *supers, List **supconstr) if (!strcmp(coldef->colname, restdef->colname)) { - elog(ERROR, "attribute '%s' duplicated", + elog(ERROR, "CREATE TABLE: attribute \"%s\" duplicated", coldef->colname); } } @@ -304,7 +304,7 @@ MergeAttributes(List *schema, List *supers, List **supconstr) { if (!strcmp(strVal(lfirst(entry)), strVal(lfirst(rest)))) { - elog(ERROR, "relation '%s' duplicated", + elog(ERROR, "CREATE TABLE: inherited relation \"%s\" duplicated", strVal(lfirst(entry))); } } @@ -326,9 +326,8 @@ MergeAttributes(List *schema, List *supers, List **supconstr) tupleDesc = RelationGetDescr(relation); constr = tupleDesc->constr; - /* XXX shouldn't this test be stricter? No indexes, for example? */ - if (relation->rd_rel->relkind == 'S') - elog(ERROR, "MergeAttr: Can't inherit from sequence superclass '%s'", name); + if (relation->rd_rel->relkind != RELKIND_RELATION) + elog(ERROR, "CREATE TABLE: inherited relation \"%s\" is not a table", name); for (attrno = relation->rd_rel->relnatts - 1; attrno >= 0; attrno--) { @@ -353,15 +352,15 @@ MergeAttributes(List *schema, List *supers, List **supconstr) * check validity * */ - if (checkAttrExists(attributeName, attributeType, inhSchema) || - checkAttrExists(attributeName, attributeType, schema)) - { + if (checkAttrExists(attributeName, attributeType, schema)) + elog(ERROR, "CREATE TABLE: attribute \"%s\" already exists in inherited schema", + attributeName); + if (checkAttrExists(attributeName, attributeType, inhSchema)) /* * this entry already exists */ continue; - } /* * add an entry to the schema @@ -629,11 +628,13 @@ again: heap_close(relation, RowExclusiveLock); } + + /* - * returns 1 if attribute already exists in schema, 0 otherwise. + * returns true if attribute already exists in schema, false otherwise. */ -static int -checkAttrExists(char *attributeName, char *attributeType, List *schema) +static bool +checkAttrExists(const char *attributeName, const char *attributeType, List *schema) { List *s; @@ -641,19 +642,16 @@ checkAttrExists(char *attributeName, char *attributeType, List *schema) { ColumnDef *def = lfirst(s); - if (!strcmp(attributeName, def->colname)) + if (strcmp(attributeName, def->colname)==0) { - /* * attribute exists. Make sure the types are the same. */ if (strcmp(attributeType, def->typename->name) != 0) - { - elog(ERROR, "%s and %s conflict for %s", - attributeType, def->typename->name, attributeName); - } - return 1; + elog(ERROR, "CREATE TABLE: attribute \"%s\" type conflict (%s and %s)", + attributeName, attributeType, def->typename->name); + return true; } } - return 0; + return false; } diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 228cb73f3af..4059e50f991 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.136 2000/01/27 18:11:35 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.137 2000/01/29 16:58:37 petere Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -832,14 +832,14 @@ AlterTableStmt: $$ = (Node *)n; } /* ALTER TABLE <name> DROP [COLUMN] <name> {RESTRICT|CASCADE} */ - | ALTER TABLE relation_name opt_inh_star DROP opt_column ColId /* drop_behavior */ + | ALTER TABLE relation_name opt_inh_star DROP opt_column ColId drop_behavior { AlterTableStmt *n = makeNode(AlterTableStmt); n->subtype = 'D'; n->relname = $3; n->inh = $4; n->name = $7; - /* n->behavior = $8; */ + n->behavior = $8; $$ = (Node *)n; } /* ALTER TABLE <name> ADD CONSTRAINT ... */ @@ -856,7 +856,7 @@ AlterTableStmt: | ALTER TABLE relation_name opt_inh_star DROP CONSTRAINT name drop_behavior { AlterTableStmt *n = makeNode(AlterTableStmt); - n->subtype = 'X'; + n->subtype = 'X'; n->relname = $3; n->inh = $4; n->name = $7; @@ -866,7 +866,8 @@ AlterTableStmt: ; alter_column_action: - SET DEFAULT a_expr_or_null { $$ = $3; } + SET DEFAULT a_expr { $$ = $3; } + | SET DEFAULT NULL_P { $$ = NULL; } | DROP DEFAULT { $$ = NULL; } ; @@ -2531,19 +2532,15 @@ UnlistenStmt: UNLISTEN relation_name * * Transactions: * - * abort transaction - * (ABORT) - * begin transaction - * (BEGIN) - * end transaction - * (END) + * BEGIN / COMMIT / ROLLBACK + * (also older versions END / ABORT) * *****************************************************************************/ TransactionStmt: ABORT_TRANS opt_trans { TransactionStmt *n = makeNode(TransactionStmt); - n->command = ABORT_TRANS; + n->command = ROLLBACK; $$ = (Node *)n; } | BEGIN_TRANS opt_trans @@ -2555,19 +2552,19 @@ TransactionStmt: ABORT_TRANS opt_trans | COMMIT opt_trans { TransactionStmt *n = makeNode(TransactionStmt); - n->command = END_TRANS; + n->command = COMMIT; $$ = (Node *)n; } | END_TRANS opt_trans { TransactionStmt *n = makeNode(TransactionStmt); - n->command = END_TRANS; + n->command = COMMIT; $$ = (Node *)n; } | ROLLBACK opt_trans { TransactionStmt *n = makeNode(TransactionStmt); - n->command = ABORT_TRANS; + n->command = ROLLBACK; $$ = (Node *)n; } ; diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 59497b96a0d..66acb230f2e 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.81 2000/01/26 05:57:07 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.82 2000/01/29 16:58:38 petere Exp $ * *------------------------------------------------------------------------- */ @@ -57,8 +57,8 @@ if (1) \ { \ if (IsAbortedTransactionBlockState()) \ { \ - elog(NOTICE, "(transaction aborted): %s", \ - "all queries ignored until end of transaction block"); \ + elog(NOTICE, "current transaction is aborted, " \ + "queries ignored until end of transaction block"); \ commandTag = "*ABORT STATE*"; \ break; \ } \ @@ -98,13 +98,13 @@ ProcessUtility(Node *parsetree, BeginTransactionBlock(); break; - case END_TRANS: - PS_SET_STATUS(commandTag = "END"); + case COMMIT: + PS_SET_STATUS(commandTag = "COMMIT"); EndTransactionBlock(); break; - case ABORT_TRANS: - PS_SET_STATUS(commandTag = "ABORT"); + case ROLLBACK: + PS_SET_STATUS(commandTag = "ROLLBACK"); UserAbortTransactionBlock(); break; } @@ -278,17 +278,16 @@ ProcessUtility(Node *parsetree, { RenameStmt *stmt = (RenameStmt *) parsetree; - PS_SET_STATUS(commandTag = "RENAME"); + PS_SET_STATUS(commandTag = "ALTER"); CHECK_IF_ABORTED(); relname = stmt->relname; if (!allowSystemTableMods && IsSystemRelationName(relname)) - elog(ERROR, "class \"%s\" is a system catalog", + elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog", relname); #ifndef NO_SECURITY if (!pg_ownercheck(userName, relname, RELNAME)) - elog(ERROR, "you do not own class \"%s\"", - relname); + elog(ERROR, "permission denied"); #endif /* ---------------- @@ -335,7 +334,7 @@ ProcessUtility(Node *parsetree, { AlterTableStmt *stmt = (AlterTableStmt *) parsetree; - PS_SET_STATUS(commandTag = "ALTER TABLE"); + PS_SET_STATUS(commandTag = "ALTER"); CHECK_IF_ABORTED(); /* diff --git a/src/bin/initdb/initdb.sh b/src/bin/initdb/initdb.sh index 52a66507e8c..cf54d1925a3 100644 --- a/src/bin/initdb/initdb.sh +++ b/src/bin/initdb/initdb.sh @@ -26,7 +26,7 @@ # # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.82 2000/01/20 21:51:05 petere Exp $ +# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.83 2000/01/29 16:58:42 petere Exp $ # #------------------------------------------------------------------------- @@ -204,6 +204,11 @@ do -E*) MULTIBYTE=`echo $1 | sed 's/^-E//'` ;; + -*) + echo "$CMDNAME: invalid option: $1" + echo "Try -? for help." + exit 1 + ;; *) PGDATA=$1 ;; @@ -218,15 +223,15 @@ if [ "$usage" ]; then echo " $CMDNAME [options] datadir" echo echo "Options:" - echo " [-D, --pgdata] <datadir> Location for this database" + echo " [-D, --pgdata] <datadir> Location for this database" echo " -W, --pwprompt Prompt for a password for the new superuser's" if [ -n "$MULTIBYTE" ] then - echo " -e, --encoding <encoding> Set the default multibyte encoding for new databases" + echo " -E, --encoding <encoding> Set the default multibyte encoding for new databases" fi echo " -i, --sysid <sysid> Database sysid for the superuser" echo "Less commonly used options: " - echo " -L, --pglib <libdir> Where to find the input files (should happend automatically" + echo " -L, --pglib <libdir> Where to find the input files" echo " -t, --template Re-initialize template database only" echo " -d, --debug Generate lots of debugging output" echo " -n, --noclean Do not clean up after errors" diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index da5629f8501..2cb012a99da 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -22,7 +22,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.140 2000/01/27 05:33:49 momjian Exp $ + * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.141 2000/01/29 16:58:44 petere Exp $ * * Modifications - 6/10/96 - dave@bensoft.com - version 1.13.dhb * @@ -178,7 +178,7 @@ version(void) puts("pg_dump (PostgreSQL) " PG_RELEASE "." PG_VERSION "." PG_SUBVERSION); puts("Portions Copyright (c) 1996-2000, PostgreSQL, Inc"); puts("Portions Copyright (C) 1996 Regents of the University of California"); - puts("Read the file COPYING to see the usage and distribution terms."); + puts("Read the file COPYRIGHT to see the usage and distribution terms."); } @@ -685,7 +685,7 @@ main(int argc, char **argv) case '?': /* getopt returns '?' on unknown argument. That's not quite what we want */ - if (strcmp(argv[optind-1], "-?")==0) + if (strcmp(argv[optind-1], "-?")==0 || strcmp(argv[optind-1], "--help")==0) { help(progname); exit(1); diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index a12d311b2e0..1441fbc0bcc 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -1,9 +1,9 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright 2000 by PostgreSQL Global Development Team + * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/command.c,v 1.15 2000/01/23 01:27:37 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/command.c,v 1.16 2000/01/29 16:58:48 petere Exp $ */ #include <c.h> #include "command.h" @@ -361,7 +361,7 @@ exec_command(const char *cmd, switch (cmd[1]) { case '\0': - case '?': + case '+': if (options[0]) success = describeTableDetails(options[0], show_verbose); else @@ -992,12 +992,42 @@ do_connect(const char *new_dbname, const char *new_user) SetVariable(pset.vars, "HOST", PQhost(pset.db)); SetVariable(pset.vars, "PORT", PQport(pset.db)); + pset.issuper = test_superuser(PQuser(pset.db)); + return success; } /* + * Test if the given user is a database superuser. + * (Used to set up the prompt right.) + */ +bool +test_superuser(const char * username) +{ + PGresult *res; + char buf[64 + NAMEDATALEN]; + bool answer; + + if (!username) + return false; + + sprintf(buf, "SELECT usesuper FROM pg_user WHERE usename = '%.*s'", NAMEDATALEN, username); + res = PSQLexec(buf); + + answer = + (PQntuples(res)>0 && PQnfields(res)>0 + && !PQgetisnull(res,0,0) + && PQgetvalue(res,0,0) + && strcmp(PQgetvalue(res,0,0), "t")==0); + PQclear(res); + return answer; +} + + + +/* * do_edit -- handler for \e * * If you do not specify a filename, the current query buffer will be copied diff --git a/src/bin/psql/command.h b/src/bin/psql/command.h index f3a7b4d36a4..65431e9c9ec 100644 --- a/src/bin/psql/command.h +++ b/src/bin/psql/command.h @@ -1,9 +1,9 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright 2000 by PostgreSQL Global Development Team + * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/command.h,v 1.6 2000/01/18 23:30:23 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/command.h,v 1.7 2000/01/29 16:58:48 petere Exp $ */ #ifndef COMMAND_H #define COMMAND_H @@ -37,6 +37,9 @@ bool process_file(char *filename); bool +test_superuser(const char * username); + +bool do_pset(const char *param, const char *value, printQueryOpt * popt, diff --git a/src/bin/psql/common.c b/src/bin/psql/common.c index c5a2e78af7d..700542cd4d1 100644 --- a/src/bin/psql/common.c +++ b/src/bin/psql/common.c @@ -1,9 +1,9 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright 2000 by PostgreSQL Global Development Team + * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/common.c,v 1.10 2000/01/19 20:08:33 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/common.c,v 1.11 2000/01/29 16:58:48 petere Exp $ */ #include <c.h> #include "common.h" diff --git a/src/bin/psql/common.h b/src/bin/psql/common.h index 08519f5a400..b4b7d93abe9 100644 --- a/src/bin/psql/common.h +++ b/src/bin/psql/common.h @@ -1,9 +1,9 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright 2000 by PostgreSQL Global Development Team + * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/common.h,v 1.4 2000/01/18 23:30:23 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/common.h,v 1.5 2000/01/29 16:58:48 petere Exp $ */ #ifndef COMMON_H #define COMMON_H diff --git a/src/bin/psql/copy.c b/src/bin/psql/copy.c index d3a5f79b5c0..d2d638c0664 100644 --- a/src/bin/psql/copy.c +++ b/src/bin/psql/copy.c @@ -1,9 +1,9 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright 2000 by PostgreSQL Global Development Team + * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/copy.c,v 1.8 2000/01/21 04:21:12 tgl Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/copy.c,v 1.9 2000/01/29 16:58:48 petere Exp $ */ #include <c.h> #include "copy.h" diff --git a/src/bin/psql/copy.h b/src/bin/psql/copy.h index 4710a623eb7..8a57e7a66d3 100644 --- a/src/bin/psql/copy.h +++ b/src/bin/psql/copy.h @@ -1,9 +1,9 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright 2000 by PostgreSQL Global Development Team + * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/copy.h,v 1.5 2000/01/18 23:30:23 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/copy.h,v 1.6 2000/01/29 16:58:48 petere Exp $ */ #ifndef COPY_H #define COPY_H diff --git a/src/bin/psql/create_help.pl b/src/bin/psql/create_help.pl index c5b0d868065..f802d5ed791 100644 --- a/src/bin/psql/create_help.pl +++ b/src/bin/psql/create_help.pl @@ -1,18 +1,22 @@ -#!/usr/bin/perl +#! /usr/bin/perl +################################################################# +# create_help.pl -- converts SGML docs to internal psql help # -# This script automatically generates the help on SQL in psql from the -# SGML docs. So far the format of the docs was consistent enough that -# this worked, but this here is my no means an SGML parser. +# Copyright 2000 by PostgreSQL Global Development Group # -# It might be a good idea that this is just done once before distribution -# so people that don't have the docs or have slightly messed up docs or -# don't have perl, etc. won't have to bother. +# $Header: /cvsroot/pgsql/src/bin/psql/create_help.pl,v 1.3 2000/01/29 16:58:48 petere Exp $ +################################################################# + +# +# This script automatically generates the help on SQL in psql from +# the SGML docs. So far the format of the docs was consistent +# enough that this worked, but this here is my no means an SGML +# parser. # # Call: perl create_help.pl sql_help.h -# (Do not rely on this script to be executable.) -# The name of the header file doesn't matter to this script, but it sure -# does matter to the rest of the source. +# The name of the header file doesn't matter to this script, but it +# sure does matter to the rest of the source. # # A rule for this is also in the psql makefile. # @@ -29,9 +33,15 @@ open OUT, ">$outputfile" or die "Couldn't open output file '$outputfile': $!\n"; print OUT "/* - * This file is automatically generated from the SGML documentation. - * Direct changes here will be overwritten. + * *** Do not change this file directly. Changes will be overwritten. *** + * + * This file was generated by + * $^X $0 $outputfile + * from the DocBook documentation in + * $docdir + * */ + #ifndef $define #define $define @@ -76,7 +86,7 @@ foreach $file (sort readdir DIR) { print OUT " { \"$cmdname\",\n \"$cmddesc\",\n \"$cmdsynopsis\" },\n\n"; } else { - print STDERR "Couldn't parse file '$file'. (N='$cmdname' D='$cmddesc')\n"; + print STDERR "$0: parsing file '$file' failed at or near line $. (N='$cmdname' D='$cmddesc')\n"; } } diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c index ca5dcaafb30..bb259b31d37 100644 --- a/src/bin/psql/describe.c +++ b/src/bin/psql/describe.c @@ -1,9 +1,9 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright 2000 by PostgreSQL Global Development Team + * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/describe.c,v 1.14 2000/01/20 15:29:20 momjian Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/describe.c,v 1.15 2000/01/29 16:58:48 petere Exp $ */ #include <c.h> #include "describe.h" @@ -504,7 +504,7 @@ xmalloc(size_t size) tmp = malloc(size); if (!tmp) { - perror("malloc"); + psql_error("out of memory"); exit(EXIT_FAILURE); } return tmp; @@ -530,20 +530,20 @@ describeTableDetails(const char *name, bool desc) /* truncate table name */ if (strlen(name) > NAMEDATALEN) { - char *my_name = xmalloc(NAMEDATALEN+1); - strncpy(my_name, name, NAMEDATALEN); - my_name[NAMEDATALEN] = '\0'; - name = my_name; + char *my_name = xmalloc(NAMEDATALEN+1); + strncpy(my_name, name, NAMEDATALEN); + my_name[NAMEDATALEN] = '\0'; + name = my_name; } /* Get general table info */ sprintf(buf, - "SELECT relhasindex, relkind, relchecks, reltriggers, relhasrules\n" - "FROM pg_class WHERE relname='%s'", - name); + "SELECT relhasindex, relkind, relchecks, reltriggers, relhasrules\n" + "FROM pg_class WHERE relname='%s'", + name); res = PSQLexec(buf); if (!res) - return false; + return false; /* Did we get anything? */ if (PQntuples(res) == 0) @@ -567,15 +567,15 @@ describeTableDetails(const char *name, bool desc) headers[1] = "Type"; cols = 2; - if (tableinfo.relkind == 'r' || tableinfo.relkind == 's') + if (tableinfo.relkind == 'r') { - cols++; - headers[cols-1] = "Extra"; + cols++; + headers[cols-1] = "Modifier"; } if (desc) { - cols++; + cols++; headers[cols-1] = "Description"; } @@ -598,19 +598,19 @@ describeTableDetails(const char *name, bool desc) /* Check if table is a view */ if (tableinfo.hasrules) { - PGresult *result; - sprintf(buf, "SELECT definition FROM pg_views WHERE viewname = '%s'", name); - result = PSQLexec(buf); - if (!result) - { - PQclear(res); - PQclear(result); - return false; - } - - if (PQntuples(result) > 0) - view_def = xstrdup(PQgetvalue(result, 0, 0)); - PQclear(result); + PGresult *result; + sprintf(buf, "SELECT definition FROM pg_views WHERE viewname = '%s'", name); + result = PSQLexec(buf); + if (!result) + { + PQclear(res); + PQclear(result); + return false; + } + + if (PQntuples(result) > 0) + view_def = xstrdup(PQgetvalue(result, 0, 0)); + PQclear(result); } @@ -621,115 +621,137 @@ describeTableDetails(const char *name, bool desc) for (i = 0; i < PQntuples(res); i++) { int4 attypmod = atoi(PQgetvalue(res, i, 3)); - const char *attype = PQgetvalue(res, i, 1); + const char *attype = PQgetvalue(res, i, 1); + const char *typename; + bool isarray = false; /* Name */ cells[i * cols + 0] = (char *)PQgetvalue(res, i, 0); /* don't free this afterwards */ /* Type */ - /* (convert some internal type names to "readable") */ + if (attype[0] == '_') + { + isarray = true; + attype++; + } + /* (convert some internal type names to SQL'ish) */ + if (strcmp(attype, "bpchar")==0) + typename = "char"; + else if (strcmp(attype, "int2")==0) + typename = "smallint"; + else if (strcmp(attype, "int4")==0) + typename = "integer"; + else if (strcmp(attype, "int8")==0) + typename = "bigint"; + else if (strcmp(attype, "bool")==0) + typename = "boolean"; + else + typename = attype; + /* more might need to be added when date/time types are sorted out */ + cells[i * cols + 1] = xmalloc(NAMEDATALEN + 16); - if (strcmp(attype, "bpchar") == 0) - sprintf(cells[i * cols + 1], "char(%d)", attypmod != -1 ? attypmod - VARHDRSZ : 0); - else if (strcmp(attype, "varchar") == 0) - sprintf(cells[i * cols + 1], "varchar(%d)", attypmod != -1 ? attypmod - VARHDRSZ : 0); - else if (strcmp(attype, "numeric") == 0) + if (strcmp(typename, "char") == 0) + sprintf(cells[i * cols + 1], "char(%d)", attypmod != -1 ? attypmod - VARHDRSZ : 1); + else if (strcmp(typename, "varchar") == 0) + sprintf(cells[i * cols + 1], "varchar(%d)", attypmod != -1 ? attypmod - VARHDRSZ : 1); + else if (strcmp(typename, "numeric") == 0) sprintf(cells[i * cols + 1], "numeric(%d,%d)", ((attypmod - VARHDRSZ) >> 16) & 0xffff, (attypmod - VARHDRSZ) & 0xffff); - else if (attype[0] == '_') - sprintf(cells[i * cols + 1], "%s[]", attype + 1); else - strcpy(cells[i * cols + 1], attype); + strcpy(cells[i * cols + 1], typename); + + if (isarray) + strcat(cells[i * cols + 1], "[]"); /* Extra: not null and default */ /* (I'm cutting off the 'default' string at 128) */ - if (tableinfo.relkind == 'r' || tableinfo.relkind == 's') - { - cells[i * cols + 2] = xmalloc(128 + 128); - cells[i * cols + 2][0] = '\0'; - if (strcmp(PQgetvalue(res, i, 4), "t") == 0) - strcat(cells[i * cols + 2], "not null"); - - /* handle "default" here */ - if (strcmp(PQgetvalue(res, i, 5), "t") == 0) - { - PGresult *result; - - sprintf(buf, "SELECT substring(d.adsrc for 128) FROM pg_attrdef d, pg_class c\n" - "WHERE c.relname = '%s' AND c.oid = d.adrelid AND d.adnum = %s", - name, PQgetvalue(res, i, 6)); - - result = PSQLexec(buf); - if (!result) - error = true; - else - { - if (cells[i * cols + 2][0]) - strcat(cells[i * cols + 2], " "); - strcat(cells[i * cols + 2], "default "); - strcat(cells[i * cols + 2], PQgetvalue(result, 0, 0)); - PQclear(result); - } - } - } - - if (error) - break; - + if (tableinfo.relkind == 'r') + { + cells[i * cols + 2] = xmalloc(128 + 128); + cells[i * cols + 2][0] = '\0'; + if (strcmp(PQgetvalue(res, i, 4), "t") == 0) + strcat(cells[i * cols + 2], "not null"); + + /* handle "default" here */ + if (strcmp(PQgetvalue(res, i, 5), "t") == 0) + { + PGresult *result; + + sprintf(buf, "SELECT substring(d.adsrc for 128) FROM pg_attrdef d, pg_class c\n" + "WHERE c.relname = '%s' AND c.oid = d.adrelid AND d.adnum = %s", + name, PQgetvalue(res, i, 6)); + + result = PSQLexec(buf); + if (!result) + error = true; + else + { + if (cells[i * cols + 2][0]) + strcat(cells[i * cols + 2], " "); + strcat(cells[i * cols + 2], "default "); + strcat(cells[i * cols + 2], PQgetvalue(result, 0, 0)); + PQclear(result); + } + } + } + + if (error) + break; + /* Description */ if (desc) cells[i * cols + cols-1] = (char*)PQgetvalue(res, i, 7); } /* Make title */ - title = xmalloc(20 + strlen(name)); + title = xmalloc(22 + strlen(name)); switch (tableinfo.relkind) { - case 'r': - if (view_def) - sprintf(title, "View \"%s\"", name); - else - sprintf(title, "Table \"%s\"", name); - break; - case 'S': - sprintf(title, "Sequence \"%s\"", name); - break; - case 'i': - sprintf(title, "Index \"%s\"", name); - break; - case 's': - sprintf(title, "System table \"%s\"", name); - break; - default: - sprintf(title, "?%c?", tableinfo.relkind); + case 'r': + if (view_def) + sprintf(title, "View \"%s\"", name); + else + sprintf(title, "Table \"%s\"", name); + break; + case 'S': + sprintf(title, "Sequence \"%s\"", name); + break; + case 'i': + sprintf(title, "Index \"%s\"", name); + break; + case 's': + sprintf(title, "Special relation \"%s\"", name); + break; + default: + sprintf(title, "?%c?", tableinfo.relkind); } /* Make footers */ /* Information about the index */ if (tableinfo.relkind == 'i') { - PGresult * result; - - sprintf(buf, "SELECT i.indisunique, i.indisprimary, a.amname\n" - "FROM pg_index i, pg_class c, pg_am a\n" - "WHERE i.indexrelid = c.oid AND c.relname = '%s' AND c.relam = a.oid", - name); - - result = PSQLexec(buf); - if (!result) - error = true; - else - { - footers = xmalloc(2 * sizeof(*footers)); - footers[0] = xmalloc(NAMEDATALEN + 32); - sprintf(footers[0], "%s%s", - strcmp(PQgetvalue(result, 0, 0), "t")==0 ? "unique " : "", - PQgetvalue(result, 0, 2) - ); - if (strcmp(PQgetvalue(result, 0, 1), "t")==0) - strcat(footers[0], " (primary key)"); - footers[1] = NULL; - } + PGresult * result; + + sprintf(buf, "SELECT i.indisunique, i.indisprimary, a.amname\n" + "FROM pg_index i, pg_class c, pg_am a\n" + "WHERE i.indexrelid = c.oid AND c.relname = '%s' AND c.relam = a.oid", + name); + + result = PSQLexec(buf); + if (!result) + error = true; + else + { + footers = xmalloc(2 * sizeof(*footers)); + footers[0] = xmalloc(NAMEDATALEN + 32); + sprintf(footers[0], "%s%s", + strcmp(PQgetvalue(result, 0, 0), "t")==0 ? "unique " : "", + PQgetvalue(result, 0, 2) + ); + if (strcmp(PQgetvalue(result, 0, 1), "t")==0) + strcat(footers[0], " (primary key)"); + footers[1] = NULL; + } } /* Information about the view */ else if (tableinfo.relkind == 'r' && view_def) @@ -743,131 +765,134 @@ describeTableDetails(const char *name, bool desc) /* Information about the table */ else if (tableinfo.relkind == 'r') { - PGresult *result1=NULL, *result2=NULL, *result3=NULL, *result4=NULL; - int index_count=0, constr_count=0, rule_count=0, trigger_count=0; - int count_footers=0; + PGresult *result1=NULL, *result2=NULL, *result3=NULL, *result4=NULL; + int index_count=0, constr_count=0, rule_count=0, trigger_count=0; + int count_footers=0; /* count indices */ - if (!error && tableinfo.hasindex) - { - sprintf(buf, "SELECT c2.relname\n" - "FROM pg_class c, pg_class c2, pg_index i\n" - "WHERE c.relname = '%s' AND c.oid = i.indrelid AND i.indexrelid = c2.oid\n" - "ORDER BY c2.relname", - name); - result1 = PSQLexec(buf); - if (!result1) - error = true; - else - index_count = PQntuples(result1); - } - - /* count table (and column) constraints */ - if (!error && tableinfo.checks) - { - sprintf(buf, "SELECT rcsrc\n" - "FROM pg_relcheck r, pg_class c\n" - "WHERE c.relname='%s' AND c.oid = r.rcrelid", - name); - result2 = PSQLexec(buf); - if (!result2) - error = true; - else - constr_count = PQntuples(result2); - } - - /* count rules */ - if (!error && tableinfo.hasrules) - { - sprintf(buf, - "SELECT r.rulename\n" - "FROM pg_rewrite r, pg_class c\n" - "WHERE c.relname='%s' AND c.oid = r.ev_class", - name); - result3 = PSQLexec(buf); - if (!result3) - error = true; - else - rule_count = PQntuples(result3); - } - - /* count triggers */ - if (!error && tableinfo.hasrules) - { - sprintf(buf, - "SELECT t.tgname\n" - "FROM pg_trigger t, pg_class c\n" - "WHERE c.relname='%s' AND c.oid = t.tgrelid", - name); - result4 = PSQLexec(buf); - if (!result4) - error = true; - else - trigger_count = PQntuples(result4); - } - - footers = xmalloc((index_count + constr_count + rule_count + trigger_count + 1) * sizeof(*footers)); - - /* print indices */ - for (i = 0; i < index_count; i++) - { - sprintf(buf, "%s %s", - index_count==1 ? "Index:" : (i==0 ? "Indices:" : " "), - PQgetvalue(result1, i, 0) - ); - if (i < index_count-1) - strcat(buf, ","); - - footers[count_footers++] = xstrdup(buf); - } - - /* print contraints */ - for (i = 0; i < constr_count; i++) - { - sprintf(buf, "%s %s", - constr_count==1 ? "Constraint:" : (i==0 ? "Constraints:" : " "), - PQgetvalue(result2, i, 0) - ); - footers[count_footers++] = xstrdup(buf); - } - - /* print rules */ - for (i = 0; i < rule_count; i++) - { - sprintf(buf, "%s %s", - rule_count==1 ? "Rule:" : (i==0 ? "Rules:" : " "), - PQgetvalue(result3, i, 0) - ); - if (i < rule_count-1) - strcat(buf, ","); - - footers[count_footers++] = xstrdup(buf); - } - - /* print triggers */ - for (i = 0; i < trigger_count; i++) - { - sprintf(buf, "%s %s", - trigger_count==1 ? "Trigger:" : (i==0 ? "Triggers:" : " "), - PQgetvalue(result4, i, 0) - ); - if (i < trigger_count-1) - strcat(buf, ","); - - footers[count_footers++] = xstrdup(buf); - } - - /* end of list marker */ - footers[count_footers] = NULL; - - PQclear(result1); - PQclear(result2); - PQclear(result3); - PQclear(result4); + if (!error && tableinfo.hasindex) + { + sprintf(buf, "SELECT c2.relname\n" + "FROM pg_class c, pg_class c2, pg_index i\n" + "WHERE c.relname = '%s' AND c.oid = i.indrelid AND i.indexrelid = c2.oid\n" + "ORDER BY c2.relname", + name); + result1 = PSQLexec(buf); + if (!result1) + error = true; + else + index_count = PQntuples(result1); + } + + /* count table (and column) constraints */ + if (!error && tableinfo.checks) + { + sprintf(buf, "SELECT rcsrc\n" + "FROM pg_relcheck r, pg_class c\n" + "WHERE c.relname='%s' AND c.oid = r.rcrelid", + name); + result2 = PSQLexec(buf); + if (!result2) + error = true; + else + constr_count = PQntuples(result2); + } + + /* count rules */ + if (!error && tableinfo.hasrules) + { + sprintf(buf, + "SELECT r.rulename\n" + "FROM pg_rewrite r, pg_class c\n" + "WHERE c.relname='%s' AND c.oid = r.ev_class", + name); + result3 = PSQLexec(buf); + if (!result3) + error = true; + else + rule_count = PQntuples(result3); + } + + /* count triggers */ + if (!error && tableinfo.hasrules) + { + sprintf(buf, + "SELECT t.tgname\n" + "FROM pg_trigger t, pg_class c\n" + "WHERE c.relname='%s' AND c.oid = t.tgrelid", + name); + result4 = PSQLexec(buf); + if (!result4) + error = true; + else + trigger_count = PQntuples(result4); + } + + footers = xmalloc((index_count + constr_count + rule_count + trigger_count + 1) + * sizeof(*footers)); + + /* print indices */ + for (i = 0; i < index_count; i++) + { + sprintf(buf, "%s %s", + index_count==1 ? "Index:" : (i==0 ? "Indices:" : " "), + PQgetvalue(result1, i, 0) + ); + if (i < index_count-1) + strcat(buf, ","); + + footers[count_footers++] = xstrdup(buf); + } + + /* print contraints */ + for (i = 0; i < constr_count; i++) + { + sprintf(buf, "%s %s", + constr_count==1 ? "Constraint:" : (i==0 ? "Constraints:" : " "), + PQgetvalue(result2, i, 0) + ); + footers[count_footers++] = xstrdup(buf); + } + + /* print rules */ + for (i = 0; i < rule_count; i++) + { + sprintf(buf, "%s %s", + rule_count==1 ? "Rule:" : (i==0 ? "Rules:" : " "), + PQgetvalue(result3, i, 0) + ); + if (i < rule_count-1) + strcat(buf, ","); + + footers[count_footers++] = xstrdup(buf); + } + + /* print triggers */ + for (i = 0; i < trigger_count; i++) + { + sprintf(buf, "%s %s", + trigger_count==1 ? "Trigger:" : (i==0 ? "Triggers:" : " "), + PQgetvalue(result4, i, 0) + ); + if (i < trigger_count-1) + strcat(buf, ","); + + footers[count_footers++] = xstrdup(buf); + } + + /* end of list marker */ + footers[count_footers] = NULL; + + PQclear(result1); + PQclear(result2); + PQclear(result3); + PQclear(result4); } if (!error) - printTable(title, headers, (const char**)cells, (const char**)footers, "llll", &myopt, pset.queryFout); + printTable(title, headers, + (const char**)cells, (const char**)footers, + "llll", &myopt, pset.queryFout); /* clean up */ free(title); @@ -875,8 +900,8 @@ describeTableDetails(const char *name, bool desc) for (i = 0; i < PQntuples(res); i++) { free(cells[i * cols + 1]); - if (tableinfo.relkind == 'r' || tableinfo.relkind == 's') - free(cells[i * cols + 2]); + if (tableinfo.relkind == 'r') + free(cells[i * cols + 2]); } free(cells); diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h index 7c87baa06d3..36f4ceca4ea 100644 --- a/src/bin/psql/describe.h +++ b/src/bin/psql/describe.h @@ -1,9 +1,9 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright 2000 by PostgreSQL Global Development Team + * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/describe.h,v 1.6 2000/01/18 23:30:23 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/describe.h,v 1.7 2000/01/29 16:58:48 petere Exp $ */ #ifndef DESCRIBE_H #define DESCRIBE_H diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c index ea503fc14fa..70100c7791f 100644 --- a/src/bin/psql/help.c +++ b/src/bin/psql/help.c @@ -1,9 +1,9 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright 2000 by PostgreSQL Global Development Team + * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/help.c,v 1.14 2000/01/26 16:10:01 momjian Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/help.c,v 1.15 2000/01/29 16:58:48 petere Exp $ */ #include <c.h> #include "help.h" diff --git a/src/bin/psql/help.h b/src/bin/psql/help.h index 45e02cc2a93..cbd9a81488f 100644 --- a/src/bin/psql/help.h +++ b/src/bin/psql/help.h @@ -1,9 +1,9 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright 2000 by PostgreSQL Global Development Team + * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/help.h,v 1.4 2000/01/18 23:30:23 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/help.h,v 1.5 2000/01/29 16:58:48 petere Exp $ */ #ifndef HELP_H #define HELP_H diff --git a/src/bin/psql/input.c b/src/bin/psql/input.c index 9aa56284379..2adff9d3422 100644 --- a/src/bin/psql/input.c +++ b/src/bin/psql/input.c @@ -1,9 +1,9 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright 2000 by PostgreSQL Global Development Team + * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/input.c,v 1.7 2000/01/18 23:30:23 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/input.c,v 1.8 2000/01/29 16:58:48 petere Exp $ */ #include <c.h> #include "input.h" diff --git a/src/bin/psql/input.h b/src/bin/psql/input.h index b8e7082900a..6e078cbfbea 100644 --- a/src/bin/psql/input.h +++ b/src/bin/psql/input.h @@ -1,9 +1,9 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright 2000 by PostgreSQL Global Development Team + * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/input.h,v 1.5 2000/01/18 23:30:23 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/input.h,v 1.6 2000/01/29 16:58:48 petere Exp $ */ #ifndef INPUT_H #define INPUT_H diff --git a/src/bin/psql/large_obj.c b/src/bin/psql/large_obj.c index cdc2c24c065..164956fded9 100644 --- a/src/bin/psql/large_obj.c +++ b/src/bin/psql/large_obj.c @@ -1,9 +1,9 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright 2000 by PostgreSQL Global Development Team + * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/large_obj.c,v 1.6 2000/01/18 23:30:23 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/large_obj.c,v 1.7 2000/01/29 16:58:48 petere Exp $ */ #include <c.h> #include "large_obj.h" @@ -60,8 +60,8 @@ handle_transaction(void) if (notice[0]) { - if ((!commit && strcmp(notice, "NOTICE: UserAbortTransactionBlock and not in in-progress state\n") != 0) || - (commit && strcmp(notice, "NOTICE: EndTransactionBlock and not inprogress/abort state\n") != 0)) + if ((!commit && strcmp(notice, "NOTICE: ROLLBACK: no transaction in progress\n") != 0) || + (commit && strcmp(notice, "NOTICE: COMMIT: no transaction in progress\n") != 0)) fputs(notice, stderr); } else if (!QUIET()) diff --git a/src/bin/psql/large_obj.h b/src/bin/psql/large_obj.h index 26de0e147f0..17e1c81d6df 100644 --- a/src/bin/psql/large_obj.h +++ b/src/bin/psql/large_obj.h @@ -1,9 +1,9 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright 2000 by PostgreSQL Global Development Team + * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/large_obj.h,v 1.6 2000/01/18 23:30:23 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/large_obj.h,v 1.7 2000/01/29 16:58:49 petere Exp $ */ #ifndef LARGE_OBJ_H #define LARGE_OBJ_H diff --git a/src/bin/psql/mainloop.h b/src/bin/psql/mainloop.h index 8caa8c6c80c..0664ddfcafa 100644 --- a/src/bin/psql/mainloop.h +++ b/src/bin/psql/mainloop.h @@ -1,9 +1,9 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright 2000 by PostgreSQL Global Development Team + * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/mainloop.h,v 1.5 2000/01/18 23:30:24 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/mainloop.h,v 1.6 2000/01/29 16:58:49 petere Exp $ */ #ifndef MAINLOOP_H #define MAINLOOP_H diff --git a/src/bin/psql/print.c b/src/bin/psql/print.c index af1172a21b3..3ff0d27c227 100644 --- a/src/bin/psql/print.c +++ b/src/bin/psql/print.c @@ -1,9 +1,9 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright 2000 by PostgreSQL Global Development Team + * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/print.c,v 1.8 2000/01/18 23:30:24 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/print.c,v 1.9 2000/01/29 16:58:49 petere Exp $ */ #include <c.h> #include "print.h" diff --git a/src/bin/psql/print.h b/src/bin/psql/print.h index 252236bf33e..1098ff8e012 100644 --- a/src/bin/psql/print.h +++ b/src/bin/psql/print.h @@ -1,9 +1,9 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright 2000 by PostgreSQL Global Development Team + * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/print.h,v 1.5 2000/01/18 23:30:24 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/print.h,v 1.6 2000/01/29 16:58:49 petere Exp $ */ #ifndef PRINT_H #define PRINT_H diff --git a/src/bin/psql/prompt.c b/src/bin/psql/prompt.c index f9d6cc098ea..a06a712e401 100644 --- a/src/bin/psql/prompt.c +++ b/src/bin/psql/prompt.c @@ -1,9 +1,9 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright 2000 by PostgreSQL Global Development Team + * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/prompt.c,v 1.6 2000/01/18 23:30:24 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/prompt.c,v 1.7 2000/01/29 16:58:49 petere Exp $ */ #include <c.h> #include "prompt.h" @@ -39,7 +39,7 @@ * %n - database user name * %/ - current database * %~ - like %/ but "~" when database name equals user name - * %# - "#" if the username is postgres, ">" otherwise + * %# - "#" if superuser, ">" otherwise * %R - in prompt1 normally =, or ^ if single line mode, * or a ! if session is not connected to a database; * in prompt2 -, *, ', or "; @@ -194,7 +194,7 @@ get_prompt(promptStatus_t status) case '#': { - if (pset.db && strcmp(PQuser(pset.db), "postgres") == 0) + if (pset.issuper) buf[0] = '#'; else buf[0] = '>'; diff --git a/src/bin/psql/prompt.h b/src/bin/psql/prompt.h index 9134f8331c9..f70a334a54d 100644 --- a/src/bin/psql/prompt.h +++ b/src/bin/psql/prompt.h @@ -1,9 +1,9 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright 2000 by PostgreSQL Global Development Team + * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/prompt.h,v 1.4 2000/01/18 23:30:24 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/prompt.h,v 1.5 2000/01/29 16:58:49 petere Exp $ */ #ifndef PROMPT_H #define PROMPT_H diff --git a/src/bin/psql/settings.h b/src/bin/psql/settings.h index 6cfeca79b29..af8171e7da5 100644 --- a/src/bin/psql/settings.h +++ b/src/bin/psql/settings.h @@ -1,9 +1,9 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright 2000 by PostgreSQL Global Development Team + * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/settings.h,v 1.7 2000/01/18 23:30:24 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/settings.h,v 1.8 2000/01/29 16:58:49 petere Exp $ */ #ifndef SETTINGS_H #define SETTINGS_H @@ -53,6 +53,9 @@ typedef struct _psqlSettings char *progname; /* in case you renamed psql */ char *inputfile; /* for error reporting */ unsigned lineno; /* also for error reporting */ + + bool issuper; /* is the current user a superuser? + (used to form the prompt) */ } PsqlSettings; extern PsqlSettings pset; diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c index d3169ab84c7..d92adce381e 100644 --- a/src/bin/psql/startup.c +++ b/src/bin/psql/startup.c @@ -1,9 +1,9 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright 2000 by PostgreSQL Global Development Team + * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/startup.c,v 1.19 2000/01/27 05:33:51 momjian Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/startup.c,v 1.20 2000/01/29 16:58:49 petere Exp $ */ #include <c.h> @@ -162,8 +162,8 @@ main(int argc, char **argv) if (PQstatus(pset.db) == CONNECTION_BAD) { - fprintf(stderr, "%s: connection to database \"%s\" failed - %s", - pset.progname, PQdb(pset.db), PQerrorMessage(pset.db)); + fprintf(stderr, "%s: %s", + pset.progname, PQerrorMessage(pset.db)); PQfinish(pset.db); exit(EXIT_BADCONN); } @@ -188,6 +188,8 @@ main(int argc, char **argv) SetVariable(pset.vars, "HOST", PQhost(pset.db)); SetVariable(pset.vars, "PORT", PQport(pset.db)); + pset.issuper = test_superuser(PQuser(pset.db)); + if (!QUIET() && !pset.notty && !options.action) { printf("Welcome to %s, the PostgreSQL interactive terminal.\n\n" @@ -436,11 +438,13 @@ parse_options(int argc, char *argv[], struct adhoc_opts * options) pset.getPassword = true; break; case '?': - if (strcmp(argv[optind-1], "-?")==0) + /* Actual help option given */ + if (strcmp(argv[optind-1], "-?")==0 || strcmp(argv[optind-1], "--help")==0) { usage(); exit(EXIT_SUCCESS); } + /* unknown option reported by getopt */ else { fputs("Try -? for help.\n", stderr); @@ -486,7 +490,7 @@ parse_options(int argc, char *argv[], struct adhoc_opts * options) /* - * Load /etc/psqlrc or .psqlrc file, if found. + * Load .psqlrc file, if found. */ static void process_psqlrc(void) @@ -498,12 +502,6 @@ process_psqlrc(void) #define R_OK 0 #endif - /* 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); - else if (access("/etc/psqlrc", R_OK) == 0) - process_file("/etc/psqlrc"); - /* Look for one in the home dir */ home = getenv("HOME"); @@ -573,6 +571,6 @@ showVersion(void) puts("Portions Copyright (c) 1996-2000, PostgreSQL, Inc"); puts("Portions Copyright (C) 1996 Regents of the University of California"); - puts("Read the file COPYING 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."); } diff --git a/src/bin/psql/stringutils.c b/src/bin/psql/stringutils.c index c8cc6034224..5ba48dc454c 100644 --- a/src/bin/psql/stringutils.c +++ b/src/bin/psql/stringutils.c @@ -1,9 +1,9 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright 2000 by PostgreSQL Global Development Team + * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/stringutils.c,v 1.22 2000/01/18 23:30:24 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/stringutils.c,v 1.23 2000/01/29 16:58:49 petere Exp $ */ #include <c.h> #include "stringutils.h" diff --git a/src/bin/psql/stringutils.h b/src/bin/psql/stringutils.h index 0a109b56394..914871d94eb 100644 --- a/src/bin/psql/stringutils.h +++ b/src/bin/psql/stringutils.h @@ -1,9 +1,9 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright 2000 by PostgreSQL Global Development Team + * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/stringutils.h,v 1.12 2000/01/18 23:30:24 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/stringutils.h,v 1.13 2000/01/29 16:58:49 petere Exp $ */ #ifndef STRINGUTILS_H #define STRINGUTILS_H diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index 718c1732f05..92112cead07 100644 --- a/src/bin/psql/tab-complete.c +++ b/src/bin/psql/tab-complete.c @@ -1,9 +1,9 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright 2000 by PostgreSQL Global Development Team + * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/tab-complete.c,v 1.8 2000/01/21 23:32:36 tgl Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/tab-complete.c,v 1.9 2000/01/29 16:58:49 petere Exp $ */ /*----------- diff --git a/src/bin/psql/tab-complete.h b/src/bin/psql/tab-complete.h index 42fa6fe1b06..8c54cffeb64 100644 --- a/src/bin/psql/tab-complete.h +++ b/src/bin/psql/tab-complete.h @@ -1,9 +1,9 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright 2000 by PostgreSQL Global Development Team + * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/tab-complete.h,v 1.2 2000/01/18 23:30:24 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/tab-complete.h,v 1.3 2000/01/29 16:58:49 petere Exp $ */ #ifndef TAB_COMPLETE_H #define TAB_COMPLETE_H diff --git a/src/bin/psql/variables.c b/src/bin/psql/variables.c index 0c559af7e67..b0523dcb675 100644 --- a/src/bin/psql/variables.c +++ b/src/bin/psql/variables.c @@ -1,9 +1,9 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright 2000 by PostgreSQL Global Development Team + * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/variables.c,v 1.4 2000/01/18 23:30:24 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/variables.c,v 1.5 2000/01/29 16:58:49 petere Exp $ */ #include <c.h> #include "variables.h" diff --git a/src/bin/psql/variables.h b/src/bin/psql/variables.h index d6b5fb72358..2b476dd0c31 100644 --- a/src/bin/psql/variables.h +++ b/src/bin/psql/variables.h @@ -1,9 +1,9 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright 2000 by PostgreSQL Global Development Team + * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/variables.h,v 1.4 2000/01/18 23:30:24 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/variables.h,v 1.5 2000/01/29 16:58:49 petere Exp $ */ /* diff --git a/src/interfaces/libpq++/pgdatabase.cc b/src/interfaces/libpq++/pgdatabase.cc index f34354be416..545c71c08d3 100644 --- a/src/interfaces/libpq++/pgdatabase.cc +++ b/src/interfaces/libpq++/pgdatabase.cc @@ -10,7 +10,7 @@ * Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/interfaces/libpq++/Attic/pgdatabase.cc,v 1.8 1999/10/13 16:46:28 momjian Exp $ + * $Header: /cvsroot/pgsql/src/interfaces/libpq++/Attic/pgdatabase.cc,v 1.9 2000/01/29 16:58:52 petere Exp $ * *------------------------------------------------------------------------- */ @@ -26,9 +26,9 @@ void PgDatabase::DisplayTuples(FILE *out, int fillAlign, memset(&po,0,sizeof(po)); - po.align = (pqbool)fillAlign; + po.align = fillAlign; po.fieldSep = (char *)fieldSep; - po.header = (pqbool)printHeader; + po.header = printHeader; PQprint(out,pgResult,&po); } @@ -43,12 +43,12 @@ void PgDatabase::PrintTuples(FILE *out, int printAttName, int terseOutput, memset(&po,0,sizeof(po)); - po.align = (pqbool)width; + po.align = width; if(terseOutput) po.fieldSep = strdup("|"); else po.fieldSep = ""; - po.header = (pqbool)printAttName; + po.header = printAttName; PQprint(out,pgResult,&po); } diff --git a/src/interfaces/libpq/fe-misc.c b/src/interfaces/libpq/fe-misc.c index 074c1249d38..ff6acefea8f 100644 --- a/src/interfaces/libpq/fe-misc.c +++ b/src/interfaces/libpq/fe-misc.c @@ -25,7 +25,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.37 2000/01/26 05:58:45 momjian Exp $ + * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.38 2000/01/29 16:58:51 petere Exp $ * *------------------------------------------------------------------------- */ @@ -51,6 +51,11 @@ #include "libpq-int.h" #include "pqsignal.h" +#ifdef MULTIBYTE +#include "miscadmin.h" +#include "mb/pg_wchar.h" +#endif + #define DONOTICE(conn,message) \ ((*(conn)->noticeHook) ((conn)->noticeArg, (message))) @@ -737,3 +742,52 @@ pqWait(int forRead, int forWrite, PGconn *conn) return 0; } + + + +/* + * A couple of "miscellaneous" multibyte related functions. They used + * to be in fe-print.c but that file is doomed. + */ + +#ifdef MULTIBYTE +/* + * returns the byte length of the word beginning s, using the + * specified encoding. + */ +int +PQmblen(const unsigned char *s, int encoding) +{ + return (pg_encoding_mblen(encoding, s)); +} + +/* + * Get encoding id from environment variable PGCLIENTENCODING. + */ +int +PQenv2encoding(void) +{ + char *str; + int encoding = SQL_ASCII; + + str = getenv("PGCLIENTENCODING"); + if (str && *str != '\0') + encoding = pg_char_to_encoding(str); + return(encoding); +} + +#else + +/* Provide a default definition in case someone calls it anyway */ +int +PQmblen(const unsigned char *s, int encoding) +{ + return 1; +} +int +PQenv2encoding(void) +{ + return 0; +} + +#endif /* MULTIBYTE */ diff --git a/src/interfaces/libpq/fe-print.c b/src/interfaces/libpq/fe-print.c index 6bf778d5a30..7c0e655f2a8 100644 --- a/src/interfaces/libpq/fe-print.c +++ b/src/interfaces/libpq/fe-print.c @@ -10,13 +10,13 @@ * didn't really belong there. * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-print.c,v 1.32 2000/01/26 05:58:46 momjian Exp $ + * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-print.c,v 1.33 2000/01/29 16:58:51 petere Exp $ * *------------------------------------------------------------------------- */ -#include <signal.h> +#include <postgres.h> -#include "postgres.h" +#include <signal.h> #include "libpq-fe.h" #include "libpq-int.h" #include "pqsignal.h" @@ -36,21 +36,14 @@ #endif #endif -#ifdef MULTIBYTE -#include "miscadmin.h" -#include "mb/pg_wchar.h" -#endif - #ifdef TIOCGWINSZ static struct winsize screen_size; - #else static struct winsize { int ws_row; int ws_col; } screen_size; - #endif @@ -66,7 +59,6 @@ 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, unsigned char *fieldNotNum, int *fieldMax, char *border, const int row_index); -static void fill(int length, int max, char filler, FILE *fp); /* @@ -78,7 +70,9 @@ static void fill(int length, int max, char filler, FILE *fp); * various flags and options. consult libpq-fe.h for * details * - * Obsoletes PQprintTuples. + * This function should probably be removed sometime since psql + * doesn't use it anymore. It is unclear to what extend this is used + * by external clients, however. */ void @@ -315,229 +309,6 @@ PQprint(FILE *fout, } -/* - * PQdisplayTuples() - * kept for backward compatibility - */ - -void -PQdisplayTuples(const PGresult *res, - FILE *fp, /* where to send the output */ - int fillAlign, /* pad the fields with spaces */ - const char *fieldSep, /* field separator */ - int printHeader,/* display headers? */ - int quiet -) -{ -#define DEFAULT_FIELD_SEP " " - - int i, - j; - int nFields; - int nTuples; - int *fLength = NULL; - - if (fieldSep == NULL) - fieldSep = DEFAULT_FIELD_SEP; - - /* Get some useful info about the results */ - nFields = PQnfields(res); - nTuples = PQntuples(res); - - if (fp == NULL) - fp = stdout; - - /* Figure the field lengths to align to */ - /* will be somewhat time consuming for very large results */ - if (fillAlign) - { - fLength = (int *) malloc(nFields * sizeof(int)); - for (j = 0; j < nFields; j++) - { - fLength[j] = strlen(PQfname(res, j)); - for (i = 0; i < nTuples; i++) - { - int flen = PQgetlength(res, i, j); - if (flen > fLength[j]) - fLength[j] = flen; - } - } - } - - if (printHeader) - { - /* first, print out the attribute names */ - for (i = 0; i < nFields; i++) - { - fputs(PQfname(res, i), fp); - if (fillAlign) - fill(strlen(PQfname(res, i)), fLength[i], ' ', fp); - fputs(fieldSep, fp); - } - fprintf(fp, "\n"); - - /* Underline the attribute names */ - for (i = 0; i < nFields; i++) - { - if (fillAlign) - fill(0, fLength[i], '-', fp); - fputs(fieldSep, fp); - } - fprintf(fp, "\n"); - } - - /* next, print out the instances */ - for (i = 0; i < nTuples; i++) - { - for (j = 0; j < nFields; j++) - { - fprintf(fp, "%s", PQgetvalue(res, i, j)); - if (fillAlign) - fill(strlen(PQgetvalue(res, i, j)), fLength[j], ' ', fp); - fputs(fieldSep, fp); - } - fprintf(fp, "\n"); - } - - if (!quiet) - fprintf(fp, "\nQuery returned %d row%s.\n", PQntuples(res), - (PQntuples(res) == 1) ? "" : "s"); - - fflush(fp); - - if (fLength) - free(fLength); -} - - - -/* - * PQprintTuples() - * - * kept for backward compatibility - * - */ -void -PQprintTuples(const PGresult *res, - FILE *fout, /* output stream */ - int PrintAttNames,/* print attribute names or not */ - int TerseOutput, /* delimiter bars or not? */ - int colWidth /* width of column, if 0, use variable - * width */ -) -{ - int nFields; - int nTups; - int i, - j; - char formatString[80]; - - char *tborder = NULL; - - nFields = PQnfields(res); - nTups = PQntuples(res); - - if (colWidth > 0) - sprintf(formatString, "%%s %%-%ds", colWidth); - else - sprintf(formatString, "%%s %%s"); - - if (nFields > 0) - { /* only print rows with at least 1 field. */ - - if (!TerseOutput) - { - int width; - - width = nFields * 14; - tborder = malloc(width + 1); - for (i = 0; i <= width; i++) - tborder[i] = '-'; - tborder[i] = '\0'; - fprintf(fout, "%s\n", tborder); - } - - for (i = 0; i < nFields; i++) - { - if (PrintAttNames) - { - fprintf(fout, formatString, - TerseOutput ? "" : "|", - PQfname(res, i)); - } - } - - if (PrintAttNames) - { - if (TerseOutput) - fprintf(fout, "\n"); - else - fprintf(fout, "|\n%s\n", tborder); - } - - for (i = 0; i < nTups; i++) - { - for (j = 0; j < nFields; j++) - { - const char *pval = PQgetvalue(res, i, j); - - fprintf(fout, formatString, - TerseOutput ? "" : "|", - pval ? pval : ""); - } - if (TerseOutput) - fprintf(fout, "\n"); - else - fprintf(fout, "|\n%s\n", tborder); - } - } -} - -#ifdef MULTIBYTE -/* - * returns the byte length of the word beginning s. - * Client side encoding is determined by the environment variable - * "PGCLIENTENCODING". - * if this variable is not defined, the same encoding as - * the backend is assumed. - */ -int -PQmblen(const unsigned char *s, int encoding) -{ - return (pg_encoding_mblen(encoding, s)); -} - -/* - * Get encoding id from environment variable PGCLIENTENCODING. - */ -int -PQenv2encoding(void) -{ - char *str; - int encoding = SQL_ASCII; - - str = getenv("PGCLIENTENCODING"); - if (str && *str != '\0') - encoding = pg_char_to_encoding(str); - return(encoding); -} - -#else - -/* Provide a default definition in case someone calls it anyway */ -int -PQmblen(const unsigned char *s, int encoding) -{ - return 1; -} -int -PQenv2encoding(void) -{ - return 0; -} - -#endif /* MULTIBYTE */ - static void do_field(const PQprintOpt *po, const PGresult *res, const int i, const int j, const int fs_len, @@ -785,14 +556,176 @@ output_row(FILE *fout, const PQprintOpt *po, const int nFields, char **fields, } -/* simply send out max-length number of filler characters to fp */ -static void -fill(int length, int max, char filler, FILE *fp) +#if 0 +/* + * really old printing routines + */ + +void +PQdisplayTuples(const PGresult *res, + FILE *fp, /* where to send the output */ + int fillAlign, /* pad the fields with spaces */ + const char *fieldSep, /* field separator */ + int printHeader,/* display headers? */ + int quiet +) +{ +#define DEFAULT_FIELD_SEP " " + + int i, + j; + int nFields; + int nTuples; + int *fLength = NULL; + + if (fieldSep == NULL) + fieldSep = DEFAULT_FIELD_SEP; + + /* Get some useful info about the results */ + nFields = PQnfields(res); + nTuples = PQntuples(res); + + if (fp == NULL) + fp = stdout; + + /* Figure the field lengths to align to */ + /* will be somewhat time consuming for very large results */ + if (fillAlign) + { + fLength = (int *) malloc(nFields * sizeof(int)); + for (j = 0; j < nFields; j++) + { + fLength[j] = strlen(PQfname(res, j)); + for (i = 0; i < nTuples; i++) + { + int flen = PQgetlength(res, i, j); + if (flen > fLength[j]) + fLength[j] = flen; + } + } + } + + if (printHeader) + { + /* first, print out the attribute names */ + for (i = 0; i < nFields; i++) + { + fputs(PQfname(res, i), fp); + if (fillAlign) + fill(strlen(PQfname(res, i)), fLength[i], ' ', fp); + fputs(fieldSep, fp); + } + fprintf(fp, "\n"); + + /* Underline the attribute names */ + for (i = 0; i < nFields; i++) + { + if (fillAlign) + fill(0, fLength[i], '-', fp); + fputs(fieldSep, fp); + } + fprintf(fp, "\n"); + } + + /* next, print out the instances */ + for (i = 0; i < nTuples; i++) + { + for (j = 0; j < nFields; j++) + { + fprintf(fp, "%s", PQgetvalue(res, i, j)); + if (fillAlign) + fill(strlen(PQgetvalue(res, i, j)), fLength[j], ' ', fp); + fputs(fieldSep, fp); + } + fprintf(fp, "\n"); + } + + if (!quiet) + fprintf(fp, "\nQuery returned %d row%s.\n", PQntuples(res), + (PQntuples(res) == 1) ? "" : "s"); + + fflush(fp); + + if (fLength) + free(fLength); +} + + + +void +PQprintTuples(const PGresult *res, + FILE *fout, /* output stream */ + int PrintAttNames,/* print attribute names or not */ + int TerseOutput, /* delimiter bars or not? */ + int colWidth /* width of column, if 0, use variable + * width */ +) { - int count; + int nFields; + int nTups; + int i, + j; + char formatString[80]; + + char *tborder = NULL; + + nFields = PQnfields(res); + nTups = PQntuples(res); + + if (colWidth > 0) + sprintf(formatString, "%%s %%-%ds", colWidth); + else + sprintf(formatString, "%%s %%s"); + + if (nFields > 0) + { /* only print rows with at least 1 field. */ + + if (!TerseOutput) + { + int width; + + width = nFields * 14; + tborder = malloc(width + 1); + for (i = 0; i <= width; i++) + tborder[i] = '-'; + tborder[i] = '\0'; + fprintf(fout, "%s\n", tborder); + } + + for (i = 0; i < nFields; i++) + { + if (PrintAttNames) + { + fprintf(fout, formatString, + TerseOutput ? "" : "|", + PQfname(res, i)); + } + } + + if (PrintAttNames) + { + if (TerseOutput) + fprintf(fout, "\n"); + else + fprintf(fout, "|\n%s\n", tborder); + } + + for (i = 0; i < nTups; i++) + { + for (j = 0; j < nFields; j++) + { + const char *pval = PQgetvalue(res, i, j); - count = max - length; - while (count-- >= 0) - putc(filler, fp); + fprintf(fout, formatString, + TerseOutput ? "" : "|", + pval ? pval : ""); + } + if (TerseOutput) + fprintf(fout, "\n"); + else + fprintf(fout, "|\n%s\n", tborder); + } + } } +#endif diff --git a/src/interfaces/libpq/libpq-fe.h b/src/interfaces/libpq/libpq-fe.h index d8915b11d39..35bbb6eff3f 100644 --- a/src/interfaces/libpq/libpq-fe.h +++ b/src/interfaces/libpq/libpq-fe.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: libpq-fe.h,v 1.57 2000/01/26 05:58:46 momjian Exp $ + * $Id: libpq-fe.h,v 1.58 2000/01/29 16:58:51 petere Exp $ * *------------------------------------------------------------------------- */ @@ -116,22 +116,15 @@ extern "C" /* Print options for PQprint() */ - /* - * We can't use the conventional "bool", because we are designed to be - * included in a user's program, and user may already have that type - * defined. Pqbool, on the other hand, is unlikely to be used. - */ - typedef char pqbool; - typedef struct _PQprintOpt { - pqbool header; /* print output field headings and row + int header; /* print output field headings and row * count */ - pqbool align; /* fill align the fields */ - pqbool standard; /* old brain dead format */ - pqbool html3; /* output html tables */ - pqbool expanded; /* expand tables */ - pqbool pager; /* use pager for output if needed */ + int align; /* fill align the fields */ + int standard; /* old brain dead format */ + int html3; /* output html tables */ + int expanded; /* expand tables */ + int pager; /* use pager for output if needed */ char *fieldSep; /* field separator */ char *tableOpt; /* insert to HTML <table ...> */ char *caption; /* HTML <caption> */ @@ -296,8 +289,8 @@ extern "C" extern int PQfsize(const PGresult *res, int field_num); extern int PQfmod(const PGresult *res, int field_num); extern const char *PQcmdStatus(const PGresult *res); - extern const char *PQoidStatus(const PGresult *res); /* old and ugly */ - extern Oid PQoidValue(const PGresult *res); /* new and improved */ + extern const char *PQoidStatus(const PGresult *res); /* old and ugly */ + extern Oid PQoidValue(const PGresult *res); /* new and improved */ extern const char *PQcmdTuples(const PGresult *res); extern const char *PQgetvalue(const PGresult *res, int tup_num, int field_num); extern int PQgetlength(const PGresult *res, int tup_num, int field_num); @@ -319,33 +312,24 @@ extern "C" const PGresult *res, const PQprintOpt *ps); /* option structure */ - /* - * PQdisplayTuples() is a better version of PQprintTuples(), but both - * are obsoleted by PQprint(). - */ - extern void PQdisplayTuples(const PGresult *res, - FILE *fp, /* where to send the - * output */ - int fillAlign, /* pad the fields with - * spaces */ - const char *fieldSep, /* field separator */ - int printHeader, /* display headers? */ - int quiet); - - extern void PQprintTuples(const PGresult *res, - FILE *fout, /* output stream */ - int printAttName, /* print attribute names - * or not */ - int terseOutput, /* delimiter bars or - * not? */ - int width); /* width of column, if - * 0, use variable width */ - - /* Determine length of multibyte encoded char at *s */ - extern int PQmblen(const unsigned char *s, int encoding); - - /* Get encoding id from environment variable PGCLIENTENCODING */ - int PQenv2encoding(void); +#if 0 + /* + * really old printing routines + */ + extern void PQdisplayTuples(const PGresult *res, + FILE *fp, /* where to send the output */ + int fillAlign, /* pad the fields with spaces */ + const char *fieldSep, /* field separator */ + int printHeader, /* display headers? */ + int quiet); + + extern void PQprintTuples(const PGresult *res, + FILE *fout, /* output stream */ + int printAttName, /* print attribute names */ + int terseOutput, /* delimiter bars */ + int width); /* width of column, if + * 0, use variable width */ +#endif /* === in fe-lobj.c === */ @@ -361,6 +345,14 @@ extern "C" extern Oid lo_import(PGconn *conn, const char *filename); extern int lo_export(PGconn *conn, Oid lobjId, const char *filename); +/* === in fe-misc.c === */ + + /* Determine length of multibyte encoded char at *s */ + extern int PQmblen(const unsigned char *s, int encoding); + + /* Get encoding id from environment variable PGCLIENTENCODING */ + extern int PQenv2encoding(void); + #ifdef __cplusplus }; diff --git a/src/test/regress/expected/errors.out b/src/test/regress/expected/errors.out index 61f1dfd0129..2aa6be0ce56 100644 --- a/src/test/regress/expected/errors.out +++ b/src/test/regress/expected/errors.out @@ -93,10 +93,10 @@ ERROR: renameatt: attribute "oid" exists -- not in a xact abort; -NOTICE: UserAbortTransactionBlock and not in in-progress state +NOTICE: ROLLBACK: no transaction in progress -- not in a xact end; -NOTICE: EndTransactionBlock and not inprogress/abort state +NOTICE: COMMIT: no transaction in progress -- -- DEFINE AGGREGATE |