mirror of
https://github.com/postgres/postgres.git
synced 2025-06-10 09:21:54 +03:00
Fix loose ends for SQL ACCESS METHOD objects
COMMENT ON ACCESS METHOD was missing; add it, along psql tab-completion support for it. psql was also missing a way to list existing access methods; the new \dA command does that. Also add tab-completion support for DROP ACCESS METHOD. Author: Michael Paquier Discussion: https://www.postgresql.org/message-id/CAB7nPqTzdZdu8J7EF8SXr_R2U5bSUUYNOT3oAWBZdEoggnwhGA@mail.gmail.com
This commit is contained in:
@ -5,6 +5,7 @@ LANGUAGE C;
|
|||||||
|
|
||||||
-- Access method
|
-- Access method
|
||||||
CREATE ACCESS METHOD bloom TYPE INDEX HANDLER blhandler;
|
CREATE ACCESS METHOD bloom TYPE INDEX HANDLER blhandler;
|
||||||
|
COMMENT ON ACCESS METHOD bloom IS 'bloom index access method';
|
||||||
|
|
||||||
-- Opclasses
|
-- Opclasses
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ PostgreSQL documentation
|
|||||||
<synopsis>
|
<synopsis>
|
||||||
COMMENT ON
|
COMMENT ON
|
||||||
{
|
{
|
||||||
|
ACCESS METHOD <replaceable class="PARAMETER">object_name</replaceable> |
|
||||||
AGGREGATE <replaceable class="PARAMETER">aggregate_name</replaceable> ( <replaceable>aggregate_signature</replaceable> ) |
|
AGGREGATE <replaceable class="PARAMETER">aggregate_name</replaceable> ( <replaceable>aggregate_signature</replaceable> ) |
|
||||||
CAST (<replaceable>source_type</replaceable> AS <replaceable>target_type</replaceable>) |
|
CAST (<replaceable>source_type</replaceable> AS <replaceable>target_type</replaceable>) |
|
||||||
COLLATION <replaceable class="PARAMETER">object_name</replaceable> |
|
COLLATION <replaceable class="PARAMETER">object_name</replaceable> |
|
||||||
@ -89,6 +90,8 @@ COMMENT ON
|
|||||||
Roles don't have owners, so the rule for <literal>COMMENT ON ROLE</> is
|
Roles don't have owners, so the rule for <literal>COMMENT ON ROLE</> is
|
||||||
that you must be superuser to comment on a superuser role, or have the
|
that you must be superuser to comment on a superuser role, or have the
|
||||||
<literal>CREATEROLE</> privilege to comment on non-superuser roles.
|
<literal>CREATEROLE</> privilege to comment on non-superuser roles.
|
||||||
|
Likewise, access methods don't have owners either; you must be superuser
|
||||||
|
to comment on an access method.
|
||||||
Of course, a superuser can comment on anything.
|
Of course, a superuser can comment on anything.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@ -296,6 +299,7 @@ COMMENT ON TABLE mytable IS NULL;
|
|||||||
Some more examples:
|
Some more examples:
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
|
COMMENT ON ACCESS METHOD rtree IS 'R-Tree access method';
|
||||||
COMMENT ON AGGREGATE my_aggregate (double precision) IS 'Computes sample variance';
|
COMMENT ON AGGREGATE my_aggregate (double precision) IS 'Computes sample variance';
|
||||||
COMMENT ON CAST (text AS int4) IS 'Allow casts from text to int4';
|
COMMENT ON CAST (text AS int4) IS 'Allow casts from text to int4';
|
||||||
COMMENT ON COLLATION "fr_CA" IS 'Canadian French';
|
COMMENT ON COLLATION "fr_CA" IS 'Canadian French';
|
||||||
|
@ -1130,6 +1130,19 @@ testdb=>
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>\dA[+] [ <link linkend="APP-PSQL-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Lists access methods. If <replaceable
|
||||||
|
class="parameter">pattern</replaceable> is specified, only access
|
||||||
|
methods whose names match the pattern are shown. If
|
||||||
|
<literal>+</literal> is appended to the command name, each access
|
||||||
|
method is listed with its associated handler function and description.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><literal>\db[+] [ <link linkend="APP-PSQL-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
|
<term><literal>\db[+] [ <link linkend="APP-PSQL-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
|
||||||
|
@ -5693,7 +5693,8 @@ opt_restart_seqs:
|
|||||||
* The COMMENT ON statement can take different forms based upon the type of
|
* The COMMENT ON statement can take different forms based upon the type of
|
||||||
* the object associated with the comment. The form of the statement is:
|
* the object associated with the comment. The form of the statement is:
|
||||||
*
|
*
|
||||||
* COMMENT ON [ [ CONVERSION | COLLATION | DATABASE | DOMAIN |
|
* COMMENT ON [ [ ACCESS METHOD | CONVERSION | COLLATION |
|
||||||
|
* DATABASE | DOMAIN |
|
||||||
* EXTENSION | EVENT TRIGGER | FOREIGN DATA WRAPPER |
|
* EXTENSION | EVENT TRIGGER | FOREIGN DATA WRAPPER |
|
||||||
* FOREIGN TABLE | INDEX | [PROCEDURAL] LANGUAGE |
|
* FOREIGN TABLE | INDEX | [PROCEDURAL] LANGUAGE |
|
||||||
* MATERIALIZED VIEW | POLICY | ROLE | SCHEMA | SEQUENCE |
|
* MATERIALIZED VIEW | POLICY | ROLE | SCHEMA | SEQUENCE |
|
||||||
@ -5713,7 +5714,7 @@ opt_restart_seqs:
|
|||||||
* OPERATOR FAMILY <name> USING <access-method> |
|
* OPERATOR FAMILY <name> USING <access-method> |
|
||||||
* RULE <rulename> ON <relname> |
|
* RULE <rulename> ON <relname> |
|
||||||
* TRIGGER <triggername> ON <relname> ]
|
* TRIGGER <triggername> ON <relname> ]
|
||||||
* IS 'text'
|
* IS { 'text' | NULL }
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
@ -5888,7 +5889,8 @@ CommentStmt:
|
|||||||
;
|
;
|
||||||
|
|
||||||
comment_type:
|
comment_type:
|
||||||
COLUMN { $$ = OBJECT_COLUMN; }
|
ACCESS METHOD { $$ = OBJECT_ACCESS_METHOD; }
|
||||||
|
| COLUMN { $$ = OBJECT_COLUMN; }
|
||||||
| DATABASE { $$ = OBJECT_DATABASE; }
|
| DATABASE { $$ = OBJECT_DATABASE; }
|
||||||
| SCHEMA { $$ = OBJECT_SCHEMA; }
|
| SCHEMA { $$ = OBJECT_SCHEMA; }
|
||||||
| INDEX { $$ = OBJECT_INDEX; }
|
| INDEX { $$ = OBJECT_INDEX; }
|
||||||
|
@ -402,6 +402,9 @@ exec_command(const char *cmd,
|
|||||||
/* standard listing of interesting things */
|
/* standard listing of interesting things */
|
||||||
success = listTables("tvmsE", NULL, show_verbose, show_system);
|
success = listTables("tvmsE", NULL, show_verbose, show_system);
|
||||||
break;
|
break;
|
||||||
|
case 'A':
|
||||||
|
success = describeAccessMethods(pattern, show_verbose);
|
||||||
|
break;
|
||||||
case 'a':
|
case 'a':
|
||||||
success = describeAggregates(pattern, show_verbose, show_system);
|
success = describeAggregates(pattern, show_verbose, show_system);
|
||||||
break;
|
break;
|
||||||
|
@ -129,6 +129,70 @@ describeAggregates(const char *pattern, bool verbose, bool showSystem)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* \dA
|
||||||
|
* Takes an optional regexp to select particular access methods
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
describeAccessMethods(const char *pattern, bool verbose)
|
||||||
|
{
|
||||||
|
PQExpBufferData buf;
|
||||||
|
PGresult *res;
|
||||||
|
printQueryOpt myopt = pset.popt;
|
||||||
|
static const bool translate_columns[] = {false, true, false};
|
||||||
|
|
||||||
|
if (pset.sversion < 90600)
|
||||||
|
{
|
||||||
|
psql_error("The server (version %d.%d) does not support access methods.\n",
|
||||||
|
pset.sversion / 10000, (pset.sversion / 100) % 100);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
initPQExpBuffer(&buf);
|
||||||
|
|
||||||
|
printfPQExpBuffer(&buf,
|
||||||
|
"SELECT amname AS \"%s\",\n"
|
||||||
|
" CASE amtype"
|
||||||
|
" WHEN 'i' THEN '%s'"
|
||||||
|
" END AS \"%s\"",
|
||||||
|
gettext_noop("Name"),
|
||||||
|
gettext_noop("Index"),
|
||||||
|
gettext_noop("Type"));
|
||||||
|
|
||||||
|
if (verbose)
|
||||||
|
{
|
||||||
|
appendPQExpBuffer(&buf,
|
||||||
|
",\n amhandler AS \"%s\",\n"
|
||||||
|
" pg_catalog.obj_description(oid, 'pg_am') AS \"%s\"",
|
||||||
|
gettext_noop("Handler"),
|
||||||
|
gettext_noop("Description"));
|
||||||
|
}
|
||||||
|
|
||||||
|
appendPQExpBufferStr(&buf,
|
||||||
|
"\nFROM pg_catalog.pg_am\n");
|
||||||
|
|
||||||
|
processSQLNamePattern(pset.db, &buf, pattern, false, false,
|
||||||
|
NULL, "amname", NULL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
appendPQExpBufferStr(&buf, "ORDER BY 1;");
|
||||||
|
|
||||||
|
res = PSQLexec(buf.data);
|
||||||
|
termPQExpBuffer(&buf);
|
||||||
|
if (!res)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
myopt.nullPrint = NULL;
|
||||||
|
myopt.title = _("List of access methods");
|
||||||
|
myopt.translate_header = true;
|
||||||
|
myopt.translate_columns = translate_columns;
|
||||||
|
myopt.n_translate_columns = lengthof(translate_columns);
|
||||||
|
|
||||||
|
printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
|
||||||
|
|
||||||
|
PQclear(res);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* \db
|
/* \db
|
||||||
* Takes an optional regexp to select particular tablespaces
|
* Takes an optional regexp to select particular tablespaces
|
||||||
*/
|
*/
|
||||||
|
@ -12,6 +12,9 @@
|
|||||||
/* \da */
|
/* \da */
|
||||||
extern bool describeAggregates(const char *pattern, bool verbose, bool showSystem);
|
extern bool describeAggregates(const char *pattern, bool verbose, bool showSystem);
|
||||||
|
|
||||||
|
/* \dA */
|
||||||
|
extern bool describeAccessMethods(const char *pattern, bool verbose);
|
||||||
|
|
||||||
/* \db */
|
/* \db */
|
||||||
extern bool describeTablespaces(const char *pattern, bool verbose);
|
extern bool describeTablespaces(const char *pattern, bool verbose);
|
||||||
|
|
||||||
|
@ -215,6 +215,7 @@ slashUsage(unsigned short int pager)
|
|||||||
fprintf(output, _(" \\d[S+] list tables, views, and sequences\n"));
|
fprintf(output, _(" \\d[S+] list tables, views, and sequences\n"));
|
||||||
fprintf(output, _(" \\d[S+] NAME describe table, view, sequence, or index\n"));
|
fprintf(output, _(" \\d[S+] NAME describe table, view, sequence, or index\n"));
|
||||||
fprintf(output, _(" \\da[S] [PATTERN] list aggregates\n"));
|
fprintf(output, _(" \\da[S] [PATTERN] list aggregates\n"));
|
||||||
|
fprintf(output, _(" \\dA[+] [PATTERN] list access methods\n"));
|
||||||
fprintf(output, _(" \\db[+] [PATTERN] list tablespaces\n"));
|
fprintf(output, _(" \\db[+] [PATTERN] list tablespaces\n"));
|
||||||
fprintf(output, _(" \\dc[S+] [PATTERN] list conversions\n"));
|
fprintf(output, _(" \\dc[S+] [PATTERN] list conversions\n"));
|
||||||
fprintf(output, _(" \\dC[+] [PATTERN] list casts\n"));
|
fprintf(output, _(" \\dC[+] [PATTERN] list casts\n"));
|
||||||
|
@ -1276,7 +1276,7 @@ psql_completion(const char *text, int start, int end)
|
|||||||
static const char *const backslash_commands[] = {
|
static const char *const backslash_commands[] = {
|
||||||
"\\a", "\\connect", "\\conninfo", "\\C", "\\cd", "\\copy",
|
"\\a", "\\connect", "\\conninfo", "\\C", "\\cd", "\\copy",
|
||||||
"\\copyright", "\\crosstabview",
|
"\\copyright", "\\crosstabview",
|
||||||
"\\d", "\\da", "\\db", "\\dc", "\\dC", "\\dd", "\\ddp", "\\dD",
|
"\\d", "\\da", "\\dA", "\\db", "\\dc", "\\dC", "\\dd", "\\ddp", "\\dD",
|
||||||
"\\des", "\\det", "\\deu", "\\dew", "\\dE", "\\df",
|
"\\des", "\\det", "\\deu", "\\dew", "\\dE", "\\df",
|
||||||
"\\dF", "\\dFd", "\\dFp", "\\dFt", "\\dg", "\\di", "\\dl", "\\dL",
|
"\\dF", "\\dFd", "\\dFp", "\\dFt", "\\dg", "\\di", "\\dl", "\\dL",
|
||||||
"\\dm", "\\dn", "\\do", "\\dO", "\\dp", "\\drds", "\\ds", "\\dS",
|
"\\dm", "\\dn", "\\do", "\\dO", "\\dp", "\\drds", "\\ds", "\\dS",
|
||||||
@ -1910,7 +1910,8 @@ psql_completion(const char *text, int start, int end)
|
|||||||
else if (Matches2("COMMENT", "ON"))
|
else if (Matches2("COMMENT", "ON"))
|
||||||
{
|
{
|
||||||
static const char *const list_COMMENT[] =
|
static const char *const list_COMMENT[] =
|
||||||
{"CAST", "COLLATION", "CONVERSION", "DATABASE", "EVENT TRIGGER", "EXTENSION",
|
{"ACCESS METHOD", "CAST", "COLLATION", "CONVERSION", "DATABASE",
|
||||||
|
"EVENT TRIGGER", "EXTENSION",
|
||||||
"FOREIGN DATA WRAPPER", "FOREIGN TABLE",
|
"FOREIGN DATA WRAPPER", "FOREIGN TABLE",
|
||||||
"SERVER", "INDEX", "LANGUAGE", "POLICY", "RULE", "SCHEMA", "SEQUENCE",
|
"SERVER", "INDEX", "LANGUAGE", "POLICY", "RULE", "SCHEMA", "SEQUENCE",
|
||||||
"TABLE", "TYPE", "VIEW", "MATERIALIZED VIEW", "COLUMN", "AGGREGATE", "FUNCTION",
|
"TABLE", "TYPE", "VIEW", "MATERIALIZED VIEW", "COLUMN", "AGGREGATE", "FUNCTION",
|
||||||
@ -1919,6 +1920,8 @@ psql_completion(const char *text, int start, int end)
|
|||||||
|
|
||||||
COMPLETE_WITH_LIST(list_COMMENT);
|
COMPLETE_WITH_LIST(list_COMMENT);
|
||||||
}
|
}
|
||||||
|
else if (Matches4("COMMENT", "ON", "ACCESS", "METHOD"))
|
||||||
|
COMPLETE_WITH_QUERY(Query_for_list_of_access_methods);
|
||||||
else if (Matches3("COMMENT", "ON", "FOREIGN"))
|
else if (Matches3("COMMENT", "ON", "FOREIGN"))
|
||||||
COMPLETE_WITH_LIST2("DATA WRAPPER", "TABLE");
|
COMPLETE_WITH_LIST2("DATA WRAPPER", "TABLE");
|
||||||
else if (Matches4("COMMENT", "ON", "TEXT", "SEARCH"))
|
else if (Matches4("COMMENT", "ON", "TEXT", "SEARCH"))
|
||||||
@ -2331,6 +2334,12 @@ psql_completion(const char *text, int start, int end)
|
|||||||
else if (Matches5("DROP", "TRIGGER", MatchAny, "ON", MatchAny))
|
else if (Matches5("DROP", "TRIGGER", MatchAny, "ON", MatchAny))
|
||||||
COMPLETE_WITH_LIST2("CASCADE", "RESTRICT");
|
COMPLETE_WITH_LIST2("CASCADE", "RESTRICT");
|
||||||
|
|
||||||
|
/* DROP ACCESS METHOD */
|
||||||
|
else if (Matches2("DROP", "ACCESS"))
|
||||||
|
COMPLETE_WITH_CONST("METHOD");
|
||||||
|
else if (Matches3("DROP", "ACCESS", "METHOD"))
|
||||||
|
COMPLETE_WITH_QUERY(Query_for_list_of_access_methods);
|
||||||
|
|
||||||
/* DROP EVENT TRIGGER */
|
/* DROP EVENT TRIGGER */
|
||||||
else if (Matches2("DROP", "EVENT"))
|
else if (Matches2("DROP", "EVENT"))
|
||||||
COMPLETE_WITH_CONST("TRIGGER");
|
COMPLETE_WITH_CONST("TRIGGER");
|
||||||
@ -2931,6 +2940,8 @@ psql_completion(const char *text, int start, int end)
|
|||||||
}
|
}
|
||||||
else if (TailMatchesCS1("\\da*"))
|
else if (TailMatchesCS1("\\da*"))
|
||||||
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_aggregates, NULL);
|
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_aggregates, NULL);
|
||||||
|
else if (TailMatchesCS1("\\dA*"))
|
||||||
|
COMPLETE_WITH_QUERY(Query_for_list_of_access_methods);
|
||||||
else if (TailMatchesCS1("\\db*"))
|
else if (TailMatchesCS1("\\db*"))
|
||||||
COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces);
|
COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces);
|
||||||
else if (TailMatchesCS1("\\dD*"))
|
else if (TailMatchesCS1("\\dD*"))
|
||||||
|
Reference in New Issue
Block a user