summaryrefslogtreecommitdiff
path: root/src/bin/psql
diff options
context:
space:
mode:
authorPeter Eisentraut2011-02-12 13:54:13 +0000
committerPeter Eisentraut2011-02-12 13:55:18 +0000
commitb313bca0afce3ab9dab0a77c64c0982835854b9a (patch)
tree862203ffd9adbc62684bec05fa32b2de4713e6b9 /src/bin/psql
parentd31e2a495b6f2127afc31b4da2e5f4e89aa2cdfe (diff)
DDL support for collations
- collowner field - CREATE COLLATION - ALTER COLLATION - DROP COLLATION - COMMENT ON COLLATION - integration with extensions - pg_dump support for the above - dependency management - psql tab completion - psql \dO command
Diffstat (limited to 'src/bin/psql')
-rw-r--r--src/bin/psql/command.c3
-rw-r--r--src/bin/psql/describe.c62
-rw-r--r--src/bin/psql/describe.h3
-rw-r--r--src/bin/psql/help.c1
-rw-r--r--src/bin/psql/tab-complete.c18
5 files changed, 83 insertions, 4 deletions
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index a80678c2c3f..d1268848d5b 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -425,6 +425,9 @@ exec_command(const char *cmd,
case 'o':
success = describeOperators(pattern, show_system);
break;
+ case 'O':
+ success = listCollations(pattern, show_verbose, show_system);
+ break;
case 'p':
success = permissionsList(pattern);
break;
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 0342eb55bdc..884101aab18 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -627,7 +627,7 @@ listAllDbs(bool verbose)
appendPQExpBuffer(&buf,
" d.datcollate as \"%s\",\n"
" d.datctype as \"%s\",\n",
- gettext_noop("Collation"),
+ gettext_noop("Collate"),
gettext_noop("Ctype"));
appendPQExpBuffer(&buf, " ");
printACLColumn(&buf, "d.datacl");
@@ -2857,6 +2857,66 @@ listCasts(const char *pattern)
}
/*
+ * \dO
+ *
+ * Describes collations
+ */
+bool
+listCollations(const char *pattern, bool verbose, bool showSystem)
+{
+ PQExpBufferData buf;
+ PGresult *res;
+ printQueryOpt myopt = pset.popt;
+ static const bool translate_columns[] = {false, false, false, false, false};
+
+ initPQExpBuffer(&buf);
+
+ printfPQExpBuffer(&buf,
+ "SELECT n.nspname AS \"%s\",\n"
+ " c.collname AS \"%s\",\n"
+ " c.collcollate AS \"%s\",\n"
+ " c.collctype AS \"%s\"",
+ gettext_noop("Schema"),
+ gettext_noop("Name"),
+ gettext_noop("Collate"),
+ gettext_noop("Ctype"));
+
+ if (verbose)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.obj_description(c.oid, 'pg_collation') AS \"%s\"",
+ gettext_noop("Description"));
+
+ appendPQExpBuffer(&buf,
+ "FROM pg_catalog.pg_collation c, pg_catalog.pg_namespace n\n"
+ "WHERE n.oid = c.collnamespace\n");
+
+ if (!showSystem && !pattern)
+ appendPQExpBuffer(&buf, " AND n.nspname <> 'pg_catalog'\n"
+ " AND n.nspname <> 'information_schema'\n");
+
+ processSQLNamePattern(pset.db, &buf, pattern, true, false,
+ "n.nspname", "c.collname", NULL,
+ "pg_catalog.pg_collation_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 collations");
+ myopt.translate_header = true;
+ myopt.translate_columns = translate_columns;
+
+ printQuery(res, &myopt, pset.queryFout, pset.logfile);
+
+ PQclear(res);
+ return true;
+}
+
+/*
* \dn
*
* Describes schemas (namespaces)
diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h
index 4b690b3b707..fb86d1e487d 100644
--- a/src/bin/psql/describe.h
+++ b/src/bin/psql/describe.h
@@ -69,6 +69,9 @@ extern bool listConversions(const char *pattern, bool showSystem);
/* \dC */
extern bool listCasts(const char *pattern);
+/* \dO */
+extern bool listCollations(const char *pattern, bool verbose, bool showSystem);
+
/* \dn */
extern bool listSchemas(const char *pattern, bool verbose, bool showSystem);
diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c
index c44079e0343..ac5edca65dd 100644
--- a/src/bin/psql/help.c
+++ b/src/bin/psql/help.c
@@ -214,6 +214,7 @@ slashUsage(unsigned short int pager)
fprintf(output, _(" \\dL[S+] [PATTERN] list procedural languages\n"));
fprintf(output, _(" \\dn[S+] [PATTERN] list schemas\n"));
fprintf(output, _(" \\do[S] [PATTERN] list operators\n"));
+ fprintf(output, _(" \\dO[S+] [PATTERN] list collations\n"));
fprintf(output, _(" \\dp [PATTERN] list table, view, and sequence access privileges\n"));
fprintf(output, _(" \\drds [PATRN1 [PATRN2]] list per-database role settings\n"));
fprintf(output, _(" \\ds[S+] [PATTERN] list sequences\n"));
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index a31281e431c..119ac1b3768 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -606,6 +606,7 @@ static const pgsql_thing_t words_after_create[] = {
{"AGGREGATE", NULL, &Query_for_list_of_aggregates},
{"CAST", NULL, NULL}, /* Casts have complex structures for names, so
* skip it */
+ {"COLLATION", "SELECT pg_catalog.quote_ident(collname) FROM pg_catalog.pg_collation WHERE collencoding = pg_char_to_encoding(getdatabaseencoding()) AND substring(pg_catalog.quote_ident(collname),1,%d)='%s'"},
/*
* CREATE CONSTRAINT TRIGGER is not supported here because it is designed
@@ -797,7 +798,7 @@ psql_completion(char *text, int start, int end)
pg_strcasecmp(prev3_wd, "TABLE") != 0)
{
static const char *const list_ALTER[] =
- {"AGGREGATE", "CONVERSION", "DATABASE", "DEFAULT PRIVILEGES", "DOMAIN",
+ {"AGGREGATE", "COLLATION", "CONVERSION", "DATABASE", "DEFAULT PRIVILEGES", "DOMAIN",
"EXTENSION", "FOREIGN DATA WRAPPER", "FOREIGN TABLE", "FUNCTION",
"GROUP", "INDEX", "LANGUAGE", "LARGE OBJECT", "OPERATOR",
"ROLE", "SCHEMA", "SERVER", "SEQUENCE", "TABLE",
@@ -843,6 +844,16 @@ psql_completion(char *text, int start, int end)
COMPLETE_WITH_LIST(list_ALTERGEN);
}
+ /* ALTER COLLATION <name> */
+ else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
+ pg_strcasecmp(prev2_wd, "COLLATION") == 0)
+ {
+ static const char *const list_ALTERGEN[] =
+ {"OWNER TO", "RENAME TO", "SET SCHEMA", NULL};
+
+ COMPLETE_WITH_LIST(list_ALTERGEN);
+ }
+
/* ALTER CONVERSION <name> */
else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
pg_strcasecmp(prev2_wd, "CONVERSION") == 0)
@@ -1521,7 +1532,7 @@ psql_completion(char *text, int start, int end)
pg_strcasecmp(prev_wd, "ON") == 0)
{
static const char *const list_COMMENT[] =
- {"CAST", "CONVERSION", "DATABASE", "FOREIGN TABLE", "INDEX", "LANGUAGE", "RULE", "SCHEMA",
+ {"CAST", "COLLATION", "CONVERSION", "DATABASE", "FOREIGN TABLE", "INDEX", "LANGUAGE", "RULE", "SCHEMA",
"SEQUENCE", "TABLE", "TYPE", "VIEW", "COLUMN", "AGGREGATE", "FUNCTION",
"OPERATOR", "TRIGGER", "CONSTRAINT", "DOMAIN", "LARGE OBJECT",
"TABLESPACE", "TEXT SEARCH", "ROLE", NULL};
@@ -1965,7 +1976,8 @@ psql_completion(char *text, int start, int end)
/* DROP object with CASCADE / RESTRICT */
else if ((pg_strcasecmp(prev3_wd, "DROP") == 0 &&
- (pg_strcasecmp(prev2_wd, "CONVERSION") == 0 ||
+ (pg_strcasecmp(prev2_wd, "COLLATION") == 0 ||
+ pg_strcasecmp(prev2_wd, "CONVERSION") == 0 ||
pg_strcasecmp(prev2_wd, "DOMAIN") == 0 ||
pg_strcasecmp(prev2_wd, "EXTENSION") == 0 ||
pg_strcasecmp(prev2_wd, "FUNCTION") == 0 ||