diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml index 20ba105160..67ecec27cf 100644 --- a/doc/src/sgml/ref/psql-ref.sgml +++ b/doc/src/sgml/ref/psql-ref.sgml @@ -1231,6 +1231,97 @@ testdb=> + + + \dAc[+] + [access-method-pattern + [input-type-pattern]] + + + + + Lists operator classes + (see ). + If access-method-patttern + is specified, only operator classes associated with access methods whose + names match pattern are listed. + If input-type-pattern + is specified, only operator classes associated with input types whose + names match the pattern are listed. + If + is appended to the command name, each operator + class is listed with its associated operator family and owner. + + + + + + + \dAf[+] + [access-method-pattern + [input-type-pattern]] + + + + + Lists operator families + (see ). + If access-method-patttern + is specified, only operator families associated with access methods whose + names match pattern are listed. + If input-type-pattern + is specified, only operator families associated with input types whose + names match the pattern are listed. + If + is appended to the command name, each operator + family is listed with its owner. + + + + + + + \dAo[+] + [access-method-pattern + [operator-family-pattern]] + + + + + + Lists operators associated with operator families + (). + If access-method-patttern + is specified, only members of operator families associated with access + methods whose names match pattern are listed. + If input-type-pattern + is specified, only memeber of operator families whose names match the + pattern are listed. + If + is appended to the command name, each operator + is listed with its strategy number, purpose and sort operator family. + + + + + + + \dAp[+] + [access-method-pattern + [operator-family-pattern]] + + + + + Lists procedures associated with operator families + (). + If access-method-patttern + is specified, only members of operator families associated with access + methods whose names match pattern are listed. + If input-type-pattern + is specified, only memeber of operator families whose names match the + pattern are listed. + + + + \db[+] [ pattern ] diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index e111cee556..abb18a19c2 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -721,7 +721,38 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd) success = listTables("tvmsE", NULL, show_verbose, show_system); break; case 'A': - success = describeAccessMethods(pattern, show_verbose); + { + char *pattern2 = NULL; + + if (pattern && cmd[2] != '\0' && cmd[2] != '+') + pattern2 = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, true); + + switch (cmd[2]) + { + case '\0': + case '+': + success = describeAccessMethods(pattern, show_verbose); + break; + case 'c': + success = listOperatorClasses(pattern, pattern2, show_verbose); + break; + case 'f': + success = listOperatorFamilies(pattern, pattern2, show_verbose); + break; + case 'o': + success = listOpFamilyOperators(pattern, pattern2, show_verbose); + break; + case 'p': + success = listOpFamilyProcedures(pattern, pattern2); + break; + default: + status = PSQL_CMD_UNKNOWN; + break; + } + + if (pattern2) + free(pattern2); + } break; case 'a': success = describeAggregates(pattern, show_verbose, show_system); diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c index f3c7eb96fa..109245fea7 100644 --- a/src/bin/psql/describe.c +++ b/src/bin/psql/describe.c @@ -14,6 +14,7 @@ #include +#include "catalog/pg_am.h" #include "catalog/pg_attribute_d.h" #include "catalog/pg_cast_d.h" #include "catalog/pg_class_d.h" @@ -6015,3 +6016,337 @@ printACLColumn(PQExpBuffer buf, const char *colname) "pg_catalog.array_to_string(%s, '\\n') AS \"%s\"", colname, gettext_noop("Access privileges")); } + +/* + * \dAc + * Lists operator classes + * + * Takes an optional regexps to filter by index access method and type. + */ +bool +listOperatorClasses(const char *access_method_pattern, + const char *type_pattern, bool verbose) +{ + PQExpBufferData buf; + PGresult *res; + printQueryOpt myopt = pset.popt; + bool have_where = false; + static const bool translate_columns[] = {false, false, false, false, false, + false, false, false}; + + initPQExpBuffer(&buf); + + printfPQExpBuffer(&buf, + "SELECT DISTINCT" + " am.amname AS \"%s\",\n" + " c.opcintype::pg_catalog.regtype AS \"%s\",\n" + " (CASE WHEN c.opckeytype <> 0 AND c.opckeytype <> c.opcintype\n" + " THEN c.opckeytype\n" + " ELSE NULL -- c.opcintype\n" + " END)::pg_catalog.regtype AS \"%s\",\n" + " CASE\n" + " WHEN pg_catalog.pg_opclass_is_visible(c.oid)\n" + " THEN format('%%I', c.opcname)\n" + " ELSE format('%%I.%%I', n.nspname, c.opcname)\n" + " END AS \"%s\",\n" + " (CASE WHEN c.opcdefault\n" + " THEN '%s'\n" + " ELSE '%s'\n" + " END) AS \"%s\"", + gettext_noop("AM"), + gettext_noop("Input type"), + gettext_noop("Storage type"), + gettext_noop("Operator class"), + gettext_noop("yes"), + gettext_noop("no"), + gettext_noop("Default?")); + if (verbose) + appendPQExpBuffer(&buf, + ",\n CASE\n" + " WHEN pg_catalog.pg_opfamily_is_visible(of.oid)\n" + " THEN format('%%I', of.opfname)\n" + " ELSE format('%%I.%%I', ofn.nspname, of.opfname)\n" + " END AS \"%s\",\n" + " pg_catalog.pg_get_userbyid(c.opcowner) AS \"%s\"\n", + gettext_noop("Operator family"), + gettext_noop("Owner")); + appendPQExpBuffer(&buf, + "\nFROM pg_catalog.pg_opclass c\n" + " LEFT JOIN pg_catalog.pg_am am on am.oid = c.opcmethod\n" + " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.opcnamespace\n" + " LEFT JOIN pg_catalog.pg_type t1 ON t1.oid = c.opcintype\n" + ); + if (verbose) + appendPQExpBuffer(&buf, + " LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = c.opcfamily\n" + " LEFT JOIN pg_catalog.pg_namespace ofn ON ofn.oid = of.opfnamespace\n"); + + if (access_method_pattern) + have_where = processSQLNamePattern(pset.db, &buf, access_method_pattern, + false, false, NULL, "am.amname", NULL, NULL); + if (type_pattern) + processSQLNamePattern(pset.db, &buf, type_pattern, have_where, false, + NULL, "t1.typname", NULL, NULL); + + appendPQExpBufferStr(&buf, "ORDER BY 1, 2, 4;"); + res = PSQLexec(buf.data); + termPQExpBuffer(&buf); + if (!res) + return false; + + myopt.nullPrint = NULL; + myopt.title = _("List of operator classes"); + 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; +} + +/* + * \dAf + * Lists operator families + * + * Takes an optional regexps to filter by index access method and type. + */ +bool +listOperatorFamilies(const char *access_method_pattern, + const char *type_pattern, bool verbose) +{ + PQExpBufferData buf; + PGresult *res; + printQueryOpt myopt = pset.popt; + bool have_where = false; + static const bool translate_columns[] = {false, false, false, false, false, + false, false, false}; + + initPQExpBuffer(&buf); + + printfPQExpBuffer(&buf, + "SELECT DISTINCT" + " am.amname AS \"%s\",\n" + " CASE\n" + " WHEN pg_catalog.pg_opfamily_is_visible(f.oid)\n" + " THEN format('%%I', f.opfname)\n" + " ELSE format('%%I.%%I', n.nspname, f.opfname)\n" + " END AS \"%s\",\n" + " (SELECT\n" + " string_agg(format_type(oc.opcintype, -1), ', ')\n" + " FROM pg_opclass oc\n" + " WHERE oc.opcfamily = f.oid) \"%s\"", + gettext_noop("AM"), + gettext_noop("Operator family"), + gettext_noop("Applicable types")); + if (verbose) + appendPQExpBuffer(&buf, + ",\n pg_catalog.pg_get_userbyid(f.opfowner) AS \"%s\"\n", + gettext_noop("Owner")); + appendPQExpBuffer(&buf, + "\nFROM pg_catalog.pg_opfamily f\n" + " LEFT JOIN pg_catalog.pg_am am on am.oid = f.opfmethod\n" + " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = f.opfnamespace\n" + ); + + if (access_method_pattern) + have_where = processSQLNamePattern(pset.db, &buf, access_method_pattern, + false, false, NULL, "am.amname", NULL, NULL); + if (type_pattern) + { + appendPQExpBuffer(&buf, + "\n %s EXISTS (\n" + " SELECT 1\n" + " FROM pg_type t\n" + " JOIN pg_opclass oc ON oc.opcintype = t.oid\n" + " WHERE oc.opcfamily = f.oid", + have_where ? "AND" : "WHERE"); + processSQLNamePattern(pset.db, &buf, type_pattern, true, false, + NULL, "t.typname", NULL, NULL); + appendPQExpBuffer(&buf, ")"); + } + + appendPQExpBufferStr(&buf, "ORDER BY 1, 2;"); + res = PSQLexec(buf.data); + termPQExpBuffer(&buf); + if (!res) + return false; + + myopt.nullPrint = NULL; + myopt.title = _("List of operator families"); + 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; +} + +/* + * \dAo + * Lists operators of operator families + * + * Takes an optional regexps to filter by index access method and operator + * family. + */ +bool +listOpFamilyOperators(const char *access_method_pattern, + const char *family_pattern, bool verbose) +{ + PQExpBufferData buf; + PGresult *res; + printQueryOpt myopt = pset.popt; + bool have_where = false; + + static const bool translate_columns[] = {false, false, false, false, false, + false, false, true, false}; + + initPQExpBuffer(&buf); + + printfPQExpBuffer(&buf, + "SELECT\n" + " am.amname AS \"%s\",\n" + " CASE\n" + " WHEN pg_catalog.pg_opfamily_is_visible(of.oid)\n" + " THEN format('%%I', of.opfname)\n" + " ELSE format('%%I.%%I', nsf.nspname, of.opfname)\n" + " END AS \"%s\",\n" + " format ('%%s (%%s, %%s)',\n" + " CASE\n" + " WHEN pg_catalog.pg_operator_is_visible(op.oid) \n" + " THEN op.oprname::pg_catalog.text \n" + " ELSE o.amopopr::pg_catalog.regoper::pg_catalog.text \n" + " END,\n" + " pg_catalog.format_type(o.amoplefttype, NULL),\n" + " pg_catalog.format_type(o.amoprighttype, NULL)\n" + " ) AS \"%s\"\n", + gettext_noop("AM"), + gettext_noop("Opfamily Name"), + gettext_noop("Operator")); + + if (verbose) + appendPQExpBuffer(&buf, + ", o.amopstrategy AS \"%s\",\n" + " CASE o.amoppurpose\n" + " WHEN 'o' THEN '%s'\n" + " WHEN 's' THEN '%s'\n" + " END AS \"%s\",\n" + " ofs.opfname AS \"%s\"\n", + gettext_noop("Strategy"), + gettext_noop("ordering"), + gettext_noop("search"), + gettext_noop("Purpose"), + gettext_noop("Sort opfamily")); + appendPQExpBuffer(&buf, + "FROM pg_catalog.pg_amop o\n" + " LEFT JOIN pg_catalog.pg_operator op ON op.oid = o.amopopr\n" + " LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = o.amopfamily\n" + " LEFT JOIN pg_catalog.pg_am am ON am.oid = of.opfmethod AND am.oid = o.amopmethod\n" + " LEFT JOIN pg_catalog.pg_namespace nsf ON of.opfnamespace = nsf.oid\n"); + if (verbose) + appendPQExpBuffer(&buf, + " LEFT JOIN pg_catalog.pg_opfamily ofs ON ofs.oid = o.amopsortfamily\n"); + + if (access_method_pattern) + have_where = processSQLNamePattern(pset.db, &buf, access_method_pattern, + false, false, NULL, "am.amname", + NULL, NULL); + + if (family_pattern) + processSQLNamePattern(pset.db, &buf, family_pattern, have_where, false, + "nsf.nspname", "of.opfname", NULL, NULL); + + appendPQExpBufferStr(&buf, "ORDER BY 1, 2, o.amopstrategy, 3;"); + + res = PSQLexec(buf.data); + termPQExpBuffer(&buf); + if (!res) + return false; + + myopt.nullPrint = NULL; + myopt.title = _("List of operators of operator families"); + 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; +} + +/* + * \dAp + * Lists procedures of operator families + * + * Takes an optional regexps to filter by index access method and operator + * family. + */ +bool +listOpFamilyProcedures(const char *access_method_pattern, + const char *family_pattern) +{ + PQExpBufferData buf; + PGresult *res; + printQueryOpt myopt = pset.popt; + bool have_where = false; + static const bool translate_columns[] = {false, false, false, false, false, false, false}; + + initPQExpBuffer(&buf); + + printfPQExpBuffer(&buf, + "SELECT DISTINCT\n" + " am.amname AS \"%s\",\n" + " CASE\n" + " WHEN pg_catalog.pg_opfamily_is_visible(of.oid)\n" + " THEN format('%%I', of.opfname)\n" + " ELSE format('%%I.%%I', ns.nspname, of.opfname)\n" + " END AS \"%s\",\n" + " pg_catalog.format_type(ap.amproclefttype, NULL) AS \"%s\",\n" + " pg_catalog.format_type(ap.amprocrighttype, NULL) AS \"%s\",\n" + " ap.amprocnum AS \"%s\"\n," + " p.proname AS \"%s\"\n", + gettext_noop("AM"), + gettext_noop("Operator family"), + gettext_noop("Left arg type"), + gettext_noop("Right arg type"), + gettext_noop("Number"), + gettext_noop("Proc name")); + + appendPQExpBuffer(&buf, + "FROM pg_catalog.pg_amproc ap\n" + " LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = ap.amprocfamily\n" + " LEFT JOIN pg_catalog.pg_am am ON am.oid = of.opfmethod\n" + " LEFT JOIN pg_catalog.pg_namespace ns ON of.opfnamespace = ns.oid\n" + " LEFT JOIN pg_catalog.pg_proc p ON ap.amproc = p.oid\n"); + + if (access_method_pattern) + have_where = processSQLNamePattern(pset.db, &buf, access_method_pattern, + false, false, NULL, "am.amname", + NULL, NULL); + if (family_pattern) + processSQLNamePattern(pset.db, &buf, family_pattern, have_where, false, + "ns.nspname", "of.opfname", NULL, NULL); + + appendPQExpBufferStr(&buf, + "ORDER BY 1, 2, 3, 4, 5;"); + + res = PSQLexec(buf.data); + termPQExpBuffer(&buf); + if (!res) + return false; + + myopt.nullPrint = NULL; + myopt.title = _("List of procedures of operator families"); + 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; +} diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h index 20dbfd20f0..35c50e3bcd 100644 --- a/src/bin/psql/describe.h +++ b/src/bin/psql/describe.h @@ -114,4 +114,23 @@ bool describePublications(const char *pattern); /* \dRs */ bool describeSubscriptions(const char *pattern, bool verbose); +/* \dAc */ +extern bool listOperatorClasses(const char *access_method_pattern, + const char *opclass_pattern, + bool verbose); + +/* \dAf */ +extern bool listOperatorFamilies(const char *access_method_pattern, + const char *opclass_pattern, + bool verbose); + +/* \dAo */ +extern bool listOpFamilyOperators(const char *accessMethod_pattern, + const char *family_pattern, bool verbose); + +/* \dAp */ +extern bool listOpFamilyProcedures(const char *access_method_pattern, + const char *family_pattern); + + #endif /* DESCRIBE_H */ diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c index 1f1f778426..9a18cb3059 100644 --- a/src/bin/psql/help.c +++ b/src/bin/psql/help.c @@ -227,6 +227,10 @@ slashUsage(unsigned short int pager) fprintf(output, _(" \\d[S+] NAME describe table, view, sequence, or index\n")); fprintf(output, _(" \\da[S] [PATTERN] list aggregates\n")); fprintf(output, _(" \\dA[+] [PATTERN] list access methods\n")); + fprintf(output, _(" \\dAc[+] [AMPTRN [TYPEPTRN]] list operator classes\n")); + fprintf(output, _(" \\dAf[+] [AMPTRN [TYPEPTRN]] list operator families\n")); + fprintf(output, _(" \\dAo[+] [AMPTRN [OPFPTRN]] list operators of operator families\n")); + fprintf(output, _(" \\dAp [AMPTRN [OPFPTRN]] list procedures of operator families\n")); fprintf(output, _(" \\db[+] [PATTERN] list tablespaces\n")); fprintf(output, _(" \\dc[S+] [PATTERN] list conversions\n")); fprintf(output, _(" \\dC[+] [PATTERN] list casts\n")); diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index 17b1f299b4..174c3db623 100644 --- a/src/bin/psql/tab-complete.c +++ b/src/bin/psql/tab-complete.c @@ -510,6 +510,13 @@ static const SchemaQuery Query_for_list_of_partitioned_relations = { .result = "pg_catalog.quote_ident(c.relname)", }; +static const SchemaQuery Query_for_list_of_operator_families = { + .catname = "pg_catalog.pg_opfamily c", + .viscondition = "pg_catalog.pg_opfamily_is_visible(c.oid)", + .namespace = "c.opfnamespace", + .result = "pg_catalog.quote_ident(c.opfname)", +}; + /* Relations supporting INSERT, UPDATE or DELETE */ static const SchemaQuery Query_for_list_of_updatables = { .catname = "pg_catalog.pg_class c", @@ -1462,7 +1469,8 @@ psql_completion(const char *text, int start, int end) "\\a", "\\connect", "\\conninfo", "\\C", "\\cd", "\\copy", "\\copyright", "\\crosstabview", - "\\d", "\\da", "\\dA", "\\db", "\\dc", "\\dC", "\\dd", "\\ddp", "\\dD", + "\\d", "\\da", "\\dA", "\\dAc", "\\dAf", "\\dAo", "\\dAp", + "\\db", "\\dc", "\\dC", "\\dd", "\\ddp", "\\dD", "\\des", "\\det", "\\deu", "\\dew", "\\dE", "\\df", "\\dF", "\\dFd", "\\dFp", "\\dFt", "\\dg", "\\di", "\\dl", "\\dL", "\\dm", "\\dn", "\\do", "\\dO", "\\dp", "\\dP", "\\dPi", "\\dPt", @@ -3698,6 +3706,12 @@ psql_completion(const char *text, int start, int end) } else if (TailMatchesCS("\\da*")) COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_aggregates, NULL); + else if (TailMatchesCS("\\dAc*", MatchAny) || + TailMatchesCS("\\dAf*", MatchAny)) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes, NULL); + else if (TailMatchesCS("\\dAo*", MatchAny) || + TailMatchesCS("\\dAp*", MatchAny)) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_operator_families, NULL); else if (TailMatchesCS("\\dA*")) COMPLETE_WITH_QUERY(Query_for_list_of_access_methods); else if (TailMatchesCS("\\db*")) diff --git a/src/test/regress/expected/psql.out b/src/test/regress/expected/psql.out index 242f817163..2423ae2f37 100644 --- a/src/test/regress/expected/psql.out +++ b/src/test/regress/expected/psql.out @@ -4809,3 +4809,165 @@ Owning table: "pg_catalog.pg_statistic" Indexes: "pg_toast_2619_index" PRIMARY KEY, btree (chunk_id, chunk_seq) +-- check printing info about access methods +\dA +List of access methods + Name | Type +--------+------- + brin | Index + btree | Index + gin | Index + gist | Index + hash | Index + heap | Table + heap2 | Table + spgist | Index +(8 rows) + +\dA * +List of access methods + Name | Type +--------+------- + brin | Index + btree | Index + gin | Index + gist | Index + hash | Index + heap | Table + heap2 | Table + spgist | Index +(8 rows) + +\dA h* +List of access methods + Name | Type +-------+------- + hash | Index + heap | Table + heap2 | Table +(3 rows) + +\dA foo +List of access methods + Name | Type +------+------ +(0 rows) + +\dA foo bar +List of access methods + Name | Type +------+------ +(0 rows) + +\dA: extra argument "bar" ignored +\dA+ + List of access methods + Name | Type | Handler | Description +--------+-------+----------------------+---------------------------------------- + brin | Index | brinhandler | block range index (BRIN) access method + btree | Index | bthandler | b-tree index access method + gin | Index | ginhandler | GIN index access method + gist | Index | gisthandler | GiST index access method + hash | Index | hashhandler | hash index access method + heap | Table | heap_tableam_handler | heap table access method + heap2 | Table | heap_tableam_handler | + spgist | Index | spghandler | SP-GiST index access method +(8 rows) + +\dA+ * + List of access methods + Name | Type | Handler | Description +--------+-------+----------------------+---------------------------------------- + brin | Index | brinhandler | block range index (BRIN) access method + btree | Index | bthandler | b-tree index access method + gin | Index | ginhandler | GIN index access method + gist | Index | gisthandler | GiST index access method + hash | Index | hashhandler | hash index access method + heap | Table | heap_tableam_handler | heap table access method + heap2 | Table | heap_tableam_handler | + spgist | Index | spghandler | SP-GiST index access method +(8 rows) + +\dA+ h* + List of access methods + Name | Type | Handler | Description +-------+-------+----------------------+-------------------------- + hash | Index | hashhandler | hash index access method + heap | Table | heap_tableam_handler | heap table access method + heap2 | Table | heap_tableam_handler | +(3 rows) + +\dA+ foo + List of access methods + Name | Type | Handler | Description +------+------+---------+------------- +(0 rows) + +\dAc brin pg*.oid* + List of operator classes + AM | Input type | Storage type | Operator class | Default? +------+------------+--------------+----------------+---------- + brin | oid | | oid_minmax_ops | yes +(1 row) + +\dAf spgist + List of operator families + AM | Operator family | Applicable types +--------+-----------------+------------------ + spgist | box_ops | box + spgist | kd_point_ops | point + spgist | network_ops | inet + spgist | poly_ops | polygon + spgist | quad_point_ops | point + spgist | range_ops | anyrange + spgist | text_ops | text +(7 rows) + +\dAf btree int4 + List of operator families + AM | Operator family | Applicable types +-------+-----------------+--------------------------- + btree | integer_ops | smallint, integer, bigint +(1 row) + +\dAo brin uuid_minmax_ops + List of operators of operator families + AM | Opfamily Name | Operator +------+-----------------+----------------- + brin | uuid_minmax_ops | < (uuid, uuid) + brin | uuid_minmax_ops | <= (uuid, uuid) + brin | uuid_minmax_ops | = (uuid, uuid) + brin | uuid_minmax_ops | >= (uuid, uuid) + brin | uuid_minmax_ops | > (uuid, uuid) +(5 rows) + +\dAo * pg_catalog.jsonb_path_ops + List of operators of operator families + AM | Opfamily Name | Operator +-----+----------------+---------------------- + gin | jsonb_path_ops | @> (jsonb, jsonb) + gin | jsonb_path_ops | @? (jsonb, jsonpath) + gin | jsonb_path_ops | @@ (jsonb, jsonpath) +(3 rows) + +\dAp brin uuid_minmax_ops + List of procedures of operator families + AM | Operator family | Left arg type | Right arg type | Number | Proc name +------+-----------------+---------------+----------------+--------+------------------------ + brin | uuid_minmax_ops | uuid | uuid | 1 | brin_minmax_opcinfo + brin | uuid_minmax_ops | uuid | uuid | 2 | brin_minmax_add_value + brin | uuid_minmax_ops | uuid | uuid | 3 | brin_minmax_consistent + brin | uuid_minmax_ops | uuid | uuid | 4 | brin_minmax_union +(4 rows) + +\dAp * pg_catalog.uuid_ops + List of procedures of operator families + AM | Operator family | Left arg type | Right arg type | Number | Proc name +-------+-----------------+---------------+----------------+--------+-------------------- + btree | uuid_ops | uuid | uuid | 1 | uuid_cmp + btree | uuid_ops | uuid | uuid | 2 | uuid_sortsupport + btree | uuid_ops | uuid | uuid | 4 | btequalimage + hash | uuid_ops | uuid | uuid | 1 | uuid_hash + hash | uuid_ops | uuid | uuid | 2 | uuid_hash_extended +(5 rows) + diff --git a/src/test/regress/sql/psql.sql b/src/test/regress/sql/psql.sql index 26a0bcf718..3c876d2699 100644 --- a/src/test/regress/sql/psql.sql +++ b/src/test/regress/sql/psql.sql @@ -1182,3 +1182,21 @@ drop role regress_partitioning_role; -- \d on toast table (use pg_statistic's toast table, which has a known name) \d pg_toast.pg_toast_2619 + +-- check printing info about access methods +\dA +\dA * +\dA h* +\dA foo +\dA foo bar +\dA+ +\dA+ * +\dA+ h* +\dA+ foo +\dAc brin pg*.oid* +\dAf spgist +\dAf btree int4 +\dAo brin uuid_minmax_ops +\dAo * pg_catalog.jsonb_path_ops +\dAp brin uuid_minmax_ops +\dAp * pg_catalog.uuid_ops