summaryrefslogtreecommitdiffstats
path: root/contrib/seg
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 12:19:15 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 12:19:15 +0000
commit6eb9c5a5657d1fe77b55cc261450f3538d35a94d (patch)
tree657d8194422a5daccecfd42d654b8a245ef7b4c8 /contrib/seg
parentInitial commit. (diff)
downloadpostgresql-13-6eb9c5a5657d1fe77b55cc261450f3538d35a94d.tar.xz
postgresql-13-6eb9c5a5657d1fe77b55cc261450f3538d35a94d.zip
Adding upstream version 13.4.upstream/13.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'contrib/seg')
-rw-r--r--contrib/seg/.gitignore6
-rw-r--r--contrib/seg/Makefile38
-rw-r--r--contrib/seg/data/test_seg.data2578
-rw-r--r--contrib/seg/expected/seg.out1268
-rw-r--r--contrib/seg/seg--1.0--1.1.sql63
-rw-r--r--contrib/seg/seg--1.1--1.2.sql14
-rw-r--r--contrib/seg/seg--1.1.sql395
-rw-r--r--contrib/seg/seg--1.2--1.3.sql58
-rwxr-xr-xcontrib/seg/seg-validate.pl54
-rw-r--r--contrib/seg/seg.c1090
-rw-r--r--contrib/seg/seg.control6
-rw-r--r--contrib/seg/segdata.h24
-rw-r--r--contrib/seg/segparse.c1610
-rw-r--r--contrib/seg/segparse.y163
-rw-r--r--contrib/seg/segscan.c2095
-rw-r--r--contrib/seg/segscan.l115
-rwxr-xr-xcontrib/seg/sort-segments.pl28
-rw-r--r--contrib/seg/sql/seg.sql237
18 files changed, 9842 insertions, 0 deletions
diff --git a/contrib/seg/.gitignore b/contrib/seg/.gitignore
new file mode 100644
index 0000000..69e73d2
--- /dev/null
+++ b/contrib/seg/.gitignore
@@ -0,0 +1,6 @@
+/segparse.c
+/segscan.c
+# Generated subdirectories
+/log/
+/results/
+/tmp_check/
diff --git a/contrib/seg/Makefile b/contrib/seg/Makefile
new file mode 100644
index 0000000..f3578a8
--- /dev/null
+++ b/contrib/seg/Makefile
@@ -0,0 +1,38 @@
+# contrib/seg/Makefile
+
+MODULE_big = seg
+OBJS = \
+ $(WIN32RES) \
+ seg.o \
+ segparse.o
+
+EXTENSION = seg
+DATA = seg--1.1.sql seg--1.1--1.2.sql seg--1.2--1.3.sql \
+ seg--1.0--1.1.sql
+PGFILEDESC = "seg - line segment data type"
+
+HEADERS = segdata.h
+
+REGRESS = seg
+
+EXTRA_CLEAN = y.tab.c y.tab.h
+
+ifdef USE_PGXS
+PG_CONFIG = pg_config
+PGXS := $(shell $(PG_CONFIG) --pgxs)
+include $(PGXS)
+else
+subdir = contrib/seg
+top_builddir = ../..
+include $(top_builddir)/src/Makefile.global
+include $(top_srcdir)/contrib/contrib-global.mk
+endif
+
+
+# segscan is compiled as part of segparse
+segparse.o: segscan.c
+
+distprep: segparse.c segscan.c
+
+maintainer-clean:
+ rm -f segparse.c segscan.c
diff --git a/contrib/seg/data/test_seg.data b/contrib/seg/data/test_seg.data
new file mode 100644
index 0000000..6965806
--- /dev/null
+++ b/contrib/seg/data/test_seg.data
@@ -0,0 +1,2578 @@
+...10.3
+...10.5
+...3.5
+...3.9
+...4.9
+...40
+...5.6
+...5.8
+...6.0
+...6.6
+...6.7
+...6.75
+...7.0
+...7.2
+...7.3
+...7.5
+...7.6
+...7.8
+...8.0
+...8.5
+...8.6
+...8.8
+...8.9
+...9.0
+...9.2
+...9.3
+...9.5
+...9.6
+...90
+...<3.0
+...<5.8
+...<7
+...<7.0
+...<8.0
+...<8.2
+...<8.9
+...>10
+...>7.2
+...>7.7
+...>8.0
+...>82
+...>9.0
+< 1.0...3.8
+< 1.5...4.1
+< 1.5...4.15
+< 10...>11.6
+< 2...>4
+< 2.0...3.4
+< 2.0...4.2
+< 2.0...>8.0
+< 2.5...4.7
+< 2.5...5.5
+< 2.5...>8.5
+< 3...>5
+< 3.0...
+< 3.0...4.5
+< 3.0...6.0
+< 3.0...6.5
+< 3.0...9.0
+< 3.0...>10
+< 3.0...>11.0
+< 3.0...>8.0
+< 3.0...>9.0
+< 3.0...>9.5
+< 3.5
+< 3.5...4.3
+< 3.5...5.3
+< 3.5...5.6
+< 3.5...6.0
+< 3.5...8.4
+< 3.6...>6.5
+< 3.7...5.4
+< 4...9.5
+< 4...>5
+< 4...>6.0
+< 4.0...
+< 4.0...10.5
+< 4.0...5.3
+< 4.0...5.75
+< 4.0...6.0
+< 4.0...7.3
+< 4.0...7.5
+< 4.0...7.7
+< 4.0...8.5
+< 4.0...>12
+< 4.0...>5.0
+< 4.0...>6.0
+< 4.0...>7.5
+< 4.0...>8.0
+< 4.0...>8.1
+< 4.0...>9.0
+< 4.2...5.2
+< 4.2...5.3
+< 4.2...5.4
+< 4.2...6.2
+< 4.3...>9.0
+< 4.4
+< 4.4...6.0
+< 4.4...<6.0
+< 4.5...6.3
+< 4.5...7.2
+< 4.5...>12
+< 4.5...>5.0
+< 4.5...>5.5
+< 4.5...>6
+< 4.5...>7.5
+< 4.5...>8
+< 4.5...>9.5
+< 4.7...>9.3
+< 4.8...>6.4
+< 5...7.5
+< 5...7.7
+< 5...>7
+< 5...>8
+< 5...>8.0
+< 5.0
+< 5.0...10
+< 5.0...6.3
+< 5.0...7.4
+< 5.0...7.7
+< 5.0...8.1
+< 5.0...8.3
+< 5.0...8.5
+< 5.0...8.8
+< 5.0...9.5
+< 5.0...<9.0
+< 5.0...>10
+< 5.0...>10.0
+< 5.0...>10.5
+< 5.0...>11
+< 5.0...>6.0
+< 5.0...>6.6
+< 5.0...>7.5
+< 5.0...>8.0
+< 5.0...>8.5
+< 5.0...>8.6
+< 5.0...>9.0
+< 5.2...7.3
+< 5.2...8.2
+< 5.2...8.5
+< 5.2...>5.8
+< 5.2...>7.6
+< 5.3
+< 5.3...6.5
+< 5.3...7.5
+< 5.3...7.8
+< 5.4...6.35
+< 5.5...10
+< 5.5...6.3
+< 5.5...7.0
+< 5.5...7.5
+< 5.5...8.4
+< 5.5...8.5
+< 5.5...>10
+< 5.5...>10.0
+< 5.5...>10.5
+< 5.5...>6.5
+< 5.5...>7
+< 5.5...>7.5
+< 5.5...>8
+< 5.5...>8.0
+< 5.5...>8.5
+< 5.5...>8.7
+< 5.5...>8.9
+< 5.5...>9.0
+< 5.6...6.75
+< 5.75...>9.0
+< 5.8...7.8
+< 5.8...>11
+< 5.8...>8.2
+< 5.9...>8.0
+< 6...>10.5
+< 6...>8
+< 6...>9.5
+< 6.0
+< 6.0...6.8
+< 6.0...7.15
+< 6.0...7.6
+< 6.0...7.7
+< 6.0...8.0
+< 6.0...8.2
+< 6.0...8.5
+< 6.0...9.0
+< 6.0...9.5
+< 6.0...>10
+< 6.0...>10.0
+< 6.0...>11
+< 6.0...>7.0
+< 6.0...>8.0
+< 6.0...>8.2
+< 6.0...>8.5
+< 6.0...>8.6
+< 6.0...>9.0
+< 6.0...>9.6
+< 6.3...9.5
+< 6.3...>6.7
+< 6.3...>7.8
+< 6.35...>7.7
+< 6.4...>8.0
+< 6.4...>8.7
+< 6.5...11
+< 6.5...7.25
+< 6.5...8.0
+< 6.5...8.2
+< 6.5...8.4
+< 6.5...8.5
+< 6.5...9.7
+< 6.5...>10.0
+< 6.5...>10.5
+< 6.5...>7.5
+< 6.5...>8.0
+< 6.5...>8.5
+< 6.5...>8.6
+< 6.5...>8.7
+< 6.5...>9.0
+< 6.5...>9.5
+< 6.6...>7.5
+< 6.6...>8.5
+< 6.8...7.8
+< 6.8...9.5
+< 6.8...>7.5
+< 6.8...>8.6
+< 6.8...>9.0
+< 6.9...9.0
+< 7...9.2
+< 7...>11
+< 7...>7.5
+< 7...>9.5
+< 7.0
+< 7.0...10
+< 7.0...10.5
+< 7.0...11.0
+< 7.0...8.2
+< 7.0...8.3
+< 7.0...8.4
+< 7.0...8.55
+< 7.0...8.7
+< 7.0...8.8
+< 7.0...9.0
+< 7.0...<8.0
+< 7.0...>10.5
+< 7.0...>11
+< 7.0...>11.0
+< 7.0...>7.0
+< 7.0...>7.3
+< 7.0...>7.4
+< 7.0...>7.5
+< 7.0...>7.75
+< 7.0...>7.8
+< 7.0...>8.0
+< 7.0...>8.2
+< 7.0...>8.5
+< 7.0...>8.6
+< 7.0...>8.9
+< 7.0...>9.0
+< 7.0...>9.5
+< 7.2...8.3
+< 7.2...>7.5
+< 7.2...>7.8
+< 7.2...>8.0
+< 7.2...>8.2
+< 7.2...>8.6
+< 7.2...>8.8
+< 7.4...>7.8
+< 7.4...>8.0
+< 7.4...>8.1
+< 7.4...>8.6
+< 7.4...>8.8
+< 7.5...9.0
+< 7.5...>10
+< 7.5...>8.0
+< 7.5...>8.5
+< 7.5...>8.7
+< 7.5...>9
+< 7.5...>9.0
+< 7.5...>9.5
+< 7.6...>7.8
+< 7.6...>8.0
+< 7.6...>8.5
+< 7.6...>8.6
+< 7.6...>8.9
+< 7.8...>9.0
+< 7.9...>8.3
+< 8.0
+< 8.0...>10.0
+< 8.0...>8.5
+< 8.0...>9.0
+< 8.0...>9.4
+< 8.0...>9.5
+< 8.2...9.8
+< 8.2...>8.6
+< 8.5...>10.5
+< 8.5...>11
+< 8.5...>9.5
+< 9...10.5
+<1.0...3.5
+<1.0...3.7
+<1.0...4.0
+<1.0...>13.0
+<1.0...>5.5
+<10.5...11.5
+<12.0...12.5
+<2...10
+<2...>4
+<2.0
+<2.0...11
+<2.0...3.5
+<2.0...5.7
+<2.0...6.0
+<2.0...6.8
+<2.0...9.7
+<2.0...>6.5
+<2.0...>9.0
+<2.3...
+<2.3...>11.0
+<2.4...6.8
+<2.5...7.7
+<2.5...>8.0
+<2.8...>8.0
+<3.0...4.6
+<3.0...5.5
+<3.0...6.0
+<3.0...6.3
+<3.0...6.4
+<3.0...6.8
+<3.0...7.0
+<3.0...7.5
+<3.0...8.3
+<3.0...>10.5
+<3.0...>5.0
+<3.0...>7.0
+<3.0...>7.2
+<3.0...>8.5
+<3.0...>8.7
+<3.0...>9.0
+<3.5...6.0
+<3.5...8.0
+<3.5...<7.0
+<3.5...>10.0
+<3.55...5.3
+<3.7...4.9
+<3.7...5.0
+<4...6.5
+<4.0...10.0
+<4.0...10.5
+<4.0...6.1
+<4.0...6.3
+<4.0...6.5
+<4.0...7.7
+<4.0...8.2
+<4.0...<9.0
+<4.0...>10
+<4.0...>10.0
+<4.0...>10.5
+<4.0...>6.0
+<4.0...>8.0
+<4.0...>9.0
+<4.1...>8.0
+<4.3...7.6
+<4.5...6.3
+<4.5...6.5
+<4.5...>6.5
+<4.5...>9.5
+<4.8...>7.4
+<4.9...>9.5
+<5...>6
+<5...>6.0
+<5...>8
+<5.0...10.0
+<5.0...6.0
+<5.0...6.6
+<5.0...6.8
+<5.0...7.0
+<5.0...7.5
+<5.0...8.2
+<5.0...9.5
+<5.0...>11.0
+<5.0...>5.5
+<5.0...>7.0
+<5.0...>8.0
+<5.0...>9.0
+<5.2...7.5
+<5.2...>6.8
+<5.2...>8.0
+<5.3...10.2
+<5.3...>10.5
+<5.4...8.0
+<5.4...8.5
+<5.4...>8.2
+<5.4...>9.1
+<5.5...6.5
+<5.5...7.0
+<5.5...7.5
+<5.5...8.2
+<5.5...8.3
+<5.5...8.5
+<5.5...8.6
+<5.5...>10.0
+<5.5...>7.0
+<5.5...>7.5
+<5.5...>8.0
+<5.5...>8.5
+<5.5...>9.0
+<5.6...7.5
+<5.6...>6.4
+<5.6...>7.4
+<5.6...>8.0
+<5.6...>8.5
+<5.7...>7.1
+<5.8...7.4
+<5.8...>6.7
+<5.8...>6.8
+<5.8...>7.0
+<5.8...>7.8
+<5.8...>8.8
+<5.85...>9.5
+<6...>9
+<6.0...10.0
+<6.0...6.8
+<6.0...7.1
+<6.0...7.2
+<6.0...7.7
+<6.0...8.0
+<6.0...8.2
+<6.0...8.4
+<6.0...8.5
+<6.0...8.6
+<6.0...9.1
+<6.0...9.2
+<6.0...9.3
+<6.0...9.5
+<6.0...>10
+<6.0...>11.0
+<6.0...>7.0
+<6.0...>7.5
+<6.0...>7.6
+<6.0...>7.9
+<6.0...>8.0
+<6.0...>8.3
+<6.0...>8.5
+<6.0...>8.6
+<6.0...>9.0
+<6.0...>9.2
+<6.0...>9.5
+<6.1...8.4
+<6.1...>6.6
+<6.1...>8.1
+<6.2
+<6.2...6.9
+<6.2...8.3
+<6.2...>7.5
+<6.2...>8.5
+<6.2...>8.7
+<6.3...10.0
+<6.3...7.4
+<6.3...9.6
+<6.3...>7.0
+<6.3...>8.0
+<6.4...7.6
+<6.4...8.5
+<6.4...>8.5
+<6.4...>9.0
+<6.5...7.8
+<6.5...8.2
+<6.5...9.2
+<6.5...>7.0
+<6.5...>7.5
+<6.5...>8.0
+<6.5...>8.5
+<6.5...>8.7
+<6.5...>9.0
+<6.5...>9.5
+<6.6
+<6.6...8.0
+<6.8...8.0
+<6.8...8.2
+<6.8...>7.5
+<6.8...>8.5
+<6.8...>9.5
+<7...9
+<7...>10
+<7.0...7.5
+<7.0...9.0
+<7.0...9.0
+<7.0...9.4
+<7.0...9.5
+<7.0...9.5
+<7.0...>10
+<7.0...>10.0
+<7.0...>11.5
+<7.0...>7.5
+<7.0...>8.0
+<7.0...>8.3
+<7.0...>8.4
+<7.0...>8.5
+<7.0...>9.0
+<7.2...8.8
+<7.2...9.0
+<7.2...>8.2
+<7.2...>8.8
+<7.2...>9.5
+<7.3...>8.0
+<7.4...8.8
+<7.4...9.6
+<7.4...>8.5
+<7.4...>8.7
+<7.5...8.5
+<7.5...<9.0
+<7.5...>8.0
+<7.5...>8.5
+<7.5...>9.5
+<7.6...>8.4
+<7.6...>9.4
+<7.8...>10.2
+<7.8...>8.2
+<8.0
+<8.0...10.0
+<8.0...>8.5
+<8.0...>8.8
+<8.0...>9.0
+<8.2...>10.2
+<8.5...9.6
+<8.5...>9.0
+<8.5...>9.5
+<8.6...>10.6
+<9.1...10.3
+<9.2...>11.0
+<9.5...12
+<9.5...>12.2
+> 11.0
+> 3.0...<7.0
+> 4.0...<10.0
+> 4.0...<9.0
+> 4.5...<9.0
+> 5.0
+> 5.0...<10.0
+> 5.0...<11
+> 5.5...
+> 5.6
+> 5.9...<9.5
+> 6.0...8.0
+> 6.0...<11.5
+> 6.0...<8.0
+> 6.0...>10.0
+> 6.2...<7.4
+> 7.0...<10
+> 7.0...>8.5
+> 7.0...>8.6
+> 7.0...>8.7
+> 7.15...
+> 8.0
+> 8.7
+> 9.3
+> 9.5
+>10.5
+>120
+>2.3...
+>3.0...<7.0
+>3.8...<8.0
+>4.0...<10
+>5.0...<7.0
+>5.0...>8.0
+>5.0...>9.2
+>5.25...6.5
+>5.5...>9.3
+>5.6...<8.2
+>6.0...>11.0
+>6.5...>8.0
+>6.6...<7.3
+>6.8...>8.5
+>6.9...>8.0
+>7.0
+>7.0...<9.0
+>7.0...<9.5
+>7.3...
+>7.5...<10.5
+>8.0
+>8.4
+>8.5
+>9.0
+>9.4
+>9.5
+>95
+~10
+~23
+~5.0...>9.0
+~6.0
+~6.4...~8.5
+~6.8
+~7.0
+~7.5
+~8.0
+~8.0...~10.0
+1.0
+1.0...4.0
+1.0...5.0
+1.1
+1.1...3.6
+1.2...3.2
+1.2...3.5
+1.3...12.0
+1.4...2.0
+1.4...8.2
+1.5
+1.5...10.5
+1.5...4.2
+1.5...4.5
+1.6...3.8
+1.6...7.2
+1.7
+1.7...2.4
+1.7...3.2
+1.7...5.0
+1.7...5.7
+1.8
+1.8...3.8
+1.8...>9.0
+1.9...3.6
+2
+2.0
+2.0...10.0
+2.0...11.0
+2.0...11.5
+2.0...2.5
+2.0...3.2
+2.0...3.5
+2.0...4.0
+2.0...4.3
+2.0...4.4
+2.0...4.6
+2.0...4.75
+2.0...4.8
+2.0...5.0
+2.0...5.5
+2.0...6.5
+2.0...7.0
+2.0...7.5
+2.0...8.0
+2.0...9.0
+2.0...>10
+2.0...>4.0
+2.0...>5.5
+2.1
+2.1...11.8
+2.1...4.2
+2.2
+2.2...11.2
+2.2...4.1
+2.2...4.2
+2.2...5.9
+2.2...6.4
+2.2...6.8
+2.3...10.6
+2.3...4.1
+2.3...4.3
+2.3...4.5
+2.3...4.7
+2.3...6.0
+2.4
+2.4...11.3
+2.4...4.5
+2.4...5.6
+2.4...5.7
+2.4...6.3
+2.5
+2.5...11
+2.5...11.2
+2.5...11.5
+2.5...11.8
+2.5...3.0
+2.5...3.7
+2.5...4.1
+2.5...4.5
+2.5...4.6
+2.5...5.0
+2.5...5.1
+2.5...5.5
+2.5...6.0
+2.5...6.3
+2.5...7.0
+2.5...9.0
+2.5...>3.5
+2.5...>4.0
+2.52
+2.56
+2.6...
+2.6...10.0
+2.6...9.3
+2.6...>4.0
+2.6...>9.4
+2.62
+2.7
+2.7...12.0
+2.7...3.7
+2.7...3.8
+2.7...4.5
+2.7...4.7
+2.7...6.0
+2.7...6.4
+2.7...7.0
+2.7...8.0
+2.75...5.25
+2.79
+2.8
+2.8...11.0
+2.8...3.4
+2.8...4.0
+2.8...7.0
+2.8...8.0
+2.8...9.0
+2.8...9.7
+2.9...3.7
+2.9...4.5
+2.9...5.0
+2.9...5.6
+2.9...6.1
+2.9...7.6
+2.9...9.0
+2.97
+3
+3...10.0
+3...10.5
+3...5.5
+3...58
+3...6
+3...8
+3.0
+3.0...10
+3.0...10.0
+3.0...10.5
+3.0...11.0
+3.0...3.5
+3.0...4.0
+3.0...4.5
+3.0...4.9
+3.0...5.0
+3.0...5.4
+3.0...5.6
+3.0...5.65
+3.0...6.0
+3.0...6.3
+3.0...6.5
+3.0...6.7
+3.0...6.9
+3.0...7.0
+3.0...7.2
+3.0...7.5
+3.0...8.0
+3.0...8.5
+3.0...8.7
+3.0...9.0
+3.0...9.7
+3.0...>10
+3.0...>10.0
+3.0...>8.0
+3.00...5.0
+3.1
+3.1...11.5
+3.1...5.2
+3.1...5.8
+3.1...6.8
+3.1...7.8
+3.15...7.25
+3.2
+3.2...10.0
+3.2...4.2
+3.2...4.6
+3.2...5.4
+3.2...5.8
+3.2...6.25
+3.2...6.8
+3.2...8.1
+3.2...>8.0
+3.2...>9.9
+3.22
+3.3
+3.3...4.7
+3.3...5.3
+3.3...5.5
+3.3...5.6
+3.3...6.0
+3.3...6.5
+3.3...6.7
+3.3...7.2
+3.3...7.4
+3.3...7.5
+3.3...7.8
+3.3...9.0
+3.4
+3.4...4.1
+3.4...4.7
+3.4...5.5
+3.4...6.2
+3.4...6.4
+3.4...8.2
+3.4...>8.0
+3.5
+3.5...10
+3.5...10.0
+3.5...10.5
+3.5...10.8
+3.5...11.0
+3.5...11.5
+3.5...12.2
+3.5...4.0
+3.5...4.4
+3.5...4.5
+3.5...5.0
+3.5...5.3
+3.5...5.5
+3.5...5.6
+3.5...6
+3.5...6.0
+3.5...6.3
+3.5...6.4
+3.5...6.5
+3.5...6.6
+3.5...6.7
+3.5...7.0
+3.5...7.2
+3.5...7.3
+3.5...7.5
+3.5...8.5
+3.5...8.6
+3.5...8.7
+3.5...9.0
+3.5...9.5
+3.5...>11.0
+3.5...>5.0
+3.5...>8.5
+3.5...>9.0
+3.6
+3.6...3.8
+3.6...4.55
+3.6...4.6
+3.6...4.8
+3.6...5.4
+3.6...5.5
+3.6...6
+3.6...6.0
+3.6...6.6
+3.6...6.8
+3.6...7.0
+3.6...7.7
+3.6...8.6
+3.6...8.7
+3.6...8.8
+3.7
+3.7...10.0
+3.7...10.6
+3.7...4.6
+3.7...5.3
+3.7...6.2
+3.7...6.3
+3.7...6.5
+3.7...6.7
+3.7...8.2
+3.7...8.3
+3.7...9.1
+3.7...>10
+3.7...>11
+3.75...5.7
+3.8
+3.8...10
+3.8...4.0
+3.8...4.5
+3.8...4.8
+3.8...5.5
+3.8...5.8
+3.8...5.9
+3.8...6.2
+3.8...7.7
+3.8...8.3
+3.8...8.7
+3.9
+3.9...5.5
+3.9...6.8
+3.9...7.8
+3.9...>7.5
+3.9...>8.5
+3.9...>9.0
+3.95
+4
+4...10
+4...11.0
+4...12
+4...5
+4...6.9
+4...7
+4...7.5
+4...8
+4...9
+4...>11
+4...>8
+4.0
+4.0...
+4.0...10
+4.0...10.0
+4.0...10.4
+4.0...10.5
+4.0...11.0
+4.0...11.7
+4.0...12.5
+4.0...13.0
+4.0...4.4
+4.0...4.5
+4.0...4.8
+4.0...5.0
+4.0...5.1
+4.0...5.2
+4.0...5.5
+4.0...5.7
+4.0...5.75
+4.0...5.8
+4.0...6.0
+4.0...6.1
+4.0...6.2
+4.0...6.3
+4.0...6.5
+4.0...60
+4.0...7.0
+4.0...7.2
+4.0...7.3
+4.0...7.5
+4.0...7.7
+4.0...7.9
+4.0...8.0
+4.0...8.1
+4.0...8.2
+4.0...8.3
+4.0...8.5
+4.0...8.8
+4.0...9.0
+4.0...9.4
+4.0...>10
+4.0...>11
+4.0...>9.0
+4.1
+4.1...10.5
+4.1...5.6
+4.1...5.8
+4.1...6.0
+4.1...7.2
+4.1...8.0
+4.1...9.1
+4.15...5.25
+4.15...6.25
+4.15...6.5
+4.2
+4.2...11.0
+4.2...11.5
+4.2...11.7
+4.2...5.0
+4.2...5.3
+4.2...5.35
+4.2...5.4
+4.2...5.6
+4.2...5.7
+4.2...6.0
+4.2...6.3
+4.2...6.4
+4.2...6.7
+4.2...7.1
+4.2...7.2
+4.2...7.3
+4.2...8.0
+4.2...8.4
+4.2...9.5
+4.2...>7.0
+4.2...>7.3
+4.2...>9.0
+4.2...>9.5
+4.25
+4.25...5.00
+4.25...9.75
+4.3
+4.3...10.3
+4.3...5.3
+4.3...5.7
+4.3...5.8
+4.3...6.0
+4.3...6.3
+4.3...6.5
+4.3...6.8
+4.3...7.0
+4.3...7.2
+4.3...7.3
+4.3...7.5
+4.3...7.6
+4.3...8
+4.3...8.2
+4.3...8.5
+4.3...8.6
+4.3...>5.0
+4.3...>6.0
+4.3...>7.0
+4.3...>8.0
+4.35
+4.4
+4.4...10.7
+4.4...4.6
+4.4...4.8
+4.4...6.0
+4.4...6.2
+4.4...6.4
+4.4...6.6
+4.4...6.7
+4.4...7.0
+4.4...7.2
+4.4...7.5
+4.4...7.6
+4.4...8.5
+4.4...9.3
+4.5
+4.5...10
+4.5...10.0
+4.5...10.5
+4.5...11.0
+4.5...11.5
+4.5...115
+4.5...12.5
+4.5...4.8
+4.5...5.0
+4.5...5.2
+4.5...5.5
+4.5...5.7
+4.5...5.8
+4.5...6.0
+4.5...6.2
+4.5...6.4
+4.5...6.5
+4.5...6.8
+4.5...7
+4.5...7.0
+4.5...7.1
+4.5...7.3
+4.5...7.5
+4.5...7.6
+4.5...7.7
+4.5...7.8
+4.5...7.9
+4.5...8.0
+4.5...8.3
+4.5...8.5
+4.5...8.6
+4.5...8.7
+4.5...8.8
+4.5...8.9
+4.5...9.0
+4.5...9.3
+4.5...9.4
+4.5...9.5
+4.5...<12
+4.5...>10
+4.5...>12
+4.5...>6.0
+4.5...>7.0
+4.5...>7.5
+4.5...>8.0
+4.5...>8.5
+4.5...>9.0
+4.6
+4.6
+4.6...4.8
+4.6...5.0
+4.6...5.2
+4.6...6.3
+4.6...6.4
+4.6...6.5
+4.6...6.6
+4.6...7.0
+4.6...7.2
+4.6...7.4
+4.6...7.5
+4.6...8.2
+4.6...8.5
+4.6...8.6
+4.6...8.7
+4.6...<6.5
+4.6...>10
+4.6...>11
+4.6...>7.4
+4.6...>8.0
+4.6...~7.0
+4.7
+4.7...10.8
+4.7...11
+4.7...11.8
+4.7...5.6
+4.7...6.0
+4.7...6.2
+4.7...6.3
+4.7...6.6
+4.7...6.7
+4.7...7.0
+4.7...7.4
+4.7...7.5
+4.7...7.7
+4.7...7.8
+4.7...8.0
+4.7...8.3
+4.7...8.4
+4.7...8.5
+4.7...9.3
+4.7...9.5
+4.7...9.6
+4.7...9.7
+4.7...>10
+4.7...>10.0
+4.7...>10.5
+4.7...>6.5
+4.7...>8.0
+4.75
+4.8
+4.8...
+4.8...10.3
+4.8...11.5
+4.8...11.6
+4.8...12.5
+4.8...5.2
+4.8...5.9
+4.8...6.0
+4.8...6.2
+4.8...6.3
+4.8...7.0
+4.8...7.3
+4.8...7.4
+4.8...7.5
+4.8...7.6
+4.8...7.7
+4.8...7.75
+4.8...8.0
+4.8...8.2
+4.8...8.4
+4.8...8.6
+4.8...9.0
+4.8...9.3
+4.8...9.7
+4.8...>10.0
+4.8...>8.0
+4.8...>9.0
+4.85
+4.9
+4.9...
+4.9...6.5
+4.9...7.2
+4.9...7.8
+4.9...8.2
+4.9...8.3
+4.9...9.0
+4.9...9.5
+4.9...<6.0
+4.9...>12
+4.9...>7.5
+4.9...>9.5
+5
+5...10.0
+5...10.5
+5...11
+5...11.5
+5...12
+5...30
+5...6
+5...6.6
+5...7
+5...8
+5...8.5
+5...9
+5...9.5
+5.0
+5.0...10
+5.0...10.0
+5.0...10.2
+5.0...10.3
+5.0...10.5
+5.0...11
+5.0...11.0
+5.0...11.2
+5.0...11.4
+5.0...11.5
+5.0...11.6
+5.0...11.7
+5.0...12.0
+5.0...5.5
+5.0...5.7
+5.0...6.0
+5.0...6.1
+5.0...6.2
+5.0...6.4
+5.0...6.5
+5.0...6.6
+5.0...6.8
+5.0...6.9
+5.0...7.0
+5.0...7.2
+5.0...7.3
+5.0...7.4
+5.0...7.5
+5.0...7.6
+5.0...7.7
+5.0...7.8
+5.0...8.0
+5.0...8.2
+5.0...8.3
+5.0...8.4
+5.0...8.5
+5.0...8.6
+5.0...8.7
+5.0...9.0
+5.0...9.0
+5.0...9.2
+5.0...9.5
+5.0...>10
+5.0...>10.0
+5.0...>11
+5.0...>12
+5.0...>12.0
+5.0...>7.0
+5.0...>8.0
+5.0...>8.4
+5.0...>8.5
+5.0...>9.0
+5.02...6.74
+5.1
+5.1...5.3
+5.1...5.4
+5.1...6.2
+5.1...6.3
+5.1...6.4
+5.1...6.6
+5.1...6.8
+5.1...7.0
+5.1...7.2
+5.1...7.3
+5.1...7.8
+5.1...8.0
+5.1...8.3
+5.1...8.7
+5.1...>7.0
+5.15
+5.2
+5.2...10.0
+5.2...10.8
+5.2...11.5
+5.2...5.3
+5.2...5.5
+5.2...5.7
+5.2...6.0
+5.2...6.2
+5.2...6.4
+5.2...6.7
+5.2...6.8
+5.2...6.9
+5.2...7.0
+5.2...7.3
+5.2...7.4
+5.2...7.5
+5.2...7.6
+5.2...7.7
+5.2...7.9
+5.2...8.0
+5.2...8.2
+5.2...8.4
+5.2...8.5
+5.2...8.7
+5.2...8.8
+5.2...9.0
+5.2...9.5
+5.2...9.6
+5.2...9.7
+5.2...9.9
+5.2...>10.0
+5.2...>11
+5.2...>12
+5.2...>6.5
+5.2...>7.0
+5.2...>7.5
+5.2...>8
+5.2...>8.0
+5.25...7.5
+5.25...8.5
+5.25...>12
+5.3
+5.3...
+5.3...10.0
+5.3...10.1
+5.3...10.2
+5.3...10.5
+5.3...10.6
+5.3...11.5
+5.3...13
+5.3...5.5
+5.3...5.8
+5.3...7.0
+5.3...7.2
+5.3...7.4
+5.3...7.5
+5.3...7.6
+5.3...7.8
+5.3...8.0
+5.3...8.2
+5.3...8.3
+5.3...8.6
+5.3...8.7
+5.3...8.8
+5.3...8.9
+5.3...9.0
+5.3...9.3
+5.3...9.5
+5.3...9.7
+5.3...9.9
+5.3...>7.8
+5.3...>9.0
+5.3...>90
+5.35
+5.4
+5.4...
+5.4...10
+5.4...10.5
+5.4...5.8
+5.4...6.8
+5.4...7.0
+5.4...7.1
+5.4...7.2
+5.4...7.3
+5.4...7.7
+5.4...7.8
+5.4...8.2
+5.4...8.5
+5.4...9.4
+5.4...>10.0
+5.4...>11.0
+5.4...>9.0
+5.45
+5.5
+5.5...
+5.5...10.0
+5.5...10.2
+5.5...10.5
+5.5...11
+5.5...11.5
+5.5...11.7
+5.5...12
+5.5...12.5
+5.5...13.5
+5.5...5.6
+5.5...5.7
+5.5...5.8
+5.5...6
+5.5...6.0
+5.5...6.2
+5.5...6.3
+5.5...6.5
+5.5...6.7
+5.5...6.8
+5.5...7.0
+5.5...7.1
+5.5...7.2
+5.5...7.3
+5.5...7.4
+5.5...7.5
+5.5...7.6
+5.5...7.7
+5.5...7.9
+5.5...8.0
+5.5...8.1
+5.5...8.2
+5.5...8.5
+5.5...8.6
+5.5...8.7
+5.5...9.0
+5.5...9.1
+5.5...9.3
+5.5...9.5
+5.5...9.7
+5.5...<6.8
+5.5...>10
+5.5...>10.0
+5.5...>11
+5.5...>11.0
+5.5...>12
+5.5...>7.0
+5.5...>8.0
+5.5...>9.0
+5.5...>9.5
+5.55
+5.55...7.8
+5.56
+5.6
+5.6...10
+5.6...10.1
+5.6...6.0
+5.6...6.2
+5.6...6.4
+5.6...6.6
+5.6...7.0
+5.6...7.1
+5.6...7.2
+5.6...7.3
+5.6...7.4
+5.6...7.5
+5.6...7.6
+5.6...7.7
+5.6...8.0
+5.6...8.3
+5.6...8.4
+5.6...8.5
+5.6...8.75
+5.6...8.8
+5.6...9
+5.6...9.0
+5.6...9.4
+5.6...9.5
+5.6...9.6
+5.6...>11
+5.6...>7.0
+5.6...>7.5
+5.6...>8.0
+5.6...>9.0
+5.65
+5.7
+5.7...
+5.7...10
+5.7...10.0
+5.7...11
+5.7...6.0
+5.7...6.2
+5.7...6.3
+5.7...6.5
+5.7...6.8
+5.7...7.0
+5.7...7.2
+5.7...7.3
+5.7...7.5
+5.7...7.6
+5.7...7.65
+5.7...7.7
+5.7...7.8
+5.7...7.9
+5.7...8.0
+5.7...8.4
+5.7...8.5
+5.7...8.7
+5.7...8.9
+5.7...9.0
+5.7...9.2
+5.7...9.4
+5.7...9.7
+5.7...>10.0
+5.7...>11
+5.7...>6.6
+5.7...>7.2
+5.7...>8.5
+5.7...>9.0
+5.73
+5.75
+5.75...7.3
+5.8
+5.8...10.0
+5.8...11
+5.8...6.0
+5.8...6.2
+5.8...6.5
+5.8...6.7
+5.8...6.8
+5.8...6.9
+5.8...7.0
+5.8...7.2
+5.8...7.3
+5.8...7.4
+5.8...7.5
+5.8...7.6
+5.8...7.7
+5.8...7.8
+5.8...8.0
+5.8...8.1
+5.8...8.2
+5.8...8.3
+5.8...8.4
+5.8...8.5
+5.8...8.6
+5.8...8.8
+5.8...9.0
+5.8...9.2
+5.8...9.3
+5.8...9.8
+5.8...>10.5
+5.8...>11
+5.8...>6.7
+5.8...>6.8
+5.8...>8.0
+5.8...>9.0
+5.85
+5.87
+5.9
+5.9...
+5.9...10.2
+5.9...6.0
+5.9...6.5
+5.9...7.3
+5.9...7.5
+5.9...7.7
+5.9...8.0
+5.9...8.2
+5.9...8.3
+5.9...8.4
+5.9...8.5
+5.9...8.7
+5.9...9.0
+5.9...>7.0
+5.9...>8.5
+5.92
+5.95...8.0
+6
+6...10
+6...11
+6...11.5
+6...6.5
+6...8
+6...8.0
+6...8.5
+6...9
+6...9.2
+6...9.3
+6...>10
+6...>12
+6...>7.2
+6...>8
+6.0
+6.0
+6.0...10
+6.0...10.0
+6.0...10.2
+6.0...10.3
+6.0...10.4
+6.0...10.5
+6.0...11
+6.0...11.0
+6.0...11.5
+6.0...13
+6.0...6.2
+6.0...6.3
+6.0...6.4
+6.0...6.5
+6.0...6.6
+6.0...6.7
+6.0...6.8
+6.0...7.0
+6.0...7.2
+6.0...7.3
+6.0...7.4
+6.0...7.5
+6.0...7.6
+6.0...7.7
+6.0...7.8
+6.0...8.0
+6.0...8.1
+6.0...8.2
+6.0...8.3
+6.0...8.4
+6.0...8.5
+6.0...8.5
+6.0...8.6
+6.0...8.7
+6.0...8.9
+6.0...9.0
+6.0...9.1
+6.0...9.2
+6.0...9.3
+6.0...9.4
+6.0...9.5
+6.0...9.7
+6.0...9.8
+6.0...9.9
+6.0...>10.0
+6.0...>10.5
+6.0...>11
+6.0...>7.0
+6.0...>7.5
+6.0...>8.0
+6.0...>8.2
+6.0...>8.5
+6.0...>8.7
+6.0...>9.0
+6.0...>9.5
+6.01
+6.1
+6.1...
+6.1...10
+6.1...10.8
+6.1...6.2
+6.1...6.6
+6.1...6.8
+6.1...6.9
+6.1...7.0
+6.1...7.2
+6.1...7.5
+6.1...7.6
+6.1...7.7
+6.1...7.8
+6.1...7.9
+6.1...8.0
+6.1...8.2
+6.1...8.5
+6.1...8.7
+6.1...8.9
+6.1...9.0
+6.1...9.3
+6.1...9.4
+6.1...>12
+6.1...>8.0
+6.1...>8.2
+6.1...>8.5
+6.1...>9.0
+6.1...>9.5
+6.15
+6.18
+6.2
+6.2...10
+6.2...10.0
+6.2...10.5
+6.2...11
+6.2...6.4
+6.2...6.5
+6.2...6.8
+6.2...6.9
+6.2...7.0
+6.2...7.2
+6.2...7.4
+6.2...7.5
+6.2...7.6
+6.2...7.7
+6.2...7.8
+6.2...8.0
+6.2...8.1
+6.2...8.2
+6.2...8.3
+6.2...8.4
+6.2...8.5
+6.2...8.6
+6.2...8.7
+6.2...8.8
+6.2...9.0
+6.2...9.1
+6.2...9.2
+6.2...9.5
+6.2...9.7
+6.2...9.8
+6.2...>10.5
+6.2...>11.5
+6.2...>7.1
+6.2...>7.8
+6.2...>8.0
+6.2...>9.0
+6.2...>9.5
+6.23...8.07
+6.24
+6.25
+6.25...7.5
+6.25...>9.0
+6.3
+6.3...
+6.3...10.0
+6.3...10.2
+6.3...10.4
+6.3...10.5
+6.3...6.4
+6.3...6.5
+6.3...6.6
+6.3...6.7
+6.3...6.8
+6.3...7.3
+6.3...7.5
+6.3...7.7
+6.3...7.8
+6.3...7.9
+6.3...8.0
+6.3...8.2
+6.3...8.3
+6.3...8.5
+6.3...8.6
+6.3...8.7
+6.3...8.9
+6.3...9.0
+6.3...9.1
+6.3...9.2
+6.3...9.3
+6.3...9.4
+6.3...9.5
+6.3...9.7
+6.3...9.8
+6.3...>10.0
+6.3...>11
+6.3...>7.5
+6.3...>7.8
+6.3...>8.0
+6.3...>8.1
+6.3...>8.3
+6.3...>8.5
+6.3...>9.0
+6.3...>9.2
+6.35
+6.4
+6.4...7.7
+6.4...10
+6.4...10.8
+6.4...6.7
+6.4...6.8
+6.4...7.0
+6.4...7.2
+6.4...7.4
+6.4...7.5
+6.4...7.6
+6.4...7.7
+6.4...7.8
+6.4...8.0
+6.4...8.1
+6.4...8.2
+6.4...8.3
+6.4...8.4
+6.4...8.6
+6.4...8.7
+6.4...8.8
+6.4...9.0
+6.4...9.3
+6.4...>10
+6.4...>11.0
+6.4...>7.8
+6.4...>8.0
+6.4...>8.5
+6.4...>8.6
+6.4...>9.0
+6.4...>9.1
+6.4...>9.2
+6.4...>9.5
+6.42
+6.5
+6.5
+6.5...
+6.5...10
+6.5...10.0
+6.5...10.2
+6.5...10.3
+6.5...10.5
+6.5...11
+6.5...11.0
+6.5...11.5
+6.5...12.0
+6.5...6.7
+6.5...6.75
+6.5...6.8
+6.5...6.9
+6.5...7.0
+6.5...7.1
+6.5...7.3
+6.5...7.4
+6.5...7.5
+6.5...7.6
+6.5...7.7
+6.5...7.8
+6.5...7.9
+6.5...8.0
+6.5...8.1
+6.5...8.2
+6.5...8.25
+6.5...8.3
+6.5...8.4
+6.5...8.5
+6.5...8.6
+6.5...8.7
+6.5...8.8
+6.5...8.9
+6.5...9
+6.5...9.0
+6.5...9.2
+6.5...9.3
+6.5...9.5
+6.5...9.7
+6.5...9.8
+6.5...>10
+6.5...>10.0
+6.5...>11
+6.5...>11.0
+6.5...>12.0
+6.5...>7.0
+6.5...>7.9
+6.5...>8.0
+6.5...>8.3
+6.5...>8.5
+6.5...>8.7
+6.5...>8.8
+6.5...>9.0
+6.5...>9.5
+6.51
+6.55
+6.6
+6.6...
+6.6...7.0
+6.6...7.1
+6.6...7.3
+6.6...7.4
+6.6...7.5
+6.6...7.9
+6.6...8.3
+6.6...8.4
+6.6...8.5
+6.6...8.6
+6.6...8.7
+6.6...8.8
+6.6...8.9
+6.6...9.0
+6.6...9.4
+6.6...9.7
+6.6...9.8
+6.6...>10.0
+6.6...>10.3
+6.6...>11
+6.6...>9.0
+6.6...>9.5
+6.65...8.6
+6.67
+6.7
+6.7...
+6.7...10.2
+6.7...11.5
+6.7...6.8
+6.7...6.9
+6.7...7.0
+6.7...7.3
+6.7...7.4
+6.7...7.5
+6.7...7.6
+6.7...7.8
+6.7...8.0
+6.7...8.1
+6.7...8.2
+6.7...8.3
+6.7...8.5
+6.7...8.6
+6.7...8.7
+6.7...8.8
+6.7...8.9
+6.7...9.0
+6.7...9.1
+6.7...9.2
+6.7...9.5
+6.7...9.7
+6.7...9.8
+6.7...>10
+6.7...>7.0
+6.7...>7.5
+6.7...>8.0
+6.7...>8.5
+6.7...>8.6
+6.7...>9
+6.7...>9.0
+6.7...>9.3
+6.74...8.0
+6.75
+6.75...
+6.75...9.5
+6.75...>9
+6.75...>9.0
+6.75...>9.5
+6.76...8.10
+6.8
+6.8...
+6.8...10
+6.8...10.0
+6.8...10.5
+6.8...6.9
+6.8...7.0
+6.8...7.1
+6.8...7.2
+6.8...7.3
+6.8...7.5
+6.8...7.6
+6.8...7.7
+6.8...7.8
+6.8...7.9
+6.8...8.0
+6.8...8.2
+6.8...8.25
+6.8...8.3
+6.8...8.5
+6.8...8.6
+6.8...8.7
+6.8...8.8
+6.8...8.9
+6.8...9.0
+6.8...9.1
+6.8...9.3
+6.8...9.4
+6.8...9.5
+6.8...9.6
+6.8...9.9
+6.8...>10.0
+6.8...>7.9
+6.8...>8.0
+6.8...>8.1
+6.8...>8.5
+6.8...>9.0
+6.8...>9.1
+6.80...>8.5
+6.81...7.53
+6.85
+6.86
+6.88
+6.9
+6.9...
+6.9...10.4
+6.9...12.2
+6.9...7.0
+6.9...7.1
+6.9...7.3
+6.9...7.6
+6.9...7.9
+6.9...8.0
+6.9...8.2
+6.9...8.4
+6.9...8.5
+6.9...8.6
+6.9...8.7
+6.9...8.8
+6.9...9.0
+6.9...9.1
+6.9...9.2
+6.9...9.5
+6.9...9.7
+6.9...>7.1
+6.9...>8
+6.9...>8.5
+6.9...>9
+6.9...>9.0
+6.9...>9.3
+6.9...>9.5
+6.9...>90
+7
+7...10
+7...10.5
+7...11
+7...7.5
+7...8
+7...8.5
+7...8.8
+7...9
+7...>10
+7...>10.5
+7...>9.5
+7.0
+7.0
+7.0...
+7.0...10
+7.0...10.0
+7.0...10.2
+7.0...10.3
+7.0...10.5
+7.0...10.7
+7.0...11
+7.0...11.0
+7.0...11.5
+7.0...7.2
+7.0...7.2
+7.0...7.3
+7.0...7.4
+7.0...7.5
+7.0...7.6
+7.0...7.8
+7.0...7.9
+7.0...8.0
+7.0...8.1
+7.0...8.2
+7.0...8.3
+7.0...8.4
+7.0...8.5
+7.0...8.6
+7.0...8.67
+7.0...8.7
+7.0...8.8
+7.0...8.9
+7.0...9.0
+7.0...9.1
+7.0...9.2
+7.0...9.3
+7.0...9.4
+7.0...9.5
+7.0...9.7
+7.0...9.75
+7.0...9.8
+7.0...9.9
+7.0...<8.0
+7.0...>10
+7.0...>10.0
+7.0...>10.5
+7.0...>11
+7.0...>11.5
+7.0...>7.8
+7.0...>8.5
+7.0...>8.7
+7.0...>9
+7.0...>9.0
+7.0...>9.5
+7.00
+7.01
+7.03
+7.05
+7.07
+7.1
+7.1...10.1
+7.1...10.3
+7.1...7.9
+7.1...8.1
+7.1...8.2
+7.1...8.3
+7.1...8.4
+7.1...8.6
+7.1...8.7
+7.1...8.9
+7.1...9.0
+7.1...9.2
+7.1...9.3
+7.1...9.4
+7.1...9.8
+7.1...>8.3
+7.1...>8.5
+7.1...>9.0
+7.1...>9.5
+7.10
+7.15
+7.15...8.3
+7.2
+7.2...10.0
+7.2...10.2
+7.2...10.5
+7.2...13.5
+7.2...7.3
+7.2...7.4
+7.2...7.5
+7.2...7.6
+7.2...7.8
+7.2...8.0
+7.2...8.2
+7.2...8.3
+7.2...8.6
+7.2...8.7
+7.2...8.8
+7.2...8.9
+7.2...9.0
+7.2...9.1
+7.2...9.2
+7.2...9.3
+7.2...9.5
+7.2...9.6
+7.2...9.7
+7.2...9.8
+7.2...>10
+7.2...>10.0
+7.2...>11
+7.2...>8.0
+7.2...>8.5
+7.2...>8.7
+7.2...>9.0
+7.2...>9.1
+7.2...>9.2
+7.2...>9.5
+7.24
+7.25
+7.25...7.75
+7.25...8.1
+7.25...8.25
+7.25...8.4
+7.25...8.6
+7.25...8.7
+7.25...9.25
+7.25...>10.0
+7.25...>8.0
+7.25...>8.25
+7.25...>9.0
+7.26
+7.3
+7.3...
+7.3...10.2
+7.3...10.5
+7.3...11
+7.3...7.5
+7.3...7.6
+7.3...7.8
+7.3...7.9
+7.3...8.0
+7.3...8.2
+7.3...8.3
+7.3...8.4
+7.3...8.5
+7.3...8.6
+7.3...8.8
+7.3...8.9
+7.3...9.0
+7.3...9.15
+7.3...9.2
+7.3...9.4
+7.3...9.5
+7.3...9.8
+7.3...9.9
+7.3...>10
+7.3...>10.0
+7.3...>10.5
+7.3...>7.8
+7.3...>8.0
+7.3...>8.3
+7.3...>9.0
+7.3...>9.2
+7.3...>9.3
+7.3...>9.5
+7.3...>9.75
+7.3...>90
+7.32
+7.35
+7.4
+7.4...
+7.4...10
+7.4...10.0
+7.4...12.1
+7.4...7.6
+7.4...7.8
+7.4...8.0
+7.4...8.2
+7.4...8.3
+7.4...8.4
+7.4...8.5
+7.4...8.6
+7.4...8.7
+7.4...8.8
+7.4...9.0
+7.4...9.2
+7.4...9.3
+7.4...9.6
+7.4...9.7
+7.4...9.8
+7.4...>10.0
+7.4...>8
+7.4...>8.5
+7.4...>8.6
+7.4...>8.7
+7.4...>9.0
+7.45
+7.5
+7.5
+7.5...
+7.5...10
+7.5...10.0
+7.5...10.1
+7.5...10.2
+7.5...10.3
+7.5...10.5
+7.5...10.8
+7.5...11
+7.5...11.0
+7.5...11.5
+7.5...12.0
+7.5...7.6
+7.5...7.8
+7.5...8
+7.5...8.0
+7.5...8.1
+7.5...8.2
+7.5...8.4
+7.5...8.5
+7.5...8.6
+7.5...8.7
+7.5...9.0
+7.5...9.1
+7.5...9.2
+7.5...9.3
+7.5...9.4
+7.5...9.5
+7.5...9.6
+7.5...9.7
+7.5...9.8
+7.5...>10
+7.5...>10.0
+7.5...>10.5
+7.5...>11.0
+7.5...>8.3
+7.5...>8.5
+7.5...>8.7
+7.5...>8.75
+7.5...>9
+7.5...>9.0
+7.5...>9.2
+7.5...>9.5
+7.54
+7.55
+7.6
+7.6
+7.6...10.3
+7.6...10.5
+7.6...7.8
+7.6...7.9
+7.6...8.0
+7.6...8.2
+7.6...8.3
+7.6...8.4
+7.6...8.5
+7.6...8.6
+7.6...8.8
+7.6...9.0
+7.6...9.2
+7.6...9.3
+7.6...9.4
+7.6...9.5
+7.6...9.7
+7.6...>10.0
+7.6...>10.3
+7.6...>10.5
+7.6...>11
+7.6...>8.25
+7.6...>8.8
+7.6...>9.0
+7.6...>9.5
+7.65
+7.7...
+7.7...10
+7.7...10.0
+7.7...10.3
+7.7...10.5
+7.7...11.0
+7.7...11.5
+7.7...7.8
+7.7...8.0
+7.7...8.3
+7.7...8.5
+7.7...8.7
+7.7...9.0
+7.7...9.25
+7.7...9.4
+7.7...9.5
+7.7...9.8
+7.7...>10.5
+7.7...>8.5
+7.7...>8.6
+7.7...>9.0
+7.7...>9.5
+7.72...8.7
+7.75
+7.75...
+7.75...8.1
+7.78
+7.8
+7.8...10.2
+7.8...7.9
+7.8...8.0
+7.8...8.1
+7.8...8.2
+7.8...8.4
+7.8...8.5
+7.8...8.7
+7.8...8.8
+7.8...8.9
+7.8...9.0
+7.8...9.2
+7.8...9.3
+7.8...9.4
+7.8...9.6
+7.8...<9.8
+7.8...>10.0
+7.8...>8.8
+7.8...>8.9
+7.8...>9.0
+7.8...>9.1
+7.8...>9.4
+7.80
+7.85
+7.9
+7.9...10.9
+7.9...8.1
+7.9...8.2
+7.9...8.3
+7.9...8.5
+7.9...8.6
+7.9...8.9
+7.9...9.0
+7.9...9.3
+7.96
+8
+8...10
+8...10.2
+8...10.5
+8...11.0
+8...8.5
+8...9
+8...>10
+8...>11
+8.0
+8.0...10
+8.0...10.0
+8.0...10.2
+8.0...10.3
+8.0...10.5
+8.0...10.8
+8.0...11.0
+8.0...11.2
+8.0...11.7
+8.0...12.0
+8.0...8.5
+8.0...8.12
+8.0...8.2
+8.0...8.4
+8.0...8.5
+8.0...8.6
+8.0...8.7
+8.0...8.8
+8.0...8.9
+8.0...9.0
+8.0...9.2
+8.0...9.4
+8.0...9.5
+8.0...9.7
+8.0...>10
+8.0...>10.0
+8.0...>10.5
+8.0...>11
+8.0...>13.0
+8.0...>8.75
+8.0...>9.0
+8.0...>9.2
+8.0...>9.5
+8.1
+8.1...10.5
+8.1...10.9
+8.1...8.2
+8.1...8.3
+8.1...8.4
+8.1...8.6
+8.1...8.7
+8.1...8.75
+8.1...8.9
+8.1...9.1
+8.1...9.9
+8.1...>9.5
+8.13
+8.15
+8.2
+8.2...
+8.2...10.2
+8.2...10.4
+8.2...8.4
+8.2...8.5
+8.2...8.8
+8.2...8.9
+8.2...9.0
+8.2...9.6
+8.2...9.8
+8.2...>10
+8.2...>10.5
+8.2...>11
+8.2...>11.0
+8.2...>8.8
+8.2...>9.3
+8.20
+8.25
+8.25...10.2
+8.27
+8.27...10
+8.28
+8.3
+8.3...
+8.3...10.2
+8.3...10.3
+8.3...10.8
+8.3...8.4
+8.3...8.5
+8.3...8.6
+8.3...8.8
+8.3...9.6
+8.3...9.9
+8.3...>9.5
+8.3...>9.8
+8.35
+8.4
+8.4...10.1
+8.4...8.5
+8.4...8.6
+8.4...8.7
+8.4...8.8
+8.4...8.9
+8.4...9.0
+8.4...9.2
+8.4...9.5
+8.4...<9.8
+8.4...>10.0
+8.4...>10.5
+8.4...>9.8
+8.48
+8.5
+8.5...
+8.5...10.0
+8.5...10.3
+8.5...10.5
+8.5...10.7
+8.5...10.8
+8.5...11
+8.5...11.0
+8.5...12.5
+8.5...8.6
+8.5...8.8
+8.5...9.0
+8.5...9.1
+8.5...9.2
+8.5...9.3
+8.5...9.4
+8.5...9.5
+8.5...9.9
+8.5...>10
+8.5...>11
+8.5...>11.5
+8.5...>9.5
+8.6
+8.6...10.2
+8.6...10.3
+8.6...11
+8.6...8.7
+8.6...8.8
+8.6...8.9
+8.6...9.4
+8.6...>11
+8.6...>99
+8.65
+8.7
+8.7...10.6
+8.7...11.2
+8.7...11.3
+8.7...11.7
+8.7...8.9
+8.7...9.1
+8.7...9.6
+8.7...9.8
+8.75
+8.8
+8.8...10.3
+8.8...10.7
+8.8...9.0
+8.8...9.2
+8.8...9.8
+8.8...>9.8
+8.9
+8.9...10.3
+8.9...10.4
+8.9...10.9
+8.9...11.5
+8.9...9.2
+9
+9.8
+9...10
+9...11
+9...>12
+9.0
+9.0...
+9.0...10
+9.0...10.0
+9.0...10.5
+9.0...10.7
+9.0...11
+9.0...11.0
+9.0...11.1
+9.0...11.2
+9.0...11.3
+9.0...11.5
+9.0...12
+9.0...9.2
+9.0...9.5
+9.0...>10.7
+9.0...>11.0
+9.1
+9.1...10
+9.1...10.1
+9.1...9.5
+9.15
+9.2
+9.2...10
+9.2...10.8
+9.2...12
+9.2...9.3
+9.2...9.4
+9.2...9.5
+9.2...9.6
+9.25
+9.3
+9.4
+9.4...10
+9.4...12.2
+9.4...9.7
+9.5
+9.5...
+9.5...10
+9.5...10.0
+9.5...10.4
+9.5...10.5
+9.5...10.6
+9.5...11.2
+9.5...9.8
+9.5...>10.2
+9.5...>10.5
+9.55
+9.6
+9.6...10
+9.6...10.2
+9.6...11.5
+9.6...>11.2
+9.63
+9.7
+9.7...11
+9.7...11.5
+9.7...9.8
+9.7...>12
+9.75
+9.76
+9.8
+9.8...10.0
+9.8...10.1
+9.8...>12.5
+9.9
+9.99
+10
+10...10.5
+10...11
+10.0
+10.0...10.4
+10.0...10.5
+10.0...11.25
+10.0...11.5
+10.0...12.5
+10.0...>12.5
+10.2
+10.2...11.8
+10.25
+10.3
+10.32
+10.4
+10.45
+10.5
+10.5...11.0
+10.5...11.5
+10.5...<13.5
+10.6
+10.7
+10.7...12.3
+10.70
+10.75
+10.8
+11
+11
+11.0
+11.3
+11.5
+11.5...12.5
+11.75
+12
+12.0
+12.2
+14
+15
+16
+16.7
+17
+18
+19
+19.8
+20
+20.0
+22
+22
+22.9
+23
+23...25
+23.7
+24
+24.0
+\N
diff --git a/contrib/seg/expected/seg.out b/contrib/seg/expected/seg.out
new file mode 100644
index 0000000..e617dd7
--- /dev/null
+++ b/contrib/seg/expected/seg.out
@@ -0,0 +1,1268 @@
+--
+-- Test seg datatype
+--
+CREATE EXTENSION seg;
+-- Check whether any of our opclasses fail amvalidate
+SELECT amname, opcname
+FROM pg_opclass opc LEFT JOIN pg_am am ON am.oid = opcmethod
+WHERE opc.oid >= 16384 AND NOT amvalidate(opc.oid);
+ amname | opcname
+--------+---------
+(0 rows)
+
+--
+-- testing the input and output functions
+--
+-- Any number
+SELECT '1'::seg AS seg;
+ seg
+-----
+ 1
+(1 row)
+
+SELECT '-1'::seg AS seg;
+ seg
+-----
+ -1
+(1 row)
+
+SELECT '1.0'::seg AS seg;
+ seg
+-----
+ 1.0
+(1 row)
+
+SELECT '-1.0'::seg AS seg;
+ seg
+------
+ -1.0
+(1 row)
+
+SELECT '1e7'::seg AS seg;
+ seg
+-------
+ 1e+07
+(1 row)
+
+SELECT '-1e7'::seg AS seg;
+ seg
+--------
+ -1e+07
+(1 row)
+
+SELECT '1.0e7'::seg AS seg;
+ seg
+---------
+ 1.0e+07
+(1 row)
+
+SELECT '-1.0e7'::seg AS seg;
+ seg
+----------
+ -1.0e+07
+(1 row)
+
+SELECT '1e+7'::seg AS seg;
+ seg
+-------
+ 1e+07
+(1 row)
+
+SELECT '-1e+7'::seg AS seg;
+ seg
+--------
+ -1e+07
+(1 row)
+
+SELECT '1.0e+7'::seg AS seg;
+ seg
+---------
+ 1.0e+07
+(1 row)
+
+SELECT '-1.0e+7'::seg AS seg;
+ seg
+----------
+ -1.0e+07
+(1 row)
+
+SELECT '1e-7'::seg AS seg;
+ seg
+-------
+ 1e-07
+(1 row)
+
+SELECT '-1e-7'::seg AS seg;
+ seg
+--------
+ -1e-07
+(1 row)
+
+SELECT '1.0e-7'::seg AS seg;
+ seg
+---------
+ 1.0e-07
+(1 row)
+
+SELECT '-1.0e-7'::seg AS seg;
+ seg
+----------
+ -1.0e-07
+(1 row)
+
+SELECT '2e-6'::seg AS seg;
+ seg
+-------
+ 2e-06
+(1 row)
+
+SELECT '2e-5'::seg AS seg;
+ seg
+-------
+ 2e-05
+(1 row)
+
+SELECT '2e-4'::seg AS seg;
+ seg
+--------
+ 0.0002
+(1 row)
+
+SELECT '2e-3'::seg AS seg;
+ seg
+-------
+ 0.002
+(1 row)
+
+SELECT '2e-2'::seg AS seg;
+ seg
+------
+ 0.02
+(1 row)
+
+SELECT '2e-1'::seg AS seg;
+ seg
+-----
+ 0.2
+(1 row)
+
+SELECT '2e-0'::seg AS seg;
+ seg
+-----
+ 2
+(1 row)
+
+SELECT '2e+0'::seg AS seg;
+ seg
+-----
+ 2
+(1 row)
+
+SELECT '2e+1'::seg AS seg;
+ seg
+-----
+ 2e1
+(1 row)
+
+SELECT '2e+2'::seg AS seg;
+ seg
+-----
+ 2e2
+(1 row)
+
+SELECT '2e+3'::seg AS seg;
+ seg
+-----
+ 2e3
+(1 row)
+
+SELECT '2e+4'::seg AS seg;
+ seg
+-----
+ 2e4
+(1 row)
+
+SELECT '2e+5'::seg AS seg;
+ seg
+-------
+ 2e+05
+(1 row)
+
+SELECT '2e+6'::seg AS seg;
+ seg
+-------
+ 2e+06
+(1 row)
+
+-- Significant digits preserved
+SELECT '1'::seg AS seg;
+ seg
+-----
+ 1
+(1 row)
+
+SELECT '1.0'::seg AS seg;
+ seg
+-----
+ 1.0
+(1 row)
+
+SELECT '1.00'::seg AS seg;
+ seg
+------
+ 1.00
+(1 row)
+
+SELECT '1.000'::seg AS seg;
+ seg
+-------
+ 1.000
+(1 row)
+
+SELECT '1.0000'::seg AS seg;
+ seg
+--------
+ 1.0000
+(1 row)
+
+SELECT '1.00000'::seg AS seg;
+ seg
+---------
+ 1.00000
+(1 row)
+
+SELECT '1.000000'::seg AS seg;
+ seg
+---------
+ 1.00000
+(1 row)
+
+SELECT '0.000000120'::seg AS seg;
+ seg
+----------
+ 1.20e-07
+(1 row)
+
+SELECT '3.400e5'::seg AS seg;
+ seg
+-----------
+ 3.400e+05
+(1 row)
+
+-- Digits truncated
+SELECT '12.34567890123456'::seg AS seg;
+ seg
+---------
+ 12.3457
+(1 row)
+
+-- Numbers with certainty indicators
+SELECT '~6.5'::seg AS seg;
+ seg
+------
+ ~6.5
+(1 row)
+
+SELECT '<6.5'::seg AS seg;
+ seg
+------
+ <6.5
+(1 row)
+
+SELECT '>6.5'::seg AS seg;
+ seg
+------
+ >6.5
+(1 row)
+
+SELECT '~ 6.5'::seg AS seg;
+ seg
+------
+ ~6.5
+(1 row)
+
+SELECT '< 6.5'::seg AS seg;
+ seg
+------
+ <6.5
+(1 row)
+
+SELECT '> 6.5'::seg AS seg;
+ seg
+------
+ >6.5
+(1 row)
+
+-- Open intervals
+SELECT '0..'::seg AS seg;
+ seg
+------
+ 0 ..
+(1 row)
+
+SELECT '0...'::seg AS seg;
+ seg
+------
+ 0 ..
+(1 row)
+
+SELECT '0 ..'::seg AS seg;
+ seg
+------
+ 0 ..
+(1 row)
+
+SELECT '0 ...'::seg AS seg;
+ seg
+------
+ 0 ..
+(1 row)
+
+SELECT '..0'::seg AS seg;
+ seg
+------
+ .. 0
+(1 row)
+
+SELECT '...0'::seg AS seg;
+ seg
+------
+ .. 0
+(1 row)
+
+SELECT '.. 0'::seg AS seg;
+ seg
+------
+ .. 0
+(1 row)
+
+SELECT '... 0'::seg AS seg;
+ seg
+------
+ .. 0
+(1 row)
+
+-- Finite intervals
+SELECT '0 .. 1'::seg AS seg;
+ seg
+--------
+ 0 .. 1
+(1 row)
+
+SELECT '-1 .. 0'::seg AS seg;
+ seg
+---------
+ -1 .. 0
+(1 row)
+
+SELECT '-1 .. 1'::seg AS seg;
+ seg
+---------
+ -1 .. 1
+(1 row)
+
+-- (+/-) intervals
+SELECT '0(+-)1'::seg AS seg;
+ seg
+---------
+ -1 .. 1
+(1 row)
+
+SELECT '0(+-)1.0'::seg AS seg;
+ seg
+-------------
+ -1.0 .. 1.0
+(1 row)
+
+SELECT '1.0(+-)0.005'::seg AS seg;
+ seg
+----------------
+ 0.995 .. 1.005
+(1 row)
+
+SELECT '101(+-)1'::seg AS seg;
+ seg
+------------------
+ 1.00e2 .. 1.02e2
+(1 row)
+
+-- incorrect number of significant digits in 99.0:
+SELECT '100(+-)1'::seg AS seg;
+ seg
+----------------
+ 99.0 .. 1.01e2
+(1 row)
+
+-- invalid input
+SELECT ''::seg AS seg;
+ERROR: bad seg representation
+LINE 1: SELECT ''::seg AS seg;
+ ^
+DETAIL: syntax error at end of input
+SELECT 'ABC'::seg AS seg;
+ERROR: bad seg representation
+LINE 1: SELECT 'ABC'::seg AS seg;
+ ^
+DETAIL: syntax error at or near "A"
+SELECT '1ABC'::seg AS seg;
+ERROR: bad seg representation
+LINE 1: SELECT '1ABC'::seg AS seg;
+ ^
+DETAIL: syntax error at or near "A"
+SELECT '1.'::seg AS seg;
+ERROR: bad seg representation
+LINE 1: SELECT '1.'::seg AS seg;
+ ^
+DETAIL: syntax error at or near "."
+SELECT '1.....'::seg AS seg;
+ERROR: bad seg representation
+LINE 1: SELECT '1.....'::seg AS seg;
+ ^
+DETAIL: syntax error at or near ".."
+SELECT '.1'::seg AS seg;
+ERROR: bad seg representation
+LINE 1: SELECT '.1'::seg AS seg;
+ ^
+DETAIL: syntax error at or near "."
+SELECT '1..2.'::seg AS seg;
+ERROR: bad seg representation
+LINE 1: SELECT '1..2.'::seg AS seg;
+ ^
+DETAIL: syntax error at or near "."
+SELECT '1 e7'::seg AS seg;
+ERROR: bad seg representation
+LINE 1: SELECT '1 e7'::seg AS seg;
+ ^
+DETAIL: syntax error at or near "e"
+SELECT '1e700'::seg AS seg;
+ERROR: "1e700" is out of range for type real
+LINE 1: SELECT '1e700'::seg AS seg;
+ ^
+--
+-- testing the operators
+--
+-- equality/inequality:
+--
+SELECT '24 .. 33.20'::seg = '24 .. 33.20'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+SELECT '24 .. 33.20'::seg = '24 .. 33.21'::seg AS bool;
+ bool
+------
+ f
+(1 row)
+
+SELECT '24 .. 33.20'::seg != '24 .. 33.20'::seg AS bool;
+ bool
+------
+ f
+(1 row)
+
+SELECT '24 .. 33.20'::seg != '24 .. 33.21'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+-- overlap
+--
+SELECT '1'::seg && '1'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+SELECT '1'::seg && '2'::seg AS bool;
+ bool
+------
+ f
+(1 row)
+
+SELECT '0 ..'::seg && '0 ..'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+SELECT '0 .. 1'::seg && '0 .. 1'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+SELECT '..0'::seg && '0..'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+SELECT '-1 .. 0.1'::seg && '0 .. 1'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+SELECT '-1 .. 0'::seg && '0 .. 1'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+SELECT '-1 .. -0.0001'::seg && '0 .. 1'::seg AS bool;
+ bool
+------
+ f
+(1 row)
+
+SELECT '0 ..'::seg && '1'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+SELECT '0 .. 1'::seg && '1'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+SELECT '0 .. 1'::seg && '2'::seg AS bool;
+ bool
+------
+ f
+(1 row)
+
+SELECT '0 .. 2'::seg && '1'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+SELECT '1'::seg && '0 .. 1'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+SELECT '2'::seg && '0 .. 1'::seg AS bool;
+ bool
+------
+ f
+(1 row)
+
+SELECT '1'::seg && '0 .. 2'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+-- overlap on the left
+--
+SELECT '1'::seg &< '0'::seg AS bool;
+ bool
+------
+ f
+(1 row)
+
+SELECT '1'::seg &< '1'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+SELECT '1'::seg &< '2'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+SELECT '0 .. 1'::seg &< '0'::seg AS bool;
+ bool
+------
+ f
+(1 row)
+
+SELECT '0 .. 1'::seg &< '1'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+SELECT '0 .. 1'::seg &< '2'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+SELECT '0 .. 1'::seg &< '0 .. 0.5'::seg AS bool;
+ bool
+------
+ f
+(1 row)
+
+SELECT '0 .. 1'::seg &< '0 .. 1'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+SELECT '0 .. 1'::seg &< '0 .. 2'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+SELECT '0 .. 1'::seg &< '1 .. 2'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+SELECT '0 .. 1'::seg &< '2 .. 3'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+-- overlap on the right
+--
+SELECT '0'::seg &> '1'::seg AS bool;
+ bool
+------
+ f
+(1 row)
+
+SELECT '1'::seg &> '1'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+SELECT '2'::seg &> '1'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+SELECT '0'::seg &> '0 .. 1'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+SELECT '1'::seg &> '0 .. 1'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+SELECT '2'::seg &> '0 .. 1'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+SELECT '0 .. 0.5'::seg &> '0 .. 1'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+SELECT '0 .. 1'::seg &> '0 .. 1'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+SELECT '0 .. 2'::seg &> '0 .. 2'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+SELECT '1 .. 2'::seg &> '0 .. 1'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+SELECT '2 .. 3'::seg &> '0 .. 1'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+-- left
+--
+SELECT '1'::seg << '0'::seg AS bool;
+ bool
+------
+ f
+(1 row)
+
+SELECT '1'::seg << '1'::seg AS bool;
+ bool
+------
+ f
+(1 row)
+
+SELECT '1'::seg << '2'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+SELECT '0 .. 1'::seg << '0'::seg AS bool;
+ bool
+------
+ f
+(1 row)
+
+SELECT '0 .. 1'::seg << '1'::seg AS bool;
+ bool
+------
+ f
+(1 row)
+
+SELECT '0 .. 1'::seg << '2'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+SELECT '0 .. 1'::seg << '0 .. 0.5'::seg AS bool;
+ bool
+------
+ f
+(1 row)
+
+SELECT '0 .. 1'::seg << '0 .. 1'::seg AS bool;
+ bool
+------
+ f
+(1 row)
+
+SELECT '0 .. 1'::seg << '0 .. 2'::seg AS bool;
+ bool
+------
+ f
+(1 row)
+
+SELECT '0 .. 1'::seg << '1 .. 2'::seg AS bool;
+ bool
+------
+ f
+(1 row)
+
+SELECT '0 .. 1'::seg << '2 .. 3'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+-- right
+--
+SELECT '0'::seg >> '1'::seg AS bool;
+ bool
+------
+ f
+(1 row)
+
+SELECT '1'::seg >> '1'::seg AS bool;
+ bool
+------
+ f
+(1 row)
+
+SELECT '2'::seg >> '1'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+SELECT '0'::seg >> '0 .. 1'::seg AS bool;
+ bool
+------
+ f
+(1 row)
+
+SELECT '1'::seg >> '0 .. 1'::seg AS bool;
+ bool
+------
+ f
+(1 row)
+
+SELECT '2'::seg >> '0 .. 1'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+SELECT '0 .. 0.5'::seg >> '0 .. 1'::seg AS bool;
+ bool
+------
+ f
+(1 row)
+
+SELECT '0 .. 1'::seg >> '0 .. 1'::seg AS bool;
+ bool
+------
+ f
+(1 row)
+
+SELECT '0 .. 2'::seg >> '0 .. 2'::seg AS bool;
+ bool
+------
+ f
+(1 row)
+
+SELECT '1 .. 2'::seg >> '0 .. 1'::seg AS bool;
+ bool
+------
+ f
+(1 row)
+
+SELECT '2 .. 3'::seg >> '0 .. 1'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+-- "contained in" (the left value belongs within the interval specified in the right value):
+--
+SELECT '0'::seg <@ '0'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+SELECT '0'::seg <@ '0 ..'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+SELECT '0'::seg <@ '.. 0'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+SELECT '0'::seg <@ '-1 .. 1'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+SELECT '0'::seg <@ '-1 .. 1'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+SELECT '-1'::seg <@ '-1 .. 1'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+SELECT '1'::seg <@ '-1 .. 1'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+SELECT '-1 .. 1'::seg <@ '-1 .. 1'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+-- "contains" (the left value contains the interval specified in the right value):
+--
+SELECT '0'::seg @> '0'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+SELECT '0 .. '::seg <@ '0'::seg AS bool;
+ bool
+------
+ f
+(1 row)
+
+SELECT '.. 0'::seg <@ '0'::seg AS bool;
+ bool
+------
+ f
+(1 row)
+
+SELECT '-1 .. 1'::seg <@ '0'::seg AS bool;
+ bool
+------
+ f
+(1 row)
+
+SELECT '0'::seg <@ '-1 .. 1'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+SELECT '-1'::seg <@ '-1 .. 1'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+SELECT '1'::seg <@ '-1 .. 1'::seg AS bool;
+ bool
+------
+ t
+(1 row)
+
+-- Load some example data and build the index
+--
+CREATE TABLE test_seg (s seg);
+\copy test_seg from 'data/test_seg.data'
+CREATE INDEX test_seg_ix ON test_seg USING gist (s);
+SET enable_indexscan = false;
+EXPLAIN (COSTS OFF)
+SELECT count(*) FROM test_seg WHERE s @> '11..11.3';
+ QUERY PLAN
+-------------------------------------------------------
+ Aggregate
+ -> Bitmap Heap Scan on test_seg
+ Recheck Cond: (s @> '1.1e1 .. 11.3'::seg)
+ -> Bitmap Index Scan on test_seg_ix
+ Index Cond: (s @> '1.1e1 .. 11.3'::seg)
+(5 rows)
+
+SELECT count(*) FROM test_seg WHERE s @> '11..11.3';
+ count
+-------
+ 143
+(1 row)
+
+RESET enable_indexscan;
+SET enable_bitmapscan = false;
+EXPLAIN (COSTS OFF)
+SELECT count(*) FROM test_seg WHERE s @> '11..11.3';
+ QUERY PLAN
+-----------------------------------------------------
+ Aggregate
+ -> Index Only Scan using test_seg_ix on test_seg
+ Index Cond: (s @> '1.1e1 .. 11.3'::seg)
+(3 rows)
+
+SELECT count(*) FROM test_seg WHERE s @> '11..11.3';
+ count
+-------
+ 143
+(1 row)
+
+RESET enable_bitmapscan;
+-- Test sorting
+SELECT * FROM test_seg WHERE s @> '11..11.3' GROUP BY s;
+ s
+-----------------
+ .. 4.0e1
+ .. >8.2e1
+ .. 9.0e1
+ <1.0 .. >13.0
+ 1.3 .. 12.0
+ 2.0 .. 11.5
+ 2.1 .. 11.8
+ <2.3 ..
+ >2.3 ..
+ 2.4 .. 11.3
+ 2.5 .. 11.5
+ 2.5 .. 11.8
+ 2.6 ..
+ 2.7 .. 12.0
+ <3.0 ..
+ 3 .. 5.8e1
+ 3.1 .. 11.5
+ 3.5 .. 11.5
+ 3.5 .. 12.2
+ <4.0 .. >1.2e1
+ <4.0 ..
+ 4 .. 1.2e1
+ 4.0 .. 11.7
+ 4.0 .. 12.5
+ 4.0 .. 13.0
+ 4.0 .. 6.0e1
+ 4.0 ..
+ 4.2 .. 11.5
+ 4.2 .. 11.7
+ <4.5 .. >1.2e1
+ 4.5 .. 11.5
+ 4.5 .. <1.2e1
+ 4.5 .. >1.2e1
+ 4.5 .. 12.5
+ 4.5 .. 1.15e2
+ 4.7 .. 11.8
+ 4.8 .. 11.5
+ 4.8 .. 11.6
+ 4.8 .. 12.5
+ 4.8 ..
+ 4.9 .. >1.2e1
+ 4.9 ..
+ 5 .. 11.5
+ 5 .. 1.2e1
+ 5 .. 3.0e1
+ 5.0 .. 11.4
+ 5.0 .. 11.5
+ 5.0 .. 11.6
+ 5.0 .. 11.7
+ 5.0 .. 12.0
+ 5.0 .. >12.0
+ 5.0 .. >1.2e1
+ 5.2 .. 11.5
+ 5.2 .. >1.2e1
+ 5.25 .. >1.2e1
+ 5.3 .. 11.5
+ 5.3 .. 1.3e1
+ 5.3 .. >9.0e1
+ 5.3 ..
+ 5.4 ..
+ 5.5 .. 11.5
+ 5.5 .. 11.7
+ 5.5 .. 1.2e1
+ 5.5 .. >1.2e1
+ 5.5 .. 12.5
+ 5.5 .. 13.5
+ 5.5 ..
+ >5.5 ..
+ 5.7 ..
+ 5.9 ..
+ 6 .. 11.5
+ 6 .. >1.2e1
+ 6.0 .. 11.5
+ 6.0 .. 1.3e1
+ >6.0 .. <11.5
+ 6.1 .. >1.2e1
+ 6.1 ..
+ 6.2 .. >11.5
+ 6.3 ..
+ 6.5 .. 11.5
+ 6.5 .. 12.0
+ 6.5 .. >12.0
+ 6.5 ..
+ 6.6 ..
+ 6.7 .. 11.5
+ 6.7 ..
+ 6.75 ..
+ 6.8 ..
+ 6.9 .. 12.2
+ 6.9 .. >9.0e1
+ 6.9 ..
+ <7.0 .. >11.5
+ 7.0 .. 11.5
+ 7.0 .. >11.5
+ 7.0 ..
+ >7.15 ..
+ 7.2 .. 13.5
+ 7.3 .. >9.0e1
+ 7.3 ..
+ >7.3 ..
+ 7.4 .. 12.1
+ 7.4 ..
+ 7.5 .. 11.5
+ 7.5 .. 12.0
+ 7.5 ..
+ 7.7 .. 11.5
+ 7.7 ..
+ 7.75 ..
+ 8.0 .. 11.7
+ 8.0 .. 12.0
+ 8.0 .. >13.0
+ 8.2 ..
+ 8.3 ..
+ 8.5 .. >11.5
+ 8.5 .. 12.5
+ 8.5 ..
+ 8.6 .. >9.9e1
+ 8.7 .. 11.3
+ 8.7 .. 11.7
+ 8.9 .. 11.5
+ 9 .. >1.2e1
+ 9.0 .. 11.3
+ 9.0 .. 11.5
+ 9.0 .. 1.2e1
+ 9.0 ..
+ 9.2 .. 1.2e1
+ 9.4 .. 12.2
+ <9.5 .. 1.2e1
+ <9.5 .. >12.2
+ 9.5 ..
+ 9.6 .. 11.5
+ 9.7 .. 11.5
+ 9.7 .. >1.2e1
+ 9.8 .. >12.5
+ <1.0e1 .. >11.6
+ 10.0 .. 11.5
+ 10.0 .. 12.5
+ 10.0 .. >12.5
+ 10.2 .. 11.8
+ <10.5 .. 11.5
+ 10.5 .. 11.5
+ 10.5 .. <13.5
+ 10.7 .. 12.3
+(143 rows)
+
+-- Test functions
+SELECT seg_lower(s), seg_center(s), seg_upper(s)
+FROM test_seg WHERE s @> '11.2..11.3' OR s IS NULL ORDER BY s;
+ seg_lower | seg_center | seg_upper
+-----------+------------+-----------
+ -Infinity | -Infinity | 40
+ -Infinity | -Infinity | 82
+ -Infinity | -Infinity | 90
+ 1 | 7 | 13
+ 1.3 | 6.65 | 12
+ 2 | 6.75 | 11.5
+ 2.1 | 6.95 | 11.8
+ 2.3 | Infinity | Infinity
+ 2.3 | Infinity | Infinity
+ 2.4 | 6.8500004 | 11.3
+ 2.5 | 7 | 11.5
+ 2.5 | 7.15 | 11.8
+ 2.6 | Infinity | Infinity
+ 2.7 | 7.35 | 12
+ 3 | Infinity | Infinity
+ 3 | 30.5 | 58
+ 3.1 | 7.3 | 11.5
+ 3.5 | 7.5 | 11.5
+ 3.5 | 7.85 | 12.2
+ 4 | 8 | 12
+ 4 | Infinity | Infinity
+ 4 | 8 | 12
+ 4 | 7.85 | 11.7
+ 4 | 8.25 | 12.5
+ 4 | 8.5 | 13
+ 4 | 32 | 60
+ 4 | Infinity | Infinity
+ 4.2 | 7.85 | 11.5
+ 4.2 | 7.95 | 11.7
+ 4.5 | 8.25 | 12
+ 4.5 | 8 | 11.5
+ 4.5 | 8.25 | 12
+ 4.5 | 8.25 | 12
+ 4.5 | 8.5 | 12.5
+ 4.5 | 59.75 | 115
+ 4.7 | 8.25 | 11.8
+ 4.8 | 8.15 | 11.5
+ 4.8 | 8.200001 | 11.6
+ 4.8 | 8.65 | 12.5
+ 4.8 | Infinity | Infinity
+ 4.9 | 8.45 | 12
+ 4.9 | Infinity | Infinity
+ 5 | 8.25 | 11.5
+ 5 | 8.5 | 12
+ 5 | 17.5 | 30
+ 5 | 8.2 | 11.4
+ 5 | 8.25 | 11.5
+ 5 | 8.3 | 11.6
+ 5 | 8.35 | 11.7
+ 5 | 8.5 | 12
+ 5 | 8.5 | 12
+ 5 | 8.5 | 12
+ 5.2 | 8.35 | 11.5
+ 5.2 | 8.6 | 12
+ 5.25 | 8.625 | 12
+ 5.3 | 8.4 | 11.5
+ 5.3 | 9.15 | 13
+ 5.3 | 47.65 | 90
+ 5.3 | Infinity | Infinity
+ 5.4 | Infinity | Infinity
+ 5.5 | 8.5 | 11.5
+ 5.5 | 8.6 | 11.7
+ 5.5 | 8.75 | 12
+ 5.5 | 8.75 | 12
+ 5.5 | 9 | 12.5
+ 5.5 | 9.5 | 13.5
+ 5.5 | Infinity | Infinity
+ 5.5 | Infinity | Infinity
+ 5.7 | Infinity | Infinity
+ 5.9 | Infinity | Infinity
+ 6 | 8.75 | 11.5
+ 6 | 9 | 12
+ 6 | 8.75 | 11.5
+ 6 | 9.5 | 13
+ 6 | 8.75 | 11.5
+ 6.1 | 9.05 | 12
+ 6.1 | Infinity | Infinity
+ 6.2 | 8.85 | 11.5
+ 6.3 | Infinity | Infinity
+ 6.5 | 9 | 11.5
+ 6.5 | 9.25 | 12
+ 6.5 | 9.25 | 12
+ 6.5 | Infinity | Infinity
+ 6.6 | Infinity | Infinity
+ 6.7 | 9.1 | 11.5
+ 6.7 | Infinity | Infinity
+ 6.75 | Infinity | Infinity
+ 6.8 | Infinity | Infinity
+ 6.9 | 9.55 | 12.2
+ 6.9 | 48.45 | 90
+ 6.9 | Infinity | Infinity
+ 7 | 9.25 | 11.5
+ 7 | 9.25 | 11.5
+ 7 | 9.25 | 11.5
+ 7 | Infinity | Infinity
+ 7.15 | Infinity | Infinity
+ 7.2 | 10.35 | 13.5
+ 7.3 | 48.65 | 90
+ 7.3 | Infinity | Infinity
+ 7.3 | Infinity | Infinity
+ 7.4 | 9.75 | 12.1
+ 7.4 | Infinity | Infinity
+ 7.5 | 9.5 | 11.5
+ 7.5 | 9.75 | 12
+ 7.5 | Infinity | Infinity
+ 7.7 | 9.6 | 11.5
+ 7.7 | Infinity | Infinity
+ 7.75 | Infinity | Infinity
+ 8 | 9.85 | 11.7
+ 8 | 10 | 12
+ 8 | 10.5 | 13
+ 8.2 | Infinity | Infinity
+ 8.3 | Infinity | Infinity
+ 8.5 | 10 | 11.5
+ 8.5 | 10.5 | 12.5
+ 8.5 | Infinity | Infinity
+ 8.6 | 53.8 | 99
+ 8.7 | 10 | 11.3
+ 8.7 | 10.2 | 11.7
+ 8.9 | 10.2 | 11.5
+ 9 | 10.5 | 12
+ 9 | 10.15 | 11.3
+ 9 | 10.25 | 11.5
+ 9 | 10.5 | 12
+ 9 | Infinity | Infinity
+ 9.2 | 10.6 | 12
+ 9.4 | 10.799999 | 12.2
+ 9.5 | 10.75 | 12
+ 9.5 | 10.85 | 12.2
+ 9.5 | Infinity | Infinity
+ 9.6 | 10.55 | 11.5
+ 9.7 | 10.6 | 11.5
+ 9.7 | 10.85 | 12
+ 9.8 | 11.15 | 12.5
+ 10 | 10.8 | 11.6
+ 10 | 10.75 | 11.5
+ 10 | 11.25 | 12.5
+ 10 | 11.25 | 12.5
+ 10.2 | 11 | 11.8
+ 10.5 | 11 | 11.5
+ 10.5 | 11 | 11.5
+ 10.5 | 12 | 13.5
+ 10.7 | 11.5 | 12.3
+ | |
+(144 rows)
+
diff --git a/contrib/seg/seg--1.0--1.1.sql b/contrib/seg/seg--1.0--1.1.sql
new file mode 100644
index 0000000..ae6cb2f
--- /dev/null
+++ b/contrib/seg/seg--1.0--1.1.sql
@@ -0,0 +1,63 @@
+/* contrib/seg/seg--1.0--1.1.sql */
+
+-- complain if script is sourced in psql, rather than via ALTER EXTENSION
+\echo Use "ALTER EXTENSION seg UPDATE TO '1.1'" to load this file. \quit
+
+-- Update procedure signatures the hard way.
+-- We use to_regprocedure() so that query doesn't fail if run against 9.6beta1 definitions,
+-- wherein the signatures have been updated already. In that case to_regprocedure() will
+-- return NULL and no updates will happen.
+DO LANGUAGE plpgsql
+$$
+DECLARE
+ my_schema pg_catalog.text := pg_catalog.quote_ident(pg_catalog.current_schema());
+ old_path pg_catalog.text := pg_catalog.current_setting('search_path');
+BEGIN
+-- for safety, transiently set search_path to just pg_catalog+pg_temp
+PERFORM pg_catalog.set_config('search_path', 'pg_catalog, pg_temp', true);
+
+UPDATE pg_catalog.pg_proc SET
+ proargtypes = pg_catalog.array_to_string(newtypes::pg_catalog.oid[], ' ')::pg_catalog.oidvector,
+ pronargs = pg_catalog.array_length(newtypes, 1)
+FROM (VALUES
+(NULL::pg_catalog.text, NULL::pg_catalog.text[]), -- establish column types
+('gseg_consistent(internal,SCH.seg,int4,oid,internal)', '{internal,SCH.seg,int2,oid,internal}')
+) AS update_data (oldproc, newtypestext),
+LATERAL (
+ SELECT array_agg(replace(typ, 'SCH', my_schema)::regtype) as newtypes FROM unnest(newtypestext) typ
+) ls
+WHERE oid = to_regprocedure(my_schema || '.' || replace(oldproc, 'SCH', my_schema));
+
+PERFORM pg_catalog.set_config('search_path', old_path, true);
+END
+$$;
+
+ALTER FUNCTION seg_in(cstring) PARALLEL SAFE;
+ALTER FUNCTION seg_out(seg) PARALLEL SAFE;
+ALTER FUNCTION seg_over_left(seg, seg) PARALLEL SAFE;
+ALTER FUNCTION seg_over_right(seg, seg) PARALLEL SAFE;
+ALTER FUNCTION seg_left(seg, seg) PARALLEL SAFE;
+ALTER FUNCTION seg_right(seg, seg) PARALLEL SAFE;
+ALTER FUNCTION seg_lt(seg, seg) PARALLEL SAFE;
+ALTER FUNCTION seg_le(seg, seg) PARALLEL SAFE;
+ALTER FUNCTION seg_gt(seg, seg) PARALLEL SAFE;
+ALTER FUNCTION seg_ge(seg, seg) PARALLEL SAFE;
+ALTER FUNCTION seg_contains(seg, seg) PARALLEL SAFE;
+ALTER FUNCTION seg_contained(seg, seg) PARALLEL SAFE;
+ALTER FUNCTION seg_overlap(seg, seg) PARALLEL SAFE;
+ALTER FUNCTION seg_same(seg, seg) PARALLEL SAFE;
+ALTER FUNCTION seg_different(seg, seg) PARALLEL SAFE;
+ALTER FUNCTION seg_cmp(seg, seg) PARALLEL SAFE;
+ALTER FUNCTION seg_union(seg, seg) PARALLEL SAFE;
+ALTER FUNCTION seg_inter(seg, seg) PARALLEL SAFE;
+ALTER FUNCTION seg_size(seg) PARALLEL SAFE;
+ALTER FUNCTION seg_center(seg) PARALLEL SAFE;
+ALTER FUNCTION seg_upper(seg) PARALLEL SAFE;
+ALTER FUNCTION seg_lower(seg) PARALLEL SAFE;
+ALTER FUNCTION gseg_consistent(internal, seg, smallint, oid, internal) PARALLEL SAFE;
+ALTER FUNCTION gseg_compress(internal) PARALLEL SAFE;
+ALTER FUNCTION gseg_decompress(internal) PARALLEL SAFE;
+ALTER FUNCTION gseg_penalty(internal, internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gseg_picksplit(internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gseg_union(internal, internal) PARALLEL SAFE;
+ALTER FUNCTION gseg_same(seg, seg, internal) PARALLEL SAFE;
diff --git a/contrib/seg/seg--1.1--1.2.sql b/contrib/seg/seg--1.1--1.2.sql
new file mode 100644
index 0000000..a6e4456
--- /dev/null
+++ b/contrib/seg/seg--1.1--1.2.sql
@@ -0,0 +1,14 @@
+/* contrib/seg/seg--1.1--1.2.sql */
+
+-- complain if script is sourced in psql, rather than via ALTER EXTENSION
+\echo Use "ALTER EXTENSION seg UPDATE TO '1.2'" to load this file. \quit
+
+ALTER OPERATOR <= (seg, seg) SET (
+ RESTRICT = scalarlesel,
+ JOIN = scalarlejoinsel
+);
+
+ALTER OPERATOR >= (seg, seg) SET (
+ RESTRICT = scalargesel,
+ JOIN = scalargejoinsel
+);
diff --git a/contrib/seg/seg--1.1.sql b/contrib/seg/seg--1.1.sql
new file mode 100644
index 0000000..d95aabc
--- /dev/null
+++ b/contrib/seg/seg--1.1.sql
@@ -0,0 +1,395 @@
+/* contrib/seg/seg--1.1.sql */
+
+-- complain if script is sourced in psql, rather than via CREATE EXTENSION
+\echo Use "CREATE EXTENSION seg" to load this file. \quit
+
+-- Create the user-defined type for 1-D floating point intervals (seg)
+
+CREATE FUNCTION seg_in(cstring)
+RETURNS seg
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION seg_out(seg)
+RETURNS cstring
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE TYPE seg (
+ INTERNALLENGTH = 12,
+ INPUT = seg_in,
+ OUTPUT = seg_out
+);
+
+COMMENT ON TYPE seg IS
+'floating point interval ''FLOAT .. FLOAT'', ''.. FLOAT'', ''FLOAT ..'' or ''FLOAT''';
+
+--
+-- External C-functions for R-tree methods
+--
+
+-- Left/Right methods
+
+CREATE FUNCTION seg_over_left(seg, seg)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+COMMENT ON FUNCTION seg_over_left(seg, seg) IS
+'overlaps or is left of';
+
+CREATE FUNCTION seg_over_right(seg, seg)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+COMMENT ON FUNCTION seg_over_right(seg, seg) IS
+'overlaps or is right of';
+
+CREATE FUNCTION seg_left(seg, seg)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+COMMENT ON FUNCTION seg_left(seg, seg) IS
+'is left of';
+
+CREATE FUNCTION seg_right(seg, seg)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+COMMENT ON FUNCTION seg_right(seg, seg) IS
+'is right of';
+
+
+-- Scalar comparison methods
+
+CREATE FUNCTION seg_lt(seg, seg)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+COMMENT ON FUNCTION seg_lt(seg, seg) IS
+'less than';
+
+CREATE FUNCTION seg_le(seg, seg)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+COMMENT ON FUNCTION seg_le(seg, seg) IS
+'less than or equal';
+
+CREATE FUNCTION seg_gt(seg, seg)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+COMMENT ON FUNCTION seg_gt(seg, seg) IS
+'greater than';
+
+CREATE FUNCTION seg_ge(seg, seg)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+COMMENT ON FUNCTION seg_ge(seg, seg) IS
+'greater than or equal';
+
+CREATE FUNCTION seg_contains(seg, seg)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+COMMENT ON FUNCTION seg_contains(seg, seg) IS
+'contains';
+
+CREATE FUNCTION seg_contained(seg, seg)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+COMMENT ON FUNCTION seg_contained(seg, seg) IS
+'contained in';
+
+CREATE FUNCTION seg_overlap(seg, seg)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+COMMENT ON FUNCTION seg_overlap(seg, seg) IS
+'overlaps';
+
+CREATE FUNCTION seg_same(seg, seg)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+COMMENT ON FUNCTION seg_same(seg, seg) IS
+'same as';
+
+CREATE FUNCTION seg_different(seg, seg)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+COMMENT ON FUNCTION seg_different(seg, seg) IS
+'different';
+
+-- support routines for indexing
+
+CREATE FUNCTION seg_cmp(seg, seg)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+COMMENT ON FUNCTION seg_cmp(seg, seg) IS 'btree comparison function';
+
+CREATE FUNCTION seg_union(seg, seg)
+RETURNS seg
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION seg_inter(seg, seg)
+RETURNS seg
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION seg_size(seg)
+RETURNS float4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+-- miscellaneous
+
+CREATE FUNCTION seg_center(seg)
+RETURNS float4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION seg_upper(seg)
+RETURNS float4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+CREATE FUNCTION seg_lower(seg)
+RETURNS float4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
+
+
+--
+-- OPERATORS
+--
+
+CREATE OPERATOR < (
+ LEFTARG = seg,
+ RIGHTARG = seg,
+ PROCEDURE = seg_lt,
+ COMMUTATOR = '>',
+ NEGATOR = '>=',
+ RESTRICT = scalarltsel,
+ JOIN = scalarltjoinsel
+);
+
+CREATE OPERATOR <= (
+ LEFTARG = seg,
+ RIGHTARG = seg,
+ PROCEDURE = seg_le,
+ COMMUTATOR = '>=',
+ NEGATOR = '>',
+ RESTRICT = scalarltsel,
+ JOIN = scalarltjoinsel
+);
+
+CREATE OPERATOR > (
+ LEFTARG = seg,
+ RIGHTARG = seg,
+ PROCEDURE = seg_gt,
+ COMMUTATOR = '<',
+ NEGATOR = '<=',
+ RESTRICT = scalargtsel,
+ JOIN = scalargtjoinsel
+);
+
+CREATE OPERATOR >= (
+ LEFTARG = seg,
+ RIGHTARG = seg,
+ PROCEDURE = seg_ge,
+ COMMUTATOR = '<=',
+ NEGATOR = '<',
+ RESTRICT = scalargtsel,
+ JOIN = scalargtjoinsel
+);
+
+CREATE OPERATOR << (
+ LEFTARG = seg,
+ RIGHTARG = seg,
+ PROCEDURE = seg_left,
+ COMMUTATOR = '>>',
+ RESTRICT = positionsel,
+ JOIN = positionjoinsel
+);
+
+CREATE OPERATOR &< (
+ LEFTARG = seg,
+ RIGHTARG = seg,
+ PROCEDURE = seg_over_left,
+ RESTRICT = positionsel,
+ JOIN = positionjoinsel
+);
+
+CREATE OPERATOR && (
+ LEFTARG = seg,
+ RIGHTARG = seg,
+ PROCEDURE = seg_overlap,
+ COMMUTATOR = '&&',
+ RESTRICT = areasel,
+ JOIN = areajoinsel
+);
+
+CREATE OPERATOR &> (
+ LEFTARG = seg,
+ RIGHTARG = seg,
+ PROCEDURE = seg_over_right,
+ RESTRICT = positionsel,
+ JOIN = positionjoinsel
+);
+
+CREATE OPERATOR >> (
+ LEFTARG = seg,
+ RIGHTARG = seg,
+ PROCEDURE = seg_right,
+ COMMUTATOR = '<<',
+ RESTRICT = positionsel,
+ JOIN = positionjoinsel
+);
+
+CREATE OPERATOR = (
+ LEFTARG = seg,
+ RIGHTARG = seg,
+ PROCEDURE = seg_same,
+ COMMUTATOR = '=',
+ NEGATOR = '<>',
+ RESTRICT = eqsel,
+ JOIN = eqjoinsel,
+ MERGES
+);
+
+CREATE OPERATOR <> (
+ LEFTARG = seg,
+ RIGHTARG = seg,
+ PROCEDURE = seg_different,
+ COMMUTATOR = '<>',
+ NEGATOR = '=',
+ RESTRICT = neqsel,
+ JOIN = neqjoinsel
+);
+
+CREATE OPERATOR @> (
+ LEFTARG = seg,
+ RIGHTARG = seg,
+ PROCEDURE = seg_contains,
+ COMMUTATOR = '<@',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+);
+
+CREATE OPERATOR <@ (
+ LEFTARG = seg,
+ RIGHTARG = seg,
+ PROCEDURE = seg_contained,
+ COMMUTATOR = '@>',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+);
+
+-- obsolete:
+CREATE OPERATOR @ (
+ LEFTARG = seg,
+ RIGHTARG = seg,
+ PROCEDURE = seg_contains,
+ COMMUTATOR = '~',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+);
+
+CREATE OPERATOR ~ (
+ LEFTARG = seg,
+ RIGHTARG = seg,
+ PROCEDURE = seg_contained,
+ COMMUTATOR = '@',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+);
+
+
+-- define the GiST support methods
+CREATE FUNCTION gseg_consistent(internal,seg,smallint,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
+
+CREATE FUNCTION gseg_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
+
+CREATE FUNCTION gseg_decompress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
+
+CREATE FUNCTION gseg_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
+
+CREATE FUNCTION gseg_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
+
+CREATE FUNCTION gseg_union(internal, internal)
+RETURNS seg
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
+
+CREATE FUNCTION gseg_same(seg, seg, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
+
+
+-- Create the operator classes for indexing
+
+CREATE OPERATOR CLASS seg_ops
+ DEFAULT FOR TYPE seg USING btree AS
+ OPERATOR 1 < ,
+ OPERATOR 2 <= ,
+ OPERATOR 3 = ,
+ OPERATOR 4 >= ,
+ OPERATOR 5 > ,
+ FUNCTION 1 seg_cmp(seg, seg);
+
+CREATE OPERATOR CLASS gist_seg_ops
+DEFAULT FOR TYPE seg USING gist
+AS
+ OPERATOR 1 << ,
+ OPERATOR 2 &< ,
+ OPERATOR 3 && ,
+ OPERATOR 4 &> ,
+ OPERATOR 5 >> ,
+ OPERATOR 6 = ,
+ OPERATOR 7 @> ,
+ OPERATOR 8 <@ ,
+ OPERATOR 13 @ ,
+ OPERATOR 14 ~ ,
+ FUNCTION 1 gseg_consistent (internal, seg, smallint, oid, internal),
+ FUNCTION 2 gseg_union (internal, internal),
+ FUNCTION 3 gseg_compress (internal),
+ FUNCTION 4 gseg_decompress (internal),
+ FUNCTION 5 gseg_penalty (internal, internal, internal),
+ FUNCTION 6 gseg_picksplit (internal, internal),
+ FUNCTION 7 gseg_same (seg, seg, internal);
diff --git a/contrib/seg/seg--1.2--1.3.sql b/contrib/seg/seg--1.2--1.3.sql
new file mode 100644
index 0000000..578e989
--- /dev/null
+++ b/contrib/seg/seg--1.2--1.3.sql
@@ -0,0 +1,58 @@
+/* contrib/seg/seg--1.2--1.3.sql */
+
+-- complain if script is sourced in psql, rather than via ALTER EXTENSION
+\echo Use "ALTER EXTENSION seg UPDATE TO '1.3'" to load this file. \quit
+
+--
+-- Get rid of unnecessary compress and decompress support functions.
+--
+-- To be allowed to drop the opclass entry for a support function,
+-- we must change the entry's dependency type from 'internal' to 'auto',
+-- as though it were a loose member of the opfamily rather than being
+-- bound into a particular opclass. There's no SQL command for that,
+-- so fake it with a manual update on pg_depend.
+--
+DO LANGUAGE plpgsql
+$$
+DECLARE
+ my_schema pg_catalog.text := pg_catalog.quote_ident(pg_catalog.current_schema());
+ old_path pg_catalog.text := pg_catalog.current_setting('search_path');
+BEGIN
+-- for safety, transiently set search_path to just pg_catalog+pg_temp
+PERFORM pg_catalog.set_config('search_path', 'pg_catalog, pg_temp', true);
+
+UPDATE pg_catalog.pg_depend
+SET deptype = 'a'
+WHERE classid = 'pg_catalog.pg_amproc'::pg_catalog.regclass
+ AND objid =
+ (SELECT objid
+ FROM pg_catalog.pg_depend
+ WHERE classid = 'pg_catalog.pg_amproc'::pg_catalog.regclass
+ AND refclassid = 'pg_catalog.pg_proc'::pg_catalog.regclass
+ AND (refobjid = (my_schema || '.gseg_compress(internal)')::pg_catalog.regprocedure))
+ AND refclassid = 'pg_catalog.pg_opclass'::pg_catalog.regclass
+ AND deptype = 'i';
+
+UPDATE pg_catalog.pg_depend
+SET deptype = 'a'
+WHERE classid = 'pg_catalog.pg_amproc'::pg_catalog.regclass
+ AND objid =
+ (SELECT objid
+ FROM pg_catalog.pg_depend
+ WHERE classid = 'pg_catalog.pg_amproc'::pg_catalog.regclass
+ AND refclassid = 'pg_catalog.pg_proc'::pg_catalog.regclass
+ AND (refobjid = (my_schema || '.gseg_decompress(internal)')::pg_catalog.regprocedure))
+ AND refclassid = 'pg_catalog.pg_opclass'::pg_catalog.regclass
+ AND deptype = 'i';
+
+PERFORM pg_catalog.set_config('search_path', old_path, true);
+END
+$$;
+
+ALTER OPERATOR FAMILY gist_seg_ops USING gist drop function 3 (seg);
+ALTER EXTENSION seg DROP function gseg_compress(pg_catalog.internal);
+DROP function gseg_compress(pg_catalog.internal);
+
+ALTER OPERATOR FAMILY gist_seg_ops USING gist drop function 4 (seg);
+ALTER EXTENSION seg DROP function gseg_decompress(pg_catalog.internal);
+DROP function gseg_decompress(pg_catalog.internal);
diff --git a/contrib/seg/seg-validate.pl b/contrib/seg/seg-validate.pl
new file mode 100755
index 0000000..9fa0887
--- /dev/null
+++ b/contrib/seg/seg-validate.pl
@@ -0,0 +1,54 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+my $integer = '[+-]?[0-9]+';
+my $real = '[+-]?[0-9]+\.[0-9]+';
+
+my $RANGE = '(\.\.)(\.)?';
+my $PLUMIN = q(\'\+\-\');
+my $FLOAT = "(($integer)|($real))([eE]($integer))?";
+my $EXTENSION = '<|>|~';
+
+my $boundary = "($EXTENSION)?$FLOAT";
+my $deviation = $FLOAT;
+
+my $rule_1 = $boundary . $PLUMIN . $deviation;
+my $rule_2 = $boundary . $RANGE . $boundary;
+my $rule_3 = $boundary . $RANGE;
+my $rule_4 = $RANGE . $boundary;
+my $rule_5 = $boundary;
+
+
+print "$rule_5\n";
+while (<>)
+{
+
+ # s/ +//g;
+ if (/^($rule_1)$/)
+ {
+ print;
+ }
+ elsif (/^($rule_2)$/)
+ {
+ print;
+ }
+ elsif (/^($rule_3)$/)
+ {
+ print;
+ }
+ elsif (/^($rule_4)$/)
+ {
+ print;
+ }
+ elsif (/^($rule_5)$/)
+ {
+ print;
+ }
+ else
+ {
+ print STDERR "error in $_\n";
+ }
+
+}
diff --git a/contrib/seg/seg.c b/contrib/seg/seg.c
new file mode 100644
index 0000000..4a8e2be
--- /dev/null
+++ b/contrib/seg/seg.c
@@ -0,0 +1,1090 @@
+/*
+ * contrib/seg/seg.c
+ *
+ ******************************************************************************
+ This file contains routines that can be bound to a Postgres backend and
+ called by the backend in the process of processing queries. The calling
+ format for these routines is dictated by Postgres architecture.
+******************************************************************************/
+
+#include "postgres.h"
+
+#include <float.h>
+
+#include "access/gist.h"
+#include "access/stratnum.h"
+#include "fmgr.h"
+
+#include "segdata.h"
+
+
+#define DatumGetSegP(X) ((SEG *) DatumGetPointer(X))
+#define PG_GETARG_SEG_P(n) DatumGetSegP(PG_GETARG_DATUM(n))
+
+
+/*
+#define GIST_DEBUG
+#define GIST_QUERY_DEBUG
+*/
+
+PG_MODULE_MAGIC;
+
+/*
+ * Auxiliary data structure for picksplit method.
+ */
+typedef struct
+{
+ float center;
+ OffsetNumber index;
+ SEG *data;
+} gseg_picksplit_item;
+
+/*
+** Input/Output routines
+*/
+PG_FUNCTION_INFO_V1(seg_in);
+PG_FUNCTION_INFO_V1(seg_out);
+PG_FUNCTION_INFO_V1(seg_size);
+PG_FUNCTION_INFO_V1(seg_lower);
+PG_FUNCTION_INFO_V1(seg_upper);
+PG_FUNCTION_INFO_V1(seg_center);
+
+/*
+** GiST support methods
+*/
+PG_FUNCTION_INFO_V1(gseg_consistent);
+PG_FUNCTION_INFO_V1(gseg_compress);
+PG_FUNCTION_INFO_V1(gseg_decompress);
+PG_FUNCTION_INFO_V1(gseg_picksplit);
+PG_FUNCTION_INFO_V1(gseg_penalty);
+PG_FUNCTION_INFO_V1(gseg_union);
+PG_FUNCTION_INFO_V1(gseg_same);
+static Datum gseg_leaf_consistent(Datum key, Datum query, StrategyNumber strategy);
+static Datum gseg_internal_consistent(Datum key, Datum query, StrategyNumber strategy);
+static Datum gseg_binary_union(Datum r1, Datum r2, int *sizep);
+
+
+/*
+** R-tree support functions
+*/
+PG_FUNCTION_INFO_V1(seg_same);
+PG_FUNCTION_INFO_V1(seg_contains);
+PG_FUNCTION_INFO_V1(seg_contained);
+PG_FUNCTION_INFO_V1(seg_overlap);
+PG_FUNCTION_INFO_V1(seg_left);
+PG_FUNCTION_INFO_V1(seg_over_left);
+PG_FUNCTION_INFO_V1(seg_right);
+PG_FUNCTION_INFO_V1(seg_over_right);
+PG_FUNCTION_INFO_V1(seg_union);
+PG_FUNCTION_INFO_V1(seg_inter);
+static void rt_seg_size(SEG *a, float *size);
+
+/*
+** Various operators
+*/
+PG_FUNCTION_INFO_V1(seg_cmp);
+PG_FUNCTION_INFO_V1(seg_lt);
+PG_FUNCTION_INFO_V1(seg_le);
+PG_FUNCTION_INFO_V1(seg_gt);
+PG_FUNCTION_INFO_V1(seg_ge);
+PG_FUNCTION_INFO_V1(seg_different);
+
+/*
+** Auxiliary functions
+*/
+static int restore(char *s, float val, int n);
+
+
+/*****************************************************************************
+ * Input/Output functions
+ *****************************************************************************/
+
+Datum
+seg_in(PG_FUNCTION_ARGS)
+{
+ char *str = PG_GETARG_CSTRING(0);
+ SEG *result = palloc(sizeof(SEG));
+
+ seg_scanner_init(str);
+
+ if (seg_yyparse(result) != 0)
+ seg_yyerror(result, "bogus input");
+
+ seg_scanner_finish();
+
+ PG_RETURN_POINTER(result);
+}
+
+Datum
+seg_out(PG_FUNCTION_ARGS)
+{
+ SEG *seg = PG_GETARG_SEG_P(0);
+ char *result;
+ char *p;
+
+ p = result = (char *) palloc(40);
+
+ if (seg->l_ext == '>' || seg->l_ext == '<' || seg->l_ext == '~')
+ p += sprintf(p, "%c", seg->l_ext);
+
+ if (seg->lower == seg->upper && seg->l_ext == seg->u_ext)
+ {
+ /*
+ * indicates that this interval was built by seg_in off a single point
+ */
+ p += restore(p, seg->lower, seg->l_sigd);
+ }
+ else
+ {
+ if (seg->l_ext != '-')
+ {
+ /* print the lower boundary if exists */
+ p += restore(p, seg->lower, seg->l_sigd);
+ p += sprintf(p, " ");
+ }
+ p += sprintf(p, "..");
+ if (seg->u_ext != '-')
+ {
+ /* print the upper boundary if exists */
+ p += sprintf(p, " ");
+ if (seg->u_ext == '>' || seg->u_ext == '<' || seg->l_ext == '~')
+ p += sprintf(p, "%c", seg->u_ext);
+ p += restore(p, seg->upper, seg->u_sigd);
+ }
+ }
+
+ PG_RETURN_CSTRING(result);
+}
+
+Datum
+seg_center(PG_FUNCTION_ARGS)
+{
+ SEG *seg = PG_GETARG_SEG_P(0);
+
+ PG_RETURN_FLOAT4(((float) seg->lower + (float) seg->upper) / 2.0);
+}
+
+Datum
+seg_lower(PG_FUNCTION_ARGS)
+{
+ SEG *seg = PG_GETARG_SEG_P(0);
+
+ PG_RETURN_FLOAT4(seg->lower);
+}
+
+Datum
+seg_upper(PG_FUNCTION_ARGS)
+{
+ SEG *seg = PG_GETARG_SEG_P(0);
+
+ PG_RETURN_FLOAT4(seg->upper);
+}
+
+
+/*****************************************************************************
+ * GiST functions
+ *****************************************************************************/
+
+/*
+** The GiST Consistent method for segments
+** Should return false if for all data items x below entry,
+** the predicate x op query == false, where op is the oper
+** corresponding to strategy in the pg_amop table.
+*/
+Datum
+gseg_consistent(PG_FUNCTION_ARGS)
+{
+ GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+ Datum query = PG_GETARG_DATUM(1);
+ StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
+
+ /* Oid subtype = PG_GETARG_OID(3); */
+ bool *recheck = (bool *) PG_GETARG_POINTER(4);
+
+ /* All cases served by this function are exact */
+ *recheck = false;
+
+ /*
+ * if entry is not leaf, use gseg_internal_consistent, else use
+ * gseg_leaf_consistent
+ */
+ if (GIST_LEAF(entry))
+ return gseg_leaf_consistent(entry->key, query, strategy);
+ else
+ return gseg_internal_consistent(entry->key, query, strategy);
+}
+
+/*
+** The GiST Union method for segments
+** returns the minimal bounding seg that encloses all the entries in entryvec
+*/
+Datum
+gseg_union(PG_FUNCTION_ARGS)
+{
+ GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
+ int *sizep = (int *) PG_GETARG_POINTER(1);
+ int numranges,
+ i;
+ Datum out = 0;
+ Datum tmp;
+
+#ifdef GIST_DEBUG
+ fprintf(stderr, "union\n");
+#endif
+
+ numranges = entryvec->n;
+ tmp = entryvec->vector[0].key;
+ *sizep = sizeof(SEG);
+
+ for (i = 1; i < numranges; i++)
+ {
+ out = gseg_binary_union(tmp, entryvec->vector[i].key, sizep);
+ tmp = out;
+ }
+
+ PG_RETURN_DATUM(out);
+}
+
+/*
+** GiST Compress and Decompress methods for segments
+** do not do anything.
+*/
+Datum
+gseg_compress(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_POINTER(PG_GETARG_POINTER(0));
+}
+
+Datum
+gseg_decompress(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_POINTER(PG_GETARG_POINTER(0));
+}
+
+/*
+** The GiST Penalty method for segments
+** As in the R-tree paper, we use change in area as our penalty metric
+*/
+Datum
+gseg_penalty(PG_FUNCTION_ARGS)
+{
+ GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0);
+ GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1);
+ float *result = (float *) PG_GETARG_POINTER(2);
+ SEG *ud;
+ float tmp1,
+ tmp2;
+
+ ud = DatumGetSegP(DirectFunctionCall2(seg_union,
+ origentry->key,
+ newentry->key));
+ rt_seg_size(ud, &tmp1);
+ rt_seg_size(DatumGetSegP(origentry->key), &tmp2);
+ *result = tmp1 - tmp2;
+
+#ifdef GIST_DEBUG
+ fprintf(stderr, "penalty\n");
+ fprintf(stderr, "\t%g\n", *result);
+#endif
+
+ PG_RETURN_POINTER(result);
+}
+
+/*
+ * Compare function for gseg_picksplit_item: sort by center.
+ */
+static int
+gseg_picksplit_item_cmp(const void *a, const void *b)
+{
+ const gseg_picksplit_item *i1 = (const gseg_picksplit_item *) a;
+ const gseg_picksplit_item *i2 = (const gseg_picksplit_item *) b;
+
+ if (i1->center < i2->center)
+ return -1;
+ else if (i1->center == i2->center)
+ return 0;
+ else
+ return 1;
+}
+
+/*
+ * The GiST PickSplit method for segments
+ *
+ * We used to use Guttman's split algorithm here, but since the data is 1-D
+ * it's easier and more robust to just sort the segments by center-point and
+ * split at the middle.
+ */
+Datum
+gseg_picksplit(PG_FUNCTION_ARGS)
+{
+ GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
+ GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
+ int i;
+ SEG *seg,
+ *seg_l,
+ *seg_r;
+ gseg_picksplit_item *sort_items;
+ OffsetNumber *left,
+ *right;
+ OffsetNumber maxoff;
+ OffsetNumber firstright;
+
+#ifdef GIST_DEBUG
+ fprintf(stderr, "picksplit\n");
+#endif
+
+ /* Valid items in entryvec->vector[] are indexed 1..maxoff */
+ maxoff = entryvec->n - 1;
+
+ /*
+ * Prepare the auxiliary array and sort it.
+ */
+ sort_items = (gseg_picksplit_item *)
+ palloc(maxoff * sizeof(gseg_picksplit_item));
+ for (i = 1; i <= maxoff; i++)
+ {
+ seg = DatumGetSegP(entryvec->vector[i].key);
+ /* center calculation is done this way to avoid possible overflow */
+ sort_items[i - 1].center = seg->lower * 0.5f + seg->upper * 0.5f;
+ sort_items[i - 1].index = i;
+ sort_items[i - 1].data = seg;
+ }
+ qsort(sort_items, maxoff, sizeof(gseg_picksplit_item),
+ gseg_picksplit_item_cmp);
+
+ /* sort items below "firstright" will go into the left side */
+ firstright = maxoff / 2;
+
+ v->spl_left = (OffsetNumber *) palloc(maxoff * sizeof(OffsetNumber));
+ v->spl_right = (OffsetNumber *) palloc(maxoff * sizeof(OffsetNumber));
+ left = v->spl_left;
+ v->spl_nleft = 0;
+ right = v->spl_right;
+ v->spl_nright = 0;
+
+ /*
+ * Emit segments to the left output page, and compute its bounding box.
+ */
+ seg_l = (SEG *) palloc(sizeof(SEG));
+ memcpy(seg_l, sort_items[0].data, sizeof(SEG));
+ *left++ = sort_items[0].index;
+ v->spl_nleft++;
+ for (i = 1; i < firstright; i++)
+ {
+ Datum sortitem = PointerGetDatum(sort_items[i].data);
+
+ seg_l = DatumGetSegP(DirectFunctionCall2(seg_union,
+ PointerGetDatum(seg_l),
+ sortitem));
+ *left++ = sort_items[i].index;
+ v->spl_nleft++;
+ }
+
+ /*
+ * Likewise for the right page.
+ */
+ seg_r = (SEG *) palloc(sizeof(SEG));
+ memcpy(seg_r, sort_items[firstright].data, sizeof(SEG));
+ *right++ = sort_items[firstright].index;
+ v->spl_nright++;
+ for (i = firstright + 1; i < maxoff; i++)
+ {
+ Datum sortitem = PointerGetDatum(sort_items[i].data);
+
+ seg_r = DatumGetSegP(DirectFunctionCall2(seg_union,
+ PointerGetDatum(seg_r),
+ sortitem));
+ *right++ = sort_items[i].index;
+ v->spl_nright++;
+ }
+
+ v->spl_ldatum = PointerGetDatum(seg_l);
+ v->spl_rdatum = PointerGetDatum(seg_r);
+
+ PG_RETURN_POINTER(v);
+}
+
+/*
+** Equality methods
+*/
+Datum
+gseg_same(PG_FUNCTION_ARGS)
+{
+ bool *result = (bool *) PG_GETARG_POINTER(2);
+
+ if (DirectFunctionCall2(seg_same, PG_GETARG_DATUM(0), PG_GETARG_DATUM(1)))
+ *result = true;
+ else
+ *result = false;
+
+#ifdef GIST_DEBUG
+ fprintf(stderr, "same: %s\n", (*result ? "TRUE" : "FALSE"));
+#endif
+
+ PG_RETURN_POINTER(result);
+}
+
+/*
+** SUPPORT ROUTINES
+*/
+static Datum
+gseg_leaf_consistent(Datum key, Datum query, StrategyNumber strategy)
+{
+ Datum retval;
+
+#ifdef GIST_QUERY_DEBUG
+ fprintf(stderr, "leaf_consistent, %d\n", strategy);
+#endif
+
+ switch (strategy)
+ {
+ case RTLeftStrategyNumber:
+ retval = DirectFunctionCall2(seg_left, key, query);
+ break;
+ case RTOverLeftStrategyNumber:
+ retval = DirectFunctionCall2(seg_over_left, key, query);
+ break;
+ case RTOverlapStrategyNumber:
+ retval = DirectFunctionCall2(seg_overlap, key, query);
+ break;
+ case RTOverRightStrategyNumber:
+ retval = DirectFunctionCall2(seg_over_right, key, query);
+ break;
+ case RTRightStrategyNumber:
+ retval = DirectFunctionCall2(seg_right, key, query);
+ break;
+ case RTSameStrategyNumber:
+ retval = DirectFunctionCall2(seg_same, key, query);
+ break;
+ case RTContainsStrategyNumber:
+ case RTOldContainsStrategyNumber:
+ retval = DirectFunctionCall2(seg_contains, key, query);
+ break;
+ case RTContainedByStrategyNumber:
+ case RTOldContainedByStrategyNumber:
+ retval = DirectFunctionCall2(seg_contained, key, query);
+ break;
+ default:
+ retval = false;
+ }
+
+ PG_RETURN_DATUM(retval);
+}
+
+static Datum
+gseg_internal_consistent(Datum key, Datum query, StrategyNumber strategy)
+{
+ bool retval;
+
+#ifdef GIST_QUERY_DEBUG
+ fprintf(stderr, "internal_consistent, %d\n", strategy);
+#endif
+
+ switch (strategy)
+ {
+ case RTLeftStrategyNumber:
+ retval =
+ !DatumGetBool(DirectFunctionCall2(seg_over_right, key, query));
+ break;
+ case RTOverLeftStrategyNumber:
+ retval =
+ !DatumGetBool(DirectFunctionCall2(seg_right, key, query));
+ break;
+ case RTOverlapStrategyNumber:
+ retval =
+ DatumGetBool(DirectFunctionCall2(seg_overlap, key, query));
+ break;
+ case RTOverRightStrategyNumber:
+ retval =
+ !DatumGetBool(DirectFunctionCall2(seg_left, key, query));
+ break;
+ case RTRightStrategyNumber:
+ retval =
+ !DatumGetBool(DirectFunctionCall2(seg_over_left, key, query));
+ break;
+ case RTSameStrategyNumber:
+ case RTContainsStrategyNumber:
+ case RTOldContainsStrategyNumber:
+ retval =
+ DatumGetBool(DirectFunctionCall2(seg_contains, key, query));
+ break;
+ case RTContainedByStrategyNumber:
+ case RTOldContainedByStrategyNumber:
+ retval =
+ DatumGetBool(DirectFunctionCall2(seg_overlap, key, query));
+ break;
+ default:
+ retval = false;
+ }
+
+ PG_RETURN_BOOL(retval);
+}
+
+static Datum
+gseg_binary_union(Datum r1, Datum r2, int *sizep)
+{
+ Datum retval;
+
+ retval = DirectFunctionCall2(seg_union, r1, r2);
+ *sizep = sizeof(SEG);
+
+ return retval;
+}
+
+
+Datum
+seg_contains(PG_FUNCTION_ARGS)
+{
+ SEG *a = PG_GETARG_SEG_P(0);
+ SEG *b = PG_GETARG_SEG_P(1);
+
+ PG_RETURN_BOOL((a->lower <= b->lower) && (a->upper >= b->upper));
+}
+
+Datum
+seg_contained(PG_FUNCTION_ARGS)
+{
+ Datum a = PG_GETARG_DATUM(0);
+ Datum b = PG_GETARG_DATUM(1);
+
+ PG_RETURN_DATUM(DirectFunctionCall2(seg_contains, b, a));
+}
+
+/*****************************************************************************
+ * Operator class for R-tree indexing
+ *****************************************************************************/
+
+Datum
+seg_same(PG_FUNCTION_ARGS)
+{
+ int cmp = DatumGetInt32(DirectFunctionCall2(seg_cmp,
+ PG_GETARG_DATUM(0),
+ PG_GETARG_DATUM(1)));
+
+ PG_RETURN_BOOL(cmp == 0);
+}
+
+/* seg_overlap -- does a overlap b?
+ */
+Datum
+seg_overlap(PG_FUNCTION_ARGS)
+{
+ SEG *a = PG_GETARG_SEG_P(0);
+ SEG *b = PG_GETARG_SEG_P(1);
+
+ PG_RETURN_BOOL(((a->upper >= b->upper) && (a->lower <= b->upper)) ||
+ ((b->upper >= a->upper) && (b->lower <= a->upper)));
+}
+
+/* seg_over_left -- is the right edge of (a) located at or left of the right edge of (b)?
+ */
+Datum
+seg_over_left(PG_FUNCTION_ARGS)
+{
+ SEG *a = PG_GETARG_SEG_P(0);
+ SEG *b = PG_GETARG_SEG_P(1);
+
+ PG_RETURN_BOOL(a->upper <= b->upper);
+}
+
+/* seg_left -- is (a) entirely on the left of (b)?
+ */
+Datum
+seg_left(PG_FUNCTION_ARGS)
+{
+ SEG *a = PG_GETARG_SEG_P(0);
+ SEG *b = PG_GETARG_SEG_P(1);
+
+ PG_RETURN_BOOL(a->upper < b->lower);
+}
+
+/* seg_right -- is (a) entirely on the right of (b)?
+ */
+Datum
+seg_right(PG_FUNCTION_ARGS)
+{
+ SEG *a = PG_GETARG_SEG_P(0);
+ SEG *b = PG_GETARG_SEG_P(1);
+
+ PG_RETURN_BOOL(a->lower > b->upper);
+}
+
+/* seg_over_right -- is the left edge of (a) located at or right of the left edge of (b)?
+ */
+Datum
+seg_over_right(PG_FUNCTION_ARGS)
+{
+ SEG *a = PG_GETARG_SEG_P(0);
+ SEG *b = PG_GETARG_SEG_P(1);
+
+ PG_RETURN_BOOL(a->lower >= b->lower);
+}
+
+Datum
+seg_union(PG_FUNCTION_ARGS)
+{
+ SEG *a = PG_GETARG_SEG_P(0);
+ SEG *b = PG_GETARG_SEG_P(1);
+ SEG *n;
+
+ n = (SEG *) palloc(sizeof(*n));
+
+ /* take max of upper endpoints */
+ if (a->upper > b->upper)
+ {
+ n->upper = a->upper;
+ n->u_sigd = a->u_sigd;
+ n->u_ext = a->u_ext;
+ }
+ else
+ {
+ n->upper = b->upper;
+ n->u_sigd = b->u_sigd;
+ n->u_ext = b->u_ext;
+ }
+
+ /* take min of lower endpoints */
+ if (a->lower < b->lower)
+ {
+ n->lower = a->lower;
+ n->l_sigd = a->l_sigd;
+ n->l_ext = a->l_ext;
+ }
+ else
+ {
+ n->lower = b->lower;
+ n->l_sigd = b->l_sigd;
+ n->l_ext = b->l_ext;
+ }
+
+ PG_RETURN_POINTER(n);
+}
+
+Datum
+seg_inter(PG_FUNCTION_ARGS)
+{
+ SEG *a = PG_GETARG_SEG_P(0);
+ SEG *b = PG_GETARG_SEG_P(1);
+ SEG *n;
+
+ n = (SEG *) palloc(sizeof(*n));
+
+ /* take min of upper endpoints */
+ if (a->upper < b->upper)
+ {
+ n->upper = a->upper;
+ n->u_sigd = a->u_sigd;
+ n->u_ext = a->u_ext;
+ }
+ else
+ {
+ n->upper = b->upper;
+ n->u_sigd = b->u_sigd;
+ n->u_ext = b->u_ext;
+ }
+
+ /* take max of lower endpoints */
+ if (a->lower > b->lower)
+ {
+ n->lower = a->lower;
+ n->l_sigd = a->l_sigd;
+ n->l_ext = a->l_ext;
+ }
+ else
+ {
+ n->lower = b->lower;
+ n->l_sigd = b->l_sigd;
+ n->l_ext = b->l_ext;
+ }
+
+ PG_RETURN_POINTER(n);
+}
+
+static void
+rt_seg_size(SEG *a, float *size)
+{
+ if (a == (SEG *) NULL || a->upper <= a->lower)
+ *size = 0.0;
+ else
+ *size = (float) Abs(a->upper - a->lower);
+}
+
+Datum
+seg_size(PG_FUNCTION_ARGS)
+{
+ SEG *seg = PG_GETARG_SEG_P(0);
+
+ PG_RETURN_FLOAT4((float) Abs(seg->upper - seg->lower));
+}
+
+
+/*****************************************************************************
+ * Miscellaneous operators
+ *****************************************************************************/
+Datum
+seg_cmp(PG_FUNCTION_ARGS)
+{
+ SEG *a = PG_GETARG_SEG_P(0);
+ SEG *b = PG_GETARG_SEG_P(1);
+
+ /*
+ * First compare on lower boundary position
+ */
+ if (a->lower < b->lower)
+ PG_RETURN_INT32(-1);
+ if (a->lower > b->lower)
+ PG_RETURN_INT32(1);
+
+ /*
+ * a->lower == b->lower, so consider type of boundary.
+ *
+ * A '-' lower bound is < any other kind (this could only be relevant if
+ * -HUGE_VAL is used as a regular data value). A '<' lower bound is < any
+ * other kind except '-'. A '>' lower bound is > any other kind.
+ */
+ if (a->l_ext != b->l_ext)
+ {
+ if (a->l_ext == '-')
+ PG_RETURN_INT32(-1);
+ if (b->l_ext == '-')
+ PG_RETURN_INT32(1);
+ if (a->l_ext == '<')
+ PG_RETURN_INT32(-1);
+ if (b->l_ext == '<')
+ PG_RETURN_INT32(1);
+ if (a->l_ext == '>')
+ PG_RETURN_INT32(1);
+ if (b->l_ext == '>')
+ PG_RETURN_INT32(-1);
+ }
+
+ /*
+ * For other boundary types, consider # of significant digits first.
+ */
+ if (a->l_sigd < b->l_sigd) /* (a) is blurred and is likely to include (b) */
+ PG_RETURN_INT32(-1);
+ if (a->l_sigd > b->l_sigd) /* (a) is less blurred and is likely to be
+ * included in (b) */
+ PG_RETURN_INT32(1);
+
+ /*
+ * For same # of digits, an approximate boundary is more blurred than
+ * exact.
+ */
+ if (a->l_ext != b->l_ext)
+ {
+ if (a->l_ext == '~') /* (a) is approximate, while (b) is exact */
+ PG_RETURN_INT32(-1);
+ if (b->l_ext == '~')
+ PG_RETURN_INT32(1);
+ /* can't get here unless data is corrupt */
+ elog(ERROR, "bogus lower boundary types %d %d",
+ (int) a->l_ext, (int) b->l_ext);
+ }
+
+ /* at this point, the lower boundaries are identical */
+
+ /*
+ * First compare on upper boundary position
+ */
+ if (a->upper < b->upper)
+ PG_RETURN_INT32(-1);
+ if (a->upper > b->upper)
+ PG_RETURN_INT32(1);
+
+ /*
+ * a->upper == b->upper, so consider type of boundary.
+ *
+ * A '-' upper bound is > any other kind (this could only be relevant if
+ * HUGE_VAL is used as a regular data value). A '<' upper bound is < any
+ * other kind. A '>' upper bound is > any other kind except '-'.
+ */
+ if (a->u_ext != b->u_ext)
+ {
+ if (a->u_ext == '-')
+ PG_RETURN_INT32(1);
+ if (b->u_ext == '-')
+ PG_RETURN_INT32(-1);
+ if (a->u_ext == '<')
+ PG_RETURN_INT32(-1);
+ if (b->u_ext == '<')
+ PG_RETURN_INT32(1);
+ if (a->u_ext == '>')
+ PG_RETURN_INT32(1);
+ if (b->u_ext == '>')
+ PG_RETURN_INT32(-1);
+ }
+
+ /*
+ * For other boundary types, consider # of significant digits first. Note
+ * result here is converse of the lower-boundary case.
+ */
+ if (a->u_sigd < b->u_sigd) /* (a) is blurred and is likely to include (b) */
+ PG_RETURN_INT32(1);
+ if (a->u_sigd > b->u_sigd) /* (a) is less blurred and is likely to be
+ * included in (b) */
+ PG_RETURN_INT32(-1);
+
+ /*
+ * For same # of digits, an approximate boundary is more blurred than
+ * exact. Again, result is converse of lower-boundary case.
+ */
+ if (a->u_ext != b->u_ext)
+ {
+ if (a->u_ext == '~') /* (a) is approximate, while (b) is exact */
+ PG_RETURN_INT32(1);
+ if (b->u_ext == '~')
+ PG_RETURN_INT32(-1);
+ /* can't get here unless data is corrupt */
+ elog(ERROR, "bogus upper boundary types %d %d",
+ (int) a->u_ext, (int) b->u_ext);
+ }
+
+ PG_RETURN_INT32(0);
+}
+
+Datum
+seg_lt(PG_FUNCTION_ARGS)
+{
+ int cmp = DatumGetInt32(DirectFunctionCall2(seg_cmp,
+ PG_GETARG_DATUM(0),
+ PG_GETARG_DATUM(1)));
+
+ PG_RETURN_BOOL(cmp < 0);
+}
+
+Datum
+seg_le(PG_FUNCTION_ARGS)
+{
+ int cmp = DatumGetInt32(DirectFunctionCall2(seg_cmp,
+ PG_GETARG_DATUM(0),
+ PG_GETARG_DATUM(1)));
+
+ PG_RETURN_BOOL(cmp <= 0);
+}
+
+Datum
+seg_gt(PG_FUNCTION_ARGS)
+{
+ int cmp = DatumGetInt32(DirectFunctionCall2(seg_cmp,
+ PG_GETARG_DATUM(0),
+ PG_GETARG_DATUM(1)));
+
+ PG_RETURN_BOOL(cmp > 0);
+}
+
+Datum
+seg_ge(PG_FUNCTION_ARGS)
+{
+ int cmp = DatumGetInt32(DirectFunctionCall2(seg_cmp,
+ PG_GETARG_DATUM(0),
+ PG_GETARG_DATUM(1)));
+
+ PG_RETURN_BOOL(cmp >= 0);
+}
+
+
+Datum
+seg_different(PG_FUNCTION_ARGS)
+{
+ int cmp = DatumGetInt32(DirectFunctionCall2(seg_cmp,
+ PG_GETARG_DATUM(0),
+ PG_GETARG_DATUM(1)));
+
+ PG_RETURN_BOOL(cmp != 0);
+}
+
+
+
+/*****************************************************************************
+ * Auxiliary functions
+ *****************************************************************************/
+
+/*
+ * The purpose of this routine is to print the given floating point
+ * value with exactly n significant digits. Its behaviour
+ * is similar to %.ng except it prints 8.00 where %.ng would
+ * print 8. Returns the length of the string written at "result".
+ *
+ * Caller must provide a sufficiently large result buffer; 16 bytes
+ * should be enough for all known float implementations.
+ */
+static int
+restore(char *result, float val, int n)
+{
+ char buf[25] = {
+ '0', '0', '0', '0', '0',
+ '0', '0', '0', '0', '0',
+ '0', '0', '0', '0', '0',
+ '0', '0', '0', '0', '0',
+ '0', '0', '0', '0', '\0'
+ };
+ char *p;
+ int exp;
+ int i,
+ dp,
+ sign;
+
+ /*
+ * Put a cap on the number of significant digits to avoid garbage in the
+ * output and ensure we don't overrun the result buffer.
+ */
+ n = Min(n, FLT_DIG);
+
+ /* remember the sign */
+ sign = (val < 0 ? 1 : 0);
+
+ /* print, in %e style to start with */
+ sprintf(result, "%.*e", n - 1, val);
+
+ /* find the exponent */
+ p = strchr(result, 'e');
+
+ /* punt if we have 'inf' or similar */
+ if (p == NULL)
+ return strlen(result);
+
+ exp = atoi(p + 1);
+ if (exp == 0)
+ {
+ /* just truncate off the 'e+00' */
+ *p = '\0';
+ }
+ else
+ {
+ if (Abs(exp) <= 4)
+ {
+ /*
+ * remove the decimal point from the mantissa and write the digits
+ * to the buf array
+ */
+ for (p = result + sign, i = 10, dp = 0; *p != 'e'; p++, i++)
+ {
+ buf[i] = *p;
+ if (*p == '.')
+ {
+ dp = i--; /* skip the decimal point */
+ }
+ }
+ if (dp == 0)
+ dp = i--; /* no decimal point was found in the above
+ * for() loop */
+
+ if (exp > 0)
+ {
+ if (dp - 10 + exp >= n)
+ {
+ /*
+ * the decimal point is behind the last significant digit;
+ * the digits in between must be converted to the exponent
+ * and the decimal point placed after the first digit
+ */
+ exp = dp - 10 + exp - n;
+ buf[10 + n] = '\0';
+
+ /* insert the decimal point */
+ if (n > 1)
+ {
+ dp = 11;
+ for (i = 23; i > dp; i--)
+ buf[i] = buf[i - 1];
+ buf[dp] = '.';
+ }
+
+ /*
+ * adjust the exponent by the number of digits after the
+ * decimal point
+ */
+ if (n > 1)
+ sprintf(&buf[11 + n], "e%d", exp + n - 1);
+ else
+ sprintf(&buf[11], "e%d", exp + n - 1);
+
+ if (sign)
+ {
+ buf[9] = '-';
+ strcpy(result, &buf[9]);
+ }
+ else
+ strcpy(result, &buf[10]);
+ }
+ else
+ { /* insert the decimal point */
+ dp += exp;
+ for (i = 23; i > dp; i--)
+ buf[i] = buf[i - 1];
+ buf[11 + n] = '\0';
+ buf[dp] = '.';
+ if (sign)
+ {
+ buf[9] = '-';
+ strcpy(result, &buf[9]);
+ }
+ else
+ strcpy(result, &buf[10]);
+ }
+ }
+ else
+ { /* exp <= 0 */
+ dp += exp - 1;
+ buf[10 + n] = '\0';
+ buf[dp] = '.';
+ if (sign)
+ {
+ buf[dp - 2] = '-';
+ strcpy(result, &buf[dp - 2]);
+ }
+ else
+ strcpy(result, &buf[dp - 1]);
+ }
+ }
+
+ /* do nothing for Abs(exp) > 4; %e must be OK */
+ /* just get rid of zeroes after [eE]- and +zeroes after [Ee]. */
+
+ /* ... this is not done yet. */
+ }
+ return strlen(result);
+}
+
+
+/*
+** Miscellany
+*/
+
+/* find out the number of significant digits in a string representing
+ * a floating point number
+ */
+int
+significant_digits(const char *s)
+{
+ const char *p = s;
+ int n,
+ c,
+ zeroes;
+
+ zeroes = 1;
+ /* skip leading zeroes and sign */
+ for (c = *p; (c == '0' || c == '+' || c == '-') && c != 0; c = *(++p));
+
+ /* skip decimal point and following zeroes */
+ for (c = *p; (c == '0' || c == '.') && c != 0; c = *(++p))
+ {
+ if (c != '.')
+ zeroes++;
+ }
+
+ /* count significant digits (n) */
+ for (c = *p, n = 0; c != 0; c = *(++p))
+ {
+ if (!((c >= '0' && c <= '9') || (c == '.')))
+ break;
+ if (c != '.')
+ n++;
+ }
+
+ if (!n)
+ return zeroes;
+
+ return n;
+}
diff --git a/contrib/seg/seg.control b/contrib/seg/seg.control
new file mode 100644
index 0000000..9ac3080
--- /dev/null
+++ b/contrib/seg/seg.control
@@ -0,0 +1,6 @@
+# seg extension
+comment = 'data type for representing line segments or floating-point intervals'
+default_version = '1.3'
+module_pathname = '$libdir/seg'
+relocatable = true
+trusted = true
diff --git a/contrib/seg/segdata.h b/contrib/seg/segdata.h
new file mode 100644
index 0000000..9488bf3
--- /dev/null
+++ b/contrib/seg/segdata.h
@@ -0,0 +1,24 @@
+/*
+ * contrib/seg/segdata.h
+ */
+typedef struct SEG
+{
+ float4 lower;
+ float4 upper;
+ char l_sigd;
+ char u_sigd;
+ char l_ext;
+ char u_ext;
+} SEG;
+
+/* in seg.c */
+extern int significant_digits(const char *str);
+
+/* in segscan.l */
+extern int seg_yylex(void);
+extern void seg_yyerror(SEG *result, const char *message) pg_attribute_noreturn();
+extern void seg_scanner_init(const char *str);
+extern void seg_scanner_finish(void);
+
+/* in segparse.y */
+extern int seg_yyparse(SEG *result);
diff --git a/contrib/seg/segparse.c b/contrib/seg/segparse.c
new file mode 100644
index 0000000..b5bcb70
--- /dev/null
+++ b/contrib/seg/segparse.c
@@ -0,0 +1,1610 @@
+/* A Bison parser, made by GNU Bison 3.3.2. */
+
+/* Bison implementation for Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation,
+ Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+ simplifying the original so-called "semantic" parser. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+/* Undocumented macros, especially those whose name start with YY_,
+ are private implementation details. Do not rely on them. */
+
+/* Identify Bison output. */
+#define YYBISON 1
+
+/* Bison version. */
+#define YYBISON_VERSION "3.3.2"
+
+/* Skeleton name. */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers. */
+#define YYPURE 0
+
+/* Push parsers. */
+#define YYPUSH 0
+
+/* Pull parsers. */
+#define YYPULL 1
+
+
+/* Substitute the variable and function names. */
+#define yyparse seg_yyparse
+#define yylex seg_yylex
+#define yyerror seg_yyerror
+#define yydebug seg_yydebug
+#define yynerrs seg_yynerrs
+
+#define yylval seg_yylval
+#define yychar seg_yychar
+
+/* First part of user prologue. */
+#line 1 "segparse.y" /* yacc.c:337 */
+
+/* contrib/seg/segparse.y */
+
+#include "postgres.h"
+
+#include <math.h>
+
+#include "fmgr.h"
+#include "utils/builtins.h"
+
+#include "segdata.h"
+
+/*
+ * Bison doesn't allocate anything that needs to live across parser calls,
+ * so we can easily have it use palloc instead of malloc. This prevents
+ * memory leaks if we error out during parsing. Note this only works with
+ * bison >= 2.0. However, in bison 1.875 the default is to use alloca()
+ * if possible, so there's not really much problem anyhow, at least if
+ * you're building with gcc.
+ */
+#define YYMALLOC palloc
+#define YYFREE pfree
+
+static float seg_atof(const char *value);
+
+static char strbuf[25] = {
+ '0', '0', '0', '0', '0',
+ '0', '0', '0', '0', '0',
+ '0', '0', '0', '0', '0',
+ '0', '0', '0', '0', '0',
+ '0', '0', '0', '0', '\0'
+};
+
+
+#line 113 "segparse.c" /* yacc.c:337 */
+# ifndef YY_NULLPTR
+# if defined __cplusplus
+# if 201103L <= __cplusplus
+# define YY_NULLPTR nullptr
+# else
+# define YY_NULLPTR 0
+# endif
+# else
+# define YY_NULLPTR ((void*)0)
+# endif
+# endif
+
+/* Enabling verbose error messages. */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+
+/* Debug traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+#if YYDEBUG
+extern int seg_yydebug;
+#endif
+
+/* Token type. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ enum yytokentype
+ {
+ SEGFLOAT = 258,
+ RANGE = 259,
+ PLUMIN = 260,
+ EXTENSION = 261
+ };
+#endif
+
+/* Value type. */
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+
+union YYSTYPE
+{
+#line 41 "segparse.y" /* yacc.c:352 */
+
+ struct BND {
+ float val;
+ char ext;
+ char sigd;
+ } bnd;
+ char * text;
+
+#line 169 "segparse.c" /* yacc.c:352 */
+};
+
+typedef union YYSTYPE YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+
+extern YYSTYPE seg_yylval;
+
+int seg_yyparse (SEG *result);
+
+
+
+
+
+#ifdef short
+# undef short
+#endif
+
+#ifdef YYTYPE_UINT8
+typedef YYTYPE_UINT8 yytype_uint8;
+#else
+typedef unsigned char yytype_uint8;
+#endif
+
+#ifdef YYTYPE_INT8
+typedef YYTYPE_INT8 yytype_int8;
+#else
+typedef signed char yytype_int8;
+#endif
+
+#ifdef YYTYPE_UINT16
+typedef YYTYPE_UINT16 yytype_uint16;
+#else
+typedef unsigned short yytype_uint16;
+#endif
+
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short yytype_int16;
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+# define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+# define YYSIZE_T size_t
+# elif ! defined YYSIZE_T
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# else
+# define YYSIZE_T unsigned
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+
+#ifndef YY_
+# if defined YYENABLE_NLS && YYENABLE_NLS
+# if ENABLE_NLS
+# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+# define YY_(Msgid) dgettext ("bison-runtime", Msgid)
+# endif
+# endif
+# ifndef YY_
+# define YY_(Msgid) Msgid
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE
+# if (defined __GNUC__ \
+ && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \
+ || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
+# define YY_ATTRIBUTE(Spec) __attribute__(Spec)
+# else
+# define YY_ATTRIBUTE(Spec) /* empty */
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE_PURE
+# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__))
+#endif
+
+#ifndef YY_ATTRIBUTE_UNUSED
+# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
+#endif
+
+/* Suppress unused-variable warnings by "using" E. */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(E) ((void) (E))
+#else
+# define YYUSE(E) /* empty */
+#endif
+
+#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
+/* Suppress an incorrect diagnostic about yylval being uninitialized. */
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+ _Pragma ("GCC diagnostic push") \
+ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
+ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
+ _Pragma ("GCC diagnostic pop")
+#else
+# define YY_INITIAL_VALUE(Value) Value
+#endif
+#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END
+#endif
+#ifndef YY_INITIAL_VALUE
+# define YY_INITIAL_VALUE(Value) /* Nothing. */
+#endif
+
+
+#if ! defined yyoverflow || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# ifdef YYSTACK_USE_ALLOCA
+# if YYSTACK_USE_ALLOCA
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# elif defined __BUILTIN_VA_ARG_INCR
+# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+# elif defined _AIX
+# define YYSTACK_ALLOC __alloca
+# elif defined _MSC_VER
+# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+# define alloca _alloca
+# else
+# define YYSTACK_ALLOC alloca
+# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+ /* Use EXIT_SUCCESS as a witness for stdlib.h. */
+# ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
+# endif
+# endif
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+ /* Pacify GCC's 'empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+# ifndef YYSTACK_ALLOC_MAXIMUM
+ /* The OS might guarantee only one guard page at the bottom of the stack,
+ and a page size can be as small as 4096 bytes. So we cannot safely
+ invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
+ to allow for a few compiler-allocated temporary stack slots. */
+# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+# endif
+# else
+# define YYSTACK_ALLOC YYMALLOC
+# define YYSTACK_FREE YYFREE
+# ifndef YYSTACK_ALLOC_MAXIMUM
+# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+# endif
+# if (defined __cplusplus && ! defined EXIT_SUCCESS \
+ && ! ((defined YYMALLOC || defined malloc) \
+ && (defined YYFREE || defined free)))
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
+# endif
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# if ! defined malloc && ! defined EXIT_SUCCESS
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# ifndef YYFREE
+# define YYFREE free
+# if ! defined free && ! defined EXIT_SUCCESS
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# endif
+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
+
+
+#if (! defined yyoverflow \
+ && (! defined __cplusplus \
+ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ yytype_int16 yyss_alloc;
+ YYSTYPE yyvs_alloc;
+};
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
+ + YYSTACK_GAP_MAXIMUM)
+
+# define YYCOPY_NEEDED 1
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
+ Stack = &yyptr->Stack_alloc; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (0)
+
+#endif
+
+#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
+/* Copy COUNT objects from SRC to DST. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if defined __GNUC__ && 1 < __GNUC__
+# define YYCOPY(Dst, Src, Count) \
+ __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
+# else
+# define YYCOPY(Dst, Src, Count) \
+ do \
+ { \
+ YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (Dst)[yyi] = (Src)[yyi]; \
+ } \
+ while (0)
+# endif
+# endif
+#endif /* !YYCOPY_NEEDED */
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 8
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST 12
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 7
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 4
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 9
+/* YYNSTATES -- Number of states. */
+#define YYNSTATES 14
+
+#define YYUNDEFTOK 2
+#define YYMAXUTOK 261
+
+/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
+ as returned by yylex, with out-of-bounds checking. */
+#define YYTRANSLATE(YYX) \
+ ((unsigned) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
+ as returned by yylex. */
+static const yytype_uint8 yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
+ 5, 6
+};
+
+#if YYDEBUG
+ /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
+static const yytype_uint8 yyrline[] =
+{
+ 0, 61, 61, 73, 91, 101, 111, 119, 128, 139
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || 0
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+ "$end", "error", "$undefined", "SEGFLOAT", "RANGE", "PLUMIN",
+ "EXTENSION", "$accept", "range", "boundary", "deviation", YY_NULLPTR
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[NUM] -- (External) token number corresponding to the
+ (internal) symbol number NUM (which must be that of a token). */
+static const yytype_uint16 yytoknum[] =
+{
+ 0, 256, 257, 258, 259, 260, 261
+};
+# endif
+
+#define YYPACT_NINF -3
+
+#define yypact_value_is_default(Yystate) \
+ (!!((Yystate) == (-3)))
+
+#define YYTABLE_NINF -1
+
+#define yytable_value_is_error(Yytable_value) \
+ 0
+
+ /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+static const yytype_int8 yypact[] =
+{
+ -1, -3, 3, 1, 8, 6, -3, -3, -3, 3,
+ 9, -3, -3, -3
+};
+
+ /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
+ Performed when YYTABLE does not specify something else to do. Zero
+ means the default is an error. */
+static const yytype_uint8 yydefact[] =
+{
+ 0, 7, 0, 0, 0, 6, 5, 8, 1, 4,
+ 0, 3, 9, 2
+};
+
+ /* YYPGOTO[NTERM-NUM]. */
+static const yytype_int8 yypgoto[] =
+{
+ -3, -3, -2, -3
+};
+
+ /* YYDEFGOTO[NTERM-NUM]. */
+static const yytype_int8 yydefgoto[] =
+{
+ -1, 4, 5, 13
+};
+
+ /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule whose
+ number is the opposite. If YYTABLE_NINF, syntax error. */
+static const yytype_uint8 yytable[] =
+{
+ 6, 0, 1, 2, 7, 3, 1, 11, 8, 3,
+ 9, 10, 12
+};
+
+static const yytype_int8 yycheck[] =
+{
+ 2, -1, 3, 4, 3, 6, 3, 9, 0, 6,
+ 4, 5, 3
+};
+
+ /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
+static const yytype_uint8 yystos[] =
+{
+ 0, 3, 4, 6, 8, 9, 9, 3, 0, 4,
+ 5, 9, 3, 10
+};
+
+ /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const yytype_uint8 yyr1[] =
+{
+ 0, 7, 8, 8, 8, 8, 8, 9, 9, 10
+};
+
+ /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
+static const yytype_uint8 yyr2[] =
+{
+ 0, 2, 3, 3, 2, 2, 1, 1, 2, 1
+};
+
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY (-2)
+#define YYEOF 0
+
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrorlab
+
+
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+ do \
+ if (yychar == YYEMPTY) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ YYPOPSTACK (yylen); \
+ yystate = *yyssp; \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror (result, YY_("syntax error: cannot back up")); \
+ YYERROR; \
+ } \
+ while (0)
+
+/* Error token number */
+#define YYTERROR 1
+#define YYERRCODE 256
+
+
+
+/* Enable debugging if requested. */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (0)
+
+/* This macro is provided for backward compatibility. */
+#ifndef YY_LOCATION_PRINT
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+#endif
+
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yy_symbol_print (stderr, \
+ Type, Value, result); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (0)
+
+
+/*-----------------------------------.
+| Print this symbol's value on YYO. |
+`-----------------------------------*/
+
+static void
+yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, SEG *result)
+{
+ FILE *yyoutput = yyo;
+ YYUSE (yyoutput);
+ YYUSE (result);
+ if (!yyvaluep)
+ return;
+# ifdef YYPRINT
+ if (yytype < YYNTOKENS)
+ YYPRINT (yyo, yytoknum[yytype], *yyvaluep);
+# endif
+ YYUSE (yytype);
+}
+
+
+/*---------------------------.
+| Print this symbol on YYO. |
+`---------------------------*/
+
+static void
+yy_symbol_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, SEG *result)
+{
+ YYFPRINTF (yyo, "%s %s (",
+ yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
+
+ yy_symbol_value_print (yyo, yytype, yyvaluep, result);
+ YYFPRINTF (yyo, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included). |
+`------------------------------------------------------------------*/
+
+static void
+yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
+{
+ YYFPRINTF (stderr, "Stack now");
+ for (; yybottom <= yytop; yybottom++)
+ {
+ int yybot = *yybottom;
+ YYFPRINTF (stderr, " %d", yybot);
+ }
+ YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top) \
+do { \
+ if (yydebug) \
+ yy_stack_print ((Bottom), (Top)); \
+} while (0)
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced. |
+`------------------------------------------------*/
+
+static void
+yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, SEG *result)
+{
+ unsigned long yylno = yyrline[yyrule];
+ int yynrhs = yyr2[yyrule];
+ int yyi;
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+ yyrule - 1, yylno);
+ /* The symbols being reduced. */
+ for (yyi = 0; yyi < yynrhs; yyi++)
+ {
+ YYFPRINTF (stderr, " $%d = ", yyi + 1);
+ yy_symbol_print (stderr,
+ yystos[yyssp[yyi + 1 - yynrhs]],
+ &yyvsp[(yyi + 1) - (yynrhs)]
+ , result);
+ YYFPRINTF (stderr, "\n");
+ }
+}
+
+# define YY_REDUCE_PRINT(Rule) \
+do { \
+ if (yydebug) \
+ yy_reduce_print (yyssp, yyvsp, Rule, result); \
+} while (0)
+
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+# if defined __GLIBC__ && defined _STRING_H
+# define yystrlen strlen
+# else
+/* Return the length of YYSTR. */
+static YYSIZE_T
+yystrlen (const char *yystr)
+{
+ YYSIZE_T yylen;
+ for (yylen = 0; yystr[yylen]; yylen++)
+ continue;
+ return yylen;
+}
+# endif
+# endif
+
+# ifndef yystpcpy
+# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
+# define yystpcpy stpcpy
+# else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+ YYDEST. */
+static char *
+yystpcpy (char *yydest, const char *yysrc)
+{
+ char *yyd = yydest;
+ const char *yys = yysrc;
+
+ while ((*yyd++ = *yys++) != '\0')
+ continue;
+
+ return yyd - 1;
+}
+# endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+ quotes and backslashes, so that it's suitable for yyerror. The
+ heuristic is that double-quoting is unnecessary unless the string
+ contains an apostrophe, a comma, or backslash (other than
+ backslash-backslash). YYSTR is taken from yytname. If YYRES is
+ null, do not copy; instead, return the length of what the result
+ would have been. */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+ if (*yystr == '"')
+ {
+ YYSIZE_T yyn = 0;
+ char const *yyp = yystr;
+
+ for (;;)
+ switch (*++yyp)
+ {
+ case '\'':
+ case ',':
+ goto do_not_strip_quotes;
+
+ case '\\':
+ if (*++yyp != '\\')
+ goto do_not_strip_quotes;
+ else
+ goto append;
+
+ append:
+ default:
+ if (yyres)
+ yyres[yyn] = *yyp;
+ yyn++;
+ break;
+
+ case '"':
+ if (yyres)
+ yyres[yyn] = '\0';
+ return yyn;
+ }
+ do_not_strip_quotes: ;
+ }
+
+ if (! yyres)
+ return yystrlen (yystr);
+
+ return (YYSIZE_T) (yystpcpy (yyres, yystr) - yyres);
+}
+# endif
+
+/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
+ about the unexpected token YYTOKEN for the state stack whose top is
+ YYSSP.
+
+ Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is
+ not large enough to hold the message. In that case, also set
+ *YYMSG_ALLOC to the required number of bytes. Return 2 if the
+ required number of bytes is too large to store. */
+static int
+yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
+ yytype_int16 *yyssp, int yytoken)
+{
+ YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
+ YYSIZE_T yysize = yysize0;
+ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+ /* Internationalized format string. */
+ const char *yyformat = YY_NULLPTR;
+ /* Arguments of yyformat. */
+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+ /* Number of reported tokens (one for the "unexpected", one per
+ "expected"). */
+ int yycount = 0;
+
+ /* There are many possibilities here to consider:
+ - If this state is a consistent state with a default action, then
+ the only way this function was invoked is if the default action
+ is an error action. In that case, don't check for expected
+ tokens because there are none.
+ - The only way there can be no lookahead present (in yychar) is if
+ this state is a consistent state with a default action. Thus,
+ detecting the absence of a lookahead is sufficient to determine
+ that there is no unexpected or expected token to report. In that
+ case, just report a simple "syntax error".
+ - Don't assume there isn't a lookahead just because this state is a
+ consistent state with a default action. There might have been a
+ previous inconsistent state, consistent state with a non-default
+ action, or user semantic action that manipulated yychar.
+ - Of course, the expected token list depends on states to have
+ correct lookahead information, and it depends on the parser not
+ to perform extra reductions after fetching a lookahead from the
+ scanner and before detecting a syntax error. Thus, state merging
+ (from LALR or IELR) and default reductions corrupt the expected
+ token list. However, the list is correct for canonical LR with
+ one exception: it will still contain any token that will not be
+ accepted due to an error action in a later state.
+ */
+ if (yytoken != YYEMPTY)
+ {
+ int yyn = yypact[*yyssp];
+ yyarg[yycount++] = yytname[yytoken];
+ if (!yypact_value_is_default (yyn))
+ {
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. In other words, skip the first -YYN actions for
+ this state because they are default actions. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn + 1;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yyx;
+
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
+ && !yytable_value_is_error (yytable[yyx + yyn]))
+ {
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+ {
+ yycount = 1;
+ yysize = yysize0;
+ break;
+ }
+ yyarg[yycount++] = yytname[yyx];
+ {
+ YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
+ if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)
+ yysize = yysize1;
+ else
+ return 2;
+ }
+ }
+ }
+ }
+
+ switch (yycount)
+ {
+# define YYCASE_(N, S) \
+ case N: \
+ yyformat = S; \
+ break
+ default: /* Avoid compiler warnings. */
+ YYCASE_(0, YY_("syntax error"));
+ YYCASE_(1, YY_("syntax error, unexpected %s"));
+ YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
+ YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
+ YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
+ YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
+# undef YYCASE_
+ }
+
+ {
+ YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
+ if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)
+ yysize = yysize1;
+ else
+ return 2;
+ }
+
+ if (*yymsg_alloc < yysize)
+ {
+ *yymsg_alloc = 2 * yysize;
+ if (! (yysize <= *yymsg_alloc
+ && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
+ *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
+ return 1;
+ }
+
+ /* Avoid sprintf, as that infringes on the user's name space.
+ Don't have undefined behavior even if the translation
+ produced a string with the wrong number of "%s"s. */
+ {
+ char *yyp = *yymsg;
+ int yyi = 0;
+ while ((*yyp = *yyformat) != '\0')
+ if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
+ {
+ yyp += yytnamerr (yyp, yyarg[yyi++]);
+ yyformat += 2;
+ }
+ else
+ {
+ yyp++;
+ yyformat++;
+ }
+ }
+ return 0;
+}
+#endif /* YYERROR_VERBOSE */
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, SEG *result)
+{
+ YYUSE (yyvaluep);
+ YYUSE (result);
+ if (!yymsg)
+ yymsg = "Deleting";
+ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ YYUSE (yytype);
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+}
+
+
+
+
+/* The lookahead symbol. */
+int yychar;
+
+/* The semantic value of the lookahead symbol. */
+YYSTYPE yylval;
+/* Number of syntax errors so far. */
+int yynerrs;
+
+
+/*----------.
+| yyparse. |
+`----------*/
+
+int
+yyparse (SEG *result)
+{
+ int yystate;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+
+ /* The stacks and their tools:
+ 'yyss': related to states.
+ 'yyvs': related to semantic values.
+
+ Refer to the stacks through separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ yytype_int16 yyssa[YYINITDEPTH];
+ yytype_int16 *yyss;
+ yytype_int16 *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs;
+ YYSTYPE *yyvsp;
+
+ YYSIZE_T yystacksize;
+
+ int yyn;
+ int yyresult;
+ /* Lookahead token as an internal (translated) token number. */
+ int yytoken = 0;
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+
+#if YYERROR_VERBOSE
+ /* Buffer for error messages, and its allocated size. */
+ char yymsgbuf[128];
+ char *yymsg = yymsgbuf;
+ YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
+
+#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
+
+ /* The number of symbols on the RHS of the reduced rule.
+ Keep to zero when no symbol should be popped. */
+ int yylen = 0;
+
+ yyssp = yyss = yyssa;
+ yyvsp = yyvs = yyvsa;
+ yystacksize = YYINITDEPTH;
+
+ YYDPRINTF ((stderr, "Starting parse\n"));
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+ goto yysetstate;
+
+
+/*------------------------------------------------------------.
+| yynewstate -- push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. So pushing a state here evens the stacks. */
+ yyssp++;
+
+
+/*--------------------------------------------------------------------.
+| yynewstate -- set current state (the top of the stack) to yystate. |
+`--------------------------------------------------------------------*/
+yysetstate:
+ *yyssp = (yytype_int16) yystate;
+
+ if (yyss + yystacksize - 1 <= yyssp)
+#if !defined yyoverflow && !defined YYSTACK_RELOCATE
+ goto yyexhaustedlab;
+#else
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYSIZE_T yysize = (YYSIZE_T) (yyssp - yyss + 1);
+
+# if defined yyoverflow
+ {
+ /* Give user a chance to reallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ yytype_int16 *yyss1 = yyss;
+
+ /* Each stack pointer address is followed by the size of the
+ data in use in that stack, in bytes. This used to be a
+ conditional around just the two extra args, but that might
+ be undefined if yyoverflow is a macro. */
+ yyoverflow (YY_("memory exhausted"),
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+ &yystacksize);
+ yyss = yyss1;
+ yyvs = yyvs1;
+ }
+# else /* defined YYSTACK_RELOCATE */
+ /* Extend the stack our own way. */
+ if (YYMAXDEPTH <= yystacksize)
+ goto yyexhaustedlab;
+ yystacksize *= 2;
+ if (YYMAXDEPTH < yystacksize)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ yytype_int16 *yyss1 = yyss;
+ union yyalloc *yyptr =
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ if (! yyptr)
+ goto yyexhaustedlab;
+ YYSTACK_RELOCATE (yyss_alloc, yyss);
+ YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE (yyss1);
+ }
+# endif
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;
+
+ YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+ (unsigned long) yystacksize));
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ YYABORT;
+ }
+#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
+
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+ if (yystate == YYFINAL)
+ YYACCEPT;
+
+ goto yybackup;
+
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+ /* Do appropriate processing given the current state. Read a
+ lookahead token if we need one and don't already have one. */
+
+ /* First try to decide what to do without reference to lookahead token. */
+ yyn = yypact[yystate];
+ if (yypact_value_is_default (yyn))
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF ((stderr, "Reading a token: "));
+ yychar = yylex ();
+ }
+
+ if (yychar <= YYEOF)
+ {
+ yychar = yytoken = YYEOF;
+ YYDPRINTF ((stderr, "Now at end of input.\n"));
+ }
+ else
+ {
+ yytoken = YYTRANSLATE (yychar);
+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+ }
+
+ /* If the proper action on seeing token YYTOKEN is to reduce or to
+ detect an error, take that action. */
+ yyn += yytoken;
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+ goto yydefault;
+ yyn = yytable[yyn];
+ if (yyn <= 0)
+ {
+ if (yytable_value_is_error (yyn))
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ /* Shift the lookahead token. */
+ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+ /* Discard the shifted token. */
+ yychar = YYEMPTY;
+
+ yystate = yyn;
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ *++yyvsp = yylval;
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+
+ goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state. |
+`-----------------------------------------------------------*/
+yydefault:
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- do a reduction. |
+`-----------------------------*/
+yyreduce:
+ /* yyn is the number of a rule to reduce with. */
+ yylen = yyr2[yyn];
+
+ /* If YYLEN is nonzero, implement the default value of the action:
+ '$$ = $1'.
+
+ Otherwise, the following line sets YYVAL to garbage.
+ This behavior is undocumented and Bison
+ users should not rely upon it. Assigning to YYVAL
+ unconditionally makes the parser a bit smaller, and it avoids a
+ GCC warning that YYVAL may be used uninitialized. */
+ yyval = yyvsp[1-yylen];
+
+
+ YY_REDUCE_PRINT (yyn);
+ switch (yyn)
+ {
+ case 2:
+#line 62 "segparse.y" /* yacc.c:1652 */
+ {
+ result->lower = (yyvsp[-2].bnd).val - (yyvsp[0].bnd).val;
+ result->upper = (yyvsp[-2].bnd).val + (yyvsp[0].bnd).val;
+ sprintf(strbuf, "%g", result->lower);
+ result->l_sigd = Max(Min(6, significant_digits(strbuf)), Max((yyvsp[-2].bnd).sigd, (yyvsp[0].bnd).sigd));
+ sprintf(strbuf, "%g", result->upper);
+ result->u_sigd = Max(Min(6, significant_digits(strbuf)), Max((yyvsp[-2].bnd).sigd, (yyvsp[0].bnd).sigd));
+ result->l_ext = '\0';
+ result->u_ext = '\0';
+ }
+#line 1266 "segparse.c" /* yacc.c:1652 */
+ break;
+
+ case 3:
+#line 74 "segparse.y" /* yacc.c:1652 */
+ {
+ result->lower = (yyvsp[-2].bnd).val;
+ result->upper = (yyvsp[0].bnd).val;
+ if ( result->lower > result->upper ) {
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("swapped boundaries: %g is greater than %g",
+ result->lower, result->upper)));
+
+ YYERROR;
+ }
+ result->l_sigd = (yyvsp[-2].bnd).sigd;
+ result->u_sigd = (yyvsp[0].bnd).sigd;
+ result->l_ext = ( (yyvsp[-2].bnd).ext ? (yyvsp[-2].bnd).ext : '\0' );
+ result->u_ext = ( (yyvsp[0].bnd).ext ? (yyvsp[0].bnd).ext : '\0' );
+ }
+#line 1287 "segparse.c" /* yacc.c:1652 */
+ break;
+
+ case 4:
+#line 92 "segparse.y" /* yacc.c:1652 */
+ {
+ result->lower = (yyvsp[-1].bnd).val;
+ result->upper = HUGE_VAL;
+ result->l_sigd = (yyvsp[-1].bnd).sigd;
+ result->u_sigd = 0;
+ result->l_ext = ( (yyvsp[-1].bnd).ext ? (yyvsp[-1].bnd).ext : '\0' );
+ result->u_ext = '-';
+ }
+#line 1300 "segparse.c" /* yacc.c:1652 */
+ break;
+
+ case 5:
+#line 102 "segparse.y" /* yacc.c:1652 */
+ {
+ result->lower = -HUGE_VAL;
+ result->upper = (yyvsp[0].bnd).val;
+ result->l_sigd = 0;
+ result->u_sigd = (yyvsp[0].bnd).sigd;
+ result->l_ext = '-';
+ result->u_ext = ( (yyvsp[0].bnd).ext ? (yyvsp[0].bnd).ext : '\0' );
+ }
+#line 1313 "segparse.c" /* yacc.c:1652 */
+ break;
+
+ case 6:
+#line 112 "segparse.y" /* yacc.c:1652 */
+ {
+ result->lower = result->upper = (yyvsp[0].bnd).val;
+ result->l_sigd = result->u_sigd = (yyvsp[0].bnd).sigd;
+ result->l_ext = result->u_ext = ( (yyvsp[0].bnd).ext ? (yyvsp[0].bnd).ext : '\0' );
+ }
+#line 1323 "segparse.c" /* yacc.c:1652 */
+ break;
+
+ case 7:
+#line 120 "segparse.y" /* yacc.c:1652 */
+ {
+ /* temp variable avoids a gcc 3.3.x bug on Sparc64 */
+ float val = seg_atof((yyvsp[0].text));
+
+ (yyval.bnd).ext = '\0';
+ (yyval.bnd).sigd = significant_digits((yyvsp[0].text));
+ (yyval.bnd).val = val;
+ }
+#line 1336 "segparse.c" /* yacc.c:1652 */
+ break;
+
+ case 8:
+#line 129 "segparse.y" /* yacc.c:1652 */
+ {
+ /* temp variable avoids a gcc 3.3.x bug on Sparc64 */
+ float val = seg_atof((yyvsp[0].text));
+
+ (yyval.bnd).ext = (yyvsp[-1].text)[0];
+ (yyval.bnd).sigd = significant_digits((yyvsp[0].text));
+ (yyval.bnd).val = val;
+ }
+#line 1349 "segparse.c" /* yacc.c:1652 */
+ break;
+
+ case 9:
+#line 140 "segparse.y" /* yacc.c:1652 */
+ {
+ /* temp variable avoids a gcc 3.3.x bug on Sparc64 */
+ float val = seg_atof((yyvsp[0].text));
+
+ (yyval.bnd).ext = '\0';
+ (yyval.bnd).sigd = significant_digits((yyvsp[0].text));
+ (yyval.bnd).val = val;
+ }
+#line 1362 "segparse.c" /* yacc.c:1652 */
+ break;
+
+
+#line 1366 "segparse.c" /* yacc.c:1652 */
+ default: break;
+ }
+ /* User semantic actions sometimes alter yychar, and that requires
+ that yytoken be updated with the new translation. We take the
+ approach of translating immediately before every use of yytoken.
+ One alternative is translating here after every semantic action,
+ but that translation would be missed if the semantic action invokes
+ YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
+ if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an
+ incorrect destructor might then be invoked immediately. In the
+ case of YYERROR or YYBACKUP, subsequent parser actions might lead
+ to an incorrect destructor call or verbose syntax error message
+ before the lookahead is translated. */
+ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+
+ *++yyvsp = yyval;
+
+ /* Now 'shift' the result of the reduction. Determine what state
+ that goes to, based on the state we popped back to and the rule
+ number reduced by. */
+ {
+ const int yylhs = yyr1[yyn] - YYNTOKENS;
+ const int yyi = yypgoto[yylhs] + *yyssp;
+ yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp
+ ? yytable[yyi]
+ : yydefgoto[yylhs]);
+ }
+
+ goto yynewstate;
+
+
+/*--------------------------------------.
+| yyerrlab -- here on detecting error. |
+`--------------------------------------*/
+yyerrlab:
+ /* Make sure we have latest lookahead translation. See comments at
+ user semantic actions for why this is necessary. */
+ yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
+
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+#if ! YYERROR_VERBOSE
+ yyerror (result, YY_("syntax error"));
+#else
+# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
+ yyssp, yytoken)
+ {
+ char const *yymsgp = YY_("syntax error");
+ int yysyntax_error_status;
+ yysyntax_error_status = YYSYNTAX_ERROR;
+ if (yysyntax_error_status == 0)
+ yymsgp = yymsg;
+ else if (yysyntax_error_status == 1)
+ {
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+ yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
+ if (!yymsg)
+ {
+ yymsg = yymsgbuf;
+ yymsg_alloc = sizeof yymsgbuf;
+ yysyntax_error_status = 2;
+ }
+ else
+ {
+ yysyntax_error_status = YYSYNTAX_ERROR;
+ yymsgp = yymsg;
+ }
+ }
+ yyerror (result, yymsgp);
+ if (yysyntax_error_status == 2)
+ goto yyexhaustedlab;
+ }
+# undef YYSYNTAX_ERROR
+#endif
+ }
+
+
+
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse lookahead token after an
+ error, discard it. */
+
+ if (yychar <= YYEOF)
+ {
+ /* Return failure if at end of input. */
+ if (yychar == YYEOF)
+ YYABORT;
+ }
+ else
+ {
+ yydestruct ("Error: discarding",
+ yytoken, &yylval, result);
+ yychar = YYEMPTY;
+ }
+ }
+
+ /* Else will try to reuse lookahead token after shifting the error
+ token. */
+ goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR. |
+`---------------------------------------------------*/
+yyerrorlab:
+ /* Pacify compilers when the user code never invokes YYERROR and the
+ label yyerrorlab therefore never appears in user code. */
+ if (0)
+ YYERROR;
+
+ /* Do not reclaim the symbols of the rule whose action triggered
+ this YYERROR. */
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+ yystate = *yyssp;
+ goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR. |
+`-------------------------------------------------------------*/
+yyerrlab1:
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
+
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (!yypact_value_is_default (yyn))
+ {
+ yyn += YYTERROR;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+ {
+ yyn = yytable[yyn];
+ if (0 < yyn)
+ break;
+ }
+ }
+
+ /* Pop the current state because it cannot handle the error token. */
+ if (yyssp == yyss)
+ YYABORT;
+
+
+ yydestruct ("Error: popping",
+ yystos[yystate], yyvsp, result);
+ YYPOPSTACK (1);
+ yystate = *yyssp;
+ YY_STACK_PRINT (yyss, yyssp);
+ }
+
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ *++yyvsp = yylval;
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+
+
+ /* Shift the error token. */
+ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturn;
+
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yyresult = 1;
+ goto yyreturn;
+
+
+#if !defined yyoverflow || YYERROR_VERBOSE
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here. |
+`-------------------------------------------------*/
+yyexhaustedlab:
+ yyerror (result, YY_("memory exhausted"));
+ yyresult = 2;
+ /* Fall through. */
+#endif
+
+
+/*-----------------------------------------------------.
+| yyreturn -- parsing is finished, return the result. |
+`-----------------------------------------------------*/
+yyreturn:
+ if (yychar != YYEMPTY)
+ {
+ /* Make sure we have latest lookahead translation. See comments at
+ user semantic actions for why this is necessary. */
+ yytoken = YYTRANSLATE (yychar);
+ yydestruct ("Cleanup: discarding lookahead",
+ yytoken, &yylval, result);
+ }
+ /* Do not reclaim the symbols of the rule whose action triggered
+ this YYABORT or YYACCEPT. */
+ YYPOPSTACK (yylen);
+ YY_STACK_PRINT (yyss, yyssp);
+ while (yyssp != yyss)
+ {
+ yydestruct ("Cleanup: popping",
+ yystos[*yyssp], yyvsp, result);
+ YYPOPSTACK (1);
+ }
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE (yyss);
+#endif
+#if YYERROR_VERBOSE
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+#endif
+ return yyresult;
+}
+#line 150 "segparse.y" /* yacc.c:1918 */
+
+
+
+static float
+seg_atof(const char *value)
+{
+ Datum datum;
+
+ datum = DirectFunctionCall1(float4in, CStringGetDatum(value));
+ return DatumGetFloat4(datum);
+}
+
+
+#include "segscan.c"
diff --git a/contrib/seg/segparse.y b/contrib/seg/segparse.y
new file mode 100644
index 0000000..040cab3
--- /dev/null
+++ b/contrib/seg/segparse.y
@@ -0,0 +1,163 @@
+%{
+/* contrib/seg/segparse.y */
+
+#include "postgres.h"
+
+#include <math.h>
+
+#include "fmgr.h"
+#include "utils/builtins.h"
+
+#include "segdata.h"
+
+/*
+ * Bison doesn't allocate anything that needs to live across parser calls,
+ * so we can easily have it use palloc instead of malloc. This prevents
+ * memory leaks if we error out during parsing. Note this only works with
+ * bison >= 2.0. However, in bison 1.875 the default is to use alloca()
+ * if possible, so there's not really much problem anyhow, at least if
+ * you're building with gcc.
+ */
+#define YYMALLOC palloc
+#define YYFREE pfree
+
+static float seg_atof(const char *value);
+
+static char strbuf[25] = {
+ '0', '0', '0', '0', '0',
+ '0', '0', '0', '0', '0',
+ '0', '0', '0', '0', '0',
+ '0', '0', '0', '0', '0',
+ '0', '0', '0', '0', '\0'
+};
+
+%}
+
+/* BISON Declarations */
+%parse-param {SEG *result}
+%expect 0
+%name-prefix="seg_yy"
+
+%union {
+ struct BND {
+ float val;
+ char ext;
+ char sigd;
+ } bnd;
+ char * text;
+}
+%token <text> SEGFLOAT
+%token <text> RANGE
+%token <text> PLUMIN
+%token <text> EXTENSION
+%type <bnd> boundary
+%type <bnd> deviation
+%start range
+
+/* Grammar follows */
+%%
+
+
+range: boundary PLUMIN deviation
+ {
+ result->lower = $1.val - $3.val;
+ result->upper = $1.val + $3.val;
+ sprintf(strbuf, "%g", result->lower);
+ result->l_sigd = Max(Min(6, significant_digits(strbuf)), Max($1.sigd, $3.sigd));
+ sprintf(strbuf, "%g", result->upper);
+ result->u_sigd = Max(Min(6, significant_digits(strbuf)), Max($1.sigd, $3.sigd));
+ result->l_ext = '\0';
+ result->u_ext = '\0';
+ }
+
+ | boundary RANGE boundary
+ {
+ result->lower = $1.val;
+ result->upper = $3.val;
+ if ( result->lower > result->upper ) {
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("swapped boundaries: %g is greater than %g",
+ result->lower, result->upper)));
+
+ YYERROR;
+ }
+ result->l_sigd = $1.sigd;
+ result->u_sigd = $3.sigd;
+ result->l_ext = ( $1.ext ? $1.ext : '\0' );
+ result->u_ext = ( $3.ext ? $3.ext : '\0' );
+ }
+
+ | boundary RANGE
+ {
+ result->lower = $1.val;
+ result->upper = HUGE_VAL;
+ result->l_sigd = $1.sigd;
+ result->u_sigd = 0;
+ result->l_ext = ( $1.ext ? $1.ext : '\0' );
+ result->u_ext = '-';
+ }
+
+ | RANGE boundary
+ {
+ result->lower = -HUGE_VAL;
+ result->upper = $2.val;
+ result->l_sigd = 0;
+ result->u_sigd = $2.sigd;
+ result->l_ext = '-';
+ result->u_ext = ( $2.ext ? $2.ext : '\0' );
+ }
+
+ | boundary
+ {
+ result->lower = result->upper = $1.val;
+ result->l_sigd = result->u_sigd = $1.sigd;
+ result->l_ext = result->u_ext = ( $1.ext ? $1.ext : '\0' );
+ }
+ ;
+
+boundary: SEGFLOAT
+ {
+ /* temp variable avoids a gcc 3.3.x bug on Sparc64 */
+ float val = seg_atof($1);
+
+ $$.ext = '\0';
+ $$.sigd = significant_digits($1);
+ $$.val = val;
+ }
+ | EXTENSION SEGFLOAT
+ {
+ /* temp variable avoids a gcc 3.3.x bug on Sparc64 */
+ float val = seg_atof($2);
+
+ $$.ext = $1[0];
+ $$.sigd = significant_digits($2);
+ $$.val = val;
+ }
+ ;
+
+deviation: SEGFLOAT
+ {
+ /* temp variable avoids a gcc 3.3.x bug on Sparc64 */
+ float val = seg_atof($1);
+
+ $$.ext = '\0';
+ $$.sigd = significant_digits($1);
+ $$.val = val;
+ }
+ ;
+
+%%
+
+
+static float
+seg_atof(const char *value)
+{
+ Datum datum;
+
+ datum = DirectFunctionCall1(float4in, CStringGetDatum(value));
+ return DatumGetFloat4(datum);
+}
+
+
+#include "segscan.c"
diff --git a/contrib/seg/segscan.c b/contrib/seg/segscan.c
new file mode 100644
index 0000000..792cb64
--- /dev/null
+++ b/contrib/seg/segscan.c
@@ -0,0 +1,2095 @@
+#line 2 "segscan.c"
+
+#line 4 "segscan.c"
+
+#define YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define yy_create_buffer seg_yy_create_buffer
+#define yy_delete_buffer seg_yy_delete_buffer
+#define yy_scan_buffer seg_yy_scan_buffer
+#define yy_scan_string seg_yy_scan_string
+#define yy_scan_bytes seg_yy_scan_bytes
+#define yy_init_buffer seg_yy_init_buffer
+#define yy_flush_buffer seg_yy_flush_buffer
+#define yy_load_buffer_state seg_yy_load_buffer_state
+#define yy_switch_to_buffer seg_yy_switch_to_buffer
+#define yypush_buffer_state seg_yypush_buffer_state
+#define yypop_buffer_state seg_yypop_buffer_state
+#define yyensure_buffer_stack seg_yyensure_buffer_stack
+#define yy_flex_debug seg_yy_flex_debug
+#define yyin seg_yyin
+#define yyleng seg_yyleng
+#define yylex seg_yylex
+#define yylineno seg_yylineno
+#define yyout seg_yyout
+#define yyrestart seg_yyrestart
+#define yytext seg_yytext
+#define yywrap seg_yywrap
+#define yyalloc seg_yyalloc
+#define yyrealloc seg_yyrealloc
+#define yyfree seg_yyfree
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 6
+#define YY_FLEX_SUBMINOR_VERSION 4
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+#ifdef yy_create_buffer
+#define seg_yy_create_buffer_ALREADY_DEFINED
+#else
+#define yy_create_buffer seg_yy_create_buffer
+#endif
+
+#ifdef yy_delete_buffer
+#define seg_yy_delete_buffer_ALREADY_DEFINED
+#else
+#define yy_delete_buffer seg_yy_delete_buffer
+#endif
+
+#ifdef yy_scan_buffer
+#define seg_yy_scan_buffer_ALREADY_DEFINED
+#else
+#define yy_scan_buffer seg_yy_scan_buffer
+#endif
+
+#ifdef yy_scan_string
+#define seg_yy_scan_string_ALREADY_DEFINED
+#else
+#define yy_scan_string seg_yy_scan_string
+#endif
+
+#ifdef yy_scan_bytes
+#define seg_yy_scan_bytes_ALREADY_DEFINED
+#else
+#define yy_scan_bytes seg_yy_scan_bytes
+#endif
+
+#ifdef yy_init_buffer
+#define seg_yy_init_buffer_ALREADY_DEFINED
+#else
+#define yy_init_buffer seg_yy_init_buffer
+#endif
+
+#ifdef yy_flush_buffer
+#define seg_yy_flush_buffer_ALREADY_DEFINED
+#else
+#define yy_flush_buffer seg_yy_flush_buffer
+#endif
+
+#ifdef yy_load_buffer_state
+#define seg_yy_load_buffer_state_ALREADY_DEFINED
+#else
+#define yy_load_buffer_state seg_yy_load_buffer_state
+#endif
+
+#ifdef yy_switch_to_buffer
+#define seg_yy_switch_to_buffer_ALREADY_DEFINED
+#else
+#define yy_switch_to_buffer seg_yy_switch_to_buffer
+#endif
+
+#ifdef yypush_buffer_state
+#define seg_yypush_buffer_state_ALREADY_DEFINED
+#else
+#define yypush_buffer_state seg_yypush_buffer_state
+#endif
+
+#ifdef yypop_buffer_state
+#define seg_yypop_buffer_state_ALREADY_DEFINED
+#else
+#define yypop_buffer_state seg_yypop_buffer_state
+#endif
+
+#ifdef yyensure_buffer_stack
+#define seg_yyensure_buffer_stack_ALREADY_DEFINED
+#else
+#define yyensure_buffer_stack seg_yyensure_buffer_stack
+#endif
+
+#ifdef yylex
+#define seg_yylex_ALREADY_DEFINED
+#else
+#define yylex seg_yylex
+#endif
+
+#ifdef yyrestart
+#define seg_yyrestart_ALREADY_DEFINED
+#else
+#define yyrestart seg_yyrestart
+#endif
+
+#ifdef yylex_init
+#define seg_yylex_init_ALREADY_DEFINED
+#else
+#define yylex_init seg_yylex_init
+#endif
+
+#ifdef yylex_init_extra
+#define seg_yylex_init_extra_ALREADY_DEFINED
+#else
+#define yylex_init_extra seg_yylex_init_extra
+#endif
+
+#ifdef yylex_destroy
+#define seg_yylex_destroy_ALREADY_DEFINED
+#else
+#define yylex_destroy seg_yylex_destroy
+#endif
+
+#ifdef yyget_debug
+#define seg_yyget_debug_ALREADY_DEFINED
+#else
+#define yyget_debug seg_yyget_debug
+#endif
+
+#ifdef yyset_debug
+#define seg_yyset_debug_ALREADY_DEFINED
+#else
+#define yyset_debug seg_yyset_debug
+#endif
+
+#ifdef yyget_extra
+#define seg_yyget_extra_ALREADY_DEFINED
+#else
+#define yyget_extra seg_yyget_extra
+#endif
+
+#ifdef yyset_extra
+#define seg_yyset_extra_ALREADY_DEFINED
+#else
+#define yyset_extra seg_yyset_extra
+#endif
+
+#ifdef yyget_in
+#define seg_yyget_in_ALREADY_DEFINED
+#else
+#define yyget_in seg_yyget_in
+#endif
+
+#ifdef yyset_in
+#define seg_yyset_in_ALREADY_DEFINED
+#else
+#define yyset_in seg_yyset_in
+#endif
+
+#ifdef yyget_out
+#define seg_yyget_out_ALREADY_DEFINED
+#else
+#define yyget_out seg_yyget_out
+#endif
+
+#ifdef yyset_out
+#define seg_yyset_out_ALREADY_DEFINED
+#else
+#define yyset_out seg_yyset_out
+#endif
+
+#ifdef yyget_leng
+#define seg_yyget_leng_ALREADY_DEFINED
+#else
+#define yyget_leng seg_yyget_leng
+#endif
+
+#ifdef yyget_text
+#define seg_yyget_text_ALREADY_DEFINED
+#else
+#define yyget_text seg_yyget_text
+#endif
+
+#ifdef yyget_lineno
+#define seg_yyget_lineno_ALREADY_DEFINED
+#else
+#define yyget_lineno seg_yyget_lineno
+#endif
+
+#ifdef yyset_lineno
+#define seg_yyset_lineno_ALREADY_DEFINED
+#else
+#define yyset_lineno seg_yyset_lineno
+#endif
+
+#ifdef yywrap
+#define seg_yywrap_ALREADY_DEFINED
+#else
+#define yywrap seg_yywrap
+#endif
+
+#ifdef yyalloc
+#define seg_yyalloc_ALREADY_DEFINED
+#else
+#define yyalloc seg_yyalloc
+#endif
+
+#ifdef yyrealloc
+#define seg_yyrealloc_ALREADY_DEFINED
+#else
+#define yyrealloc seg_yyrealloc
+#endif
+
+#ifdef yyfree
+#define seg_yyfree_ALREADY_DEFINED
+#else
+#define yyfree seg_yyfree
+#endif
+
+#ifdef yytext
+#define seg_yytext_ALREADY_DEFINED
+#else
+#define yytext seg_yytext
+#endif
+
+#ifdef yyleng
+#define seg_yyleng_ALREADY_DEFINED
+#else
+#define yyleng seg_yyleng
+#endif
+
+#ifdef yyin
+#define seg_yyin_ALREADY_DEFINED
+#else
+#define yyin seg_yyin
+#endif
+
+#ifdef yyout
+#define seg_yyout_ALREADY_DEFINED
+#else
+#define yyout seg_yyout
+#endif
+
+#ifdef yy_flex_debug
+#define seg_yy_flex_debug_ALREADY_DEFINED
+#else
+#define yy_flex_debug seg_yy_flex_debug
+#endif
+
+#ifdef yylineno
+#define seg_yylineno_ALREADY_DEFINED
+#else
+#define yylineno seg_yylineno
+#endif
+
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
+#endif
+
+#ifndef SIZE_MAX
+#define SIZE_MAX (~(size_t)0)
+#endif
+
+#endif /* ! C99 */
+
+#endif /* ! FLEXINT_H */
+
+/* begin standard C++ headers. */
+
+/* TODO: this is always defined, so inline it */
+#define yyconst const
+
+#if defined(__GNUC__) && __GNUC__ >= 3
+#define yynoreturn __attribute__((__noreturn__))
+#else
+#define yynoreturn
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an
+ * integer in range [0..255] for use as an array index.
+ */
+#define YY_SC_TO_UI(c) ((YY_CHAR) (c))
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN (yy_start) = 1 + 2 *
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START (((yy_start) - 1) / 2)
+#define YYSTATE YY_START
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart( yyin )
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k.
+ * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
+ * Ditto for the __ia64__ case accordingly.
+ */
+#define YY_BUF_SIZE 32768
+#else
+#define YY_BUF_SIZE 16384
+#endif /* __ia64__ */
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+extern int yyleng;
+
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+ #define YY_LESS_LINENO(n)
+ #define YY_LINENO_REWIND_TO(ptr)
+
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ *yy_cp = (yy_hold_char); \
+ YY_RESTORE_YY_MORE_OFFSET \
+ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+#define unput(c) yyunput( c, (yytext_ptr) )
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ int yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ int yy_bs_lineno; /**< The line count. */
+ int yy_bs_column; /**< The column count. */
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via yyrestart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+
+ };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* Stack of input buffers. */
+static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
+static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
+static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
+ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
+ : NULL)
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+static int yy_n_chars; /* number of characters read into yy_ch_buf */
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = NULL;
+static int yy_init = 0; /* whether we need to initialize */
+static int yy_start = 0; /* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart ( FILE *input_file );
+void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer );
+YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size );
+void yy_delete_buffer ( YY_BUFFER_STATE b );
+void yy_flush_buffer ( YY_BUFFER_STATE b );
+void yypush_buffer_state ( YY_BUFFER_STATE new_buffer );
+void yypop_buffer_state ( void );
+
+static void yyensure_buffer_stack ( void );
+static void yy_load_buffer_state ( void );
+static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file );
+#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER )
+
+YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size );
+YY_BUFFER_STATE yy_scan_string ( const char *yy_str );
+YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len );
+
+void *yyalloc ( yy_size_t );
+void *yyrealloc ( void *, yy_size_t );
+void yyfree ( void * );
+
+#define yy_new_buffer yy_create_buffer
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){ \
+ yyensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ yy_create_buffer( yyin, YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+ }
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){\
+ yyensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ yy_create_buffer( yyin, YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+ }
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+
+#define seg_yywrap() (/*CONSTCOND*/1)
+#define YY_SKIP_YYWRAP
+typedef flex_uint8_t YY_CHAR;
+
+FILE *yyin = NULL, *yyout = NULL;
+
+typedef int yy_state_type;
+
+extern int yylineno;
+int yylineno = 1;
+
+extern char *yytext;
+#ifdef yytext_ptr
+#undef yytext_ptr
+#endif
+#define yytext_ptr yytext
+
+static yy_state_type yy_get_previous_state ( void );
+static yy_state_type yy_try_NUL_trans ( yy_state_type current_state );
+static int yy_get_next_buffer ( void );
+static void yynoreturn yy_fatal_error ( const char* msg );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ (yytext_ptr) = yy_bp; \
+ yyleng = (int) (yy_cp - yy_bp); \
+ (yy_hold_char) = *yy_cp; \
+ *yy_cp = '\0'; \
+ (yy_c_buf_p) = yy_cp;
+#define YY_NUM_RULES 9
+#define YY_END_OF_BUFFER 10
+/* This struct is not used in this scanner,
+ but its presence is necessary. */
+struct yy_trans_info
+ {
+ flex_int32_t yy_verify;
+ flex_int32_t yy_nxt;
+ };
+static const flex_int16_t yy_accept[30] =
+ { 0,
+ 0, 0, 10, 8, 7, 7, 8, 8, 8, 8,
+ 3, 4, 5, 6, 7, 0, 0, 3, 1, 0,
+ 0, 0, 0, 1, 3, 0, 3, 2, 0
+ } ;
+
+static const YY_CHAR yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 1, 2, 2, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 1, 1, 1, 1, 1, 1, 4, 5,
+ 6, 1, 7, 1, 8, 9, 1, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 1, 1, 11,
+ 1, 12, 1, 1, 1, 1, 1, 1, 13, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 13, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 14, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+static const YY_CHAR yy_meta[15] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 2, 2, 1, 2,
+ 1, 1, 1, 1
+ } ;
+
+static const flex_int16_t yy_base[31] =
+ { 0,
+ 0, 0, 40, 41, 13, 15, 32, 31, 27, 27,
+ 10, 41, 41, 41, 19, 27, 26, 0, 24, 22,
+ 21, 26, 23, 41, 14, 18, 16, 41, 41, 23
+ } ;
+
+static const flex_int16_t yy_def[31] =
+ { 0,
+ 29, 1, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 11, 29, 29,
+ 30, 29, 29, 29, 29, 29, 29, 29, 0, 29
+ } ;
+
+static const flex_int16_t yy_nxt[56] =
+ { 0,
+ 4, 5, 6, 7, 8, 4, 9, 9, 10, 11,
+ 12, 13, 4, 14, 15, 15, 15, 15, 20, 18,
+ 15, 15, 21, 25, 26, 27, 21, 27, 28, 28,
+ 27, 25, 24, 23, 22, 19, 18, 17, 16, 29,
+ 3, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29
+ } ;
+
+static const flex_int16_t yy_chk[56] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 5, 5, 6, 6, 11, 11,
+ 15, 15, 11, 25, 30, 27, 25, 26, 23, 22,
+ 21, 20, 19, 17, 16, 10, 9, 8, 7, 3,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29
+ } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+extern int yy_flex_debug;
+int yy_flex_debug = 0;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "segscan.l"
+#line 2 "segscan.l"
+/*
+ * A scanner for EMP-style numeric ranges
+ */
+
+/* LCOV_EXCL_START */
+
+/* No reason to constrain amount of data slurped */
+#define YY_READ_BUF_SIZE 16777216
+
+/* Avoid exit() on fatal scanner errors (a bit ugly -- see yy_fatal_error) */
+#undef fprintf
+#define fprintf(file, fmt, msg) fprintf_to_ereport(fmt, msg)
+
+static void
+fprintf_to_ereport(const char *fmt, const char *msg)
+{
+ ereport(ERROR, (errmsg_internal("%s", msg)));
+}
+
+/* Handles to the buffer that the lexer uses internally */
+static YY_BUFFER_STATE scanbufhandle;
+static char *scanbuf;
+static int scanbuflen;
+#line 745 "segscan.c"
+#define YY_NO_INPUT 1
+#line 747 "segscan.c"
+
+#define INITIAL 0
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+static int yy_init_globals ( void );
+
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+int yylex_destroy ( void );
+
+int yyget_debug ( void );
+
+void yyset_debug ( int debug_flag );
+
+YY_EXTRA_TYPE yyget_extra ( void );
+
+void yyset_extra ( YY_EXTRA_TYPE user_defined );
+
+FILE *yyget_in ( void );
+
+void yyset_in ( FILE * _in_str );
+
+FILE *yyget_out ( void );
+
+void yyset_out ( FILE * _out_str );
+
+ int yyget_leng ( void );
+
+char *yyget_text ( void );
+
+int yyget_lineno ( void );
+
+void yyset_lineno ( int _line_number );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap ( void );
+#else
+extern int yywrap ( void );
+#endif
+#endif
+
+#ifndef YY_NO_UNPUT
+
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy ( char *, const char *, int );
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen ( const char * );
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+static int yyinput ( void );
+#else
+static int input ( void );
+#endif
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k */
+#define YY_READ_BUF_SIZE 16384
+#else
+#define YY_READ_BUF_SIZE 8192
+#endif /* __ia64__ */
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0)
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+ { \
+ int c = '*'; \
+ int n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else \
+ { \
+ errno=0; \
+ while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \
+ { \
+ if( errno != EINTR) \
+ { \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ break; \
+ } \
+ errno=0; \
+ clearerr(yyin); \
+ } \
+ }\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int yylex (void);
+
+#define YY_DECL int yylex (void)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK /*LINTED*/break;
+#endif
+
+#define YY_RULE_SETUP \
+ YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+ yy_state_type yy_current_state;
+ char *yy_cp, *yy_bp;
+ int yy_act;
+
+ if ( !(yy_init) )
+ {
+ (yy_init) = 1;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! (yy_start) )
+ (yy_start) = 1; /* first start state */
+
+ if ( ! yyin )
+ yyin = stdin;
+
+ if ( ! yyout )
+ yyout = stdout;
+
+ if ( ! YY_CURRENT_BUFFER ) {
+ yyensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ yy_create_buffer( yyin, YY_BUF_SIZE );
+ }
+
+ yy_load_buffer_state( );
+ }
+
+ {
+#line 43 "segscan.l"
+
+
+#line 965 "segscan.c"
+
+ while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */
+ {
+ yy_cp = (yy_c_buf_p);
+
+ /* Support of yytext. */
+ *yy_cp = (yy_hold_char);
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = (yy_start);
+yy_match:
+ do
+ {
+ YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ;
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 30 )
+ yy_c = yy_meta[yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
+ ++yy_cp;
+ }
+ while ( yy_current_state != 29 );
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
+
+yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+
+ YY_DO_BEFORE_ACTION;
+
+do_action: /* This label is used only to access EOF actions. */
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+ case 0: /* must back up */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = (yy_hold_char);
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
+ goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 45 "segscan.l"
+yylval.text = yytext; return RANGE;
+ YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 46 "segscan.l"
+yylval.text = yytext; return PLUMIN;
+ YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 47 "segscan.l"
+yylval.text = yytext; return SEGFLOAT;
+ YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 48 "segscan.l"
+yylval.text = "<"; return EXTENSION;
+ YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 49 "segscan.l"
+yylval.text = ">"; return EXTENSION;
+ YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 50 "segscan.l"
+yylval.text = "~"; return EXTENSION;
+ YY_BREAK
+case 7:
+/* rule 7 can match eol */
+YY_RULE_SETUP
+#line 51 "segscan.l"
+/* discard spaces */
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 52 "segscan.l"
+return yytext[0]; /* alert parser of the garbage */
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 54 "segscan.l"
+YY_FATAL_ERROR( "flex scanner jammed" );
+ YY_BREAK
+#line 1064 "segscan.c"
+case YY_STATE_EOF(INITIAL):
+ yyterminate();
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = (yy_hold_char);
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * yylex(). If so, then we have to assure
+ * consistency between YY_CURRENT_BUFFER and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++(yy_c_buf_p);
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ (yy_did_buffer_switch_on_eof) = 0;
+
+ if ( yywrap( ) )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) =
+ (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ (yy_c_buf_p) =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+ } /* end of user's declarations */
+} /* end of yylex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (void)
+{
+ char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ char *source = (yytext_ptr);
+ int number_to_move, i;
+ int ret_val;
+
+ if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1);
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
+
+ else
+ {
+ int num_to_read =
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;
+
+ int yy_c_buf_p_offset =
+ (int) ((yy_c_buf_p) - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ yyrealloc( (void *) b->yy_ch_buf,
+ (yy_size_t) (b->yy_buf_size + 2) );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = NULL;
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+ number_to_move - 1;
+
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+ (yy_n_chars), num_to_read );
+
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ if ( (yy_n_chars) == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ yyrestart( yyin );
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ /* Extend the array by 50%, plus the number we really need. */
+ int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc(
+ (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size );
+ if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+ /* "- 2" to take care of EOB's */
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2);
+ }
+
+ (yy_n_chars) += number_to_move;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+
+ (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+ return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+ static yy_state_type yy_get_previous_state (void)
+{
+ yy_state_type yy_current_state;
+ char *yy_cp;
+
+ yy_current_state = (yy_start);
+
+ for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+ {
+ YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 30 )
+ yy_c = yy_meta[yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
+ }
+
+ return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state )
+{
+ int yy_is_jam;
+ char *yy_cp = (yy_c_buf_p);
+
+ YY_CHAR yy_c = 1;
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 30 )
+ yy_c = yy_meta[yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
+ yy_is_jam = (yy_current_state == 29);
+
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+#ifndef YY_NO_UNPUT
+
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+ static int yyinput (void)
+#else
+ static int input (void)
+#endif
+
+{
+ int c;
+
+ *(yy_c_buf_p) = (yy_hold_char);
+
+ if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ /* This was really a NUL. */
+ *(yy_c_buf_p) = '\0';
+
+ else
+ { /* need more input */
+ int offset = (int) ((yy_c_buf_p) - (yytext_ptr));
+ ++(yy_c_buf_p);
+
+ switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ yyrestart( yyin );
+
+ /*FALLTHROUGH*/
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( yywrap( ) )
+ return 0;
+
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput();
+#else
+ return input();
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) = (yytext_ptr) + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */
+ *(yy_c_buf_p) = '\0'; /* preserve yytext */
+ (yy_hold_char) = *++(yy_c_buf_p);
+
+ return c;
+}
+#endif /* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ *
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+ void yyrestart (FILE * input_file )
+{
+
+ if ( ! YY_CURRENT_BUFFER ){
+ yyensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ yy_create_buffer( yyin, YY_BUF_SIZE );
+ }
+
+ yy_init_buffer( YY_CURRENT_BUFFER, input_file );
+ yy_load_buffer_state( );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ *
+ */
+ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer )
+{
+
+ /* TODO. We should be able to replace this entire function body
+ * with
+ * yypop_buffer_state();
+ * yypush_buffer_state(new_buffer);
+ */
+ yyensure_buffer_stack ();
+ if ( YY_CURRENT_BUFFER == new_buffer )
+ return;
+
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+ yy_load_buffer_state( );
+
+ /* We don't actually know whether we did this switch during
+ * EOF (yywrap()) processing, but the only time this flag
+ * is looked at is after yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+static void yy_load_buffer_state (void)
+{
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+ yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+ (yy_hold_char) = *(yy_c_buf_p);
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ *
+ * @return the allocated buffer state.
+ */
+ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size )
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ yy_init_buffer( b, file );
+
+ return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with yy_create_buffer()
+ *
+ */
+ void yy_delete_buffer (YY_BUFFER_STATE b )
+{
+
+ if ( ! b )
+ return;
+
+ if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ yyfree( (void *) b->yy_ch_buf );
+
+ yyfree( (void *) b );
+}
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a yyrestart() or at EOF.
+ */
+ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file )
+
+{
+ int oerrno = errno;
+
+ yy_flush_buffer( b );
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+ /* If b is the current buffer, then yy_init_buffer was _probably_
+ * called from yyrestart() or through yy_get_next_buffer.
+ * In that case, we don't want to reset the lineno or column.
+ */
+ if (b != YY_CURRENT_BUFFER){
+ b->yy_bs_lineno = 1;
+ b->yy_bs_column = 0;
+ }
+
+ b->yy_is_interactive = 0;
+
+ errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ *
+ */
+ void yy_flush_buffer (YY_BUFFER_STATE b )
+{
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == YY_CURRENT_BUFFER )
+ yy_load_buffer_state( );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ * the current state. This function will allocate the stack
+ * if necessary.
+ * @param new_buffer The new state.
+ *
+ */
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
+{
+ if (new_buffer == NULL)
+ return;
+
+ yyensure_buffer_stack();
+
+ /* This block is copied from yy_switch_to_buffer. */
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ /* Only push if top exists. Otherwise, replace top. */
+ if (YY_CURRENT_BUFFER)
+ (yy_buffer_stack_top)++;
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+ /* copied from yy_switch_to_buffer. */
+ yy_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ * The next element becomes the new top.
+ *
+ */
+void yypop_buffer_state (void)
+{
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ yy_delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ if ((yy_buffer_stack_top) > 0)
+ --(yy_buffer_stack_top);
+
+ if (YY_CURRENT_BUFFER) {
+ yy_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+ }
+}
+
+/* Allocates the stack if it does not exist.
+ * Guarantees space for at least one push.
+ */
+static void yyensure_buffer_stack (void)
+{
+ yy_size_t num_to_alloc;
+
+ if (!(yy_buffer_stack)) {
+
+ /* First allocation is just for 2 elements, since we don't know if this
+ * scanner will even need a stack. We use 2 instead of 1 to avoid an
+ * immediate realloc on the next call.
+ */
+ num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */
+ (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
+ (num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+ if ( ! (yy_buffer_stack) )
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+ memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+
+ (yy_buffer_stack_max) = num_to_alloc;
+ (yy_buffer_stack_top) = 0;
+ return;
+ }
+
+ if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
+
+ /* Increase the buffer to prepare for a possible push. */
+ yy_size_t grow_size = 8 /* arbitrary grow size */;
+
+ num_to_alloc = (yy_buffer_stack_max) + grow_size;
+ (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
+ ((yy_buffer_stack),
+ num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+ if ( ! (yy_buffer_stack) )
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+ /* zero only the new slots.*/
+ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
+ (yy_buffer_stack_max) = num_to_alloc;
+ }
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size )
+{
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return NULL;
+
+ b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+ b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = NULL;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ yy_switch_to_buffer( b );
+
+ return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to yylex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ *
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ * yy_scan_bytes() instead.
+ */
+YY_BUFFER_STATE yy_scan_string (const char * yystr )
+{
+
+ return yy_scan_bytes( yystr, (int) strlen(yystr) );
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
+ * scan from a @e copy of @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len )
+{
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = (yy_size_t) (_yybytes_len + 2);
+ buf = (char *) yyalloc( n );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+ for ( i = 0; i < _yybytes_len; ++i )
+ buf[i] = yybytes[i];
+
+ buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = yy_scan_buffer( buf, n );
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yynoreturn yy_fatal_error (const char* msg )
+{
+ fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ yytext[yyleng] = (yy_hold_char); \
+ (yy_c_buf_p) = yytext + yyless_macro_arg; \
+ (yy_hold_char) = *(yy_c_buf_p); \
+ *(yy_c_buf_p) = '\0'; \
+ yyleng = yyless_macro_arg; \
+ } \
+ while ( 0 )
+
+/* Accessor methods (get/set functions) to struct members. */
+
+/** Get the current line number.
+ *
+ */
+int yyget_lineno (void)
+{
+
+ return yylineno;
+}
+
+/** Get the input stream.
+ *
+ */
+FILE *yyget_in (void)
+{
+ return yyin;
+}
+
+/** Get the output stream.
+ *
+ */
+FILE *yyget_out (void)
+{
+ return yyout;
+}
+
+/** Get the length of the current token.
+ *
+ */
+int yyget_leng (void)
+{
+ return yyleng;
+}
+
+/** Get the current token.
+ *
+ */
+
+char *yyget_text (void)
+{
+ return yytext;
+}
+
+/** Set the current line number.
+ * @param _line_number line number
+ *
+ */
+void yyset_lineno (int _line_number )
+{
+
+ yylineno = _line_number;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param _in_str A readable stream.
+ *
+ * @see yy_switch_to_buffer
+ */
+void yyset_in (FILE * _in_str )
+{
+ yyin = _in_str ;
+}
+
+void yyset_out (FILE * _out_str )
+{
+ yyout = _out_str ;
+}
+
+int yyget_debug (void)
+{
+ return yy_flex_debug;
+}
+
+void yyset_debug (int _bdebug )
+{
+ yy_flex_debug = _bdebug ;
+}
+
+static int yy_init_globals (void)
+{
+ /* Initialization is the same as for the non-reentrant scanner.
+ * This function is called from yylex_destroy(), so don't allocate here.
+ */
+
+ (yy_buffer_stack) = NULL;
+ (yy_buffer_stack_top) = 0;
+ (yy_buffer_stack_max) = 0;
+ (yy_c_buf_p) = NULL;
+ (yy_init) = 0;
+ (yy_start) = 0;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+ yyin = stdin;
+ yyout = stdout;
+#else
+ yyin = NULL;
+ yyout = NULL;
+#endif
+
+ /* For future reference: Set errno on error, since we are called by
+ * yylex_init()
+ */
+ return 0;
+}
+
+/* yylex_destroy is for both reentrant and non-reentrant scanners. */
+int yylex_destroy (void)
+{
+
+ /* Pop the buffer stack, destroying each element. */
+ while(YY_CURRENT_BUFFER){
+ yy_delete_buffer( YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ yypop_buffer_state();
+ }
+
+ /* Destroy the stack itself. */
+ yyfree((yy_buffer_stack) );
+ (yy_buffer_stack) = NULL;
+
+ /* Reset the globals. This is important in a non-reentrant scanner so the next time
+ * yylex() is called, initialization will occur. */
+ yy_init_globals( );
+
+ return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, const char * s2, int n )
+{
+
+ int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (const char * s )
+{
+ int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+}
+#endif
+
+void *yyalloc (yy_size_t size )
+{
+ return malloc(size);
+}
+
+void *yyrealloc (void * ptr, yy_size_t size )
+{
+
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return realloc(ptr, size);
+}
+
+void yyfree (void * ptr )
+{
+ free( (char *) ptr ); /* see yyrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#line 54 "segscan.l"
+
+
+/* LCOV_EXCL_STOP */
+
+void
+yyerror(SEG *result, const char *message)
+{
+ if (*yytext == YY_END_OF_BUFFER_CHAR)
+ {
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("bad seg representation"),
+ /* translator: %s is typically "syntax error" */
+ errdetail("%s at end of input", message)));
+ }
+ else
+ {
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("bad seg representation"),
+ /* translator: first %s is typically "syntax error" */
+ errdetail("%s at or near \"%s\"", message, yytext)));
+ }
+}
+
+
+/*
+ * Called before any actual parsing is done
+ */
+void
+seg_scanner_init(const char *str)
+{
+ Size slen = strlen(str);
+
+ /*
+ * Might be left over after ereport()
+ */
+ if (YY_CURRENT_BUFFER)
+ yy_delete_buffer(YY_CURRENT_BUFFER);
+
+ /*
+ * Make a scan buffer with special termination needed by flex.
+ */
+ scanbuflen = slen;
+ scanbuf = palloc(slen + 2);
+ memcpy(scanbuf, str, slen);
+ scanbuf[slen] = scanbuf[slen + 1] = YY_END_OF_BUFFER_CHAR;
+ scanbufhandle = yy_scan_buffer(scanbuf, slen + 2);
+
+ BEGIN(INITIAL);
+}
+
+
+/*
+ * Called after parsing is done to clean up after seg_scanner_init()
+ */
+void
+seg_scanner_finish(void)
+{
+ yy_delete_buffer(scanbufhandle);
+ pfree(scanbuf);
+}
+
diff --git a/contrib/seg/segscan.l b/contrib/seg/segscan.l
new file mode 100644
index 0000000..5f6595e
--- /dev/null
+++ b/contrib/seg/segscan.l
@@ -0,0 +1,115 @@
+%{
+/*
+ * A scanner for EMP-style numeric ranges
+ */
+
+/* LCOV_EXCL_START */
+
+/* No reason to constrain amount of data slurped */
+#define YY_READ_BUF_SIZE 16777216
+
+/* Avoid exit() on fatal scanner errors (a bit ugly -- see yy_fatal_error) */
+#undef fprintf
+#define fprintf(file, fmt, msg) fprintf_to_ereport(fmt, msg)
+
+static void
+fprintf_to_ereport(const char *fmt, const char *msg)
+{
+ ereport(ERROR, (errmsg_internal("%s", msg)));
+}
+
+/* Handles to the buffer that the lexer uses internally */
+static YY_BUFFER_STATE scanbufhandle;
+static char *scanbuf;
+static int scanbuflen;
+%}
+
+%option 8bit
+%option never-interactive
+%option nodefault
+%option noinput
+%option nounput
+%option noyywrap
+%option warn
+%option prefix="seg_yy"
+
+
+range (\.\.)(\.)?
+plumin (\'\+\-\')|(\(\+\-)\)
+integer [+-]?[0-9]+
+real [+-]?[0-9]+\.[0-9]+
+float ({integer}|{real})([eE]{integer})?
+
+%%
+
+{range} yylval.text = yytext; return RANGE;
+{plumin} yylval.text = yytext; return PLUMIN;
+{float} yylval.text = yytext; return SEGFLOAT;
+\< yylval.text = "<"; return EXTENSION;
+\> yylval.text = ">"; return EXTENSION;
+\~ yylval.text = "~"; return EXTENSION;
+[ \t\n\r\f]+ /* discard spaces */
+. return yytext[0]; /* alert parser of the garbage */
+
+%%
+
+/* LCOV_EXCL_STOP */
+
+void
+yyerror(SEG *result, const char *message)
+{
+ if (*yytext == YY_END_OF_BUFFER_CHAR)
+ {
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("bad seg representation"),
+ /* translator: %s is typically "syntax error" */
+ errdetail("%s at end of input", message)));
+ }
+ else
+ {
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("bad seg representation"),
+ /* translator: first %s is typically "syntax error" */
+ errdetail("%s at or near \"%s\"", message, yytext)));
+ }
+}
+
+
+/*
+ * Called before any actual parsing is done
+ */
+void
+seg_scanner_init(const char *str)
+{
+ Size slen = strlen(str);
+
+ /*
+ * Might be left over after ereport()
+ */
+ if (YY_CURRENT_BUFFER)
+ yy_delete_buffer(YY_CURRENT_BUFFER);
+
+ /*
+ * Make a scan buffer with special termination needed by flex.
+ */
+ scanbuflen = slen;
+ scanbuf = palloc(slen + 2);
+ memcpy(scanbuf, str, slen);
+ scanbuf[slen] = scanbuf[slen + 1] = YY_END_OF_BUFFER_CHAR;
+ scanbufhandle = yy_scan_buffer(scanbuf, slen + 2);
+
+ BEGIN(INITIAL);
+}
+
+
+/*
+ * Called after parsing is done to clean up after seg_scanner_init()
+ */
+void
+seg_scanner_finish(void)
+{
+ yy_delete_buffer(scanbufhandle);
+ pfree(scanbuf);
+}
diff --git a/contrib/seg/sort-segments.pl b/contrib/seg/sort-segments.pl
new file mode 100755
index 0000000..2e3c973
--- /dev/null
+++ b/contrib/seg/sort-segments.pl
@@ -0,0 +1,28 @@
+#!/usr/bin/perl
+
+# this script will sort any table with the segment data type in its last column
+
+use strict;
+use warnings;
+
+my @rows;
+
+while (<>)
+{
+ chomp;
+ push @rows, $_;
+}
+
+foreach (
+ sort {
+ my @ar = split("\t", $a);
+ my $valA = pop @ar;
+ $valA =~ s/[~<> ]+//g;
+ @ar = split("\t", $b);
+ my $valB = pop @ar;
+ $valB =~ s/[~<> ]+//g;
+ $valA <=> $valB
+ } @rows)
+{
+ print "$_\n";
+}
diff --git a/contrib/seg/sql/seg.sql b/contrib/seg/sql/seg.sql
new file mode 100644
index 0000000..6fe33e9
--- /dev/null
+++ b/contrib/seg/sql/seg.sql
@@ -0,0 +1,237 @@
+--
+-- Test seg datatype
+--
+
+CREATE EXTENSION seg;
+
+-- Check whether any of our opclasses fail amvalidate
+SELECT amname, opcname
+FROM pg_opclass opc LEFT JOIN pg_am am ON am.oid = opcmethod
+WHERE opc.oid >= 16384 AND NOT amvalidate(opc.oid);
+
+--
+-- testing the input and output functions
+--
+
+-- Any number
+SELECT '1'::seg AS seg;
+SELECT '-1'::seg AS seg;
+SELECT '1.0'::seg AS seg;
+SELECT '-1.0'::seg AS seg;
+SELECT '1e7'::seg AS seg;
+SELECT '-1e7'::seg AS seg;
+SELECT '1.0e7'::seg AS seg;
+SELECT '-1.0e7'::seg AS seg;
+SELECT '1e+7'::seg AS seg;
+SELECT '-1e+7'::seg AS seg;
+SELECT '1.0e+7'::seg AS seg;
+SELECT '-1.0e+7'::seg AS seg;
+SELECT '1e-7'::seg AS seg;
+SELECT '-1e-7'::seg AS seg;
+SELECT '1.0e-7'::seg AS seg;
+SELECT '-1.0e-7'::seg AS seg;
+SELECT '2e-6'::seg AS seg;
+SELECT '2e-5'::seg AS seg;
+SELECT '2e-4'::seg AS seg;
+SELECT '2e-3'::seg AS seg;
+SELECT '2e-2'::seg AS seg;
+SELECT '2e-1'::seg AS seg;
+SELECT '2e-0'::seg AS seg;
+SELECT '2e+0'::seg AS seg;
+SELECT '2e+1'::seg AS seg;
+SELECT '2e+2'::seg AS seg;
+SELECT '2e+3'::seg AS seg;
+SELECT '2e+4'::seg AS seg;
+SELECT '2e+5'::seg AS seg;
+SELECT '2e+6'::seg AS seg;
+
+
+-- Significant digits preserved
+SELECT '1'::seg AS seg;
+SELECT '1.0'::seg AS seg;
+SELECT '1.00'::seg AS seg;
+SELECT '1.000'::seg AS seg;
+SELECT '1.0000'::seg AS seg;
+SELECT '1.00000'::seg AS seg;
+SELECT '1.000000'::seg AS seg;
+SELECT '0.000000120'::seg AS seg;
+SELECT '3.400e5'::seg AS seg;
+
+-- Digits truncated
+SELECT '12.34567890123456'::seg AS seg;
+
+-- Numbers with certainty indicators
+SELECT '~6.5'::seg AS seg;
+SELECT '<6.5'::seg AS seg;
+SELECT '>6.5'::seg AS seg;
+SELECT '~ 6.5'::seg AS seg;
+SELECT '< 6.5'::seg AS seg;
+SELECT '> 6.5'::seg AS seg;
+
+-- Open intervals
+SELECT '0..'::seg AS seg;
+SELECT '0...'::seg AS seg;
+SELECT '0 ..'::seg AS seg;
+SELECT '0 ...'::seg AS seg;
+SELECT '..0'::seg AS seg;
+SELECT '...0'::seg AS seg;
+SELECT '.. 0'::seg AS seg;
+SELECT '... 0'::seg AS seg;
+
+-- Finite intervals
+SELECT '0 .. 1'::seg AS seg;
+SELECT '-1 .. 0'::seg AS seg;
+SELECT '-1 .. 1'::seg AS seg;
+
+-- (+/-) intervals
+SELECT '0(+-)1'::seg AS seg;
+SELECT '0(+-)1.0'::seg AS seg;
+SELECT '1.0(+-)0.005'::seg AS seg;
+SELECT '101(+-)1'::seg AS seg;
+-- incorrect number of significant digits in 99.0:
+SELECT '100(+-)1'::seg AS seg;
+
+-- invalid input
+SELECT ''::seg AS seg;
+SELECT 'ABC'::seg AS seg;
+SELECT '1ABC'::seg AS seg;
+SELECT '1.'::seg AS seg;
+SELECT '1.....'::seg AS seg;
+SELECT '.1'::seg AS seg;
+SELECT '1..2.'::seg AS seg;
+SELECT '1 e7'::seg AS seg;
+SELECT '1e700'::seg AS seg;
+
+--
+-- testing the operators
+--
+
+-- equality/inequality:
+--
+SELECT '24 .. 33.20'::seg = '24 .. 33.20'::seg AS bool;
+SELECT '24 .. 33.20'::seg = '24 .. 33.21'::seg AS bool;
+SELECT '24 .. 33.20'::seg != '24 .. 33.20'::seg AS bool;
+SELECT '24 .. 33.20'::seg != '24 .. 33.21'::seg AS bool;
+
+-- overlap
+--
+SELECT '1'::seg && '1'::seg AS bool;
+SELECT '1'::seg && '2'::seg AS bool;
+SELECT '0 ..'::seg && '0 ..'::seg AS bool;
+SELECT '0 .. 1'::seg && '0 .. 1'::seg AS bool;
+SELECT '..0'::seg && '0..'::seg AS bool;
+SELECT '-1 .. 0.1'::seg && '0 .. 1'::seg AS bool;
+SELECT '-1 .. 0'::seg && '0 .. 1'::seg AS bool;
+SELECT '-1 .. -0.0001'::seg && '0 .. 1'::seg AS bool;
+SELECT '0 ..'::seg && '1'::seg AS bool;
+SELECT '0 .. 1'::seg && '1'::seg AS bool;
+SELECT '0 .. 1'::seg && '2'::seg AS bool;
+SELECT '0 .. 2'::seg && '1'::seg AS bool;
+SELECT '1'::seg && '0 .. 1'::seg AS bool;
+SELECT '2'::seg && '0 .. 1'::seg AS bool;
+SELECT '1'::seg && '0 .. 2'::seg AS bool;
+
+-- overlap on the left
+--
+SELECT '1'::seg &< '0'::seg AS bool;
+SELECT '1'::seg &< '1'::seg AS bool;
+SELECT '1'::seg &< '2'::seg AS bool;
+SELECT '0 .. 1'::seg &< '0'::seg AS bool;
+SELECT '0 .. 1'::seg &< '1'::seg AS bool;
+SELECT '0 .. 1'::seg &< '2'::seg AS bool;
+SELECT '0 .. 1'::seg &< '0 .. 0.5'::seg AS bool;
+SELECT '0 .. 1'::seg &< '0 .. 1'::seg AS bool;
+SELECT '0 .. 1'::seg &< '0 .. 2'::seg AS bool;
+SELECT '0 .. 1'::seg &< '1 .. 2'::seg AS bool;
+SELECT '0 .. 1'::seg &< '2 .. 3'::seg AS bool;
+
+-- overlap on the right
+--
+SELECT '0'::seg &> '1'::seg AS bool;
+SELECT '1'::seg &> '1'::seg AS bool;
+SELECT '2'::seg &> '1'::seg AS bool;
+SELECT '0'::seg &> '0 .. 1'::seg AS bool;
+SELECT '1'::seg &> '0 .. 1'::seg AS bool;
+SELECT '2'::seg &> '0 .. 1'::seg AS bool;
+SELECT '0 .. 0.5'::seg &> '0 .. 1'::seg AS bool;
+SELECT '0 .. 1'::seg &> '0 .. 1'::seg AS bool;
+SELECT '0 .. 2'::seg &> '0 .. 2'::seg AS bool;
+SELECT '1 .. 2'::seg &> '0 .. 1'::seg AS bool;
+SELECT '2 .. 3'::seg &> '0 .. 1'::seg AS bool;
+
+-- left
+--
+SELECT '1'::seg << '0'::seg AS bool;
+SELECT '1'::seg << '1'::seg AS bool;
+SELECT '1'::seg << '2'::seg AS bool;
+SELECT '0 .. 1'::seg << '0'::seg AS bool;
+SELECT '0 .. 1'::seg << '1'::seg AS bool;
+SELECT '0 .. 1'::seg << '2'::seg AS bool;
+SELECT '0 .. 1'::seg << '0 .. 0.5'::seg AS bool;
+SELECT '0 .. 1'::seg << '0 .. 1'::seg AS bool;
+SELECT '0 .. 1'::seg << '0 .. 2'::seg AS bool;
+SELECT '0 .. 1'::seg << '1 .. 2'::seg AS bool;
+SELECT '0 .. 1'::seg << '2 .. 3'::seg AS bool;
+
+-- right
+--
+SELECT '0'::seg >> '1'::seg AS bool;
+SELECT '1'::seg >> '1'::seg AS bool;
+SELECT '2'::seg >> '1'::seg AS bool;
+SELECT '0'::seg >> '0 .. 1'::seg AS bool;
+SELECT '1'::seg >> '0 .. 1'::seg AS bool;
+SELECT '2'::seg >> '0 .. 1'::seg AS bool;
+SELECT '0 .. 0.5'::seg >> '0 .. 1'::seg AS bool;
+SELECT '0 .. 1'::seg >> '0 .. 1'::seg AS bool;
+SELECT '0 .. 2'::seg >> '0 .. 2'::seg AS bool;
+SELECT '1 .. 2'::seg >> '0 .. 1'::seg AS bool;
+SELECT '2 .. 3'::seg >> '0 .. 1'::seg AS bool;
+
+
+-- "contained in" (the left value belongs within the interval specified in the right value):
+--
+SELECT '0'::seg <@ '0'::seg AS bool;
+SELECT '0'::seg <@ '0 ..'::seg AS bool;
+SELECT '0'::seg <@ '.. 0'::seg AS bool;
+SELECT '0'::seg <@ '-1 .. 1'::seg AS bool;
+SELECT '0'::seg <@ '-1 .. 1'::seg AS bool;
+SELECT '-1'::seg <@ '-1 .. 1'::seg AS bool;
+SELECT '1'::seg <@ '-1 .. 1'::seg AS bool;
+SELECT '-1 .. 1'::seg <@ '-1 .. 1'::seg AS bool;
+
+-- "contains" (the left value contains the interval specified in the right value):
+--
+SELECT '0'::seg @> '0'::seg AS bool;
+SELECT '0 .. '::seg <@ '0'::seg AS bool;
+SELECT '.. 0'::seg <@ '0'::seg AS bool;
+SELECT '-1 .. 1'::seg <@ '0'::seg AS bool;
+SELECT '0'::seg <@ '-1 .. 1'::seg AS bool;
+SELECT '-1'::seg <@ '-1 .. 1'::seg AS bool;
+SELECT '1'::seg <@ '-1 .. 1'::seg AS bool;
+
+-- Load some example data and build the index
+--
+CREATE TABLE test_seg (s seg);
+
+\copy test_seg from 'data/test_seg.data'
+
+CREATE INDEX test_seg_ix ON test_seg USING gist (s);
+
+SET enable_indexscan = false;
+EXPLAIN (COSTS OFF)
+SELECT count(*) FROM test_seg WHERE s @> '11..11.3';
+SELECT count(*) FROM test_seg WHERE s @> '11..11.3';
+RESET enable_indexscan;
+
+SET enable_bitmapscan = false;
+EXPLAIN (COSTS OFF)
+SELECT count(*) FROM test_seg WHERE s @> '11..11.3';
+SELECT count(*) FROM test_seg WHERE s @> '11..11.3';
+RESET enable_bitmapscan;
+
+-- Test sorting
+SELECT * FROM test_seg WHERE s @> '11..11.3' GROUP BY s;
+
+-- Test functions
+SELECT seg_lower(s), seg_center(s), seg_upper(s)
+FROM test_seg WHERE s @> '11.2..11.3' OR s IS NULL ORDER BY s;