diff --git a/contrib/try_convert/data/tt_cidr.data b/contrib/try_convert/data/tt_cidr.data new file mode 100644 index 0000000000..73d05ee9bd --- /dev/null +++ b/contrib/try_convert/data/tt_cidr.data @@ -0,0 +1,16 @@ +192.168.100.128/25 +192.168/24 +192.168/25 +192.168.1 +192.168 +128.1 +128 +128.1.2 +10.1.2 +10.1 +10 +10.1.2.3/32 +2001:4f8:3:ba::/64 +2001:4f8:3:ba:2e0:81ff:fe22:d1f1/128 +::ffff:1.2.3.0/120 +::ffff:1.2.3.0/128 \ No newline at end of file diff --git a/contrib/try_convert/data/tt_inet.data b/contrib/try_convert/data/tt_inet.data new file mode 100644 index 0000000000..e523116692 --- /dev/null +++ b/contrib/try_convert/data/tt_inet.data @@ -0,0 +1,19 @@ +192.168.100.128/25 +192.168.0.0/24 +192.168.0.0/25 +192.168.100.128 +192.168.0.1/24 +192.168.0.1/25 +192.168.1.0 +192.168.0.0 +128.1.0.0 +128.0.0.0 +128.1.2.0 +10.1.2.0 +10.1.0.0 +10.0.0.0 +10.1.2.3/32 +2001:4f8:3:ba::/64 +2001:4f8:3:ba:2e0:81ff:fe22:d1f1/128 +::ffff:1.2.3.0/120 +::ffff:1.2.3.0/128 \ No newline at end of file diff --git a/contrib/try_convert/data/tt_macaddr.data b/contrib/try_convert/data/tt_macaddr.data new file mode 100644 index 0000000000..b3d66c3c48 --- /dev/null +++ b/contrib/try_convert/data/tt_macaddr.data @@ -0,0 +1,6 @@ +08:00:2b:01:02:03 +08-00-2b-01-02-03 +08002b:010203 +08002b-010203 +0800.2b01.0203 +08002b010203 \ No newline at end of file diff --git a/contrib/try_convert/generate_test.py b/contrib/try_convert/generate_test.py index 28a1b9073a..3aea24485f 100644 --- a/contrib/try_convert/generate_test.py +++ b/contrib/try_convert/generate_test.py @@ -23,16 +23,15 @@ # 'path', # 'point', # 'polygon', - # 'cidr', # IP - # 'inet', + 'cidr', # IP + 'inet', + 'macaddr', # 'json', # JSON # 'jsonb', # 'bytea', # STRINGS # 'char', # 'varchar', 'text', - # 'macaddr', - # 'macaddr8', # 'money', # # 'pg_lsn', # # 'tsquery', diff --git a/contrib/try_convert/input/try_convert.source b/contrib/try_convert/input/try_convert.source index 7cc4911982..62aaa6d25e 100644 --- a/contrib/try_convert/input/try_convert.source +++ b/contrib/try_convert/input/try_convert.source @@ -1,6 +1,6 @@ -- SCRIPT-GENERATED TEST for TRY_CONVERT --- Tests 14 types of 91 from pg_types.h --- Tests 52 cast of 206 from pg_cast.h +-- Tests 17 types of 91 from pg_types.h +-- Tests 56 cast of 206 from pg_cast.h create schema tryconvert; set search_path = tryconvert; @@ -140,6 +140,36 @@ $func$ -- do nothing: _out already carries default END $func$; +CREATE OR REPLACE FUNCTION try_convert_by_sql(_in cidr, INOUT _out ANYELEMENT) + LANGUAGE plpgsql AS +$func$ + BEGIN + EXECUTE format('SELECT %L::%s', $1, source_type) + INTO _out; + EXCEPTION WHEN others THEN + -- do nothing: _out already carries default + END +$func$; +CREATE OR REPLACE FUNCTION try_convert_by_sql(_in inet, INOUT _out ANYELEMENT) + LANGUAGE plpgsql AS +$func$ + BEGIN + EXECUTE format('SELECT %L::%s', $1, source_type) + INTO _out; + EXCEPTION WHEN others THEN + -- do nothing: _out already carries default + END +$func$; +CREATE OR REPLACE FUNCTION try_convert_by_sql(_in macaddr, INOUT _out ANYELEMENT) + LANGUAGE plpgsql AS +$func$ + BEGIN + EXECUTE format('SELECT %L::%s', $1, source_type) + INTO _out; + EXCEPTION WHEN others THEN + -- do nothing: _out already carries default + END +$func$; CREATE OR REPLACE FUNCTION try_convert_by_sql(_in text, INOUT _out ANYELEMENT) LANGUAGE plpgsql AS $func$ @@ -178,6 +208,12 @@ CREATE TABLE tt_timestamptz (v timestamptz) DISTRIBUTED BY (v); COPY tt_timestamptz from '@abs_srcdir@/data/tt_timestamptz.data'; CREATE TABLE tt_interval (v interval) DISTRIBUTED BY (v); COPY tt_interval from '@abs_srcdir@/data/tt_interval.data'; +CREATE TABLE tt_cidr (v cidr) DISTRIBUTED BY (v); +COPY tt_cidr from '@abs_srcdir@/data/tt_cidr.data'; +CREATE TABLE tt_inet (v inet) DISTRIBUTED BY (v); +COPY tt_inet from '@abs_srcdir@/data/tt_inet.data'; +CREATE TABLE tt_macaddr (v macaddr) DISTRIBUTED BY (v); +COPY tt_macaddr from '@abs_srcdir@/data/tt_macaddr.data'; CREATE TABLE tt_text (v text) DISTRIBUTED BY (v); COPY tt_text from '@abs_srcdir@/data/tt_text.data'; @@ -221,6 +257,15 @@ select * from (select try_convert(v, NULL::timestamptz) as v1, try_convert_by_sq select * from (select try_convert(v, NULL::text) as v1, try_convert_by_sql(v, NULL::text) as v2 from tt_interval) as t(v1, v2) where not (v1 = v2); select * from (select try_convert(v, NULL::interval) as v1, try_convert_by_sql(v, NULL::interval) as v2 from (select v::text from tt_interval) as t(v)) as t(v1, v2) where not (v1 = v2); select * from (select try_convert(v, NULL::interval) as v1, try_convert_by_sql(v, NULL::interval) as v2 from (select ('!@#%^&*' || v::text || '!@#%^&*') from tt_interval) as t(v)) as t(v1, v2) where not (v1 = v2); +select * from (select try_convert(v, NULL::text) as v1, try_convert_by_sql(v, NULL::text) as v2 from tt_cidr) as t(v1, v2) where not (v1 = v2); +select * from (select try_convert(v, NULL::cidr) as v1, try_convert_by_sql(v, NULL::cidr) as v2 from (select v::text from tt_cidr) as t(v)) as t(v1, v2) where not (v1 = v2); +select * from (select try_convert(v, NULL::cidr) as v1, try_convert_by_sql(v, NULL::cidr) as v2 from (select ('!@#%^&*' || v::text || '!@#%^&*') from tt_cidr) as t(v)) as t(v1, v2) where not (v1 = v2); +select * from (select try_convert(v, NULL::text) as v1, try_convert_by_sql(v, NULL::text) as v2 from tt_inet) as t(v1, v2) where not (v1 = v2); +select * from (select try_convert(v, NULL::inet) as v1, try_convert_by_sql(v, NULL::inet) as v2 from (select v::text from tt_inet) as t(v)) as t(v1, v2) where not (v1 = v2); +select * from (select try_convert(v, NULL::inet) as v1, try_convert_by_sql(v, NULL::inet) as v2 from (select ('!@#%^&*' || v::text || '!@#%^&*') from tt_inet) as t(v)) as t(v1, v2) where not (v1 = v2); +select * from (select try_convert(v, NULL::text) as v1, try_convert_by_sql(v, NULL::text) as v2 from tt_macaddr) as t(v1, v2) where not (v1 = v2); +select * from (select try_convert(v, NULL::macaddr) as v1, try_convert_by_sql(v, NULL::macaddr) as v2 from (select v::text from tt_macaddr) as t(v)) as t(v1, v2) where not (v1 = v2); +select * from (select try_convert(v, NULL::macaddr) as v1, try_convert_by_sql(v, NULL::macaddr) as v2 from (select ('!@#%^&*' || v::text || '!@#%^&*') from tt_macaddr) as t(v)) as t(v1, v2) where not (v1 = v2); select * from (select try_convert(v, NULL::text) as v1, try_convert_by_sql(v, NULL::text) as v2 from tt_text) as t(v1, v2) where not (v1 = v2); select * from (select try_convert(v, NULL::text) as v1, try_convert_by_sql(v, NULL::text) as v2 from (select v::text from tt_text) as t(v)) as t(v1, v2) where not (v1 = v2); select * from (select try_convert(v, NULL::text) as v1, try_convert_by_sql(v, NULL::text) as v2 from (select ('!@#%^&*' || v::text || '!@#%^&*') from tt_text) as t(v)) as t(v1, v2) where not (v1 = v2); @@ -270,6 +315,10 @@ select * from (select try_convert(v, NULL::timestamp) as v1, try_convert_by_sql( select * from (select try_convert(v, NULL::timetz) as v1, try_convert_by_sql(v, NULL::timetz) as v2 from tt_timestamptz) as t(v1, v2) where not (v1 = v2); select * from (select try_convert(v, NULL::time) as v1, try_convert_by_sql(v, NULL::time) as v2 from tt_interval) as t(v1, v2) where not (v1 = v2); select * from (select try_convert(v, NULL::time) as v1, try_convert_by_sql(v, NULL::time) as v2 from tt_timetz) as t(v1, v2) where not (v1 = v2); +select * from (select try_convert(v, NULL::inet) as v1, try_convert_by_sql(v, NULL::inet) as v2 from tt_cidr) as t(v1, v2) where not (v1 = v2); +select * from (select try_convert(v, NULL::cidr) as v1, try_convert_by_sql(v, NULL::cidr) as v2 from tt_inet) as t(v1, v2) where not (v1 = v2); +select * from (select try_convert(v, NULL::text) as v1, try_convert_by_sql(v, NULL::text) as v2 from tt_cidr) as t(v1, v2) where not (v1 = v2); +select * from (select try_convert(v, NULL::text) as v1, try_convert_by_sql(v, NULL::text) as v2 from tt_inet) as t(v1, v2) where not (v1 = v2); select * from (select try_convert(v, NULL::text) as v1, try_convert_by_sql(v, NULL::text) as v2 from tt_bool) as t(v1, v2) where not (v1 = v2); select * from (select try_convert(v, NULL::time) as v1, try_convert_by_sql(v, NULL::time) as v2 from tt_time) as t(v1, v2) where not (v1 = v2); select * from (select try_convert(v, NULL::timestamp) as v1, try_convert_by_sql(v, NULL::timestamp) as v2 from tt_timestamp) as t(v1, v2) where not (v1 = v2); diff --git a/contrib/try_convert/output/try_convert.source b/contrib/try_convert/output/try_convert.source index 4c2b81f388..053293bc63 100644 --- a/contrib/try_convert/output/try_convert.source +++ b/contrib/try_convert/output/try_convert.source @@ -1,6 +1,6 @@ -- SCRIPT-GENERATED TEST for TRY_CONVERT --- Tests 14 types of 91 from pg_types.h --- Tests 52 cast of 206 from pg_cast.h +-- Tests 17 types of 91 from pg_types.h +-- Tests 56 cast of 206 from pg_cast.h create schema tryconvert; set search_path = tryconvert; -- start_ignore @@ -136,6 +136,36 @@ $func$ -- do nothing: _out already carries default END $func$; +CREATE OR REPLACE FUNCTION try_convert_by_sql(_in cidr, INOUT _out ANYELEMENT) + LANGUAGE plpgsql AS +$func$ + BEGIN + EXECUTE format('SELECT %L::%s', $1, source_type) + INTO _out; + EXCEPTION WHEN others THEN + -- do nothing: _out already carries default + END +$func$; +CREATE OR REPLACE FUNCTION try_convert_by_sql(_in inet, INOUT _out ANYELEMENT) + LANGUAGE plpgsql AS +$func$ + BEGIN + EXECUTE format('SELECT %L::%s', $1, source_type) + INTO _out; + EXCEPTION WHEN others THEN + -- do nothing: _out already carries default + END +$func$; +CREATE OR REPLACE FUNCTION try_convert_by_sql(_in macaddr, INOUT _out ANYELEMENT) + LANGUAGE plpgsql AS +$func$ + BEGIN + EXECUTE format('SELECT %L::%s', $1, source_type) + INTO _out; + EXCEPTION WHEN others THEN + -- do nothing: _out already carries default + END +$func$; CREATE OR REPLACE FUNCTION try_convert_by_sql(_in text, INOUT _out ANYELEMENT) LANGUAGE plpgsql AS $func$ @@ -173,6 +203,12 @@ CREATE TABLE tt_timestamptz (v timestamptz) DISTRIBUTED BY (v); COPY tt_timestamptz from '@abs_srcdir@/data/tt_timestamptz.data'; CREATE TABLE tt_interval (v interval) DISTRIBUTED BY (v); COPY tt_interval from '@abs_srcdir@/data/tt_interval.data'; +CREATE TABLE tt_cidr (v cidr) DISTRIBUTED BY (v); +COPY tt_cidr from '@abs_srcdir@/data/tt_cidr.data'; +CREATE TABLE tt_inet (v inet) DISTRIBUTED BY (v); +COPY tt_inet from '@abs_srcdir@/data/tt_inet.data'; +CREATE TABLE tt_macaddr (v macaddr) DISTRIBUTED BY (v); +COPY tt_macaddr from '@abs_srcdir@/data/tt_macaddr.data'; CREATE TABLE tt_text (v text) DISTRIBUTED BY (v); COPY tt_text from '@abs_srcdir@/data/tt_text.data'; -- TEXT TESTS @@ -371,6 +407,51 @@ select * from (select try_convert(v, NULL::interval) as v1, try_convert_by_sql(v ----+---- (0 rows) +select * from (select try_convert(v, NULL::text) as v1, try_convert_by_sql(v, NULL::text) as v2 from tt_cidr) as t(v1, v2) where not (v1 = v2); + v1 | v2 +----+---- +(0 rows) + +select * from (select try_convert(v, NULL::cidr) as v1, try_convert_by_sql(v, NULL::cidr) as v2 from (select v::text from tt_cidr) as t(v)) as t(v1, v2) where not (v1 = v2); + v1 | v2 +----+---- +(0 rows) + +select * from (select try_convert(v, NULL::cidr) as v1, try_convert_by_sql(v, NULL::cidr) as v2 from (select ('!@#%^&*' || v::text || '!@#%^&*') from tt_cidr) as t(v)) as t(v1, v2) where not (v1 = v2); + v1 | v2 +----+---- +(0 rows) + +select * from (select try_convert(v, NULL::text) as v1, try_convert_by_sql(v, NULL::text) as v2 from tt_inet) as t(v1, v2) where not (v1 = v2); + v1 | v2 +----+---- +(0 rows) + +select * from (select try_convert(v, NULL::inet) as v1, try_convert_by_sql(v, NULL::inet) as v2 from (select v::text from tt_inet) as t(v)) as t(v1, v2) where not (v1 = v2); + v1 | v2 +----+---- +(0 rows) + +select * from (select try_convert(v, NULL::inet) as v1, try_convert_by_sql(v, NULL::inet) as v2 from (select ('!@#%^&*' || v::text || '!@#%^&*') from tt_inet) as t(v)) as t(v1, v2) where not (v1 = v2); + v1 | v2 +----+---- +(0 rows) + +select * from (select try_convert(v, NULL::text) as v1, try_convert_by_sql(v, NULL::text) as v2 from tt_macaddr) as t(v1, v2) where not (v1 = v2); + v1 | v2 +----+---- +(0 rows) + +select * from (select try_convert(v, NULL::macaddr) as v1, try_convert_by_sql(v, NULL::macaddr) as v2 from (select v::text from tt_macaddr) as t(v)) as t(v1, v2) where not (v1 = v2); + v1 | v2 +----+---- +(0 rows) + +select * from (select try_convert(v, NULL::macaddr) as v1, try_convert_by_sql(v, NULL::macaddr) as v2 from (select ('!@#%^&*' || v::text || '!@#%^&*') from tt_macaddr) as t(v)) as t(v1, v2) where not (v1 = v2); + v1 | v2 +----+---- +(0 rows) + select * from (select try_convert(v, NULL::text) as v1, try_convert_by_sql(v, NULL::text) as v2 from tt_text) as t(v1, v2) where not (v1 = v2); v1 | v2 ----+---- @@ -612,6 +693,26 @@ select * from (select try_convert(v, NULL::time) as v1, try_convert_by_sql(v, NU ----+---- (0 rows) +select * from (select try_convert(v, NULL::inet) as v1, try_convert_by_sql(v, NULL::inet) as v2 from tt_cidr) as t(v1, v2) where not (v1 = v2); + v1 | v2 +----+---- +(0 rows) + +select * from (select try_convert(v, NULL::cidr) as v1, try_convert_by_sql(v, NULL::cidr) as v2 from tt_inet) as t(v1, v2) where not (v1 = v2); + v1 | v2 +----+---- +(0 rows) + +select * from (select try_convert(v, NULL::text) as v1, try_convert_by_sql(v, NULL::text) as v2 from tt_cidr) as t(v1, v2) where not (v1 = v2); + v1 | v2 +----+---- +(0 rows) + +select * from (select try_convert(v, NULL::text) as v1, try_convert_by_sql(v, NULL::text) as v2 from tt_inet) as t(v1, v2) where not (v1 = v2); + v1 | v2 +----+---- +(0 rows) + select * from (select try_convert(v, NULL::text) as v1, try_convert_by_sql(v, NULL::text) as v2 from tt_bool) as t(v1, v2) where not (v1 = v2); v1 | v2 ----+---- diff --git a/contrib/try_convert/try_convert--1.0.sql b/contrib/try_convert/try_convert--1.0.sql index 868dc1235e..641c9f2ff5 100644 --- a/contrib/try_convert/try_convert--1.0.sql +++ b/contrib/try_convert/try_convert--1.0.sql @@ -45,3 +45,8 @@ select add_type_for_try_convert('interval'::regtype); select add_type_for_try_convert('text'::regtype); select add_type_for_try_convert('bool'::regtype); + +-- IP/MAC +select add_type_for_try_convert('cidr'::regtype); +select add_type_for_try_convert('inet'::regtype); +select add_type_for_try_convert('macaddr'::regtype);