Skip to main content
YSQL supports all PostgreSQL 15 data types. The following table lists primitive and compound data types available in YSQL.

Numeric Types

Integer Types

Data TypeAliasStorageRangeDescription
smallintint22 bytes-32,768 to 32,767Small-range integer
integerint, int44 bytes-2,147,483,648 to 2,147,483,647Typical integer
bigintint88 bytes-9,223,372,036,854,775,808 to 9,223,372,036,854,775,807Large-range integer
CREATE TABLE integers_example (
  id SERIAL PRIMARY KEY,
  small_num SMALLINT,
  regular_num INTEGER,
  big_num BIGINT
);

INSERT INTO integers_example (small_num, regular_num, big_num)
VALUES (100, 1000000, 9223372036854775807);

Serial Types

Data TypeAliasStorageRangeDescription
smallserialserial22 bytes1 to 32,767Auto-incrementing small integer
serialserial44 bytes1 to 2,147,483,647Auto-incrementing integer
bigserialserial88 bytes1 to 9,223,372,036,854,775,807Auto-incrementing large integer
CREATE TABLE users (
  user_id SERIAL PRIMARY KEY,
  username TEXT NOT NULL
);

INSERT INTO users (username) VALUES ('alice'), ('bob');
-- user_id is automatically generated

Floating-Point Types

Data TypeAliasStoragePrecisionDescription
realfloat44 bytes6 decimal digitsSingle precision
double precisionfloat88 bytes15 decimal digitsDouble precision
CREATE TABLE measurements (
  sensor_id INT PRIMARY KEY,
  temperature REAL,
  precise_value DOUBLE PRECISION
);

Arbitrary Precision

numeric
numeric[(p, s)]
Exact numeric with selectable precision. Parameter p is precision (total digits), s is scale (decimal digits).
decimal
decimal[(p, s)]
Alias for numeric. Exact numeric with selectable precision.
CREATE TABLE financial (
  transaction_id INT PRIMARY KEY,
  amount NUMERIC(10, 2),  -- 10 digits total, 2 after decimal
  price DECIMAL(8, 3)
);

INSERT INTO financial VALUES (1, 12345.67, 999.999);

Monetary Type

CREATE TABLE products (
  product_id INT PRIMARY KEY,
  price MONEY
);

INSERT INTO products VALUES (1, '$19.99');

Character Types

Data TypeDescription
character varying(n) / varchar(n)Variable-length with limit
character(n) / char(n)Fixed-length, blank padded
textVariable unlimited length
CREATE TABLE strings_example (
  id INT PRIMARY KEY,
  code CHAR(5),           -- Fixed 5 characters
  name VARCHAR(100),      -- Up to 100 characters
  description TEXT        -- Unlimited length
);

INSERT INTO strings_example VALUES 
  (1, 'ABC01', 'Sample Product', 'This is a long description...');

Binary Data

bytea
bytea
Binary string data type for storing raw bytes. Useful for images, files, or encrypted data.
CREATE TABLE files (
  file_id INT PRIMARY KEY,
  file_name TEXT,
  file_data BYTEA
);

-- Insert binary data
INSERT INTO files VALUES (1, 'image.png', '\\xDEADBEEF'::bytea);

Date/Time Types

Data TypeStorageDescriptionRange
timestamp8 bytesDate and time (no timezone)4713 BC to 294276 AD
timestamptz8 bytesDate and time with timezone4713 BC to 294276 AD
date4 bytesDate (no time)4713 BC to 5874897 AD
time8 bytesTime of day (no date)00:00:00 to 24:00:00
timetz12 bytesTime of day with timezone00:00:00+1559 to 24:00:00-1559
interval16 bytesTime interval-178000000 years to 178000000 years
CREATE TABLE events (
  event_id INT PRIMARY KEY,
  event_time TIMESTAMP,
  event_time_tz TIMESTAMPTZ,
  event_date DATE,
  duration INTERVAL
);

INSERT INTO events VALUES (
  1,
  '2024-03-15 14:30:00',
  '2024-03-15 14:30:00-08',
  '2024-03-15',
  INTERVAL '2 hours 30 minutes'
);

SELECT 
  event_time,
  event_time + duration AS end_time,
  EXTRACT(YEAR FROM event_date) AS year
FROM events;

Boolean Type

CREATE TABLE flags (
  id INT PRIMARY KEY,
  is_active BOOLEAN DEFAULT TRUE,
  is_deleted BOOL DEFAULT FALSE
);

INSERT INTO flags VALUES 
  (1, TRUE, FALSE),
  (2, 't', 'f'),      -- Alternative syntax
  (3, 'yes', 'no'),   -- Alternative syntax
  (4, '1', '0');      -- Alternative syntax

SELECT * FROM flags WHERE is_active AND NOT is_deleted;

UUID Type

uuid
uuid
Universally Unique Identifier (128-bit). Useful for distributed primary keys.
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

CREATE TABLE sessions (
  session_id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  user_id INT,
  created_at TIMESTAMP DEFAULT now()
);

INSERT INTO sessions (user_id) VALUES (1001);
SELECT * FROM sessions;

JSON Types

YSQL supports both json and jsonb types for storing JSON data.
json
json
Textual JSON data. Preserves formatting and order but slower to process.
jsonb
jsonb
Binary JSON data. Faster to process, supports indexing. Recommended for most use cases.
CREATE TABLE api_logs (
  log_id SERIAL PRIMARY KEY,
  request_data JSONB,
  response_data JSON,
  created_at TIMESTAMP DEFAULT now()
);

INSERT INTO api_logs (request_data, response_data) VALUES (
  '{"method": "GET", "path": "/api/users", "params": {"limit": 10}}',
  '{"status": 200, "data": [{"id": 1, "name": "Alice"}]}'
);

-- Query JSON data
SELECT 
  request_data->>'method' AS http_method,
  request_data->'params'->>'limit' AS limit,
  response_data->>'status' AS status
FROM api_logs;

-- Create index on JSONB
CREATE INDEX idx_request_method ON api_logs ((request_data->>'method'));

Array Types

Any data type can be made into an array by appending [].
CREATE TABLE array_example (
  id INT PRIMARY KEY,
  tags TEXT[],
  scores INT[],
  matrix INT[][]
);

INSERT INTO array_example VALUES (
  1,
  ARRAY['postgresql', 'yugabytedb', 'sql'],
  ARRAY[95, 87, 92],
  ARRAY[[1,2],[3,4]]
);

-- Access array elements (1-indexed)
SELECT 
  tags[1] AS first_tag,
  scores[2] AS second_score,
  array_length(tags, 1) AS tag_count
FROM array_example;

-- Query with ANY
SELECT * FROM array_example 
WHERE 'sql' = ANY(tags);

Range Types

Range TypeDescription
int4rangeRange of integer
int8rangeRange of bigint
numrangeRange of numeric
tsrangeRange of timestamp
tstzrangeRange of timestamptz
daterangeRange of date
CREATE TABLE reservations (
  reservation_id INT PRIMARY KEY,
  room_number INT,
  stay_period DATERANGE,
  price_range NUMRANGE
);

INSERT INTO reservations VALUES (
  1,
  101,
  '[2024-03-15, 2024-03-20)',
  '[100.00, 200.00]'
);

-- Check if date is in range
SELECT * FROM reservations 
WHERE stay_period @> '2024-03-17'::date;

-- Check for overlapping ranges
SELECT * FROM reservations 
WHERE stay_period && '[2024-03-18, 2024-03-22)'::daterange;

Geometric Types

TypeDescriptionExample
pointPoint on a plane(x,y)
lineInfinite line{A,B,C}
lsegLine segment[(x1,y1),(x2,y2)]
boxRectangular box(x1,y1),(x2,y2)
pathClosed or open path[(x1,y1),...]
polygonPolygon((x1,y1),...)
circleCircle<(x,y),r>
CREATE TABLE locations (
  location_id INT PRIMARY KEY,
  position POINT,
  area CIRCLE,
  boundary BOX
);

INSERT INTO locations VALUES (
  1,
  '(10.5, 20.3)',
  '<(0,0),5>',
  '(0,0),(10,10)'
);

Network Address Types

CREATE TABLE network_devices (
  device_id INT PRIMARY KEY,
  ip_address INET,
  network CIDR,
  mac_address MACADDR
);

INSERT INTO network_devices VALUES (
  1,
  '192.168.1.100',
  '192.168.1.0/24',
  '08:00:2b:01:02:03'
);

SELECT * FROM network_devices 
WHERE ip_address << '192.168.1.0/24'::inet;

Enumerated Types

CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy');

CREATE TABLE persons (
  person_id INT PRIMARY KEY,
  name TEXT,
  current_mood mood
);

INSERT INTO persons VALUES (1, 'Alice', 'happy');

SELECT * FROM persons WHERE current_mood = 'happy';

Composite Types

CREATE TYPE address AS (
  street TEXT,
  city TEXT,
  state CHAR(2),
  zip_code VARCHAR(10)
);

CREATE TABLE companies (
  company_id INT PRIMARY KEY,
  name TEXT,
  headquarters address
);

INSERT INTO companies VALUES (
  1,
  'YugabyteDB Inc',
  ROW('123 Main St', 'San Francisco', 'CA', '94105')
);

SELECT 
  name,
  (headquarters).city,
  (headquarters).state
FROM companies;

Special Types

Text Search Types

CREATE TABLE documents (
  doc_id INT PRIMARY KEY,
  title TEXT,
  body TEXT,
  tsv TSVECTOR
);

INSERT INTO documents VALUES (
  1,
  'PostgreSQL Guide',
  'PostgreSQL is a powerful database',
  to_tsvector('english', 'PostgreSQL is a powerful database')
);

CREATE INDEX idx_tsv ON documents USING gin(tsv);

SELECT * FROM documents 
WHERE tsv @@ to_tsquery('english', 'database');

XML Type

CREATE TABLE xml_data (
  id INT PRIMARY KEY,
  data XML
);

INSERT INTO xml_data VALUES (
  1,
  '<book><title>Database Systems</title></book>'
);

Type Conversion

-- Explicit casting
SELECT 
  '123'::INTEGER AS int_value,
  123::TEXT AS text_value,
  CAST('2024-03-15' AS DATE) AS date_value;

-- Type coercion
SELECT 
  1 + 2.5 AS mixed_numeric,  -- Returns 3.5 (numeric)
  'Value: ' || 42 AS concat;  -- Returns 'Value: 42'

Index Support

Not all data types can be used in index key columns: Supported in indexes:
  • All numeric types
  • Character types (text, varchar, char)
  • Date/time types
  • UUID
  • Boolean
  • JSONB (with GIN indexes)
Not supported in primary key/index:
  • JSON (use JSONB instead)
  • Arrays (without special index types)
  • Geometric types (limited support)
  • Network types
-- Supported
CREATE INDEX idx_timestamp ON events(event_time);
CREATE INDEX idx_jsonb ON api_logs USING gin(request_data);

-- Creates GIN index for arrays
CREATE INDEX idx_tags ON array_example USING gin(tags);

Additional Resources

For more detailed information, see:

Build docs developers (and LLMs) love