Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit3a9a74a

Browse files
committed
Convert all remaining geometric operators to new fmgr style. This
allows fixing problems with operators that expected to be able toreturn a NULL, such as the '#' line-segment-intersection operatorthat tried to return NULL when the two segments don't intersect.(See, eg, bug report from 1-Nov-99 on pghackers.) Fix some otherbugs in passing, such as backwards comparison in path_distance().
1 parentd70d46f commit3a9a74a

File tree

8 files changed

+1748
-1585
lines changed

8 files changed

+1748
-1585
lines changed

‎src/backend/access/rtree/rtproc.c

Lines changed: 74 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,19 @@
33
* rtproc.c
44
* pg_amproc entries for rtrees.
55
*
6+
* NOTE: for largely-historical reasons, the intersection functions should
7+
* return a NULL pointer (*not* an SQL null value) to indicate "no
8+
* intersection". The size functions must be prepared to accept such
9+
* a pointer and return 0. This convention means that only pass-by-reference
10+
* data types can be used as the output of the union and intersection
11+
* routines, but that's not a big problem.
12+
*
13+
*
614
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
715
* Portions Copyright (c) 1994, Regents of the University of California
816
*
9-
*
1017
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtproc.c,v 1.28 2000/07/29 18:45:52 tgl Exp $
18+
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtproc.c,v 1.29 2000/07/30 20:43:40 tgl Exp $
1219
*
1320
*-------------------------------------------------------------------------
1421
*/
@@ -18,29 +25,31 @@
1825
#include"utils/geo_decls.h"
1926

2027

21-
BOX*
22-
rt_box_union(BOX*a,BOX*b)
28+
Datum
29+
rt_box_union(PG_FUNCTION_ARGS)
2330
{
31+
BOX*a=PG_GETARG_BOX_P(0);
32+
BOX*b=PG_GETARG_BOX_P(1);
2433
BOX*n;
2534

26-
if ((n= (BOX*)palloc(sizeof(*n)))== (BOX*)NULL)
27-
elog(ERROR,"Cannot allocate box for union");
35+
n= (BOX*)palloc(sizeof(BOX));
2836

2937
n->high.x=Max(a->high.x,b->high.x);
3038
n->high.y=Max(a->high.y,b->high.y);
3139
n->low.x=Min(a->low.x,b->low.x);
3240
n->low.y=Min(a->low.y,b->low.y);
3341

34-
returnn;
42+
PG_RETURN_BOX_P(n);
3543
}
3644

37-
BOX*
38-
rt_box_inter(BOX*a,BOX*b)
45+
Datum
46+
rt_box_inter(PG_FUNCTION_ARGS)
3947
{
48+
BOX*a=PG_GETARG_BOX_P(0);
49+
BOX*b=PG_GETARG_BOX_P(1);
4050
BOX*n;
4151

42-
if ((n= (BOX*)palloc(sizeof(*n)))== (BOX*)NULL)
43-
elog(ERROR,"Cannot allocate box for union");
52+
n= (BOX*)palloc(sizeof(BOX));
4453

4554
n->high.x=Min(a->high.x,b->high.x);
4655
n->high.y=Min(a->high.y,b->high.y);
@@ -50,21 +59,26 @@ rt_box_inter(BOX *a, BOX *b)
5059
if (n->high.x<n->low.x||n->high.y<n->low.y)
5160
{
5261
pfree(n);
53-
return (BOX*)NULL;
62+
/* Indicate "no intersection" by returning NULL pointer */
63+
n=NULL;
5464
}
5565

56-
returnn;
66+
PG_RETURN_BOX_P(n);
5767
}
5868

59-
void
60-
rt_box_size(BOX*a,float*size)
69+
Datum
70+
rt_box_size(PG_FUNCTION_ARGS)
6171
{
72+
BOX*a=PG_GETARG_BOX_P(0);
73+
/* NB: size is an output argument */
74+
float*size= (float*)PG_GETARG_POINTER(1);
75+
6276
if (a== (BOX*)NULL||a->high.x <=a->low.x||a->high.y <=a->low.y)
6377
*size=0.0;
6478
else
6579
*size= (float) ((a->high.x-a->low.x)* (a->high.y-a->low.y));
6680

67-
return;
81+
PG_RETURN_VOID();
6882
}
6983

7084
/*
@@ -75,10 +89,10 @@ rt_box_size(BOX *a, float *size)
7589
*as the return type for the size routine, so we no longer need to
7690
*have a special return type for big boxes.
7791
*/
78-
void
79-
rt_bigbox_size(BOX*a,float*size)
92+
Datum
93+
rt_bigbox_size(PG_FUNCTION_ARGS)
8094
{
81-
rt_box_size(a,size);
95+
returnrt_box_size(fcinfo);
8296
}
8397

8498
Datum
@@ -105,30 +119,6 @@ rt_poly_union(PG_FUNCTION_ARGS)
105119
PG_RETURN_POLYGON_P(p);
106120
}
107121

108-
Datum
109-
rt_poly_size(PG_FUNCTION_ARGS)
110-
{
111-
POLYGON*a=PG_GETARG_POLYGON_P(0);
112-
/* NB: size is an output argument */
113-
float*size= (float*)PG_GETARG_POINTER(1);
114-
doublexdim,
115-
ydim;
116-
117-
if (a== (POLYGON*)NULL||
118-
a->boundbox.high.x <=a->boundbox.low.x||
119-
a->boundbox.high.y <=a->boundbox.low.y)
120-
*size=0.0;
121-
else
122-
{
123-
xdim= (a->boundbox.high.x-a->boundbox.low.x);
124-
ydim= (a->boundbox.high.y-a->boundbox.low.y);
125-
126-
*size= (float) (xdim*ydim);
127-
}
128-
129-
PG_RETURN_VOID();
130-
}
131-
132122
Datum
133123
rt_poly_inter(PG_FUNCTION_ARGS)
134124
{
@@ -146,16 +136,52 @@ rt_poly_inter(PG_FUNCTION_ARGS)
146136
p->boundbox.low.x=Max(a->boundbox.low.x,b->boundbox.low.x);
147137
p->boundbox.low.y=Max(a->boundbox.low.y,b->boundbox.low.y);
148138

149-
/* Avoid leaking memory when handed toasted input. */
150-
PG_FREE_IF_COPY(a,0);
151-
PG_FREE_IF_COPY(b,1);
152-
153139
if (p->boundbox.high.x<p->boundbox.low.x||
154140
p->boundbox.high.y<p->boundbox.low.y)
155141
{
156142
pfree(p);
157-
PG_RETURN_NULL();
143+
/* Indicate "no intersection" by returning NULL pointer */
144+
p=NULL;
158145
}
159146

147+
/* Avoid leaking memory when handed toasted input. */
148+
PG_FREE_IF_COPY(a,0);
149+
PG_FREE_IF_COPY(b,1);
150+
160151
PG_RETURN_POLYGON_P(p);
161152
}
153+
154+
Datum
155+
rt_poly_size(PG_FUNCTION_ARGS)
156+
{
157+
Pointeraptr=PG_GETARG_POINTER(0);
158+
/* NB: size is an output argument */
159+
float*size= (float*)PG_GETARG_POINTER(1);
160+
POLYGON*a;
161+
doublexdim,
162+
ydim;
163+
164+
/* Can't just use GETARG because of possibility that input is NULL;
165+
* since POLYGON is toastable, GETARG will try to inspect its value
166+
*/
167+
if (aptr==NULL)
168+
{
169+
*size=0.0;
170+
PG_RETURN_VOID();
171+
}
172+
/* Now safe to apply GETARG */
173+
a=PG_GETARG_POLYGON_P(0);
174+
175+
if (a->boundbox.high.x <=a->boundbox.low.x||
176+
a->boundbox.high.y <=a->boundbox.low.y)
177+
*size=0.0;
178+
else
179+
{
180+
xdim= (a->boundbox.high.x-a->boundbox.low.x);
181+
ydim= (a->boundbox.high.y-a->boundbox.low.y);
182+
183+
*size= (float) (xdim*ydim);
184+
}
185+
186+
PG_RETURN_VOID();
187+
}

‎src/backend/access/rtree/rtree.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtree.c,v 1.52 2000/07/14 22:17:36 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtree.c,v 1.53 2000/07/30 20:43:40 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -745,13 +745,16 @@ picksplit(Relation r,
745745
DatumGetPointer(FunctionCall2(&rtstate->interFn,
746746
PointerGetDatum(datum_alpha),
747747
PointerGetDatum(datum_beta)));
748+
/* The interFn may return a NULL pointer (not an SQL null!)
749+
* to indicate no intersection. sizeFn must cope with this.
750+
*/
748751
FunctionCall2(&rtstate->sizeFn,
749752
PointerGetDatum(inter_d),
750753
PointerGetDatum(&size_inter));
751754
size_waste=size_union-size_inter;
752755

753-
pfree(union_d);
754-
756+
if(union_d!= (char*)NULL)
757+
pfree(union_d);
755758
if (inter_d!= (char*)NULL)
756759
pfree(inter_d);
757760

@@ -1051,7 +1054,8 @@ _rtdump(Relation r)
10511054
itoffno=ItemPointerGetOffsetNumber(&(itup->t_tid));
10521055
datum= ((char*)itup);
10531056
datum+=sizeof(IndexTupleData);
1054-
itkey= (char*)box_out((BOX*)datum);
1057+
itkey=DatumGetCString(DirectFunctionCall1(box_out,
1058+
PointerGetDatum(datum)));
10551059
printf("\t[%d] size %d heap <%d,%d> key:%s\n",
10561060
offnum,IndexTupleSize(itup),itblkno,itoffno,itkey);
10571061
pfree(itkey);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp