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

Commit8b29e88

Browse files
committed
Add window RANGE support for float4, float8, numeric.
Commit0a459ce left this for later, but since time's running out,I went ahead and took care of it. There are more data types thatsomebody might someday want RANGE support for, but this is enoughto satisfy all expectations of the SQL standard, which just says that"numeric, datetime, and interval" types should have RANGE support.
1 parent081bfc1 commit8b29e88

File tree

7 files changed

+429
-1
lines changed

7 files changed

+429
-1
lines changed

‎src/backend/utils/adt/float.c

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1180,6 +1180,93 @@ btfloat84cmp(PG_FUNCTION_ARGS)
11801180
PG_RETURN_INT32(float8_cmp_internal(arg1,arg2));
11811181
}
11821182

1183+
/*
1184+
* in_range support function for float8.
1185+
*
1186+
* Note: we needn't supply a float8_float4 variant, as implicit coercion
1187+
* of the offset value takes care of that scenario just as well.
1188+
*/
1189+
Datum
1190+
in_range_float8_float8(PG_FUNCTION_ARGS)
1191+
{
1192+
float8val=PG_GETARG_FLOAT8(0);
1193+
float8base=PG_GETARG_FLOAT8(1);
1194+
float8offset=PG_GETARG_FLOAT8(2);
1195+
boolsub=PG_GETARG_BOOL(3);
1196+
boolless=PG_GETARG_BOOL(4);
1197+
float8sum;
1198+
1199+
/*
1200+
* Reject negative or NaN offset. Negative is per spec, and NaN is
1201+
* because appropriate semantics for that seem non-obvious.
1202+
*/
1203+
if (isnan(offset)||offset<0)
1204+
ereport(ERROR,
1205+
(errcode(ERRCODE_INVALID_PRECEDING_FOLLOWING_SIZE),
1206+
errmsg("invalid preceding or following size in window function")));
1207+
1208+
/*
1209+
* Deal with cases where val and/or base is NaN, following the rule that
1210+
* NaN sorts after non-NaN (cf float8_cmp_internal). The offset cannot
1211+
* affect the conclusion.
1212+
*/
1213+
if (isnan(val))
1214+
{
1215+
if (isnan(base))
1216+
PG_RETURN_BOOL(true);/* NAN = NAN */
1217+
else
1218+
PG_RETURN_BOOL(!less);/* NAN > non-NAN */
1219+
}
1220+
elseif (isnan(base))
1221+
{
1222+
PG_RETURN_BOOL(less);/* non-NAN < NAN */
1223+
}
1224+
1225+
/*
1226+
* Deal with infinite offset (necessarily +inf, at this point). We must
1227+
* special-case this because if base happens to be -inf, their sum would
1228+
* be NaN, which is an overflow-ish condition we should avoid.
1229+
*/
1230+
if (isinf(offset))
1231+
{
1232+
PG_RETURN_BOOL(sub ? !less :less);
1233+
}
1234+
1235+
/*
1236+
* Otherwise it should be safe to compute base +/- offset. We trust the
1237+
* FPU to cope if base is +/-inf or the true sum would overflow, and
1238+
* produce a suitably signed infinity, which will compare properly against
1239+
* val whether or not that's infinity.
1240+
*/
1241+
if (sub)
1242+
sum=base-offset;
1243+
else
1244+
sum=base+offset;
1245+
1246+
if (less)
1247+
PG_RETURN_BOOL(val <=sum);
1248+
else
1249+
PG_RETURN_BOOL(val >=sum);
1250+
}
1251+
1252+
/*
1253+
* in_range support function for float4.
1254+
*
1255+
* We would need a float4_float8 variant in any case, so we supply that and
1256+
* let implicit coercion take care of the float4_float4 case.
1257+
*/
1258+
Datum
1259+
in_range_float4_float8(PG_FUNCTION_ARGS)
1260+
{
1261+
/* Doesn't seem worth duplicating code for, so just invoke float8_float8 */
1262+
returnDirectFunctionCall5(in_range_float8_float8,
1263+
Float8GetDatumFast((float8)PG_GETARG_FLOAT4(0)),
1264+
Float8GetDatumFast((float8)PG_GETARG_FLOAT4(1)),
1265+
PG_GETARG_DATUM(2),
1266+
PG_GETARG_DATUM(3),
1267+
PG_GETARG_DATUM(4));
1268+
}
1269+
11831270

11841271
/*
11851272
*===================

‎src/backend/utils/adt/numeric.c

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2165,6 +2165,81 @@ cmp_numerics(Numeric num1, Numeric num2)
21652165
returnresult;
21662166
}
21672167

2168+
/*
2169+
* in_range support function for numeric.
2170+
*/
2171+
Datum
2172+
in_range_numeric_numeric(PG_FUNCTION_ARGS)
2173+
{
2174+
Numericval=PG_GETARG_NUMERIC(0);
2175+
Numericbase=PG_GETARG_NUMERIC(1);
2176+
Numericoffset=PG_GETARG_NUMERIC(2);
2177+
boolsub=PG_GETARG_BOOL(3);
2178+
boolless=PG_GETARG_BOOL(4);
2179+
boolresult;
2180+
2181+
/*
2182+
* Reject negative or NaN offset. Negative is per spec, and NaN is
2183+
* because appropriate semantics for that seem non-obvious.
2184+
*/
2185+
if (NUMERIC_IS_NAN(offset)||NUMERIC_SIGN(offset)==NUMERIC_NEG)
2186+
ereport(ERROR,
2187+
(errcode(ERRCODE_INVALID_PRECEDING_FOLLOWING_SIZE),
2188+
errmsg("invalid preceding or following size in window function")));
2189+
2190+
/*
2191+
* Deal with cases where val and/or base is NaN, following the rule that
2192+
* NaN sorts after non-NaN (cf cmp_numerics). The offset cannot affect
2193+
* the conclusion.
2194+
*/
2195+
if (NUMERIC_IS_NAN(val))
2196+
{
2197+
if (NUMERIC_IS_NAN(base))
2198+
result= true;/* NAN = NAN */
2199+
else
2200+
result= !less;/* NAN > non-NAN */
2201+
}
2202+
elseif (NUMERIC_IS_NAN(base))
2203+
{
2204+
result=less;/* non-NAN < NAN */
2205+
}
2206+
else
2207+
{
2208+
/*
2209+
* Otherwise go ahead and compute base +/- offset. While it's
2210+
* possible for this to overflow the numeric format, it's unlikely
2211+
* enough that we don't take measures to prevent it.
2212+
*/
2213+
NumericVarvalv;
2214+
NumericVarbasev;
2215+
NumericVaroffsetv;
2216+
NumericVarsum;
2217+
2218+
init_var_from_num(val,&valv);
2219+
init_var_from_num(base,&basev);
2220+
init_var_from_num(offset,&offsetv);
2221+
init_var(&sum);
2222+
2223+
if (sub)
2224+
sub_var(&basev,&offsetv,&sum);
2225+
else
2226+
add_var(&basev,&offsetv,&sum);
2227+
2228+
if (less)
2229+
result= (cmp_var(&valv,&sum) <=0);
2230+
else
2231+
result= (cmp_var(&valv,&sum) >=0);
2232+
2233+
free_var(&sum);
2234+
}
2235+
2236+
PG_FREE_IF_COPY(val,0);
2237+
PG_FREE_IF_COPY(base,1);
2238+
PG_FREE_IF_COPY(offset,2);
2239+
2240+
PG_RETURN_BOOL(result);
2241+
}
2242+
21682243
Datum
21692244
hash_numeric(PG_FUNCTION_ARGS)
21702245
{

‎src/include/catalog/catversion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,6 @@
5353
*/
5454

5555
/*yyyymmddN */
56-
#defineCATALOG_VERSION_NO201802061
56+
#defineCATALOG_VERSION_NO201802241
5757

5858
#endif

‎src/include/catalog/pg_amproc.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ DATA(insert (1970 700 701 1 2194 ));
105105
DATA(insert (19707017011355 ));
106106
DATA(insert (197070170123133 ));
107107
DATA(insert (197070170012195 ));
108+
DATA(insert (197070170134139 ));
109+
DATA(insert (197070070134140 ));
108110
DATA(insert (19748698691926 ));
109111
DATA(insert (197621211350 ));
110112
DATA(insert (1976212123129 ));
@@ -133,6 +135,7 @@ DATA(insert (1986 19 19 1 359 ));
133135
DATA(insert (1986191923135 ));
134136
DATA(insert (19881700170011769 ));
135137
DATA(insert (19881700170023283 ));
138+
DATA(insert (19881700170034141 ));
136139
DATA(insert (198926261356 ));
137140
DATA(insert (1989262623134 ));
138141
DATA(insert (199130301404 ));

‎src/include/catalog/pg_proc.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,12 @@ DATA(insert OID = 4131 ( in_range PGNSP PGUID 12 1 0 0 0 f f f f t f i s 5 0
661661
DESCR("window RANGE support");
662662
DATA(insert OID = 4132 ( in_range PGNSP PGUID 12 1 0 0 0 f f f f t f i s 5 0 16 "21 21 21 16 16" _null_ _null_ _null_ _null_ _null_ in_range_int2_int2 _null_ _null_ _null_ ));
663663
DESCR("window RANGE support");
664+
DATA(insert OID = 4139 ( in_range PGNSP PGUID 12 1 0 0 0 f f f f t f i s 5 0 16 "701 701 701 16 16" _null_ _null_ _null_ _null_ _null_ in_range_float8_float8 _null_ _null_ _null_ ));
665+
DESCR("window RANGE support");
666+
DATA(insert OID = 4140 ( in_range PGNSP PGUID 12 1 0 0 0 f f f f t f i s 5 0 16 "700 700 701 16 16" _null_ _null_ _null_ _null_ _null_ in_range_float4_float8 _null_ _null_ _null_ ));
667+
DESCR("window RANGE support");
668+
DATA(insert OID = 4141 ( in_range PGNSP PGUID 12 1 0 0 0 f f f f t f i s 5 0 16 "1700 1700 1700 16 16" _null_ _null_ _null_ _null_ _null_ in_range_numeric_numeric _null_ _null_ _null_ ));
669+
DESCR("window RANGE support");
664670

665671
DATA(insert OID = 361 ( lseg_distance PGNSP PGUID 12 1 0 0 0 f f f f t f i s 2 0 701 "601 601" _null_ _null_ _null_ _null_ _null_lseg_distance _null_ _null_ _null_ ));
666672
DATA(insert OID = 362 ( lseg_interpt PGNSP PGUID 12 1 0 0 0 f f f f t f i s 2 0 600 "601 601" _null_ _null_ _null_ _null_ _null_lseg_interpt _null_ _null_ _null_ ));

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp