示例#1
0
Datum get_semester(PG_FUNCTION_ARGS) {
  pg_tm current_date;
  GetCurrentDateTime(&current_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);
}
示例#2
0
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();
}
示例#3
0
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);
}
示例#5
0
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);
}
示例#7
0
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);
}
示例#8
0
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);
}
示例#9
0
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();
}
示例#10
0
文件: mol_op.c 项目: Acpharis/rdkit
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);           
}
示例#11
0
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);
}
示例#12
0
文件: mol_op.c 项目: Acpharis/rdkit
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 );
}
示例#13
0
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);
}
示例#14
0
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);
}
示例#15
0
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);

}
示例#17
0
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);
}
示例#18
0
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();
	}
}
示例#19
0
/**
 * @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);
}
示例#20
0
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);
}
示例#21
0
文件: plsh.c 项目: amutu/plsh
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();
}
示例#22
0
文件: tsrank.c 项目: amulsul/postgres
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);
}
示例#23
0
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));
}
示例#24
0
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);
}
示例#25
0
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);
    
}
示例#27
0
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);
}
示例#28
0
/*
 * 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();
    
}
示例#30
0
/*
 * 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);
}