Datum get_semester(PG_FUNCTION_ARGS) { pg_tm current_date; GetCurrentDateTime(¤t_date); DateADT entering_date = DatumGetDateADT(PG_GETARG_DATUM(0)); int entering_year, entering_month, entering_day; j2date(entering_date + date2j(2000, 1, 1), &entering_year, &entering_month, &entering_day); int semester = (current_date.tm_year - entering_year) * 2; if (current_date.tm_mon > 6) semester++; PG_RETURN_INT32(semester); }
Datum hashoptions(PG_FUNCTION_ARGS) { Datum reloptions = PG_GETARG_DATUM(0); bool validate = PG_GETARG_BOOL(1); bytea *result; result = default_reloptions(reloptions, validate, RELKIND_INDEX, HASH_MIN_FILLFACTOR, HASH_DEFAULT_FILLFACTOR); if (result) PG_RETURN_BYTEA_P(result); PG_RETURN_NULL(); }
Datum on_partitions_removed(PG_FUNCTION_ARGS) { Oid relid; LWLockAcquire(pmstate->load_config_lock, LW_EXCLUSIVE); /* parent relation oid */ relid = DatumGetInt32(PG_GETARG_DATUM(0)); remove_relation_info(relid); LWLockRelease(pmstate->load_config_lock); PG_RETURN_NULL(); }
Datum geography_from_binary(PG_FUNCTION_ARGS) { char *wkb_bytea = (char*)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); GSERIALIZED *gser = NULL; size_t wkb_size = VARSIZE(wkb_bytea); uint8_t *wkb = (uint8_t*)VARDATA(wkb_bytea); LWGEOM *lwgeom = lwgeom_from_wkb(wkb, wkb_size, LW_PARSER_CHECK_NONE); if ( ! lwgeom ) lwerror("Unable to parse WKB"); gser = gserialized_geography_from_lwgeom(lwgeom, 0); lwgeom_free(lwgeom); PG_RETURN_POINTER(gser); }
Datum ts_rankcd_wtt(PG_FUNCTION_ARGS) { ArrayType *win = (ArrayType *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); TSVector txt = PG_GETARG_TSVECTOR(1); TSQuery query = PG_GETARG_TSQUERY(2); float res; res = calc_rank_cd(getWeights(win), txt, query, DEF_NORM_METHOD); PG_FREE_IF_COPY(win, 0); PG_FREE_IF_COPY(txt, 1); PG_FREE_IF_COPY(query, 2); PG_RETURN_FLOAT4(res); }
Datum LWGEOM_line_locate_point(PG_FUNCTION_ARGS) { GSERIALIZED *geom1 = (GSERIALIZED *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); GSERIALIZED *geom2 = (GSERIALIZED *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); LWLINE *lwline; LWPOINT *lwpoint; POINTARRAY *pa; POINT2D p; double ret; if ( gserialized_get_type(geom1) != LINETYPE ) { elog(ERROR,"line_locate_point: 1st arg isnt a line"); PG_RETURN_NULL(); } if ( gserialized_get_type(geom2) != POINTTYPE ) { elog(ERROR,"line_locate_point: 2st arg isnt a point"); PG_RETURN_NULL(); } if ( gserialized_get_srid(geom1) != gserialized_get_srid(geom2) ) { elog(ERROR, "Operation on two geometries with different SRIDs"); PG_RETURN_NULL(); } lwline = lwgeom_as_lwline(lwgeom_from_gserialized(geom1)); lwpoint = lwgeom_as_lwpoint(lwgeom_from_gserialized(geom2)); pa = lwline->points; lwpoint_getPoint2d_p(lwpoint, &p); ret = ptarray_locate_point(pa, &p, NULL); PG_RETURN_FLOAT8(ret); }
Datum lwgeom_eq(PG_FUNCTION_ARGS) { GSERIALIZED *geom1 = (GSERIALIZED *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); GSERIALIZED *geom2 = (GSERIALIZED *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); GBOX box1; GBOX box2; bool result; POSTGIS_DEBUG(2, "lwgeom_eq called"); if (gserialized_get_srid(geom1) != gserialized_get_srid(geom2)) { elog(BTREE_SRID_MISMATCH_SEVERITY, "Operation on two GEOMETRIES with different SRIDs\n"); PG_FREE_IF_COPY(geom1, 0); PG_FREE_IF_COPY(geom2, 1); PG_RETURN_NULL(); } gserialized_get_gbox_p(geom1, &box1); gserialized_get_gbox_p(geom2, &box2); PG_FREE_IF_COPY(geom1, 0); PG_FREE_IF_COPY(geom2, 1); if ( ! (FPeq(box1.xmin, box2.xmin) && FPeq(box1.ymin, box2.ymin) && FPeq(box1.xmax, box2.xmax) && FPeq(box1.ymax, box2.ymax)) ) { result = FALSE; } else { result = TRUE; } PG_RETURN_BOOL(result); }
Datum geography_le(PG_FUNCTION_ARGS) { /* Put aside some stack memory and use it for GIDX pointers. */ char gboxmem1[GIDX_MAX_SIZE]; char gboxmem2[GIDX_MAX_SIZE]; GIDX *gbox1 = (GIDX*)gboxmem1; GIDX *gbox2 = (GIDX*)gboxmem2; POINT3D p1, p2; /* Must be able to build box for each argument (ie, not empty geometry) */ if ( ! gserialized_datum_get_gidx_p(PG_GETARG_DATUM(0), gbox1) || ! gserialized_datum_get_gidx_p(PG_GETARG_DATUM(1), gbox2) ) { PG_RETURN_BOOL(FALSE); } geography_gidx_center(gbox1, &p1); geography_gidx_center(gbox2, &p2); if ( p1.x <= p2.x || p1.y <= p2.y || p1.z <= p2.z ) PG_RETURN_BOOL(TRUE); PG_RETURN_BOOL(FALSE); }
Datum pgq_set_connection_context(PG_FUNCTION_ARGS) { char *ctx; if (current_context) pfree(current_context); current_context = NULL; if (PG_NARGS() > 0 && !PG_ARGISNULL(0)) { ctx = DatumGetCString(DirectFunctionCall1(textout, PG_GETARG_DATUM(0))); current_context = MemoryContextStrdup(TopMemoryContext, ctx); pfree(ctx); } PG_RETURN_VOID(); }
Datum mol_murckoscaffold(PG_FUNCTION_ARGS) { CROMol mol; fcinfo->flinfo->fn_extra = SearchMolCache( fcinfo->flinfo->fn_extra, fcinfo->flinfo->fn_mcxt, PG_GETARG_DATUM(0), NULL, &mol, NULL); CROMol scaffold=MolMurckoScaffold(mol); if(!scaffold) PG_RETURN_NULL(); Mol *res = deconstructROMol(scaffold); freeCROMol(scaffold); PG_RETURN_MOL_P(res); }
Datum fingerprint(PG_FUNCTION_ARGS){ Datum mol_datum = PG_GETARG_DATUM(0); Datum options_datum = PG_GETARG_DATUM(1); void* result = 0; PG_BINGO_BEGIN { BingoPgCommon::BingoSessionHandler bingo_handler(fcinfo->flinfo->fn_oid); bingo_handler.setFunctionName("fingerprint"); BingoPgText mol_text(mol_datum); BingoPgText mol_options(options_datum); int buf_size; const char* mol_buf = mol_text.getText(buf_size); int res_buf; const char* bingo_result = mangoFingerprint(mol_buf, buf_size, mol_options.getString(), &res_buf); if(bingo_result == 0) { CORE_HANDLE_WARNING(0, 1, "bingo.fingerprint", bingoGetError()); PG_RETURN_NULL(); } BingoPgText result_data; result_data.initFromBuffer(bingo_result, res_buf); result = result_data.release(); } PG_BINGO_END if(result == 0) PG_RETURN_NULL(); PG_RETURN_BYTEA_P(result); }
Datum mol_inchikey(PG_FUNCTION_ARGS) { CROMol mol; const char *str; fcinfo->flinfo->fn_extra = SearchMolCache( fcinfo->flinfo->fn_extra, fcinfo->flinfo->fn_mcxt, PG_GETARG_DATUM(0), NULL, &mol, NULL); str = MolInchiKey(mol); char *res=pnstrdup(str, strlen(str)); free((void *)str); PG_RETURN_CSTRING( res ); }
Datum LWGEOM_to_BOX3D(PG_FUNCTION_ARGS) { GSERIALIZED *geom = (GSERIALIZED *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); LWGEOM *lwgeom = lwgeom_from_gserialized(geom); GBOX gbox; BOX3D *result; int rv = lwgeom_calculate_gbox(lwgeom, &gbox); if ( rv == LW_FAILURE ) PG_RETURN_NULL(); result = box3d_from_gbox(&gbox); PG_RETURN_POINTER(result); }
Datum mol_adjust_query_properties(PG_FUNCTION_ARGS) { CROMol mol; fcinfo->flinfo->fn_extra = searchMolCache(fcinfo->flinfo->fn_extra, fcinfo->flinfo->fn_mcxt, PG_GETARG_DATUM(0), NULL, &mol, NULL); Assert(mol != 0); char *data = PG_GETARG_CSTRING(1); CROMol adj = MolAdjustQueryProperties(mol, data); if (!adj) PG_RETURN_NULL(); Mol *res = deconstructROMol(adj); freeCROMol(adj); PG_RETURN_MOL_P(res); }
Datum gserialized_gist_distance_2d(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY*) PG_GETARG_POINTER(0); BOX2DF query_box; BOX2DF *entry_box; StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); double distance; POSTGIS_DEBUG(4, "[GIST] 'distance' function called"); /* We are using '13' as the gist distance-betweeen-centroids strategy number * and '14' as the gist distance-between-boxes strategy number */ if ( strategy != 13 && strategy != 14 ) { elog(ERROR, "unrecognized strategy number: %d", strategy); PG_RETURN_FLOAT8(MAXFLOAT); } /* Null box should never make this far. */ if ( gserialized_datum_get_box2df_p(PG_GETARG_DATUM(1), &query_box) == LW_FAILURE ) { POSTGIS_DEBUG(4, "[GIST] null query_gbox_index!"); PG_RETURN_FLOAT8(MAXFLOAT); } /* Get the entry box */ entry_box = (BOX2DF*)DatumGetPointer(entry->key); /* Box-style distance test */ if ( strategy == 14 ) { distance = (double)box2df_distance(entry_box, &query_box); PG_RETURN_FLOAT8(distance); } /* Treat leaf node tests different from internal nodes */ if (GIST_LEAF(entry)) { /* Calculate distance to leaves */ distance = (double)box2df_distance_leaf_centroid(entry_box, &query_box); } else { /* Calculate distance for internal nodes */ distance = (double)box2df_distance_node_centroid(entry_box, &query_box); } PG_RETURN_FLOAT8(distance); }
Datum adaptive_add_item_agg2(PG_FUNCTION_ARGS) { AdaptiveCounter acounter; /* info for anyelement */ Oid element_type = get_fn_expr_argtype(fcinfo->flinfo, 1); Datum element = PG_GETARG_DATUM(1); int16 typlen; bool typbyval; char typalign; /* is the counter created (if not, create it with default parameters) */ if (PG_ARGISNULL(0)) { acounter = ac_init(DEFAULT_ERROR, DEFAULT_NDISTINCT); } else { acounter = (AdaptiveCounter)PG_GETARG_BYTEA_P(0); } /* add the item to the estimator */ if (! PG_ARGISNULL(1)) { /* TODO The requests for type info shouldn't be a problem (thanks to lsyscache), * but if it turns out to have a noticeable impact it's possible to cache that * between the calls (in the estimator). */ /* get type information for the second parameter (anyelement item) */ get_typlenbyvalalign(element_type, &typlen, &typbyval, &typalign); /* it this a varlena type, passed by reference or by value ? */ if (typlen == -1) { /* varlena */ ac_add_item(acounter, VARDATA(element), VARSIZE(element) - VARHDRSZ); } else if (typbyval) { /* fixed-length, passed by value */ ac_add_item(acounter, (char*)&element, typlen); } else { /* fixed-length, passed by reference */ ac_add_item(acounter, (char*)element, typlen); } } /* return the updated bytea */ PG_RETURN_BYTEA_P(acounter); }
Datum subarray(PG_FUNCTION_ARGS) { ArrayType *a = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0))); ArrayType *result; int32 start = (PG_GETARG_INT32(1) > 0) ? PG_GETARG_INT32(1) - 1 : PG_GETARG_INT32(1); int32 len = (fcinfo->nargs == 3) ? PG_GETARG_INT32(2) : 0; int32 end = 0; int32 c; CHECKARRVALID(a); if (ARRISVOID(a)) { PG_FREE_IF_COPY(a, 0); PG_RETURN_POINTER(new_intArrayType(0)); } c = ARRNELEMS(a); if (start < 0) start = c + start; if (len < 0) end = c + len; else if (len == 0) end = c; else end = start + len; if (end > c) end = c; if (start < 0) start = 0; if (start >= end || end <= 0) { PG_FREE_IF_COPY(a, 0); PG_RETURN_POINTER(new_intArrayType(0)); } result = new_intArrayType(end - start); if (end - start > 0) memcpy(ARRPTR(result), ARRPTR(a) + start, (end - start) * sizeof(int32)); PG_FREE_IF_COPY(a, 0); PG_RETURN_POINTER(result); }
Datum metaphone(PG_FUNCTION_ARGS) { char *str_i = TextDatumGetCString(PG_GETARG_DATUM(0)); size_t str_i_len = strlen(str_i); int reqlen; char *metaph; int retval; /* return an empty string if we receive one */ if (!(str_i_len > 0)) PG_RETURN_TEXT_P(cstring_to_text("")); if (str_i_len > MAX_METAPHONE_STRLEN) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("argument exceeds the maximum length of %d bytes", MAX_METAPHONE_STRLEN))); if (!(str_i_len > 0)) ereport(ERROR, (errcode(ERRCODE_ZERO_LENGTH_CHARACTER_STRING), errmsg("argument is empty string"))); reqlen = PG_GETARG_INT32(1); if (reqlen > MAX_METAPHONE_STRLEN) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("output exceeds the maximum length of %d bytes", MAX_METAPHONE_STRLEN))); if (!(reqlen > 0)) ereport(ERROR, (errcode(ERRCODE_ZERO_LENGTH_CHARACTER_STRING), errmsg("output cannot be empty string"))); retval = _metaphone(str_i, reqlen, &metaph); if (retval == META_SUCCESS) PG_RETURN_TEXT_P(cstring_to_text(metaph)); else { /* internal error */ elog(ERROR, "metaphone: failure"); /* keep the compiler quiet */ PG_RETURN_NULL(); } }
/** * @brief Return the n-th element from a composite value * * To the user, AnyType is a fully recursive type: Each AnyType object can be a * composite object and be composed of a number of other AnyType objects. * On top of the C++ abstraction layer, function have a single-top level * AnyType object as parameter. */ inline AbstractionLayer::AnyType AbstractionLayer::AnyType::operator[](uint16_t inID) const { consistencyCheck(); if (isNull()) throw std::invalid_argument("Unexpected Null value in function " "argument."); if (!isComposite()) throw std::invalid_argument("Invalid type conversion requested. " "Expected composite type but got simple type."); if (mContent == ReturnComposite) return mChildren[inID]; Oid typeID = 0; bool isMutable = false; Datum datum = 0; bool isTuple = false; HeapTupleHeader pgTuple = NULL; try { if (mContent == FunctionComposite) { if (inID >= size_t(PG_NARGS())) throw std::out_of_range("Access behind end of argument list"); if (PG_ARGISNULL(inID)) return AnyType(); backendGetTypeIDForFunctionArg(inID, typeID, isMutable); datum = PG_GETARG_DATUM(inID); } else if (mContent == NativeComposite) backendGetTypeIDAndDatumForTupleElement(inID, typeID, datum); if (typeID == InvalidOid) throw std::invalid_argument("Backend returned invalid type ID."); backendGetIsCompositeTypeAndHeapTupleHeader(typeID, datum, isTuple, pgTuple); } catch (PGException &e) { throw std::invalid_argument("An exception occurred while " "gathering information about PostgreSQL function arguments."); } return isTuple ? AnyType(pgTuple, datum, typeID) : AnyType(datum, typeID, isMutable); }
Datum pointcloud_agg_transfn(PG_FUNCTION_ARGS) { Oid arg1_typeid = get_fn_expr_argtype(fcinfo->flinfo, 1); MemoryContext aggcontext; abs_trans *a; ArrayBuildState *state; Datum elem; if (arg1_typeid == InvalidOid) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("could not determine input data type"))); if (fcinfo->context && IsA(fcinfo->context, AggState)) { aggcontext = ((AggState *) fcinfo->context)->aggcontext; } else if (fcinfo->context && IsA(fcinfo->context, WindowAggState)) { aggcontext = ((WindowAggState *) fcinfo->context)->aggcontext; } else { /* cannot be called directly because of dummy-type argument */ elog(ERROR, "pointcloud_agg_transfn called in non-aggregate context"); aggcontext = NULL; /* keep compiler quiet */ } if ( PG_ARGISNULL(0) ) { a = (abs_trans*) palloc(sizeof(abs_trans)); a->s = NULL; } else { a = (abs_trans*) PG_GETARG_POINTER(0); } state = a->s; elem = PG_ARGISNULL(1) ? (Datum) 0 : PG_GETARG_DATUM(1); state = accumArrayResult(state, elem, PG_ARGISNULL(1), arg1_typeid, aggcontext); a->s = state; PG_RETURN_POINTER(a); }
Datum plsh_inline_handler(PG_FUNCTION_ARGS) { InlineCodeBlock *codeblock = (InlineCodeBlock *) DatumGetPointer(PG_GETARG_DATUM(0)); int argc; char * arguments[FUNC_MAX_ARGS + 2]; const char *rest; char *tempfile; parse_shell_and_arguments(codeblock->source_text, &argc, arguments, &rest); tempfile = write_to_tempfile(rest); arguments[argc++] = tempfile; arguments[argc] = NULL; handler_internal2(tempfile, arguments, "inline code block", NULL, NULL); PG_RETURN_VOID(); }
Datum ts_rank_wttf(PG_FUNCTION_ARGS) { ArrayType *win = (ArrayType *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); TSVector txt = PG_GETARG_TSVECTOR(1); TSQuery query = PG_GETARG_TSQUERY(2); int method = PG_GETARG_INT32(3); float res; res = calc_rank(getWeights(win), txt, query, method); PG_FREE_IF_COPY(win, 0); PG_FREE_IF_COPY(txt, 1); PG_FREE_IF_COPY(query, 2); PG_RETURN_FLOAT4(res); }
Datum mol_formula(PG_FUNCTION_ARGS) { CROMol mol; char *str; int len; bool separateIsotopes = PG_GETARG_BOOL(1); bool abbreviateHIsotopes = PG_GETARG_BOOL(2); fcinfo->flinfo->fn_extra = searchMolCache(fcinfo->flinfo->fn_extra, fcinfo->flinfo->fn_mcxt, PG_GETARG_DATUM(0), NULL, &mol, NULL); str = makeMolFormulaText(mol, &len, separateIsotopes, abbreviateHIsotopes); PG_RETURN_CSTRING(pnstrdup(str, len)); }
Datum LWGEOM_numpoints_linestring(PG_FUNCTION_ARGS) { PG_LWGEOM *geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); int32 ret; POSTGIS_DEBUG(2, "LWGEOM_numpoints_linestring called."); ret = lwgeom_numpoints_linestring_recursive(SERIALIZED_FORM(geom)); if ( ret == -1 ) { PG_FREE_IF_COPY(geom, 0); PG_RETURN_NULL(); } PG_FREE_IF_COPY(geom, 0); PG_RETURN_INT32(ret); }
Datum geography_from_geometry(PG_FUNCTION_ARGS) { GSERIALIZED *geom = (GSERIALIZED*)PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)); LWGEOM *lwgeom = NULL; GSERIALIZED *g_ser = NULL; geography_valid_type(gserialized_get_type(geom)); lwgeom = lwgeom_from_gserialized(geom); /* Force default SRID */ if ( (int)lwgeom->srid <= 0 ) { lwgeom->srid = SRID_DEFAULT; } /* Error on any SRID != default */ srid_is_latlong(fcinfo, lwgeom->srid); /* Force the geometry to have valid geodetic coordinate range. */ lwgeom_nudge_geodetic(lwgeom); if ( lwgeom_force_geodetic(lwgeom) == LW_TRUE ) { ereport(NOTICE, ( errmsg_internal("Coordinate values were coerced into range [-180 -90, 180 90] for GEOGRAPHY" )) ); } /* ** Serialize our lwgeom and set the geodetic flag so subsequent ** functions do the right thing. */ lwgeom_set_geodetic(lwgeom, true); /* Recalculate the boxes after re-setting the geodetic bit */ lwgeom_drop_bbox(lwgeom); lwgeom_add_bbox(lwgeom); g_ser = geography_serialize(lwgeom); /* ** Replace the unaligned lwgeom with a new aligned one based on GSERIALIZED. */ lwgeom_free(lwgeom); PG_FREE_IF_COPY(geom, 0); PG_RETURN_POINTER(g_ser); }
Datum probabilistic_add_item_agg2(PG_FUNCTION_ARGS) { ProbabilisticCounter pcounter; /* info for anyelement */ Oid element_type = get_fn_expr_argtype(fcinfo->flinfo, 1); Datum element = PG_GETARG_DATUM(1); int16 typlen; bool typbyval; char typalign; /* create a new estimator (with requested error rate) or reuse the existing one */ if (PG_ARGISNULL(0)) { pcounter = pc_create(DEFAULT_NBYTES, DEFAULT_NSALTS); } else { /* existing estimator */ pcounter = (ProbabilisticCounter)PG_GETARG_BYTEA_P(0); } /* add the item to the estimator (skip NULLs) */ if (! PG_ARGISNULL(1)) { /* TODO The requests for type info shouldn't be a problem (thanks to lsyscache), * but if it turns out to have a noticeable impact it's possible to cache that * between the calls (in the estimator). */ /* get type information for the second parameter (anyelement item) */ get_typlenbyvalalign(element_type, &typlen, &typbyval, &typalign); /* it this a varlena type, passed by reference or by value ? */ if (typlen == -1) { /* varlena */ pc_add_element(pcounter, VARDATA(element), VARSIZE(element) - VARHDRSZ); } else if (typbyval) { /* fixed-length, passed by value */ pc_add_element(pcounter, (char*)&element, typlen); } else { /* fixed-length, passed by reference */ pc_add_element(pcounter, (char*)element, typlen); } } /* return the updated bytea */ PG_RETURN_BYTEA_P(pcounter); }
Datum hll_add(PG_FUNCTION_ARGS) { HyperLogLog *hll = (HyperLogLog *) PG_GETARG_VARLENA_P(0); /* Sparse representation can be repalloc'd so create a copy */ if (HLL_IS_SPARSE(hll)) { HyperLogLog *cpy = palloc(HLLSize(hll)); memcpy(cpy, hll, HLLSize(hll)); hll = cpy; } fcinfo->flinfo->fn_extra = lookup_type_cache(get_fn_expr_argtype(fcinfo->flinfo, 1), 0); hll = hll_add_datum(fcinfo, hll, PG_GETARG_DATUM(1)); PG_RETURN_POINTER(hll); }
/* * mongo_fdw_validator validates options given to one of the following commands: * foreign data wrapper, server, user mapping, or foreign table. This function * errors out if the given option name or its value is considered invalid. */ Datum mongo_fdw_validator(PG_FUNCTION_ARGS) { Datum optionArray = PG_GETARG_DATUM(0); Oid optionContextId = PG_GETARG_OID(1); List *optionList = untransformRelOptions(optionArray); ListCell *optionCell = NULL; foreach(optionCell, optionList) { DefElem *optionDef = (DefElem *) lfirst(optionCell); char *optionName = optionDef->defname; bool optionValid = false; int32 optionIndex = 0; for (optionIndex = 0; optionIndex < ValidOptionCount; optionIndex++) { const MongoValidOption *validOption = &(ValidOptionArray[optionIndex]); if ((optionContextId == validOption->optionContextId) && (strncmp(optionName, validOption->optionName, NAMEDATALEN) == 0)) { optionValid = true; break; } } /* if invalid option, display an informative error message */ if (!optionValid) { StringInfo optionNamesString = OptionNamesString(optionContextId); ereport(ERROR, (errcode(ERRCODE_FDW_INVALID_OPTION_NAME), errmsg("invalid option \"%s\"", optionName), errhint("Valid options in this context are: %s", optionNamesString->data))); } /* if port option is given, error out if its value isn't an integer */ if (strncmp(optionName, OPTION_NAME_PORT, NAMEDATALEN) == 0) { char *optionValue = defGetString(optionDef); int32 portNumber = pg_atoi(optionValue, sizeof(int32), 0); (void) portNumber; } }
Datum probabilistic_add_item(PG_FUNCTION_ARGS) { ProbabilisticCounter pcounter; /* requires the estimator to be already created */ if (PG_ARGISNULL(0)) elog(ERROR, "probabilistic counter must not be NULL"); /* if the element is not NULL, add it to the estimator (i.e. skip NULLs) */ if (! PG_ARGISNULL(1)) { Oid element_type = get_fn_expr_argtype(fcinfo->flinfo, 1); Datum element = PG_GETARG_DATUM(1); int16 typlen; bool typbyval; char typalign; /* estimator (we know it's not a NULL value) */ pcounter = (ProbabilisticCounter)PG_GETARG_BYTEA_P(0); /* TODO The requests for type info shouldn't be a problem (thanks to lsyscache), * but if it turns out to have a noticeable impact it's possible to cache that * between the calls (in the estimator). */ /* get type information for the second parameter (anyelement item) */ get_typlenbyvalalign(element_type, &typlen, &typbyval, &typalign); /* it this a varlena type, passed by reference or by value ? */ if (typlen == -1) { /* varlena */ pc_add_element(pcounter, VARDATA(element), VARSIZE(element) - VARHDRSZ); } else if (typbyval) { /* fixed-length, passed by value */ pc_add_element(pcounter, (char*)&element, typlen); } else { /* fixed-length, passed by reference */ pc_add_element(pcounter, (char*)element, typlen); } } PG_RETURN_VOID(); }
/* * For BTGreaterEqualStrategyNumber, BTGreaterStrategyNumber, and * BTEqualStrategyNumber we want to start the index scan at the * supplied query datum, and work forward. For BTLessStrategyNumber * and BTLessEqualStrategyNumber, we need to start at the leftmost * key, and work forward until the supplied query datum (which must be * sent along inside the QueryInfo structure). */ static Datum gin_btree_extract_query(FunctionCallInfo fcinfo, bool is_varlena, Datum (*leftmostvalue) (void), Datum (*typecmp) (FunctionCallInfo)) { Datum datum = PG_GETARG_DATUM(0); int32 *nentries = (int32 *) PG_GETARG_POINTER(1); StrategyNumber strategy = PG_GETARG_UINT16(2); bool **partialmatch = (bool **) PG_GETARG_POINTER(3); Pointer **extra_data = (Pointer **) PG_GETARG_POINTER(4); Datum *entries = (Datum *) palloc(sizeof(Datum)); QueryInfo *data = (QueryInfo *) palloc(sizeof(QueryInfo)); bool *ptr_partialmatch; *nentries = 1; ptr_partialmatch = *partialmatch = (bool *) palloc(sizeof(bool)); *ptr_partialmatch = false; if (is_varlena) datum = PointerGetDatum(PG_DETOAST_DATUM(datum)); data->strategy = strategy; data->datum = datum; data->is_varlena = is_varlena; data->typecmp = typecmp; *extra_data = (Pointer *) palloc(sizeof(Pointer)); **extra_data = (Pointer) data; switch (strategy) { case BTLessStrategyNumber: case BTLessEqualStrategyNumber: entries[0] = leftmostvalue(); *ptr_partialmatch = true; break; case BTGreaterEqualStrategyNumber: case BTGreaterStrategyNumber: *ptr_partialmatch = true; case BTEqualStrategyNumber: entries[0] = datum; break; default: elog(ERROR, "unrecognized strategy number: %d", strategy); } PG_RETURN_POINTER(entries); }