From 078d0ed15591f8021bd0064d3eb48ae383e72cd7 Mon Sep 17 00:00:00 2001 From: Arthur Zakirov Date: Mon, 19 Dec 2016 01:15:59 +0300 Subject: [PATCH] #5 untroduce pgv_set() and pgv_get() functions to handle anynonarray pseudotype --- Makefile | 2 +- README.md | 37 +- expected/pg_variables_any.out | 629 ++++++++++++++++++++++++++++++++++ pg_variables--1.0.sql | 12 + pg_variables.c | 51 +++ sql/pg_variables_any.sql | 159 +++++++++ 6 files changed, 875 insertions(+), 15 deletions(-) create mode 100644 expected/pg_variables_any.out create mode 100644 sql/pg_variables_any.sql diff --git a/Makefile b/Makefile index 38cc013..49592e0 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ EXTENSION = pg_variables DATA = pg_variables--1.0.sql PGFILEDESC = "pg_variables - sessional variables" -REGRESS = pg_variables +REGRESS = pg_variables pg_variables_any ifdef USE_PGXS PG_CONFIG = pg_config diff --git a/README.md b/README.md index eadadd4..ee9d34a 100644 --- a/README.md +++ b/README.md @@ -9,9 +9,9 @@ Note that the module does **not support transactions and savepoints**. For example: ```sql -SELECT pgv_set_int('vars', 'int1', 101); +SELECT pgv_set('vars', 'int1', 101); BEGIN; -SELECT pgv_set_int('vars', 'int2', 102); +SELECT pgv_set('vars', 'int2', 102); ROLLBACK; SELECT * FROM pgv_list() order by package, name; @@ -42,32 +42,41 @@ Typical installation procedure may look like this: The functions provided by the **pg_variables** module are shown in the tables below. The module supports the following scalar and record types. -To use **pgv_get_()** functions required package and variable must exists. It is -necessary to set variable with **pgv_set_()** functions to use **pgv_get_()** -functions. +To use **pgv_get()** function required package and variable must exists. It is +necessary to set variable with **pgv_set()** function to use **pgv_get()** +function. If a package does not exists you will get the following error: ```sql -SELECT pgv_get_int('vars', 'int1'); +SELECT pgv_get('vars', 'int1', NULL::int); ERROR: unrecognized package "vars" ``` If a variable does not exists you will get the following error: ```sql -SELECT pgv_get_int('vars', 'int1'); +SELECT pgv_get('vars', 'int1', NULL::int); ERROR: unrecognized variable "int1" ``` -**pgv_get_()** functions check the variable type. If the variable type does not +**pgv_get()** function check the variable type. If the variable type does not match with the function type the error will be raised: ```sql -SELECT pgv_get_text('vars', 'int1'); +SELECT pgv_get('vars', 'int1', NULL::text); ERROR: variable "int1" requires "integer" value ``` +## Scalar variables functions + +Function | Returns +-------- | ------- +`pgv_set(package text, name text, value anynonarray)` | `void` +`pgv_get(package text, name text, var_type anynonarray, strict bool default true)` | `anynonarray` + +## **Deprecated** scalar variables functions + ### Integer variables Function | Returns @@ -117,7 +126,7 @@ Function | Returns `pgv_set_jsonb(package text, name text, value jsonb)` | `void` `pgv_get_jsonb(package text, name text, strict bool default true)` | `jsonb` -### Records +## Record variables functions The following functions are provided by the module to work with collections of record types. @@ -159,16 +168,16 @@ Note that **pgv_stats()** works only with the PostgreSQL 9.6 and newer. It is easy to use functions to work with scalar variables: ```sql -SELECT pgv_set_int('vars', 'int1', 101); -SELECT pgv_set_int('vars', 'int2', 102); +SELECT pgv_set('vars', 'int1', 101); +SELECT pgv_set('vars', 'int2', 102); -SELECT pgv_get_int('vars', 'int1'); +SELECT pgv_get('vars', 'int1', NULL::int); pgv_get_int ------------- 101 (1 row) -SELECT pgv_get_int('vars', 'int2'); +SELECT pgv_get('vars', 'int2', NULL::int); pgv_get_int ------------- 102 diff --git a/expected/pg_variables_any.out b/expected/pg_variables_any.out new file mode 100644 index 0000000..b7b6cb9 --- /dev/null +++ b/expected/pg_variables_any.out @@ -0,0 +1,629 @@ +-- Integer variables +SELECT pgv_get('vars', 'int1', NULL::int); +ERROR: unrecognized package "vars" +SELECT pgv_get('vars', 'int1', NULL::int, false); + pgv_get +--------- + +(1 row) + +SELECT pgv_set('vars', 'int1', 101); + pgv_set +--------- + +(1 row) + +SELECT pgv_set('vars', 'int2', 102); + pgv_set +--------- + +(1 row) + +SELECT pgv_get('vars', 'int1', NULL::int); + pgv_get +--------- + 101 +(1 row) + +SELECT pgv_get('vars', 'int2', NULL::int); + pgv_get +--------- + 102 +(1 row) + +SELECT pgv_set('vars', 'int1', 103); + pgv_set +--------- + +(1 row) + +SELECT pgv_get('vars', 'int1', NULL::int); + pgv_get +--------- + 103 +(1 row) + +SELECT pgv_get('vars', 'int3', NULL::int); +ERROR: unrecognized variable "int3" +SELECT pgv_get('vars', 'int3', NULL::int, false); + pgv_get +--------- + +(1 row) + +SELECT pgv_exists('vars', 'int3'); + pgv_exists +------------ + f +(1 row) + +SELECT pgv_exists('vars', 'int1'); + pgv_exists +------------ + t +(1 row) + +SELECT pgv_exists('vars2'); + pgv_exists +------------ + f +(1 row) + +SELECT pgv_exists('vars'); + pgv_exists +------------ + t +(1 row) + +SELECT pgv_set('vars', 'intNULL', NULL::int); + pgv_set +--------- + +(1 row) + +SELECT pgv_get('vars', 'intNULL', NULL::int); + pgv_get +--------- + +(1 row) + +-- Text variables +SELECT pgv_set('vars', 'str1', 's101'::text); + pgv_set +--------- + +(1 row) + +SELECT pgv_set('vars', 'int1', 's101'::text); +ERROR: variable "int1" requires "integer" value +SELECT pgv_set('vars', 'str1', 101); +ERROR: variable "str1" requires "text" value +SELECT pgv_set('vars', 'str2', 's102'::text); + pgv_set +--------- + +(1 row) + +SELECT pgv_get('vars', 'str1', NULL::text); + pgv_get +--------- + s101 +(1 row) + +SELECT pgv_get('vars', 'str2', NULL::text); + pgv_get +--------- + s102 +(1 row) + +SELECT pgv_set('vars', 'str1', 's103'::text); + pgv_set +--------- + +(1 row) + +SELECT pgv_get('vars', 'str1', NULL::text); + pgv_get +--------- + s103 +(1 row) + +SELECT pgv_get('vars', 'str3', NULL::text); +ERROR: unrecognized variable "str3" +SELECT pgv_get('vars', 'str3', NULL::text, false); + pgv_get +--------- + +(1 row) + +SELECT pgv_exists('vars', 'str3'); + pgv_exists +------------ + f +(1 row) + +SELECT pgv_exists('vars', 'str1'); + pgv_exists +------------ + t +(1 row) + +SELECT pgv_get('vars', 'int1', NULL::text); +ERROR: variable "int1" requires "integer" value +SELECT pgv_get('vars', 'str1', NULL::int); +ERROR: variable "str1" requires "text" value +SELECT pgv_set('vars', 'strNULL', NULL::text); + pgv_set +--------- + +(1 row) + +SELECT pgv_get('vars', 'strNULL', NULL::text); + pgv_get +--------- + +(1 row) + +-- Numeric variables +SELECT pgv_set('vars', 'num1', 1.01::numeric); + pgv_set +--------- + +(1 row) + +SELECT pgv_set('vars', 'num2', 1.02::numeric); + pgv_set +--------- + +(1 row) + +SELECT pgv_set('vars', 'str1', 1.01::numeric); +ERROR: variable "str1" requires "text" value +SELECT pgv_get('vars', 'num1', NULL::numeric); + pgv_get +--------- + 1.01 +(1 row) + +SELECT pgv_get('vars', 'num2', NULL::numeric); + pgv_get +--------- + 1.02 +(1 row) + +SELECT pgv_set('vars', 'num1', 1.03::numeric); + pgv_set +--------- + +(1 row) + +SELECT pgv_get('vars', 'num1', NULL::numeric); + pgv_get +--------- + 1.03 +(1 row) + +SELECT pgv_get('vars', 'num3', NULL::numeric); +ERROR: unrecognized variable "num3" +SELECT pgv_get('vars', 'num3', NULL::numeric, false); + pgv_get +--------- + +(1 row) + +SELECT pgv_exists('vars', 'num3'); + pgv_exists +------------ + f +(1 row) + +SELECT pgv_exists('vars', 'num1'); + pgv_exists +------------ + t +(1 row) + +SELECT pgv_get('vars', 'str1', NULL::numeric); +ERROR: variable "str1" requires "text" value +SELECT pgv_set('vars', 'numNULL', NULL::numeric); + pgv_set +--------- + +(1 row) + +SELECT pgv_get('vars', 'numNULL', NULL::numeric); + pgv_get +--------- + +(1 row) + +SET timezone = 'Europe/Moscow'; +-- Timestamp variables +SELECT pgv_set('vars', 'ts1', '2016-03-30 10:00:00'::timestamp); + pgv_set +--------- + +(1 row) + +SELECT pgv_set('vars', 'ts2', '2016-03-30 11:00:00'::timestamp); + pgv_set +--------- + +(1 row) + +SELECT pgv_set('vars', 'num1', '2016-03-30 12:00:00'::timestamp); +ERROR: variable "num1" requires "numeric" value +SELECT pgv_get('vars', 'ts1', NULL::timestamp); + pgv_get +-------------------------- + Wed Mar 30 10:00:00 2016 +(1 row) + +SELECT pgv_get('vars', 'ts2', NULL::timestamp); + pgv_get +-------------------------- + Wed Mar 30 11:00:00 2016 +(1 row) + +SELECT pgv_set('vars', 'ts1', '2016-03-30 12:00:00'::timestamp); + pgv_set +--------- + +(1 row) + +SELECT pgv_get('vars', 'ts1', NULL::timestamp); + pgv_get +-------------------------- + Wed Mar 30 12:00:00 2016 +(1 row) + +SELECT pgv_get('vars', 'ts3', NULL::timestamp); +ERROR: unrecognized variable "ts3" +SELECT pgv_get('vars', 'ts3', NULL::timestamp, false); + pgv_get +--------- + +(1 row) + +SELECT pgv_exists('vars', 'ts3'); + pgv_exists +------------ + f +(1 row) + +SELECT pgv_exists('vars', 'ts1'); + pgv_exists +------------ + t +(1 row) + +SELECT pgv_get('vars', 'num1', NULL::timestamp); +ERROR: variable "num1" requires "numeric" value +SELECT pgv_set('vars', 'tsNULL', NULL::timestamp); + pgv_set +--------- + +(1 row) + +SELECT pgv_get('vars', 'tsNULL', NULL::timestamp); + pgv_get +--------- + +(1 row) + +-- TimestampTZ variables +SELECT pgv_set('vars', 'tstz1', '2016-03-30 10:00:00 GMT+01'::timestamptz); + pgv_set +--------- + +(1 row) + +SELECT pgv_set('vars', 'tstz2', '2016-03-30 11:00:00 GMT+02'::timestamptz); + pgv_set +--------- + +(1 row) + +SELECT pgv_set('vars', 'ts1', '2016-03-30 12:00:00 GMT+03'::timestamptz); +ERROR: variable "ts1" requires "timestamp without time zone" value +SELECT pgv_get('vars', 'tstz1', NULL::timestamptz); + pgv_get +------------------------------ + Wed Mar 30 14:00:00 2016 MSK +(1 row) + +SELECT pgv_get('vars', 'tstz2', NULL::timestamptz); + pgv_get +------------------------------ + Wed Mar 30 16:00:00 2016 MSK +(1 row) + +SELECT pgv_set('vars', 'tstz1', '2016-03-30 12:00:00 GMT+01'::timestamptz); + pgv_set +--------- + +(1 row) + +SELECT pgv_get('vars', 'tstz1', NULL::timestamptz); + pgv_get +------------------------------ + Wed Mar 30 16:00:00 2016 MSK +(1 row) + +SELECT pgv_get('vars', 'tstz3', NULL::timestamptz); +ERROR: unrecognized variable "tstz3" +SELECT pgv_get('vars', 'tstz3', NULL::timestamptz, false); + pgv_get +--------- + +(1 row) + +SELECT pgv_exists('vars', 'tstz3'); + pgv_exists +------------ + f +(1 row) + +SELECT pgv_exists('vars', 'tstz1'); + pgv_exists +------------ + t +(1 row) + +SELECT pgv_get('vars', 'ts1', NULL::timestamptz); +ERROR: variable "ts1" requires "timestamp without time zone" value +SELECT pgv_set('vars', 'tstzNULL', NULL::timestamptz); + pgv_set +--------- + +(1 row) + +SELECT pgv_get('vars', 'tstzNULL', NULL::timestamptz); + pgv_get +--------- + +(1 row) + +-- Date variables +SELECT pgv_set('vars', 'd1', '2016-03-29'::date); + pgv_set +--------- + +(1 row) + +SELECT pgv_set('vars', 'd2', '2016-03-30'::date); + pgv_set +--------- + +(1 row) + +SELECT pgv_set('vars', 'tstz1', '2016-04-01'::date); +ERROR: variable "tstz1" requires "timestamp with time zone" value +SELECT pgv_get('vars', 'd1', NULL::date); + pgv_get +------------ + 03-29-2016 +(1 row) + +SELECT pgv_get('vars', 'd2', NULL::date); + pgv_get +------------ + 03-30-2016 +(1 row) + +SELECT pgv_set('vars', 'd1', '2016-04-02'::date); + pgv_set +--------- + +(1 row) + +SELECT pgv_get('vars', 'd1', NULL::date); + pgv_get +------------ + 04-02-2016 +(1 row) + +SELECT pgv_get('vars', 'd3', NULL::date); +ERROR: unrecognized variable "d3" +SELECT pgv_get('vars', 'd3', NULL::date, false); + pgv_get +--------- + +(1 row) + +SELECT pgv_exists('vars', 'd3'); + pgv_exists +------------ + f +(1 row) + +SELECT pgv_exists('vars', 'd1'); + pgv_exists +------------ + t +(1 row) + +SELECT pgv_get('vars', 'tstz1', NULL::date); +ERROR: variable "tstz1" requires "timestamp with time zone" value +SELECT pgv_set('vars', 'dNULL', NULL::date); + pgv_set +--------- + +(1 row) + +SELECT pgv_get('vars', 'dNULL', NULL::date); + pgv_get +--------- + +(1 row) + +-- Jsonb variables +SELECT pgv_set('vars2', 'j1', '[1, 2, "foo", null]'::jsonb); + pgv_set +--------- + +(1 row) + +SELECT pgv_set('vars2', 'j2', '{"bar": "baz", "balance": 7.77, "active": false}'::jsonb); + pgv_set +--------- + +(1 row) + +SELECT pgv_set('vars', 'd1', '[1, 2, "foo", null]'::jsonb); +ERROR: variable "d1" requires "date" value +SELECT pgv_get('vars2', 'j1', NULL::jsonb); + pgv_get +--------------------- + [1, 2, "foo", null] +(1 row) + +SELECT pgv_get('vars2', 'j2', NULL::jsonb); + pgv_get +-------------------------------------------------- + {"bar": "baz", "active": false, "balance": 7.77} +(1 row) + +SELECT pgv_set('vars2', 'j1', '{"foo": [true, "bar"], "tags": {"a": 1, "b": null}}'::jsonb); + pgv_set +--------- + +(1 row) + +SELECT pgv_get('vars2', 'j1', NULL::jsonb); + pgv_get +----------------------------------------------------- + {"foo": [true, "bar"], "tags": {"a": 1, "b": null}} +(1 row) + +SELECT pgv_get('vars2', 'j3', NULL::jsonb); +ERROR: unrecognized variable "j3" +SELECT pgv_get('vars2', 'j3', NULL::jsonb, false); + pgv_get +--------- + +(1 row) + +SELECT pgv_exists('vars2', 'j3'); + pgv_exists +------------ + f +(1 row) + +SELECT pgv_exists('vars2', 'j1'); + pgv_exists +------------ + t +(1 row) + +SELECT pgv_get('vars', 'd1', NULL::jsonb); +ERROR: variable "d1" requires "date" value +SELECT pgv_set('vars', 'jNULL', NULL::jsonb); + pgv_set +--------- + +(1 row) + +SELECT pgv_get('vars', 'jNULL', NULL::jsonb); + pgv_get +--------- + +(1 row) + +-- Manipulate variables +SELECT * FROM pgv_list() order by package, name; + package | name +---------+---------- + vars | d1 + vars | d2 + vars | dNULL + vars | int1 + vars | int2 + vars | intNULL + vars | jNULL + vars | num1 + vars | num2 + vars | numNULL + vars | str1 + vars | str2 + vars | strNULL + vars | ts1 + vars | ts2 + vars | tsNULL + vars | tstz1 + vars | tstz2 + vars | tstzNULL + vars2 | j1 + vars2 | j2 +(21 rows) + +SELECT pgv_remove('vars', 'int3'); +ERROR: unrecognized variable "int3" +SELECT pgv_remove('vars', 'int1'); + pgv_remove +------------ + +(1 row) + +SELECT pgv_get('vars', 'int1', NULL::int); +ERROR: unrecognized variable "int1" +SELECT pgv_exists('vars'); + pgv_exists +------------ + t +(1 row) + +SELECT pgv_remove('vars2'); + pgv_remove +------------ + +(1 row) + +SELECT pgv_get('vars2', 'j1', NULL::jsonb); +ERROR: unrecognized package "vars2" +SELECT pgv_exists('vars2'); + pgv_exists +------------ + f +(1 row) + +SELECT * FROM pgv_list() order by package, name; + package | name +---------+---------- + vars | d1 + vars | d2 + vars | dNULL + vars | int2 + vars | intNULL + vars | jNULL + vars | num1 + vars | num2 + vars | numNULL + vars | str1 + vars | str2 + vars | strNULL + vars | ts1 + vars | ts2 + vars | tsNULL + vars | tstz1 + vars | tstz2 + vars | tstzNULL +(18 rows) + +SELECT pgv_free(); + pgv_free +---------- + +(1 row) + +SELECT pgv_exists('vars'); + pgv_exists +------------ + f +(1 row) + +SELECT * FROM pgv_list() order by package, name; + package | name +---------+------ +(0 rows) + diff --git a/pg_variables--1.0.sql b/pg_variables--1.0.sql index c56ab7f..2b19ac6 100644 --- a/pg_variables--1.0.sql +++ b/pg_variables--1.0.sql @@ -5,6 +5,18 @@ -- Scalar variables functions +CREATE FUNCTION pgv_set(package text, name text, value anynonarray) +RETURNS void +AS 'MODULE_PATHNAME', 'variable_set_any' +LANGUAGE C VOLATILE; + +CREATE FUNCTION pgv_get(package text, name text, var_type anynonarray, strict bool default true) +RETURNS anynonarray +AS 'MODULE_PATHNAME', 'variable_get_any' +LANGUAGE C VOLATILE; + +-- Deprecated scalar variables functions + CREATE FUNCTION pgv_set_int(package text, name text, value int) RETURNS void AS 'MODULE_PATHNAME', 'variable_set_int' diff --git a/pg_variables.c b/pg_variables.c index 30e3e17..ef3386a 100644 --- a/pg_variables.c +++ b/pg_variables.c @@ -26,6 +26,10 @@ PG_MODULE_MAGIC; /* Scalar variables functions */ +PG_FUNCTION_INFO_V1(variable_set_any); +PG_FUNCTION_INFO_V1(variable_get_any); + +/* Deprecated scalar variables functions */ PG_FUNCTION_INFO_V1(variable_set_int); PG_FUNCTION_INFO_V1(variable_get_int); PG_FUNCTION_INFO_V1(variable_set_text); @@ -154,6 +158,53 @@ variable_get(text *package_name, text *var_name, return scalar->value; } +Datum +variable_set_any(PG_FUNCTION_ARGS) +{ + text *package_name; + text *var_name; + + CHECK_ARGS_FOR_NULL(); + + package_name = PG_GETARG_TEXT_PP(0); + var_name = PG_GETARG_TEXT_PP(1); + + variable_set(package_name, var_name, get_fn_expr_argtype(fcinfo->flinfo, 2), + PG_ARGISNULL(2) ? 0 : PG_GETARG_DATUM(2), + PG_ARGISNULL(2)); + + PG_FREE_IF_COPY(package_name, 0); + PG_FREE_IF_COPY(var_name, 1); + PG_RETURN_VOID(); +} + +Datum +variable_get_any(PG_FUNCTION_ARGS) +{ + text *package_name; + text *var_name; + bool strict; + bool is_null; + Datum value; + + CHECK_ARGS_FOR_NULL(); + + package_name = PG_GETARG_TEXT_PP(0); + var_name = PG_GETARG_TEXT_PP(1); + strict = PG_GETARG_BOOL(3); + + value = variable_get(package_name, var_name, + get_fn_expr_argtype(fcinfo->flinfo, 2), + &is_null, strict); + + PG_FREE_IF_COPY(package_name, 0); + PG_FREE_IF_COPY(var_name, 1); + if (!is_null) + PG_RETURN_DATUM(value); + else + PG_RETURN_NULL(); +} + Datum variable_set_int(PG_FUNCTION_ARGS) { diff --git a/sql/pg_variables_any.sql b/sql/pg_variables_any.sql new file mode 100644 index 0000000..3b9d488 --- /dev/null +++ b/sql/pg_variables_any.sql @@ -0,0 +1,159 @@ +-- Integer variables +SELECT pgv_get('vars', 'int1', NULL::int); +SELECT pgv_get('vars', 'int1', NULL::int, false); + +SELECT pgv_set('vars', 'int1', 101); +SELECT pgv_set('vars', 'int2', 102); + +SELECT pgv_get('vars', 'int1', NULL::int); +SELECT pgv_get('vars', 'int2', NULL::int); +SELECT pgv_set('vars', 'int1', 103); +SELECT pgv_get('vars', 'int1', NULL::int); + +SELECT pgv_get('vars', 'int3', NULL::int); +SELECT pgv_get('vars', 'int3', NULL::int, false); +SELECT pgv_exists('vars', 'int3'); +SELECT pgv_exists('vars', 'int1'); +SELECT pgv_exists('vars2'); +SELECT pgv_exists('vars'); + +SELECT pgv_set('vars', 'intNULL', NULL::int); +SELECT pgv_get('vars', 'intNULL', NULL::int); + +-- Text variables +SELECT pgv_set('vars', 'str1', 's101'::text); +SELECT pgv_set('vars', 'int1', 's101'::text); +SELECT pgv_set('vars', 'str1', 101); +SELECT pgv_set('vars', 'str2', 's102'::text); + +SELECT pgv_get('vars', 'str1', NULL::text); +SELECT pgv_get('vars', 'str2', NULL::text); +SELECT pgv_set('vars', 'str1', 's103'::text); +SELECT pgv_get('vars', 'str1', NULL::text); + +SELECT pgv_get('vars', 'str3', NULL::text); +SELECT pgv_get('vars', 'str3', NULL::text, false); +SELECT pgv_exists('vars', 'str3'); +SELECT pgv_exists('vars', 'str1'); +SELECT pgv_get('vars', 'int1', NULL::text); +SELECT pgv_get('vars', 'str1', NULL::int); + +SELECT pgv_set('vars', 'strNULL', NULL::text); +SELECT pgv_get('vars', 'strNULL', NULL::text); + +-- Numeric variables +SELECT pgv_set('vars', 'num1', 1.01::numeric); +SELECT pgv_set('vars', 'num2', 1.02::numeric); +SELECT pgv_set('vars', 'str1', 1.01::numeric); + +SELECT pgv_get('vars', 'num1', NULL::numeric); +SELECT pgv_get('vars', 'num2', NULL::numeric); +SELECT pgv_set('vars', 'num1', 1.03::numeric); +SELECT pgv_get('vars', 'num1', NULL::numeric); + +SELECT pgv_get('vars', 'num3', NULL::numeric); +SELECT pgv_get('vars', 'num3', NULL::numeric, false); +SELECT pgv_exists('vars', 'num3'); +SELECT pgv_exists('vars', 'num1'); +SELECT pgv_get('vars', 'str1', NULL::numeric); + +SELECT pgv_set('vars', 'numNULL', NULL::numeric); +SELECT pgv_get('vars', 'numNULL', NULL::numeric); + +SET timezone = 'Europe/Moscow'; + +-- Timestamp variables +SELECT pgv_set('vars', 'ts1', '2016-03-30 10:00:00'::timestamp); +SELECT pgv_set('vars', 'ts2', '2016-03-30 11:00:00'::timestamp); +SELECT pgv_set('vars', 'num1', '2016-03-30 12:00:00'::timestamp); + +SELECT pgv_get('vars', 'ts1', NULL::timestamp); +SELECT pgv_get('vars', 'ts2', NULL::timestamp); +SELECT pgv_set('vars', 'ts1', '2016-03-30 12:00:00'::timestamp); +SELECT pgv_get('vars', 'ts1', NULL::timestamp); + +SELECT pgv_get('vars', 'ts3', NULL::timestamp); +SELECT pgv_get('vars', 'ts3', NULL::timestamp, false); +SELECT pgv_exists('vars', 'ts3'); +SELECT pgv_exists('vars', 'ts1'); +SELECT pgv_get('vars', 'num1', NULL::timestamp); + +SELECT pgv_set('vars', 'tsNULL', NULL::timestamp); +SELECT pgv_get('vars', 'tsNULL', NULL::timestamp); + +-- TimestampTZ variables + +SELECT pgv_set('vars', 'tstz1', '2016-03-30 10:00:00 GMT+01'::timestamptz); +SELECT pgv_set('vars', 'tstz2', '2016-03-30 11:00:00 GMT+02'::timestamptz); +SELECT pgv_set('vars', 'ts1', '2016-03-30 12:00:00 GMT+03'::timestamptz); + +SELECT pgv_get('vars', 'tstz1', NULL::timestamptz); +SELECT pgv_get('vars', 'tstz2', NULL::timestamptz); +SELECT pgv_set('vars', 'tstz1', '2016-03-30 12:00:00 GMT+01'::timestamptz); +SELECT pgv_get('vars', 'tstz1', NULL::timestamptz); + +SELECT pgv_get('vars', 'tstz3', NULL::timestamptz); +SELECT pgv_get('vars', 'tstz3', NULL::timestamptz, false); +SELECT pgv_exists('vars', 'tstz3'); +SELECT pgv_exists('vars', 'tstz1'); +SELECT pgv_get('vars', 'ts1', NULL::timestamptz); + +SELECT pgv_set('vars', 'tstzNULL', NULL::timestamptz); +SELECT pgv_get('vars', 'tstzNULL', NULL::timestamptz); + +-- Date variables +SELECT pgv_set('vars', 'd1', '2016-03-29'::date); +SELECT pgv_set('vars', 'd2', '2016-03-30'::date); +SELECT pgv_set('vars', 'tstz1', '2016-04-01'::date); + +SELECT pgv_get('vars', 'd1', NULL::date); +SELECT pgv_get('vars', 'd2', NULL::date); +SELECT pgv_set('vars', 'd1', '2016-04-02'::date); +SELECT pgv_get('vars', 'd1', NULL::date); + +SELECT pgv_get('vars', 'd3', NULL::date); +SELECT pgv_get('vars', 'd3', NULL::date, false); +SELECT pgv_exists('vars', 'd3'); +SELECT pgv_exists('vars', 'd1'); +SELECT pgv_get('vars', 'tstz1', NULL::date); + +SELECT pgv_set('vars', 'dNULL', NULL::date); +SELECT pgv_get('vars', 'dNULL', NULL::date); + +-- Jsonb variables +SELECT pgv_set('vars2', 'j1', '[1, 2, "foo", null]'::jsonb); +SELECT pgv_set('vars2', 'j2', '{"bar": "baz", "balance": 7.77, "active": false}'::jsonb); +SELECT pgv_set('vars', 'd1', '[1, 2, "foo", null]'::jsonb); + +SELECT pgv_get('vars2', 'j1', NULL::jsonb); +SELECT pgv_get('vars2', 'j2', NULL::jsonb); +SELECT pgv_set('vars2', 'j1', '{"foo": [true, "bar"], "tags": {"a": 1, "b": null}}'::jsonb); +SELECT pgv_get('vars2', 'j1', NULL::jsonb); + +SELECT pgv_get('vars2', 'j3', NULL::jsonb); +SELECT pgv_get('vars2', 'j3', NULL::jsonb, false); +SELECT pgv_exists('vars2', 'j3'); +SELECT pgv_exists('vars2', 'j1'); +SELECT pgv_get('vars', 'd1', NULL::jsonb); + +SELECT pgv_set('vars', 'jNULL', NULL::jsonb); +SELECT pgv_get('vars', 'jNULL', NULL::jsonb); + +-- Manipulate variables +SELECT * FROM pgv_list() order by package, name; + +SELECT pgv_remove('vars', 'int3'); +SELECT pgv_remove('vars', 'int1'); +SELECT pgv_get('vars', 'int1', NULL::int); +SELECT pgv_exists('vars'); + +SELECT pgv_remove('vars2'); +SELECT pgv_get('vars2', 'j1', NULL::jsonb); +SELECT pgv_exists('vars2'); + +SELECT * FROM pgv_list() order by package, name; + +SELECT pgv_free(); +SELECT pgv_exists('vars'); + +SELECT * FROM pgv_list() order by package, name;