Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[YSQL] Enable support for sequences #665

Closed
ravimurthy opened this issue Dec 14, 2018 · 1 comment
Closed

[YSQL] Enable support for sequences #665

ravimurthy opened this issue Dec 14, 2018 · 1 comment
Assignees
Labels
kind/enhancement This is an enhancement of an existing feature

Comments

@ravimurthy
Copy link
Contributor

Add support for sequences

  1. DDL commands - CREATE SEQUENCE, DROP SEQUENCE and ALTER SEQUENCE
  2. Sequence functions - https://www.postgresql.org/docs/9.1/functions-sequence.html
  3. Creating tables with nextval(seq) as default value
@kmuthukk kmuthukk added the kind/enhancement This is an enhancement of an existing feature label Dec 14, 2018
yugabyte-ci pushed a commit that referenced this issue Mar 12, 2019
Summary:
This diff adds support for:
- CREATE SEQUENCE
- DROP SEQUENCE
- nextval
- currval
- lastval
- Create a table with columns of serial types

Our implementation of sequences uses one replicated user level table to store all sequences data. This table has four columns: db_oid, rel_oid, last_val, and is_called. The first two columns uniquely identify a sequence. last_val and is_called is the data necessary to determine what is the next value in the sequence. Our implementation differs from Postgres implementation by using one row in a special table as opposed to using a one-row table to store the same data.

Initially, when a sequence is created, an RPC to insert a new row is sent to the tserver that is the leader of the tablet which will store the new row. Initially last_val is set to the start value (default 1), and is_called is set to false. is_called is false when last_val hasn't been used. In other words, if nextval() reads the sequence data, it returns last_val if is_called is false. It returns last_val + increment otherwise.

Postgres implementation of nextval locks the sequence table, reads the data, checks whether incrementing (possibly by a negative value) would violate any constrains, writes the new values for last_val and is_called, and then it unlocks the table. In YugaByte's implementation we cannot lock the data table because this table is shared among all the sequences. Instead, a nextval() call sends a read RPC to read the current values `last_val` and `is_called`, constraints are then evaluated for these values, and if no errors occurred, we do a conditional update (update the row only if the values haven't changed since we last read them). If the conditional update fails, we retry the whole operation again: read data, check constraints, update data. Because our implementation uses two RPCs each time we increment `last_val` or change `is_called`, the performance of a default sequence (with `CACHE` set to 1) will be much lower than a similar sequence in Postgres. To minimize this, the user should use a cache sufficiently large to avoid issuing two RPCs for each sequence value requested through nextval(). The disadvantage of this approach, is that once a block of cache numbers has been generated, any unused numbers from the cache will be lost forever.

Pending:
- Support for CYCLE option
- ALTER SEQUENCE
- setval

Test Plan:
Manual for now. Tests coming soon:
```
postgres=# create sequence s1 increment 3 start 100 cache 1000 ;
CREATE SEQUENCE
postgres=# select nextval('s1');
 nextval
---------
     100
(1 row)

postgres=# select nextval('s1');
 nextval
---------
     103
(1 row)

postgres=# ^D\q
dog.local:~/code/yugabyte [postgres_sequence ↓·2↑·1|✚ 5⚑ 7]
14:22 $ ./bin/yb-ctl destroy; ./bin/yb-ctl create --enable_postgres; ./bin/yb-ctl status; ./bin/yb-ctl setup_pg_sequences_table; ./bin/psql -p 5433 -U postgres -h localhost^C
dog.local:~/code/yugabyte [postgres_sequence ↓·2↑·1|✚ 5⚑ 7]
14:22 $ ./bin/psql -p 5433 -U postgres -h localhost
psql (10.4)
Type "help" for help.

postgres=# select nextval('s1');
 nextval
---------
    3100
(1 row)

postgres=# ^D\q
dog.local:~/code/yugabyte [postgres_sequence ↓·2↑·1|✚ 5⚑ 7]
14:23 $ ./bin/psql -p 5433 -U postgres -h localhost
psql (10.4)
Type "help" for help.

postgres=# select nextval('s1');
 nextval
---------
    6100
(1 row)
```

```
psql (10.4)
Type "help" for help.

postgres=# create table t(k serial primary key, v int);
insert CREATE TABLE
postgres=# insert into t(v) values (100);
INSERT 0 1
postgres=# insert into t(v) values (101);
INSERT 0 1
postgres=# insert into t(v) values (102);
INSERT 0 1
postgres=# select * from t;
 k |  v
---+-----
 1 | 100
 2 | 101
 3 | 102
(3 rows)

postgres=# \d t;
                            Table "public.t"
 Column |  Type   | Collation | Nullable |           Default
--------+---------+-----------+----------+------------------------------
 k      | integer |           | not null | nextval('t_k_seq'::regclass)
 v      | integer |           |          |

postgres=# select nextval('t_k_seq');
 nextval
---------
       4
(1 row)

postgres=# select currval('t_k_seq');
 currval
---------
       4
(1 row)

postgres=# select lastval();
 lastval
---------
       4
(1 row)

```

```
postgres=# SELECT c.relname FROM pg_class c WHERE c.relkind = 'S';
 relname
---------
(0 rows)

postgres=# create sequence s1;
CREATE SEQUENCE
postgres=# create table t4(k serial, v int);
CREATE TABLE
postgres=# SELECT c.relname FROM pg_class c WHERE c.relkind = 'S';
 relname
----------
 s1
 t4_k_seq
(2 rows)

postgres=# drop sequence s1;
DROP SEQUENCE
postgres=# drop table t4;
DROP TABLE
postgres=# SELECT c.relname FROM pg_class c WHERE c.relkind = 'S';
 relname
----------
 t4_k_seq
(1 row)

postgres=# drop sequence t4_k_seq;
DROP SEQUENCE
postgres=# SELECT c.relname FROM pg_class c WHERE c.relkind = 'S';
 relname
---------
(0 rows)
```

Reviewers: neil, karthik, mihnea, robert

Reviewed By: robert

Subscribers: kannan, bogdan, neha, yql

Differential Revision: https://phabricator.dev.yugabyte.com/D6128
@hectorgcr
Copy link
Contributor

Closing this one. Tracking ALTER SEQUENCE in #1002 and setval in #1003

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/enhancement This is an enhancement of an existing feature
Projects
None yet
Development

No branches or pull requests

3 participants