Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1r6aV9-001W8O-OH for pgsql-bugs@arkaria.postgresql.org; Fri, 24 Nov 2023 18:02:03 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1r6aV8-00DiIq-GB for pgsql-bugs@arkaria.postgresql.org; Fri, 24 Nov 2023 18:02:02 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1r6aUI-00DgRF-84 for pgsql-bugs@lists.postgresql.org; Fri, 24 Nov 2023 18:01:10 +0000 Received: from sss.pgh.pa.us ([68.162.161.243]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1r6aUC-008KZB-TF for pgsql-bugs@lists.postgresql.org; Fri, 24 Nov 2023 18:01:09 +0000 Received: from sss1.sss.pgh.pa.us (localhost [127.0.0.1]) by sss.pgh.pa.us (8.15.2/8.15.2) with ESMTP id 3AOI12qN3331143; Fri, 24 Nov 2023 13:01:03 -0500 From: Tom Lane To: dhyan@nataraj.su cc: pgsql-bugs@lists.postgresql.org Subject: Re: BUG #18214: poly_contain (@>) hangs forever for input data with zeros and infinities In-reply-to: <18214-891f77caa80a35cc@postgresql.org> References: <18214-891f77caa80a35cc@postgresql.org> Comments: In-reply-to PG Bug reporting form message dated "Fri, 24 Nov 2023 11:21:39 +0000" MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-ID: <3331141.1700848862.1@sss.pgh.pa.us> Date: Fri, 24 Nov 2023 13:01:02 -0500 Message-ID: <3331142.1700848862@sss.pgh.pa.us> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk PG Bug reporting form writes: > In postgreses 14-16, you execute following query it will work "forever" > select '((-inf, 0), (0, inf), (-inf, 0), (0, inf), (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, > 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), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, > 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0))'::polygon @> '((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, 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), (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, 0), (0, 0), (0, 0), > (-inf, 0))'::polygon; I poked at this a bit. v13 and earlier return quickly, although their answer is "false" which I'm not too sure is correct. git bisect shows the behavior changed at commit 8597a48d01b6cc0b09ff626253ac93c67e5516d5 Author: Tom Lane Date: Sat Nov 21 16:46:43 2020 -0500 Fix FPeq() and friends to get the right answers for infinities. I'm inclined to think that poly_contain_poly, or more specifically lseg_inside_poly, is just a broken algorithm. I don't have much faith that it gets the right answer (especially for non-simple polygons, which we do try to handle correctly in e.g. point_inside), and it's pretty obviously horrid from a time-complexity standpoint. I think we need to throw it away and start fresh rather than try to band-aid it further. I googled "polygon containment" and read about sweep-line algorithms, which might be the way to go here, but it's not something I care to put time into personally. > My colleagues have poked this bug a bit, and suggested that the cause of the > problem is probably the lseg_contain_point(LSEG *lseg, Point *pt) function, > that gives wrong result for the infinity case. Hmm, yeah, that pretty obviously fails for infinities, or any values large enough to cause overflow. I doubt that fixing it is sufficient to rescue poly_contain_poly, but it seems worth improving anyway because it has other callers. Not quite sure how we should define its behavior for infinity inputs though. If the point has any Inf coordinate, it seems clear that it's on the segment only if it is equal() to one of the endpoints. But what about a finite point versus a segment with Inf coordinate(s)? regards, tom lane