Skip to content

Commit

Permalink
sql: Add INET built-in functions
Browse files Browse the repository at this point in the history
Adds further support for cockroachdb#6981.

This adds several built-in functions for the INET column. See
https://www.postgresql.org/docs/9.6/static/functions-net.html for
reference. The added built-ins are:
- abbrev(inet) text
- broadcast(inet) text
- family(inet) int
- host(inet) text
- hostmask(inet) inet
- masklen(inet) int
- netmask(inet) inet
- set_masklen(inet, int) inet
- text(inet) text
- inet_same_family(inet, inet) boolean

This does not include the built-ins
- network(inet) cidr
- inet_merge(inet, inet) cidr

This also moves 'FAMILY' in the SQL grammar from reserved_keyword to
type_func_name_keyword.
  • Loading branch information
lgo committed Sep 25, 2017
1 parent 028bbd8 commit b98505b
Show file tree
Hide file tree
Showing 8 changed files with 3,548 additions and 2,865 deletions.
324 changes: 324 additions & 0 deletions pkg/sql/logictest/testdata/logic_test/inet
Original file line number Diff line number Diff line change
Expand Up @@ -280,3 +280,327 @@ SELECT * FROM arrays
{}
{192.168.0.1/10,::1}
{192.168.0.1,192.168.0.1/10,::1,::ffff:1.2.3.4}


# Testing builtins

# Test abbrev
# For INET, abbev has the same output as ::string. This is not the case for
# CIDR. The input string is not always equal to the output string, e.g.
# abbrev('10.0/16'::inet) => '10.0.0.0/16'

query T
SELECT abbrev('10.1.0.0/16'::INET)
----
10.1.0.0/16

query T
SELECT abbrev('192.168.0.1/16'::INET)
----
192.168.0.1/16

query T
SELECT abbrev('192.168.0.1'::INET)
----
192.168.0.1

query T
SELECT abbrev('192.168.0.1/32'::INET)
----
192.168.0.1

query T
SELECT abbrev('10.0/16'::INET)
----
10.0.0.0/16

query T
SELECT abbrev('::ffff:192.168.0.1'::INET)
----
::ffff:192.168.0.1

query T
SELECT abbrev('::ffff:192.168.0.1/24'::INET)
----
::ffff:192.168.0.1/24

# Test broadcast

query T
SELECT broadcast('10.1.0.0/16'::INET)
----
10.1.255.255/16

query T
SELECT broadcast('192.168.0.1/16'::INET)
----
192.168.255.255/16

query T
SELECT broadcast('192.168.0.1'::INET)
----
192.168.0.1

query T
SELECT broadcast('192.168.0.1/32'::INET)
----
192.168.0.1

query T
SELECT broadcast('::ffff:192.168.0.1'::INET)
----
::ffff:192.168.0.1

query T
SELECT broadcast('::ffff:1.2.3.1/20'::INET)
----
0:fff:ffff:ffff:ffff:ffff:ffff:ffff/20

query T
SELECT broadcast('2001:4f8:3:ba::/64'::INET)
----
2001:4f8:3:ba:ffff:ffff:ffff:ffff/64

# Test family

query I
SELECT family('10.1.0.0/16'::INET)
----
4

query I
SELECT family('192.168.0.1/16'::INET)
----
4

query I
SELECT family('192.168.0.1'::INET)
----
4

query I
SELECT family('::ffff:192.168.0.1'::INET)
----
6

query I
SELECT family('::ffff:1.2.3.1/20'::INET)
----
6

query I
SELECT family('2001:4f8:3:ba::/64'::INET)
----
6

# Test host

query T
SELECT host('10.1.0.0/16'::INET)
----
10.1.0.0

query T
SELECT host('192.168.0.1/16'::INET)
----
192.168.0.1

query T
SELECT host('192.168.0.1'::INET)
----
192.168.0.1

query T
SELECT host('192.168.0.1/32'::INET)
----
192.168.0.1

query T
SELECT host('::ffff:192.168.0.1'::INET)
----
::ffff:192.168.0.1

query T
SELECT host('::ffff:192.168.0.1/24'::INET)
----
::ffff:192.168.0.1

# Test hostmask

query T
SELECT hostmask('192.168.1.2'::INET)
----
0.0.0.0

query T
SELECT hostmask('192.168.1.2/16'::INET)
----
0.0.255.255

query T
SELECT hostmask('192.168.1.2/10'::INET)
----
0.63.255.255

query T
SELECT hostmask('2001:4f8:3:ba::/64'::INET)
----
::ffff:ffff:ffff:ffff

# Test masklen

query I
SELECT masklen('192.168.1.2'::INET)
----
32

query I
SELECT masklen('192.168.1.2/16'::INET)
----
16

query I
SELECT masklen('192.168.1.2/10'::INET)
----
10

query I
SELECT masklen('2001:4f8:3:ba::/64'::INET)
----
64

query I
SELECT masklen('2001:4f8:3:ba::'::INET)
----
128

# Test netmask

query T
SELECT netmask('192.168.1.2'::INET)
----
255.255.255.255

query T
SELECT netmask('192.168.1.2/16'::INET)
----
255.255.0.0

query T
SELECT netmask('192.168.1.2/10'::INET)
----
255.192.0.0

query T
SELECT netmask('192.168.1.2/0'::INET)
----
0.0.0.0

query T
SELECT netmask('2001:4f8:3:ba::/64'::INET)
----
ffff:ffff:ffff:ffff::

query T
SELECT netmask('2001:4f8:3:ba::/0'::INET)
----
::

query T
SELECT netmask('2001:4f8:3:ba:2e0:81ff:fe22:d1f1/128'::INET)
----
ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff

query T
SELECT netmask('::ffff:1.2.3.1/120'::INET)
----
ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00

query T
SELECT netmask('::ffff:1.2.3.1/20'::INET)
----
ffff:f000::

# Test set_masklen

query T
SELECT set_masklen('10.1.0.0/16'::INET, 10)
----
10.1.0.0/10

query T
SELECT set_masklen('192.168.0.1/16'::INET, 32)
----
192.168.0.1

statement error invalid mask length
SELECT set_masklen('192.168.0.1'::INET, 100)

statement error invalid mask length
SELECT set_masklen('192.168.0.1'::INET, 33)

statement error invalid mask length
SELECT set_masklen('192.168.0.1'::INET, -1)

query T
SELECT set_masklen('192.168.0.1'::INET, 0)
----
192.168.0.1/0

query T
SELECT set_masklen('::ffff:192.168.0.1'::INET, 100)
----
::ffff:192.168.0.1/100

statement error invalid mask length
SELECT set_masklen('::ffff:192.168.0.1'::INET, -1)

statement error invalid mask length
SELECT set_masklen('::ffff:192.168.0.1'::INET, 129)

query T
SELECT set_masklen('::ffff:192.168.0.1/24'::INET, 0)
----
::ffff:192.168.0.1/0

# Test text
# The difference between text and abbrev/::string is that text always outputs
# the prefix length, whereas abbrev omit it when the prefix length is the
# total bits size (32 for IPv4, 128 for IPv6).

query T
SELECT text('10.1.0.0/16'::INET)
----
10.1.0.0/16

query T
SELECT text('192.168.0.1/16'::INET)
----
192.168.0.1/16

query T
SELECT text('192.168.0.1'::INET)
----
192.168.0.1/32

query T
SELECT text('192.168.0.1/32'::INET)
----
192.168.0.1/32

query T
SELECT text('::ffff:192.168.0.1'::INET)
----
::ffff:192.168.0.1/128

query T
SELECT text('::ffff:192.168.0.1/24'::INET)
----
::ffff:192.168.0.1/24

# Test inet_same_family

query T
SELECT text('::ffff:192.168.0.1/24'::INET)
----
::ffff:192.168.0.1/24
Loading

0 comments on commit b98505b

Please sign in to comment.