Skip to content

Commit 2c1d5cd

Browse files
mkgrgismkgrgis
and
mkgrgis
committed
Add initial SpatiaLite ↔ PostGIS support (#96)
Co-authored-by: mkgrgis <mihail.aksenov@bk.ru>
1 parent 9ec7b00 commit 2c1d5cd

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+20904
-2628
lines changed

.github/workflows/CI.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,9 @@ jobs:
6161
- name: install SQLite, ${{ matrix.config }} mode
6262
run: |
6363
if [[ "${{ matrix.config }}" == "default" ]]; then
64-
bash GitHubActions/install_sqlite.sh ${{ env.SQLITE_VERSION }} ${{ env.SQLITE_YEAR }}
64+
bash GitHubActions/install_sqlite.sh ${{ env.SQLITE_VERSION }} ${{ env.SQLITE_YEAR }} "${{ matrix.config }}"
6565
elif [[ "${{ matrix.config }}" == "postgis" ]]; then
66-
bash GitHubActions/install_sqlite.sh ${{ env.SQLITE_VERSION }} ${{ env.SQLITE_YEAR }} --enable-rtree
66+
bash GitHubActions/install_sqlite.sh ${{ env.SQLITE_VERSION }} ${{ env.SQLITE_YEAR }} "${{ matrix.config }}" --enable-rtree
6767
fi
6868
6969
- name: build sqlite_fdw, ${{ matrix.config }} mode

GIS.md

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
GIS support in SQLite Foreign Data Wrapper for PostgreSQL
2+
=========================================================
3+
4+
<img src="https://www.tmapy.cz/wp-content/uploads/2021/02/postgis-logo.png" align="center" height="80" alt="PostGIS"/> + <img src="https://www.gaia-gis.it/fossil/libspatialite/logo" align="center" height="80" alt="SpatiaLite"/>
5+
6+
SQLite FDW for PostgreSQL can connect PostgreSQL with or without [PostGIS](https://www.postgis.net/)
7+
to [SpatiaLite](https://www.gaia-gis.it/fossil/libspatialite/index) SQLite database file.
8+
This description contains only information about GIS support without common SQL and
9+
system descriptions from [common FDW description](README.md).
10+
11+
Notes about compilation environment and PROJ library
12+
----------------------------------------------------
13+
Both SpatiaLite and PostGIS uses [PROJ C++ library](https://github.com/OSGeo/PROJ) from
14+
[Open Source Geospatial Foundation](https://github.com/OSGeo) for reprojecting and some calculations.
15+
Recommended configuration of SQLite FDW with GIS support contains both SpatiaLite and PostGIS.
16+
**It is recommended to install only 1 version of PROJ in a system to avoid integration issue**.
17+
Before compilation you should ensure equal versions of PROJ library required by SpatiaLite and PostGIS on
18+
your system. Otherwise some encapsualted and unwanted memory freeing errors can occur.
19+
If you need different PROJ library versions, you can reference [this PROJ issue](https://github.com/OSGeo/PROJ/issues/4361)
20+
and try to use something like `CFLAGS="$CFLAGS -DPROJ_RENAME_SYMBOLS -O2"` during compilation of
21+
SpatiaLite or PostGIS to link one of this extensions with other PROJ version.
22+
23+
Common conditions of GIS support
24+
--------------------------------
25+
26+
1. SQLite FDW should be compiled with `ENABLE_GIS=1` environment variable value.
27+
2. You must install SpatiaLite header files before compilation.
28+
Linux packages like `libspatialite-dev` or `libspatialite-devel` can contain this files.
29+
3. A column should have data type (domain) name from following list:
30+
* addbandarg
31+
* box2d
32+
* box3d
33+
* geography
34+
* geometry
35+
* geometry_dump
36+
* geomval
37+
* getfaceedges_returntype
38+
* rastbandarg
39+
* raster
40+
* reclassarg
41+
* summarystats
42+
* topoelement
43+
* topoelementarray
44+
* topogeometry
45+
* unionarg
46+
* validatetopology_returntype
47+
48+
Only listed data types have full data transformation support:
49+
* geography
50+
* geometry
51+
52+
All other data types (domains) are treated as PostGIS specific, but unsupported.
53+
54+
You can use SpatiaLite GIS data support _without PostGIS installation_ after such
55+
SQL commands as `CREATE DOMAIN geometry AS bytea;` and `CREATE DOMAIN geography AS bytea;`.
56+
This allows to have in PostgreSQL PostGIS compatible `bytea` data easy
57+
convertable to PostGIS storage format.
58+
59+
PostGIS and SpatiaLite vector data formats
60+
-------------------------------------------
61+
62+
Vector GIS data in PostGIS can be stored in a columns with `geography` or `geometry`
63+
data type. This columns contains a binary data.
64+
[Well-known binary (WKB)](https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry#Well-known_binary)
65+
data storage format is a standard of [Open Geospatial Consortium (OGC)](https://en.wikipedia.org/wiki/Open_Geospatial_Consortium)
66+
and supported by [GEOS library](https://libgeos.org). PostGIS internal GIS data
67+
storage format based on WKB with [SRID](https://en.wikipedia.org/wiki/Spatial_reference_system#Identifiers)
68+
additions. This format is known as [EWKB](https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry#Format_variations) and supported by
69+
[GEOS library](https://libgeos.org) and SpatiaLite input/output functions.
70+
71+
Hexadecimal text representation of EWKB data is a transport form for `geography`
72+
and `geometry` GIS data between PostgreSQL and *SpatiLite input/output functions*.
73+
Hence no PostGIS input/output functions are necessary, but all of this functions
74+
are supported.
75+
76+
EWKB hexadecimal text data transport is faster than
77+
[EWKT](https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry)
78+
but slower than EWKB blob data transport.
79+
80+
SpatiaLite internal storage based on `blob` data [affinity](https://www.sqlite.org/datatype3.html)
81+
and is not a standard of [OGC](https://en.wikipedia.org/wiki/Open_Geospatial_Consortium).
82+
Also this format doesn't supported by [GEOS library](https://libgeos.org).
83+
84+
Limitations
85+
-----------
86+
87+
* In opposition to PostGIS, **SpatiaLite doesn't allow to store any GIS vector data without SRID**.
88+
Hence any well-formed SpatiaLite data can be converted for PostGIS, but
89+
well-formed PostGIS data _without SRID_ cannot be converted for SpatiaLite.
90+
All of SpatiaLite input functions will return `NULL` in this case.
91+
Please use [ST_SetSRID PostGIS function](https://postgis.net/docs/ST_SetSRID.html)
92+
in case of incomplete SRID data to prepare PostGIS data for importing to SpatiaLite
93+
or comparing with SpatiaLite data.
94+
95+
* Only `=` PostgreSQL operator is pushed down to SQLite (SpatiaLite) for vector GIS data such
96+
as `geography` or `geometry`. `<>` PostgreSQL operator is NOT pushed down.
97+
98+
End of description.

GitHubActions/build_postgis.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
# This script downloads PostgreSQL from the official web site into ./workdir
66
# then builds it.
77
#
8-
# Usage: ./build_postgres.sh pg_version postgis_version
8+
# Usage: ./build_postgis.sh pg_version postgis_version
99
# pg_version is a PostgreSQL version to be installed like 16.0.
1010
# postgis_version is a PostGIS version to be installed.
1111
#
1212
# Requirements
13-
# - be able to connect to the PostgreSQL official web site by curl.
13+
# - be able to connect to the PostGIS official web site by wget.
1414
#
1515
################################################################################
1616

GitHubActions/build_postgres.sh

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
#
1515
################################################################################
1616

17-
VERSION=$1
17+
POSTGRESQL_VERSION=$1
1818
CONFIGURE_OPTIONS=""
1919

2020
while (( "$#" )); do
@@ -24,9 +24,9 @@ done
2424

2525
mkdir -p ./workdir
2626
cd ./workdir
27-
curl -O https://ftp.postgresql.org/pub/source/v${VERSION}/postgresql-${VERSION}.tar.bz2
28-
tar xjf postgresql-${VERSION}.tar.bz2
29-
cd postgresql-${VERSION}
27+
curl -O https://ftp.postgresql.org/pub/source/v${POSTGRESQL_VERSION}/postgresql-${POSTGRESQL_VERSION}.tar.bz2
28+
tar xjf postgresql-${POSTGRESQL_VERSION}.tar.bz2
29+
cd postgresql-${POSTGRESQL_VERSION}
3030

3131
if [ -z "$CONFIGURE_OPTIONS" ]; then
3232
./configure

GitHubActions/build_sqlite_fdw.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
# - SQLite development package is installed in a system.
1515
################################################################################
1616

17-
VERSION=$1
17+
VERSION="$1"
1818
MODE="$2"
1919

2020
mkdir -p ./workdir/postgresql-${VERSION}/contrib/sqlite_fdw

GitHubActions/execute_test.sh

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ MODE="$2"
2626
cd ./workdir/postgresql-${VERSION}/contrib/sqlite_fdw
2727

2828
if [ "$MODE" == "postgis" ]; then
29-
MAKEFILE_OPT="ENABLE_GIS=1"
30-
echo "$MODE mode, makefile option = $MAKEFILE_OPT"
29+
export ENABLE_GIS=1
3130

3231
# Start postgres server
3332
POSTGRES_HOME=/usr/local/pgsql

GitHubActions/install_sqlite.sh

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,28 @@
55
# This sript downloads SQLite source code from the official web site into
66
# ./workdir then builds and installs it.
77
#
8-
# Usage: ./install_sqlite.sh version year [configure_options]
9-
# version: SQLite version to be installed
8+
# Usage: ./install_sqlite.sh version year testing_mode [configure_options]
9+
# version: SQLite version to be installed.
1010
# year: A year of SQLite released. It is used for determining a download URL.
11-
# configure_options are a list of option for sqlite server.
11+
# testing_mode: 'default' or 'postgis' value.
12+
# configure_options: are a list of option for sqlite server.
1213
#
13-
# Ex) ./install_sqlite.sh 3420000 2023 --enable-rtree
14+
# Ex) ./install_sqlite.sh 3420000 2023 postgis --enable-rtree
1415
#
1516
# Requirements
1617
# - be able to connect to the SQLite official web site by curl.
1718
# - having superuser privileges
1819
#
1920
################################################################################
2021

21-
VERSION=$1
22-
YEAR=$2
22+
VERSION="$1"
23+
YEAR="$2"
24+
TESTING_MODE="$3"
2325

2426
CONFIGURE_OPTIONS=""
2527

2628
while (( "$#" )); do
27-
CONFIGURE_OPTIONS="$CONFIGURE_OPTIONS $3"
29+
CONFIGURE_OPTIONS="$CONFIGURE_OPTIONS $4"
2830
shift
2931
done
3032

@@ -42,3 +44,7 @@ fi
4244

4345
make
4446
sudo make install
47+
48+
if [ "$TESTING_MODE" == "postgis" ]; then
49+
sudo apt-get install libspatialite-dev -y
50+
fi

Makefile

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,20 @@
1010
##########################################################################
1111

1212
MODULE_big = sqlite_fdw
13-
OBJS = connection.o option.o deparse.o sqlite_query.o sqlite_fdw.o sqlite_data_norm.o
13+
OBJS = connection.o option.o deparse.o sqlite_query.o sqlite_fdw.o sqlite_data_norm.o sqlite_gis.o
1414

1515
EXTENSION = sqlite_fdw
1616
DATA = sqlite_fdw--1.0.sql sqlite_fdw--1.0--1.1.sql
1717

18+
ifdef ENABLE_GIS
19+
override PG_CFLAGS += -DSQLITE_FDW_GIS_ENABLE
20+
GISTEST=postgis
21+
else
22+
GISTEST=nogis
23+
endif
24+
1825
ifndef REGRESS
19-
REGRESS = extra/sqlite_fdw_post types/bitstring types/bool types/float4 types/float8 types/int4 types/int8 types/numeric types/macaddr types/macaddr8 types/out_of_range types/timestamp types/uuid extra/join extra/limit extra/aggregates extra/prepare extra/select_having extra/select extra/insert extra/update extra/encodings sqlite_fdw type aggregate selectfunc extra/returning
26+
REGRESS = extra/sqlite_fdw_post types/bitstring types/bool types/float4 types/float8 types/int4 types/int8 types/numeric types/$(GISTEST) types/macaddr types/macaddr8 types/out_of_range types/timestamp types/uuid extra/join extra/limit extra/aggregates extra/prepare extra/select_having extra/select extra/insert extra/update extra/encodings sqlite_fdw type_$(GISTEST) aggregate selectfunc extra/returning
2027
endif
2128

2229
REGRESS_OPTS = --encoding=utf8
@@ -33,6 +40,10 @@ endif
3340

3441
SHLIB_LINK := -lsqlite3
3542

43+
ifdef ENABLE_GIS
44+
override SHLIB_LINK += -lspatialite
45+
endif
46+
3647
ifdef USE_PGXS
3748
PG_CONFIG = pg_config
3849
PGXS := $(shell $(PG_CONFIG) --pgxs)
@@ -43,7 +54,6 @@ endif
4354
ifeq (,$(findstring $(MAJORVERSION), 13 14 15 16 17))
4455
$(error PostgreSQL 13, 14, 15, 16 or 17 is required to compile this extension)
4556
endif
46-
4757
else
4858
subdir = contrib/sqlite_fdw
4959
top_builddir = ../..
@@ -60,3 +70,9 @@ endif
6070
REGRESS := $(addprefix $(REGRESS_PREFIX_SUB)/,$(REGRESS))
6171
$(shell mkdir -p results/$(REGRESS_PREFIX_SUB)/extra)
6272
$(shell mkdir -p results/$(REGRESS_PREFIX_SUB)/types)
73+
74+
ifdef ENABLE_GIS
75+
check: temp-install
76+
temp-install: EXTRA_INSTALL+=contrib/postgis
77+
checkprep: EXTRA_INSTALL+=contrib/postgis
78+
endif

0 commit comments

Comments
 (0)