Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1j22oJ-0005TJ-Tg for pgsql-docs@arkaria.postgresql.org; Thu, 13 Feb 2020 00:56:56 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1j22oH-0001CM-LV for pgsql-docs@arkaria.postgresql.org; Thu, 13 Feb 2020 00:56:53 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1j22oH-00018m-3u for pgsql-docs@lists.postgresql.org; Thu, 13 Feb 2020 00:56:53 +0000 Received: from sss.pgh.pa.us ([66.207.139.130]) by magus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1j22o9-0006xi-Rb for pgsql-docs@lists.postgresql.org; Thu, 13 Feb 2020 00:56:52 +0000 Received: from sss1.sss.pgh.pa.us (localhost [127.0.0.1]) by sss.pgh.pa.us (8.14.4/8.14.4) with ESMTP id 01D0uXGO023575; Wed, 12 Feb 2020 19:56:33 -0500 From: Tom Lane To: Alvaro Herrera cc: Alexander Lakhin , pgsql-docs@lists.postgresql.org Subject: Re: Getting our tables to render better in PDF output In-reply-to: <20200212221818.GA15503@alvherre.pgsql> References: <20200212221818.GA15503@alvherre.pgsql> Comments: In-reply-to Alvaro Herrera message dated "Wed, 12 Feb 2020 19:18:18 -0300" MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaa0" Content-ID: <23542.1581555357.0@sss.pgh.pa.us> Content-Transfer-Encoding: 8bit Date: Wed, 12 Feb 2020 19:56:33 -0500 Message-ID: <23574.1581555393@sss.pgh.pa.us> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk ------- =_aaaaaaaaaa0 Content-Type: text/plain; charset="UTF-8" Content-ID: <23542.1581555357.1@sss.pgh.pa.us> Content-Transfer-Encoding: 8bit Alvaro Herrera writes: > Yeah, it'd look very odd, and certainly the no-parens case makes it > worse. I like this end result: >> Function Signature >> age age(timestamp) → interval >> now now() → timestamp with time zone >> current_timestamp current_timestamp → timestamp with time zone I gave that a try, and it seems to work really well. It can even handle the ridiculously long signature for make_interval() in reasonable style, as shown in the screenshot attached. One problem with the rightarrow idea is that it's not rendering quite right for me: it looks great in HTML, but in PDF it comes out flush with the baseline, as you can see in the screenshot. Hopefully there's a way to fix that that we can hide in the custom entity ... but I have no idea how. I decided to try converting the date/time operators table too, to see how well this works for that. It's bulkier than before, but also (I think) more precise. I realized that this table actually had three examples already for float8 * interval, but it wasn't at all obvious that they were the same operator. So that aspect is a lot nicer here. On the other hand, it seems like the text descriptions are only marginally useful here. I can imagine that they would be useful in some other operator tables, such as geometric operators, but I'm a bit tempted to leave them out in this particular table. The format would adapt to that easily. Another thing worth considering is removing duplicate left-hand- column entries, that is, considering all the instances of similarly-named functions/operators to be "the same". In the attached patch, I did that for isfinite() but not anywhere else. I'm not quite sure if it's a good idea or not. It seems like it makes sense for isfinite(), but perhaps less so for operators. Again, comments welcome. This is starting to feel like a real proposal now, but I'm still not at all wedded to it. regards, tom lane ------- =_aaaaaaaaaa0 Content-Type: text/x-diff; name="better-function-tables-wip.patch"; charset="us-ascii" Content-ID: <23542.1581555357.2@sss.pgh.pa.us> Content-Description: better-function-tables-wip.patch Content-Transfer-Encoding: quoted-printable diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index ceda48e..adfa571 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -2934,7 +2934,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two'= , 'three'); the result written in hexadecimal md5('Th\000omas'::bytea) - 8ab2d3c9689aaf18​b4958c334c82d8b1= + 8ab2d3c9689aaf18&break;b4958c334c82d8b1<= /entry> = @@ -2985,7 +2985,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two'= , 'three'); SHA-224 hash sha224('abc'::bytea) - \x23097d223405d8228642a477bda2​55b32aadbce4= bda0b3f7e36c9da7 + \x23097d223405d8228642a477bda2&break;55b32aadbce4b= da0b3f7e36c9da7 = @@ -3000,7 +3000,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two'= , 'three'); SHA-256 hash sha256('abc'::bytea) - \xba7816bf8f01cfea414140de5dae2223​b00361a3= 96177a9cb410ff61f20015ad + \xba7816bf8f01cfea414140de5dae2223&break;b00361a39= 6177a9cb410ff61f20015ad = @@ -3015,7 +3015,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two'= , 'three'); SHA-384 hash sha384('abc'::bytea) - \xcb00753f45a35e8bb5a03d699ac65007​272c32ab= 0eded1631a8b605a43ff5bed​8086072ba1e7cc2358baeca134c825a7= + \xcb00753f45a35e8bb5a03d699ac65007&break;272c32ab0= eded1631a8b605a43ff5bed&break;8086072ba1e7cc2358baeca134c825a7 = @@ -3030,7 +3030,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two'= , 'three'); SHA-512 hash sha512('abc'::bytea) - \xddaf35a193617abacc417349ae204131​12e6fa4e= 89a97ea20a9eeee64b55d39a​2192992a274fc1a836ba3c23a3feebbd​45= 4d4423643ce80e2a9ac94fa54ca49f + \xddaf35a193617abacc417349ae204131&break;12e6fa4e8= 9a97ea20a9eeee64b55d39a&break;2192992a274fc1a836ba3c23a3feebbd&break;454d4= 423643ce80e2a9ac94fa54ca49f = @@ -6670,127 +6670,256 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+= )(.*)){1,1}'); Date/Time Operators = + + + + + + + + - Operator - Example - Result + Operator= + Signature + + + Description + + + Example + Example Result = - + - date '2001-09-28' + integer '7' - date '2001-10-05' + + + date + integer + &returns; date - - + - date '2001-09-28' + interval '1 hour' - timestamp '2001-09-28 01:00:00' + Add a number of days to a date - - + - date '2001-09-28' + time '03:00' - timestamp '2001-09-28 03:00:00' + date '2001-09-28' + 7 + 2001-10-05 = - + - interval '1 day' + interval '1 hour' - interval '1 day 01:00:00' + + + date + interval + &returns; timestamp + + + Add an interval to a date + + + date '2001-09-28' + interval= '1 hour' + 2001-09-28 01:00:00 = - + - timestamp '2001-09-28 01:00' + interval '23 hours= ' - timestamp '2001-09-29 00:00:00' + + + date + time + &returns; timestamp + + + Add a time-of-day to a date + + + date '2001-09-28' + time '03= :00' + 2001-09-28 03:00:00 = - + - time '01:00' + interval '3 hours' - time '04:00:00' + + + interval + interval + &returns; interval + + + Add intervals + + + interval '1 day' + interval = '1 hour' + 1 day 01:00:00 = - - - - interval '23 hours' - interval '-23:00:00' + + + timestamp + interval + &returns; timestamp + + + Add an interval to a timestamp + + + timestamp '2001-09-28 01:00'= + interval '23 hours' + 2001-09-29 00:00:00 = - - - date '2001-10-01' - date '2001-09-28' - integer '3' (days) + + + time + interval + &returns; time + + + Add an interval to a time + + + time '01:00' + interval '3 h= ours' + 04:00:00 = - - - date '2001-10-01' - integer '7' - date '2001-09-24' + - + - interval + &returns; interval + + + Negate an interval + + + - interval '23 hours' + -23:00:00 = - - - date '2001-09-28' - interval '1 hour' - timestamp '2001-09-27 23:00:00' + - + date - date + &returns; integer + + + Subtract dates + + + date '2001-10-01' - date '20= 01-09-28' + 3 = - - - time '05:00' - time '03:00' - interval '02:00:00' + - + date - integer + &returns; date + + + Subtract a number of days from a date + + + date '2001-10-01' - 7 + 2001-09-24 = - - - time '05:00' - interval '2 hours' - time '03:00:00' + - + date - interval + &returns; timestamp + + + Subtract an interval from a date + + + date '2001-09-28' - interval= '1 hour' + 2001-09-27 23:00:00 = - - - timestamp '2001-09-28 23:00' - interval '23 hours= ' - timestamp '2001-09-28 00:00:00' + - + time - time + &returns; interval + + + Subtract times + + + time '05:00' - time '03:00'<= /literal> + 02:00:00 = - - - interval '1 day' - interval '1 hour' - interval '1 day -01:00:00' + - + time - interval + &returns; time + + + Subtract an interval from a time + + + time '05:00' - interval '2 h= ours' + 03:00:00 = - - - timestamp '2001-09-29 03:00' - timestamp '2001-09= -27 12:00' - interval '1 day 15:00:00' + - + timestamp - interval + &returns; timestamp + + + Subtract an interval from a timestamp + + + timestamp '2001-09-28 23:00'= - interval '23 hours' + 2001-09-28 00:00:00 = - * - 900 * interval '1 second' - interval '00:15:00' + - + interval - interval + &returns; interval + + + Subtract intervals + + + interval '1 day' - interval = '1 hour' + 1 day -01:00:00 = - * - 21 * interval '1 day' - interval '21 days' + - + timestamp - timestamp + &returns; interval + + + Subtract timestamps + + + timestamp '2001-09-29 03:00'= - timestamp '2001-09-27 12:00' + 1 day 15:00:00 = - * - double precision '3.5' * interval '1 hour' - interval '03:30:00' + * + double precision *<= /literal> interval + &returns; interval + + + Multiply an interval by a scalar + + + 900 * interval '1 second' + 00:15:00 + + + 21 * interval '1 day' + 21 days + + + 3.5 * interval '1 hour' + 03:30:00 = - / - interval '1 hour' / double precision '1.5' - interval '00:40:00' + / + interval / double precision + &returns; interval + + + Divide an interval by a scalar + + + interval '1 hour' / 1.5 + 00:40:00 @@ -6798,471 +6927,614 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+= )(.*)){1,1}'); = Date/Time Functions - + + + + + + + + + - Function - Return Type - Description - Example - Result + Function= + Signature + + + Description + + + Example + Example Result = - + age - age(timestamp, timestamp) + age - interval - Subtract arguments, producing a symbolic re= sult that + age(timestamp<= /type>, timestamp) + &returns; interval + + + Subtract arguments, producing a s= ymbolic result that uses years and months, rather than just days - age(timestamp '2001-04-10', timestamp '1957-06-13= ') - 43 years 9 mons 27 days + + + age(timestamp '2001-04-10', = timestamp '1957-06-13') + 43 years 9 mons 27 days = - age(timestamp)<= /literal> - interval - Subtract from current_date (at midnig= ht) - age(timestamp '1957-06-13') - 43 years 8 mons 3 days + age<= /entry> + age(timestamp<= /type>) + &returns; interval + + + Subtract from current_date (at midnight) + + + age(timestamp '1957-06-13')<= /literal> + variable<= /entry> = - + clock_timestamp - clock_timestamp() + clock_timestamp - timestamp with time zone - Current date and time (changes during statement execution)= ; + clock_timestamp() + &returns; timestamp with time zone + + + Current date and time (changes during st= atement execution); see - - + + + clock_timestamp()<= /entry> + variable<= /entry> = - + current_date - current_date + current_date - date - Current date; + current_date + &returns; date + + + Current date; see - - + + + current_date + variable<= /entry> = - + current_time - current_time + current_time - time with time zone - Current time of day; + current_time + &returns; time with time zone + + + Current time of day; see - - + + + current_time + variable<= /entry> = - + current_timestamp - current_timestamp + current_timestamp - timestamp with time zone - Current date and time (start of current transaction); + current_timestamp + &returns; timestamp with time zone + + + Current date and time (start of current = transaction); see - - + + + current_timestamp<= /entry> + variable<= /entry> = - + date_part - date_part(text, timestamp<= /type>) + date_part - double precision - Get subfield (equivalent to extract); + date_part(text= , timestamp) + &returns; double precision + + + Get subfield (equivalent to ex= tract); see - date_part('hour', timestamp '2001-02-16 20:38:40'= ) - 20 + + + date_part('hour', timestamp = '2001-02-16 20:38:40') + 20 = - date_part(text, inte= rval) - double precision - Get subfield (equivalent to + date_part + date_part(text= , interval) + &returns; double precision + + + Get subfield (equivalent to extract); see - date_part('month', interval '2 years 3 months') - 3 + + + date_part('month', interval = '2 years 3 months') + 3 = - + date_trunc - date_trunc(text, timestamp= ) + date_trunc - timestamp - Truncate to specified precision; see + date_trunc(tex= t, timestamp) + &returns; timestamp + + + Truncate to specified precision; see - date_trunc('hour', timestamp '2001-02-16 20:38:40= ') - 2001-02-16 20:00:00 + + + date_trunc('hour', timestamp= '2001-02-16 20:38:40') + 2001-02-16 20:00:00 = - date_trunc(text, tim= estamp with time zone, text) - timestamp with time zone - Truncate to specified precision in the specified time zone= ; see + date_trunc + date_trunc(tex= t, timestamp with time zone, text) + &returns; timestamp with time zone + + + Truncate to specified precision in the s= pecified time zone; see - date_trunc('day', timestamptz '2001-02-16 20:38:4= 0+00', 'Australia/Sydney') - 2001-02-16 13:00:00+00 + + + date_trunc('day', timestampt= z '2001-02-16 20:38:40+00', 'Australia/Sydney') + 2001-02-16 13:00:00+00 = - date_trunc(text, int= erval) - interval - Truncate to specified precision; see + date_trunc + date_trunc(tex= t, interval) + &returns; interval + + + Truncate to specified precision; see - date_trunc('hour', interval '2 days 3 hours 40 mi= nutes') - 2 days 03:00:00 + + + date_trunc('hour', interval = '2 days 3 hours 40 minutes') + 2 days 03:00:00 = - + extract - extract(field from - timestamp) + extract - double precision - Get subfield; see + extract(f= ield from timestamp) + &returns; double precision + + + Get subfield; see - extract(hour from timestamp '2001-02-16 20:38:40'= ) - 20 + + + extract(hour from timestamp = '2001-02-16 20:38:40') + 20 = - extract(field from - interval) - double precision - Get subfield; see + extract + extract(f= ield from interval) + &returns; double precision + + + Get subfield; see - extract(month from interval '2 years 3 months') - 3 + + + extract(month from interval = '2 years 3 months') + 3 = - + isfinite - isfinite(date) + isfinite - boolean - Test for finite date (not +/-infinity) - isfinite(date '2001-02-16') - true + isfinite(date<= /type>) + &returns; boolean + + + Test for finite date (not +/-infinity) + + + isfinite(date '2001-02-16')<= /literal> + true = - isfinite(timestamp) - boolean - Test for finite time stamp (not +/-infinity) - isfinite(timestamp '2001-02-16 21:28:30') - true + isfinite(times= tamp) + &returns; boolean + + + Test for finite time stamp (not +/-infin= ity) + + + isfinite(timestamp '2001-02-= 16 21:28:30') + true = - isfinite(interval) - boolean - Test for finite interval - isfinite(interval '4 hours') - true + isfinite(inter= val) + &returns; boolean + + + Test for finite interval + + + isfinite(interval '4 hours')= + true = - + justify_days - justify_days(interval) + justify_days - interval - Adjust interval so 30-day time periods are represented as = months - justify_days(interval '35 days') - 1 mon 5 days + justify_days(i= nterval) + &returns; interval + + + Adjust interval so 30-day time periods a= re represented as months + + + justify_days(interval '35 da= ys') + 1 mon 5 days = - + justify_hours - justify_hours(interval) + justify_hours - interval - Adjust interval so 24-hour time periods are represented as= days - justify_hours(interval '27 hours') - 1 day 03:00:00 + justify_hours(= interval) + &returns; interval + + + Adjust interval so 24-hour time periods = are represented as days + + + justify_hours(interval '27 h= ours') + 1 day 03:00:00 = - + justify_interval - justify_interval(interval) + justify_interval - interval - Adjust interval using justify_days an= d justify_hours, with additional sign adjustments - justify_interval(interval '1 mon -1 hour') - 29 days 23:00:00 + justify_interval(interval) + &returns; interval + + + Adjust interval using justify_= days and justify_hours, with additional si= gn adjustments + + + justify_interval(&break;inte= rval '1 mon -1 hour') + 29 days 23:00:00<= /entry> = - + localtime - localtime + localtime - time - Current time of day; + localtime + &returns; time + + + Current time of day; see - - + + + localtime + variable<= /entry> = - + localtimestamp - localtimestamp + localtimestamp - timestamp - Current date and time (start of current transaction); + localtimestamp + &returns; timestamp + + + Current date and time (start of current = transaction); see - - + + + localtimestamp + variable<= /entry> = - + make_date - - - make_date(year int, - month int, - day int) - - + make_date - date - + make_date(year int, + month int, + day int) + &returns; date + + + Create date from year, month and day fields - make_date(2013, 7, 15) - 2013-07-15 + + + make_date(2013, 7, 15) + 2013-07-15 = - - + make_interval - - - make_interval(years int DE= FAULT 0, - months int DEFAULT 0, - weeks int DEFAULT 0, - days int DEFAULT 0, - hours int DEFAULT 0, - mins int DEFAULT 0, - secs double precision DEFA= ULT 0.0) - - + make_interval - interval - + make_interval( year int + , month int + , week int + , day int + , hour int + , min int + , sec double precision + ) + &returns; interval + + + Create interval from years, months, weeks, days, hours, minutes = and - seconds fields + seconds fields, each of which can default to zero - make_interval(days =3D> 10) - 10 days + + + make_interval(days =3D> 1= 0) + 10 days = - + make_time - - - make_time(hour int, - min int, - sec double precision) - - + make_time - time - + make_time(hour int, + min int, + sec double precision) + &returns; time + + + Create time from hour, minute and seconds fields - make_time(8, 15, 23.5) - 08:15:23.5 + + + make_time(8, 15, 23.5) + 08:15:23.5 = - + make_timestamp - - - make_timestamp(year int, - month int, - day int, - hour int, - min int, - sec double precision) - - + make_timestamp - timestamp - + make_timestamp(year int, + month int, + day int, + hour int, + min int, + sec double precision) + &returns; timestamp + + + Create timestamp from year, month, day, hour, minute and seconds= fields - make_timestamp(2013, 7, 15, 8, 15, 23.5) - 2013-07-15 08:15:23.5 + + + make_timestamp(2013, 7, 15, = 8, 15, 23.5) + 2013-07-15 08:15:23.5 = - + make_timestamptz - - - make_timestamptz(year int, - month int, - day int, - hour int, - min int, - sec double precision, - timezone text <= /optional>) - - + make_timestamptz - timestamp with time zone - + make_timestamptz(year int, + month int, + day int, + hour int, + min int, + sec double precision + , timezone text ) + &returns; timestamp with time zone + + + Create timestamp with time zone from year, month, day, hour, min= ute and seconds fields; if timezone is not specified, the current time zone is used - make_timestamptz(2013, 7, 15, 8, 15, 23.5) - 2013-07-15 08:15:23.5+01 + + + make_timestamptz(2013, 7, 15= , 8, 15, 23.5) + 2013-07-15 08:15:23.5+01 = - + now - now() + now - timestamp with time zone - Current date and time (start of current transaction); + now() + &returns; timestamp with time zone + + + Current date and time (start of current = transaction); see - - + + + now() + variable<= /entry> = - + statement_timestamp - statement_timestamp() + statement_timestamp - timestamp with time zone - Current date and time (start of current statement); + statement_timestamp(= ) + &returns; timestamp with time zone + + + Current date and time (start of current = statement); see - - + + + statement_timestamp() + variable<= /entry> = - + timeofday - timeofday() + timeofday - text - Current date and time + timeofday() + &returns; text + + + Current date and time (like clock_timestamp, but as a text<= /type> string); see - - + + + timeofday() + variable<= /entry> = - + transaction_timestamp - transaction_timestamp() + transaction_timestamp - timestamp with time zone - Current date and time (start of current transaction); + transaction_timestamp() + &returns; timestamp with time zone + + + Current date and time (start of current = transaction); see - - - + transaction_&break;timestamp= () + variable<= /entry> + + + to_timestamp - to_timestamp(double precision) + to_timestamp - timestamp with time zone - Convert Unix epoch (seconds since 1970-01-01 00:00:00+00) = to + to_timestamp(d= ouble precision) + &returns; timestamp with time zone + + + Convert Unix epoch (seconds since 1970-0= 1-01 00:00:00+00) to timestamp - to_timestamp(1284352323) - 2010-09-13 04:32:03+00 + + + to_timestamp(&break;12843523= 23) + 2010-09-13 04:32:03+00 @@ -8236,52 +8508,83 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yel= low', 'green', 'blue', 'purple =
Enum Support Functions - + + + + + + + + + - Function - Description - Example - Example Result + Function<= /entry> + Signature + + + Description + + + Example + Example Result - - - enum_first - - enum_first(anyenum) + + + enum_first + + enum_first - Returns the first value of the input enum type - enum_first(null::rainbow) - red + enum_first(anye= num) &returns; anyenum - - - enum_last - - enum_last(anyenum) + Returns the first value of the input enum= type + + + enum_first(&break;null::rainb= ow) + red + + + + + enum_last + + enum_last - Returns the last value of the input enum type - enum_last(null::rainbow) - purple + enum_last(anyen= um) &returns; anyenum - - - enum_range - - enum_range(anyenum) + Returns the last value of the input enum = type + + + enum_last(&break;null::rainbo= w) + purple + + + + + enum_range + + enum_range - Returns all values of the input enum type in an ordered arr= ay - enum_range(null::rainbow) - {red,orange,yellow,green,blue,purple} + enum_range(anye= num) &returns; anyarray + + + Returns all values of the input enum type= in an ordered array + + + enum_range(&break;null::rainb= ow) + {red,orange,yellow,&break;gr= een,blue,purple} + + + enum_range + enum_range(anye= num, anyenum) &returns; anyarray - enum_range(anyenum, anyenum) - + Returns the range between the two given enum values, as an ordere= d array. The values must be from the same enum type. If the first parameter is null, the result will start with the first value of @@ -8289,16 +8592,18 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yel= low', 'green', 'blue', 'purple If the second parameter is null, the result will end with the las= t value of the enum type. - enum_range('orange'::rainbow, 'green'::rainbow) - {orange,yellow,green} - enum_range(NULL, 'green'::rainbow) - {red,orange,yellow,green} + enum_range(&break;'orange'::r= ainbow, 'green'::rainbow) + {orange,yellow,green} + + + enum_range(NULL, 'green'::rai= nbow) + {red,orange,yellow,&break;gr= een} - enum_range('orange'::rainbow, NULL) - {orange,yellow,green,blue,purple} + enum_range(&break;'orange'::r= ainbow, NULL) + {orange,yellow,green,&break;= blue,purple} diff --git a/doc/src/sgml/postgres.sgml b/doc/src/sgml/postgres.sgml index e59cba7..bfe5661 100644 --- a/doc/src/sgml/postgres.sgml +++ b/doc/src/sgml/postgres.sgml @@ -11,6 +11,12 @@ = = +