diff --git a/doc/es/mobilitydb-manual.pdf b/doc/es/mobilitydb-manual.pdf index 49167c9736..92c279e7fb 100644 Binary files a/doc/es/mobilitydb-manual.pdf and b/doc/es/mobilitydb-manual.pdf differ diff --git a/doc/es/reference.xml b/doc/es/reference.xml index fe90070c4c..5820ed2a2b 100644 --- a/doc/es/reference.xml +++ b/doc/es/reference.xml @@ -253,23 +253,27 @@ - shift: Desplazar un conjunto o un rango con un valor o intervalo de tiempo + shift: Desplazar con un valor o intervalo de tiempo - scale: Escalar un conjunto o un rango con un valor o intervalo de tiempo + scale: Escalar con un valor o intervalo de tiempo - shiftScale: Desplazar y escalar un conjunto o un rango con los valores o intervalos de tiempo + shiftScale: Desplazar y escalar con los valores o intervalos de tiempo - round: Redondear un conjunto o un rango flotante a un número de decimales + floor, ceil: Redondear al entero inferior o superior - degrees, radians: Convertir un conjunto flotante a grados o radianes + round: Redondear a un número de decimales + + + + degrees, radians: Convertir a grados o radianes @@ -281,7 +285,7 @@ - tprecision: Establecer la precisión temporal del valor de tiempo al intervalo con respecto al origen + tprecision: Establecer la precisión temporal al intervalo con respecto al origen @@ -1127,7 +1131,11 @@ - round: Redondear los valores a un número de posiciones decimales + floor, ceil: Redondear al entero inferior o superior + + + + round: Redondear a un número de posiciones decimales diff --git a/doc/es/set_span_types.xml b/doc/es/set_span_types.xml index 0eaa55c7f6..233854cfa4 100644 --- a/doc/es/set_span_types.xml +++ b/doc/es/set_span_types.xml @@ -707,7 +707,7 @@ SELECT timestamps(tstzspanset '{[2001-01-01, 2001-01-03), (2001-01-03, 2001-01-0 shift - Desplazar un conjunto o un span con un valor o intervalo de tiempo + Desplazar con un valor o intervalo de tiempo shift(numbers,base) → numbers shift(dates,integer) → dates shift(times,interval) → times @@ -728,7 +728,7 @@ SELECT shift(tstzspanset '{[2001-01-01, 2001-01-03], [2001-01-04, 2001-01-05]}', scale - Escalear un conjunto o un rango con un valor o intervalo de tiempo + Escalear con un valor o intervalo de tiempo scale(numbers,base) → numbers scale(dates,integer) → dates scale(times,interval) → times @@ -756,7 +756,7 @@ SELECT scale(tstzset '{2001-01-01}', '-1 day'); shiftScale - Desplazar y escalear un conjunto o un rango con los valores o intervalos de tiempo + Desplazar y escalear con los valores o intervalos de tiempo shiftScale(numbers,base,base) → numbers shiftScale(dates,integer,integer) → dates shiftScale(times,interval,interval) → times @@ -781,9 +781,27 @@ SELECT shiftScale(tstzspanset '{[2001-01-01, 2001-01-03], [2001-01-04, 2001-01-0 - + + floor + ceil + Redondear al entero inferior o superior + floor({floatset,floatspans}) → {floatset,floatspans} + ceil({floatset,floatspans}) → {floatset,floatspans} + +SELECT floor(floatset '{1.5,2.5}'); +-- {1, 2} +SELECT ceil(floatspan '[1.5,2.5)'); +-- [2, 3) +SELECT floor(floatspan '(1.5, 1.6)'); +-- [1, 1] +SELECT ceil(floatspanset '{[1.5, 2.5],[3.5,4.5]}'); +-- {[2, 3], [4, 5]} + + + + round - Redondear un conjunto o un rango flotante a un número de decimales + Redondear a un número de decimales round({floatset,floatspans},integer=0) → {floatset,floatspans} SELECT round(floatset '{1.123456789,2.123456789}', 3); @@ -800,7 +818,7 @@ SELECT round(floatspanset '{[1.123456789, 2.123456789],[3.123456789,4.123456789] degrees radians - Convertir un conjunto flotante a grados o radianes + Convertir a grados o radianes degrees(floatset, normalize=false) → floatset radians(floatset) → floatset El parámetro adicional en la función degrees puede ser utilizado para normalizar los valores entre 0 y 360 grados. diff --git a/doc/es/temporal_types_alpha.xml b/doc/es/temporal_types_alpha.xml index 4b97f94ac9..6fb6da9c74 100644 --- a/doc/es/temporal_types_alpha.xml +++ b/doc/es/temporal_types_alpha.xml @@ -153,9 +153,23 @@ SELECT deltaValue(tfloat '{[1.5@2001-01-01, 2@2001-01-02, 1@2001-01-03], + + floor + ceil + Redondear al entero inferior o superior + floor(tfloat) → tfloat + ceil(tfloat) → tfloat + +SELECT floor(tfloat '[0.5@2001-01-01, 1.5@2001-01-02]'); +-- [0@2001-01-01, 1@2001-01-02] +SELECT ceil(tfloat '[0.5@2001-01-01, 0.6@2001-01-02, 0.7@2001-01-03]'); +-- [1@2001-01-01, 1@2001-01-03] + + + round - Redondear los valores a un número de posiciones decimales + Redondear a un número de posiciones decimales round(tfloat,integer=0) → tfloat SELECT round(tfloat '[0.785398163397448@2001-01-01, 2.356194490192345@2001-01-02]', 2); diff --git a/doc/mobilitydb-manual.pdf b/doc/mobilitydb-manual.pdf index 594d70dfc5..826d05ff69 100644 Binary files a/doc/mobilitydb-manual.pdf and b/doc/mobilitydb-manual.pdf differ diff --git a/doc/reference.xml b/doc/reference.xml index 9e5dbd9a0a..bca76e6362 100644 --- a/doc/reference.xml +++ b/doc/reference.xml @@ -252,23 +252,27 @@ - shift: Shift the set or span by a value or interval + shift: Shift by a value or interval - scale: Scale the set or span by a value or interval + scale: Scale by a value or interval - shiftScale: Shift and scale the set or span by the values or intervals + shiftScale: Shift and scale by the values or intervals - round: Round the bounds of a float set or span to a number of decimal places + floor, ceil: Round down or up to the lowest integer - degrees, radians: Convert a float set to degrees or radians + round: Round to a number of decimal places + + + + degrees, radians: Transform to degrees or radians @@ -280,7 +284,7 @@ - tprecision: Set the temporal precision of the time value to the interval with respect to the origin + tprecision: Set the temporal precision to the interval with respect to the origin @@ -1094,6 +1098,10 @@ deltaValue: Return the value difference between consecutive instants of the temporal number + + floor, ceil: Round down or up to the nearest integer + + round: Round the values to a number of decimal places diff --git a/doc/set_span_types.xml b/doc/set_span_types.xml index 9e49e5f39f..96dd19d649 100644 --- a/doc/set_span_types.xml +++ b/doc/set_span_types.xml @@ -695,7 +695,7 @@ SELECT timestamps(tstzspanset '{[2001-01-01, 2001-01-03), (2001-01-03, 2001-01-0 shift - Shift the set or span by a value or interval + Shift by a value or interval shift(numbers,base) → numbers shift(dates,integer) → dates shift(times,interval) → times @@ -716,7 +716,7 @@ SELECT shift(tstzspanset '{[2001-01-01, 2001-01-03], [2001-01-04, 2001-01-05]}', scale - Scale the set or span by a value or interval + Scale by a value or interval scale(numbers,base) → numbers scale(dates,integer) → dates scale(times,interval) → times @@ -744,7 +744,7 @@ SELECT scale(tstzset '{2001-01-01}', '-1 day'); shiftScale - Shift and scale the set or span by the values or intervals + Shift and scale by the values or intervals shiftScale(numbers,base,base) → numbers shiftScale(dates,integer,integer) → dates shiftScale(times,interval,interval) → times @@ -769,9 +769,27 @@ SELECT shiftScale(tstzspanset '{[2001-01-01, 2001-01-03], [2001-01-04, 2001-01-0 - + + floor + ceil + Round down or up to the nearest integer + floor({floatset,floatspans}) → {floatset,floatspans} + ceil({floatset,floatspans}) → {floatset,floatspans} + +SELECT floor(floatset '{1.5,2.5}'); +-- {1, 2} +SELECT ceil(floatspan '[1.5,2.5)'); +-- [2, 3) +SELECT floor(floatspan '(1.5, 1.6)'); +-- [1, 1] +SELECT ceil(floatspanset '{[1.5, 2.5],[3.5,4.5]}'); +-- {[2, 3], [4, 5]} + + + + round - Round a float set, span, or span set to a number of decimal places + Round to a number of decimal places round({floatset,floatspans},integer=0) → {floatset,floatspans} SELECT round(floatset '{1.123456789,2.123456789}', 3); @@ -788,7 +806,7 @@ SELECT round(floatspanset '{[1.123456789, 2.123456789],[3.123456789,4.123456789] degrees radians - Convert a flot set to degrees or radians + Convert to degrees or radians degrees(floatset, normalize=false) → floatset radians(floatset) → floatset The additional parameter in the degrees function can be used to normalize the values between 0 and 360 degrees. diff --git a/doc/temporal_types_alpha.xml b/doc/temporal_types_alpha.xml index 003fee81d0..f0f49f3cf2 100644 --- a/doc/temporal_types_alpha.xml +++ b/doc/temporal_types_alpha.xml @@ -153,9 +153,23 @@ SELECT deltaValue(tfloat '{[1.5@2001-01-01, 2@2001-01-02, 1@2001-01-03], + + floor + ceil + Round up or down to the neareast integer + floor(tfloat) → tfloat + ceil(tfloat) → tfloat + +SELECT floor(tfloat '[0.5@2001-01-01, 1.5@2001-01-02]'); +-- [0@2001-01-01, 1@2001-01-02] +SELECT ceil(tfloat '[0.5@2001-01-01, 0.6@2001-01-02, 0.7@2001-01-03]'); +-- [1@2001-01-01, 1@2001-01-03] + + + round - Round the values to a number of decimal places + Round to a number of decimal places round(tfloat,integer=0) → tfloat SELECT round(tfloat '[0.785398163397448@2001-01-01, 2.356194490192345@2001-01-02]', 2); diff --git a/meos/include/general/span.h b/meos/include/general/span.h index b199eb22f7..f285b5dcc9 100644 --- a/meos/include/general/span.h +++ b/meos/include/general/span.h @@ -39,6 +39,7 @@ #include /* MEOS */ #include +#include "general/temporal.h" #include "general/meos_catalog.h" /*****************************************************************************/ @@ -92,6 +93,7 @@ extern Datum span_incr_bound(Datum upper, meosType basetype); extern Span *spanarr_normalize(Span *spans, int count, bool sort, int *newcount); extern void span_bounds(const Span *s, double *xmin, double *xmax); +extern void floatspan_floor_ceil_iter(Span *s, datum_func1 func); extern void lower_upper_shift_scale_value(Datum shift, Datum width, meosType type, bool hasshift, bool haswidth, Datum *lower, Datum *upper); extern void lower_upper_shift_scale_time(const Interval *shift, diff --git a/meos/include/general/temporal.h b/meos/include/general/temporal.h index 9d336570e6..ae0bff1394 100644 --- a/meos/include/general/temporal.h +++ b/meos/include/general/temporal.h @@ -73,8 +73,8 @@ #define CONTINUOUS false /** Symbolic constants for sets and for normalizing spans */ -#define ORDERED true -#define ORDERED_NO false +#define ORDER true +#define ORDER_NO false /** Symbolic constants for the output of string elements */ #define QUOTES true diff --git a/meos/include/meos.h b/meos/include/meos.h index d36aa1450b..678fbcd83e 100644 --- a/meos/include/meos.h +++ b/meos/include/meos.h @@ -488,7 +488,7 @@ extern Span *intspan_make(int lower, int upper, bool lower_inc, bool upper_inc); extern Set *set_copy(const Set *s); extern Span *span_copy(const Span *s); extern SpanSet *spanset_copy(const SpanSet *ss); -extern SpanSet *spanset_make(Span *spans, int count, bool normalize, bool ordered); +extern SpanSet *spanset_make(Span *spans, int count, bool normalize, bool order); extern Set *textset_make(const text **values, int count); extern Set *tstzset_make(const TimestampTz *values, int count); extern Span *tstzspan_make(TimestampTz lower, TimestampTz upper, bool lower_inc, bool upper_inc); @@ -629,12 +629,18 @@ extern SpanSet *bigintspanset_shift_scale(const SpanSet *ss, int64 shift, int64 extern Set *dateset_shift_scale(const Set *s, int shift, int width, bool hasshift, bool haswidth); extern Span *datespan_shift_scale(const Span *s, int shift, int width, bool hasshift, bool haswidth); extern SpanSet *datespanset_shift_scale(const SpanSet *ss, int shift, int width, bool hasshift, bool haswidth); +extern Set *floatset_ceil(const Set *s); +extern Set *floatset_floor(const Set *s); extern Set *floatset_degrees(const Set *s, bool normalize); extern Set *floatset_radians(const Set *s); extern Set *floatset_round(const Set *s, int maxdd); extern Set *floatset_shift_scale(const Set *s, double shift, double width, bool hasshift, bool haswidth); +extern Span *floatspan_ceil(const Span *s); +extern Span *floatspan_floor(const Span *s); extern Span *floatspan_round(const Span *s, int maxdd); extern Span *floatspan_shift_scale(const Span *s, double shift, double width, bool hasshift, bool haswidth); +extern SpanSet *floatspanset_ceil(const SpanSet *ss); +extern SpanSet *floatspanset_floor(const SpanSet *ss); extern SpanSet *floatspanset_round(const SpanSet *ss, int maxdd); extern SpanSet *floatspanset_shift_scale(const SpanSet *ss, double shift, double width, bool hasshift, bool haswidth); extern Set *geoset_round(const Set *s, int maxdd); @@ -1426,6 +1432,8 @@ extern Temporal *temporal_shift_time(const Temporal *temp, const Interval *shift extern TInstant *temporal_to_tinstant(const Temporal *temp); extern TSequence *temporal_to_tsequence(const Temporal *temp, char *interp_str); extern TSequenceSet *temporal_to_tsequenceset(const Temporal *temp, char *interp_str); +extern Temporal *tfloat_floor(const Temporal *temp); +extern Temporal *tfloat_ceil(const Temporal *temp); extern Temporal *tfloat_degrees(const Temporal *temp, bool normalize); extern Temporal *tfloat_radians(const Temporal *temp); extern Temporal *tfloat_round(const Temporal *temp, int maxdd); diff --git a/meos/include/meos_internal.h b/meos/include/meos_internal.h index cc42bb4e59..99e321aa85 100644 --- a/meos/include/meos_internal.h +++ b/meos/include/meos_internal.h @@ -165,6 +165,8 @@ #define DatumGetTimestampTz(X)((TimestampTz) DatumGetInt64(X)) #endif /* MEOS */ +extern Datum datum_floor(Datum d); +extern Datum datum_ceil(Datum d); extern Datum datum_degrees(Datum d, Datum normalize); extern Datum datum_radians(Datum d); extern uint32 datum_hash(Datum d, meosType basetype); @@ -276,15 +278,15 @@ extern char *spanset_out(const SpanSet *ss, int maxdd); /* Constructor functions for set and span types */ extern Set *set_cp(const Set *s); -extern Set *set_make(const Datum *values, int count, meosType basetype, bool ordered); -extern Set *set_make_exp(const Datum *values, int count, int maxcount, meosType basetype, bool ordered); -extern Set *set_make_free(Datum *values, int count, meosType basetype, bool ordered); +extern Set *set_make(const Datum *values, int count, meosType basetype, bool order); +extern Set *set_make_exp(const Datum *values, int count, int maxcount, meosType basetype, bool order); +extern Set *set_make_free(Datum *values, int count, meosType basetype, bool order); extern Span *span_cp(const Span *s); extern Span *span_make(Datum lower, Datum upper, bool lower_inc, bool upper_inc, meosType basetype); extern void span_set(Datum lower, Datum upper, bool lower_inc, bool upper_inc, meosType basetype, meosType spantype, Span *s); extern SpanSet *spanset_cp(const SpanSet *ss); -extern SpanSet *spanset_make_exp(Span *spans, int count, int maxcount, bool normalize, bool ordered); -extern SpanSet *spanset_make_free(Span *spans, int count, bool normalize, bool ordered); +extern SpanSet *spanset_make_exp(Span *spans, int count, int maxcount, bool normalize, bool order); +extern SpanSet *spanset_make_free(Span *spans, int count, bool normalize, bool order); /*****************************************************************************/ diff --git a/meos/src/general/set.c b/meos/src/general/set.c index 015bed9ace..d6035dd248 100644 --- a/meos/src/general/set.c +++ b/meos/src/general/set.c @@ -670,11 +670,12 @@ SET_VAL_N(const Set *s, int index) * @param[in] count Number of elements in the array * @param[in] maxcount Maximum number of elements in the array * @param[in] basetype Type of the values - * @param[in] ordered True when the values are ordered and without duplicates + * @param[in] order True when the values should be ordered and duplicates + * should be removed */ Set * set_make_exp(const Datum *values, int count, int maxcount, meosType basetype, - bool ordered) + bool order) { assert(values); assert(count > 0); assert(count <= maxcount); bool hasz = false; @@ -702,7 +703,7 @@ set_make_exp(const Datum *values, int count, int maxcount, meosType basetype, /* Sort the values and remove duplicates */ Datum *newvalues; int newcount; - if (! ordered && count > 1) + if (order && count > 1) { /* Sort the values and remove duplicates */ newvalues = palloc(sizeof(Datum) * count); @@ -762,7 +763,7 @@ set_make_exp(const Datum *values, int count, int maxcount, meosType basetype, Set *result = palloc0(memsize); SET_VARSIZE(result, memsize); MEOS_FLAGS_SET_BYVAL(result->flags, typbyval); - MEOS_FLAGS_SET_ORDERED(result->flags, ordered); + MEOS_FLAGS_SET_ORDERED(result->flags, ! order); if (geo_basetype(basetype)) { MEOS_FLAGS_SET_X(result->flags, true); @@ -802,7 +803,7 @@ set_make_exp(const Datum *values, int count, int maxcount, meosType basetype, if (bboxsize != 0) valuearr_compute_bbox(newvalues, basetype, newcount, SET_BBOX_PTR(result)); - if (! ordered && count > 1) + if (order && count > 1) pfree(newvalues); return result; } @@ -814,14 +815,15 @@ set_make_exp(const Datum *values, int count, int maxcount, meosType basetype, * @param[in] values Array of values * @param[in] count Number of elements in the array * @param[in] basetype Type of the values - * @param[in] ordered True when the values are ordered and without duplicates + * @param[in] order True when the values should be ordered and duplicates + * should be removed * @csqlfn #Set_constructor() */ Set * -set_make(const Datum *values, int count, meosType basetype, bool ordered) +set_make(const Datum *values, int count, meosType basetype, bool order) { assert(values); assert(count > 0); - return set_make_exp(values, count, count, basetype, ordered); + return set_make_exp(values, count, count, basetype, order); } /** @@ -841,7 +843,7 @@ intset_make(const int *values, int count) Datum *datums = palloc(sizeof(Datum) * count); for (int i = 0; i < count; ++i) datums[i] = Int32GetDatum(values[i]); - return set_make_free(datums, count, T_INT4, ORDERED_NO); + return set_make_free(datums, count, T_INT4, ORDER); } /** @@ -861,7 +863,7 @@ bigintset_make(const int64 *values, int count) Datum *datums = palloc(sizeof(Datum) * count); for (int i = 0; i < count; ++i) datums[i] = Int64GetDatum(values[i]); - return set_make_free(datums, count, T_INT8, ORDERED_NO); + return set_make_free(datums, count, T_INT8, ORDER); } /** @@ -881,7 +883,7 @@ floatset_make(const double *values, int count) Datum *datums = palloc(sizeof(Datum) * count); for (int i = 0; i < count; ++i) datums[i] = Float8GetDatum(values[i]); - return set_make_free(datums, count, T_FLOAT8, ORDERED_NO); + return set_make_free(datums, count, T_FLOAT8, ORDER); } /** @@ -901,7 +903,7 @@ textset_make(const text **values, int count) Datum *datums = palloc(sizeof(Datum) * count); for (int i = 0; i < count; ++i) datums[i] = PointerGetDatum(values[i]); - return set_make_free(datums, count, T_TEXT, ORDERED_NO); + return set_make_free(datums, count, T_TEXT, ORDER); } /** @@ -921,7 +923,7 @@ dateset_make(const DateADT *values, int count) Datum *datums = palloc(sizeof(Datum) * count); for (int i = 0; i < count; ++i) datums[i] = DateADTGetDatum(values[i]); - return set_make_free(datums, count, T_DATE, ORDERED_NO); + return set_make_free(datums, count, T_DATE, ORDER); } /** @@ -941,7 +943,7 @@ tstzset_make(const TimestampTz *values, int count) Datum *datums = palloc(sizeof(Datum) * count); for (int i = 0; i < count; ++i) datums[i] = TimestampTzGetDatum(values[i]); - return set_make_free(datums, count, T_TIMESTAMPTZ, ORDERED_NO); + return set_make_free(datums, count, T_TIMESTAMPTZ, ORDER); } /** @@ -963,7 +965,7 @@ geoset_make(const GSERIALIZED **values, int count) datums[i] = PointerGetDatum(values[i]); meosType geotype = FLAGS_GET_GEODETIC(values[0]->gflags) ? T_GEOMETRY : T_GEOGRAPHY; - return set_make_free(datums, count, geotype, ORDERED_NO); + return set_make_free(datums, count, geotype, ORDER); } #endif /* MEOS */ @@ -974,15 +976,16 @@ geoset_make(const GSERIALIZED **values, int count) * @param[in] values Array of values * @param[in] count Number of elements in the array * @param[in] basetype Type of the values - * @param[in] ordered True when the values are ordered and without duplicates + * @param[in] order True when the values should be ordered and duplicates + * should be removed */ Set * -set_make_free(Datum *values, int count, meosType basetype, bool ordered) +set_make_free(Datum *values, int count, meosType basetype, bool order) { assert(values); assert(count >= 0); Set *result = NULL; if (count > 0) - result = set_make_exp(values, count, count, basetype, ordered); + result = set_make_exp(values, count, count, basetype, order); pfree(values); return result; } @@ -1031,7 +1034,7 @@ set_copy(const Set *s) Set * value_to_set(Datum value, meosType basetype) { - return set_make_exp(&value, 1, 1, basetype, ORDERED); + return set_make_exp(&value, 1, 1, basetype, ORDER_NO); } #if MEOS @@ -1045,7 +1048,7 @@ Set * int_to_set(int i) { Datum v = Int32GetDatum(i); - return set_make_exp(&v, 1, 1, T_INT4, ORDERED); + return set_make_exp(&v, 1, 1, T_INT4, ORDER_NO); } /** @@ -1058,7 +1061,7 @@ Set * bigint_to_set(int64 i) { Datum v = Int64GetDatum(i); - return set_make_exp(&v, 1, 1, T_INT8, ORDERED); + return set_make_exp(&v, 1, 1, T_INT8, ORDER_NO); } /** @@ -1071,7 +1074,7 @@ Set * float_to_set(double d) { Datum v = Float8GetDatum(d); - return set_make_exp(&v, 1, 1, T_FLOAT8, ORDERED); + return set_make_exp(&v, 1, 1, T_FLOAT8, ORDER_NO); } /** @@ -1087,7 +1090,7 @@ text_to_set(text *txt) if (! ensure_not_null((void *) txt)) return NULL; Datum v = PointerGetDatum(txt); - return set_make_exp(&v, 1, 1, T_TEXT, ORDERED); + return set_make_exp(&v, 1, 1, T_TEXT, ORDER_NO); } /** @@ -1100,7 +1103,7 @@ Set * date_to_set(DateADT d) { Datum v = DateADTGetDatum(d); - return set_make_exp(&v, 1, 1, T_DATE, ORDERED); + return set_make_exp(&v, 1, 1, T_DATE, ORDER_NO); } /** @@ -1113,7 +1116,7 @@ Set * timestamptz_to_set(TimestampTz t) { Datum v = TimestampTzGetDatum(t); - return set_make_exp(&v, 1, 1, T_TIMESTAMPTZ, ORDERED); + return set_make_exp(&v, 1, 1, T_TIMESTAMPTZ, ORDER_NO); } /** @@ -1130,7 +1133,7 @@ geo_to_set(GSERIALIZED *gs) return NULL; Datum v = PointerGetDatum(gs); meosType geotype = FLAGS_GET_GEODETIC(gs->gflags) ? T_GEOGRAPHY : T_GEOMETRY; - return set_make_exp(&v, 1, 1, geotype, ORDERED); + return set_make_exp(&v, 1, 1, geotype, ORDER_NO); } #endif /* MEOS */ @@ -1153,7 +1156,7 @@ intset_floatset(const Set *s) for (int i = 0; i < s->count; i++) values[i] = Float8GetDatum((double) DatumGetInt32(SET_VAL_N(s, i))); /* All distinct integers will yield distinct floats */ - return set_make_free(values, s->count, T_FLOAT8, ORDERED); + return set_make_free(values, s->count, T_FLOAT8, ORDER_NO); } #if MEOS @@ -1190,7 +1193,7 @@ floatset_intset(const Set *s) for (int i = 0; i < s->count; i++) values[i] = Int32GetDatum((int) DatumGetFloat8(SET_VAL_N(s, i))); /* Two distinct floats can yield the same integer */ - return set_make_free(values, s->count, T_INT4, ORDERED_NO); + return set_make_free(values, s->count, T_INT4, ORDER); } #if MEOS @@ -1228,7 +1231,7 @@ dateset_tstzset(const Set *s) values[i] = TimestampTzGetDatum(date_to_timestamptz(DatumGetDateADT( SET_VAL_N(s, i)))); /* All distinct dates will yield distinct timestamptz */ - return set_make_free(values, s->count, T_TIMESTAMPTZ, ORDERED); + return set_make_free(values, s->count, T_TIMESTAMPTZ, ORDER_NO); } #if MEOS @@ -1266,7 +1269,7 @@ tstzset_dateset(const Set *s) values[i] = DateADTGetDatum(timestamptz_to_date(DatumGetTimestampTz( SET_VAL_N(s, i)))); /* Two distinct timestamptz can yield the same date */ - return set_make_free(values, s->count, T_DATE, ORDERED_NO); + return set_make_free(values, s->count, T_DATE, ORDER); } #if MEOS @@ -1943,17 +1946,53 @@ Set * set_compact(const Set *s) { assert(s); - /* Collect the values which may be UNORDERED */ + /* Collect the values which may be not ordered */ Datum *values = palloc(sizeof(Datum) * s->count); for (int i = 0; i < s->count; i++) values[i] = SET_VAL_N(s, i); - Set *result = set_make_exp(values, s->count, s->count, s->basetype, ORDERED); + Set *result = set_make_exp(values, s->count, s->count, s->basetype, ORDER_NO); pfree(values); return result; } #endif /* MEOS */ +/** + * @ingroup meos_internal_setspan_transf + * @brief Return a float set rounded down to the nearest integer + * @csqlfn #Floatset_floor() + */ +Set * +floatset_floor(const Set *s) +{ + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_set_isof_type(s, T_FLOATSET)) + return NULL; + + Datum *values = palloc(sizeof(Datum) * s->count); + for (int i = 0; i < s->count; i++) + values[i] = datum_floor(SET_VAL_N(s, i)); + return set_make_exp(values, s->count, s->count, T_FLOAT8, ORDER); +} + +/** + * @ingroup meos_internal_setspan_transf + * @brief Return a float set rounded up to the nearest integer + * @csqlfn #Floatset_ceil() + */ +Set * +floatset_ceil(const Set *s) +{ + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_set_isof_type(s, T_FLOATSET)) + return NULL; + + Datum *values = palloc(sizeof(Datum) * s->count); + for (int i = 0; i < s->count; i++) + values[i] = datum_ceil(SET_VAL_N(s, i)); + return set_make_exp(values, s->count, s->count, T_FLOAT8, ORDER); +} + /** * @ingroup meos_internal_setspan_transf * @brief Return a float set with the values converted to degrees @@ -2038,7 +2077,7 @@ textset_lower(const Set *s) Datum *values = palloc(sizeof(Datum) * s->count); for (int i = 0; i < s->count; i++) values[i] = datum_lower(SET_VAL_N(s, i)); - return set_make_free(values, s->count, T_TEXT, ORDERED); + return set_make_free(values, s->count, T_TEXT, ORDER_NO); } /** @@ -2057,7 +2096,7 @@ textset_upper(const Set *s) Datum *values = palloc(sizeof(Datum) * s->count); for (int i = 0; i < s->count; i++) values[i] = datum_upper(SET_VAL_N(s, i)); - return set_make_free(values, s->count, T_TEXT, ORDERED); + return set_make_free(values, s->count, T_TEXT, ORDER_NO); } /** @@ -2076,7 +2115,7 @@ textset_initcap(const Set *s) Datum *values = palloc(sizeof(Datum) * s->count); for (int i = 0; i < s->count; i++) values[i] = datum_initcap(SET_VAL_N(s, i)); - return set_make_free(values, s->count, T_TEXT, ORDERED); + return set_make_free(values, s->count, T_TEXT, ORDER_NO); } /** @@ -2094,7 +2133,7 @@ textcat_textset_text_int(const Set *s, const text *txt, bool invert) values[i] = invert ? datum_textcat(PointerGetDatum(txt), SET_VAL_N(s, i)) : datum_textcat(SET_VAL_N(s, i), PointerGetDatum(txt)); - return set_make_free(values, s->count, T_TEXT, ORDERED); + return set_make_free(values, s->count, T_TEXT, ORDER_NO); } #if MEOS diff --git a/meos/src/general/set_aggfuncs_meos.c b/meos/src/general/set_aggfuncs_meos.c index a43c306ae3..9099b83e7e 100644 --- a/meos/src/general/set_aggfuncs_meos.c +++ b/meos/src/general/set_aggfuncs_meos.c @@ -153,7 +153,7 @@ set_append_value_exp(Set *set, Datum value) #endif /* DEBUG_EXPAND */ Set *result = set_make_exp(values, set->count + 1, maxcount, set->basetype, - ORDERED_NO); + ORDER); pfree(values); pfree(set); return result; } @@ -171,7 +171,7 @@ value_union_transfn(Set *state, Datum value, meosType basetype) /* Null state: create a new state with the value */ if (! state) /* Arbitrary initialization to 64 elements */ - return set_make_exp(&value, 1, 64, basetype, ORDERED_NO); + return set_make_exp(&value, 1, 64, basetype, ORDER); return set_append_value_exp(state, value); } @@ -284,7 +284,7 @@ set_union_transfn(Set *state, Set *s) { Datum value = SET_VAL_N(s, 0); /* Arbitrary initialization to 64 elements */ - state = set_make_exp(&value, 1, 64, s->basetype, ORDERED_NO); + state = set_make_exp(&value, 1, 64, s->basetype, ORDER); } /* Ensure validity of the arguments */ @@ -313,7 +313,7 @@ set_union_finalfn(Set *state) values[i] = SET_VAL_N(state, i); meosType basetype = settype_basetype(state->settype); Set *result = set_make_exp(values, state->count, state->count, basetype, - ORDERED_NO); + ORDER); /* Free memory */ pfree(values); diff --git a/meos/src/general/set_ops.c b/meos/src/general/set_ops.c index c77bd50554..8c847354bb 100644 --- a/meos/src/general/set_ops.c +++ b/meos/src/general/set_ops.c @@ -167,7 +167,7 @@ setop_set_set(const Set *s1, const Set *s2, SetOper op) while (j < s2->count) values[nvals++] = SET_VAL_N(s2, j++); } - return set_make_free(values, nvals, basetype, ORDERED); + return set_make_free(values, nvals, basetype, ORDER_NO); } /***************************************************************************** @@ -1541,7 +1541,7 @@ union_set_value(const Set *s, Datum value) } if (! found) values[nvals++] = value; - return set_make_free(values, nvals, s->basetype, ORDERED); + return set_make_free(values, nvals, s->basetype, ORDER_NO); } /** @@ -2252,7 +2252,7 @@ minus_set_value(const Set *s, Datum value) if (datum_ne(value, value1, s->basetype)) values[nvals++] = value1; } - return set_make_free(values, nvals, s->basetype, ORDERED); + return set_make_free(values, nvals, s->basetype, ORDER_NO); } #if MEOS diff --git a/meos/src/general/span.c b/meos/src/general/span.c index 5a67a6b79e..b1f7bdaf69 100644 --- a/meos/src/general/span.c +++ b/meos/src/general/span.c @@ -304,16 +304,16 @@ span_decr_bound(Datum lower, meosType basetype) * The normalized spans are new spans that must be freed. * @param[in] spans Array of spans * @param[in] count Number of elements in the input array - * @param[in] ordered True if the spans are ordered + * @param[in] order True if the spans should be ordered * @param[out] newcount Number of elements in the output array * @pre @p count is greater than 0 */ Span * -spanarr_normalize(Span *spans, int count, bool ordered, int *newcount) +spanarr_normalize(Span *spans, int count, bool order, int *newcount) { assert(spans); assert(count > 0); assert(newcount); /* Sort the spans if they are not ordered */ - if (! ordered) + if (order) spanarr_sort(spans, count); int nspans = 0; Span *result = palloc(sizeof(Span) * count); @@ -1417,6 +1417,61 @@ tstzspan_duration(const Span *s) * Transformation functions *****************************************************************************/ +/** + * @brief Round down a span to the nearest integer + */ +void +floatspan_floor_ceil_iter(Span *s, datum_func1 func) +{ + assert(s); + Datum lower = func(s->lower); + Datum upper = func(s->upper); + bool lower_inc = s->lower_inc; + bool upper_inc = s->upper_inc; + if (datum_eq(lower, upper, s->basetype)) + { + lower_inc = upper_inc = true; + } + span_set(lower, upper, lower_inc, upper_inc, s->basetype, s->spantype, s); + return; +} + +/** + * @ingroup meos_internal_setspan_transf + * @brief Return a float span rounded down to the nearest integer + * @csqlfn #Floatspan_floor() + */ +Span * +floatspan_floor(const Span *s) +{ + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_span_isof_type(s, T_FLOATSPAN)) + return NULL; + + Span *result = span_cp(s); + floatspan_floor_ceil_iter(result, &datum_floor); + return result; +} + +/** + * @ingroup meos_internal_setspan_transf + * @brief Return a float span rounded up to the nearest integer + * @csqlfn #Floatspan_ceil() + */ +Span * +floatspan_ceil(const Span *s) +{ + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_span_isof_type(s, T_FLOATSPAN)) + return NULL; + + Span *result = span_cp(s); + floatspan_floor_ceil_iter(result, &datum_ceil); + return result; +} + +/*****************************************************************************/ + /** * @ingroup meos_internal_setspan_transf * @brief Return the second span expanded with the first one diff --git a/meos/src/general/span_aggfuncs_meos.c b/meos/src/general/span_aggfuncs_meos.c index af39ac60e8..df0be06318 100644 --- a/meos/src/general/span_aggfuncs_meos.c +++ b/meos/src/general/span_aggfuncs_meos.c @@ -80,7 +80,7 @@ spanset_append_span(SpanSet *ss, const Span *span, bool expand) #endif /* DEBUG_EXPAND */ SpanSet *result = spanset_make_exp(spans, ss->count + 1, maxcount, - NORMALIZE_NO, ORDERED_NO); + NORMALIZE_NO, ORDER); pfree(spans); // pfree(ss); return result; @@ -127,7 +127,7 @@ spanset_append_spanset(SpanSet *ss1, const SpanSet *ss2, bool expand) #endif /* DEBUG_EXPAND */ SpanSet *result = spanset_make_exp(spans, count, maxcount, NORMALIZE_NO, - ORDERED_NO); + ORDER); pfree(spans); return result; } @@ -147,7 +147,7 @@ span_union_transfn(SpanSet *state, const Span *s) /* Null state: create a new span set with the input span */ if (! state) /* Arbitrary initialization to 64 elements */ - return spanset_make_exp((Span *) s, 1, 64, NORMALIZE_NO, ORDERED_NO); + return spanset_make_exp((Span *) s, 1, 64, NORMALIZE_NO, ORDER); /* Ensure validity of the arguments */ if (! ensure_same_span_type(&state->elems[0], s)) @@ -173,7 +173,7 @@ spanset_union_transfn(SpanSet *state, const SpanSet *ss) int count = ((ss->count / 64) + 1) * 64; /* Arbitrary initialization to next multiple of 64 elements */ return spanset_make_exp((Span *) &ss->elems, ss->count, count, - NORMALIZE_NO, ORDERED_NO); + NORMALIZE_NO, ORDER); } /* Ensure validity of the arguments */ diff --git a/meos/src/general/span_ops.c b/meos/src/general/span_ops.c index 85d450b55c..a3186f20f0 100644 --- a/meos/src/general/span_ops.c +++ b/meos/src/general/span_ops.c @@ -1724,7 +1724,7 @@ union_span_span(const Span *s1, const Span *s2) spans[0] = *s2; spans[1] = *s1; } - return spanset_make_exp(spans, 2, 2, NORMALIZE_NO, ORDERED); + return spanset_make_exp(spans, 2, 2, NORMALIZE_NO, ORDER_NO); } /***************************************************************************** @@ -2052,7 +2052,7 @@ minus_span_value(const Span *s, Datum value) int count = mi_span_value(s, value, spans); if (count == 0) return NULL; - return spanset_make_exp(spans, count, count, NORMALIZE_NO, ORDERED); + return spanset_make_exp(spans, count, count, NORMALIZE_NO, ORDER_NO); } #if MEOS @@ -2226,7 +2226,7 @@ minus_span_span(const Span *s1, const Span *s2) int count = mi_span_span(s1, s2, spans); if (count == 0) return NULL; - return spanset_make_exp(spans, count, count, NORMALIZE_NO, ORDERED); + return spanset_make_exp(spans, count, count, NORMALIZE_NO, ORDER_NO); } /****************************************************************************** diff --git a/meos/src/general/spanset.c b/meos/src/general/spanset.c index 96f22b4bfa..f815e369f4 100644 --- a/meos/src/general/spanset.c +++ b/meos/src/general/spanset.c @@ -419,15 +419,15 @@ tstzspanset_out(const SpanSet *ss) * @param[in] count Number of elements in the array * @param[in] maxcount Maximum number of elements in the array * @param[in] normalize True when the resulting value should be normalized - * @param[in] ordered True when the input spans are ordered + * @param[in] order True when the input spans should should be ordered */ SpanSet * spanset_make_exp(Span *spans, int count, int maxcount, bool normalize, - bool ordered) + bool order) { assert(spans); assert(count > 0); assert(count <= maxcount); /* Test the validity of the spans */ - if (ordered) + if (! order) { for (int i = 0; i < count - 1; i++) { @@ -450,7 +450,7 @@ spanset_make_exp(Span *spans, int count, int maxcount, bool normalize, int newcount = count; if (normalize && count > 1) /* Sort the values and remove duplicates */ - newspans = spanarr_normalize(spans, count, ordered, &newcount); + newspans = spanarr_normalize(spans, count, order, &newcount); /* The first element span is already declared in the struct */ size_t memsize = DOUBLE_PAD(sizeof(SpanSet)) + @@ -483,16 +483,16 @@ spanset_make_exp(Span *spans, int count, int maxcount, bool normalize, * @param[in] spans Array of spans * @param[in] count Number of elements in the array * @param[in] normalize True if the resulting value should be normalized - * @param[in] ordered True if the input spans are ordered + * @param[in] order True if the input spans should be ordered * @csqlfn #Spanset_constructor() */ SpanSet * -spanset_make(Span *spans, int count, bool normalize, bool ordered) +spanset_make(Span *spans, int count, bool normalize, bool order) { /* Ensure validity of the arguments */ if (! ensure_not_null((void *) spans) || ! ensure_positive(count)) return NULL; - return spanset_make_exp(spans, count, count, normalize, ordered); + return spanset_make_exp(spans, count, count, normalize, order); } #endif /* MEOS */ @@ -503,16 +503,16 @@ spanset_make(Span *spans, int count, bool normalize, bool ordered) * @param[in] spans Array of spans * @param[in] count Number of elements in the array * @param[in] normalize True if the resulting value should be normalized. - * @param[in] ordered True if the input spans are ordered + * @param[in] order True if the input spans should be ordered * @see #spanset_make */ SpanSet * -spanset_make_free(Span *spans, int count, bool normalize, bool ordered) +spanset_make_free(Span *spans, int count, bool normalize, bool order) { assert(spans); assert(count >= 0); SpanSet *result = NULL; if (count > 0) - result = spanset_make_exp(spans, count, count, normalize, ordered); + result = spanset_make_exp(spans, count, count, normalize, order); pfree(spans); return result; } @@ -564,7 +564,7 @@ value_to_spanset(Datum value, meosType basetype) meosType spantype = basetype_spantype(basetype); Span s; span_set(value, value, true, true, basetype, spantype, &s); - return spanset_make_exp(&s, 1, 1, NORMALIZE_NO, ORDERED); + return spanset_make_exp(&s, 1, 1, NORMALIZE_NO, ORDER_NO); } #if MEOS @@ -646,7 +646,7 @@ set_spanset(const Set *s) Datum value = SET_VAL_N(s, i); span_set(value, value, true, true, s->basetype, spantype, &spans[i]); } - return spanset_make_free(spans, s->count, NORMALIZE, ORDERED); + return spanset_make_free(spans, s->count, NORMALIZE, ORDER_NO); } #if MEOS @@ -676,7 +676,7 @@ SpanSet * span_spanset(const Span *s) { assert(s); - return spanset_make_exp((Span *) s, 1, 1, NORMALIZE_NO, ORDERED); + return spanset_make_exp((Span *) s, 1, 1, NORMALIZE_NO, ORDER_NO); } #if MEOS @@ -714,7 +714,7 @@ intspanset_floatspanset(const SpanSet *ss) Span *spans = palloc(sizeof(Span) * ss->count); for (int i = 0; i < ss->count; i++) intspan_set_floatspan(SPANSET_SP_N(ss, i), &spans[i]); - return spanset_make_free(spans, ss->count, NORMALIZE, ORDERED); + return spanset_make_free(spans, ss->count, NORMALIZE, ORDER_NO); } #if MEOS @@ -750,7 +750,7 @@ floatspanset_intspanset(const SpanSet *ss) Span *spans = palloc(sizeof(Span) * ss->count); for (int i = 0; i < ss->count; i++) floatspan_set_intspan(SPANSET_SP_N(ss, i), &spans[i]); - return spanset_make_free(spans, ss->count, NORMALIZE, ORDERED); + return spanset_make_free(spans, ss->count, NORMALIZE, ORDER_NO); } #if MEOS @@ -786,7 +786,7 @@ datespanset_tstzspanset(const SpanSet *ss) Span *spans = palloc(sizeof(Span) * ss->count); for (int i = 0; i < ss->count; i++) datespan_set_tstzspan(SPANSET_SP_N(ss, i), &spans[i]); - return spanset_make_free(spans, ss->count, NORMALIZE, ORDERED); + return spanset_make_free(spans, ss->count, NORMALIZE, ORDER_NO); } #if MEOS @@ -822,7 +822,7 @@ tstzspanset_datespanset(const SpanSet *ss) Span *spans = palloc(sizeof(Span) * ss->count); for (int i = 0; i < ss->count; i++) tstzspan_set_datespan(SPANSET_SP_N(ss, i), &spans[i]); - return spanset_make_free(spans, ss->count, NORMALIZE, ORDERED_NO); + return spanset_make_free(spans, ss->count, NORMALIZE, ORDER); } #if MEOS @@ -1323,7 +1323,7 @@ datespanset_dates(const SpanSet *ss) dates[ndates++] = s->lower; dates[ndates++] = s->upper; } - return set_make_free(dates, ndates, T_DATE, ORDERED); + return set_make_free(dates, ndates, T_DATE, ORDER_NO); } /** @@ -1497,7 +1497,7 @@ tstzspanset_timestamps(const SpanSet *ss) if (times[ntimes - 1] != s->upper) times[ntimes++] = s->upper; } - return set_make_free(times, ntimes, T_TIMESTAMPTZ, ORDERED); + return set_make_free(times, ntimes, T_TIMESTAMPTZ, ORDER_NO); } /** @@ -1624,12 +1624,54 @@ spanset_compact(const SpanSet *ss) assert(ss); /* Create the final value reusing the array of spans in the span set */ return spanset_make_exp((Span *) &ss->elems, ss->count, ss->count, - NORMALIZE, ORDERED_NO); + NORMALIZE, ORDER); } #endif /* MEOS */ /*****************************************************************************/ +/** + * @ingroup meos_internal_setspan_transf + * @brief Return a float span set rounded down to the nearest integer + * @csqlfn #Floatspanset_floor() + */ +SpanSet * +floatspanset_floor(const SpanSet *ss) +{ + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_spanset_isof_type(ss, T_FLOATSPANSET)) + return NULL; + + Span *spans = palloc(sizeof(Span) * ss->count); + memcpy(spans, ss->elems, sizeof(Span) * ss->count); + for (int i = 0; i < ss->count; i++) + floatspan_floor_ceil_iter(&spans[i], &datum_floor); + return spanset_make_free(spans, ss->count, NORMALIZE, ORDER_NO); +} + +/** + * @ingroup meos_internal_setspan_transf + * @brief Return a float span set rounded up to the nearest integer + * @csqlfn #Floatset_ceil() + */ +SpanSet * +floatspanset_ceil(const SpanSet *ss) +{ + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_spanset_isof_type(ss, T_FLOATSPANSET)) + return NULL; + + Span *spans = palloc(sizeof(Span) * ss->count); + memcpy(spans, ss->elems, sizeof(Span) * ss->count); + for (int i = 0; i < ss->count; i++) + floatspan_floor_ceil_iter(&spans[i], &datum_ceil); + return spanset_make_free(spans, ss->count, NORMALIZE, ORDER_NO); +} + +/*****************************************************************************/ + /** * @ingroup meos_internal_setspan_transf * @brief Return a number set shifted and/or scaled by two intervals diff --git a/meos/src/general/spanset_ops.c b/meos/src/general/spanset_ops.c index a9eac163ae..e454bd8be7 100644 --- a/meos/src/general/spanset_ops.c +++ b/meos/src/general/spanset_ops.c @@ -1931,7 +1931,7 @@ union_spanset_span(const SpanSet *ss, const Span *s) /* Add the remaining component spans if any are left */ while (i < ss->count) spans[nspans++] = *SPANSET_SP_N(ss, i++); - return spanset_make_free(spans, nspans, NORMALIZE_NO, ORDERED); + return spanset_make_free(spans, nspans, NORMALIZE_NO, ORDER_NO); } /** @@ -2030,7 +2030,7 @@ union_spanset_spanset(const SpanSet *ss1, const SpanSet *ss2) spans[nspans++] = *SPANSET_SP_N(ss1, i++); while (j < ss2->count) spans[nspans++] = *SPANSET_SP_N(ss2, j++); - return spanset_make_free(spans, nspans, NORMALIZE_NO, ORDERED); + return spanset_make_free(spans, nspans, NORMALIZE_NO, ORDER_NO); } /***************************************************************************** @@ -2167,7 +2167,7 @@ intersection_spanset_span(const SpanSet *ss, const Span *s) Span s1; if (! inter_span_span(SPANSET_SP_N(ss, 0), s, &s1)) return NULL; - return spanset_make_exp((Span *) &s1, 1, 1, NORMALIZE_NO, ORDERED); + return spanset_make_exp((Span *) &s1, 1, 1, NORMALIZE_NO, ORDER_NO); } /* Ensure validity of the arguments */ @@ -2197,7 +2197,7 @@ intersection_spanset_span(const SpanSet *ss, const Span *s) if (s->upper < s1->upper) break; } - return spanset_make_free(spans, nspans, NORMALIZE_NO, ORDERED); + return spanset_make_free(spans, nspans, NORMALIZE_NO, ORDER_NO); } /** @@ -2260,7 +2260,7 @@ intersection_spanset_spanset(const SpanSet *ss1, const SpanSet *ss2) else j++; } - return spanset_make_free(spans, nspans, NORMALIZE_NO, ORDERED); + return spanset_make_free(spans, nspans, NORMALIZE_NO, ORDER_NO); } /***************************************************************************** @@ -2437,7 +2437,7 @@ minus_span_spanset(const Span *s, const SpanSet *ss) Span *spans = palloc(sizeof(Span) * (ss->count + 1)); int count = mi_span_spanset(s, ss, 0, ss->count, spans); - return spanset_make_free(spans, count, NORMALIZE_NO, ORDERED); + return spanset_make_free(spans, count, NORMALIZE_NO, ORDER_NO); } /** @@ -2459,7 +2459,7 @@ minus_spanset_value(const SpanSet *ss, Datum value) int nspans = 0; for (int i = 0; i < ss->count; i++) nspans += mi_span_value(SPANSET_SP_N(ss, i), value, &spans[nspans]); - return spanset_make_free(spans, nspans, NORMALIZE_NO, ORDERED); + return spanset_make_free(spans, nspans, NORMALIZE_NO, ORDER_NO); } #if MEOS @@ -2580,7 +2580,7 @@ minus_spanset_span(const SpanSet *ss, const Span *s) const Span *s1 = SPANSET_SP_N(ss, i); nspans += mi_span_span(s1, s, &spans[nspans]); } - return spanset_make_free(spans, nspans, NORMALIZE_NO, ORDERED); + return spanset_make_free(spans, nspans, NORMALIZE_NO, ORDER_NO); } /** @@ -2644,7 +2644,7 @@ minus_spanset_spanset(const SpanSet *ss1, const SpanSet *ss2) /* Copy the sequences after the span set */ while (i < ss1->count) spans[nspans++] = *SPANSET_SP_N(ss1, i++); - return spanset_make_free(spans, nspans, NORMALIZE_NO, ORDERED); + return spanset_make_free(spans, nspans, NORMALIZE_NO, ORDER_NO); } /****************************************************************************** diff --git a/meos/src/general/temporal.c b/meos/src/general/temporal.c index 74ed702032..0dc9eda5e4 100644 --- a/meos/src/general/temporal.c +++ b/meos/src/general/temporal.c @@ -1285,6 +1285,78 @@ tnumber_to_tbox(const Temporal *temp) * Transformation functions *****************************************************************************/ +/** + * @brief Return a number rounded down to the nearest integer + */ +Datum +datum_floor(Datum value) +{ + return Float8GetDatum(floor(DatumGetFloat8(value))); +} + +/** + * @brief Return a number rounded up to the nearest integer + */ +Datum +datum_ceil(Datum value) +{ + return Float8GetDatum(ceil(DatumGetFloat8(value))); +} + +/** + * @ingroup meos_temporal_transf + * @brief Return a temporal number rounded down to the nearest integer + * @param[in] temp Temporal value + * @csqlfn #Tfloat_floor() + */ +Temporal * +tfloat_floor(const Temporal *temp) +{ + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_temporal_isof_type(temp, T_TFLOAT)) + return NULL; + + /* We only need to fill these parameters for tfunc_temporal */ + LiftedFunctionInfo lfinfo; + memset(&lfinfo, 0, sizeof(LiftedFunctionInfo)); + lfinfo.func = (varfunc) &datum_floor; + lfinfo.numparam = 0; + lfinfo.argtype[0] = T_TFLOAT; + lfinfo.restype = T_TFLOAT; + lfinfo.tpfunc_base = NULL; + lfinfo.tpfunc = NULL; + return tfunc_temporal(temp, &lfinfo); +} + +/** + * @ingroup meos_temporal_transf + * @brief Return a temporal number rounded up to the nearest integer + * @param[in] temp Temporal value + * @csqlfn #Tfloat_ceil() + */ +Temporal * +tfloat_ceil(const Temporal *temp) +{ + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_temporal_isof_type(temp, T_TFLOAT)) + return NULL; + + /* We only need to fill these parameters for tfunc_temporal */ + LiftedFunctionInfo lfinfo; + memset(&lfinfo, 0, sizeof(LiftedFunctionInfo)); + lfinfo.func = (varfunc) &datum_ceil; + lfinfo.numparam = 0; + lfinfo.argtype[0] = T_TFLOAT; + lfinfo.restype = T_TFLOAT; + lfinfo.tpfunc_base = NULL; + lfinfo.tpfunc = NULL; + return tfunc_temporal(temp, &lfinfo); +} + +/*****************************************************************************/ + /** * @ingroup meos_temporal_transf * @brief Return a float value converted from radians to degrees diff --git a/meos/src/general/temporal_analytics.c b/meos/src/general/temporal_analytics.c index 18af48d499..f0eca291dc 100644 --- a/meos/src/general/temporal_analytics.c +++ b/meos/src/general/temporal_analytics.c @@ -97,7 +97,7 @@ tstzset_tprecision(const Set *s, const Interval *duration, TimestampTz torigin) /* Loop for each value */ for (int i = 0; i < s->count; i++) values[i] = timestamptz_bucket(SET_VAL_N(s, i), duration, torigin); - return set_make_free(values, s->count, T_TIMESTAMPTZ, ORDERED_NO); + return set_make_free(values, s->count, T_TIMESTAMPTZ, ORDER); } /** @@ -169,7 +169,7 @@ tstzspanset_tprecision(const SpanSet *ss, const Interval *duration, lower += tunits; upper += tunits; } - return spanset_make_free(spans, nspans, NORMALIZE, ORDERED); + return spanset_make_free(spans, nspans, NORMALIZE, ORDER_NO); } /***************************************************************************** diff --git a/meos/src/general/tsequence.c b/meos/src/general/tsequence.c index c0c6010cd9..18afc7b883 100644 --- a/meos/src/general/tsequence.c +++ b/meos/src/general/tsequence.c @@ -1886,7 +1886,7 @@ tnumberseq_valuespans(const TSequence *seq) Span *spans = palloc(sizeof(Span) * count); for (int i = 0; i < count; i++) span_set(values[i], values[i], true, true, basetype, spantype, &spans[i]); - SpanSet *result = spanset_make_free(spans, count, NORMALIZE, ORDERED); + SpanSet *result = spanset_make_free(spans, count, NORMALIZE, ORDER_NO); pfree(values); return result; } @@ -1912,7 +1912,7 @@ tsequence_time(const TSequence *seq) TimestampTz t = TSEQUENCE_INST_N(seq, i)->t; span_set(t, t, true, true, T_TIMESTAMPTZ, T_TSTZSPAN, &periods[i]); } - return spanset_make_free(periods, seq->count, NORMALIZE_NO, ORDERED); + return spanset_make_free(periods, seq->count, NORMALIZE_NO, ORDER_NO); } /** diff --git a/meos/src/general/tsequenceset.c b/meos/src/general/tsequenceset.c index a30714a73f..08b44b7349 100644 --- a/meos/src/general/tsequenceset.c +++ b/meos/src/general/tsequenceset.c @@ -818,7 +818,7 @@ tnumberseqset_valuespans(const TSequenceSet *ss) TBox *box = TSEQUENCE_BBOX_PTR(TSEQUENCESET_SEQ_N(ss, i)); memcpy(&spans[i], &box->span, sizeof(Span)); } - return spanset_make_free(spans, ss->count, NORMALIZE, ORDERED_NO); + return spanset_make_free(spans, ss->count, NORMALIZE, ORDER); } /* Temporal sequence number with discrete or step interpolation */ @@ -828,7 +828,7 @@ tnumberseqset_valuespans(const TSequenceSet *ss) spans = palloc(sizeof(Span) * count); for (i = 0; i < count; i++) span_set(values[i], values[i], true, true, basetype, spantype, &spans[i]); - SpanSet *result = spanset_make_free(spans, count, NORMALIZE, ORDERED_NO); + SpanSet *result = spanset_make_free(spans, count, NORMALIZE, ORDER); pfree(values); return result; } @@ -972,7 +972,7 @@ tsequenceset_time(const TSequenceSet *ss) Span *periods = palloc(sizeof(Span) * ss->count); for (int i = 0; i < ss->count; i++) periods[i] = (TSEQUENCESET_SEQ_N(ss, i))->period; - return spanset_make_free(periods, ss->count, NORMALIZE_NO, ORDERED); + return spanset_make_free(periods, ss->count, NORMALIZE_NO, ORDER_NO); } /** diff --git a/meos/src/general/type_in.c b/meos/src/general/type_in.c index 880a0feacf..9cc4ec5cbd 100644 --- a/meos/src/general/type_in.c +++ b/meos/src/general/type_in.c @@ -1396,7 +1396,7 @@ spanset_from_wkb_state(wkb_parse_state *s) /* Read and create the span set */ for (int i = 0; i < count; i++) span_from_wkb_state_iter(s, &spans[i]); - return spanset_make_free(spans, count, NORMALIZE, ORDERED); + return spanset_make_free(spans, count, NORMALIZE, ORDER_NO); } /*****************************************************************************/ @@ -1450,7 +1450,7 @@ set_from_wkb_state(wkb_parse_state *s) /* Read and create the set */ for (int i = 0; i < count; i++) values[i] = basevalue_from_wkb_state(s); - return set_make_free(values, count, s->basetype, ORDERED); + return set_make_free(values, count, s->basetype, ORDER_NO); } /*****************************************************************************/ diff --git a/meos/src/general/type_parser.c b/meos/src/general/type_parser.c index 933bcf7d17..9ffed39b94 100644 --- a/meos/src/general/type_parser.c +++ b/meos/src/general/type_parser.c @@ -472,9 +472,9 @@ set_parse(const char **str, meosType settype) const char *type_str = "set"; int set_srid = 0; p_whitespace(str); - - /* Starts with "SRID=". The SRID specification must be gobbled. We cannot use - * the atoi() function because this requires a string terminated by '\0' + + /* Starts with "SRID=". The SRID specification must be gobbled. We cannot use + * the atoi() function because this requires a string terminated by '\0' * and we cannot modify the string. */ if (pg_strncasecmp(*str, "SRID=", 5) == 0) { @@ -530,7 +530,7 @@ set_parse(const char **str, meosType settype) for (int i = 0; i < count; i++) gserialized_set_srid(DatumGetGserializedP(values[i]), set_srid); } - return set_make_free(values, count, basetype, ORDERED_NO); + return set_make_free(values, count, basetype, ORDER); } /** @@ -637,7 +637,7 @@ spanset_parse(const char **str, meosType spansettype) span_parse(str, spantype, false, &spans[i]); } p_cbrace(str); - return spanset_make_free(spans, count, NORMALIZE, ORDERED); + return spanset_make_free(spans, count, NORMALIZE, ORDER_NO); } /*****************************************************************************/ diff --git a/meos/src/general/type_round.c b/meos/src/general/type_round.c index e8a1c5fd91..553b61ec70 100644 --- a/meos/src/general/type_round.c +++ b/meos/src/general/type_round.c @@ -107,7 +107,7 @@ set_round(const Set *s, int maxdd, datum_func2 func) Datum size = Int32GetDatum(maxdd); for (int i = 0; i < s->count; i++) values[i] = func(SET_VAL_N(s, i), size); - return set_make_free(values, s->count, s->basetype, ORDERED_NO); + return set_make_free(values, s->count, s->basetype, ORDER); } /** @@ -267,7 +267,7 @@ floatspanset_rnd(const SpanSet *ss, int maxdd) Span *spans = palloc(sizeof(Span) * ss->count); for (int i = 0; i < ss->count; i++) floatspan_rnd_set(SPANSET_SP_N(ss, i), maxdd, &spans[i]); - return spanset_make_free(spans, ss->count, NORMALIZE, ORDERED); + return spanset_make_free(spans, ss->count, NORMALIZE, ORDER_NO); } diff --git a/meos/src/npoint/tnpoint.c b/meos/src/npoint/tnpoint.c index d648cd8d83..f63c9d7eb4 100644 --- a/meos/src/npoint/tnpoint.c +++ b/meos/src/npoint/tnpoint.c @@ -389,7 +389,7 @@ tnpointinst_routes(const TInstant *inst) { Npoint *np = DatumGetNpointP(tinstant_val(inst)); Datum value = Int64GetDatum(np->rid); - return set_make_exp(&value, 1, 1, T_INT8, ORDERED); + return set_make_exp(&value, 1, 1, T_INT8, ORDER_NO); } /** @@ -406,7 +406,7 @@ tnpointdiscseq_routes(const TSequence *seq) } datumarr_sort(values, seq->count, T_INT8); int count = datumarr_remove_duplicates(values, seq->count, T_INT8); - return set_make_free(values, count, T_INT8, ORDERED); + return set_make_free(values, count, T_INT8, ORDER_NO); } /** @@ -417,7 +417,7 @@ tnpointcontseq_routes(const TSequence *seq) { const Npoint *np = DatumGetNpointP(tinstant_val(TSEQUENCE_INST_N(seq, 0))); Datum value = Int64GetDatum(np->rid); - return set_make_exp(&value, 1, 1, T_INT8, ORDERED); + return set_make_exp(&value, 1, 1, T_INT8, ORDER_NO); } /** @@ -435,7 +435,7 @@ tnpointseqset_routes(const TSequenceSet *ss) } datumarr_sort(values, ss->count, T_INT8); int count = datumarr_remove_duplicates(values, ss->count, T_INT8); - return set_make_free(values, count, T_INT8, ORDERED); + return set_make_free(values, count, T_INT8, ORDER_NO); } /** diff --git a/meos/src/point/tpoint_restrict.c b/meos/src/point/tpoint_restrict.c index d1b2413217..490b885880 100644 --- a/meos/src/point/tpoint_restrict.c +++ b/meos/src/point/tpoint_restrict.c @@ -516,7 +516,7 @@ tpointseq_interperiods(const TSequence *seq, GSERIALIZED *gsinter, int *count) } int newcount; - result = spanarr_normalize(periods, npers, ORDERED_NO, &newcount); + result = spanarr_normalize(periods, npers, ORDER, &newcount); *count = newcount; pfree(periods); return result; @@ -638,8 +638,7 @@ tpointseq_linear_at_geom(const TSequence *seq, const GSERIALIZED *gs) } /* Compute the periodset */ assert(totalpers > 0); - SpanSet *ss = spanset_make_free(allperiods, totalpers, NORMALIZE, - ORDERED_NO); + SpanSet *ss = spanset_make_free(allperiods, totalpers, NORMALIZE, ORDER); /* Recover the Z values from the original sequence */ result = tcontseq_restrict_tstzspanset(seq, ss, REST_AT); pfree(ss); diff --git a/meos/src/point/tpoint_tempspatialrels.c b/meos/src/point/tpoint_tempspatialrels.c index 6912372ade..d7f8fa8eaf 100644 --- a/meos/src/point/tpoint_tempspatialrels.c +++ b/meos/src/point/tpoint_tempspatialrels.c @@ -258,8 +258,7 @@ tinterrel_tpointseq_simple_geom(const TSequence *seq, Datum geom, else { /* It is necessary to sort the periods */ - SpanSet *ps1 = spanset_make_exp(periods, npers, npers, NORMALIZE, - ORDERED_NO); + SpanSet *ps1 = spanset_make_exp(periods, npers, npers, NORMALIZE, ORDER); ss = minus_span_spanset(&seq->period, ps1); pfree(ps1); } diff --git a/mobilitydb/sql/general/001_set.in.sql b/mobilitydb/sql/general/001_set.in.sql index 1842e8ce1b..cc2671ba4c 100644 --- a/mobilitydb/sql/general/001_set.in.sql +++ b/mobilitydb/sql/general/001_set.in.sql @@ -654,6 +654,15 @@ CREATE FUNCTION shiftScale(tstzset, interval, interval) AS 'MODULE_PATHNAME', 'Tstzset_shift_scale' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; +CREATE FUNCTION floor(floatset) + RETURNS floatset + AS 'MODULE_PATHNAME', 'Floatset_floor' + LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; +CREATE FUNCTION ceil(floatset) + RETURNS floatset + AS 'MODULE_PATHNAME', 'Floatset_ceil' + LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + CREATE FUNCTION round(floatset, integer DEFAULT 0) RETURNS floatset AS 'MODULE_PATHNAME', 'Floatset_round' diff --git a/mobilitydb/sql/general/003_span.in.sql b/mobilitydb/sql/general/003_span.in.sql index 5b1fed6582..7d6981e524 100644 --- a/mobilitydb/sql/general/003_span.in.sql +++ b/mobilitydb/sql/general/003_span.in.sql @@ -607,6 +607,15 @@ CREATE FUNCTION shiftScale(tstzspan, interval, interval) AS 'MODULE_PATHNAME', 'Tstzspan_shift_scale' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; +CREATE FUNCTION floor(floatspan) + RETURNS floatspan + AS 'MODULE_PATHNAME', 'Floatspan_floor' + LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; +CREATE FUNCTION ceil(floatspan) + RETURNS floatspan + AS 'MODULE_PATHNAME', 'Floatspan_ceil' + LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + CREATE FUNCTION round(floatspan, integer DEFAULT 0) RETURNS floatspan AS 'MODULE_PATHNAME', 'Floatspan_round' diff --git a/mobilitydb/sql/general/007_spanset.in.sql b/mobilitydb/sql/general/007_spanset.in.sql index 5457a00160..b162063d99 100644 --- a/mobilitydb/sql/general/007_spanset.in.sql +++ b/mobilitydb/sql/general/007_spanset.in.sql @@ -834,6 +834,15 @@ CREATE FUNCTION shiftScale(tstzspanset, interval, interval) AS 'MODULE_PATHNAME', 'Tstzspanset_shift_scale' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; +CREATE FUNCTION floor(floatspanset) + RETURNS floatspanset + AS 'MODULE_PATHNAME', 'Floatspanset_floor' + LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; +CREATE FUNCTION ceil(floatspanset) + RETURNS floatspanset + AS 'MODULE_PATHNAME', 'Floatspanset_ceil' + LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + CREATE FUNCTION round(floatspanset, integer DEFAULT 0) RETURNS floatspanset AS 'MODULE_PATHNAME', 'Floatspanset_round' diff --git a/mobilitydb/sql/general/026_tnumber_mathfuncs.in.sql b/mobilitydb/sql/general/026_tnumber_mathfuncs.in.sql index 5cbf23eba1..fcbb2b5add 100644 --- a/mobilitydb/sql/general/026_tnumber_mathfuncs.in.sql +++ b/mobilitydb/sql/general/026_tnumber_mathfuncs.in.sql @@ -353,6 +353,16 @@ CREATE FUNCTION deltaValue(tfloat) AS 'MODULE_PATHNAME', 'Tnumber_delta_value' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; +CREATE FUNCTION floor(tfloat) + RETURNS tfloat + AS 'MODULE_PATHNAME', 'Tfloat_floor' + LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION ceil(tfloat) + RETURNS tfloat + AS 'MODULE_PATHNAME', 'Tfloat_ceil' + LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + CREATE FUNCTION round(tfloat, integer DEFAULT 0) RETURNS tfloat AS 'MODULE_PATHNAME', 'Tfloat_round' diff --git a/mobilitydb/src/general/set.c b/mobilitydb/src/general/set.c index cb1462b99f..cfc5217df0 100644 --- a/mobilitydb/src/general/set.c +++ b/mobilitydb/src/general/set.c @@ -148,7 +148,7 @@ Set_constructor(PG_FUNCTION_ARGS) int count; Datum *values = datumarr_extract(array, &count); meosType basetype = settype_basetype(settype); - Set *result = set_make_free(values, count, basetype, ORDERED_NO); + Set *result = set_make_free(values, count, basetype, ORDER); PG_FREE_IF_COPY(array, 0); PG_RETURN_SET_P(result); } @@ -455,6 +455,38 @@ Tstzset_shift_scale(PG_FUNCTION_ARGS) PG_RETURN_SET_P(result); } +PGDLLEXPORT Datum Floatset_floor(PG_FUNCTION_ARGS); +PG_FUNCTION_INFO_V1(Floatset_floor); +/** + * @ingroup mobilitydb_setspan_transf + * @brief Return a float set rounded down to the nearest integer + * @sqlfn floor() + */ +Datum +Floatset_floor(PG_FUNCTION_ARGS) +{ + Set *s = PG_GETARG_SET_P(0); + Set *result = floatset_floor(s); + PG_FREE_IF_COPY(s, 0); + PG_RETURN_SET_P(result); +} + +PGDLLEXPORT Datum Floatset_ceil(PG_FUNCTION_ARGS); +PG_FUNCTION_INFO_V1(Floatset_ceil); +/** + * @ingroup mobilitydb_setspan_transf + * @brief Return a float set rounded up to the nearest integer + * @sqlfn ceil() + */ +Datum +Floatset_ceil(PG_FUNCTION_ARGS) +{ + Set *s = PG_GETARG_SET_P(0); + Set *result = floatset_ceil(s); + PG_FREE_IF_COPY(s, 0); + PG_RETURN_SET_P(result); +} + PGDLLEXPORT Datum Floatset_round(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(Floatset_round); /** diff --git a/mobilitydb/src/general/set_aggfuncs.c b/mobilitydb/src/general/set_aggfuncs.c index eacf47e4a6..8c1f251add 100644 --- a/mobilitydb/src/general/set_aggfuncs.c +++ b/mobilitydb/src/general/set_aggfuncs.c @@ -159,7 +159,7 @@ Set_union_finalfn(PG_FUNCTION_ARGS) values[i] = typlen > 0 ? state->dvalues[i] : PointerGetDatum(PG_DETOAST_DATUM(state->dvalues[i])); - Set *result = set_make_exp(values, count, count, basetype, ORDERED_NO); + Set *result = set_make_exp(values, count, count, basetype, ORDER); /* Free memory */ if (typbyval) diff --git a/mobilitydb/src/general/span.c b/mobilitydb/src/general/span.c index 92312a6764..c54844d959 100644 --- a/mobilitydb/src/general/span.c +++ b/mobilitydb/src/general/span.c @@ -527,6 +527,34 @@ Tstzspan_shift_scale(PG_FUNCTION_ARGS) PG_RETURN_SPAN_P(tstzspan_shift_scale(s, shift, duration)); } +PGDLLEXPORT Datum Floatspan_floor(PG_FUNCTION_ARGS); +PG_FUNCTION_INFO_V1(Floatspan_floor); +/** + * @ingroup mobilitydb_setspan_transf + * @brief Return a float span rounded down to the nearest integer + * @sqlfn floor() + */ +Datum +Floatspan_floor(PG_FUNCTION_ARGS) +{ + Span *s = PG_GETARG_SPAN_P(0); + PG_RETURN_SPAN_P(floatspan_floor(s)); +} + +PGDLLEXPORT Datum Floatspan_ceil(PG_FUNCTION_ARGS); +PG_FUNCTION_INFO_V1(Floatspan_ceil); +/** + * @ingroup mobilitydb_setspan_transf + * @brief Return a float span rounded up to the nearest integer + * @sqlfn ceil() + */ +Datum +Floatspan_ceil(PG_FUNCTION_ARGS) +{ + Span *s = PG_GETARG_SPAN_P(0); + PG_RETURN_SPAN_P(floatspan_ceil(s)); +} + PGDLLEXPORT Datum Floatspan_round(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(Floatspan_round); /** diff --git a/mobilitydb/src/general/span_aggfuncs.c b/mobilitydb/src/general/span_aggfuncs.c index 0423297404..006cca702f 100644 --- a/mobilitydb/src/general/span_aggfuncs.c +++ b/mobilitydb/src/general/span_aggfuncs.c @@ -241,7 +241,7 @@ Span_union_finalfn(PG_FUNCTION_ARGS) if (k == 0) PG_RETURN_NULL(); - PG_RETURN_SPANSET_P(spanset_make_free(spans, k, NORMALIZE, ORDERED_NO)); + PG_RETURN_SPANSET_P(spanset_make_free(spans, k, NORMALIZE, ORDER)); } /*****************************************************************************/ diff --git a/mobilitydb/src/general/spanset.c b/mobilitydb/src/general/spanset.c index 87cbb90e69..ef98fe46fb 100644 --- a/mobilitydb/src/general/spanset.c +++ b/mobilitydb/src/general/spanset.c @@ -148,7 +148,7 @@ Spanset_constructor(PG_FUNCTION_ARGS) ensure_not_empty_array(array); int count; Span *spans = spanarr_extract(array, &count); - SpanSet *result = spanset_make_free(spans, count, NORMALIZE, ORDERED); + SpanSet *result = spanset_make_free(spans, count, NORMALIZE, ORDER_NO); PG_FREE_IF_COPY(array, 0); PG_RETURN_SPANSET_P(result); } @@ -352,7 +352,7 @@ Multirange_to_spanset(PG_FUNCTION_ARGS) range_set_span(range, typcache->rngtype, &spans[i]); } SpanSet *result = spanset_make_free(spans, mrange->rangeCount, NORMALIZE, - ORDERED); + ORDER_NO); PG_FREE_IF_COPY(mrange, 0); PG_RETURN_SPANSET_P(result); } @@ -860,6 +860,38 @@ Tstzspanset_shift_scale(PG_FUNCTION_ARGS) PG_RETURN_SPANSET_P(result); } +PGDLLEXPORT Datum Floatspanset_floor(PG_FUNCTION_ARGS); +PG_FUNCTION_INFO_V1(Floatspanset_floor); +/** + * @ingroup mobilitydb_setspan_transf + * @brief Return a float span set rounded down to the nearest integer + * @sqlfn floor() + */ +Datum +Floatspanset_floor(PG_FUNCTION_ARGS) +{ + SpanSet *ss = PG_GETARG_SPANSET_P(0); + SpanSet *result = floatspanset_floor(ss); + PG_FREE_IF_COPY(ss, 0); + PG_RETURN_SPANSET_P(result); +} + +PGDLLEXPORT Datum Floatspanset_ceil(PG_FUNCTION_ARGS); +PG_FUNCTION_INFO_V1(Floatspanset_ceil); +/** + * @ingroup mobilitydb_setspan_transf + * @brief Return a float span set rounded up to the nearest integer + * @sqlfn ceil() + */ +Datum +Floatspanset_ceil(PG_FUNCTION_ARGS) +{ + SpanSet *ss = PG_GETARG_SPANSET_P(0); + SpanSet *result = floatspanset_ceil(ss); + PG_FREE_IF_COPY(ss, 0); + PG_RETURN_SPANSET_P(result); +} + PGDLLEXPORT Datum Floatspanset_round(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(Floatspanset_round); /** diff --git a/mobilitydb/src/general/temporal.c b/mobilitydb/src/general/temporal.c index 0a77056d84..169b19d511 100644 --- a/mobilitydb/src/general/temporal.c +++ b/mobilitydb/src/general/temporal.c @@ -903,7 +903,7 @@ Temporal_valueset(PG_FUNCTION_ARGS) PG_FREE_IF_COPY(temp, 0); PG_RETURN_ARRAYTYPE_P(result); } - Set *result = set_make_free(values, count, basetype, ORDERED); + Set *result = set_make_free(values, count, basetype, ORDER_NO); PG_FREE_IF_COPY(temp, 0); PG_RETURN_SET_P(result); } diff --git a/mobilitydb/src/general/tnumber_mathfuncs.c b/mobilitydb/src/general/tnumber_mathfuncs.c index 6f0c620d50..bf4ca59b06 100644 --- a/mobilitydb/src/general/tnumber_mathfuncs.c +++ b/mobilitydb/src/general/tnumber_mathfuncs.c @@ -332,6 +332,38 @@ Tnumber_delta_value(PG_FUNCTION_ARGS) PG_RETURN_TEMPORAL_P(result); } +PGDLLEXPORT Datum Tfloat_floor(PG_FUNCTION_ARGS); +PG_FUNCTION_INFO_V1(Tfloat_floor); +/** + * @ingroup mobilitydb_temporal_math + * @brief Return a temporal number rounded down to the nearest integer + * @sqlfn floor() + */ +Datum +Tfloat_floor(PG_FUNCTION_ARGS) +{ + Temporal *temp = PG_GETARG_TEMPORAL_P(0); + Temporal *result = tfloat_floor(temp); + PG_FREE_IF_COPY(temp, 0); + PG_RETURN_TEMPORAL_P(result); +} + +PGDLLEXPORT Datum Tfloat_ceil(PG_FUNCTION_ARGS); +PG_FUNCTION_INFO_V1(Tfloat_ceil); +/** + * @ingroup mobilitydb_temporal_math + * @brief Return a temporal number rounded up to the nearest integer + * @sqlfn ceil() + */ +Datum +Tfloat_ceil(PG_FUNCTION_ARGS) +{ + Temporal *temp = PG_GETARG_TEMPORAL_P(0); + Temporal *result = tfloat_ceil(temp); + PG_FREE_IF_COPY(temp, 0); + PG_RETURN_TEMPORAL_P(result); +} + PGDLLEXPORT Datum Float_degrees(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(Float_degrees); /** diff --git a/mobilitydb/test/general/expected/001_set.test.out b/mobilitydb/test/general/expected/001_set.test.out index debec6f757..03a4946337 100644 --- a/mobilitydb/test/general/expected/001_set.test.out +++ b/mobilitydb/test/general/expected/001_set.test.out @@ -520,6 +520,30 @@ SELECT shiftScale(tstzset '{2000-01-01, 2000-01-02, 2000-01-03}', '1 day', '1 ho {"Sun Jan 02 00:00:00 2000 PST", "Sun Jan 02 00:30:00 2000 PST", "Sun Jan 02 01:00:00 2000 PST"} (1 row) +SELECT floor(floatset '{0.5, 1.5, 2.5}'); + floor +----------- + {0, 1, 2} +(1 row) + +SELECT floor(floatset '{0.5, 1.5, 1.6}'); + floor +-------- + {0, 1} +(1 row) + +SELECT ceil(floatset '{0.5, 1.5, 2.5}'); + ceil +----------- + {1, 2, 3} +(1 row) + +SELECT ceil(floatset '{0.5, 1.5, 1.6}'); + ceil +-------- + {1, 2} +(1 row) + SELECT round(floatset '{0.12345, 1.12345, 2.12345}', 3); round ----------------------- diff --git a/mobilitydb/test/general/expected/003_span.test.out b/mobilitydb/test/general/expected/003_span.test.out index 16e1ab5dc0..e76c2dc5e4 100644 --- a/mobilitydb/test/general/expected/003_span.test.out +++ b/mobilitydb/test/general/expected/003_span.test.out @@ -574,6 +574,30 @@ SELECT shiftScale(tstzspan '(2000-01-01,2000-01-02)', '5 min', '1 hour'); (Sat Jan 01 00:05:00 2000 PST, Sat Jan 01 01:05:00 2000 PST) (1 row) +SELECT floor(floatspan '[1.5,2.5]'); + floor +-------- + [1, 2] +(1 row) + +SELECT ceil(floatspan '[1.5,2.5]'); + ceil +-------- + [2, 3] +(1 row) + +SELECT floor(floatspan '(1.5,1.6)'); + floor +-------- + [1, 1] +(1 row) + +SELECT ceil(floatspan '(1.5,1.6)'); + ceil +-------- + [2, 2] +(1 row) + SELECT round(floatspan '[1.123456789,2.123456789]',6); round ---------------------- diff --git a/mobilitydb/test/general/expected/007_spanset.test.out b/mobilitydb/test/general/expected/007_spanset.test.out index 3c5a61734f..76474c2c98 100644 --- a/mobilitydb/test/general/expected/007_spanset.test.out +++ b/mobilitydb/test/general/expected/007_spanset.test.out @@ -1251,6 +1251,18 @@ SELECT spanset_hash_extended(tstzspanset '{[2000-01-01,2000-01-02]}', 1) <> span t (1 row) +SELECT floor(floatspanset '{[1.5,2.5),[3.5,4.5),[5.5,6.5)}'); + floor +-------------------------- + {[1, 2), [3, 4), [5, 6)} +(1 row) + +SELECT ceil(floatspanset '{[1.5,2.5),[3.5,4.5),[5.5,6.5)}'); + ceil +-------------------------- + {[2, 3), [4, 5), [6, 7)} +(1 row) + SELECT round(floatspanset '{[1.12345,2.12345),[3.12345,4.12345),[5.12345,6.12345)}', 2); round -------------------------------------------- diff --git a/mobilitydb/test/general/expected/026_tnumber_mathfuncs.test.out b/mobilitydb/test/general/expected/026_tnumber_mathfuncs.test.out index 23a00f6736..374a582927 100644 --- a/mobilitydb/test/general/expected/026_tnumber_mathfuncs.test.out +++ b/mobilitydb/test/general/expected/026_tnumber_mathfuncs.test.out @@ -1217,6 +1217,54 @@ SELECT tint '[-1@2000-01-01, 1@2000-01-02]' / tint '[0@2000-01-01, 1@2000-01-02] ERROR: Division by zero SELECT tfloat '[-1@2000-01-01, 1@2000-01-02]' / tfloat '[-1@2000-01-01, 1@2000-01-02]'; ERROR: Division by zero +SELECT floor(tfloat '1.5@2000-01-01'); + floor +-------------------------------- + 1@Sat Jan 01 00:00:00 2000 PST +(1 row) + +SELECT floor(tfloat '{1.5@2000-01-01, 2.5@2000-01-02, 1.5@2000-01-03}'); + floor +-------------------------------------------------------------------------------------------------- + {1@Sat Jan 01 00:00:00 2000 PST, 2@Sun Jan 02 00:00:00 2000 PST, 1@Mon Jan 03 00:00:00 2000 PST} +(1 row) + +SELECT floor(tfloat '[1.5@2000-01-01, 2.5@2000-01-02, 1.5@2000-01-03]'); + floor +-------------------------------------------------------------------------------------------------- + [1@Sat Jan 01 00:00:00 2000 PST, 2@Sun Jan 02 00:00:00 2000 PST, 1@Mon Jan 03 00:00:00 2000 PST] +(1 row) + +SELECT floor(tfloat '{[1.5@2000-01-01, 2.5@2000-01-02, 1.5@2000-01-03],[3.5@2000-01-04, 3.5@2000-01-05]}'); + floor +---------------------------------------------------------------------------------------------------------------------------------------------------------------------- + {[1@Sat Jan 01 00:00:00 2000 PST, 2@Sun Jan 02 00:00:00 2000 PST, 1@Mon Jan 03 00:00:00 2000 PST], [3@Tue Jan 04 00:00:00 2000 PST, 3@Wed Jan 05 00:00:00 2000 PST]} +(1 row) + +SELECT ceil(tfloat '1.5@2000-01-01'); + ceil +-------------------------------- + 2@Sat Jan 01 00:00:00 2000 PST +(1 row) + +SELECT ceil(tfloat '{1.5@2000-01-01, 2.5@2000-01-02, 1.5@2000-01-03}'); + ceil +-------------------------------------------------------------------------------------------------- + {2@Sat Jan 01 00:00:00 2000 PST, 3@Sun Jan 02 00:00:00 2000 PST, 2@Mon Jan 03 00:00:00 2000 PST} +(1 row) + +SELECT ceil(tfloat '[1.5@2000-01-01, 2.5@2000-01-02, 1.5@2000-01-03]'); + ceil +-------------------------------------------------------------------------------------------------- + [2@Sat Jan 01 00:00:00 2000 PST, 3@Sun Jan 02 00:00:00 2000 PST, 2@Mon Jan 03 00:00:00 2000 PST] +(1 row) + +SELECT ceil(tfloat '{[1.5@2000-01-01, 2.5@2000-01-02, 1.5@2000-01-03],[3.5@2000-01-04, 3.5@2000-01-05]}'); + ceil +---------------------------------------------------------------------------------------------------------------------------------------------------------------------- + {[2@Sat Jan 01 00:00:00 2000 PST, 3@Sun Jan 02 00:00:00 2000 PST, 2@Mon Jan 03 00:00:00 2000 PST], [4@Tue Jan 04 00:00:00 2000 PST, 4@Wed Jan 05 00:00:00 2000 PST]} +(1 row) + SELECT round(tfloat '1.5@2000-01-01',0); round -------------------------------- diff --git a/mobilitydb/test/general/queries/001_set.test.sql b/mobilitydb/test/general/queries/001_set.test.sql index d84e8889fa..d967065140 100644 --- a/mobilitydb/test/general/queries/001_set.test.sql +++ b/mobilitydb/test/general/queries/001_set.test.sql @@ -165,6 +165,10 @@ SELECT shiftScale(dateset '{2000-01-01, 2000-01-02, 2000-01-03}', 4, 4); SELECT shiftScale(tstzset '{2000-01-01}', '1 day', '1 hour'); SELECT shiftScale(tstzset '{2000-01-01, 2000-01-02, 2000-01-03}', '1 day', '1 hour'); +SELECT floor(floatset '{0.5, 1.5, 2.5}'); +SELECT floor(floatset '{0.5, 1.5, 1.6}'); +SELECT ceil(floatset '{0.5, 1.5, 2.5}'); +SELECT ceil(floatset '{0.5, 1.5, 1.6}'); SELECT round(floatset '{0.12345, 1.12345, 2.12345}', 3); SELECT degrees(floatset '{0, 0.5, 1}'); SELECT degrees(floatset '{0, 0.5, 1}', true); diff --git a/mobilitydb/test/general/queries/003_span.test.sql b/mobilitydb/test/general/queries/003_span.test.sql index 662fdcbff2..5558cdac6d 100644 --- a/mobilitydb/test/general/queries/003_span.test.sql +++ b/mobilitydb/test/general/queries/003_span.test.sql @@ -183,6 +183,10 @@ SELECT shiftScale(tstzspan '(2000-01-01,2000-01-02]', '5 min', '1 hour'); SELECT shiftScale(tstzspan '[2000-01-01,2000-01-02)', '5 min', '1 hour'); SELECT shiftScale(tstzspan '(2000-01-01,2000-01-02)', '5 min', '1 hour'); +SELECT floor(floatspan '[1.5,2.5]'); +SELECT ceil(floatspan '[1.5,2.5]'); +SELECT floor(floatspan '(1.5,1.6)'); +SELECT ceil(floatspan '(1.5,1.6)'); SELECT round(floatspan '[1.123456789,2.123456789]',6); SELECT round(floatspan '[-inf,2.123456789]',6); SELECT round(floatspan '[1.123456789,inf]',6); diff --git a/mobilitydb/test/general/queries/007_spanset.test.sql b/mobilitydb/test/general/queries/007_spanset.test.sql index 14e342fa34..5c1841560b 100644 --- a/mobilitydb/test/general/queries/007_spanset.test.sql +++ b/mobilitydb/test/general/queries/007_spanset.test.sql @@ -307,6 +307,8 @@ SELECT spanset_hash_extended(tstzspanset '{[2000-01-01,2000-01-02]}', 1) <> span -- Transformation functions ------------------------------------------------------------------------------- +SELECT floor(floatspanset '{[1.5,2.5),[3.5,4.5),[5.5,6.5)}'); +SELECT ceil(floatspanset '{[1.5,2.5),[3.5,4.5),[5.5,6.5)}'); SELECT round(floatspanset '{[1.12345,2.12345),[3.12345,4.12345),[5.12345,6.12345)}', 2); SELECT shift(intspanset '{[1,2),[3,4),[5,6)}', 2); diff --git a/mobilitydb/test/general/queries/026_tnumber_mathfuncs.test.sql b/mobilitydb/test/general/queries/026_tnumber_mathfuncs.test.sql index 54c6e6ebca..a370e22ff1 100644 --- a/mobilitydb/test/general/queries/026_tnumber_mathfuncs.test.sql +++ b/mobilitydb/test/general/queries/026_tnumber_mathfuncs.test.sql @@ -284,6 +284,18 @@ SELECT tfloat '[-1@2000-01-01, 1@2000-01-02]' / tfloat '[-1@2000-01-01, 1@2000-0 ------------------------------------------------------------------------------- +SELECT floor(tfloat '1.5@2000-01-01'); +SELECT floor(tfloat '{1.5@2000-01-01, 2.5@2000-01-02, 1.5@2000-01-03}'); +SELECT floor(tfloat '[1.5@2000-01-01, 2.5@2000-01-02, 1.5@2000-01-03]'); +SELECT floor(tfloat '{[1.5@2000-01-01, 2.5@2000-01-02, 1.5@2000-01-03],[3.5@2000-01-04, 3.5@2000-01-05]}'); + +SELECT ceil(tfloat '1.5@2000-01-01'); +SELECT ceil(tfloat '{1.5@2000-01-01, 2.5@2000-01-02, 1.5@2000-01-03}'); +SELECT ceil(tfloat '[1.5@2000-01-01, 2.5@2000-01-02, 1.5@2000-01-03]'); +SELECT ceil(tfloat '{[1.5@2000-01-01, 2.5@2000-01-02, 1.5@2000-01-03],[3.5@2000-01-04, 3.5@2000-01-05]}'); + +------------------------------------------------------------------------------- + SELECT round(tfloat '1.5@2000-01-01',0); SELECT round(tfloat '{1.5@2000-01-01, 2.5@2000-01-02, 1.5@2000-01-03}',0); SELECT round(tfloat '[1.5@2000-01-01, 2.5@2000-01-02, 1.5@2000-01-03]',0);