Skip to content

Commit

Permalink
sql: implement SERIAL column type
Browse files Browse the repository at this point in the history
Closes #4491.

There are two good options for this, each with tradeoffs. One is for SERIAL to
be an alias for DEFAULT unique_rowid and the other is to emulate Postgres's
SEQUENCEs.

Emulating SEQUENCE funnels every insert through a single point of contention,
but would be a drop-in replacement.

unique_rowid has no contention, is faster, and works for the common use of a
unique and increasing identifier (modulo overlapping transactions).
Unfortunately, it may also cause user confusion and break ORMs that (correctly
in Postgres) assume that SERIAL starts at 0 and (incorrectly) that SERIAL has no
holes. An interesting side benefit of unique_rowid is that it prevents the
problem of inadvertantly exposing user growth numbers (sign up for a service
once per day and keep track of the userids), which is a common issue with
SERIAL.

If it was known that user confusion and ORM compatibility would not be an issue,
unique_rowid would be the clear decision. Since it's still early enough to run
small experiments, this is the approach used here. If this results in sufficient
evidence that it was the wrong decision, a later version of Cockroach will
switch the behavior to emulate SEQUENCEs. Existing SERIAL columns will, however,
retain the old behavior.
  • Loading branch information
danhhz committed Jun 3, 2016
1 parent e05afb1 commit d389405
Show file tree
Hide file tree
Showing 6 changed files with 340 additions and 301 deletions.
7 changes: 7 additions & 0 deletions sql/parser/col_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ var (
intColTypeInteger = &IntColType{Name: "INTEGER"}
intColTypeSmallInt = &IntColType{Name: "SMALLINT"}
intColTypeBigInt = &IntColType{Name: "BIGINT"}
intColTypeSerial = &IntColType{Name: "SERIAL"}
)

func newIntBitType(n int) *IntColType {
Expand All @@ -86,6 +87,12 @@ func (node *IntColType) Format(buf *bytes.Buffer, f FmtFlags) {
}
}

// IsSerial returns true when this column should be given a DEFAULT of a unique,
// incrementing function.
func (node *IntColType) IsSerial() bool {
return node.Name == intColTypeSerial.Name
}

// Pre-allocated immutable float column types.
var (
floatColTypeReal = &FloatColType{Name: "REAL"}
Expand Down
1 change: 1 addition & 0 deletions sql/parser/parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ func TestParse(t *testing.T) {
{`CREATE TABLE a (b STRING)`},
{`CREATE TABLE a (b STRING(3))`},
{`CREATE TABLE a (b FLOAT)`},
{`CREATE TABLE a (b SERIAL)`},
{`CREATE TABLE a (b INT NULL)`},
{`CREATE TABLE a (b INT NOT NULL)`},
{`CREATE TABLE a (b INT PRIMARY KEY)`},
Expand Down
Loading

0 comments on commit d389405

Please sign in to comment.