Compare commits

..

10 Commits

Author SHA1 Message Date
jordi fita mas ecc78c9590 Add Debian packaging 2023-01-24 15:08:30 +01:00
Peter Eisentraut 00241b96b8 CI: Remove Travis, add Cirrus 2022-05-26 17:03:29 +02:00
Peter Eisentraut 7a7849a48a Fix -Wimplicit-fallthrough=3 warning
for PostgreSQL 13
2020-05-21 08:36:08 +02:00
Peter Eisentraut 969031cd25 Travis CI: Fix build script
We need to pass PG_CONFIG to "sudo make install" because sudo clears
the PATH and so it might run the install step against another version.
2020-05-21 08:22:45 +02:00
Peter Eisentraut 9277ca4d9c Travis CI: Update to bionic, add new PostgreSQL versions 2019-12-28 10:28:52 +01:00
Peter Eisentraut e5d25a8fe9 Travis CI: Update setup
Update PGDG repo setup, update to xenial, use inline scripts instead
of external gists.
2019-04-24 11:43:45 +02:00
Peter Eisentraut 437ae00801 Travis CI: Add new PostgreSQL versions 2019-04-23 18:21:16 +02:00
Peter Eisentraut dd3f45945b Add license file
closes #5
2015-12-24 22:43:34 -05:00
Peter Eisentraut 73270357c5 Refine sort order 2015-12-23 22:35:15 -05:00
Peter Eisentraut a9cf856ca0 Add more URLs to tests, mainly for checking sorting 2015-12-23 19:00:57 -05:00
13 changed files with 374 additions and 56 deletions

35
.cirrus.yml Normal file
View File

@ -0,0 +1,35 @@
env:
DEBIAN_FRONTEND: noninteractive
LANG: C
task:
name: Linux (Debian/Ubuntu)
matrix:
- container:
image: ubuntu:20.04
env:
matrix:
- PGVERSION: 14
- PGVERSION: 13
- PGVERSION: 12
- PGVERSION: 11
- PGVERSION: 10
- PGVERSION: 9.6
- PGVERSION: 9.5
- PGVERSION: 9.4
- PGVERSION: 9.3
setup_script:
- apt-get update
- apt-get -y install curl gnupg lsb-release
- curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -
- echo "deb http://apt.postgresql.org/pub/repos/apt/ $(lsb_release -cs)-pgdg main" | tee /etc/apt/sources.list.d/pgdg.list
- apt-get update
- apt-get -y install gcc liburiparser-dev make pkg-config postgresql-$PGVERSION postgresql-server-dev-$PGVERSION
- pg_createcluster --start $PGVERSION test -p 55435 -- -A trust
build_script:
- PATH=/usr/lib/postgresql/$PGVERSION/bin:$PATH
- make all
- make install
test_script:
- PATH=/usr/lib/postgresql/$PGVERSION/bin:$PATH
- PGPORT=55435 make installcheck PGUSER=postgres

View File

@ -1,14 +0,0 @@
language: c
before_install:
- wget https://gist.github.com/petere/5893799/raw/apt.postgresql.org.sh
- wget https://gist.github.com/petere/6023944/raw/pg-travis-test.sh
- sudo sh ./apt.postgresql.org.sh
install:
- sudo apt-get install -qq liburiparser-dev
env:
- PGVERSION=9.1
- PGVERSION=9.2
- PGVERSION=9.3
- PGVERSION=9.4
script:
- bash ./pg-travis-test.sh

19
LICENSE.md Normal file
View File

@ -0,0 +1,19 @@
© 2015 Peter Eisentraut <peter@eisentraut.org>
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose, without fee, and without a written
agreement is hereby granted, provided that the above copyright notice
and this paragraph and the following two paragraphs appear in all
copies.
IN NO EVENT SHALL THE AUTHORS BE LIABLE TO ANY PARTY FOR DIRECT,
INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
DOCUMENTATION, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
THE AUTHORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS
IS" BASIS, AND THE AUTHORS HAVE NO OBLIGATIONS TO PROVIDE MAINTENANCE,
SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

5
debian/changelog vendored Normal file
View File

@ -0,0 +1,5 @@
pguri (1.20151224-1) bullseye; urgency=medium
* Add Debian packaging
-- jordi fita mas <jordi@tandem.blog> Tue, 24 Jan 2023 13:07:39 +0000

34
debian/control vendored Normal file
View File

@ -0,0 +1,34 @@
Source: pguri
Section: database
Priority: optional
Maintainer: jordi fita mas <jordi@tandem.blog>
Build-Depends:
debhelper-compat (= 13),
postgresql-all (>= 217~),
liburiparser-dev
Standards-Version: 4.6.0
Vcs-Browser: https://github.com/petere/pguri
Vcs-Git: https://github.com/petere/pguri.git
Homepage: https://github.com/petere/pguri
Rules-Requires-Root: no
Package: postgresql-13-pguri
Architecture: all
Depends:
${shlibs:Depends},
${misc:Depends},
postgresql-13
description: uri type for PostgreSQL
This is an extension for PostgreSQL that provides a uri data type. Advantages
over using plain text for storing URIs include:
.
* URI syntax checking,
* functions for extracting URI components, and
* human-friendly sorting.
.
The actual URI parsing is provided by the uriparser library, which supports
URI syntax as per RFC 3986.
.
Note that this might not be the right data type to use if you want to store
user-provided URI data, such as HTTP referrers, since they might contain
arbitrary junk.

34
debian/control.in vendored Normal file
View File

@ -0,0 +1,34 @@
Source: pguri
Section: database
Priority: optional
Maintainer: jordi fita mas <jordi@tandem.blog>
Build-Depends:
debhelper-compat (= 13),
postgresql-all (>= 217~),
liburiparser-dev
Standards-Version: 4.6.0
Vcs-Browser: https://github.com/petere/pguri
Vcs-Git: https://github.com/petere/pguri.git
Homepage: https://github.com/petere/pguri
Rules-Requires-Root: no
Package: postgresql-PGVERSION-pguri
Architecture: all
Depends:
${shlibs:Depends},
${misc:Depends},
postgresql-PGVERSION
description: uri type for PostgreSQL
This is an extension for PostgreSQL that provides a uri data type. Advantages
over using plain text for storing URIs include:
.
* URI syntax checking,
* functions for extracting URI components, and
* human-friendly sorting.
.
The actual URI parsing is provided by the uriparser library, which supports
URI syntax as per RFC 3986.
.
Note that this might not be the right data type to use if you want to store
user-provided URI data, such as HTTP referrers, since they might contain
arbitrary junk.

29
debian/copyright vendored Normal file
View File

@ -0,0 +1,29 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Source: https://github.com/petere/pguri
Upstream-Name: pguri
Upstream-Contact: peter@eisentraut.org
Files: *
Copyright: 2015 Peter Eisentraut
License:
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose, without fee, and without a written agreement is
hereby granted, provided that the above copyright notice and this paragraph and
the following two paragraphs appear in all copies.
.
IN NO EVENT SHALL THE AUTHORS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE AUTHORS HAVE
BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.
THE AUTHORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE
AUTHORS HAVE NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
ENHANCEMENTS, OR MODIFICATIONS.
Files: debian/*
Copyright: 2023 jordi fita mas
License:
This debian package is distributed under the same license as the source
package.

1
debian/pgversions vendored Normal file
View File

@ -0,0 +1 @@
13+

6
debian/rules vendored Executable file
View File

@ -0,0 +1,6 @@
#!/usr/bin/make -f
include /usr/share/postgresql-common/pgxs_debian_control.mk
%:
dh $@ --with pgxs_loop

1
debian/source/format vendored Normal file
View File

@ -0,0 +1 @@
3.0 (quilt)

View File

@ -4,10 +4,14 @@ CREATE TABLE test (a serial, b uri);
INSERT INTO test (b) INSERT INTO test (b)
VALUES ('http://www.postgresql.org/'), VALUES ('http://www.postgresql.org/'),
('http://www.postgresql.org/docs/devel/static/xfunc-sql.html#XFUNC-SQL-FUNCTION-ARGUMENTS'), ('http://www.postgresql.org/docs/devel/static/xfunc-sql.html#XFUNC-SQL-FUNCTION-ARGUMENTS'),
('http://www.postgresql.org:591/'),
('http://www.postgresql.org:80/'),
('https://duckduckgo.com/?q=postgresql&ia=about'), ('https://duckduckgo.com/?q=postgresql&ia=about'),
('ftp://ftp.gnu.org/gnu/bison'), ('ftp://ftp.gnu.org/gnu/bison'),
('mailto:foo@example.com'), ('mailto:foo@example.com'),
('ssh://username@review.openstack.org:29418/openstack/nova.git'), ('ssh://username@review.openstack.org:29418/openstack/nova.git'),
('ssh://foobar@review.openstack.org:29418/openstack/nova.git'),
('ssh://review.openstack.org:29418/openstack/nova.git'),
('http://admin:password@192.168.0.1'), ('http://admin:password@192.168.0.1'),
('http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html'), ('http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html'),
('http://[1080::8:800:200C:417A]/foo'), ('http://[1080::8:800:200C:417A]/foo'),
@ -26,22 +30,26 @@ SELECT * FROM test;
----+----------------------------------------------------------------------------------------- ----+-----------------------------------------------------------------------------------------
1 | http://www.postgresql.org/ 1 | http://www.postgresql.org/
2 | http://www.postgresql.org/docs/devel/static/xfunc-sql.html#XFUNC-SQL-FUNCTION-ARGUMENTS 2 | http://www.postgresql.org/docs/devel/static/xfunc-sql.html#XFUNC-SQL-FUNCTION-ARGUMENTS
3 | https://duckduckgo.com/?q=postgresql&ia=about 3 | http://www.postgresql.org:591/
4 | ftp://ftp.gnu.org/gnu/bison 4 | http://www.postgresql.org:80/
5 | mailto:foo@example.com 5 | https://duckduckgo.com/?q=postgresql&ia=about
6 | ssh://username@review.openstack.org:29418/openstack/nova.git 6 | ftp://ftp.gnu.org/gnu/bison
7 | http://admin:password@192.168.0.1 7 | mailto:foo@example.com
8 | http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html 8 | ssh://username@review.openstack.org:29418/openstack/nova.git
9 | http://[1080::8:800:200C:417A]/foo 9 | ssh://foobar@review.openstack.org:29418/openstack/nova.git
10 | http://host: 10 | ssh://review.openstack.org:29418/openstack/nova.git
11 | 11 | http://admin:password@192.168.0.1
12 | / 12 | http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html
13 | foobar 13 | http://[1080::8:800:200C:417A]/foo
14 | /foobar 14 | http://host:
15 | HTTP://www.EXAMPLE.com/ 15 |
16 | http://www.ex%41mple.com/ 16 | /
17 | eXAMPLE://a/./b/../b/%63/%7bfoo%7d 17 | foobar
(17 rows) 18 | /foobar
19 | HTTP://www.EXAMPLE.com/
20 | http://www.ex%41mple.com/
21 | eXAMPLE://a/./b/../b/%63/%7bfoo%7d
(21 rows)
-- error cases -- error cases
SELECT uri 'http://host:port/'; SELECT uri 'http://host:port/';
@ -86,6 +94,30 @@ uri_path_array | {docs,devel,static,xfunc-sql.html}
uri_query | _null_ uri_query | _null_
uri_fragment | XFUNC-SQL-FUNCTION-ARGUMENTS uri_fragment | XFUNC-SQL-FUNCTION-ARGUMENTS
-[ RECORD 3 ]--+---------------------------------------------------------------------------------------- -[ RECORD 3 ]--+----------------------------------------------------------------------------------------
uri | http://www.postgresql.org:591/
uri_normalize | http://www.postgresql.org:591/
uri_scheme | http
uri_userinfo | _null_
uri_host | www.postgresql.org
uri_host_inet | _null_
uri_port | 591
uri_path | /
uri_path_array | {""}
uri_query | _null_
uri_fragment | _null_
-[ RECORD 4 ]--+----------------------------------------------------------------------------------------
uri | http://www.postgresql.org:80/
uri_normalize | http://www.postgresql.org:80/
uri_scheme | http
uri_userinfo | _null_
uri_host | www.postgresql.org
uri_host_inet | _null_
uri_port | 80
uri_path | /
uri_path_array | {""}
uri_query | _null_
uri_fragment | _null_
-[ RECORD 5 ]--+----------------------------------------------------------------------------------------
uri | https://duckduckgo.com/?q=postgresql&ia=about uri | https://duckduckgo.com/?q=postgresql&ia=about
uri_normalize | https://duckduckgo.com/?q=postgresql&ia=about uri_normalize | https://duckduckgo.com/?q=postgresql&ia=about
uri_scheme | https uri_scheme | https
@ -97,7 +129,7 @@ uri_path | /
uri_path_array | {""} uri_path_array | {""}
uri_query | q=postgresql&ia=about uri_query | q=postgresql&ia=about
uri_fragment | _null_ uri_fragment | _null_
-[ RECORD 4 ]--+---------------------------------------------------------------------------------------- -[ RECORD 6 ]--+----------------------------------------------------------------------------------------
uri | ftp://ftp.gnu.org/gnu/bison uri | ftp://ftp.gnu.org/gnu/bison
uri_normalize | ftp://ftp.gnu.org/gnu/bison uri_normalize | ftp://ftp.gnu.org/gnu/bison
uri_scheme | ftp uri_scheme | ftp
@ -109,7 +141,7 @@ uri_path | /gnu/bison
uri_path_array | {gnu,bison} uri_path_array | {gnu,bison}
uri_query | _null_ uri_query | _null_
uri_fragment | _null_ uri_fragment | _null_
-[ RECORD 5 ]--+---------------------------------------------------------------------------------------- -[ RECORD 7 ]--+----------------------------------------------------------------------------------------
uri | mailto:foo@example.com uri | mailto:foo@example.com
uri_normalize | mailto:foo@example.com uri_normalize | mailto:foo@example.com
uri_scheme | mailto uri_scheme | mailto
@ -121,7 +153,7 @@ uri_path | foo@example.com
uri_path_array | {foo@example.com} uri_path_array | {foo@example.com}
uri_query | _null_ uri_query | _null_
uri_fragment | _null_ uri_fragment | _null_
-[ RECORD 6 ]--+---------------------------------------------------------------------------------------- -[ RECORD 8 ]--+----------------------------------------------------------------------------------------
uri | ssh://username@review.openstack.org:29418/openstack/nova.git uri | ssh://username@review.openstack.org:29418/openstack/nova.git
uri_normalize | ssh://username@review.openstack.org:29418/openstack/nova.git uri_normalize | ssh://username@review.openstack.org:29418/openstack/nova.git
uri_scheme | ssh uri_scheme | ssh
@ -133,7 +165,31 @@ uri_path | /openstack/nova.git
uri_path_array | {openstack,nova.git} uri_path_array | {openstack,nova.git}
uri_query | _null_ uri_query | _null_
uri_fragment | _null_ uri_fragment | _null_
-[ RECORD 7 ]--+---------------------------------------------------------------------------------------- -[ RECORD 9 ]--+----------------------------------------------------------------------------------------
uri | ssh://foobar@review.openstack.org:29418/openstack/nova.git
uri_normalize | ssh://foobar@review.openstack.org:29418/openstack/nova.git
uri_scheme | ssh
uri_userinfo | foobar
uri_host | review.openstack.org
uri_host_inet | _null_
uri_port | 29418
uri_path | /openstack/nova.git
uri_path_array | {openstack,nova.git}
uri_query | _null_
uri_fragment | _null_
-[ RECORD 10 ]-+----------------------------------------------------------------------------------------
uri | ssh://review.openstack.org:29418/openstack/nova.git
uri_normalize | ssh://review.openstack.org:29418/openstack/nova.git
uri_scheme | ssh
uri_userinfo | _null_
uri_host | review.openstack.org
uri_host_inet | _null_
uri_port | 29418
uri_path | /openstack/nova.git
uri_path_array | {openstack,nova.git}
uri_query | _null_
uri_fragment | _null_
-[ RECORD 11 ]-+----------------------------------------------------------------------------------------
uri | http://admin:password@192.168.0.1 uri | http://admin:password@192.168.0.1
uri_normalize | http://admin:password@192.168.0.1 uri_normalize | http://admin:password@192.168.0.1
uri_scheme | http uri_scheme | http
@ -145,7 +201,7 @@ uri_path |
uri_path_array | {} uri_path_array | {}
uri_query | _null_ uri_query | _null_
uri_fragment | _null_ uri_fragment | _null_
-[ RECORD 8 ]--+---------------------------------------------------------------------------------------- -[ RECORD 12 ]-+----------------------------------------------------------------------------------------
uri | http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html uri | http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html
uri_normalize | http://[fedc:ba98:7654:3210:fedc:ba98:7654:3210]:80/index.html uri_normalize | http://[fedc:ba98:7654:3210:fedc:ba98:7654:3210]:80/index.html
uri_scheme | http uri_scheme | http
@ -157,7 +213,7 @@ uri_path | /index.html
uri_path_array | {index.html} uri_path_array | {index.html}
uri_query | _null_ uri_query | _null_
uri_fragment | _null_ uri_fragment | _null_
-[ RECORD 9 ]--+---------------------------------------------------------------------------------------- -[ RECORD 13 ]-+----------------------------------------------------------------------------------------
uri | http://[1080::8:800:200C:417A]/foo uri | http://[1080::8:800:200C:417A]/foo
uri_normalize | http://[1080:0000:0000:0000:0008:0800:200c:417a]/foo uri_normalize | http://[1080:0000:0000:0000:0008:0800:200c:417a]/foo
uri_scheme | http uri_scheme | http
@ -169,7 +225,7 @@ uri_path | /foo
uri_path_array | {foo} uri_path_array | {foo}
uri_query | _null_ uri_query | _null_
uri_fragment | _null_ uri_fragment | _null_
-[ RECORD 10 ]-+---------------------------------------------------------------------------------------- -[ RECORD 14 ]-+----------------------------------------------------------------------------------------
uri | http://host: uri | http://host:
uri_normalize | http://host: uri_normalize | http://host:
uri_scheme | http uri_scheme | http
@ -181,7 +237,7 @@ uri_path |
uri_path_array | {} uri_path_array | {}
uri_query | _null_ uri_query | _null_
uri_fragment | _null_ uri_fragment | _null_
-[ RECORD 11 ]-+---------------------------------------------------------------------------------------- -[ RECORD 15 ]-+----------------------------------------------------------------------------------------
uri | uri |
uri_normalize | uri_normalize |
uri_scheme | _null_ uri_scheme | _null_
@ -193,7 +249,7 @@ uri_path |
uri_path_array | {} uri_path_array | {}
uri_query | _null_ uri_query | _null_
uri_fragment | _null_ uri_fragment | _null_
-[ RECORD 12 ]-+---------------------------------------------------------------------------------------- -[ RECORD 16 ]-+----------------------------------------------------------------------------------------
uri | / uri | /
uri_normalize | / uri_normalize | /
uri_scheme | _null_ uri_scheme | _null_
@ -205,7 +261,7 @@ uri_path | /
uri_path_array | {} uri_path_array | {}
uri_query | _null_ uri_query | _null_
uri_fragment | _null_ uri_fragment | _null_
-[ RECORD 13 ]-+---------------------------------------------------------------------------------------- -[ RECORD 17 ]-+----------------------------------------------------------------------------------------
uri | foobar uri | foobar
uri_normalize | foobar uri_normalize | foobar
uri_scheme | _null_ uri_scheme | _null_
@ -217,7 +273,7 @@ uri_path | foobar
uri_path_array | {foobar} uri_path_array | {foobar}
uri_query | _null_ uri_query | _null_
uri_fragment | _null_ uri_fragment | _null_
-[ RECORD 14 ]-+---------------------------------------------------------------------------------------- -[ RECORD 18 ]-+----------------------------------------------------------------------------------------
uri | /foobar uri | /foobar
uri_normalize | /foobar uri_normalize | /foobar
uri_scheme | _null_ uri_scheme | _null_
@ -229,7 +285,7 @@ uri_path | /foobar
uri_path_array | {foobar} uri_path_array | {foobar}
uri_query | _null_ uri_query | _null_
uri_fragment | _null_ uri_fragment | _null_
-[ RECORD 15 ]-+---------------------------------------------------------------------------------------- -[ RECORD 19 ]-+----------------------------------------------------------------------------------------
uri | HTTP://www.EXAMPLE.com/ uri | HTTP://www.EXAMPLE.com/
uri_normalize | http://www.example.com/ uri_normalize | http://www.example.com/
uri_scheme | HTTP uri_scheme | HTTP
@ -241,7 +297,7 @@ uri_path | /
uri_path_array | {""} uri_path_array | {""}
uri_query | _null_ uri_query | _null_
uri_fragment | _null_ uri_fragment | _null_
-[ RECORD 16 ]-+---------------------------------------------------------------------------------------- -[ RECORD 20 ]-+----------------------------------------------------------------------------------------
uri | http://www.ex%41mple.com/ uri | http://www.ex%41mple.com/
uri_normalize | http://www.example.com/ uri_normalize | http://www.example.com/
uri_scheme | http uri_scheme | http
@ -253,7 +309,7 @@ uri_path | /
uri_path_array | {""} uri_path_array | {""}
uri_query | _null_ uri_query | _null_
uri_fragment | _null_ uri_fragment | _null_
-[ RECORD 17 ]-+---------------------------------------------------------------------------------------- -[ RECORD 21 ]-+----------------------------------------------------------------------------------------
uri | eXAMPLE://a/./b/../b/%63/%7bfoo%7d uri | eXAMPLE://a/./b/../b/%63/%7bfoo%7d
uri_normalize | example://a/b/c/%7Bfoo%7D uri_normalize | example://a/b/c/%7Bfoo%7D
uri_scheme | eXAMPLE uri_scheme | eXAMPLE
@ -274,20 +330,24 @@ SELECT DISTINCT b FROM test ORDER BY b;
/ /
/foobar /foobar
foobar foobar
HTTP://www.EXAMPLE.com/
eXAMPLE://a/./b/../b/%63/%7bfoo%7d eXAMPLE://a/./b/../b/%63/%7bfoo%7d
ftp://ftp.gnu.org/gnu/bison ftp://ftp.gnu.org/gnu/bison
http://[1080::8:800:200C:417A]/foo
http://admin:password@192.168.0.1 http://admin:password@192.168.0.1
http://[1080::8:800:200C:417A]/foo
http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html
http://host: http://host:
http://www.ex%41mple.com/ http://www.ex%41mple.com/
HTTP://www.EXAMPLE.com/
http://www.postgresql.org/ http://www.postgresql.org/
http://www.postgresql.org/docs/devel/static/xfunc-sql.html#XFUNC-SQL-FUNCTION-ARGUMENTS http://www.postgresql.org/docs/devel/static/xfunc-sql.html#XFUNC-SQL-FUNCTION-ARGUMENTS
http://www.postgresql.org:80/
http://www.postgresql.org:591/
https://duckduckgo.com/?q=postgresql&ia=about https://duckduckgo.com/?q=postgresql&ia=about
mailto:foo@example.com mailto:foo@example.com
ssh://review.openstack.org:29418/openstack/nova.git
ssh://foobar@review.openstack.org:29418/openstack/nova.git
ssh://username@review.openstack.org:29418/openstack/nova.git ssh://username@review.openstack.org:29418/openstack/nova.git
(17 rows) (21 rows)
CREATE TABLE test2 (x text, y uri); CREATE TABLE test2 (x text, y uri);
INSERT INTO test2 VALUES ('foo', 'http://www.postgresql.org/'); INSERT INTO test2 VALUES ('foo', 'http://www.postgresql.org/');

View File

@ -7,10 +7,14 @@ CREATE TABLE test (a serial, b uri);
INSERT INTO test (b) INSERT INTO test (b)
VALUES ('http://www.postgresql.org/'), VALUES ('http://www.postgresql.org/'),
('http://www.postgresql.org/docs/devel/static/xfunc-sql.html#XFUNC-SQL-FUNCTION-ARGUMENTS'), ('http://www.postgresql.org/docs/devel/static/xfunc-sql.html#XFUNC-SQL-FUNCTION-ARGUMENTS'),
('http://www.postgresql.org:591/'),
('http://www.postgresql.org:80/'),
('https://duckduckgo.com/?q=postgresql&ia=about'), ('https://duckduckgo.com/?q=postgresql&ia=about'),
('ftp://ftp.gnu.org/gnu/bison'), ('ftp://ftp.gnu.org/gnu/bison'),
('mailto:foo@example.com'), ('mailto:foo@example.com'),
('ssh://username@review.openstack.org:29418/openstack/nova.git'), ('ssh://username@review.openstack.org:29418/openstack/nova.git'),
('ssh://foobar@review.openstack.org:29418/openstack/nova.git'),
('ssh://review.openstack.org:29418/openstack/nova.git'),
('http://admin:password@192.168.0.1'), ('http://admin:password@192.168.0.1'),
('http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html'), ('http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html'),
('http://[1080::8:800:200C:417A]/foo'), ('http://[1080::8:800:200C:417A]/foo'),

120
uri.c
View File

@ -42,6 +42,7 @@ parse_uri(const char *s, UriUriA *urip)
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("invalid input syntax for type uri at or near \"%s\"", errmsg("invalid input syntax for type uri at or near \"%s\"",
state.errorPos))); state.errorPos)));
break;
default: default:
elog(ERROR, "liburiparser error code %d", state.errorCode); elog(ERROR, "liburiparser error code %d", state.errorCode);
} }
@ -170,6 +171,16 @@ uri_host_inet(PG_FUNCTION_ARGS)
} }
} }
static int
_uri_port_num(UriUriA *urip)
{
if (!urip->portText.first || !urip->portText.afterLast
|| urip->portText.afterLast == urip->portText.first)
return -1;
return strtol(pnstrdup(urip->portText.first, urip->portText.afterLast - urip->portText.first),
NULL, 10);
}
PG_FUNCTION_INFO_V1(uri_port); PG_FUNCTION_INFO_V1(uri_port);
Datum Datum
uri_port(PG_FUNCTION_ARGS) uri_port(PG_FUNCTION_ARGS)
@ -177,15 +188,14 @@ uri_port(PG_FUNCTION_ARGS)
Datum arg = PG_GETARG_DATUM(0); Datum arg = PG_GETARG_DATUM(0);
char *s = TextDatumGetCString(arg); char *s = TextDatumGetCString(arg);
UriUriA uri; UriUriA uri;
const char *p; int num;
parse_uri(s, &uri); parse_uri(s, &uri);
if (!uri.portText.first || !uri.portText.afterLast num = _uri_port_num(&uri);
|| uri.portText.afterLast == uri.portText.first)
PG_RETURN_NULL();
p = pnstrdup(uri.portText.first, uri.portText.afterLast - uri.portText.first);
uriFreeUriMembersA(&uri); uriFreeUriMembersA(&uri);
PG_RETURN_INT32(strtol(p, NULL, 10)); if (num < 0)
PG_RETURN_NULL();
PG_RETURN_INT32(num);
} }
PG_FUNCTION_INFO_V1(uri_query); PG_FUNCTION_INFO_V1(uri_query);
@ -324,6 +334,56 @@ uri_normalize(PG_FUNCTION_ARGS)
PG_RETURN_URI_P((uritype *) cstring_to_text(ret)); PG_RETURN_URI_P((uritype *) cstring_to_text(ret));
} }
static int
strcasecmp_ascii(const char *s1, const char *s2)
{
for (;;)
{
unsigned char ch1 = (unsigned char) *s1++;
unsigned char ch2 = (unsigned char) *s2++;
if (ch1 != ch2)
{
if (ch1 >= 'A' && ch1 <= 'Z')
ch1 += 'a' - 'A';
if (ch2 >= 'A' && ch2 <= 'Z')
ch2 += 'a' - 'A';
if (ch1 != ch2)
return (int) ch1 - (int) ch2;
}
if (ch1 == 0)
break;
}
return 0;
}
static int
strncasecmp_ascii(const char *s1, const char *s2, size_t n)
{
while (n-- > 0)
{
unsigned char ch1 = (unsigned char) *s1++;
unsigned char ch2 = (unsigned char) *s2++;
if (ch1 != ch2)
{
if (ch1 >= 'A' && ch1 <= 'Z')
ch1 += 'a' - 'A';
if (ch2 >= 'A' && ch2 <= 'Z')
ch2 += 'a' - 'A';
if (ch1 != ch2)
return (int) ch1 - (int) ch2;
}
if (ch1 == 0)
break;
}
return 0;
}
static int static int
cmp_text_range(UriTextRangeA a, UriTextRangeA b) cmp_text_range(UriTextRangeA a, UriTextRangeA b)
{ {
@ -338,7 +398,7 @@ cmp_text_range(UriTextRangeA a, UriTextRangeA b)
return 1; return 1;
else else
{ {
int x = strncmp(a.first, b.first, int x = strncasecmp_ascii(a.first, b.first,
Min(a.afterLast - a.first, b.afterLast - b.first)); Min(a.afterLast - a.first, b.afterLast - b.first));
if (x == 0) if (x == 0)
return (a.afterLast - a.first) - (b.afterLast - b.first); return (a.afterLast - a.first) - (b.afterLast - b.first);
@ -346,6 +406,44 @@ cmp_text_range(UriTextRangeA a, UriTextRangeA b)
} }
} }
static int
cmp_hosts(UriUriA *uap, UriUriA *ubp)
{
if (!uap->hostText.first)
{
if (!ubp->hostText.first)
return 0;
else
return -1;
}
else if (uap->hostData.ip4)
{
if (!ubp->hostText.first)
return 1;
else if (ubp->hostData.ip4)
return memcmp(uap->hostData.ip4->data,
ubp->hostData.ip4->data,
sizeof(uap->hostData.ip4->data));
else
return -1;
}
else if (uap->hostData.ip6)
{
if (!ubp->hostText.first)
return 1;
else if (ubp->hostData.ip4)
return 1;
else if (ubp->hostData.ip6)
return memcmp(uap->hostData.ip6->data,
ubp->hostData.ip6->data,
sizeof(uap->hostData.ip6->data));
else
return -1;
}
else
return cmp_text_range(uap->hostText, ubp->hostText);
}
static int static int
_uri_cmp(Datum a, Datum b) _uri_cmp(Datum a, Datum b)
{ {
@ -361,7 +459,13 @@ _uri_cmp(Datum a, Datum b)
if (res == 0) if (res == 0)
res = cmp_text_range(ua.scheme, ub.scheme); res = cmp_text_range(ua.scheme, ub.scheme);
if (res == 0) if (res == 0)
res = cmp_text_range(ua.hostText, ub.hostText); res = cmp_hosts(&ua, &ub);
if (res == 0)
res = _uri_port_num(&ua) - _uri_port_num(&ub);
if (res == 0)
res = cmp_text_range(ua.userInfo, ub.userInfo);
if (res == 0)
res = strcasecmp_ascii(sa, sb);
if (res == 0) if (res == 0)
res = strcmp(sa, sb); res = strcmp(sa, sb);
uriFreeUriMembersA(&ua); uriFreeUriMembersA(&ua);