[PATCH] Improve geometric types

Started by Emre Hasegelialmost 9 years ago125 messageshackers
Jump to latest
#1Emre Hasegeli
emre@hasegeli.com

This is my next attempt to bring more sanity to the geometric types.
After the previous one [1]/messages/by-id/CAE2gYzwwxPWbzxY3mtN4WL7W0DCkWo8gnB2ThUHU2XQ9XwgHMg@mail.gmail.com went nowhere, I extracted the parts I can
fix without touching the EPSILON. I still hope to improve the
problems around EPSILON after this. I organised the changes as 4
patches for ease of review:

== geo-funcs-v1 ==

Refactor geometric functions and operators code

The geometric types were not using each other's functions. I believe
the reason behind this is simpler types line point and line being
developed after more complicated ones. This patch reduces duplicate
code and makes functions of different datatypes more compatible. We can
do much better than that, but it would require touching many more lines.
The changes can be summarised as:

* Re-use more functions to implement others
* Unify *_construct functions to obtain pre-allocated memory
* Unify *_interpt_internal functions to obtain pre-allocated memory
* Remove private functions from geo_decls.h
* Switch using C11 hypot() as the comment suggested

src/backend/utils/adt/geo_ops.c | 810 +++++++++++++-------------------
src/include/utils/geo_decls.h | 12 +-
src/test/regress/regress.c | 11 +-
3 files changed, 345 insertions(+), 488 deletions(-)

== float-header-v04 ==

Provide header file for built-in float datatypes

Even though, some datatypes under adt/ have separate header files,
most of the simple ones do not. Their public functions were on
the builtins.h. We would need to make more functions of floats public
to let the geometric types built on top of them. This is a good
opportunity to make a separate header file for floats.

1acf7572554515b99ef6e783750aaea8777524ec made _cmp functions public
to solve NaN problem locally for GiST indexes. This patch reworks it
in favour of a more extensive API. Kevin Grittner suggested to design
the API using inline functions. They are easier to use compared
to macros, and avoid double-evaluation hazards.

contrib/btree_gin/btree_gin.c | 3 +-
contrib/btree_gist/btree_ts.c | 2 +-
contrib/cube/cube.c | 2 +-
contrib/postgres_fdw/postgres_fdw.c | 2 +-
src/backend/access/gist/gistget.c | 2 +-
src/backend/access/gist/gistproc.c | 55 +-
src/backend/access/gist/gistutil.c | 2 +-
src/backend/utils/adt/float.c | 593 ++++--------------
src/backend/utils/adt/formatting.c | 8 +-
src/backend/utils/adt/geo_ops.c | 6 +-
src/backend/utils/adt/geo_spgist.c | 2 +-
src/backend/utils/adt/numeric.c | 1 +
src/backend/utils/adt/rangetypes_gist.c | 3 +-
src/backend/utils/adt/rangetypes_selfuncs.c | 3 +-
src/backend/utils/adt/rangetypes_typanalyze.c | 3 +-
src/backend/utils/adt/timestamp.c | 1 +
src/backend/utils/misc/guc.c | 1 +
src/include/utils/builtins.h | 14 -
src/include/utils/float.h | 383 +++++++++++
src/include/utils/geo_decls.h | 1 +
20 files changed, 561 insertions(+), 526 deletions(-)

== geo-float-v1 ==

Use the built-in float datatype to implement geometric types

This will provide:

* Check for underflow and overflow
* Check for division by zero
* Handle NaNs consistently

The patch also replaces all occurrences of "double" as "float8". They
are the same, but were randomly spread around on the same file.

src/backend/access/gist/gistproc.c | 156 +++++----
src/backend/utils/adt/geo_ops.c | 546 +++++++++++++++--------------
src/backend/utils/adt/geo_spgist.c | 36 +-
src/include/utils/float.h | 13 +
src/include/utils/geo_decls.h | 40 +--
5 files changed, 412 insertions(+), 379 deletions(-)

== line-fixes-v1 ==

Fix obvious problems around the line datatype

I have noticed some line operators retuning wrong results, and Tom Lane
spotted similar problems on more places. Source history reveals that
during 1990s, the internal format of the line datatype is changed, but
most functions haven't got the hint. The fixes are:

* Make operators more symmetric
* Reject invalid specification A=B=0 on receive
* Avoid division by zero on perpendicular operator
* Fix intersection and distance operators when neither A nor B is 1
* Avoid point distance operator crashing on float precision loss
* Fix line segment distance by getting the minimum as the comment suggested

Previous discussion:
/messages/by-id/CAE2gYzw_-z=V2kh8QqFjenu=8MJXzOP44wRW=AzzeamrmTT1=Q@mail.gmail.com

src/backend/utils/adt/geo_ops.c | 115 +++++++++++++++++++++-----------
1 file changed, 77 insertions(+), 38 deletions(-)

[1]: /messages/by-id/CAE2gYzwwxPWbzxY3mtN4WL7W0DCkWo8gnB2ThUHU2XQ9XwgHMg@mail.gmail.com

Attachments:

0003-geo-float-v1.patchapplication/octet-stream; name=0003-geo-float-v1.patchDownload+412-380
0004-line-fixes-v1.patchapplication/octet-stream; name=0004-line-fixes-v1.patchDownload+77-39
0001-geo-funcs-v1.patchapplication/octet-stream; name=0001-geo-funcs-v1.patchDownload+345-489
0002-float-header-v04.patchapplication/octet-stream; name=0002-float-header-v04.patchDownload+561-527
#2Aleksander Alekseev
aleksander@timescale.com
In reply to: Emre Hasegeli (#1)
Re: [PATCH] Improve geometric types

The following review has been posted through the commitfest application:
make installcheck-world: not tested
Implements feature: not tested
Spec compliant: not tested
Documentation: not tested

Hi Emre,

I'm afraid these patches conflict with current master branch.

The new status of this patch is: Waiting on Author

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#3Emre Hasegeli
emre@hasegeli.com
In reply to: Aleksander Alekseev (#2)
Re: [PATCH] Improve geometric types

I'm afraid these patches conflict with current master branch.

Rebased.

Attachments:

0001-geo-funcs-v2.patchapplication/octet-stream; name=0001-geo-funcs-v2.patchDownload+346-490
0002-float-header-v05.patchapplication/octet-stream; name=0002-float-header-v05.patchDownload+561-527
0003-geo-float-v2.patchapplication/octet-stream; name=0003-geo-float-v2.patchDownload+412-380
0004-line-fixes-v2.patchapplication/octet-stream; name=0004-line-fixes-v2.patchDownload+77-39
#4Aleksander Alekseev
aleksander@timescale.com
In reply to: Emre Hasegeli (#3)
Re: [PATCH] Improve geometric types

The following review has been posted through the commitfest application:
make installcheck-world: tested, failed
Implements feature: not tested
Spec compliant: not tested
Documentation: not tested

PostgreSQL fails with SIGSEGV during `make check-world`.

Backtrace: http://afiskon.ru/s/d4/f3dc17838a_sigsegv.txt
regression.diffs (not very useful): http://afiskon.ru/s/ac/ac5294656c_regression.diffs.txt
regression.out: http://afiskon.ru/s/70/39d872e2b8_regression.out.txt
How to reproduce: https://github.com/afiskon/pgscripts/blob/master/full-build.sh

The environment is Arch Linux x64, gcc 7.1.1

The new status of this patch is: Waiting on Author

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#5Emre Hasegeli
emre@hasegeli.com
In reply to: Aleksander Alekseev (#4)
Re: [PATCH] Improve geometric types

PostgreSQL fails with SIGSEGV during `make check-world`.

Fixed. I am sorry for not running "check-world" before.

Attachments:

0001-geo-funcs-v2.patchapplication/octet-stream; name=0001-geo-funcs-v2.patchDownload+346-490
0002-float-header-v06.patchapplication/octet-stream; name=0002-float-header-v06.patchDownload+562-525
0003-geo-float-v3.patchapplication/octet-stream; name=0003-geo-float-v3.patchDownload+412-381
0004-line-fixes-v2.patchapplication/octet-stream; name=0004-line-fixes-v2.patchDownload+77-39
#6Aleksander Alekseev
aleksander@timescale.com
In reply to: Emre Hasegeli (#5)
Re: [PATCH] Improve geometric types

The following review has been posted through the commitfest application:
make installcheck-world: tested, passed
Implements feature: tested, passed
Spec compliant: tested, passed
Documentation: tested, passed

LGTM.

The new status of this patch is: Ready for Committer

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#7Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Aleksander Alekseev (#6)
Re: [PATCH] Improve geometric types

Hello, sorry to late for the party, but may I comment on this?

At Tue, 05 Sep 2017 13:18:12 +0000, Aleksander Alekseev <a.alekseev@postgrespro.ru> wrote in <20170905131812.18925.13551.pgcf@coridan.postgresql.org>

The following review has been posted through the commitfest application:
make installcheck-world: tested, passed
Implements feature: tested, passed
Spec compliant: tested, passed
Documentation: tested, passed

LGTM.

The new status of this patch is: Ready for Committer

The first patch reconstructs the operators in layers. These
functions are called very frequently when used. Some function are
already inlined in float.h but some static functions in float.h
also can be and are better be inlined. Some of *_internal,
point_construct, line_calculate_point and so on are the
candidates.

You removed some DirectFunctionCall to the functions within the
same file but other functions remain in the style,
ex. poly_center or on_sl. The function called from the former
seems large enough but the latter function calls a so small
function that it could be inlined. Would you like to make some
additional functions use C call (instead of DirectFunctionCall)
and inlining them?

This is not a fault of this patch, but some functions like on_pb
seems missing comment to describe what it is. Would you like to
add some?

In the second patch, the additional include fmgrprotos.h in
btree_gin.c seems needless. Some float[48] features were macros
so that they share the same expressions between float4 and
float8. They still seems sharing perfectly the same expressions
in float.h. Is there any reason for converting them into typed
inline functions?

In float.h, MAXDOUBLEWIDTH is redueced from 500 to 128, but the
exponent of double is up to 308 so it doesn't seem sufficient. On
the other hand we won't use non-scientific notation for extremely
large numbers and it requires (perhaps) up to 26 bytes in the
case. In the soruce code, most of them uses "%e" and one of them
uses '%g". %e always takes the format of
"-1.(17digits)e+308".. So it would be less than 26
characters.

=# set extra_float_digits to 3;
=# select -1.221423424320453e308::float8;
?column?
---------------------------
-1.22142342432045302e+308

man printf: (linux)

Style e is used if the exponent from its conversion is less than
-4 or greater than or equal to the precision.

So we should be safe to have a buffer with 26 byte length and 500
bytes will apparently too large and even 128 will be too loose in
most cases. So how about something like the following?

#define MINDOUBLEWIDTH 32
...
float4out@float.c<modified>:

int ndig = FLT_DIG + extra_float_digits;

if (ndig < 1)
ndig = 1;

len = snprintf(ascii, MINDOUBLEWIDTH + 1, "%+.*g", ndig, num);
if (len > MINDOUBLEWIDTH + 1)
{
ascii = (char *) repalloc(ascii, len);
if (snprintf(ascii, len, "%+.*e", ndig, num) > len)
error(ERROR, "something wrong happens...");
}

I don't think the if part can be used so there would be no
performance degradation, I believe.

----
I'd like to pause here.

regards,

--
Kyotaro Horiguchi
NTT Open Source Software Center

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#8Emre Hasegeli
emre@hasegeli.com
In reply to: Kyotaro Horiguchi (#7)
Re: [PATCH] Improve geometric types

Hello, sorry to late for the party, but may I comment on this?

Thank you for picking this up again.

The first patch reconstructs the operators in layers. These
functions are called very frequently when used. Some function are
already inlined in float.h but some static functions in float.h
also can be and are better be inlined. Some of *_internal,
point_construct, line_calculate_point and so on are the
candidates.

They are static functions. I though compiler can decide to inline
them. Do you think adding "inline" to the function signatures are
necessary?

You removed some DirectFunctionCall to the functions within the
same file but other functions remain in the style,
ex. poly_center or on_sl. The function called from the former
seems large enough but the latter function calls a so small
function that it could be inlined. Would you like to make some
additional functions use C call (instead of DirectFunctionCall)
and inlining them?

I tried to minimise my changes to make reviewing easier. I can make
"_internal" functions for the remaining DirectFunctionCall()s, if you
find it necessary.

This is not a fault of this patch, but some functions like on_pb
seems missing comment to describe what it is. Would you like to
add some?

I will add some on the next version.

In the second patch, the additional include fmgrprotos.h in
btree_gin.c seems needless.

It must be something I missed on rebase. I will remove it.

Some float[48] features were macros
so that they share the same expressions between float4 and
float8. They still seems sharing perfectly the same expressions
in float.h. Is there any reason for converting them into typed
inline functions?

Kevin Grittner suggested using inline functions instead of macros.
They are easier to use compared to macros, and avoid double-evaluation
hazards.

In float.h, MAXDOUBLEWIDTH is redueced from 500 to 128, but the
exponent of double is up to 308 so it doesn't seem sufficient. On
the other hand we won't use non-scientific notation for extremely
large numbers and it requires (perhaps) up to 26 bytes in the
case. In the soruce code, most of them uses "%e" and one of them
uses '%g". %e always takes the format of
"-1.(17digits)e+308".. So it would be less than 26
characters.

=# set extra_float_digits to 3;
=# select -1.221423424320453e308::float8;
?column?
---------------------------
-1.22142342432045302e+308

man printf: (linux)

Style e is used if the exponent from its conversion is less than
-4 or greater than or equal to the precision.

So we should be safe to have a buffer with 26 byte length and 500
bytes will apparently too large and even 128 will be too loose in
most cases. So how about something like the following?

#define MINDOUBLEWIDTH 32

Should it be same for float4 and float8?

...
float4out@float.c<modified>:

int ndig = FLT_DIG + extra_float_digits;

if (ndig < 1)
ndig = 1;

len = snprintf(ascii, MINDOUBLEWIDTH + 1, "%+.*g", ndig, num);
if (len > MINDOUBLEWIDTH + 1)
{
ascii = (char *) repalloc(ascii, len);
if (snprintf(ascii, len, "%+.*e", ndig, num) > len)
error(ERROR, "something wrong happens...");
}

I don't think the if part can be used so there would be no
performance degradation, I believe.

Wouldn't this change the output of the float datatypes? That would be
a backwards incompatible change.

I'd like to pause here.

I will submit new versions after your are done with your review.

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#9Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Emre Hasegeli (#8)
Re: [PATCH] Improve geometric types

At Tue, 12 Sep 2017 19:30:44 +0200, Emre Hasegeli <emre@hasegeli.com> wrote in <CAE2gYzxDRvNdhrWQa7ym423uvHLWJXkqx=BoJePYMdrKPR1Zhg@mail.gmail.com>

Hello, sorry to late for the party, but may I comment on this?

Thank you for picking this up again.

The first patch reconstructs the operators in layers. These
functions are called very frequently when used. Some function are
already inlined in float.h but some static functions in float.h
also can be and are better be inlined. Some of *_internal,
point_construct, line_calculate_point and so on are the
candidates.

They are static functions. I though compiler can decide to inline
them. Do you think adding "inline" to the function signatures are
necessary?

C++ surely make just static functions inlined but I'm not sure C
compiler does that. "static" is a scope modifier and "inline" is
not (what kind of modifier is it?). In regard to gcc,

https://gcc.gnu.org/onlinedocs/gcc-7.2.0/gcc/Inline.html#Inline

By declaring a function inline, you can direct GCC to make
calls to that function faster. <snip> You can also direct GCC
to try to integrate all “simple enough” functions into their
callers with the option -finline-functions.

I didn't find that postgresql uses the options so I think we
shouldn't expect that they are inlined automatically.

You removed some DirectFunctionCall to the functions within the
same file but other functions remain in the style,
ex. poly_center or on_sl. The function called from the former
seems large enough but the latter function calls a so small
function that it could be inlined. Would you like to make some
additional functions use C call (instead of DirectFunctionCall)
and inlining them?

I tried to minimise my changes to make reviewing easier. I can make
"_internal" functions for the remaining DirectFunctionCall()s, if you
find it necessary.

Ok, it would be another patch even if we need that.

This is not a fault of this patch, but some functions like on_pb
seems missing comment to describe what it is. Would you like to
add some?

I will add some on the next version.

In the second patch, the additional include fmgrprotos.h in
btree_gin.c seems needless.

It must be something I missed on rebase. I will remove it.

Some float[48] features were macros
so that they share the same expressions between float4 and
float8. They still seems sharing perfectly the same expressions
in float.h. Is there any reason for converting them into typed
inline functions?

Kevin Grittner suggested using inline functions instead of macros.
They are easier to use compared to macros, and avoid double-evaluation
hazards.

I recall a bit about the double-evaluation hazards. I think the
functions needs a comment describing the reasons so that anyone
kind won't try to merge them into a macro again.

In float.h, MAXDOUBLEWIDTH is redueced from 500 to 128, but the
exponent of double is up to 308 so it doesn't seem sufficient. On
the other hand we won't use non-scientific notation for extremely
large numbers and it requires (perhaps) up to 26 bytes in the
case. In the soruce code, most of them uses "%e" and one of them
uses '%g". %e always takes the format of
"-1.(17digits)e+308".. So it would be less than 26
characters.

=# set extra_float_digits to 3;
=# select -1.221423424320453e308::float8;
?column?
---------------------------
-1.22142342432045302e+308

man printf: (linux)

Style e is used if the exponent from its conversion is less than
-4 or greater than or equal to the precision.

So we should be safe to have a buffer with 26 byte length and 500
bytes will apparently too large and even 128 will be too loose in
most cases. So how about something like the following?

#define MINDOUBLEWIDTH 32

Should it be same for float4 and float8?

Strictly they are different each other but float8 needs 26 bytes
(additional 1 byte is the sign for expnent, which I forgot.) and
float4 needs 15 bytes so it could be reduced to 32 and 16
respectively.

| select -1.11111111111111111111111111e-38::float4;
| -1.11111113e-38
| select -1.11111111111111111111111111e-4::float4;
| -0.000111111112
| select -1.11111111111111111111111111e-5::float4;
| -1.11111112e-05

On the other hand float4 is anyway converted into double in
float4out and I'm not sure that the extension doesn't adds
spurious digits. Therefore I think it would be reasonable that
"%g" formatter requires up to 27 bytes (26 + terminating zero) so
it should use MINDOUBLEWIDTH regardless of the precision of the
value given to the formatter.

Addition to that if we are deliberately using %g in float4out, we
can use flot8out_internal instead of most of the stuff of
float4out.

| Datum
| float4out(PG_FUNCTION_ARGS)
| {
| float8 num = PG_GETARG_FLOAT4(0);
|
| PG_RETURN_CSTRING(float8out_internal(num));
| }

...
float4out@float.c<modified>:

int ndig = FLT_DIG + extra_float_digits;

if (ndig < 1)
ndig = 1;

len = snprintf(ascii, MINDOUBLEWIDTH + 1, "%+.*g", ndig, num);
if (len > MINDOUBLEWIDTH + 1)
{
ascii = (char *) repalloc(ascii, len);
if (snprintf(ascii, len, "%+.*e", ndig, num) > len)
error(ERROR, "something wrong happens...");
}

I don't think the if part can be used so there would be no
performance degradation, I believe.

Wouldn't this change the output of the float datatypes? That would be
a backwards incompatible change.

It just reduces the unused part after terminator \0, and we won't
get incompatible result.

I'd like to pause here.

I will submit new versions after your are done with your review.

regards,

--
Kyotaro Horiguchi
NTT Open Source Software Center

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#10Robert Haas
robertmhaas@gmail.com
In reply to: Kyotaro Horiguchi (#9)
Re: [PATCH] Improve geometric types

On Thu, Sep 14, 2017 at 3:33 AM, Kyotaro HORIGUCHI
<horiguchi.kyotaro@lab.ntt.co.jp> wrote:

I recall a bit about the double-evaluation hazards. I think the
functions needs a comment describing the reasons so that anyone
kind won't try to merge them into a macro again.

I think we can count on PostgreSQL developers to understand the
advantages of an inline function over a macro. Even if they don't,
the solution can't be to put a comment in every place where an inline
function is used explaining it. That would be very repetitive.

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#11Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Robert Haas (#10)
Re: [PATCH] Improve geometric types

At Thu, 14 Sep 2017 16:19:13 -0400, Robert Haas <robertmhaas@gmail.com> wrote in <CA+TgmobinBA7uvQifYaYGdDUoF6VTo56dvoTT6nKSpJF-Zfv5A@mail.gmail.com>

On Thu, Sep 14, 2017 at 3:33 AM, Kyotaro HORIGUCHI
<horiguchi.kyotaro@lab.ntt.co.jp> wrote:

I recall a bit about the double-evaluation hazards. I think the
functions needs a comment describing the reasons so that anyone
kind won't try to merge them into a macro again.

I think we can count on PostgreSQL developers to understand the
advantages of an inline function over a macro. Even if they don't,
the solution can't be to put a comment in every place where an inline
function is used explaining it. That would be very repetitive.

Of course putting such a comment to all inline functions is
silly. The point here is that many pairs of two functions with
exactly the same shape but handle different types are defined
side by side. Such situation seems tempting to merge them into
single macros, as the previous author did there.

So a simple one like the following would be enough.

/* don't merge the following same functions with different types
into single macros so that double evaluation won't happen */

Is it still too verbose?

regards,

--
Kyotaro Horiguchi
NTT Open Source Software Center

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#12Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Kyotaro Horiguchi (#11)
Re: [PATCH] Improve geometric types

At Fri, 15 Sep 2017 17:23:28 +0900 (Tokyo Standard Time), Kyotaro HORIGUCHI <horiguchi.kyotaro@lab.ntt.co.jp> wrote in <20170915.172328.97446299.horiguchi.kyotaro@lab.ntt.co.jp>

At Thu, 14 Sep 2017 16:19:13 -0400, Robert Haas <robertmhaas@gmail.com> wrote in <CA+TgmobinBA7uvQifYaYGdDUoF6VTo56dvoTT6nKSpJF-Zfv5A@mail.gmail.com>

On Thu, Sep 14, 2017 at 3:33 AM, Kyotaro HORIGUCHI
<horiguchi.kyotaro@lab.ntt.co.jp> wrote:

I recall a bit about the double-evaluation hazards. I think the
functions needs a comment describing the reasons so that anyone
kind won't try to merge them into a macro again.

I think we can count on PostgreSQL developers to understand the
advantages of an inline function over a macro. Even if they don't,
the solution can't be to put a comment in every place where an inline
function is used explaining it. That would be very repetitive.

Of course putting such a comment to all inline functions is
silly. The point here is that many pairs of two functions with
exactly the same shape but handle different types are defined
side by side. Such situation seems tempting to merge them into
single macros, as the previous author did there.

So a simple one like the following would be enough.

/* don't merge the following same functions with different types
into single macros so that double evaluation won't happen */

Is it still too verbose?

That being said, I'm not stick on that if Robert or others think
it as needless.

regards,

--
Kyotaro Horiguchi
NTT Open Source Software Center

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#13Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Kyotaro Horiguchi (#9)
Re: [PATCH] Improve geometric types

Hello, just one point on 0001.

The patch replace pg_hypot with hypot in libc. The man page says
as follows.

man 3 hypot

If the result overflows, a range error occurs, and the functions return
HUGE_VAL, HUGE_VALF, or HUGE_VALL, respectively.

..

ERRORS
See math_error(7) for information on how to determine whether an error
has occurred when calling these functions.

The following errors can occur:

Range error: result overflow
errno is set to ERANGE. An overflow floating-point exception
(FE_OVERFLOW) is raised.

Range error: result underflow
An underflow floating-point exception (FE_UNDERFLOW) is raised.

These functions do not set errno for this case.

So, the code seems to need some amendments following to this
spec.

regards,

--
Kyotaro Horiguchi
NTT Open Source Software Center

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#14Robert Haas
robertmhaas@gmail.com
In reply to: Kyotaro Horiguchi (#11)
Re: [PATCH] Improve geometric types

On Fri, Sep 15, 2017 at 4:23 AM, Kyotaro HORIGUCHI
<horiguchi.kyotaro@lab.ntt.co.jp> wrote:

/* don't merge the following same functions with different types
into single macros so that double evaluation won't happen */

Is it still too verbose?

Personally, I don't think such a comment has much value, but I am not
going to spend a lot of time arguing about it. It's really up to the
eventual committer to decide, and that probably won't be me in this
case. My knowledge of the geometric types isn't great, and I am a tad
busy breaking^Wimproving things I do understand.

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#15Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Robert Haas (#14)
Re: [PATCH] Improve geometric types

At Fri, 15 Sep 2017 11:25:30 -0400, Robert Haas <robertmhaas@gmail.com> wrote in <CA+TgmoYgg8=m9+Y54Az1r+KBpMuiEOZM_DLDF04jMP4twGR3Ng@mail.gmail.com>

On Fri, Sep 15, 2017 at 4:23 AM, Kyotaro HORIGUCHI
<horiguchi.kyotaro@lab.ntt.co.jp> wrote:

/* don't merge the following same functions with different types
into single macros so that double evaluation won't happen */

Is it still too verbose?

Personally, I don't think such a comment has much value, but I am not
going to spend a lot of time arguing about it. It's really up to the
eventual committer to decide, and that probably won't be me in this
case. My knowledge of the geometric types isn't great, and I am a tad
busy breaking^Wimproving things I do understand.

Ok, I agree with you.

# Though it is not a issue of geometric types :p

I'll withdrow the comment. Maybe someone notices of that when
reviewing such a patch.

regards,

--
Kyotaro Horiguchi
NTT Open Source Software Center

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#16Emre Hasegeli
emre@hasegeli.com
In reply to: Kyotaro Horiguchi (#9)
Re: [PATCH] Improve geometric types

The new versions of the patches are attached addressing your comments.

C++ surely make just static functions inlined but I'm not sure C
compiler does that.

Thank you for your explanation. I marked the mentioned functions "inline".

So we should be safe to have a buffer with 26 byte length and 500
bytes will apparently too large and even 128 will be too loose in
most cases. So how about something like the following?

#define MINDOUBLEWIDTH 32

I left this part out for now. We can improve it separately.

Attachments:

0003-geo-float-v04.patchapplication/octet-stream; name=0003-geo-float-v04.patchDownload+401-366
0004-line-fixes-v03.patchapplication/octet-stream; name=0004-line-fixes-v03.patchDownload+81-54
0001-geo-funcs-v03.patchapplication/octet-stream; name=0001-geo-funcs-v03.patchDownload+455-581
0002-float-header-v07.patchapplication/octet-stream; name=0002-float-header-v07.patchDownload+554-514
#17Emre Hasegeli
emre@hasegeli.com
In reply to: Kyotaro Horiguchi (#13)
Re: [PATCH] Improve geometric types

The patch replace pg_hypot with hypot in libc. The man page says
as follows.

man 3 hypot

If the result overflows, a range error occurs, and the functions return
HUGE_VAL, HUGE_VALF, or HUGE_VALL, respectively.

..

ERRORS
See math_error(7) for information on how to determine whether an error
has occurred when calling these functions.

The following errors can occur:

Range error: result overflow
errno is set to ERANGE. An overflow floating-point exception
(FE_OVERFLOW) is raised.

Range error: result underflow
An underflow floating-point exception (FE_UNDERFLOW) is raised.

These functions do not set errno for this case.

So, the code seems to need some amendments following to this
spec.

I included them on the latest version.

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#18Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Emre Hasegeli (#8)
Re: [PATCH] Improve geometric types

Hello. Thank you for the new version.

0001: applies cleanly. regress passed.
this mainly refactoring geo_ops.c and replacing pg_hypot with hypot(3).
0002: applies cleanly. regress passed.
this just replaces float-ops macros into inline functions.
0003: applies cleanly. regress passed.
replaces double with float8 and bare arithmetic with defined functions.
0004: applies cleanly. regress passsed.
fix broken line-related functions.
I have some comments on this (later).

At Wed, 27 Sep 2017 17:44:52 +0200, Emre Hasegeli <emre@hasegeli.com> wrote in <CAE2gYzz2=335XEMHK-neNo=HgGskkPHQxUXkh8yDNsZAnCB5Bg@mail.gmail.com>

The new versions of the patches are attached addressing your comments.

C++ surely make just static functions inlined but I'm not sure C
compiler does that.

Thank you for your explanation. I marked the mentioned functions "inline".

Thanks.

So we should be safe to have a buffer with 26 byte length and 500
bytes will apparently too large and even 128 will be too loose in
most cases. So how about something like the following?

#define MINDOUBLEWIDTH 32

I left this part out for now. We can improve it separately.

Agreed. I found that psprintf does that with initial length of
128.

By the way, I found that MAXDOUBLEWIDTH has two inconsistent
definitions in formatting.c(500) and float.c(128). The definition
in new float.h is according to float.c and it seems better to be
untouched and it would be another issue.

At Wed, 27 Sep 2017 17:45:04 +0200, Emre Hasegeli <emre@hasegeli.com> wrote in <CAE2gYzz1KuT57vrO-XZk3KSqdpehAupJPLYu7AshuUwRF7MiMg@mail.gmail.com>

The patch replace pg_hypot with hypot in libc. The man page says
as follows.

...

I included them on the latest version.

# The commit message of 0001 says that "using C11 hypot()" but it
# is sine C99. I suppose we shold follow C99 at the time so I
# suggest rewrite it in the next version if any.

It seems bettern than expected. I confirmed that
pg_hypot(DBL_MAX, DBL_MAX) returned a value that is equivalent to
HUGE_VAL * HUGE_VAL on glibc, but I'm not sure the behavior on
other platforms is the same.

======
For other potential reviewers:

I found the origin of the function here.

/messages/by-id/4A90BD76.7070804@netspace.net.au
/messages/by-id/AANLkTim4cHELcGPf5w7Zd43_dQi_2RJ_b5_F_idSSbZI@mail.gmail.com

And the reason for pg_hypot is seen here.

/messages/by-id/407d949e0908222139t35ad3ad2q3e6b15646a27dd64@mail.gmail.com

I think the replacement is now acceptable according to the discussion.
======

And this should be the last comment of mine on the patch set.

In 0004, line_distance and line_interpt_internal seem
correct. Seemingly horizontal/vertical checks are redundant but
it is because unclearly defined EPSLON bahavior. lseg_perp seems
correct.

close_pl got a bug fix not only refactoring. I think it is
recommended to separate bugs and improvements, but I'm fine with
the current patch.

You added sanity check "A==0 && B==0" (in Ax + By + C) in
line_recv. I'm not sure the necessity of the check since it has
been checked in line_in but anyway the comparisons seem to be
typo(or thinko) of FPzero.

dist_pl is changed to take the smaller distance of both ends of
the segment. It seems absorbing error, so it might be better
taking the mean of the two distances. If you have a firm reason
for the change, it is better to be written there, or it might be
better left alone.

regards,

--
Kyotaro Horiguchi
NTT Open Source Software Center

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#19Emre Hasegeli
emre@hasegeli.com
In reply to: Kyotaro Horiguchi (#18)
Re: [PATCH] Improve geometric types

And this should be the last comment of mine on the patch set.

Thank you. The new versions of the patches are attached addressing
your comments.

By the way, I found that MAXDOUBLEWIDTH has two inconsistent
definitions in formatting.c(500) and float.c(128). The definition
in new float.h is according to float.c and it seems better to be
untouched and it would be another issue.

The last version of the patch don't move these declarations to the header file.

# The commit message of 0001 says that "using C11 hypot()" but it
# is sine C99. I suppose we shold follow C99 at the time so I
# suggest rewrite it in the next version if any.

Changed.

close_pl got a bug fix not only refactoring. I think it is
recommended to separate bugs and improvements, but I'm fine with
the current patch.

I split the refactoring to the first patch.

You added sanity check "A==0 && B==0" (in Ax + By + C) in
line_recv. I'm not sure the necessity of the check since it has
been checked in line_in but anyway the comparisons seem to be
typo(or thinko) of FPzero.

Tom Lane suggested [1]/messages/by-id/11053.1466362319@sss.pgh.pa.us this one. I now made it use FPzero().

dist_pl is changed to take the smaller distance of both ends of
the segment. It seems absorbing error, so it might be better
taking the mean of the two distances. If you have a firm reason
for the change, it is better to be written there, or it might be
better left alone.

I don't really, so I left that part out.

[1]: /messages/by-id/11053.1466362319@sss.pgh.pa.us

Attachments:

0001-geo-funcs-v04.patchapplication/octet-stream; name=0001-geo-funcs-v04.patchDownload+466-595
0002-float-header-v08.patchapplication/octet-stream; name=0002-float-header-v08.patchDownload+554-514
0003-geo-float-v05.patchapplication/octet-stream; name=0003-geo-float-v05.patchDownload+400-365
0004-line-fixes-v04.patchapplication/octet-stream; name=0004-line-fixes-v04.patchDownload+70-39
#20Robert Haas
robertmhaas@gmail.com
In reply to: Kyotaro Horiguchi (#18)
Re: [PATCH] Improve geometric types

On Mon, Oct 2, 2017 at 4:23 AM, Kyotaro HORIGUCHI
<horiguchi.kyotaro@lab.ntt.co.jp> wrote:

For other potential reviewers:

I found the origin of the function here.

/messages/by-id/4A90BD76.7070804@netspace.net.au
/messages/by-id/AANLkTim4cHELcGPf5w7Zd43_dQi_2RJ_b5_F_idSSbZI@mail.gmail.com

And the reason for pg_hypot is seen here.

/messages/by-id/407d949e0908222139t35ad3ad2q3e6b15646a27dd64@mail.gmail.com

I think the replacement is now acceptable according to the discussion.
======

I think if we're going to do this it should be separated out as its
own patch. Also, I think someone should explain what the reasoning
behind the change is. Do we, for example, foresee that the built-in
code might be faster or less likely to overflow? Because we're
clearly taking a risk -- most trivially, that the BF will break, or
more seriously, that some machines will have versions of this function
that don't actually behave quite the same.

That brings up a related point. How good is our test case coverage
for hypot(), especially in strange corner cases, like this one
mentioned in pg_hypot()'s comment:

* This implementation conforms to IEEE Std 1003.1 and GLIBC, in that the
* case of hypot(inf,nan) results in INF, and not NAN.

I'm potentially willing to commit a patch that just makes the
pg_hypot() -> hypot() change and does nothing else, if there are not
objections to that change, but I want to be sure that we'll know right
away if that turns out to break.

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#21Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Emre Hasegeli (#19)
#22Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Robert Haas (#20)
#23Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Robert Haas (#20)
#24Emre Hasegeli
emre@hasegeli.com
In reply to: Robert Haas (#20)
#25Emre Hasegeli
emre@hasegeli.com
In reply to: Alvaro Herrera (#23)
#26Tom Lane
tgl@sss.pgh.pa.us
In reply to: Emre Hasegeli (#25)
#27Emre Hasegeli
emre@hasegeli.com
In reply to: Tom Lane (#26)
#28Emre Hasegeli
emre@hasegeli.com
In reply to: Emre Hasegeli (#27)
#29Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Emre Hasegeli (#28)
#30Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Kyotaro Horiguchi (#29)
#31Emre Hasegeli
emre@hasegeli.com
In reply to: Kyotaro Horiguchi (#29)
#32Emre Hasegeli
emre@hasegeli.com
In reply to: Kyotaro Horiguchi (#18)
#33Emre Hasegeli
emre@hasegeli.com
In reply to: Kyotaro Horiguchi (#30)
#34Michael Paquier
michael@paquier.xyz
In reply to: Emre Hasegeli (#33)
#35Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Emre Hasegeli (#33)
#36Emre Hasegeli
emre@hasegeli.com
In reply to: Alvaro Herrera (#35)
#37Emre Hasegeli
emre@hasegeli.com
In reply to: Emre Hasegeli (#33)
#38Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Emre Hasegeli (#37)
#39Emre Hasegeli
emre@hasegeli.com
In reply to: Kyotaro Horiguchi (#38)
#40Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Emre Hasegeli (#39)
#41Emre Hasegeli
emre@hasegeli.com
In reply to: Kyotaro Horiguchi (#40)
#42Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Emre Hasegeli (#41)
#43Emre Hasegeli
emre@hasegeli.com
In reply to: Kyotaro Horiguchi (#42)
#44Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Emre Hasegeli (#43)
#45Emre Hasegeli
emre@hasegeli.com
In reply to: Kyotaro Horiguchi (#44)
#46Emre Hasegeli
emre@hasegeli.com
In reply to: Emre Hasegeli (#45)
#47Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Emre Hasegeli (#46)
#48Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Kyotaro Horiguchi (#47)
#49Emre Hasegeli
emre@hasegeli.com
In reply to: Kyotaro Horiguchi (#47)
#50Emre Hasegeli
emre@hasegeli.com
In reply to: Kyotaro Horiguchi (#48)
#51Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Kyotaro Horiguchi (#48)
#52Emre Hasegeli
emre@hasegeli.com
In reply to: Kyotaro Horiguchi (#51)
#53Andres Freund
andres@anarazel.de
In reply to: Emre Hasegeli (#52)
#54Aleksander Alekseev
aleksander@timescale.com
In reply to: Andres Freund (#53)
#55Emre Hasegeli
emre@hasegeli.com
In reply to: Aleksander Alekseev (#54)
#56Emre Hasegeli
emre@hasegeli.com
In reply to: Andres Freund (#53)
#57Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Emre Hasegeli (#55)
#58Emre Hasegeli
emre@hasegeli.com
In reply to: Kyotaro Horiguchi (#57)
#59Emre Hasegeli
emre@hasegeli.com
In reply to: Emre Hasegeli (#55)
#60Tomas Vondra
tomas.vondra@2ndquadrant.com
In reply to: Emre Hasegeli (#59)
#61Tom Lane
tgl@sss.pgh.pa.us
In reply to: Tomas Vondra (#60)
#62Tomas Vondra
tomas.vondra@2ndquadrant.com
In reply to: Tom Lane (#61)
#63Emre Hasegeli
emre@hasegeli.com
In reply to: Tomas Vondra (#62)
#64Thomas Munro
thomas.munro@gmail.com
In reply to: Emre Hasegeli (#59)
#65Emre Hasegeli
emre@hasegeli.com
In reply to: Thomas Munro (#64)
#66Tomas Vondra
tomas.vondra@2ndquadrant.com
In reply to: Emre Hasegeli (#65)
#67Thomas Munro
thomas.munro@gmail.com
In reply to: Tomas Vondra (#66)
#68Emre Hasegeli
emre@hasegeli.com
In reply to: Thomas Munro (#67)
#69Emre Hasegeli
emre@hasegeli.com
In reply to: Emre Hasegeli (#68)
#70Emre Hasegeli
emre@hasegeli.com
In reply to: Emre Hasegeli (#69)
#71Tomas Vondra
tomas.vondra@2ndquadrant.com
In reply to: Emre Hasegeli (#70)
#72Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Tomas Vondra (#71)
#73Tomas Vondra
tomas.vondra@2ndquadrant.com
In reply to: Kyotaro Horiguchi (#72)
#74Tomas Vondra
tomas.vondra@2ndquadrant.com
In reply to: Tomas Vondra (#73)
#75Thomas Munro
thomas.munro@gmail.com
In reply to: Tomas Vondra (#74)
#76Thomas Munro
thomas.munro@gmail.com
In reply to: Thomas Munro (#75)
#77Tomas Vondra
tomas.vondra@2ndquadrant.com
In reply to: Thomas Munro (#76)
#78Jeff Janes
jeff.janes@gmail.com
In reply to: Tomas Vondra (#73)
#79Tomas Vondra
tomas.vondra@2ndquadrant.com
In reply to: Jeff Janes (#78)
#80Tomas Vondra
tomas.vondra@2ndquadrant.com
In reply to: Tomas Vondra (#77)
#81Tomas Vondra
tomas.vondra@2ndquadrant.com
In reply to: Tomas Vondra (#80)
#82Tom Lane
tgl@sss.pgh.pa.us
In reply to: Tomas Vondra (#81)
#83Tom Lane
tgl@sss.pgh.pa.us
In reply to: Tom Lane (#82)
#84Tomas Vondra
tomas.vondra@2ndquadrant.com
In reply to: Tom Lane (#83)
#85Tomas Vondra
tomas.vondra@2ndquadrant.com
In reply to: Tomas Vondra (#79)
#86Tom Lane
tgl@sss.pgh.pa.us
In reply to: Tomas Vondra (#85)
#87Tomas Vondra
tomas.vondra@2ndquadrant.com
In reply to: Tom Lane (#86)
#88Emre Hasegeli
emre@hasegeli.com
In reply to: Tomas Vondra (#85)
#89Emre Hasegeli
emre@hasegeli.com
In reply to: Tomas Vondra (#84)
#90Tomas Vondra
tomas.vondra@2ndquadrant.com
In reply to: Emre Hasegeli (#89)
#91Tomas Vondra
tomas.vondra@2ndquadrant.com
In reply to: Emre Hasegeli (#89)
#92Emre Hasegeli
emre@hasegeli.com
In reply to: Tomas Vondra (#91)
#93Tomas Vondra
tomas.vondra@2ndquadrant.com
In reply to: Emre Hasegeli (#92)
#94Emre Hasegeli
emre@hasegeli.com
In reply to: Tomas Vondra (#93)
#95Emre Hasegeli
emre@hasegeli.com
In reply to: Tomas Vondra (#90)
#96Tomas Vondra
tomas.vondra@2ndquadrant.com
In reply to: Emre Hasegeli (#94)
#97Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Tomas Vondra (#96)
#98Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Emre Hasegeli (#94)
#99Tomas Vondra
tomas.vondra@2ndquadrant.com
In reply to: Kyotaro Horiguchi (#97)
#100Tomas Vondra
tomas.vondra@2ndquadrant.com
In reply to: Tomas Vondra (#99)
#101Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Tomas Vondra (#100)
#102Tomas Vondra
tomas.vondra@2ndquadrant.com
In reply to: Kyotaro Horiguchi (#101)
#103Tomas Vondra
tomas.vondra@2ndquadrant.com
In reply to: Tomas Vondra (#102)
#104Emre Hasegeli
emre@hasegeli.com
In reply to: Tomas Vondra (#103)
#105Tomas Vondra
tomas.vondra@2ndquadrant.com
In reply to: Emre Hasegeli (#104)
#106Emre Hasegeli
emre@hasegeli.com
In reply to: Tomas Vondra (#105)
#107Tomas Vondra
tomas.vondra@2ndquadrant.com
In reply to: Emre Hasegeli (#106)
#108Tom Lane
tgl@sss.pgh.pa.us
In reply to: Emre Hasegeli (#106)
#109Tomas Vondra
tomas.vondra@2ndquadrant.com
In reply to: Tom Lane (#108)
#110Tom Lane
tgl@sss.pgh.pa.us
In reply to: Tomas Vondra (#109)
#111Tomas Vondra
tomas.vondra@2ndquadrant.com
In reply to: Tom Lane (#110)
#112Tom Lane
tgl@sss.pgh.pa.us
In reply to: Tomas Vondra (#111)
#113Tomas Vondra
tomas.vondra@2ndquadrant.com
In reply to: Tom Lane (#112)
#114Tomas Vondra
tomas.vondra@2ndquadrant.com
In reply to: Tomas Vondra (#113)
#115Tom Lane
tgl@sss.pgh.pa.us
In reply to: Tomas Vondra (#114)
#116Tomas Vondra
tomas.vondra@2ndquadrant.com
In reply to: Tom Lane (#115)
#117Tom Lane
tgl@sss.pgh.pa.us
In reply to: Tomas Vondra (#116)
#118Tomas Vondra
tomas.vondra@2ndquadrant.com
In reply to: Tom Lane (#117)
#119Tom Lane
tgl@sss.pgh.pa.us
In reply to: Tomas Vondra (#116)
#120Tomas Vondra
tomas.vondra@2ndquadrant.com
In reply to: Tom Lane (#119)
#121Tom Lane
tgl@sss.pgh.pa.us
In reply to: Tomas Vondra (#120)
#122Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Tomas Vondra (#120)
#123Tomas Vondra
tomas.vondra@2ndquadrant.com
In reply to: Alvaro Herrera (#122)
#124Tomas Vondra
tomas.vondra@2ndquadrant.com
In reply to: Tom Lane (#121)
#125Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Tomas Vondra (#123)