Datum linterp_TimestampTz(PG_FUNCTION_ARGS) { float8 p; TimestampTz y0 = PG_GETARG_TIMESTAMP(2); TimestampTz y1 = PG_GETARG_TIMESTAMP(4); TimestampTz result = 0; bool eq_bounds = false; bool eq_abscissas = false; /* Common */ p = linterp_abscissa(fcinfo, &eq_bounds, &eq_abscissas); /* Ordinate type specific code*/ if ( eq_bounds ) { /* Internally, TSTZ is like TS, UTC is stored. */ if ( eq_abscissas && timestamp_cmp_internal(y0,y1) == 0 ) result = y0; else PG_RETURN_NULL(); } else { result = timestamptz_li_value(p, y0, y1); } PG_RETURN_TIMESTAMPTZ(result); }
Datum ts_dist(PG_FUNCTION_ARGS) { Timestamp a = PG_GETARG_TIMESTAMP(0); Timestamp b = PG_GETARG_TIMESTAMP(1); Interval *r; if (TIMESTAMP_NOT_FINITE(a) || TIMESTAMP_NOT_FINITE(b)) { Interval *p = palloc(sizeof(Interval)); p->day = INT_MAX; p->month = INT_MAX; #ifdef HAVE_INT64_TIMESTAMP p->time = INT64CONST(0x7FFFFFFFFFFFFFFF); #else p->time = DBL_MAX; #endif PG_RETURN_INTERVAL_P(p); } else r = DatumGetIntervalP(DirectFunctionCall2(timestamp_mi, PG_GETARG_DATUM(0), PG_GETARG_DATUM(1))); PG_RETURN_INTERVAL_P(abs_interval(r)); }
Datum ora_timestamp_round(PG_FUNCTION_ARGS) { Timestamp timestamp = PG_GETARG_TIMESTAMP(0); Timestamp result; text *fmt = PG_GETARG_TEXT_PP(1); fsec_t fsec; struct pg_tm tt, *tm = &tt; bool redotz = false; if (TIMESTAMP_NOT_FINITE(timestamp)) PG_RETURN_TIMESTAMPTZ(timestamp); if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0) ereport(ERROR, (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), errmsg("timestamp out of range"))); tm_round(tm, fmt, &redotz); if (tm2timestamp(tm, fsec, NULL, &result) != 0) ereport(ERROR, (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), errmsg("timestamp out of range"))); PG_RETURN_TIMESTAMP(result); }
/* timestamptz_abstime() * Convert timestamp with time zone to abstime. */ Datum timestamptz_abstime(PG_FUNCTION_ARGS) { TimestampTz timestamp = PG_GETARG_TIMESTAMP(0); AbsoluteTime result; fsec_t fsec; struct pg_tm tt, *tm = &tt; if (TIMESTAMP_IS_NOBEGIN(timestamp)) result = NOSTART_ABSTIME; else if (TIMESTAMP_IS_NOEND(timestamp)) result = NOEND_ABSTIME; else if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) == 0) result = tm2abstime(tm, 0); else { ereport(ERROR, (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), errmsg("timestamp out of range"))); result = INVALID_ABSTIME; } PG_RETURN_ABSOLUTETIME(result); }
Datum HASHAPI_Hash_1_timestamp(PG_FUNCTION_ARGS) { int32 num_segs; /* number of segments */ Timestamp val1; /* varchar value */ unsigned int targetbucket; /* 0-based */ int16 algorithm; /* hashing algorithm */ Datum d1; Oid oid; /* Get number of segments */ num_segs = PG_GETARG_INT32(0); /* Get hashing algoriithm */ algorithm = PG_GETARG_INT16(1); /* Get the value to hash */ val1 = PG_GETARG_TIMESTAMP(2); d1 = TimestampGetDatum(val1); /* create a CdbHash for this hash test. */ h = makeCdbHash(num_segs, algorithm); /* init cdb hash */ cdbhashinit(h); oid = TIMESTAMPOID; cdbhash(h, d1, oid); /* reduce the result hash value */ targetbucket = cdbhashreduce(h); PG_RETURN_INT32(targetbucket); /* return target bucket (segID) */ }
/* timestamp_abstime() * Convert timestamp to abstime. */ Datum timestamp_abstime(PG_FUNCTION_ARGS) { Timestamp timestamp = PG_GETARG_TIMESTAMP(0); AbsoluteTime result; fsec_t fsec; int tz; struct pg_tm tt, *tm = &tt; if (TIMESTAMP_IS_NOBEGIN(timestamp)) result = NOSTART_ABSTIME; else if (TIMESTAMP_IS_NOEND(timestamp)) result = NOEND_ABSTIME; else if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) == 0) { tz = DetermineTimeZoneOffset(tm, session_timezone); result = tm2abstime(tm, tz); } else { ereport(ERROR, (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), errmsg("timestamp out of range"), errOmitLocation(true))); result = INVALID_ABSTIME; } PG_RETURN_ABSOLUTETIME(result); }
Datum orafce_to_char_timestamp(PG_FUNCTION_ARGS) { Timestamp date_txt = PG_GETARG_TIMESTAMP(0); text *result = NULL; if(nls_date_format && strlen(nls_date_format)) { /* it will return the DATE in nls_date_format*/ result = DatumGetTextP(DirectFunctionCall2(timestamp_to_char, CStringGetDatum(date_txt), CStringGetDatum(cstring_to_text(nls_date_format)))); } PG_RETURN_TEXT_P(result); }
Datum gbt_ts_distance(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); Timestamp query = PG_GETARG_TIMESTAMP(1); /* Oid subtype = PG_GETARG_OID(3); */ tsKEY *kkk = (tsKEY *) DatumGetPointer(entry->key); GBT_NUMKEY_R key; key.lower = (GBT_NUMKEY *) &kkk->lower; key.upper = (GBT_NUMKEY *) &kkk->upper; PG_RETURN_FLOAT8( gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo) ); }
Datum gbt_ts_consistent(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); Timestamp query = PG_GETARG_TIMESTAMP(1); StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); /* Oid subtype = PG_GETARG_OID(3); */ bool *recheck = (bool *) PG_GETARG_POINTER(4); tsKEY *kkk = (tsKEY *) DatumGetPointer(entry->key); GBT_NUMKEY_R key; /* All cases served by this function are exact */ *recheck = false; key.lower = (GBT_NUMKEY *) &kkk->lower; key.upper = (GBT_NUMKEY *) &kkk->upper; PG_RETURN_BOOL( gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo) ); }
/* Clause 3.3.9.4 */ Datum TradeUpdateFrame2(PG_FUNCTION_ARGS) { FuncCallContext *funcctx; AttInMetadata *attinmeta; int call_cntr; int max_calls; int i; int j; char **values = NULL; /* Stuff done only on the first call of the function. */ if (SRF_IS_FIRSTCALL()) { MemoryContext oldcontext; enum tuf2 { i_bid_price=0, i_cash_transaction_amount, i_cash_transaction_dts, i_cash_transaction_name, i_exec_name, i_is_cash, i_num_found, i_num_updated, i_settlement_amount, i_settlement_cash_due_date, i_settlement_cash_type, i_trade_history_dts, i_trade_history_status_id, i_trade_list, i_trade_price }; long acct_id = PG_GETARG_INT64(0); Timestamp end_trade_dts_ts = PG_GETARG_TIMESTAMP(1); int max_trades = PG_GETARG_INT32(2); int max_updates = PG_GETARG_INT32(3); Timestamp start_trade_dts_ts = PG_GETARG_TIMESTAMP(4); int ret; TupleDesc tupdesc; SPITupleTable *tuptable = NULL; HeapTuple tuple = NULL; struct pg_tm tt, *tm = &tt; fsec_t fsec; char *tzn = NULL; #ifdef DEBUG char sql[2048]; #endif Datum args[4]; char nulls[4] = { ' ', ' ', ' ', ' ' }; char end_trade_dts[MAXDATELEN + 1]; char start_trade_dts[MAXDATELEN + 1]; int num_found; int num_updated = 0; int num_cash = 0; if (timestamp2tm(end_trade_dts_ts, NULL, tm, &fsec, NULL, NULL) == 0) { EncodeDateTimeM(tm, fsec, tzn, end_trade_dts); } if (timestamp2tm(start_trade_dts_ts, NULL, tm, &fsec, NULL, NULL) == 0) { EncodeDateTimeM(tm, fsec, tzn, start_trade_dts); } #ifdef DEBUG dump_tuf2_inputs(acct_id, end_trade_dts, max_trades, max_updates, start_trade_dts); #endif /* * Prepare a values array for building the returned tuple. * This should be an array of C strings, which will * be processed later by the type input functions. * Don't forget to factor in commas (,) and braces ({}) for the arrays. */ values = (char **) palloc(sizeof(char *) * 15); values[i_bid_price] = (char *) palloc(((S_PRICE_T_LEN + 1) * 20 + 2) * sizeof(char)); values[i_cash_transaction_amount] = (char *) palloc(((VALUE_T_LEN + 1) * 20 + 2) * sizeof(char)); values[i_cash_transaction_dts] = (char *) palloc(((MAXDATELEN + 1) * 20 + 2) * sizeof(char)); values[i_cash_transaction_name] = (char *) palloc(((CT_NAME_LEN + 3) * 20 + 2) * sizeof(char)); values[i_exec_name] = (char *) palloc(((T_EXEC_NAME_LEN + 3) * 20 + 2) * sizeof(char)); values[i_is_cash] = (char *) palloc(((SMALLINT_LEN + 1) * 20 + 2) * sizeof(char)); values[i_num_found] = (char *) palloc((INTEGER_LEN + 1) * sizeof(char)); values[i_num_updated] = (char *) palloc((INTEGER_LEN + 1) * sizeof(char)); values[i_settlement_amount] = (char *) palloc(((VALUE_T_LEN + 1) * 20 + 2) * sizeof(char)); values[i_settlement_cash_due_date] = (char *) palloc(((MAXDATELEN + 1) * 20 + 2) * sizeof(char)); values[i_settlement_cash_type] = (char *) palloc(((SE_CASH_TYPE_LEN + 3) * 20 + 2) * sizeof(char)); values[i_trade_history_dts] = (char *) palloc((((MAXDATELEN + 2) * 3 + 2) * 20 + 5) * sizeof(char)); values[i_trade_history_status_id] = (char *) palloc((((ST_ID_LEN + 2) * 3 + 2) * 20 + 5) * sizeof(char)); values[i_trade_list] = (char *) palloc(((BIGINT_LEN + 1) * 20 + 2) * sizeof(char)); values[i_trade_price] = (char *) palloc(((S_PRICE_T_LEN + 1) * 20 + 2) * sizeof(char)); /* create a function context for cross-call persistence */ funcctx = SRF_FIRSTCALL_INIT(); funcctx->max_calls = 1; /* switch to memory context appropriate for multiple function calls */ oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); SPI_connect(); plan_queries(TUF2_statements); #ifdef DEBUG sprintf(sql, SQLTUF2_1, acct_id, start_trade_dts, end_trade_dts, max_trades); elog(NOTICE, "SQL\n%s", sql); #endif /* DEBUG */ args[0] = Int64GetDatum(acct_id); args[1] = TimestampGetDatum(start_trade_dts_ts); args[2] = TimestampGetDatum(end_trade_dts_ts); args[3] = Int32GetDatum(max_trades); ret = SPI_execute_plan(TUF2_1, args, nulls, true, 0); if (ret == SPI_OK_SELECT && SPI_processed > 0) { tupdesc = SPI_tuptable->tupdesc; tuptable = SPI_tuptable; } num_found = SPI_processed; strcpy(values[i_bid_price], "{"); strcpy(values[i_exec_name], "{"); strcpy(values[i_is_cash], "{"); strcpy(values[i_trade_list], "{"); strcpy(values[i_trade_price], "{"); strcpy(values[i_settlement_amount], "{"); strcpy(values[i_settlement_cash_due_date], "{"); strcpy(values[i_settlement_cash_type], "{"); strcpy(values[i_cash_transaction_amount], "{"); strcpy(values[i_cash_transaction_dts], "{"); strcpy(values[i_cash_transaction_name], "{"); strcpy(values[i_trade_history_dts], "{"); strcpy(values[i_trade_history_status_id], "{"); for (i = 0; i < num_found; i++) { TupleDesc l_tupdesc; SPITupleTable *l_tuptable = NULL; HeapTuple l_tuple = NULL; char *is_cash_str; char *trade_list; char cash_type[41]; tuple = tuptable->vals[i]; if (i > 0) { strcat(values[i_bid_price], ","); strcat(values[i_exec_name], ","); strcat(values[i_is_cash], ","); strcat(values[i_trade_list], ","); strcat(values[i_trade_price], ","); strcat(values[i_settlement_amount], ","); strcat(values[i_settlement_cash_due_date], ","); strcat(values[i_settlement_cash_type], ","); strcat(values[i_trade_history_dts], ","); strcat(values[i_trade_history_status_id], ","); } strcat(values[i_bid_price], SPI_getvalue(tuple, tupdesc, 1)); strcat(values[i_exec_name], "\""); strcat(values[i_exec_name], SPI_getvalue(tuple, tupdesc, 2)); strcat(values[i_exec_name], "\""); is_cash_str = SPI_getvalue(tuple, tupdesc, 3); strcat(values[i_is_cash], (is_cash_str[0] == 't' ? "0" : "1")); trade_list = SPI_getvalue(tuple, tupdesc, 4); strcat(values[i_trade_list], trade_list); strcat(values[i_trade_price], SPI_getvalue(tuple, tupdesc, 5)); if (num_updated < max_updates) { char *old_cash_type; #ifdef DEBUG sprintf(sql, SQLTUF2_2, trade_list); elog(NOTICE, "SQL\n%s", sql); #endif /* DEBUG */ args[0] = Int64GetDatum(atoll(trade_list)); ret = SPI_execute_plan(TUF2_2, args, nulls, true, 0); if (ret == SPI_OK_SELECT && SPI_processed > 0) { l_tupdesc = SPI_tuptable->tupdesc; l_tuptable = SPI_tuptable; l_tuple = l_tuptable->vals[0]; old_cash_type = SPI_getvalue(l_tuple, l_tupdesc, 1); } else { FAIL_FRAME_SET(&funcctx->max_calls, TUF2_statements[1].sql); dump_tuf2_inputs(acct_id, end_trade_dts, max_trades, max_updates, start_trade_dts); continue; } #ifdef DEBUG elog(NOTICE, "cash_type = '%s'", old_cash_type); #endif /* DEBUG */ if (is_cash_str[0] == 't') { if (strcmp(old_cash_type, "Cash Account") == 0) { strcpy(cash_type, "Cash"); } else { strcpy(cash_type, "Cash Account"); } } else { if (strcmp(old_cash_type, "Margin Account") == 0) { strcpy(cash_type, "Margin"); } else { strcpy(cash_type, "Margin Account"); } } #ifdef DEBUG sprintf(sql, SQLTUF2_3, cash_type, trade_list); elog(NOTICE, "SQL\n%s", sql); #endif /* DEBUG */ args[0] = CStringGetTextDatum(cash_type); args[1] = Int64GetDatum(atoll(trade_list)); ret = SPI_execute_plan(TUF2_3, args, nulls, false, 0); if (ret != SPI_OK_UPDATE) { FAIL_FRAME_SET(&funcctx->max_calls, TUF2_statements[2].sql); dump_tuf2_inputs(acct_id, end_trade_dts, max_trades, max_updates, start_trade_dts); continue; } num_updated += SPI_processed; } #ifdef DEBUG sprintf(sql, SQLTUF2_4, trade_list); elog(NOTICE, "SQL\n%s", sql); #endif /* DEBUG */ args[0] = Int64GetDatum(atoll(trade_list)); ret = SPI_execute_plan(TUF2_4, args, nulls, true, 0); if (ret == SPI_OK_SELECT && SPI_processed > 0) { l_tupdesc = SPI_tuptable->tupdesc; l_tuptable = SPI_tuptable; l_tuple = l_tuptable->vals[0]; strcat(values[i_settlement_amount], SPI_getvalue(l_tuple, l_tupdesc, 1)); strcat(values[i_settlement_cash_due_date], SPI_getvalue(l_tuple, l_tupdesc, 2)); strcat(values[i_settlement_cash_type], "\""); strcat(values[i_settlement_cash_type], SPI_getvalue(l_tuple, l_tupdesc, 3)); strcat(values[i_settlement_cash_type], "\""); } else { FAIL_FRAME_SET(&funcctx->max_calls, TUF2_statements[3].sql); dump_tuf2_inputs(acct_id, end_trade_dts, max_trades, max_updates, start_trade_dts); continue; } if (is_cash_str[0] == 't') { #ifdef DEBUG sprintf(sql, SQLTUF2_5, trade_list); elog(NOTICE, "SQL\n%s", sql); #endif /* DEBUG */ ret = SPI_execute_plan(TUF2_5, args, nulls, true, 0); if (ret == SPI_OK_SELECT && SPI_processed > 0) { l_tupdesc = SPI_tuptable->tupdesc; l_tuptable = SPI_tuptable; l_tuple = l_tuptable->vals[0]; if (num_cash > 0) { strcat(values[i_cash_transaction_amount], ","); strcat(values[i_cash_transaction_dts], ","); strcat(values[i_cash_transaction_name], ","); } strcat(values[i_cash_transaction_amount], SPI_getvalue(l_tuple, l_tupdesc, 1)); strcat(values[i_cash_transaction_dts], SPI_getvalue(l_tuple, l_tupdesc, 2)); strcat(values[i_cash_transaction_name], "\""); strcat(values[i_cash_transaction_name], SPI_getvalue(l_tuple, l_tupdesc, 3)); strcat(values[i_cash_transaction_name], "\""); ++num_cash; } else { FAIL_FRAME_SET(&funcctx->max_calls, TUF2_statements[4].sql); dump_tuf2_inputs(acct_id, end_trade_dts, max_trades, max_updates, start_trade_dts); continue; } } else { if (num_cash > 0) { strcat(values[i_cash_transaction_amount], ","); strcat(values[i_cash_transaction_dts], ","); strcat(values[i_cash_transaction_name], ","); } strcat(values[i_cash_transaction_amount], "0"); strcat(values[i_cash_transaction_dts], "1970-1-1 0:0:0"); strcat(values[i_cash_transaction_name], "\"\""); ++num_cash; } #ifdef DEBUG sprintf(sql, SQLTUF2_6, trade_list); elog(NOTICE, "SQL\n%s", sql); #endif /* DEBUG */ ret = SPI_execute_plan(TUF2_6, args, nulls, true, 0); if (ret == SPI_OK_SELECT && SPI_processed > 0) { l_tupdesc = SPI_tuptable->tupdesc; l_tuptable = SPI_tuptable; } else { FAIL_FRAME_SET(&funcctx->max_calls, TUF2_statements[5].sql); dump_tuf2_inputs(acct_id, end_trade_dts, max_trades, max_updates, start_trade_dts); continue; } strcat(values[i_trade_history_dts], "{"); strcat(values[i_trade_history_status_id], "{"); for (j = 0; j < SPI_processed; j ++) { if (j > 0) { strcat(values[i_trade_history_dts], ","); strcat(values[i_trade_history_status_id], ","); } l_tuple = l_tuptable->vals[j]; strcat(values[i_trade_history_dts], SPI_getvalue(l_tuple, l_tupdesc, 1)); strcat(values[i_trade_history_status_id], "\""); strcat(values[i_trade_history_status_id], SPI_getvalue(l_tuple, l_tupdesc, 2)); strcat(values[i_trade_history_status_id], "\""); } for (j = SPI_processed; j < 3; j++) { if (j > 0) { strcat(values[i_trade_history_dts], ","); strcat(values[i_trade_history_status_id], ","); } strcat(values[i_trade_history_dts], "NULL"); strcat(values[i_trade_history_status_id], "\"\""); } strcat(values[i_trade_history_dts], "}"); strcat(values[i_trade_history_status_id], "}"); } strcat(values[i_bid_price], "}"); strcat(values[i_exec_name], "}"); strcat(values[i_is_cash], "}"); strcat(values[i_trade_list], "}"); strcat(values[i_trade_price], "}"); strcat(values[i_settlement_amount], "}"); strcat(values[i_settlement_cash_due_date], "}"); strcat(values[i_settlement_cash_type], "}"); strcat(values[i_cash_transaction_amount], "}"); strcat(values[i_cash_transaction_dts], "}"); strcat(values[i_cash_transaction_name], "}"); strcat(values[i_trade_history_dts], "}"); strcat(values[i_trade_history_status_id], "}"); sprintf(values[i_num_found], "%d", num_found); sprintf(values[i_num_updated], "%d", num_updated); /* Build a tuple descriptor for our result type */ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) { ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("function returning record called in context " "that cannot accept type record"))); } /* * generate attribute metadata needed later to produce tuples from raw * C strings */ attinmeta = TupleDescGetAttInMetadata(tupdesc); funcctx->attinmeta = attinmeta; MemoryContextSwitchTo(oldcontext); } /* stuff done on every call of the function */ funcctx = SRF_PERCALL_SETUP(); call_cntr = funcctx->call_cntr; max_calls = funcctx->max_calls; attinmeta = funcctx->attinmeta; if (call_cntr < max_calls) { /* do when there is more left to send */ HeapTuple tuple; Datum result; #ifdef DEBUG for (i = 0; i < 15; i++) { elog(NOTICE, "TUF2 OUT: %d %s", i, values[i]); } #endif /* DEBUG */ /* Build a tuple. */ tuple = BuildTupleFromCStrings(attinmeta, values); /* Make the tuple into a datum. */ result = HeapTupleGetDatum(tuple); SRF_RETURN_NEXT(funcctx, result); } else { /* Do when there is no more left. */ SPI_finish(); SRF_RETURN_DONE(funcctx); } }
/* * linterp_abscissa * * Common code that checks arguments. The result is a floating point value * representing what fraction of the distance x lies along the interval from * x0 to x1. It can be negative or greater than one (extrapolation) though * this isn't the intended use. If x0 == x1, then the fraction is not * determined and the function returns 0 and sets *notnull false. In all * other cases (except error exits) *notnull is set to true. An additional * flag indicates whether the abscissa value is equal to the lower boundary * value. */ static float8 linterp_abscissa(PG_FUNCTION_ARGS, bool *p_eq_bounds, bool *p_eq_abscissas) { Oid x_type; Oid x0_type; Oid x1_type; Oid y0_type; Oid y1_type; float8 p = 0; bool eq_bounds = false; bool eq_abscissas = false; /* The abscissa (x) arguments are nominally declared anyelement. * All the type checking is up to us. We insist that the types * are exactly alike. Explicit casts may be needed. */ x_type = get_fn_expr_argtype(fcinfo->flinfo, 0); x0_type = get_fn_expr_argtype(fcinfo->flinfo, 1); x1_type = get_fn_expr_argtype(fcinfo->flinfo, 3); if (!OidIsValid(x_type)||!OidIsValid(x0_type)||!OidIsValid(x1_type)) { elog(ERROR, "could not determine argument data types"); } if ( x_type!=x0_type || x_type!=x1_type ) { elog(ERROR, "abscissa types unequal"); } /* The ordinate (y) arguments are specifically declared in the SQL * function declaration. Here we just check and insist they are * identical. */ y0_type = get_fn_expr_argtype(fcinfo->flinfo, 2); y1_type = get_fn_expr_argtype(fcinfo->flinfo, 4); if ( y0_type != y1_type ) { elog(ERROR, "mismatched ordinate types"); } switch (x_type) { case INT8OID: { float8 x = (float8)PG_GETARG_INT64(0); float8 x0 = (float8)PG_GETARG_INT64(1); float8 x1 = (float8)PG_GETARG_INT64(3); if ( x1 == x0 ) { eq_bounds = true; eq_abscissas = ( x == x0 ); } else p = (x-x0)/(x1-x0); } break; case INT4OID: { float8 x = (float8)PG_GETARG_INT32(0); float8 x0 = (float8)PG_GETARG_INT32(1); float8 x1 = (float8)PG_GETARG_INT32(3); if ( x1 == x0 ) { eq_bounds = true; eq_abscissas = ( x == x0 ); } else p = (x-x0)/(x1-x0); } break; case INT2OID: { float8 x = (float8)PG_GETARG_INT16(0); float8 x0 = (float8)PG_GETARG_INT16(1); float8 x1 = (float8)PG_GETARG_INT16(3); if ( x1 == x0 ) { eq_bounds = true; eq_abscissas = ( x == x0 ); } else p = (x-x0)/(x1-x0); } break; case FLOAT4OID: { float8 x = (float8)PG_GETARG_FLOAT4(0); float8 x0 = (float8)PG_GETARG_FLOAT4(1); float8 x1 = (float8)PG_GETARG_FLOAT4(3); if ( x1 == x0 ) { eq_bounds = true; eq_abscissas = ( x == x0 ); } else p = (x-x0)/(x1-x0); } break; case FLOAT8OID: { float8 x = PG_GETARG_FLOAT8(0); float8 x0 = PG_GETARG_FLOAT8(1); float8 x1 = PG_GETARG_FLOAT8(3); if ( x1 == x0 ) { eq_bounds = true; eq_abscissas = ( x == x0 ); } else p = (x-x0)/(x1-x0); } break; case DATEOID: { DateADT x = PG_GETARG_DATEADT(0); DateADT x0 = PG_GETARG_DATEADT(1); DateADT x1 = PG_GETARG_DATEADT(3); int32 x_x0 = date_diff(x, x0); int32 x1_x0 = date_diff(x1, x0); if ( x1 == x0 ) { eq_bounds = true; eq_abscissas = ( x_x0 == 0 ); } else p = ((float8)x_x0)/((float8)x1_x0); } break; case TIMEOID: { TimeADT x = PG_GETARG_TIMEADT(0); TimeADT x0 = PG_GETARG_TIMEADT(1); TimeADT x1 = PG_GETARG_TIMEADT(3); p = time_li_fraction(x, x0, x1, &eq_bounds, &eq_abscissas); } break; case TIMESTAMPOID: { Timestamp x = PG_GETARG_TIMESTAMP(0); Timestamp x0 = PG_GETARG_TIMESTAMP(1); Timestamp x1 = PG_GETARG_TIMESTAMP(3); p = timestamp_li_fraction(x, x0, x1, &eq_bounds, &eq_abscissas); } break; case TIMESTAMPTZOID: { TimestampTz x = PG_GETARG_TIMESTAMPTZ(0); TimestampTz x0 = PG_GETARG_TIMESTAMPTZ(1); TimestampTz x1 = PG_GETARG_TIMESTAMPTZ(3); p = timestamptz_li_fraction(x, x0, x1, &eq_bounds, &eq_abscissas); } break; case INTERVALOID: { Interval * x = PG_GETARG_INTERVAL_P(0); Interval * x0 = PG_GETARG_INTERVAL_P(1); Interval * x1 = PG_GETARG_INTERVAL_P(3); p = interval_li_fraction(x, x0, x1, &eq_bounds, &eq_abscissas); } break; case NUMERICOID: { Numeric x = PG_GETARG_NUMERIC(0); Numeric x0 = PG_GETARG_NUMERIC(1); Numeric x1 = PG_GETARG_NUMERIC(3); p = numeric_li_fraction(x, x0, x1, &eq_bounds, &eq_abscissas); } break; default: elog(ERROR, "abscissa type not supported"); } if ( p_eq_bounds ) *p_eq_bounds = eq_bounds; if ( p_eq_abscissas ) *p_eq_abscissas = eq_abscissas; return p; }