/* headline(text, text, tsquery [,text]) */ Datum tsa_headline_byname(PG_FUNCTION_ARGS) { Datum arg0 = PG_GETARG_DATUM(0); Datum arg1 = PG_GETARG_DATUM(1); Datum arg2 = PG_GETARG_DATUM(2); Datum result; Oid config_oid; /* first parameter has to be converted to oid */ config_oid = DatumGetObjectId(DirectFunctionCall1(regconfigin, DirectFunctionCall1(textout, arg0))); if (PG_NARGS() == 3) result = DirectFunctionCall3(ts_headline_byid, ObjectIdGetDatum(config_oid), arg1, arg2); else { Datum arg3 = PG_GETARG_DATUM(3); result = DirectFunctionCall4(ts_headline_byid_opt, ObjectIdGetDatum(config_oid), arg1, arg2, arg3); } return result; }
Datum ora_to_date(PG_FUNCTION_ARGS) { text *date_txt = PG_GETARG_TEXT_PP(0); Timestamp result; if(nls_date_format && strlen(nls_date_format)) { Datum newDate; /* it will return timestamp at GMT */ newDate = DirectFunctionCall2(to_timestamp, CStringGetDatum(date_txt), CStringGetDatum(cstring_to_text(nls_date_format))); /* convert to local timestamp */ result = DatumGetTimestamp(DirectFunctionCall1(timestamptz_timestamp, newDate)); } else result = DatumGetTimestamp(DirectFunctionCall3(timestamp_in, CStringGetDatum(text_to_cstring(date_txt)), ObjectIdGetDatum(InvalidOid), Int32GetDatum(-1))); PG_RETURN_TIMESTAMP(result); }
/* ** The GiST Consistent method for _intments ** Should return false if for all data items x below entry, ** the predicate x op query == FALSE, where op is the oper ** corresponding to strategy in the pg_amop table. */ Datum g_int_consistent(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); ArrayType *query = (ArrayType *) PG_DETOAST_DATUM_COPY(PG_GETARG_POINTER(1)); StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); bool retval; if (strategy == BooleanSearchStrategy) { retval =execconsistent((QUERYTYPE *) query, (ArrayType *) DatumGetPointer(entry->key), ISLEAFKEY((ArrayType *) DatumGetPointer(entry->key))); pfree( query ); PG_RETURN_BOOL(retval); } /* sort query for fast search, key is already sorted */ if (ARRISVOID(query)) { pfree( query ); PG_RETURN_BOOL(false); } PREPAREARR(query); switch (strategy) { case RTOverlapStrategyNumber: retval = inner_int_overlap((ArrayType *) DatumGetPointer(entry->key), query); break; case RTSameStrategyNumber: if (GIST_LEAF(entry)) DirectFunctionCall3( g_int_same, entry->key, PointerGetDatum(query), PointerGetDatum(&retval) ); else retval = inner_int_contains((ArrayType *) DatumGetPointer(entry->key), query); break; case RTContainsStrategyNumber: retval = inner_int_contains((ArrayType *) DatumGetPointer(entry->key), query); break; case RTContainedByStrategyNumber: if (GIST_LEAF(entry)) retval = inner_int_contains(query, (ArrayType *) DatumGetPointer(entry->key)); else retval = inner_int_overlap((ArrayType *) DatumGetPointer(entry->key), query); break; default: retval = FALSE; } pfree( query ); PG_RETURN_BOOL(retval); }
/* * build_regexp_split_result - build output string for current match * * We return the string between the current match and the previous one, * or the string after the last match when next_match == nmatches. */ static Datum build_regexp_split_result(regexp_matches_ctx *splitctx) { int startpos; int endpos; if (splitctx->next_match > 0) startpos = splitctx->match_locs[splitctx->next_match * 2 - 1]; else startpos = 0; if (startpos < 0) elog(ERROR, "invalid match ending position"); if (splitctx->next_match < splitctx->nmatches) { endpos = splitctx->match_locs[splitctx->next_match * 2]; if (endpos < startpos) elog(ERROR, "invalid match starting position"); return DirectFunctionCall3(text_substr, PointerGetDatum(splitctx->orig_str), Int32GetDatum(startpos + 1), Int32GetDatum(endpos - startpos)); } else { /* no more matches, return rest of string */ return DirectFunctionCall2(text_substr_no_len, PointerGetDatum(splitctx->orig_str), Int32GetDatum(startpos + 1)); } }
Datum ST_LocateBetween(PG_FUNCTION_ARGS) { GSERIALIZED *geom_in = PG_GETARG_GSERIALIZED_P(0); double from = PG_GETARG_FLOAT8(1); double to = PG_GETARG_FLOAT8(2); double offset = PG_GETARG_FLOAT8(3); LWCOLLECTION *geom_out = NULL; LWGEOM *line_in = NULL; static char ordinate = 'M'; /* M */ if ( ! gserialized_has_m(geom_in) ) { elog(ERROR,"This function only accepts geometries that have an M dimension."); PG_RETURN_NULL(); } /* This should be a call to ST_LocateAlong! */ if ( to == from ) { PG_RETURN_DATUM(DirectFunctionCall3(ST_LocateAlong, PG_GETARG_DATUM(0), PG_GETARG_DATUM(1), PG_GETARG_DATUM(3))); } line_in = lwgeom_from_gserialized(geom_in); geom_out = lwgeom_clip_to_ordinate_range(line_in, ordinate, from, to, offset); lwgeom_free(line_in); PG_FREE_IF_COPY(geom_in, 0); if ( ! geom_out ) { elog(ERROR,"lwline_clip_to_ordinate_range returned null"); PG_RETURN_NULL(); } PG_RETURN_POINTER(geometry_serialize((LWGEOM*)geom_out)); }
/* * len < 0 means "length is not specified". */ static text * ora_substr(Datum str, int start, int len) { if (start == 0) start = 1; /* 0 is interpreted as 1 */ else if (start < 0) { text *t; int32 n; t = DatumGetTextPP(str); n = pg_mbstrlen_with_len(VARDATA_ANY(t), VARSIZE_ANY_EXHDR(t)); start = n + start + 1; if (start <= 0) return cstring_to_text(""); str = PointerGetDatum(t); /* save detoasted text */ } if (len < 0) return DatumGetTextP(DirectFunctionCall2(text_substr_no_len, str, Int32GetDatum(start))); else return DatumGetTextP(DirectFunctionCall3(text_substr, str, Int32GetDatum(start), Int32GetDatum(len))); }
Datum pgstrom_numeric_var_accum(PG_FUNCTION_ARGS) { int32 nrows = PG_GETARG_INT32(1); MemoryContext aggcxt; MemoryContext oldcxt; numeric_agg_state *state; if (!AggCheckCallContext(fcinfo, &aggcxt)) elog(ERROR, "aggregate function called in non-aggregate context"); if (PG_ARGISNULL(1)) nrows = 0; else if (nrows < 0) elog(ERROR, "Bug? negative nrows were given"); /* make a state object and update it */ oldcxt = MemoryContextSwitchTo(aggcxt); state = PG_ARGISNULL(0) ? NULL : (numeric_agg_state *)PG_GETARG_POINTER(0); if (!state) { state = palloc0(sizeof(numeric_agg_state)); state->N = 0; state->sumX = DirectFunctionCall3(numeric_in, CStringGetDatum("0"), ObjectIdGetDatum(0), Int32GetDatum(-1)); state->sumX2 = DirectFunctionCall3(numeric_in, CStringGetDatum("0"), ObjectIdGetDatum(0), Int32GetDatum(-1)); } if (nrows > 0 && !PG_ARGISNULL(2) && !PG_ARGISNULL(3)) { state->N += nrows; state->sumX = DirectFunctionCall2(numeric_add, state->sumX, PG_GETARG_DATUM(2)); state->sumX2 = DirectFunctionCall2(numeric_add, state->sumX2, PG_GETARG_DATUM(3)); } MemoryContextSwitchTo(oldcxt); PG_RETURN_POINTER(state); }
/* * Returns start time of an online exclusive backup. * * When there's no exclusive backup in progress, the function * returns NULL. */ Datum pg_backup_start_time(PG_FUNCTION_ARGS) { Datum xtime; FILE *lfp; char fline[MAXPGPATH]; char backup_start_time[30]; /* * See if label file is present */ lfp = AllocateFile(BACKUP_LABEL_FILE, "r"); if (lfp == NULL) { if (errno != ENOENT) ereport(ERROR, (errcode_for_file_access(), errmsg("could not read file \"%s\": %m", BACKUP_LABEL_FILE))); PG_RETURN_NULL(); } /* * Parse the file to find the START TIME line. */ backup_start_time[0] = '\0'; while (fgets(fline, sizeof(fline), lfp) != NULL) { if (sscanf(fline, "START TIME: %25[^\n]\n", backup_start_time) == 1) break; } /* Check for a read error. */ if (ferror(lfp)) ereport(ERROR, (errcode_for_file_access(), errmsg("could not read file \"%s\": %m", BACKUP_LABEL_FILE))); /* Close the backup label file. */ if (FreeFile(lfp)) ereport(ERROR, (errcode_for_file_access(), errmsg("could not close file \"%s\": %m", BACKUP_LABEL_FILE))); if (strlen(backup_start_time) == 0) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE))); /* * Convert the time string read from file to TimestampTz form. */ xtime = DirectFunctionCall3(timestamptz_in, CStringGetDatum(backup_start_time), ObjectIdGetDatum(InvalidOid), Int32GetDatum(-1)); PG_RETURN_DATUM(xtime); }
static Datum leftmostvalue_varbit(void) { return DirectFunctionCall3(varbit_in, CStringGetDatum(""), ObjectIdGetDatum(0), Int32GetDatum(-1)); }
Datum ginqueryarrayextract(PG_FUNCTION_ARGS) { PG_RETURN_DATUM(DirectFunctionCall3(ginarrayextract, PG_GETARG_DATUM(0), PG_GETARG_DATUM(1), PG_GETARG_DATUM(2))); }
static Datum leftmostvalue_inet(void) { return DirectFunctionCall3(inet_in, CStringGetDatum("0.0.0.0/0"), ObjectIdGetDatum(0), Int32GetDatum(-1)); }
Datum ts_headline_byid(PG_FUNCTION_ARGS) { PG_RETURN_DATUM(DirectFunctionCall3(ts_headline_byid_opt, PG_GETARG_DATUM(0), PG_GETARG_DATUM(1), PG_GETARG_DATUM(2))); }
Datum ts_headline(PG_FUNCTION_ARGS) { PG_RETURN_DATUM(DirectFunctionCall3(ts_headline_byid_opt, ObjectIdGetDatum(getTSCurrentConfig(true)), PG_GETARG_DATUM(0), PG_GETARG_DATUM(1))); }
Datum spheretrans_from_float8_and_type(PG_FUNCTION_ARGS) { SEuler *se; Datum d[3]; int i; char *c = PG_GETARG_CSTRING(3); unsigned char t = 0; d[0] = PG_GETARG_DATUM(0); d[1] = PG_GETARG_DATUM(1); d[2] = PG_GETARG_DATUM(2); se = (SEuler *) DatumGetPointer( DirectFunctionCall3(spheretrans_from_float8, d[0], d[1], d[2])); for (i = 0; i < 3; i++) { switch (c[i]) { case 'x': case 'X': t = EULER_AXIS_X; break; case 'y': case 'Y': t = EULER_AXIS_Y; break; case 'z': case 'Z': t = EULER_AXIS_Z; break; default: t = 0; } if (t == 0) { pfree(se); elog(ERROR, "invalid axis format"); } switch (i) { case 0: se->phi_a = t; break; case 1: se->theta_a = t; break; case 2: se->psi_a = t; break; } } PG_RETURN_POINTER(se); }
Datum tsquery_phrase(PG_FUNCTION_ARGS) { PG_RETURN_POINTER(DirectFunctionCall3( tsquery_phrase_distance, PG_GETARG_DATUM(0), PG_GETARG_DATUM(1), Int32GetDatum(1))); }
/* ** The GiST Consistent method for _intments ** Should return false if for all data items x below entry, ** the predicate x op query == FALSE, where op is the oper ** corresponding to strategy in the pg_amop table. */ Datum g_int_consistent(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); ArrayType *query = (ArrayType *) PG_GETARG_POINTER(1); StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); bool retval; if (strategy == BooleanSearchStrategy) PG_RETURN_BOOL(execconsistent((QUERYTYPE *) query, (ArrayType *) DatumGetPointer(entry->key), ISLEAFKEY((ArrayType *) DatumGetPointer(entry->key)))); /* XXX are we sure it's safe to scribble on the query object here? */ /* XXX what about toasted input? */ /* sort query for fast search, key is already sorted */ if (ARRISVOID(query)) PG_RETURN_BOOL(false); PREPAREARR(query); switch (strategy) { case RTOverlapStrategyNumber: retval = inner_int_overlap((ArrayType *) DatumGetPointer(entry->key), query); break; case RTSameStrategyNumber: if (GIST_LEAF(entry)) DirectFunctionCall3( g_int_same, entry->key, PointerGetDatum(query), PointerGetDatum(&retval) ); else retval = inner_int_contains((ArrayType *) DatumGetPointer(entry->key), query); break; case RTContainsStrategyNumber: retval = inner_int_contains((ArrayType *) DatumGetPointer(entry->key), query); break; case RTContainedByStrategyNumber: if (GIST_LEAF(entry)) retval = inner_int_contains(query, (ArrayType *) DatumGetPointer(entry->key)); else retval = inner_int_overlap((ArrayType *) DatumGetPointer(entry->key), query); break; default: retval = FALSE; } PG_RETURN_BOOL(retval); }
Datum decimal64_numeric(PG_FUNCTION_ARGS) { PGDecimal64 a = PG_GETARG_DECIMAL64(0); Datum ret; char s[DECDOUBLE_String]; decDoubleToString(&a, s); ret = DirectFunctionCall3(numeric_in, CStringGetDatum(s), Int32GetDatum(0), Int32GetDatum(-1)); PG_RETURN_DATUM(ret); }
Datum geography_from_text(PG_FUNCTION_ARGS) { text *wkt_text = PG_GETARG_TEXT_P(0); /* Extract the cstring from the varlena */ char *wkt = text2cstring(wkt_text); /* Pass the cstring to the input parser, and magic occurs! */ Datum rv = DirectFunctionCall3(geography_in, PointerGetDatum(wkt), Int32GetDatum(0), Int32GetDatum(-1)); /* Clean up and return */ pfree(wkt); PG_RETURN_DATUM(rv); }
Datum to_tsvector_current(PG_FUNCTION_ARGS) { Datum res = DirectFunctionCall3( to_tsvector, Int32GetDatum(get_currcfg()), PG_GETARG_DATUM(0), (Datum) 0 ); PG_RETURN_DATUM(res); }
/* Invokes a compression constructor */ CompressionState * callCompressionConstructor(PGFunction constructor, TupleDesc tupledesc, StorageAttributes *sa, bool is_compress) { return DatumGetPointer(DirectFunctionCall3(constructor, PointerGetDatum(tupledesc), PointerGetDatum(sa), BoolGetDatum(is_compress))); }
/* * textregexsubstr() * Return a substring matched by a regular expression. */ Datum textregexsubstr(PG_FUNCTION_ARGS) { text *s = PG_GETARG_TEXT_PP(0); text *p = PG_GETARG_TEXT_PP(1); regex_t *re; regmatch_t pmatch[2]; int so, eo; /* Compile RE */ re = RE_compile_and_cache(p, REG_ADVANCED, PG_GET_COLLATION()); /* * We pass two regmatch_t structs to get info about the overall match and * the match for the first parenthesized subexpression (if any). If there * is a parenthesized subexpression, we return what it matched; else * return what the whole regexp matched. */ if (!RE_execute(re, VARDATA_ANY(s), VARSIZE_ANY_EXHDR(s), 2, pmatch)) PG_RETURN_NULL(); /* definitely no match */ if (re->re_nsub > 0) { /* has parenthesized subexpressions, use the first one */ so = pmatch[1].rm_so; eo = pmatch[1].rm_eo; } else { /* no parenthesized subexpression, use whole match */ so = pmatch[0].rm_so; eo = pmatch[0].rm_eo; } /* * It is possible to have a match to the whole pattern but no match for a * subexpression; for example 'foo(bar)?' is considered to match 'foo' but * there is no subexpression match. So this extra test for match failure * is not redundant. */ if (so < 0 || eo < 0) PG_RETURN_NULL(); return DirectFunctionCall3(text_substr, PointerGetDatum(s), Int32GetDatum(so + 1), Int32GetDatum(eo - so)); }
/* * build_regexp_matches_result - build output array for current match */ static ArrayType * build_regexp_matches_result(regexp_matches_ctx *matchctx) { char *buf = matchctx->conv_buf; int bufsiz PG_USED_FOR_ASSERTS_ONLY = matchctx->conv_bufsiz; Datum *elems = matchctx->elems; bool *nulls = matchctx->nulls; int dims[1]; int lbs[1]; int loc; int i; /* Extract matching substrings from the original string */ loc = matchctx->next_match * matchctx->npatterns * 2; for (i = 0; i < matchctx->npatterns; i++) { int so = matchctx->match_locs[loc++]; int eo = matchctx->match_locs[loc++]; if (so < 0 || eo < 0) { elems[i] = (Datum) 0; nulls[i] = true; } else if (buf) { int len = pg_wchar2mb_with_len(matchctx->wide_str + so, buf, eo - so); Assert(len < bufsiz); elems[i] = PointerGetDatum(cstring_to_text_with_len(buf, len)); nulls[i] = false; } else { elems[i] = DirectFunctionCall3(text_substr, PointerGetDatum(matchctx->orig_str), Int32GetDatum(so + 1), Int32GetDatum(eo - so)); nulls[i] = false; } } /* And form an array */ dims[0] = matchctx->npatterns; lbs[0] = 1; /* XXX: this hardcodes assumptions about the text type */ return construct_md_array(elems, nulls, 1, dims, lbs, TEXTOID, -1, false, 'i'); }
/* * pgstrom.psum_x2(numeric) */ Datum pgstrom_partial_sum_x2_numeric(PG_FUNCTION_ARGS) { Datum value; if (!PG_ARGISNULL(0)) value = PG_GETARG_DATUM(0); /* a valid numeric value */ else value = DirectFunctionCall3(numeric_in, CStringGetDatum("0"), ObjectIdGetDatum(InvalidOid), Int32GetDatum(-1)); return DirectFunctionCall2(numeric_mul, value, value); }
Datum to_tsvector_name(PG_FUNCTION_ARGS) { text *cfg = PG_GETARG_TEXT_P(0); Datum res = DirectFunctionCall3( to_tsvector, Int32GetDatum(name2id_cfg(cfg)), PG_GETARG_DATUM(1), (Datum) 0 ); PG_FREE_IF_COPY(cfg, 0); PG_RETURN_DATUM(res); }
/* * Utility to convert PGresult cell in text to Datum */ static Datum ResultToDatum(PGresult *result, int row, AttrNumber attnum, PGFunction func, bool *isnull) { if (PQgetisnull(result, row, attnum)) { *isnull = true; return (Datum) 0; } else { *isnull = false; return DirectFunctionCall3(func, CStringGetDatum(PQgetvalue(result, row, attnum)), ObjectIdGetDatum(InvalidOid), Int32GetDatum(-1)); } }
/* * Convert string using encoding_nanme. We assume that string's * encoding is same as DB encoding. * * TEXT convert(TEXT string, NAME encoding_name) */ Datum pg_convert(PG_FUNCTION_ARGS) { Datum string = PG_GETARG_DATUM(0); Datum dest_encoding_name = PG_GETARG_DATUM(1); Datum src_encoding_name = DirectFunctionCall1( namein, CStringGetDatum(DatabaseEncoding->name)); Datum result; result = DirectFunctionCall3( pg_convert2, string, src_encoding_name, dest_encoding_name); /* free memory allocated by namein */ pfree((void *) src_encoding_name); PG_RETURN_TEXT_P(result); }
Datum setval3_mirror(PG_FUNCTION_ARGS) { Oid relid = PG_GETARG_OID(0); int64 next = PG_GETARG_INT64(1); bool iscalled = PG_GETARG_BOOL(2); int64 result; result = DatumGetInt64(DirectFunctionCall3(setval3_oid, ObjectIdGetDatum(relid), Int64GetDatum(next), BoolGetDatum(iscalled))); saveSequenceUpdate(relid, result, iscalled); PG_RETURN_INT64(result); }
/* * textregexsubstr() * Return a substring matched by a regular expression. */ Datum textregexsubstr(PG_FUNCTION_ARGS) { text *s = PG_GETARG_TEXT_P(0); text *p = PG_GETARG_TEXT_P(1); bool match; regmatch_t pmatch[2]; /* * We pass two regmatch_t structs to get info about the overall match and * the match for the first parenthesized subexpression (if any). If there * is a parenthesized subexpression, we return what it matched; else * return what the whole regexp matched. */ match = RE_compile_and_execute(p, VARDATA(s), VARSIZE(s) - VARHDRSZ, regex_flavor, 2, pmatch); /* match? then return the substring matching the pattern */ if (match) { int so, eo; so = pmatch[1].rm_so; eo = pmatch[1].rm_eo; if (so < 0 || eo < 0) { /* no parenthesized subexpression */ so = pmatch[0].rm_so; eo = pmatch[0].rm_eo; } return DirectFunctionCall3(text_substr, PointerGetDatum(s), Int32GetDatum(so + 1), Int32GetDatum(eo - so)); } PG_RETURN_NULL(); }
Datum geography_from_binary(PG_FUNCTION_ARGS) { char *wkb_cstring = NULL; text *wkb_hex = NULL; char *wkb_bytea = (char*)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); char *hexarg = palloc(4 + VARHDRSZ); /* Create our second argument to binary_encode */ SET_VARSIZE(hexarg, 4 + VARHDRSZ); memcpy(VARDATA(hexarg), "hex", 4); /* Convert the bytea into a hex representation cstring */ wkb_hex = (text*)DatumGetPointer(DirectFunctionCall2(binary_encode, PointerGetDatum(wkb_bytea), PointerGetDatum(hexarg))); wkb_cstring = text2cstring(wkb_hex); pfree(hexarg); /* Pass the cstring to the input parser, and magic occurs! */ PG_RETURN_DATUM(DirectFunctionCall3(geography_in, PointerGetDatum(wkb_cstring), Int32GetDatum(0), Int32GetDatum(-1))); }
/* * Convert string using encoding_name. The source * encoding is the DB encoding. * * BYTEA convert_to(TEXT string, NAME encoding_name) */ Datum pg_convert_to(PG_FUNCTION_ARGS) { Datum string = PG_GETARG_DATUM(0); Datum dest_encoding_name = PG_GETARG_DATUM(1); Datum src_encoding_name = DirectFunctionCall1(namein, CStringGetDatum(DatabaseEncoding->name)); Datum result; /* * pg_convert expects a bytea as its first argument. We're passing it a * text argument here, relying on the fact that they are both in fact * varlena types, and thus structurally identical. */ result = DirectFunctionCall3(pg_convert, string, src_encoding_name, dest_encoding_name); PG_RETURN_DATUM(result); }