Skip to content

Commit 26dcd60

Browse files
VladlenPopolitovhackorum
authored andcommitted
add type INT16
1 parent b91f79c commit 26dcd60

21 files changed

Lines changed: 8802 additions & 0 deletions

contrib/int16/Makefile

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# contrib/int16/Makefile
2+
3+
MODULE_big = int16
4+
OBJS = \
5+
$(WIN32RES) \
6+
int16.o \
7+
int16_numeric.o \
8+
int16_funcs.o
9+
10+
EXTENSION = int16
11+
DATA = int16--1.0.sql
12+
PGFILEDESC = "int16 - 128-bit signed integer data type"
13+
14+
HEADERS = int16.h
15+
16+
REGRESS = init int16 int16_overflow int16_numeric int16_funcs
17+
18+
ifdef USE_PGXS
19+
PG_CONFIG = pg_config
20+
PGXS := $(shell $(PG_CONFIG) --pgxs)
21+
include $(PGXS)
22+
else
23+
subdir = contrib/int16
24+
top_builddir = ../..
25+
include $(top_builddir)/src/Makefile.global
26+
include $(top_srcdir)/contrib/contrib-global.mk
27+
endif

contrib/int16/README

Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
PostgreSQL contrib module int16
2+
===================================
3+
4+
This module provides the int16 data type, a 128-bit signed integer with a
5+
range of approximately -1.7e38 to +1.7e38.
6+
7+
DESCRIPTION
8+
-----------
9+
10+
The int16 extension adds a 128-bit signed integer data type to PostgreSQL,
11+
extending the built-in int8 (bigint) type. It is designed for applications
12+
that require integer values beyond the 64-bit range.
13+
14+
Key features:
15+
- Storage: 16 bytes, passed by reference, aligned on 8-byte boundary
16+
- Full arithmetic: +, -, *, /, %, unary -, unary +, abs()
17+
- Full comparison: =, <>, <, >, <=, >=, and 3-way cmp()
18+
- Bitwise operators: &, |, #, ~, <<, >>
19+
- Cross-type operations with int2, int4, int8 (arithmetic and comparison)
20+
- Type casts: implicit from int2/int4/int8/numeric, assignment to int2/int4/int8/numeric
21+
- B-tree and Hash index support (including deduplication and skip scan)
22+
- Aggregates: sum(), avg(), min(), max() (parallel-safe)
23+
- Window functions: RANGE support via in_range()
24+
- generate_series() for int16 ranges
25+
- Mathematical functions: gcd(), lcm(), factorial()
26+
27+
28+
BUILDING
29+
--------
30+
31+
To build the module from the PostgreSQL source tree:
32+
33+
cd contrib/int16
34+
make USE_PGXS=1
35+
make USE_PGXS=1 install
36+
37+
After installation, enable the extension in your database:
38+
39+
CREATE EXTENSION int16;
40+
41+
USAGE
42+
-----
43+
44+
Once installed, the int16 type is available in all schemas.
45+
46+
Basic usage:
47+
48+
SELECT '123456789012345678901234567890'::int16;
49+
50+
Create tables with int16 columns:
51+
52+
CREATE TABLE t (id serial PRIMARY KEY, value int16);
53+
INSERT INTO t (value) VALUES ('170141183460469231731687303715884105727'::int16);
54+
SELECT * FROM t WHERE value > '100000000000000000000'::int16;
55+
56+
FUNCTIONS AND OPERATORS
57+
-----------------------
58+
59+
Input/Output:
60+
int16in(cstring) - Parse string to int16
61+
int16out(int16) - Convert int16 to string
62+
int16recv(internal) - Receive binary data (16 bytes, network byte order)
63+
int16send(int16) - Send binary data
64+
65+
Arithmetic (int16 op int16):
66+
+ int16pl - Addition
67+
- int16mi - Subtraction
68+
* int16mul - Multiplication
69+
/ int16div - Integer division
70+
% int16mod - Remainder
71+
- int16um - Unary minus
72+
+ int16up - Unary plus
73+
@ int16abs - Absolute value
74+
75+
Comparison (int16 op int16):
76+
= int16eq - Equal
77+
<> int16ne - Not equal
78+
< int16lt - Less than
79+
> int16gt - Greater than
80+
<= int16le - Less than or equal
81+
>= int16ge - Greater than or equal
82+
int16_cmp(a,b) - Three-way comparison (-1, 0, 1)
83+
84+
Bitwise:
85+
& int16and - Bitwise AND
86+
| int16or - Bitwise OR
87+
# int16xor - Bitwise XOR
88+
~ int16not - Bitwise NOT
89+
<< int16shl - Left shift (n is int4)
90+
>> int16shr - Arithmetic right shift (n is int4)
91+
92+
Cross-type arithmetic (int16 with int8/int4/int2, both directions):
93+
+, -, *, / - Functions: int168pl, int816pl, int164pl, int416pl, etc.
94+
95+
Cross-type comparison (int16 with int8/int4/int2, both directions):
96+
=, <>, <, >, <=, >= - Functions: int168eq, int816eq, int164eq, etc.
97+
_cmp functions - int168cmp, int816cmp, int164cmp, etc.
98+
99+
Type casts:
100+
int8/int4/int2 -> int16 IMPLICIT (widening)
101+
int16 -> int8/int4/int2 ASSIGNMENT (narrowing)
102+
int16 -> numeric IMPLICIT (widening)
103+
numeric -> int16 ASSIGNMENT (narrowing)
104+
105+
Aggregates (parallel-safe):
106+
sum(int16) -> int16 - Sum (error on overflow)
107+
avg(int16) -> numeric - Average
108+
min(int16) -> int16 - Minimum
109+
max(int16) -> int16 - Maximum
110+
111+
Mathematical functions:
112+
gcd(int16, int16) - Greatest common divisor
113+
lcm(int16, int16) - Least common multiple
114+
factorial(int16) - Factorial (returns numeric)
115+
116+
generate_series:
117+
generate_series(start int16, stop int16) - Step 1
118+
generate_series(start int16, stop int16, step int16) - Custom step
119+
120+
Window functions:
121+
in_range(val int16, base int16, offset int16, ...) - RANGE frame support
122+
123+
Index support:
124+
B-tree - int16_ops (includes sortsupport, in_range, equalimage, skipsupport)
125+
Hash - int16_ops
126+
127+
EXAMPLES
128+
--------
129+
130+
1. Basic arithmetic:
131+
132+
SELECT '100000000000000000000'::int16 + '1'::int16;
133+
-- 100000000000000000001
134+
135+
SELECT '100000000000000000000'::int16 * '2'::int16;
136+
-- 200000000000000000000
137+
138+
SELECT '100000000000000000000'::int16 / '3'::int16;
139+
-- 33333333333333333333
140+
141+
SELECT @('-100000000000000000000'::int16);
142+
-- 100000000000000000000
143+
144+
2. Cross-type operations:
145+
146+
SELECT '100'::int16 + 50; -- int16 + int4 -> int16
147+
SELECT 50 + '100'::int16; -- int4 + int16 -> int16
148+
SELECT '100'::int16 + 50::int8; -- int16 + int8 -> int16
149+
SELECT '100'::int16 = 100; -- true
150+
151+
3. Aggregates:
152+
153+
CREATE TABLE big_values (val int16);
154+
INSERT INTO big_values VALUES
155+
('100000000000000000000'::int16),
156+
('200000000000000000000'::int16),
157+
('300000000000000000000'::int16);
158+
159+
SELECT sum(val) FROM big_values; -- 600000000000000000000
160+
SELECT avg(val) FROM big_values; -- 200000000000000000000.0000000000000000
161+
162+
4. generate_series:
163+
164+
SELECT * FROM generate_series('1'::int16, '5'::int16);
165+
SELECT * FROM generate_series('5'::int16, '1'::int16, '-1'::int16);
166+
167+
5. Window functions with RANGE:
168+
169+
SELECT id, amount, count(*) OVER (
170+
ORDER BY amount
171+
RANGE BETWEEN '10'::int16 PRECEDING AND '10'::int16 FOLLOWING
172+
) FROM sales;
173+
174+
6. B-tree and Hash indexes:
175+
176+
CREATE TABLE t (val int16);
177+
CREATE INDEX ON t USING btree (val);
178+
CREATE INDEX ON t USING hash (val);
179+
180+
LIMITATIONS
181+
-----------
182+
183+
- Passed by reference: int16 is 16 bytes and passed by reference (like uuid),
184+
not by value (like int8). This may introduce slight overhead compared to int8.
185+
186+
- Missing functions: ceil(), floor(), round(), sign(), sqrt(), width_bucket()
187+
are not provided. Cast to numeric for these operations:
188+
SELECT round('123'::int16::numeric);
189+
190+
- avg() returns numeric: Average is computed in numeric because int16 cannot
191+
always represent the exact division result.
192+
193+
- sum() can overflow: Sum is computed as int16 and raises an error on overflow
194+
(unlike sum(int8) which uses numeric internally).
195+
196+
- factorial() limited to 32177: For n > 32177, the result overflows numeric.
197+
198+
- No GiST, GIN, SP-GiST, BRIN support: Only B-tree and Hash indexes are
199+
implemented.
200+
201+
- Binary protocol: int16recv expects exactly 16 bytes in network byte order
202+
(most significant 64-bit block first).
203+
204+
- gcd and lcm with INT16_MIN:
205+
gcd(INT16_MIN, 0), gcd(INT16_MIN, INT16_MIN), and lcm(INT16_MAX, 2)
206+
raise overflow errors because the absolute value of INT16_MIN is not
207+
representable in 128 bits. gcd(INT16_MIN, -1) returns 1.
208+
209+
210+
TESTING
211+
-------
212+
213+
Run the regression tests (requires a running PostgreSQL server):
214+
215+
cd contrib/int16
216+
make installcheck
217+
218+
Test files are located in sql/, expected results in expected/.

contrib/int16/expected/init.out

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
CREATE EXTENSION int16;

0 commit comments

Comments
 (0)