CREATE EXTENSION varint;

-- Basic type comparison tests for varint64
SELECT   '64'::VARINT64 =    '64'::VARINT64 AS t;
SELECT    '0'::VARINT64 =     '1'::VARINT64 AS f;

SELECT   '64'::VARINT64 <>   '64'::VARINT64 AS f;
SELECT    '0'::VARINT64 <>    '1'::VARINT64 AS t;

SELECT   '-1'::VARINT64 <    '64'::VARINT64 AS t;
SELECT '-256'::VARINT64 <   '256'::VARINT64 AS t;
SELECT   '64'::VARINT64 <    '64'::VARINT64 AS f;
SELECT   '64'::VARINT64 <    '63'::VARINT64 AS f;
SELECT '1024'::VARINT64 < '-4096'::VARINT64 AS f;

SELECT   '-1'::VARINT64 <=    '64'::VARINT64 AS t;
SELECT '-256'::VARINT64 <=   '256'::VARINT64 AS t;
SELECT   '64'::VARINT64 <=    '64'::VARINT64 AS t;
SELECT   '64'::VARINT64 <=    '63'::VARINT64 AS f;
SELECT '1024'::VARINT64 <= '-4096'::VARINT64 AS f;

SELECT   '-1'::VARINT64 >    '64'::VARINT64 AS f;
SELECT '-256'::VARINT64 >   '256'::VARINT64 AS f;
SELECT   '64'::VARINT64 >    '64'::VARINT64 AS f;
SELECT   '64'::VARINT64 >    '63'::VARINT64 AS t;
SELECT '1024'::VARINT64 > '-4096'::VARINT64 AS t;

SELECT   '-1'::VARINT64 >=    '64'::VARINT64 AS f;
SELECT '-256'::VARINT64 >=   '256'::VARINT64 AS f;
SELECT   '64'::VARINT64 >=    '64'::VARINT64 AS t;
SELECT   '64'::VARINT64 >=    '63'::VARINT64 AS t;
SELECT '1024'::VARINT64 >= '-4096'::VARINT64 AS t;

-- varint64 <=> {int2,int4,int8} conversion tests
SELECT       '0'::VARINT64::INT2 AS "0";
SELECT       '0'::INT2::VARINT64 AS "0";
SELECT   '32767'::INT2::VARINT64 AS "32767";
SELECT   '32767'::VARINT64::INT2 AS "32767";
SELECT  '-32768'::INT2::VARINT64 AS "-32768";
SELECT  '-32768'::VARINT64::INT2 AS "-32768";
SELECT   '32768'::INT2::VARINT64 AS "ERROR: 32768";
SELECT   '32768'::VARINT64::INT2 AS "ERROR: 32768";
SELECT  '-32769'::INT2::VARINT64 AS "ERROR: -32769";
SELECT  '-32769'::VARINT64::INT2 AS "ERROR: -32769";

SELECT            '0'::VARINT64::INT4 AS "0";
SELECT            '0'::INT4::VARINT64 AS "0";
SELECT   '2147483647'::INT4::VARINT64 AS "2147483647";
SELECT   '2147483647'::VARINT64::INT4 AS "2147483647";
SELECT  '-2147483648'::INT4::VARINT64 AS "-2147483648";
SELECT  '-2147483648'::VARINT64::INT4 AS "-2147483648";
SELECT   '2147483648'::INT4::VARINT64 AS "ERROR: 2147483648";
SELECT   '2147483648'::VARINT64::INT4 AS "ERROR: 2147483648";
SELECT  '-2147483649'::INT4::VARINT64 AS "ERROR: -2147483649";
SELECT  '-2147483649'::VARINT64::INT4 AS "ERROR: -2147483649";

SELECT                     '0'::VARINT64::INT8 AS "0";
SELECT                     '0'::INT8::VARINT64 AS "0";
SELECT   '9223372036854775807'::INT8::VARINT64 AS "9223372036854775807";
SELECT   '9223372036854775807'::VARINT64::INT8 AS "9223372036854775807";
SELECT  '-9223372036854775808'::INT8::VARINT64 AS "-9223372036854775808";
SELECT  '-9223372036854775808'::VARINT64::INT8 AS "-9223372036854775808";
SELECT   '9223372036854775808'::INT8::VARINT64 AS "ERROR: 9223372036854775808";
SELECT   '9223372036854775808'::VARINT64::INT8 AS "ERROR: 9223372036854775808";
SELECT  '-9223372036854775809'::INT8::VARINT64 AS "ERROR: -9223372036854775809";
SELECT  '-9223372036854775809'::VARINT64::INT8 AS "ERROR: -9223372036854775809";

-- Implicit type conversion tests for varint64
SELECT 1::INT2 + 1::VARINT64 AS "2";
SELECT 2::INT2 + 2::VARINT64 AS "4";
SELECT 3::INT2 + 3::VARINT64 AS "6";

-- Durable type comparison tests for varint64
CREATE TABLE varint64_table(lhs VARINT64, rhs VARINT64);

-- Leading/trailing spaces using two or more spaces or tabs
INSERT INTO varint64_table VALUES('  127  ','  256');
INSERT INTO varint64_table VALUES('128  ','		4096');
INSERT INTO varint64_table VALUES('4096		','		-4096		');
INSERT INTO varint64_table VALUES('4567890123456789','4567890123456789');
INSERT INTO varint64_table VALUES('+4567890123456789','-4567890123456789');
INSERT INTO varint64_table VALUES('-1',                   '0');
INSERT INTO varint64_table VALUES('-1',                  '-1');
INSERT INTO varint64_table VALUES('-1',                   '1');
INSERT INTO varint64_table VALUES('-1',                  '63');
INSERT INTO varint64_table VALUES('-1',                 '-64');
INSERT INTO varint64_table VALUES('-1',                  '64');
INSERT INTO varint64_table VALUES('-1',                 '-65');
INSERT INTO varint64_table VALUES('-1',                '8191');
INSERT INTO varint64_table VALUES('-1',               '-8192');
INSERT INTO varint64_table VALUES('-1',                '8192');
INSERT INTO varint64_table VALUES('-1',               '-8193');
INSERT INTO varint64_table VALUES('-1',             '1048575');
INSERT INTO varint64_table VALUES('-1',            '-1048576');
INSERT INTO varint64_table VALUES('-1',             '1048576');
INSERT INTO varint64_table VALUES('-1',            '-1048577');
INSERT INTO varint64_table VALUES('-1',           '134217727');
INSERT INTO varint64_table VALUES('-1',          '-134217728');
INSERT INTO varint64_table VALUES('-1',           '134217728');
INSERT INTO varint64_table VALUES('-1',          '-134217729');
INSERT INTO varint64_table VALUES('-1',         '17179869183');
INSERT INTO varint64_table VALUES('-1',        '-17179869184');
INSERT INTO varint64_table VALUES('-1',         '17179869184');
INSERT INTO varint64_table VALUES('-1',        '-17179869185');
INSERT INTO varint64_table VALUES('-1',       '2199023255551');
INSERT INTO varint64_table VALUES('-1',      '-2199023255552');
INSERT INTO varint64_table VALUES('-1',       '2199023255552');
INSERT INTO varint64_table VALUES('-1',      '-2199023255553');
INSERT INTO varint64_table VALUES('-1',     '281474976710655');
INSERT INTO varint64_table VALUES('-1',    '-281474976710656');
INSERT INTO varint64_table VALUES('-1',     '281474976710656');
INSERT INTO varint64_table VALUES('-1',    '-281474976710657');
INSERT INTO varint64_table VALUES('-1',   '36028797018963967');
INSERT INTO varint64_table VALUES('-1',  '-36028797018963968');
INSERT INTO varint64_table VALUES('-1',   '36028797018963968');
INSERT INTO varint64_table VALUES('-1',  '-36028797018963969');
INSERT INTO varint64_table VALUES('-1', '4611686018427387903');
INSERT INTO varint64_table VALUES('-1','-4611686018427387904');
INSERT INTO varint64_table VALUES('-1', '4611686018427387904');
INSERT INTO varint64_table VALUES('-1','-4611686018427387905');

-- Test bogus inputs
INSERT INTO varint64_table (lhs) VALUES ('  ');
INSERT INTO varint64_table (lhs) VALUES ('xxx');
INSERT INTO varint64_table (lhs) VALUES ('3908203590239580293850293850329485');
INSERT INTO varint64_table (lhs) VALUES ('-1204982019841029840928340329840934');
INSERT INTO varint64_table (lhs) VALUES ('- 123');
INSERT INTO varint64_table (lhs) VALUES ('  123  456 ');
INSERT INTO varint64_table (lhs) VALUES ('');

-- Test table IO
SELECT * FROM varint64_table;
SELECT * FROM varint64_table WHERE rhs =  '4567890123456789'::VARINT64;
SELECT * FROM varint64_table WHERE rhs <> '4567890123456789'::VARINT64;
SELECT * FROM varint64_table WHERE rhs < '4567890123456789'::VARINT64;
SELECT * FROM varint64_table WHERE rhs > '4567890123456789'::VARINT64;
SELECT * FROM varint64_table WHERE rhs <= '4567890123456789'::VARINT64;
SELECT * FROM varint64_table WHERE rhs >= '4567890123456789'::VARINT64;
SELECT * FROM varint64_table WHERE rhs <> '456'::VARINT64;
SELECT * FROM varint64_table WHERE rhs <  '456'::VARINT64;
SELECT * FROM varint64_table WHERE rhs >  '456'::VARINT64;
SELECT * FROM varint64_table WHERE rhs <= '456'::VARINT64;
SELECT * FROM varint64_table WHERE rhs >= '456'::VARINT64;
SELECT * FROM varint64_table WHERE '123'::VARINT64 =  lhs;
SELECT * FROM varint64_table WHERE '123'::VARINT64 <> lhs;
SELECT * FROM varint64_table WHERE '123'::VARINT64 <  lhs;
SELECT * FROM varint64_table WHERE '123'::VARINT64 >  lhs;
SELECT * FROM varint64_table WHERE '123'::VARINT64 <= lhs;
SELECT * FROM varint64_table WHERE '123'::VARINT64 >= lhs;

-- And now for the punchline: test the encoded sizes of various bits
SELECT rhs, pg_column_size(rhs) FROM varint64_table WHERE lhs = '-1' ORDER BY rhs ASC;

-- Cleanup
DROP TABLE varint64_table;
DROP EXTENSION varint CASCADE;
