diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index aca8b0d..e654cb6 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -11,7 +11,7 @@ jobs: test: strategy: matrix: - pg: [15, 14, 13, 12, 11, 10] + pg: [16, 15, 14, 13, 12, 11, 10] name: 🐘 PostgreSQL ${{ matrix.pg }} runs-on: ubuntu-latest container: pgxn/pgxn-tools diff --git a/sql/currency--0.0.4.sql b/sql/currency--0.0.4.sql new file mode 100644 index 0000000..a9d8e3c --- /dev/null +++ b/sql/currency--0.0.4.sql @@ -0,0 +1,203 @@ + +CREATE TYPE currency; + +CREATE FUNCTION supported_currencies() + RETURNS SETOF currency + AS '$libdir/currency.so' + LANGUAGE C IMMUTABLE STRICT; + +CREATE FUNCTION currency_in(cstring) + RETURNS currency + AS '$libdir/currency.so' + LANGUAGE C IMMUTABLE STRICT; + +CREATE FUNCTION currency_out(currency) + RETURNS cstring + AS '$libdir/currency.so' + LANGUAGE C IMMUTABLE STRICT; + +CREATE FUNCTION currency_recv(internal) + RETURNS currency + AS '$libdir/currency.so' + LANGUAGE C IMMUTABLE STRICT; + +CREATE FUNCTION currency_send(currency) + RETURNS bytea + AS '$libdir/currency.so' + LANGUAGE C IMMUTABLE STRICT; + +CREATE TYPE currency ( + internallength = 1, + input = currency_in, + output = currency_out, + send = currency_send, + receive = currency_recv, + alignment = char, + PASSEDBYVALUE +); + +COMMENT ON TYPE currency + IS '1-byte ISO 4217 Currency Code'; + +CREATE FUNCTION currency_lt(currency, currency) + RETURNS BOOL + AS '$libdir/currency.so' + LANGUAGE C IMMUTABLE STRICT; + +COMMENT ON FUNCTION currency_lt(currency, currency) IS 'implementation of < operator'; + +CREATE FUNCTION currency_le(currency, currency) + RETURNS BOOL + AS '$libdir/currency.so' + LANGUAGE C IMMUTABLE STRICT; + +COMMENT ON FUNCTION currency_le(currency, currency) IS 'implementation of <= operator'; + +CREATE FUNCTION currency_eq(currency, currency) + RETURNS BOOL + AS '$libdir/currency.so' + LANGUAGE C IMMUTABLE STRICT; + +COMMENT ON FUNCTION currency_eq(currency, currency) IS 'implementation of = operator'; + +CREATE FUNCTION currency_neq(currency, currency) + RETURNS BOOL + AS '$libdir/currency.so' + LANGUAGE C IMMUTABLE STRICT; + +COMMENT ON FUNCTION currency_neq(currency, currency) IS 'implementation of <> operator'; + +CREATE FUNCTION currency_ge(currency, currency) + RETURNS BOOL + AS '$libdir/currency.so' + LANGUAGE C IMMUTABLE STRICT; + +COMMENT ON FUNCTION currency_ge(currency, currency) IS 'implementation of >= operator'; + +CREATE FUNCTION currency_gt(currency, currency) + RETURNS BOOL + AS '$libdir/currency.so' + LANGUAGE C IMMUTABLE STRICT; + +COMMENT ON FUNCTION currency_gt(currency, currency) IS 'implementation of > operator'; + +CREATE FUNCTION hash_currency(currency) + RETURNS integer + AS '$libdir/currency.so' + LANGUAGE C IMMUTABLE STRICT; + +COMMENT ON FUNCTION hash_currency(currency) IS 'hash'; + +CREATE OPERATOR < ( + leftarg = currency, + rightarg = currency, + procedure = currency_lt, + commutator = >, + negator = >=, + restrict = scalarltsel, + join = scalarltjoinsel +); + +COMMENT ON OPERATOR <(currency, currency) IS 'less than'; + +CREATE OPERATOR <= ( + leftarg = currency, + rightarg = currency, + procedure = currency_le, + commutator = >=, + negator = >, + restrict = scalarltsel, + join = scalarltjoinsel +); + +COMMENT ON OPERATOR <=(currency, currency) IS 'less than or equal'; + +CREATE OPERATOR = ( + leftarg = currency, + rightarg = currency, + procedure = currency_eq, + commutator = =, + negator = <>, + restrict = eqsel, + join = eqjoinsel, + HASHES, MERGES +); + +COMMENT ON OPERATOR =(currency, currency) IS 'equal'; + +CREATE OPERATOR >= ( + leftarg = currency, + rightarg = currency, + procedure = currency_ge, + commutator = <=, + negator = <, + restrict = scalargtsel, + join = scalargtjoinsel +); + +COMMENT ON OPERATOR >=(currency, currency) IS 'greater than or equal'; + +CREATE OPERATOR > ( + leftarg = currency, + rightarg = currency, + procedure = currency_gt, + commutator = <, + negator = <=, + restrict = scalargtsel, + join = scalargtjoinsel +); + +COMMENT ON OPERATOR >(currency, currency) IS 'greater than'; + +CREATE OPERATOR <> ( + leftarg = currency, + rightarg = currency, + procedure = currency_neq, + commutator = <>, + negator = =, + restrict = neqsel, + join = neqjoinsel +); + +COMMENT ON OPERATOR <>(currency, currency) IS 'not equal'; + +CREATE FUNCTION currency_cmp(currency, currency) + RETURNS int4 + AS '$libdir/currency.so' + LANGUAGE C IMMUTABLE STRICT; + +CREATE OPERATOR CLASS currency_ops + DEFAULT FOR TYPE currency USING btree AS + OPERATOR 1 < , + OPERATOR 2 <= , + OPERATOR 3 = , + OPERATOR 4 >= , + OPERATOR 5 > , + FUNCTION 1 currency_cmp(currency, currency); + +CREATE OPERATOR CLASS currency_ops + DEFAULT FOR TYPE currency USING hash AS + OPERATOR 1 = , + FUNCTION 1 hash_currency(currency); + +DO $$ +DECLARE version_num integer; +BEGIN + SELECT current_setting('server_version_num') INTO STRICT version_num; + IF version_num > 90600 THEN + EXECUTE $E$ ALTER FUNCTION currency_in(cstring) PARALLEL SAFE $E$; + EXECUTE $E$ ALTER FUNCTION currency_out(currency) PARALLEL SAFE $E$; + EXECUTE $E$ ALTER FUNCTION currency_recv(internal) PARALLEL SAFE $E$; + EXECUTE $E$ ALTER FUNCTION currency_send(currency) PARALLEL SAFE $E$; + EXECUTE $E$ ALTER FUNCTION currency_eq(currency, currency) PARALLEL SAFE $E$; + EXECUTE $E$ ALTER FUNCTION currency_neq(currency, currency) PARALLEL SAFE $E$; + EXECUTE $E$ ALTER FUNCTION currency_lt(currency, currency) PARALLEL SAFE $E$; + EXECUTE $E$ ALTER FUNCTION currency_le(currency, currency) PARALLEL SAFE $E$; + EXECUTE $E$ ALTER FUNCTION currency_gt(currency, currency) PARALLEL SAFE $E$; + EXECUTE $E$ ALTER FUNCTION currency_ge(currency, currency) PARALLEL SAFE $E$; + EXECUTE $E$ ALTER FUNCTION currency_cmp(currency, currency) PARALLEL SAFE $E$; + EXECUTE $E$ ALTER FUNCTION hash_currency(currency) PARALLEL SAFE $E$; + END IF; +END; +$$; + diff --git a/src/currency.h b/src/currency.h index 3d3d8c1..100743f 100644 --- a/src/currency.h +++ b/src/currency.h @@ -6,6 +6,9 @@ #include "access/hash.h" #include "libpq/pqformat.h" #include "funcapi.h" +#if PG_VERSION_NUM >= 160000 +#include "varatt.h" +#endif typedef unsigned char currency; diff --git a/test/expected/parallel_test.out b/test/expected/parallel_test.out index 20ce82c..859952f 100644 --- a/test/expected/parallel_test.out +++ b/test/expected/parallel_test.out @@ -1,6 +1,13 @@ BEGIN; SET max_parallel_workers_per_gather=4; -SET force_parallel_mode=on; +DO $$ +BEGIN + IF current_setting('server_version_num')::int >= 160000 THEN + EXECUTE 'SET debug_parallel_query = on'; + ELSE + EXECUTE 'SET force_parallel_mode = on'; + END IF; +END $$; CREATE TABLE parallel_test(i int, c currency) WITH (parallel_workers = 4); INSERT INTO parallel_test (i, c) SELECT i, c.country diff --git a/test/expected/parallel_test_1.out b/test/expected/parallel_test_1.out index 4aef4fe..90f9a01 100644 --- a/test/expected/parallel_test_1.out +++ b/test/expected/parallel_test_1.out @@ -1,6 +1,13 @@ BEGIN; SET max_parallel_workers_per_gather=4; -SET force_parallel_mode=on; +DO $$ +BEGIN + IF current_setting('server_version_num')::int >= 160000 THEN + EXECUTE 'SET debug_parallel_query = on'; + ELSE + EXECUTE 'SET force_parallel_mode = on'; + END IF; +END $$; CREATE TABLE parallel_test(i int, c currency) WITH (parallel_workers = 4); INSERT INTO parallel_test (i, c) SELECT i, c.country diff --git a/test/sql/parallel_test.sql b/test/sql/parallel_test.sql index d3aa498..c62ce3d 100644 --- a/test/sql/parallel_test.sql +++ b/test/sql/parallel_test.sql @@ -1,6 +1,13 @@ BEGIN; SET max_parallel_workers_per_gather=4; -SET force_parallel_mode=on; +DO $$ +BEGIN + IF current_setting('server_version_num')::int >= 160000 THEN + EXECUTE 'SET debug_parallel_query = on'; + ELSE + EXECUTE 'SET force_parallel_mode = on'; + END IF; +END $$; CREATE TABLE parallel_test(i int, c currency) WITH (parallel_workers = 4); INSERT INTO parallel_test (i, c)