diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml index bb8d8f5eb4..66a92802ba 100644 --- a/doc/src/sgml/ref/psql-ref.sgml +++ b/doc/src/sgml/ref/psql-ref.sgml @@ -1,5 +1,5 @@ @@ -851,6 +851,29 @@ testdb=> + + \dc [ pattern ] + + + Lists all available conversions (between encodings). If pattern + is specified, only matching conversions are shown. + + + + + + + \dC + + + Lists all available type casts. Casts can be explicit, explicit and assignment + or implicit, and are used to change a variable from one type to another. + + + + + \df [ pattern ] diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c index e7fd1c1e5c..fa0d20af30 100644 --- a/src/backend/catalog/namespace.c +++ b/src/backend/catalog/namespace.c @@ -13,7 +13,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.41 2002/12/04 05:18:31 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.42 2002/12/12 21:02:19 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -143,7 +143,7 @@ Datum pg_type_is_visible(PG_FUNCTION_ARGS); Datum pg_function_is_visible(PG_FUNCTION_ARGS); Datum pg_operator_is_visible(PG_FUNCTION_ARGS); Datum pg_opclass_is_visible(PG_FUNCTION_ARGS); - +Datum pg_conversion_is_visible(PG_FUNCTION_ARGS); /* * RangeVarGetRelid @@ -1035,6 +1035,87 @@ OpclassIsVisible(Oid opcid) return visible; } +/* + * ConversionGetConid + * Try to resolve an unqualified conversion name. + * Returns OID if conversion found in search path, else InvalidOid. + * + * This is essentially the same as RelnameGetRelid. + */ +Oid +ConversionGetConid(const char *conname) +{ + Oid conid; + List *lptr; + + recomputeNamespacePath(); + + foreach(lptr, namespaceSearchPath) + { + Oid namespaceId = (Oid) lfirsti(lptr); + + conid = GetSysCacheOid(CONNAMENSP, + PointerGetDatum(conname), + ObjectIdGetDatum(namespaceId), + 0, 0); + if (OidIsValid(conid)) + return conid; + } + + /* Not found in path */ + return InvalidOid; +} + +/* + * ConversionIsVisible + * Determine whether a conversion (identified by OID) is visible in the + * current search path. Visible means "would be found by searching + * for the unqualified conversion name". + */ +bool +ConversionIsVisible(Oid conid) +{ + HeapTuple contup; + Form_pg_conversion conform; + Oid connamespace; + bool visible; + + contup = SearchSysCache(CONOID, + ObjectIdGetDatum(conid), + 0, 0, 0); + if (!HeapTupleIsValid(contup)) + elog(ERROR, "Cache lookup failed for converions %u", conid); + conform = (Form_pg_conversion) GETSTRUCT(contup); + + recomputeNamespacePath(); + + /* + * Quick check: if it ain't in the path at all, it ain't visible. + * Items in the system namespace are surely in the path and so we + * needn't even do intMember() for them. + */ + connamespace = conform->connamespace; + if (connamespace != PG_CATALOG_NAMESPACE && + !intMember(connamespace, namespaceSearchPath)) + visible = false; + else + { + /* + * If it is in the path, it might still not be visible; it could + * be hidden by another conversion of the same name earlier in the + * path. So we must do a slow check to see if this conversion would + * be found by ConvnameGetConid. + */ + char *conname = NameStr(conform->conname); + + visible = (ConversionGetConid(conname) == conid); + } + + ReleaseSysCache(contup); + + return visible; +} + /* * DeconstructQualifiedName * Given a possibly-qualified name expressed as a list of String nodes, @@ -1854,3 +1935,11 @@ pg_opclass_is_visible(PG_FUNCTION_ARGS) PG_RETURN_BOOL(OpclassIsVisible(oid)); } + +Datum +pg_conversion_is_visible(PG_FUNCTION_ARGS) +{ + Oid oid = PG_GETARG_OID(0); + + PG_RETURN_BOOL(ConversionIsVisible(oid)); +} diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index bfe5b45e1e..06d3159856 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -3,7 +3,7 @@ * * Copyright 2000-2002 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/command.c,v 1.85 2002/11/08 19:12:21 momjian Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/command.c,v 1.86 2002/12/12 21:02:21 momjian Exp $ */ #include "postgres_fe.h" #include "command.h" @@ -381,7 +381,13 @@ exec_command(const char *cmd, case 'D': success = listDomains(pattern); break; - + case 'c': + success = listConversions(pattern); + break; + case 'C': + success = listCasts(pattern); + break; + default: status = CMD_UNKNOWN; } diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c index dae66b22d0..f5a2c895ee 100644 --- a/src/bin/psql/describe.c +++ b/src/bin/psql/describe.c @@ -3,7 +3,7 @@ * * Copyright 2000-2002 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/describe.c,v 1.71 2002/10/19 20:50:44 tgl Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/describe.c,v 1.72 2002/12/12 21:02:24 momjian Exp $ */ #include "postgres_fe.h" #include "describe.h" @@ -1389,6 +1389,106 @@ listDomains(const char *pattern) return true; } +/* + * \dc + * + * Describes conversions. + */ +bool +listConversions(const char *pattern) +{ + PQExpBufferData buf; + PGresult *res; + printQueryOpt myopt = pset.popt; + + initPQExpBuffer(&buf); + + printfPQExpBuffer(&buf, + "SELECT n.nspname AS \"%s\",\n" + " c.conname AS \"%s\",\n" + " pg_catalog.pg_encoding_to_char(c.conforencoding) AS \"%s\",\n" + " pg_catalog.pg_encoding_to_char(c.contoencoding) AS \"%s\",\n" + " CASE WHEN c.condefault THEN '%s'\n" + " ELSE NULL END AS \"%s\"\n" + "FROM pg_catalog.pg_conversion c, pg_catalog.pg_namespace n\n" + "WHERE n.oid = c.connamespace\n", + _("Schema"), + _("Name"), + _("Source"), + _("Dest"), + _("default"), + _("Modifier")); + + processNamePattern(&buf, pattern, true, false, + "n.nspname", "c.conname", NULL, + "pg_catalog.pg_conversion_is_visible(c.oid)"); + + appendPQExpBuffer(&buf, "ORDER BY 1, 2;"); + + res = PSQLexec(buf.data, false); + termPQExpBuffer(&buf); + if (!res) + return false; + + myopt.nullPrint = NULL; + myopt.title = _("List of conversions"); + + printQuery(res, &myopt, pset.queryFout); + + PQclear(res); + return true; +} + +/* + * \dC + * + * Describes casts. + */ +bool +listCasts(const char *pattern) +{ + PQExpBufferData buf; + PGresult *res; + printQueryOpt myopt = pset.popt; + + initPQExpBuffer(&buf); +/* NEED LEFT JOIN FOR BINARY CASTS */ + printfPQExpBuffer(&buf, + "SELECT t1.typname AS \"%s\",\n" + " t2.typname AS \"%s\",\n" + " CASE WHEN p.proname IS NULL THEN '%s'\n" + " ELSE p.proname\n" + " END as \"%s\",\n" + " CASE WHEN c.castcontext = 'e' THEN '%s'\n" + " WHEN c.castcontext = 'a' THEN '%s'\n" + " ELSE '%s'\n" + " END as \"%s\"\n" + "FROM pg_catalog.pg_cast c LEFT JOIN pg_catalog.pg_proc p\n" + " ON c.castfunc=p.oid, pg_catalog.pg_type t1, pg_catalog.pg_type t2\n" + "WHERE c.castsource=t1.oid AND c.casttarget=t2.oid ORDER BY 1, 2", + _("Source"), + _("Target"), + _("BINARY"), + _("Function"), + _("explicit"), + _("assignment explicit"), + _("implicit"), + _("Context")); + + res = PSQLexec(buf.data, false); + termPQExpBuffer(&buf); + if (!res) + return false; + + myopt.nullPrint = NULL; + myopt.title = _("List of casts"); + + printQuery(res, &myopt, pset.queryFout); + + PQclear(res); + return true; +} + /* * processNamePattern * diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h index 0c22cafcbc..6461b41d30 100644 --- a/src/bin/psql/describe.h +++ b/src/bin/psql/describe.h @@ -3,7 +3,7 @@ * * Copyright 2000-2002 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/describe.h,v 1.18 2002/08/27 18:28:29 momjian Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/describe.h,v 1.19 2002/12/12 21:02:24 momjian Exp $ */ #ifndef DESCRIBE_H #define DESCRIBE_H @@ -43,4 +43,11 @@ bool listTables(const char *tabtypes, const char *pattern, bool verbose); /* \dD */ bool listDomains(const char *pattern); +/* \dc */ +bool listConversions(const char *pattern); + +/* \dC */ +bool listCasts(const char *pattern); + + #endif /* DESCRIBE_H */ diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c index e99f6f1720..ecbc286170 100644 --- a/src/bin/psql/help.c +++ b/src/bin/psql/help.c @@ -3,7 +3,7 @@ * * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/help.c,v 1.66 2002/12/11 23:07:06 momjian Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/help.c,v 1.67 2002/12/12 21:02:24 momjian Exp $ */ #include "postgres_fe.h" #include "common.h" @@ -206,6 +206,8 @@ slashUsage(unsigned short int pager) fprintf(output, _(" \\d{t|i|s|v|S} [PATTERN] (add \"+\" for more detail)\n" " list tables/indexes/sequences/views/system tables\n")); fprintf(output, _(" \\da [PATTERN] list aggregate functions\n")); + fprintf(output, _(" \\dc [PATTERN] list conversions\n")); + fprintf(output, _(" \\dC list casts\n")); fprintf(output, _(" \\dd [PATTERN] show comment for object\n")); fprintf(output, _(" \\dD [PATTERN] list domains\n")); fprintf(output, _(" \\df [PATTERN] list functions (add \"+\" for more detail)\n")); diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index fa31318733..710b5c71ac 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -37,7 +37,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: catversion.h,v 1.169 2002/12/12 15:49:40 tgl Exp $ + * $Id: catversion.h,v 1.170 2002/12/12 21:02:25 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 200212101 +#define CATALOG_VERSION_NO 200212121 #endif diff --git a/src/include/catalog/namespace.h b/src/include/catalog/namespace.h index 793a84b7c6..27e3e75168 100644 --- a/src/include/catalog/namespace.h +++ b/src/include/catalog/namespace.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: namespace.h,v 1.22 2002/11/02 18:41:22 tgl Exp $ + * $Id: namespace.h,v 1.23 2002/12/12 21:02:25 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -65,6 +65,8 @@ extern bool OperatorIsVisible(Oid oprid); extern OpclassCandidateList OpclassGetCandidates(Oid amid); extern Oid OpclassnameGetOpcid(Oid amid, const char *opcname); extern bool OpclassIsVisible(Oid opcid); +extern bool ConversionIsVisible(Oid opcid); +extern Oid ConversionGetConid(const char *conname); extern void DeconstructQualifiedName(List *names, char **nspname_p, diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index 348646c549..7558206a65 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: pg_proc.h,v 1.279 2002/12/06 05:20:26 momjian Exp $ + * $Id: pg_proc.h,v 1.280 2002/12/12 21:02:25 momjian Exp $ * * NOTES * The script catalog/genbki.sh reads this file and generates .bki @@ -2930,6 +2930,8 @@ DATA(insert OID = 2082 ( pg_operator_is_visible PGNSP PGUID 12 f f t f s 1 16 " DESCR("is operator visible in search path?"); DATA(insert OID = 2083 ( pg_opclass_is_visible PGNSP PGUID 12 f f t f s 1 16 "26" pg_opclass_is_visible - _null_ )); DESCR("is opclass visible in search path?"); +DATA(insert OID = 2093 ( pg_conversion_is_visible PGNSP PGUID 12 f f t f s 1 16 "26" pg_conversion_is_visible - _null_ )); +DESCR("is conversion visible in search path?"); /* Aggregates (moved here from pg_aggregate for 7.3) */