diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/catalog/information_schema.sql | 12 | ||||
-rw-r--r-- | src/backend/commands/sequence.c | 51 |
2 files changed, 58 insertions, 5 deletions
diff --git a/src/backend/catalog/information_schema.sql b/src/backend/catalog/information_schema.sql index 090c10c3220..5b8b9417701 100644 --- a/src/backend/catalog/information_schema.sql +++ b/src/backend/catalog/information_schema.sql @@ -1430,16 +1430,18 @@ CREATE VIEW sequences AS CAST(64 AS cardinal_number) AS numeric_precision, CAST(2 AS cardinal_number) AS numeric_precision_radix, CAST(0 AS cardinal_number) AS numeric_scale, - CAST(null AS cardinal_number) AS maximum_value, -- FIXME - CAST(null AS cardinal_number) AS minimum_value, -- FIXME - CAST(null AS cardinal_number) AS increment, -- FIXME - CAST(null AS yes_or_no) AS cycle_option -- FIXME + -- XXX: The following could be improved if we had LATERAL. + CAST((pg_sequence_parameters(c.oid)).start_value AS character_data) AS start_value, + CAST((pg_sequence_parameters(c.oid)).minimum_value AS character_data) AS minimum_value, + CAST((pg_sequence_parameters(c.oid)).maximum_value AS character_data) AS maximum_value, + CAST((pg_sequence_parameters(c.oid)).increment AS character_data) AS increment, + CAST(CASE WHEN (pg_sequence_parameters(c.oid)).cycle_option THEN 'YES' ELSE 'NO' END AS yes_or_no) AS cycle_option FROM pg_namespace nc, pg_class c WHERE c.relnamespace = nc.oid AND c.relkind = 'S' AND (NOT pg_is_other_temp_schema(nc.oid)) AND (pg_has_role(c.relowner, 'USAGE') - OR has_table_privilege(c.oid, 'SELECT, UPDATE') ); + OR has_sequence_privilege(c.oid, 'SELECT, UPDATE, USAGE') ); GRANT SELECT ON sequences TO PUBLIC; diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c index 39d2f9a8062..0ff722d6f8a 100644 --- a/src/backend/commands/sequence.c +++ b/src/backend/commands/sequence.c @@ -24,6 +24,7 @@ #include "commands/defrem.h" #include "commands/sequence.h" #include "commands/tablecmds.h" +#include "funcapi.h" #include "miscadmin.h" #include "nodes/makefuncs.h" #include "storage/bufmgr.h" @@ -1420,6 +1421,56 @@ process_owned_by(Relation seqrel, List *owned_by) } +/* + * Return sequence parameters, for use by information schema + */ +Datum +pg_sequence_parameters(PG_FUNCTION_ARGS) +{ + Oid relid = PG_GETARG_OID(0); + TupleDesc tupdesc; + Datum values[5]; + bool isnull[5]; + SeqTable elm; + Relation seqrel; + Buffer buf; + Form_pg_sequence seq; + + /* open and AccessShareLock sequence */ + init_sequence(relid, &elm, &seqrel); + + if (pg_class_aclcheck(relid, GetUserId(), ACL_SELECT | ACL_UPDATE | ACL_USAGE) != ACLCHECK_OK) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("permission denied for sequence %s", + RelationGetRelationName(seqrel)))); + + tupdesc = CreateTemplateTupleDesc(5, false); + TupleDescInitEntry(tupdesc, (AttrNumber) 1, "start_value", INT8OID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 2, "minimum_value", INT8OID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 3, "maximum_value", INT8OID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 4, "increment", INT8OID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 5, "cycle_option", BOOLOID, -1, 0); + + BlessTupleDesc(tupdesc); + + memset(isnull, 0, sizeof(isnull)); + + seq = read_info(elm, seqrel, &buf); + + values[0] = Int64GetDatum(seq->start_value); + values[1] = Int64GetDatum(seq->min_value); + values[2] = Int64GetDatum(seq->max_value); + values[3] = Int64GetDatum(seq->increment_by); + values[4] = BoolGetDatum(seq->is_cycled); + + UnlockReleaseBuffer(buf); + relation_close(seqrel, NoLock); + + return HeapTupleGetDatum(heap_form_tuple(tupdesc, values, isnull)); +} + + void seq_redo(XLogRecPtr lsn, XLogRecord *record) { |