From 2b84cbb60f6ff6cb58d42dff026aaf0b2e9ca8ab Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Sat, 29 Jan 2000 16:58:54 +0000 Subject: [PATCH] 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 --- doc/src/sgml/libpq.sgml | 64 ++-- doc/src/sgml/ref/abort.sgml | 10 +- doc/src/sgml/ref/alter_table.sgml | 171 ++++------ doc/src/sgml/ref/begin.sgml | 23 +- doc/src/sgml/ref/commit.sgml | 9 +- doc/src/sgml/ref/end.sgml | 10 +- doc/src/sgml/ref/psql-ref.sgml | 25 +- doc/src/sgml/ref/rollback.sgml | 13 +- doc/src/sgml/ref/update.sgml | 4 +- src/backend/access/transam/xact.c | 10 +- src/backend/commands/command.c | 15 +- src/backend/commands/creatinh.c | 44 ++- src/backend/parser/gram.y | 27 +- src/backend/tcop/utility.c | 23 +- src/bin/initdb/initdb.sh | 13 +- src/bin/pg_dump/pg_dump.c | 6 +- src/bin/psql/command.c | 36 ++- src/bin/psql/command.h | 7 +- src/bin/psql/common.c | 4 +- src/bin/psql/common.h | 4 +- src/bin/psql/copy.c | 4 +- src/bin/psql/copy.h | 4 +- src/bin/psql/create_help.pl | 38 ++- src/bin/psql/describe.c | 451 ++++++++++++++------------- src/bin/psql/describe.h | 4 +- src/bin/psql/help.c | 4 +- src/bin/psql/help.h | 4 +- src/bin/psql/input.c | 4 +- src/bin/psql/input.h | 4 +- src/bin/psql/large_obj.c | 8 +- src/bin/psql/large_obj.h | 4 +- src/bin/psql/mainloop.h | 4 +- src/bin/psql/print.c | 4 +- src/bin/psql/print.h | 4 +- src/bin/psql/prompt.c | 8 +- src/bin/psql/prompt.h | 4 +- src/bin/psql/settings.h | 7 +- src/bin/psql/startup.c | 24 +- src/bin/psql/stringutils.c | 4 +- src/bin/psql/stringutils.h | 4 +- src/bin/psql/tab-complete.c | 4 +- src/bin/psql/tab-complete.h | 4 +- src/bin/psql/variables.c | 4 +- src/bin/psql/variables.h | 4 +- src/interfaces/libpq++/pgdatabase.cc | 10 +- src/interfaces/libpq/fe-misc.c | 56 +++- src/interfaces/libpq/fe-print.c | 417 +++++++++++-------------- src/interfaces/libpq/libpq-fe.h | 78 +++-- src/test/regress/expected/errors.out | 4 +- 49 files changed, 821 insertions(+), 870 deletions(-) diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml index 3f9738b462..7543e9add6 100644 --- a/doc/src/sgml/libpq.sgml +++ b/doc/src/sgml/libpq.sgml @@ -274,8 +274,8 @@ PostgresPollingStatusType *PQconnectPoll(PQconn *conn) - To begin, call conn=PQconnectStart("<connection_info_string>"). If - conn is NULL, then libpq has been unable to allocate a new PGconn + To begin, call conn=PQconnectStart("<connection_info_string>"). + If conn is NULL, then libpq has been unable to allocate a new PGconn structure. Otherwise, a valid PGconn pointer is returned (though not yet representing a valid connection to the database). On return from PQconnectStart, call status=PQstatus(conn). If status equals @@ -1019,6 +1019,9 @@ const char * PQcmdTuples(const PGresult *res); Oid PQoidValue(const PGresult *res); + The type Oid and the constant Invalid + will be defined if you include the libpq + header file. They will both be some integer type. @@ -1031,7 +1034,8 @@ Oid PQoidValue(const PGresult *res); const char * PQoidStatus(const PGresult *res); -The function is deprecated in favor of PQoidValue. +The function is deprecated in favor of PQoidValue +and is not thread-safe. @@ -1045,57 +1049,25 @@ void PQprint(FILE* fout, /* output stream */ const PGresult *res, const PQprintOpt *po); -struct _PQprintOpt { - pqbool 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 */ +struct { + int header; /* print output field headings and row count */ + 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> */ char **fieldName; /* null terminated array of replacement field names */ -} +} PQprintOpt; -This function is intended to replace PQprintTuples(), which is -now obsolete. The psql program uses -PQprint() to display query results. +This function was formerly used by psql +to print query results, but this is no longer the case and this +function is no longer supported. - - -PQprintTuples - Prints out all the tuples and, optionally, the - attribute names to the specified output stream. - -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, variable width if 0*/ - - - - - - -PQdisplayTuples - Prints out all the tuples and, optionally, the - attribute names to the specified output stream. - -void PQdisplayTuples(const PGresult* res, - FILE *fout, /* output stream */ - int fillAlign, /* space fill to align columns */ - const char *fieldSep, /* field separator */ - int printHeader, /* display headers? */ - int quiet); /* suppress print of row count at end */ - -PQdisplayTuples() was intended to supersede -PQprintTuples(), and -is in turn superseded by PQprint(). - diff --git a/doc/src/sgml/ref/abort.sgml b/doc/src/sgml/ref/abort.sgml index e97654a077..c31fcb2acb 100644 --- a/doc/src/sgml/ref/abort.sgml +++ b/doc/src/sgml/ref/abort.sgml @@ -1,5 +1,5 @@ @@ -52,7 +52,7 @@ ABORT [ WORK | TRANSACTION ] -ABORT +ROLLBACK @@ -62,8 +62,8 @@ ABORT -NOTICE: UserAbortTransactionBlock and not in in-progress state -ABORT +NOTICE: ROLLBACK: no transaction in progress +ROLLBACK @@ -130,7 +130,7 @@ ABORT WORK; SQL92 - This command is a Postgres extension present + This command is a PostgreSQL extension present for historical reasons. ROLLBACK is the SQL92 equivalent command. diff --git a/doc/src/sgml/ref/alter_table.sgml b/doc/src/sgml/ref/alter_table.sgml index bb49772e8e..54d06e5ce5 100644 --- a/doc/src/sgml/ref/alter_table.sgml +++ b/doc/src/sgml/ref/alter_table.sgml @@ -1,5 +1,5 @@ @@ -23,11 +23,14 @@ Postgres documentation 1999-07-20 -ALTER TABLE table - [ * ] ADD [ COLUMN ] column table [ * ] + ADD [ COLUMN ] column type -ALTER TABLE table - [ * ] RENAME [ COLUMN ] column TO table [ * ] + ALTER [ COLUMN ] column { SET DEFAULT value | DROP DEFAULT } +ALTER TABLE table [ * ] + RENAME [ COLUMN ] column TO newcolumn ALTER TABLE table RENAME TO newtable @@ -82,7 +85,7 @@ ALTER TABLE table newtable - New name for an existing column. + New name for the table. @@ -101,9 +104,7 @@ ALTER TABLE table - -ALTER - + ALTER Message returned from column or table renaming. @@ -112,20 +113,7 @@ ALTER - -NEW - - - - Message returned from column addition. - - - - - - -ERROR - + ERROR Message returned if table or column is not available. @@ -146,9 +134,12 @@ ERROR ALTER TABLE changes the definition of an existing table. - The new columns and their types are specified in the same style - and with the the same restrictions as in CREATE TABLE. - The RENAME clause causes the name of a table or column + The ADD COLUMN form adds a new column to the table + using the same syntax as . The ALTER COLUMN form + allows you to set or remove the default for the column. Note that defaults + only apply to newly inserted rows. + The RENAME clause causes the name of a table or column to change without changing any of the data contained in the affected table. Thus, the table or column will remain of the same type and size after this command is @@ -189,13 +180,12 @@ SELECT NewColumn FROM SuperClass - For efficiency reasons, default values for added attributes are - not placed in existing instances of a class. - That is, existing instances will have NULL values in the new - attributes. If non-NULL values are desired, a subsequent - UPDATE query - () - should be run. + In the current implementation, default and constraint clauses for the + new column will be ignored. You can use the SET DEFAULT + form of ALTER TABLE to set the default later. + (You will also have to update the already existing rows to the + new default value, using .) @@ -248,87 +238,38 @@ ALTER TABLE distributors RENAME TO suppliers; 1998-04-15 - - SQL92 - - - ALTER TABLE/RENAME - is a Postgres language extension. - + SQL92 + + The ADD COLUMN form is compliant with the exception that + it does not support defaults and constraints, as explained above. + The ALTER COLUMN form is in full compliance. + - - SQL92 specifies some additional capabilities for ALTER TABLE - statement which are not yet directly supported by - Postgres: - + + SQL92 specifies some additional capabilities for ALTER TABLE + statement which are not yet directly supported by PostgreSQL: - - - - -ALTER TABLE table ALTER [ - COLUMN ] column - SET DEFAULT default -ALTER TABLE table ALTER [ - COLUMN ] column - ADD [ CONSTRAINT >constrain> ] table-constraint + + + + +ALTER TABLE table ADD table constraint definition +ALTER TABLE table DROP CONSTRAINT constraint { RESTRICT | CASCADE } - Puts the default value or constraint specified into the - definition of column in the table. - See CREATE TABLE for the - syntax of the default and table-constraint clauses. - If a default clause already exists, it will be replaced by - the new definition. If any constraints on this column already - exist, they will be retained using a boolean AND with the new - constraint. + Adds or removes a table constraint (such as a check constraint, + unique constraint, or foreign key constraint). To create + or remove a unique constraint, create or drop a unique index, + respectively (see ). + To change other kinds of constraints you need to recreate + and reload the table, using other parameters to the + + command. - - Currently, to set new default constraints on an existing column - the table must be recreated and reloaded: - - -CREATE TABLE temp AS SELECT * FROM distributors; -DROP TABLE distributors; -CREATE TABLE distributors ( - did DECIMAL(3) DEFAULT 1, - name VARCHAR(40) NOT NULL, - city VARCHAR(30) -); -INSERT INTO distributors SELECT * FROM temp; -DROP TABLE temp; - - - - - - - - -ALTER TABLE table - DROP DEFAULT default -ALTER TABLE table - DROP CONSTRAINT constraint { RESTRICT | CASCADE } - - - - - Removes the default value specified by default or the rule - specified by constraint from the definition of a table. - If RESTRICT is specified only a constraint with no dependent - constraints can be destroyed. - If CASCADE is specified, Any constraints that are dependent on - this constraint are also dropped. - - - - Currently, to remove a default value or constraints on an - existing column the table must be recreated and reloaded: - + For example, to drop any constraints on a table distributors: CREATE TABLE temp AS SELECT * FROM distributors; DROP TABLE distributors; @@ -342,23 +283,14 @@ DROP TABLE temp; -ALTER TABLE table - DROP [ COLUMN ] column { RESTRICT | CASCADE } +ALTER TABLE table DROP [ COLUMN ] column { RESTRICT | CASCADE } Removes a column from a table. - If RESTRICT is specified only a column with no dependent - objects can be destroyed. - If CASCADE is specified, all objects that are dependent on - this column are also dropped. - - - Currently, to remove an existing column the table must be recreated and reloaded: - CREATE TABLE temp AS SELECT did, city FROM distributors; DROP TABLE distributors; @@ -373,6 +305,13 @@ DROP TABLE temp; + + + + The clauses to rename columns and tables are PostgreSQL + extensions. SQL92 does not provide for them. + + diff --git a/doc/src/sgml/ref/begin.sgml b/doc/src/sgml/ref/begin.sgml index a6e45aaadb..1ee645c771 100644 --- a/doc/src/sgml/ref/begin.sgml +++ b/doc/src/sgml/ref/begin.sgml @@ -1,5 +1,5 @@ @@ -72,7 +72,7 @@ BEGIN -NOTICE: BeginTransactionBlock and not in default state +NOTICE: BEGIN: already a transaction in progress @@ -95,7 +95,7 @@ NOTICE: BeginTransactionBlock and not in default state - By default, Postgres executes transactions + By default, PostgreSQL executes transactions in unchained mode (also known as autocommit in other database systems). @@ -116,7 +116,7 @@ NOTICE: BeginTransactionBlock and not in default state The default transaction isolation level in - Postgres + PostgreSQL is READ COMMITTED, where queries inside the transaction see only changes committed before query execution. So, you have to use SET TRANSACTION ISOLATION LEVEL SERIALIZABLE @@ -128,7 +128,7 @@ NOTICE: BeginTransactionBlock and not in default state - If the transaction is committed, Postgres + If the transaction is committed, PostgreSQL will ensure either that all updates are done or else that none of them are done. Transactions have the standard ACID (atomic, consistent, isolatable, and durable) property. @@ -141,11 +141,6 @@ NOTICE: BeginTransactionBlock and not in default state Notes - - The keyword TRANSACTION is just a cosmetic alternative to WORK. - Neither keyword need be specified. - - Refer to for further information @@ -190,7 +185,7 @@ BEGIN WORK; BEGIN - is a Postgres language extension. + is a PostgreSQL language extension. There is no explicit BEGIN command in SQL92; transaction initiation is always implicit and it terminates either @@ -204,6 +199,12 @@ BEGIN WORK; + + Incidentally, the BEGIN keyword is used for a different + purpose in embedded SQL. You are advised to be careful about the transaction + semantics when porting database applications. + + SQL92 also requires SERIALIZABLE to be the default transaction isolation level. diff --git a/doc/src/sgml/ref/commit.sgml b/doc/src/sgml/ref/commit.sgml index 03dfea23f5..651e649205 100644 --- a/doc/src/sgml/ref/commit.sgml +++ b/doc/src/sgml/ref/commit.sgml @@ -1,5 +1,5 @@ @@ -62,7 +62,7 @@ COMMIT [ WORK | TRANSACTION ] -END +COMMIT @@ -72,7 +72,7 @@ END -NOTICE EndTransactionBlock and not inprogress/abort state +NOTICE: COMMIT: no transaction in progress @@ -141,7 +141,8 @@ COMMIT WORK; SQL92 - Full compatibility. + SQL92 only specifies the two forms COMMIT + and COMMIT WORK. Otherwise full compatibility. diff --git a/doc/src/sgml/ref/end.sgml b/doc/src/sgml/ref/end.sgml index 0b5f6ce41b..5292b97e97 100644 --- a/doc/src/sgml/ref/end.sgml +++ b/doc/src/sgml/ref/end.sgml @@ -1,5 +1,5 @@ @@ -62,7 +62,7 @@ END [ WORK | TRANSACTION ] -END +COMMIT @@ -72,7 +72,7 @@ END -NOTICE EndTransactionBlock and not inprogress/abort state +NOTICE: COMMIT: no transaction in progress @@ -94,7 +94,7 @@ NOTICE EndTransactionBlock and not inprogress/abort state - END is a Postgres + END is a PostgreSQL synonym for . @@ -144,7 +144,7 @@ END WORK; - END is a Postgres + END is a PostgreSQL extension which provides functionality equivalent to . diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml index 4e3d555480..8f68d7ede4 100644 --- a/doc/src/sgml/ref/psql-ref.sgml +++ b/doc/src/sgml/ref/psql-ref.sgml @@ -1,5 +1,5 @@ @@ -1944,7 +1944,7 @@ testdb=> \set content `sed -e "s/'/\\\\\\'/g" < my_file.txt` %# - If the username is postgres, a + If the current user is a database superuser, then a #, otherwise a >. @@ -2020,10 +2020,9 @@ testdb=> \set content `sed -e "s/'/\\\\\\'/g" < my_file.txt` Before starting up in interactive mode, psql attempts - to read and execute the files /etc/psqlrc and - $HOME/.psqlrc. They could be used to set up the client or - the server to taste (using the \set and SET - commands). + to read and execute commands from the file $HOME/.psqlrc. It + could be used to set up the client or the server to taste (using the \set + and SET commands). @@ -2034,7 +2033,7 @@ testdb=> \set content `sed -e "s/'/\\\\\\'/g" < my_file.txt` psql supports the readline and history libraries for convenienent line editing and retrieval. The command history is stored in a file - named .psqlrc in your home directory and is reloaded when + named .psql_history in your home directory and is reloaded when psql starts up. Tab-completion is also supported, although the completion logic makes no claim to be an SQL parser. @@ -2088,7 +2087,7 @@ $ ./configure --with-includes=/opt/gnu/include --with-libraries=/opt/gnu/lib .. Notice the changing prompt. testdb=> CREATE TABLE my_table ( -testdb-> first int4 not null default 0, +testdb-> first integer not null default 0, testdb-> second text testdb-> ); CREATE @@ -2096,11 +2095,11 @@ CREATE Now look at the table definition again: testdb=> \d my_table - Table "my_table" - Attribute | Type | Info ------------+------+-------------------- - first | int4 | not null default 0 - second | text | + Table "my_table" + Attribute | Type | Modifier +-----------+---------+-------------------- + first | integer | not null default 0 + second | text | At this point you decide to change the prompt to something more diff --git a/doc/src/sgml/ref/rollback.sgml b/doc/src/sgml/ref/rollback.sgml index 17832debd1..dcee1df8bb 100644 --- a/doc/src/sgml/ref/rollback.sgml +++ b/doc/src/sgml/ref/rollback.sgml @@ -1,5 +1,5 @@ @@ -61,8 +61,7 @@ ABORT -NOTICE: UserAbortTransactionBlock and not in in-progress state -ABORT +NOTICE: ROLLBACK: no transaction in progress @@ -95,10 +94,6 @@ ABORT Notes - - The keywords WORK and TRANSACTION are noise and can be omitted. - - Use to successfully terminate a transaction. @@ -134,8 +129,8 @@ ROLLBACK WORK; SQL92 - Full compatibility. The TRANSACTION keyword is a - Postgres extension. + SQL92 only specifies the two forms ROLLBACK + and ROLLBACK WORK. Otherwise full compatibility. diff --git a/doc/src/sgml/ref/update.sgml b/doc/src/sgml/ref/update.sgml index 8808f9e799..7c33e31e37 100644 --- a/doc/src/sgml/ref/update.sgml +++ b/doc/src/sgml/ref/update.sgml @@ -1,5 +1,5 @@ @@ -23,7 +23,7 @@ Postgres documentation 1999-07-20 -UPDATE table SET R">colle> = expression [, ...] +UPDATE table SET col = expression [, ...] [ FROM fromlist ] [ WHERE condition ] diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index 83be164389..58e1744558 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 745eae0832..ef6b66d9c3 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 a90019974e..da0fcd479e 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 228cb73f3a..4059e50f99 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 DROP [COLUMN] {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 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 59497b96a0..66acb230f2 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 52a66507e8..cf54d1925a 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] Location for this database" + echo " [-D, --pgdata] Location for this database" echo " -W, --pwprompt Prompt for a password for the new superuser's" if [ -n "$MULTIBYTE" ] then - echo " -e, --encoding Set the default multibyte encoding for new databases" + echo " -E, --encoding Set the default multibyte encoding for new databases" fi echo " -i, --sysid Database sysid for the superuser" echo "Less commonly used options: " - echo " -L, --pglib Where to find the input files (should happend automatically" + echo " -L, --pglib 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 da5629f850..2cb012a99d 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 a12d311b2e..1441fbc0bc 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 #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,11 +992,41 @@ 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 * diff --git a/src/bin/psql/command.h b/src/bin/psql/command.h index f3a7b4d36a..65431e9c9e 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 @@ -36,6 +36,9 @@ HandleSlashCmds(const char *line, bool process_file(char *filename); +bool +test_superuser(const char * username); + bool do_pset(const char *param, const char *value, diff --git a/src/bin/psql/common.c b/src/bin/psql/common.c index c5a2e78af7..700542cd4d 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 #include "common.h" diff --git a/src/bin/psql/common.h b/src/bin/psql/common.h index 08519f5a40..b4b7d93abe 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 d3a5f79b5c..d2d638c066 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 #include "copy.h" diff --git a/src/bin/psql/copy.h b/src/bin/psql/copy.h index 4710a623eb..8a57e7a66d 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 c5b0d86806..f802d5ed79 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 +# +# Copyright 2000 by PostgreSQL Global Development Group +# +# $Header: /cvsroot/pgsql/src/bin/psql/create_help.pl,v 1.3 2000/01/29 16:58:48 petere Exp $ +################################################################# # -# 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. -# -# 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. +# 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 ca5dcaafb3..bb259b31d3 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 #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; - } + 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); + 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"); + 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; + /* 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)); + 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; + 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; + 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); + 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; - } + 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); - } + 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 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 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); - } + /* 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)); + 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, ","); + /* 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); - } + 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 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, ","); + /* 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); - } + 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, ","); + /* 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); - } + footers[count_footers++] = xstrdup(buf); + } - /* end of list marker */ - footers[count_footers] = NULL; + /* end of list marker */ + footers[count_footers] = NULL; - PQclear(result1); - PQclear(result2); - PQclear(result3); - PQclear(result4); + 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 7c87baa06d..36f4ceca4e 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 ea503fc14f..70100c7791 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 #include "help.h" diff --git a/src/bin/psql/help.h b/src/bin/psql/help.h index 45e02cc2a9..cbd9a81488 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 9aa5628437..2adff9d342 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 #include "input.h" diff --git a/src/bin/psql/input.h b/src/bin/psql/input.h index b8e7082900..6e078cbfbe 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 cdc2c24c06..164956fded 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 #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 26de0e147f..17e1c81d6d 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 8caa8c6c80..0664ddfcaf 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 af1172a21b..3ff0d27c22 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 #include "print.h" diff --git a/src/bin/psql/print.h b/src/bin/psql/print.h index 252236bf33..1098ff8e01 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 f9d6cc098e..a06a712e40 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 #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 9134f8331c..f70a334a54 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 6cfeca79b2..af8171e7da 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 d3169ab84c..d92adce381 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 @@ -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 c8cc603422..5ba48dc454 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 #include "stringutils.h" diff --git a/src/bin/psql/stringutils.h b/src/bin/psql/stringutils.h index 0a109b5639..914871d94e 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 718c1732f0..92112cead0 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 42fa6fe1b0..8c54cffeb6 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 0c559af7e6..b0523dcb67 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 #include "variables.h" diff --git a/src/bin/psql/variables.h b/src/bin/psql/variables.h index d6b5fb7235..2b476dd0c3 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 f34354be41..545c71c08d 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 074c1249d3..ff6acefea8 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 6bf778d5a3..7c0e655f2a 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 +#include -#include "postgres.h" +#include #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 +) { - int count; +#define DEFAULT_FIELD_SEP " " - count = max - length; - while (count-- >= 0) - putc(filler, fp); + 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 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); + } + } +} +#endif diff --git a/src/interfaces/libpq/libpq-fe.h b/src/interfaces/libpq/libpq-fe.h index d8915b11d3..35bbb6eff3 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 */ char *caption; /* HTML
*/ @@ -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 61f1dfd012..2aa6be0ce5 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