diff --git a/pkg/sql/logictest/testdata/logic_test/create_statements b/pkg/sql/logictest/testdata/logic_test/create_statements index b229c01ca3f6..2ea6ad2493a4 100644 --- a/pkg/sql/logictest/testdata/logic_test/create_statements +++ b/pkg/sql/logictest/testdata/logic_test/create_statements @@ -3110,29 +3110,29 @@ CREATE TABLE pg_catalog.pg_sequence ( seqcycle BOOL NULL ) {} {} CREATE TABLE pg_catalog.pg_sequences ( - cache_size INT8 NULL, - cycle BOOL NULL, - data_type REGTYPE NULL, - max_value INT8 NULL, + schemaname NAME NULL, + sequencename NAME NULL, sequenceowner NAME NULL, + data_type REGTYPE NULL, start_value INT8 NULL, - increment_by INT8 NULL, - last_value INT8 NULL, min_value INT8 NULL, - schemaname NAME NULL, - sequencename NAME NULL -) CREATE TABLE pg_catalog.pg_sequences ( - cache_size INT8 NULL, - cycle BOOL NULL, - data_type REGTYPE NULL, max_value INT8 NULL, + increment_by INT8 NULL, + cycle BOOL NULL, + cache_size INT8 NULL, + last_value INT8 NULL +) CREATE TABLE pg_catalog.pg_sequences ( + schemaname NAME NULL, + sequencename NAME NULL, sequenceowner NAME NULL, + data_type REGTYPE NULL, start_value INT8 NULL, - increment_by INT8 NULL, - last_value INT8 NULL, min_value INT8 NULL, - schemaname NAME NULL, - sequencename NAME NULL + max_value INT8 NULL, + increment_by INT8 NULL, + cycle BOOL NULL, + cache_size INT8 NULL, + last_value INT8 NULL ) {} {} CREATE TABLE pg_catalog.pg_settings ( name STRING NULL, diff --git a/pkg/sql/logictest/testdata/logic_test/pg_catalog b/pkg/sql/logictest/testdata/logic_test/pg_catalog index 448192efb342..565a1059b95b 100644 --- a/pkg/sql/logictest/testdata/logic_test/pg_catalog +++ b/pkg/sql/logictest/testdata/logic_test/pg_catalog @@ -2015,7 +2015,7 @@ objoid classoid objsubid description 4294967155 4294967205 0 security labels (empty - feature does not exist) 4294967156 4294967205 0 security labels (empty) 4294967154 4294967205 0 sequences (see also information_schema.sequences) -4294967153 4294967205 0 pg_sequences was created for compatibility and is currently unimplemented +4294967153 4294967205 0 pg_sequences is very similar as pg_sequence. 4294967152 4294967205 0 session variables (incomplete) 4294967151 4294967205 0 pg_shadow was created for compatibility and is currently unimplemented 4294967148 4294967205 0 shared dependencies (empty - not implemented) @@ -3305,3 +3305,38 @@ SET stub_catalog_tables=true statement ok SELECT * FROM pg_seclabel + +statement ok +CREATE SEQUENCE serial START 101 INCREMENT 5 + +# Last value must return NULL when querying pg_sequences and sequence haven't +# been used. +query I +SELECT last_value FROM pg_sequences WHERE sequencename = 'serial' +---- +NULL + +statement ok +SELECT nextval('serial'); +SELECT nextval('serial'); +SELECT nextval('serial'); + +# Now last_value should be 111 +query TTTOIIIIBII colnames +SELECT * FROM pg_sequences WHERE sequencename = 'serial' +---- +schemaname sequencename sequenceowner data_type start_value min_value max_value increment_by cycle cache_size last_value +public serial root 20 101 1 9223372036854775807 5 false 1 111 + +# Testing sequenceowner and cache_size +statement ok +CREATE USER anyuser; +GRANT CREATE ON DATABASE test TO anyuser; +ALTER SEQUENCE serial OWNER TO anyuser; +ALTER SEQUENCE serial CACHE 10; + +query TI colnames +SELECT sequenceowner, cache_size FROM pg_sequences WHERE sequencename = 'serial' +---- +sequenceowner cache_size +anyuser 10 diff --git a/pkg/sql/pg_catalog.go b/pkg/sql/pg_catalog.go index ccdfffb97818..208fe9d36da7 100644 --- a/pkg/sql/pg_catalog.go +++ b/pkg/sql/pg_catalog.go @@ -2882,12 +2882,51 @@ var pgCatalogReplicationOriginStatusTable = virtualSchemaTable{ } var pgCatalogSequencesTable = virtualSchemaTable{ - comment: "pg_sequences was created for compatibility and is currently unimplemented", - schema: vtable.PgCatalogSequences, - populate: func(ctx context.Context, p *planner, _ catalog.DatabaseDescriptor, addRow func(...tree.Datum) error) error { - return nil + comment: `pg_sequences is very similar as pg_sequence. +https://www.postgresql.org/docs/13/view-pg-sequences.html +`, + schema: vtable.PgCatalogSequences, + populate: func(ctx context.Context, p *planner, dbContext catalog.DatabaseDescriptor, addRow func(...tree.Datum) error) error { + return forEachTableDesc(ctx, p, dbContext, hideVirtual, /* virtual schemas do not have indexes */ + func(db catalog.DatabaseDescriptor, scName string, table catalog.TableDescriptor) error { + if !table.IsSequence() { + return nil + } + opts := table.GetSequenceOpts() + lastValue := tree.DNull + sequenceValue, err := p.GetSequenceValue(ctx, p.execCfg.Codec, table) + if err != nil { + return err + } + + // Before using for the first time, sequenceValue will be: + // opts.Start - opts.Increment. + if sequenceValue != opts.Start-opts.Increment { + lastValue = tree.NewDInt(tree.DInt(sequenceValue)) + } + + // sequenceowner refers to the username that owns the sequence which is + // available in the table descriptor that can be changed by ALTER + // SEQUENCE sequencename OWNER TO username. Sequence opts have a + // table.column owner which is the value that can be modifyied by ALTER + // SEQUENE sequencename OWNED BY table.column, This is not the expected + // value on sequenceowner. + return addRow( + tree.NewDString(scName), // schemaname + tree.NewDString(table.GetName()), // sequencename + getOwnerName(table), // sequenceowner + tree.NewDOid(tree.DInt(oid.T_int8)), // data_type + tree.NewDInt(tree.DInt(opts.Start)), // start_value + tree.NewDInt(tree.DInt(opts.MinValue)), // min_value + tree.NewDInt(tree.DInt(opts.MaxValue)), // max_value + tree.NewDInt(tree.DInt(opts.Increment)), // increment_by + tree.DBoolFalse, // cycle + tree.NewDInt(tree.DInt(opts.CacheSize)), // cache_size + lastValue, // last_value + ) + }, + ) }, - unimplemented: true, } // typOid is the only OID generation approach that does not use oidHasher, because diff --git a/pkg/sql/vtable/pg_catalog.go b/pkg/sql/vtable/pg_catalog.go index cb0cd076ebbd..2df592cb1e41 100644 --- a/pkg/sql/vtable/pg_catalog.go +++ b/pkg/sql/vtable/pg_catalog.go @@ -1349,17 +1349,17 @@ CREATE TABLE pg_catalog.pg_policy ( //PgCatalogSequences is an empty table in the pg_catalog that is not implemented yet const PgCatalogSequences = ` CREATE TABLE pg_catalog.pg_sequences ( - cache_size INT, - cycle BOOL, - data_type REGTYPE, - max_value INT, + schemaname NAME, + sequencename NAME, sequenceowner NAME, + data_type REGTYPE, start_value INT, - increment_by INT, - last_value INT, min_value INT, - schemaname NAME, - sequencename NAME + max_value INT, + increment_by INT, + cycle BOOL, + cache_size INT, + last_value INT )` //PgCatalogSubscriptionRel is an empty table in the pg_catalog that is not implemented yet