MobilityDB 1.1

◆ tfunc_base()

static Datum tfunc_base ( Datum  value,
LiftedFunctionInfo lfinfo 
)
static

Generic functions for lifting functions and operators on temporal types.

These functions are used for lifting arithmetic operators (+, -, *, /), Boolean operators (and, or, not), comparisons (<, <=, >, >=), distance (<->), spatial relationships (tcontains), etc.

The lifting of functions and operators must take into account the following characteristic of the function to be lifted

  1. The number of arguments of the function
    • unary functions, such as degrees for temporal floats or round for temporal points.
    • binary functions and operators, such as arithmetic operators and comparisons (e.g., + or <) or spatial relationships functions (e.g.,tintersects).
  2. The type of the arguments for binary functions
    • a temporal type and a base type. In this case the non-lifted function is applied to each instant of the temporal type.
    • two temporal types. In this case the operands must be synchronized and the function is applied to each pair of synchronized instants.
  3. Whether the type of the arguments may vary. For example, temporal numbers can be of different base type (that is, integer and float). Therefore, the types of the arguments must be taken into account when computing binary operators (e.g., + or <) for temporal numbers.
  4. The number of optional parameters of the function
    • no arguments, such as most spatial relationships functions (e.g., tintersects).
    • one argument, such as spatial relationships functions that need an additional parameter (e.g., tdwithin).
    • two arguments, e.g., when assembling a temporal point from two temporal floats, the SRID and a boolean flag stating whether the resulting temporal point is geometric or geographic are needed.
  5. Whether the function has instantaneous discontinuities at the crossings. Examples of such functions are temporal comparisons for temporal floats or temporal spatial relationships since the value of the result may change immediately before, at, or immediately after a crossing.
  6. Whether intermediate points between synchronized instants must be added to take into account the crossings or the turning points (or local minimum/maximum) of the function. For example, tfloat + tfloat only needs to synchronize the arguments while tfloat * tfloat requires in addition to add the turning point, which is the timestamp between the two consecutive synchronized instants in which the linear functions defined by the two segments are equal.

Examples

  • tfloat_degrees => tfunc_temporal applies the degrees function to each instant.
  • tfloatseq + base => tfunc_tsequence_base applies the + operator to each instant and results in a tfloatseq.
  • tfloatseq < base => tfunc_tlinearseq_base_discont applies the < operator to each instant, if the sequence is equal to the base value in the middle of two consecutive instants add an instantaneous sequence at the crossing. The result is a tfloatseqset.
  • tfloatseq + tfloatseq => tfunc_tcontseq_tcontseq synchronizes the sequences and applies the + operator to each instant.
  • tfloatseq * tfloatseq => tfunc_tcontseq_tcontseq synchronizes the sequences possibly adding the turning points between two consecutive instants and applies the * operator to each instant. The result is a tfloatseq.
  • tfloatseq < tfloatseq => tfunc_tcontseq_tcontseq_multi synchronizes the sequences, applies the < operator to each instant, and if there is a crossing in the middle of two consecutive pairs of instants add an instant sequence at the crossing. The result is a tfloatseqset.

A struct named LiftedFunctionInfo is used to describe the above characteristics of the function to be lifted. Such struct is filled by the calling function and is passed through the dispatch functions. To avoid code redundancy when coping with functions with 2, 3, and 4 arguments, variadic function pointers are used. The idea is sketched next.

typedef Datum (*varfunc) (Datum, ...);
{
Datum resvalue;
if (lfinfo->numparam == 1)
resvalue = (*lfinfo->func)(temporalinst_value(inst));
else if (lfinfo->numparam == 2)
resvalue = (*lfinfo->func)(temporalinst_value(inst), lfinfo->param[0]);
resvalue = (*lfinfo->func)(temporalinst_value(inst), lfinfo->param[0]);
else
elog(ERROR, "Number of function parameters not supported: %u",
lfinfo->numparam);
TInstant *result = tinstant_make(resvalue, lfinfo->restype, inst->t);
DATUM_FREE(resvalue, temptype_basetype(lfinfo->restype));
return result;
}
// Definitions for TSequence, TSequence, and TSequenceSet
[...]
// Dispatch function
{
// Dispatch depending on the temporal type
[...]
}
TInstant * tinstant_make(Datum value, meosType temptype, TimestampTz t)
Construct a temporal instant from the arguments.
Definition: tinstant.c:276
TInstant * tfunc_tinstant(const TInstant *inst, LiftedFunctionInfo *lfinfo)
Apply the function with the optional arguments to the temporal value.
Definition: lifting.c:195
Temporal * tfunc_temporal(const Temporal *temp, LiftedFunctionInfo *lfinfo)
Apply the function to the temporal value (dispatch function)
Definition: lifting.c:244
meosType temptype_basetype(meosType temptype)
Return the base type from the temporal type.
Definition: meos_catalog.c:122
Datum(* varfunc)(Datum,...)
Definition: temporal.h:364
#define DATUM_FREE(value, basetype)
Definition: temporal.h:396
uintptr_t Datum
Definition: pg_ext_defs.in.h:4
#define elog(error,...)
Definition: postgres.h:53
#define ERROR
Definition: postgres.h:51
int numparam
Number of parameters of the function.
Definition: lifting.h:56
Datum param[MAX_PARAMS]
Datum array for the parameters of the function.
Definition: lifting.h:57
meosType restype
Temporal type of the result of the function.
Definition: lifting.h:60
Datum(* func)(Datum,...)
Variadic function that is lifted.
Definition: lifting.h:55
Definition: lifting.h:54
TimestampTz t
Timestamp (8 bytes)
Definition: meos.h:153
Structure to represent temporal values of instant subtype.
Definition: meos.h:148
Structure to represent the common structure of temporal values of any temporal subtype.
Definition: meos.h:136

An example of use of the lifting functions is given next.

// Transform the geometry to a geography
PGDLLEXPORT Datum
tgeompoint_tgeogpoint(PG_FUNCTION_ARGS)
{
memset(&lfinfo, 0, sizeof(LiftedFunctionInfo));
lfinfo->func = (varfunc) &geom_to_geog;
lfinfo->numparam = 1;
lfinfo->restype = T_TGEOGPOINT;
lfinfo->tpfunc_base = NULL;
lfinfo->tpfunc = NULL;
Temporal *result = tfunc_temporal(temp, (Datum) NULL, lfinfo);
PG_FREE_IF_COPY(temp, 0);
PG_RETURN_POINTER(result);
}
Temporal * tgeompoint_tgeogpoint(const Temporal *temp, bool oper)
Convert a temporal point to a geometry/geography point.
Definition: tpoint_spatialfuncs.c:2054
@ T_TGEOGPOINT
temporal geography point type
Definition: meos_catalog.h:95
#define PG_GETARG_TEMPORAL_P(X)
Definition: temporal.h:391
bool(* tpfunc_base)(const TInstant *, const TInstant *, Datum, meosType, Datum *, TimestampTz *)
Turning point function for temporal and base types.
Definition: lifting.h:64
bool(* tpfunc)(const TInstant *, const TInstant *, const TInstant *, const TInstant *, Datum *, TimestampTz *)
Turning point function for two temporal types.
Definition: lifting.h:66

Apply the variadic function with the optional arguments to the base value