From 7e9633b51113a6991f92a1f5139b60ee5415c044 Mon Sep 17 00:00:00 2001 From: Raphael 'kena' Poss Date: Wed, 22 Aug 2018 19:07:31 +0200 Subject: [PATCH] sql: fix the handling of integer types Prior to this patch, CockroachDB maintained an unnecessary distinction between "INT" and "INTEGER", between "BIGINT" and "INT8", etc. This distinction is unnecessary but also costly, as we were paying the price of a "name" attribute in coltypes.TInt, with a string comparison and hash table lookup on every use of the type. What really matters is that the type shows up properly in introspection; this has already been ensured by various OID-to-pgcatalog mappings and the recently introduced `InformationSchemaTypeName()`. Any distinction beyond that is unnecessary and can be dropped from the implementation. Release note: None --- docs/generated/sql/bnf/stmt_block.bnf | 4 +- pkg/ccl/importccl/import_stmt_test.go | 18 ++-- pkg/ccl/importccl/read_import_mysql.go | 22 ++--- pkg/ccl/importccl/read_import_pgdump_test.go | 2 +- .../mysqldump/everything.cockroach-schema.sql | 8 +- .../mysqldump/second.cockroach-schema.sql | 4 +- .../mysqldump/simple.cockroach-schema.sql | 2 +- .../mysqldump/third.cockroach-schema.sql | 10 +-- pkg/sql/coltypes/aliases.go | 25 ++---- pkg/sql/coltypes/arith.go | 35 ++++---- .../testdata/logic_test/alter_column_type | 2 +- pkg/sql/logictest/testdata/logic_test/array | 6 +- .../testdata/logic_test/information_schema | 6 ++ .../logictest/testdata/logic_test/pg_catalog | 8 +- pkg/sql/logictest/testdata/logic_test/serial | 10 +-- pkg/sql/logictest/testdata/logic_test/table | 14 +-- pkg/sql/opt/memo/private_storage_test.go | 2 +- pkg/sql/opt/norm/testdata/rules/scalar | 2 +- pkg/sql/opt/optbuilder/testdata/scalar | 2 +- pkg/sql/parser/parse_test.go | 5 ++ pkg/sql/parser/sql.y | 26 +++--- pkg/sql/schemachange/alter_column_type.go | 2 +- .../schemachange/alter_column_type_test.go | 32 +++++-- pkg/sql/sem/tree/col_types_test.go | 12 +-- pkg/sql/serial.go | 2 +- pkg/sql/sqlbase/column_type_properties.go | 52 +++++++----- pkg/sql/sqlbase/structured.proto | 85 +++++++++---------- pkg/sql/table_test.go | 10 +-- 28 files changed, 217 insertions(+), 191 deletions(-) diff --git a/docs/generated/sql/bnf/stmt_block.bnf b/docs/generated/sql/bnf/stmt_block.bnf index abde76c388b6..d772c7d65d96 100644 --- a/docs/generated/sql/bnf/stmt_block.bnf +++ b/docs/generated/sql/bnf/stmt_block.bnf @@ -1793,12 +1793,12 @@ reference_actions ::= numeric ::= 'INT' + | 'INTEGER' | 'INT2' + | 'SMALLINT' | 'INT4' | 'INT8' | 'INT64' - | 'INTEGER' - | 'SMALLINT' | 'BIGINT' | 'REAL' | 'FLOAT4' diff --git a/pkg/ccl/importccl/import_stmt_test.go b/pkg/ccl/importccl/import_stmt_test.go index 433e1258bab6..a5838eb5a451 100644 --- a/pkg/ccl/importccl/import_stmt_test.go +++ b/pkg/ccl/importccl/import_stmt_test.go @@ -483,8 +483,8 @@ COPY t (a, b, c) FROM stdin; ORDER BY descriptor_name `: {{ `CREATE TABLE a ( - i INTEGER NOT NULL, - k INTEGER NULL, + i INT NOT NULL, + k INT NULL, CONSTRAINT a_pkey PRIMARY KEY (i ASC), CONSTRAINT a_k_fkey FOREIGN KEY (k) REFERENCES a (i), INDEX a_auto_index_a_k_fkey (k ASC), @@ -492,7 +492,7 @@ COPY t (a, b, c) FROM stdin; FAMILY "primary" (i, k) )`}, { `CREATE TABLE b ( - j INTEGER NOT NULL, + j INT NOT NULL, CONSTRAINT b_pkey PRIMARY KEY (j ASC), CONSTRAINT b_j_fkey FOREIGN KEY (j) REFERENCES a (i), FAMILY "primary" (j) @@ -631,8 +631,8 @@ const ( )` testPgdumpCreateWeather = `CREATE TABLE weather ( city VARCHAR(80) NULL, - temp_lo INTEGER NULL, - temp_hi INTEGER NULL, + temp_lo INT NULL, + temp_hi INT NULL, prcp FLOAT4 NULL, date DATE NULL, CONSTRAINT weather_city_fkey FOREIGN KEY (city) REFERENCES cities (city), @@ -2220,7 +2220,7 @@ func TestImportPgDump(t *testing.T) { // Verify table schema because PKs and indexes are at the bottom of pg_dump. sqlDB.CheckQueryResults(t, `SHOW CREATE TABLE simple`, [][]string{{ "simple", `CREATE TABLE simple ( - i INTEGER NOT NULL, + i INT NOT NULL, s STRING NULL, b BYTES NULL, CONSTRAINT simple_pkey PRIMARY KEY (i ASC), @@ -2262,7 +2262,7 @@ func TestImportPgDump(t *testing.T) { // Verify table schema because PKs and indexes are at the bottom of pg_dump. sqlDB.CheckQueryResults(t, `SHOW CREATE TABLE second`, [][]string{{ "second", `CREATE TABLE second ( - i INTEGER NOT NULL, + i INT NOT NULL, s STRING NULL, CONSTRAINT second_pkey PRIMARY KEY (i ASC), FAMILY "primary" (i, s) @@ -2296,8 +2296,8 @@ func TestImportPgDump(t *testing.T) { if c.expected == expectAll { sqlDB.CheckQueryResults(t, `SHOW CREATE TABLE seqtable`, [][]string{{ "seqtable", `CREATE TABLE seqtable ( - a INTEGER NULL DEFAULT nextval('public.a_seq':::STRING), - b INTEGER NULL, + a INT NULL DEFAULT nextval('public.a_seq':::STRING), + b INT NULL, FAMILY "primary" (a, b, rowid) )`, }}) diff --git a/pkg/ccl/importccl/read_import_mysql.go b/pkg/ccl/importccl/read_import_mysql.go index f220238338a6..0ce736adf82b 100644 --- a/pkg/ccl/importccl/read_import_mysql.go +++ b/pkg/ccl/importccl/read_import_mysql.go @@ -511,25 +511,25 @@ func mysqlColToCockroach( def.Type = coltypes.Bytes case mysqltypes.Int8: - def.Type = coltypes.SmallInt + def.Type = coltypes.Int2 case mysqltypes.Uint8: - def.Type = coltypes.SmallInt + def.Type = coltypes.Int2 case mysqltypes.Int16: - def.Type = coltypes.SmallInt + def.Type = coltypes.Int2 case mysqltypes.Uint16: - def.Type = coltypes.SmallInt + def.Type = coltypes.Int2 case mysqltypes.Int24: - def.Type = coltypes.Int + def.Type = coltypes.Int4 case mysqltypes.Uint24: - def.Type = coltypes.Int + def.Type = coltypes.Int4 case mysqltypes.Int32: - def.Type = coltypes.Int + def.Type = coltypes.Int4 case mysqltypes.Uint32: - def.Type = coltypes.Int + def.Type = coltypes.Int4 case mysqltypes.Int64: - def.Type = coltypes.BigInt + def.Type = coltypes.Int8 case mysqltypes.Uint64: - def.Type = coltypes.BigInt + def.Type = coltypes.Int8 case mysqltypes.Float32: def.Type = coltypes.Float4 @@ -548,7 +548,7 @@ func mysqlColToCockroach( case mysqltypes.Datetime: def.Type = coltypes.TimestampWithTZ case mysqltypes.Year: - def.Type = coltypes.SmallInt + def.Type = coltypes.Int2 case mysqltypes.Enum: def.Type = coltypes.String diff --git a/pkg/ccl/importccl/read_import_pgdump_test.go b/pkg/ccl/importccl/read_import_pgdump_test.go index e03851d6232e..076723608b7f 100644 --- a/pkg/ccl/importccl/read_import_pgdump_test.go +++ b/pkg/ccl/importccl/read_import_pgdump_test.go @@ -123,7 +123,7 @@ COPY public.t (s) FROM stdin; } fmt.Fprintf(&sb, "%s;\n", s) } - const expect = `CREATE TABLE public.second (i INTEGER NOT NULL, s STRING); + const expect = `CREATE TABLE public.second (i INT NOT NULL, s STRING); COPY public.second (i, s) FROM STDIN; "0" "0"; "1" "1"; diff --git a/pkg/ccl/importccl/testdata/mysqldump/everything.cockroach-schema.sql b/pkg/ccl/importccl/testdata/mysqldump/everything.cockroach-schema.sql index 62dfd4388780..abef6844efd9 100644 --- a/pkg/ccl/importccl/testdata/mysqldump/everything.cockroach-schema.sql +++ b/pkg/ccl/importccl/testdata/mysqldump/everything.cockroach-schema.sql @@ -1,5 +1,5 @@ CREATE TABLE everything ( - i INT PRIMARY KEY, + i INT4 PRIMARY KEY, c CHAR(10) NOT NULL, s VARCHAR(100), @@ -21,11 +21,11 @@ CREATE TABLE everything ( nu NUMERIC(10, 0), d53 DECIMAL(5,3), - iw INT NOT NULL, - iz INT, + iw INT4 NOT NULL, + iz INT4, ti SMALLINT, si SMALLINT, - mi INT, + mi INT4, bi BIGINT, fl FLOAT4 NOT NULL, diff --git a/pkg/ccl/importccl/testdata/mysqldump/second.cockroach-schema.sql b/pkg/ccl/importccl/testdata/mysqldump/second.cockroach-schema.sql index 225ed446ae01..7ea4de707ea4 100644 --- a/pkg/ccl/importccl/testdata/mysqldump/second.cockroach-schema.sql +++ b/pkg/ccl/importccl/testdata/mysqldump/second.cockroach-schema.sql @@ -1,6 +1,6 @@ CREATE TABLE second ( - i INT PRIMARY KEY, - k INT, + i INT4 PRIMARY KEY, + k INT4, UNIQUE INDEX ik (i, k), INDEX ki (k, i), CONSTRAINT second_ibfk_1 FOREIGN KEY (k) REFERENCES simple (i) ON UPDATE CASCADE diff --git a/pkg/ccl/importccl/testdata/mysqldump/simple.cockroach-schema.sql b/pkg/ccl/importccl/testdata/mysqldump/simple.cockroach-schema.sql index 3c54dd1f9881..3648f890f5a0 100644 --- a/pkg/ccl/importccl/testdata/mysqldump/simple.cockroach-schema.sql +++ b/pkg/ccl/importccl/testdata/mysqldump/simple.cockroach-schema.sql @@ -1,7 +1,7 @@ CREATE SEQUENCe simple_auto_inc; CREATE TABLE simple ( - i INT PRIMARY KEY DEFAULT nextval('simple_auto_inc':::string), + i INT4 PRIMARY KEY DEFAULT nextval('simple_auto_inc':::string), s text, b bytea ) diff --git a/pkg/ccl/importccl/testdata/mysqldump/third.cockroach-schema.sql b/pkg/ccl/importccl/testdata/mysqldump/third.cockroach-schema.sql index 54b43d31cfe8..bc8f34df6a11 100644 --- a/pkg/ccl/importccl/testdata/mysqldump/third.cockroach-schema.sql +++ b/pkg/ccl/importccl/testdata/mysqldump/third.cockroach-schema.sql @@ -1,10 +1,10 @@ CREATE TABLE third ( - i INT PRIMARY KEY, - a INT, - b INT, - c INT, + i INT4 PRIMARY KEY, + a INT4, + b INT4, + c INT4, INDEX a (a, b), INDEX c (c), FOREIGN KEY (a, b) REFERENCES second (i, k), FOREIGN KEY (c) REFERENCES third (i) ON UPDATE CASCADE -); \ No newline at end of file +); diff --git a/pkg/sql/coltypes/aliases.go b/pkg/sql/coltypes/aliases.go index 7ea3703d2219..2f44fa4cf407 100644 --- a/pkg/sql/coltypes/aliases.go +++ b/pkg/sql/coltypes/aliases.go @@ -28,29 +28,22 @@ var ( Bool = &TBool{} // Int is an immutable T instance. - Int = &TInt{Name: "INT"} + Int = &TInt{} // Int2 is an immutable T instance. - Int2 = &TInt{Name: "INT2", Width: 16, ImplicitWidth: true} + Int2 = &TInt{Width: 16} // Int4 is an immutable T instance. - Int4 = &TInt{Name: "INT4", Width: 32, ImplicitWidth: true} + Int4 = &TInt{Width: 32} // Int8 is an immutable T instance. - Int8 = &TInt{Name: "INT8"} - // Int64 is an immutable T instance. - Int64 = &TInt{Name: "INT64"} - // Integer is an immutable T instance. - Integer = &TInt{Name: "INTEGER"} - // SmallInt is an immutable T instance. - SmallInt = &TInt{Name: "SMALLINT", Width: 16, ImplicitWidth: true} - // BigInt is an immutable T instance. - BigInt = &TInt{Name: "BIGINT"} + Int8 = &TInt{Width: 64} + // Serial is an immutable T instance. - Serial = &TSerial{IntType: Int} + Serial = &TSerial{TInt: Int} // Serial2 is an immutable T instance. - Serial2 = &TSerial{IntType: Int2} + Serial2 = &TSerial{TInt: Int2} // Serial4 is an immutable T instance. - Serial4 = &TSerial{IntType: Int4} + Serial4 = &TSerial{TInt: Int4} // Serial8 is an immutable T instance. - Serial8 = &TSerial{IntType: Int8} + Serial8 = &TSerial{TInt: Int8} // Float4 is an immutable T instance. Float4 = &TFloat{Short: true} diff --git a/pkg/sql/coltypes/arith.go b/pkg/sql/coltypes/arith.go index 8b67480d25c1..3ca384dd67bb 100644 --- a/pkg/sql/coltypes/arith.go +++ b/pkg/sql/coltypes/arith.go @@ -34,36 +34,37 @@ func (node *TBool) Format(buf *bytes.Buffer, f lex.EncodeFlags) { // TInt represents an INT, INTEGER, SMALLINT or BIGINT type. type TInt struct { - Name string - Width int - ImplicitWidth bool + Width int +} + +// IntegerTypeNames maps a TInt data width to a canonical type name. +var IntegerTypeNames = map[int]string{ + 0: "INT", + 16: "INT2", + 32: "INT4", + 64: "INT8", } // TypeName implements the ColTypeFormatter interface. -func (node *TInt) TypeName() string { return node.Name } +func (node *TInt) TypeName() string { return IntegerTypeNames[node.Width] } // Format implements the ColTypeFormatter interface. func (node *TInt) Format(buf *bytes.Buffer, f lex.EncodeFlags) { - buf.WriteString(node.Name) - if node.Width > 0 && !node.ImplicitWidth { - fmt.Fprintf(buf, "(%d)", node.Width) - } + buf.WriteString(node.TypeName()) } // TSerial represents a SERIAL type. -type TSerial struct { - IntType *TInt -} +type TSerial struct{ *TInt } -var serialNames = map[*TInt]string{ - Int: "SERIAL", - Int2: "SERIAL2", - Int4: "SERIAL4", - Int8: "SERIAL8", +var serialNames = map[int]string{ + 0: "SERIAL", + 16: "SERIAL2", + 32: "SERIAL4", + 64: "SERIAL8", } // TypeName implements the ColTypeFormatter interface. -func (node *TSerial) TypeName() string { return serialNames[node.IntType] } +func (node *TSerial) TypeName() string { return serialNames[node.Width] } // Format implements the ColTypeFormatter interface. func (node *TSerial) Format(buf *bytes.Buffer, _ lex.EncodeFlags) { diff --git a/pkg/sql/logictest/testdata/logic_test/alter_column_type b/pkg/sql/logictest/testdata/logic_test/alter_column_type index 189cdd7eb00a..08f84dc12d5c 100644 --- a/pkg/sql/logictest/testdata/logic_test/alter_column_type +++ b/pkg/sql/logictest/testdata/logic_test/alter_column_type @@ -111,7 +111,7 @@ query TTBTTTB colnames SHOW COLUMNS FROM t ---- column_name data_type is_nullable column_default generation_expression indices is_hidden -a INTEGER true NULL · {} false +a INT true NULL · {} false rowid INT false unique_rowid() · {"primary"} true statement ok diff --git a/pkg/sql/logictest/testdata/logic_test/array b/pkg/sql/logictest/testdata/logic_test/array index 236ba6967cbf..25ef36a93c30 100644 --- a/pkg/sql/logictest/testdata/logic_test/array +++ b/pkg/sql/logictest/testdata/logic_test/array @@ -565,9 +565,9 @@ query TT SHOW CREATE TABLE a ---- a CREATE TABLE a ( - b SMALLINT[] NULL, - FAMILY "primary" (b, rowid) - ) + b INT2[] NULL, + FAMILY "primary" (b, rowid) +) statement error integer out of range for type SMALLINT \(column "b"\) INSERT INTO a VALUES (ARRAY[100000]) diff --git a/pkg/sql/logictest/testdata/logic_test/information_schema b/pkg/sql/logictest/testdata/logic_test/information_schema index 91dd3e962dda..d99262790b15 100644 --- a/pkg/sql/logictest/testdata/logic_test/information_schema +++ b/pkg/sql/logictest/testdata/logic_test/information_schema @@ -826,6 +826,9 @@ DROP TABLE nullability statement ok CREATE TABLE data_types ( a INT, + a2 INT2, + a4 INT4, + a8 INT8, b FLOAT, br REAL, c DECIMAL, @@ -848,6 +851,9 @@ WHERE table_schema = 'public' AND table_name = 'data_types' ---- table_name column_name data_type crdb_sql_type data_types a integer INT +data_types a2 smallint INT2 +data_types a4 integer INT4 +data_types a8 bigint INT8 data_types b double precision FLOAT8 data_types br real FLOAT4 data_types c numeric DECIMAL diff --git a/pkg/sql/logictest/testdata/logic_test/pg_catalog b/pkg/sql/logictest/testdata/logic_test/pg_catalog index 648c47971586..4b317230b784 100644 --- a/pkg/sql/logictest/testdata/logic_test/pg_catalog +++ b/pkg/sql/logictest/testdata/logic_test/pg_catalog @@ -1270,13 +1270,13 @@ SHOW COLUMNS FROM pg_catalog.pg_stat_activity column_name data_type is_nullable column_default generation_expression indices is_hidden datid OID true NULL · {} false datname NAME true NULL · {} false -pid INTEGER true NULL · {} false +pid INT true NULL · {} false usesysid OID true NULL · {} false username NAME true NULL · {} false application_name STRING true NULL · {} false client_addr INET true NULL · {} false client_hostname STRING true NULL · {} false -client_port INTEGER true NULL · {} false +client_port INT true NULL · {} false backend_start TIMESTAMPTZ true NULL · {} false xact_start TIMESTAMPTZ true NULL · {} false query_start TIMESTAMPTZ true NULL · {} false @@ -1284,8 +1284,8 @@ state_change TIMESTAMPTZ true NULL · wait_event_type STRING true NULL · {} false wait_event STRING true NULL · {} false state STRING true NULL · {} false -backend_xid INTEGER true NULL · {} false -backend_xmin INTEGER true NULL · {} false +backend_xid INT true NULL · {} false +backend_xmin INT true NULL · {} false query STRING true NULL · {} false diff --git a/pkg/sql/logictest/testdata/logic_test/serial b/pkg/sql/logictest/testdata/logic_test/serial index 2facb9c02eef..b7e0d2605e89 100644 --- a/pkg/sql/logictest/testdata/logic_test/serial +++ b/pkg/sql/logictest/testdata/logic_test/serial @@ -241,8 +241,8 @@ query TT SHOW CREATE TABLE smallbig ---- smallbig CREATE TABLE smallbig ( - a SMALLINT NOT NULL DEFAULT nextval('smallbig_a_seq1':::STRING), - b BIGINT NOT NULL DEFAULT nextval('smallbig_b_seq1':::STRING), + a INT2 NOT NULL DEFAULT nextval('smallbig_a_seq1':::STRING), + b INT8 NOT NULL DEFAULT nextval('smallbig_b_seq1':::STRING), c INT NULL, FAMILY "primary" (a, b, c, rowid) ) @@ -259,9 +259,9 @@ query TT SHOW CREATE TABLE serials ---- serials CREATE TABLE serials ( - a SMALLINT NOT NULL DEFAULT nextval('serials_a_seq1':::STRING), - b INTEGER NOT NULL DEFAULT nextval('serials_b_seq1':::STRING), - c BIGINT NOT NULL DEFAULT nextval('serials_c_seq1':::STRING), + a INT2 NOT NULL DEFAULT nextval('serials_a_seq1':::STRING), + b INT4 NOT NULL DEFAULT nextval('serials_b_seq1':::STRING), + c INT8 NOT NULL DEFAULT nextval('serials_c_seq1':::STRING), d INT NULL, FAMILY "primary" (a, b, c, d, rowid) ) diff --git a/pkg/sql/logictest/testdata/logic_test/table b/pkg/sql/logictest/testdata/logic_test/table index 0a0a74a7a604..2054ecfdb76b 100644 --- a/pkg/sql/logictest/testdata/logic_test/table +++ b/pkg/sql/logictest/testdata/logic_test/table @@ -357,7 +357,7 @@ query TTBTTTB colnames SHOW COLUMNS FROM alltypes ---- column_name data_type is_nullable column_default generation_expression indices is_hidden -cbigint BIGINT true NULL · {} false +cbigint INT8 true NULL · {} false cbigserial INT false unique_rowid() · {} false cblob BYTES true NULL · {} false cbool BOOL true NULL · {} false @@ -377,11 +377,11 @@ cfloat FLOAT8 true NULL · cfloat4 FLOAT4 true NULL · {} false cfloat8 FLOAT8 true NULL · {} false cint INT true NULL · {} false -cint2 SMALLINT true NULL · {} false -cint4 INTEGER true NULL · {} false -cint64 BIGINT true NULL · {} false -cint8 BIGINT true NULL · {} false -cinteger INTEGER true NULL · {} false +cint2 INT2 true NULL · {} false +cint4 INT4 true NULL · {} false +cint64 INT8 true NULL · {} false +cint8 INT8 true NULL · {} false +cinteger INT true NULL · {} false cinterval INTERVAL true NULL · {} false cjson JSONB true NULL · {} false cnumeric DECIMAL true NULL · {} false @@ -390,7 +390,7 @@ cnumeric21 DECIMAL(2,1) true NULL · cqchar "char" true NULL · {} false creal FLOAT4 true NULL · {} false cserial INT false unique_rowid() · {} false -csmallint SMALLINT true NULL · {} false +csmallint INT2 true NULL · {} false csmallserial INT false unique_rowid() · {} false cstring STRING true NULL · {} false cstring12 STRING(12) true NULL · {} false diff --git a/pkg/sql/opt/memo/private_storage_test.go b/pkg/sql/opt/memo/private_storage_test.go index 70f45aac3ba3..9cce42b6aece 100644 --- a/pkg/sql/opt/memo/private_storage_test.go +++ b/pkg/sql/opt/memo/private_storage_test.go @@ -363,7 +363,7 @@ func TestInternColType(t *testing.T) { // Arithmetic types. test(coltypes.Bool, &coltypes.TBool{}, true) - test(coltypes.SmallInt, &coltypes.TInt{Name: "SMALLINT", Width: 16, ImplicitWidth: true}, true) + test(coltypes.Int2, &coltypes.TInt{Width: 16}, true) test(coltypes.Float4, &coltypes.TFloat{Short: true}, true) test(coltypes.Float4, &coltypes.TFloat{}, false) diff --git a/pkg/sql/opt/norm/testdata/rules/scalar b/pkg/sql/opt/norm/testdata/rules/scalar index fd51d91468b2..5f2b5208a74e 100644 --- a/pkg/sql/opt/norm/testdata/rules/scalar +++ b/pkg/sql/opt/norm/testdata/rules/scalar @@ -182,7 +182,7 @@ project ├── a.arr::DECIMAL[] [type=decimal[], outer=(6)] ├── a.s::JSONB [type=jsonb, outer=(4)] ├── a.s::VARCHAR(2) [type=string, outer=(4)] - ├── a.i::SMALLINT::INT8 [type=int, outer=(2)] + ├── a.i::INT2::INT8 [type=int, outer=(2)] ├── a.s::CHAR::VARCHAR [type=string, outer=(4)] ├── ARRAY[1,2]::OIDVECTOR [type=oid[]] └── ARRAY[1,2]::INT2VECTOR [type=int[]] diff --git a/pkg/sql/opt/optbuilder/testdata/scalar b/pkg/sql/opt/optbuilder/testdata/scalar index 33d343fb45f8..5a442bf4b0f5 100644 --- a/pkg/sql/opt/optbuilder/testdata/scalar +++ b/pkg/sql/opt/optbuilder/testdata/scalar @@ -710,7 +710,7 @@ concat [type=int[]] ├── array: [type=int[]] │ ├── const: 1 [type=int] │ └── const: 2 [type=int] - └── cast: SMALLINT [type=int] + └── cast: INT2 [type=int] └── null [type=unknown] build-scalar diff --git a/pkg/sql/parser/parse_test.go b/pkg/sql/parser/parse_test.go index 889c54d99c37..abeff58e6e18 100644 --- a/pkg/sql/parser/parse_test.go +++ b/pkg/sql/parser/parse_test.go @@ -585,6 +585,9 @@ func TestParse(t *testing.T) { {`SELECT BOOL 'foo', 'foo'::BOOL`}, {`SELECT INT 'foo', 'foo'::INT`}, + {`SELECT INT2 'foo', 'foo'::INT2`}, + {`SELECT INT4 'foo', 'foo'::INT4`}, + {`SELECT INT8 'foo', 'foo'::INT8`}, {`SELECT FLOAT4 'foo', 'foo'::FLOAT4`}, {`SELECT DECIMAL 'foo', 'foo'::DECIMAL`}, {`SELECT CHAR 'foo', 'foo'::CHAR`}, @@ -1105,6 +1108,8 @@ func TestParse2(t *testing.T) { {`CREATE TABLE a (b BIGSERIAL, c SMALLSERIAL)`, `CREATE TABLE a (b SERIAL8, c SERIAL2)`}, + {`CREATE TABLE a (b BIGINT, c SMALLINT, d INTEGER)`, + `CREATE TABLE a (b INT8, c INT2, d INT)`}, {`CREATE TABLE a (b FLOAT, c FLOAT(10), d FLOAT(40), e REAL, f DOUBLE PRECISION)`, `CREATE TABLE a (b FLOAT8, c FLOAT4, d FLOAT8, e FLOAT4, f FLOAT8)`}, {`CREATE TABLE a (b NUMERIC, c NUMERIC(10), d DEC)`, diff --git a/pkg/sql/parser/sql.y b/pkg/sql/parser/sql.y index b8615eb2c8bf..381908ea3dd3 100644 --- a/pkg/sql/parser/sql.y +++ b/pkg/sql/parser/sql.y @@ -6007,10 +6007,18 @@ numeric: { $$.val = coltypes.Int } +| INTEGER + { + $$.val = coltypes.Int + } | INT2 - { - $$.val = coltypes.Int2 - } + { + $$.val = coltypes.Int2 + } +| SMALLINT + { + $$.val = coltypes.Int2 + } | INT4 { $$.val = coltypes.Int4 @@ -6021,19 +6029,11 @@ numeric: } | INT64 { - $$.val = coltypes.Int64 - } -| INTEGER - { - $$.val = coltypes.Integer - } -| SMALLINT - { - $$.val = coltypes.SmallInt + $$.val = coltypes.Int8 } | BIGINT { - $$.val = coltypes.BigInt + $$.val = coltypes.Int8 } | REAL { diff --git a/pkg/sql/schemachange/alter_column_type.go b/pkg/sql/schemachange/alter_column_type.go index 4a4025e83945..7c5b31b24aa3 100644 --- a/pkg/sql/schemachange/alter_column_type.go +++ b/pkg/sql/schemachange/alter_column_type.go @@ -165,7 +165,7 @@ func classifierWidth( switch { case oldType.Width == newType.Width: return ColumnConversionTrivial - case oldType.Width == 0: + case oldType.Width == 0 && newType.Width < 64: return ColumnConversionValidate case newType.Width == 0 || newType.Width > oldType.Width: return ColumnConversionTrivial diff --git a/pkg/sql/schemachange/alter_column_type_test.go b/pkg/sql/schemachange/alter_column_type_test.go index 181f42fb4003..7868a57d431a 100644 --- a/pkg/sql/schemachange/alter_column_type_test.go +++ b/pkg/sql/schemachange/alter_column_type_test.go @@ -98,16 +98,28 @@ func TestColumnConversions(t *testing.T) { }, {SemanticType: sqlbase.ColumnType_INT}: { - // Verify that INT -> INTEGER is a no-op { SemanticType: sqlbase.ColumnType_INT, - VisibleType: sqlbase.ColumnType_INTEGER, + VisibleType: sqlbase.ColumnType_BIGINT, + Width: 64, }: ColumnConversionTrivial, - {SemanticType: sqlbase.ColumnType_INT, Width: 32}: ColumnConversionValidate, + { + SemanticType: sqlbase.ColumnType_INT, + VisibleType: sqlbase.ColumnType_INTEGER, + Width: 32, + }: ColumnConversionValidate, }, {SemanticType: sqlbase.ColumnType_INT, Width: 32}: { - {SemanticType: sqlbase.ColumnType_INT, Width: 16}: ColumnConversionValidate, - {SemanticType: sqlbase.ColumnType_INT, Width: 64}: ColumnConversionTrivial, + { + SemanticType: sqlbase.ColumnType_INT, + VisibleType: sqlbase.ColumnType_SMALLINT, + Width: 16, + }: ColumnConversionValidate, + { + SemanticType: sqlbase.ColumnType_INT, + VisibleType: sqlbase.ColumnType_BIGINT, + Width: 64, + }: ColumnConversionTrivial, }, {SemanticType: sqlbase.ColumnType_STRING}: { @@ -207,7 +219,15 @@ func TestColumnConversions(t *testing.T) { } case sqlbase.ColumnType_INT: - insert = []interface{}{int64(math.MinInt64), int64(-1), int64(0), int64(1), int64(math.MaxInt64)} + insert = []interface{}{int64(-1), int64(0), int64(1)} + switch from.Width { + case 0, 64: + insert = append(insert, int64(math.MinInt64), int64(math.MaxInt64)) + case 32: + insert = append(insert, int64(math.MinInt32), int64(math.MaxInt32)) + case 16: + insert = append(insert, int64(math.MinInt16), int64(math.MaxInt16)) + } switch to.SemanticType { case sqlbase.ColumnType_INT: expect = insert diff --git a/pkg/sql/sem/tree/col_types_test.go b/pkg/sql/sem/tree/col_types_test.go index 127e31eb50e7..57eb06190f28 100644 --- a/pkg/sql/sem/tree/col_types_test.go +++ b/pkg/sql/sem/tree/col_types_test.go @@ -30,14 +30,10 @@ func TestParseColumnType(t *testing.T) { expectedType coltypes.T }{ {"BOOL", &coltypes.TBool{}}, - {"SMALLINT", &coltypes.TInt{Name: "SMALLINT", Width: 16, ImplicitWidth: true}}, - {"BIGINT", &coltypes.TInt{Name: "BIGINT"}}, - {"INTEGER", &coltypes.TInt{Name: "INTEGER"}}, - {"INT", &coltypes.TInt{Name: "INT"}}, - {"INT2", &coltypes.TInt{Name: "INT2", Width: 16, ImplicitWidth: true}}, - {"INT4", &coltypes.TInt{Name: "INT4", Width: 32, ImplicitWidth: true}}, - {"INT8", &coltypes.TInt{Name: "INT8"}}, - {"INT64", &coltypes.TInt{Name: "INT64"}}, + {"INT", &coltypes.TInt{}}, + {"INT2", &coltypes.TInt{Width: 16}}, + {"INT4", &coltypes.TInt{Width: 32}}, + {"INT8", &coltypes.TInt{Width: 64}}, {"FLOAT4", &coltypes.TFloat{Short: true}}, {"FLOAT8", &coltypes.TFloat{}}, {"DECIMAL", &coltypes.TDecimal{}}, diff --git a/pkg/sql/serial.go b/pkg/sql/serial.go index f8ffa9b14272..e376fa27a5a3 100644 --- a/pkg/sql/serial.go +++ b/pkg/sql/serial.go @@ -79,7 +79,7 @@ func (p *planner) processSerialInColumnDef( case sessiondata.SerialUsesSQLSequences: // With real sequences we can use exactly the requested type. - newSpec.Type = t.IntType + newSpec.Type = t.TInt } if serialNormalizationMode == sessiondata.SerialUsesRowID { diff --git a/pkg/sql/sqlbase/column_type_properties.go b/pkg/sql/sqlbase/column_type_properties.go index 0e939ffdaac3..5fe75fea808f 100644 --- a/pkg/sql/sqlbase/column_type_properties.go +++ b/pkg/sql/sqlbase/column_type_properties.go @@ -113,8 +113,16 @@ func PopulateTypeAttrs(base ColumnType, typ coltypes.T) (ColumnType, error) { switch t := typ.(type) { case *coltypes.TInt: base.Width = int32(t.Width) - if val, present := aliasToVisibleTypeMap[t.Name]; present { - base.VisibleType = val + + // For 2.1 nodes only Width is sufficient, but we also populate + // VisibleType for compatibility with pre-2.1 nodes. + switch t.Width { + case 16: + base.VisibleType = ColumnType_SMALLINT + case 64: + base.VisibleType = ColumnType_BIGINT + case 32: + base.VisibleType = ColumnType_INTEGER } case *coltypes.TFloat: @@ -176,22 +184,6 @@ func PopulateTypeAttrs(base ColumnType, typ coltypes.T) (ColumnType, error) { return base, nil } -// aliasToVisibleTypeMap maps type aliases to ColumnType_VisibleType variants -// so that the alias is persisted. When adding new column type aliases or new -// VisibleType variants, consider adding to this mapping as well. -// -// This is used by PopulateTypeAttrs when propagating a coltypes.T -// specification to a ColumnType suitable in a descriptor. -var aliasToVisibleTypeMap = map[string]ColumnType_VisibleType{ - coltypes.Int2.Name: ColumnType_SMALLINT, - coltypes.Int4.Name: ColumnType_INTEGER, - coltypes.Int8.Name: ColumnType_BIGINT, - coltypes.Int64.Name: ColumnType_BIGINT, - coltypes.Integer.Name: ColumnType_INTEGER, - coltypes.SmallInt.Name: ColumnType_SMALLINT, - coltypes.BigInt.Name: ColumnType_BIGINT, -} - // coltypeStringVariantToVisibleType encodes the visible type of a // coltypes.TString/TCollatedString variant. func coltypeStringVariantToVisibleType(c coltypes.TStringVariant) ColumnType_VisibleType { @@ -233,6 +225,10 @@ func (c *ColumnType) stringTypeName() string { // See also InformationSchemaVisibleType() below. func (c *ColumnType) SQLString() string { switch c.SemanticType { + case ColumnType_INT: + if name, ok := coltypes.IntegerTypeNames[int(c.Width)]; ok { + return name + } case ColumnType_STRING, ColumnType_COLLATEDSTRING: typName := c.stringTypeName() // In general, if there is a specified width we want to print it next @@ -294,12 +290,18 @@ func (c *ColumnType) InformationSchemaVisibleType() string { return "boolean" case ColumnType_INT: - // TODO(knz): This is not exactly correct. See #28690 for a - // followup. This needs to use the type width instead. - if c.VisibleType == ColumnType_NONE { + switch c.Width { + case 16: + return "smallint" + case 64: + return "bigint" + default: + // We report "integer" both for int4 and int. This is probably + // lying a bit, but it will appease clients that feed "int" into + // their CREATE TABLE and expect the pg "integer" name to come + // up in information_schema. return "integer" } - return c.VisibleType.String() case ColumnType_STRING, ColumnType_COLLATEDSTRING: switch c.VisibleType { @@ -393,7 +395,11 @@ func (c *ColumnType) MaxOctetLength() (int32, bool) { func (c *ColumnType) NumericPrecision() (int32, bool) { switch c.SemanticType { case ColumnType_INT: - return 64, true + width := c.Width + if width == 0 { + width = 64 + } + return width, true case ColumnType_FLOAT: _, prec := c.FloatProperties() return prec, true diff --git a/pkg/sql/sqlbase/structured.proto b/pkg/sql/sqlbase/structured.proto index e2b7e5312bdb..c6c1093b9370 100644 --- a/pkg/sql/sqlbase/structured.proto +++ b/pkg/sql/sqlbase/structured.proto @@ -28,46 +28,45 @@ import "gogoproto/gogo.proto"; // Simple (unary) scalars types // ---------------------------- // -// | SQL type | Semantic Type | Visible Type | Precision | Width | Notes | -// |--------------------------------|----------------|------------------|-----------|-------|-------------------| -// | NULL (unknown) | NULL | NONE | 0 | 0 | | -// | BOOL | BOOL | NONE | 0 | 0 | | -// | DATE | DATE | NONE | 0 | 0 | | -// | TIMESTAMP | TIMESTAMP | NONE | 0 | 0 | | -// | TIMESTAMPTZ | TIMESTAMPTZ | NONE | 0 | 0 | | -// | INTERVAL | INTERVAL | NONE | 0 | 0 | | -// | NAME | NAME | NONE | 0 | 0 | | -// | OID | OID | NONE | 0 | 0 | | -// | UUID | UUID | NONE | 0 | 0 | | -// | INET | INET | NONE | 0 | 0 | | -// | TIME | TIME | NONE | 0 | 0 | | -// | JSON | JSON | NONE | 0 | 0 | | -// | | | | | | | -// | BYTES | BYTES | NONE | 0 | 0 | | -// | | | | | | | -// | STRING | STRING | NONE | 0 | 0 | | -// | STRING(N) | STRING | NONE | 0 | N | | -// | VARCHAR | STRING | VARCHAR | 0 | 0 | | -// | VARCHAR(N) | STRING | VARCHAR | 0 | N | | -// | CHAR | STRING | CHAR | 0 | 1 | | -// | CHAR(N) | STRING | CHAR | 0 | N | | -// | "char" | STRING | QCHAR | 0 | 0 | | -// | | | | | | | -// | COLLATEDSTRING | COLLATEDSTRING | NONE | 0 | 0 | also uses Locale | -// | COLLATEDSTRING(N) | COLLATEDSTRING | NONE | 0 | N | also uses Locale | -// | | | | | | | -// | DECIMAL | DECIMAL | NONE | 0 | 0 | | -// | DECIMAL(N) | DECIMAL | NONE | N | 0 | | -// | DECIMAL(N,M) | DECIMAL | NONE | N | M | | -// | | | | | | | -// | FLOAT8 | FLOAT | NONE | 0 | 0 | | -// | FLOAT4 | FLOAT | REAL | 0 | 0 | | -// | | | | | | | -// | INT | INT | NONE | 0 | 0 | See #28690 | -// | INTEGER | INT | INTEGER | 0 | 0 | See #28690 | -// | INT2,SMALLINT | INT | SMALLINT | 0 | 16 | See #28690 | -// | INT4 | INT | INTEGER | 0 | 32 | See #28690 | -// | INT8,INT64,BIGINT | INT | BIGINT | 0 | 64 | See #28690 | +// | SQL type | Semantic Type | Visible Type | Precision | Width | Notes | +// |-------------------|----------------|--------------|-----------|-------|------------------| +// | NULL (unknown) | NULL | NONE | 0 | 0 | | +// | BOOL | BOOL | NONE | 0 | 0 | | +// | DATE | DATE | NONE | 0 | 0 | | +// | TIMESTAMP | TIMESTAMP | NONE | 0 | 0 | | +// | TIMESTAMPTZ | TIMESTAMPTZ | NONE | 0 | 0 | | +// | INTERVAL | INTERVAL | NONE | 0 | 0 | | +// | NAME | NAME | NONE | 0 | 0 | | +// | OID | OID | NONE | 0 | 0 | | +// | UUID | UUID | NONE | 0 | 0 | | +// | INET | INET | NONE | 0 | 0 | | +// | TIME | TIME | NONE | 0 | 0 | | +// | JSON | JSON | NONE | 0 | 0 | | +// | | | | | | | +// | BYTES | BYTES | NONE | 0 | 0 | | +// | | | | | | | +// | STRING | STRING | NONE | 0 | 0 | | +// | STRING(N) | STRING | NONE | 0 | N | | +// | VARCHAR | STRING | VARCHAR | 0 | 0 | | +// | VARCHAR(N) | STRING | VARCHAR | 0 | N | | +// | CHAR | STRING | CHAR | 0 | 1 | | +// | CHAR(N) | STRING | CHAR | 0 | N | | +// | "char" | STRING | QCHAR | 0 | 0 | | +// | | | | | | | +// | COLLATEDSTRING | COLLATEDSTRING | NONE | 0 | 0 | also uses Locale | +// | COLLATEDSTRING(N) | COLLATEDSTRING | NONE | 0 | N | also uses Locale | +// | | | | | | | +// | DECIMAL | DECIMAL | NONE | 0 | 0 | | +// | DECIMAL(N) | DECIMAL | NONE | N | 0 | | +// | DECIMAL(N,M) | DECIMAL | NONE | N | M | | +// | | | | | | | +// | FLOAT8 | FLOAT | NONE | 0 | 0 | | +// | FLOAT4 | FLOAT | REAL | 0 | 0 | | +// | | | | | | | +// | INT,INTEGER | INT | NONE | 0 | 0 | | +// | INT2,SMALLINT | INT | NONE | 0 | 16 | | +// | INT4 | INT | NONE | 0 | 32 | | +// | INT8,INT64,BIGINT | INT | NONE | 0 | 64 | | // // Tuple columns // ------------- @@ -151,9 +150,9 @@ message ColumnType { enum VisibleType { NONE = 0; - INTEGER = 1; - SMALLINT = 2; - BIGINT = 3; + INTEGER = 1; // Deprecated, remove post-2.2. + SMALLINT = 2; // Deprecated, remove post-2.2. + BIGINT = 3; // Deprecated, remove post-2.2. reserved 4; REAL = 5; DOUBLE_PRECISION = 6; // Deprecated, remove post-2.2. diff --git a/pkg/sql/table_test.go b/pkg/sql/table_test.go index 5fe14303e27a..9190f6ff6dfd 100644 --- a/pkg/sql/table_test.go +++ b/pkg/sql/table_test.go @@ -45,27 +45,27 @@ func TestMakeTableDescColumns(t *testing.T) { }, { "INT2", - sqlbase.ColumnType{SemanticType: sqlbase.ColumnType_INT, Width: 16, VisibleType: sqlbase.ColumnType_SMALLINT}, + sqlbase.ColumnType{SemanticType: sqlbase.ColumnType_INT, VisibleType: sqlbase.ColumnType_SMALLINT, Width: 16}, true, }, { "INT4", - sqlbase.ColumnType{SemanticType: sqlbase.ColumnType_INT, Width: 32, VisibleType: sqlbase.ColumnType_INTEGER}, + sqlbase.ColumnType{SemanticType: sqlbase.ColumnType_INT, VisibleType: sqlbase.ColumnType_INTEGER, Width: 32}, true, }, { "INT8", - sqlbase.ColumnType{SemanticType: sqlbase.ColumnType_INT, VisibleType: sqlbase.ColumnType_BIGINT}, + sqlbase.ColumnType{SemanticType: sqlbase.ColumnType_INT, VisibleType: sqlbase.ColumnType_BIGINT, Width: 64}, true, }, { "INT64", - sqlbase.ColumnType{SemanticType: sqlbase.ColumnType_INT, VisibleType: sqlbase.ColumnType_BIGINT}, + sqlbase.ColumnType{SemanticType: sqlbase.ColumnType_INT, VisibleType: sqlbase.ColumnType_BIGINT, Width: 64}, true, }, { "BIGINT", - sqlbase.ColumnType{SemanticType: sqlbase.ColumnType_INT, VisibleType: sqlbase.ColumnType_BIGINT}, + sqlbase.ColumnType{SemanticType: sqlbase.ColumnType_INT, VisibleType: sqlbase.ColumnType_BIGINT, Width: 64}, true, }, {