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

Commitf31a931

Browse files
committed
Improve contrib/cube's handling of zero-D cubes, infinities, and NaNs.
It's always been possible to create a zero-dimensional cube by convertingfrom a zero-length float8 array, but cube_in failed to accept the '()'representation that cube_out produced for that case, resulting in adump/reload hazard. Make it accept the case. Also fix a couple ofother places that didn't behave sanely for zero-dimensional cubes:cube_size would produce 1.0 when surely the answer should be 0.0,and g_cube_distance risked a divide-by-zero failure.Likewise, it's always been possible to create cubes containing float8infinity or NaN coordinate values, but cube_in couldn't parse such input,and cube_out produced platform-dependent spellings of the values. Convertthem to use float8in_internal and float8out_internal so that the behaviorwill be the same as for float8, as we recently did for the core geometrictypes (cf commit50861cd). As in that commit, I don't pretend that thispatch fixes all insane corner-case behaviors that may exist for NaNs, butit's a step forward.(This change allows removal of the separate cube_1.out and cube_3.outexpected-files, as the platform dependency that previously required themis now gone: an underflowing coordinate value will now produce an errornot plus or minus zero.)Make errors from cube_in follow project conventions as to spelling("invalid input syntax for cube" not "bad cube representation")and errcode (INVALID_TEXT_REPRESENTATION not SYNTAX_ERROR).Also a few marginal code cleanups and comment improvements.Tom Lane, reviewed by Amul SulDiscussion: <15085.1472494782@sss.pgh.pa.us>
1 parent51c3e9f commitf31a931

File tree

9 files changed

+275
-3626
lines changed

9 files changed

+275
-3626
lines changed

‎contrib/cube/cube.c

Lines changed: 20 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ cube_in(PG_FUNCTION_ARGS)
122122
cube_scanner_init(str);
123123

124124
if (cube_yyparse(&result)!=0)
125-
cube_yyerror(&result,"bogus input");
125+
cube_yyerror(&result,"cube parser failed");
126126

127127
cube_scanner_finish();
128128

@@ -254,12 +254,9 @@ cube_subset(PG_FUNCTION_ARGS)
254254
for (i=0;i<dim;i++)
255255
{
256256
if ((dx[i] <=0)|| (dx[i]>DIM(c)))
257-
{
258-
pfree(result);
259257
ereport(ERROR,
260258
(errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
261259
errmsg("Index out of bounds")));
262-
}
263260
result->x[i]=c->x[dx[i]-1];
264261
if (!IS_POINT(c))
265262
result->x[i+dim]=c->x[dx[i]+DIM(c)-1];
@@ -276,27 +273,15 @@ cube_out(PG_FUNCTION_ARGS)
276273
StringInfoDatabuf;
277274
intdim=DIM(cube);
278275
inti;
279-
intndig;
280276

281277
initStringInfo(&buf);
282278

283-
/*
284-
* Get the number of digits to display.
285-
*/
286-
ndig=DBL_DIG+extra_float_digits;
287-
if (ndig<1)
288-
ndig=1;
289-
290-
/*
291-
* while printing the first (LL) corner, check if it is equal to the
292-
* second one
293-
*/
294279
appendStringInfoChar(&buf,'(');
295280
for (i=0;i<dim;i++)
296281
{
297282
if (i>0)
298283
appendStringInfoString(&buf,", ");
299-
appendStringInfo(&buf,"%.*g",ndig,LL_COORD(cube,i));
284+
appendStringInfoString(&buf,float8out_internal(LL_COORD(cube,i)));
300285
}
301286
appendStringInfoChar(&buf,')');
302287

@@ -307,7 +292,7 @@ cube_out(PG_FUNCTION_ARGS)
307292
{
308293
if (i>0)
309294
appendStringInfoString(&buf,", ");
310-
appendStringInfo(&buf,"%.*g",ndig,UR_COORD(cube,i));
295+
appendStringInfoString(&buf,float8out_internal(UR_COORD(cube,i)));
311296
}
312297
appendStringInfoChar(&buf,')');
313298
}
@@ -370,9 +355,6 @@ g_cube_union(PG_FUNCTION_ARGS)
370355
NDBOX*tmp;
371356
inti;
372357

373-
/*
374-
* fprintf(stderr, "union\n");
375-
*/
376358
tmp=DatumGetNDBOX(entryvec->vector[0].key);
377359

378360
/*
@@ -441,9 +423,6 @@ g_cube_penalty(PG_FUNCTION_ARGS)
441423
rt_cube_size(DatumGetNDBOX(origentry->key),&tmp2);
442424
*result= (float) (tmp1-tmp2);
443425

444-
/*
445-
* fprintf(stderr, "penalty\n"); fprintf(stderr, "\t%g\n", *result);
446-
*/
447426
PG_RETURN_FLOAT8(*result);
448427
}
449428

@@ -484,9 +463,6 @@ g_cube_picksplit(PG_FUNCTION_ARGS)
484463
*right;
485464
OffsetNumbermaxoff;
486465

487-
/*
488-
* fprintf(stderr, "picksplit\n");
489-
*/
490466
maxoff=entryvec->n-2;
491467
nbytes= (maxoff+2)*sizeof(OffsetNumber);
492468
v->spl_left= (OffsetNumber*)palloc(nbytes);
@@ -617,9 +593,6 @@ g_cube_same(PG_FUNCTION_ARGS)
617593
else
618594
*result= FALSE;
619595

620-
/*
621-
* fprintf(stderr, "same: %s\n", (*result ? "TRUE" : "FALSE" ));
622-
*/
623596
PG_RETURN_NDBOX(result);
624597
}
625598

@@ -633,9 +606,6 @@ g_cube_leaf_consistent(NDBOX *key,
633606
{
634607
boolretval;
635608

636-
/*
637-
* fprintf(stderr, "leaf_consistent, %d\n", strategy);
638-
*/
639609
switch (strategy)
640610
{
641611
caseRTOverlapStrategyNumber:
@@ -665,9 +635,6 @@ g_cube_internal_consistent(NDBOX *key,
665635
{
666636
boolretval;
667637

668-
/*
669-
* fprintf(stderr, "internal_consistent, %d\n", strategy);
670-
*/
671638
switch (strategy)
672639
{
673640
caseRTOverlapStrategyNumber:
@@ -865,30 +832,35 @@ cube_size(PG_FUNCTION_ARGS)
865832
{
866833
NDBOX*a=PG_GETARG_NDBOX(0);
867834
doubleresult;
868-
inti;
869-
870-
result=1.0;
871-
for (i=0;i<DIM(a);i++)
872-
result=result*Abs((LL_COORD(a,i)-UR_COORD(a,i)));
873835

836+
rt_cube_size(a,&result);
874837
PG_FREE_IF_COPY(a,0);
875838
PG_RETURN_FLOAT8(result);
876839
}
877840

878841
void
879842
rt_cube_size(NDBOX*a,double*size)
880843
{
844+
doubleresult;
881845
inti;
882846

883847
if (a== (NDBOX*)NULL)
884-
*size=0.0;
848+
{
849+
/* special case for GiST */
850+
result=0.0;
851+
}
852+
elseif (IS_POINT(a)||DIM(a)==0)
853+
{
854+
/* necessarily has zero size */
855+
result=0.0;
856+
}
885857
else
886858
{
887-
*size=1.0;
859+
result=1.0;
888860
for (i=0;i<DIM(a);i++)
889-
*size= (*size)*Abs(UR_COORD(a,i)-LL_COORD(a,i));
861+
result *=Abs(UR_COORD(a,i)-LL_COORD(a,i));
890862
}
891-
return;
863+
*size=result;
892864
}
893865

894866
/* make up a metric in which one box will be 'lower' than the other
@@ -1155,10 +1127,6 @@ cube_overlap_v0(NDBOX *a, NDBOX *b)
11551127
{
11561128
inti;
11571129

1158-
/*
1159-
* This *very bad* error was found in the source: if ( (a==NULL) ||
1160-
* (b=NULL) ) return(FALSE);
1161-
*/
11621130
if ((a==NULL)|| (b==NULL))
11631131
return (FALSE);
11641132

@@ -1370,7 +1338,9 @@ g_cube_distance(PG_FUNCTION_ARGS)
13701338
{
13711339
intcoord=PG_GETARG_INT32(1);
13721340

1373-
if (IS_POINT(cube))
1341+
if (DIM(cube)==0)
1342+
retval=0.0;
1343+
elseif (IS_POINT(cube))
13741344
retval=cube->x[(coord-1) %DIM(cube)];
13751345
else
13761346
retval=Min(cube->x[(coord-1) %DIM(cube)],

‎contrib/cube/cubedata.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
/* contrib/cube/cubedata.h */
22

3+
/*
4+
* This limit is pretty arbitrary, but don't make it so large that you
5+
* risk overflow in sizing calculations.
6+
*/
37
#defineCUBE_MAX_DIM (100)
48

59
typedefstructNDBOX
@@ -29,6 +33,7 @@ typedef struct NDBOX
2933
doublex[FLEXIBLE_ARRAY_MEMBER];
3034
}NDBOX;
3135

36+
/* NDBOX access macros */
3237
#definePOINT_BIT0x80000000
3338
#defineDIM_MASK0x7fffffff
3439

@@ -43,10 +48,12 @@ typedef struct NDBOX
4348
#definePOINT_SIZE(_dim)(offsetof(NDBOX, x) + sizeof(double)*(_dim))
4449
#defineCUBE_SIZE(_dim)(offsetof(NDBOX, x) + sizeof(double)*(_dim)*2)
4550

51+
/* fmgr interface macros */
4652
#defineDatumGetNDBOX(x)((NDBOX *) PG_DETOAST_DATUM(x))
4753
#definePG_GETARG_NDBOX(x)DatumGetNDBOX(PG_GETARG_DATUM(x))
4854
#definePG_RETURN_NDBOX(x)PG_RETURN_POINTER(x)
4955

56+
/* GiST operator strategy numbers */
5057
#defineCubeKNNDistanceCoord15/* ~> */
5158
#defineCubeKNNDistanceTaxicab16/* <#> */
5259
#defineCubeKNNDistanceEuclid17/* <-> */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp