• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

C++ PG_GETARG_POINTER函数代码示例

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

本文整理汇总了C++中PG_GETARG_POINTER函数的典型用法代码示例。如果您正苦于以下问题:C++ PG_GETARG_POINTER函数的具体用法?C++ PG_GETARG_POINTER怎么用?C++ PG_GETARG_POINTER使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。



在下文中一共展示了PG_GETARG_POINTER函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。

示例1: gistbuild

/*
 * Main entry point to GiST index build. Initially calls insert over and over,
 * but switches to more efficient buffering build algorithm after a certain
 * number of tuples (unless buffering mode is disabled).
 */
Datum
gistbuild(PG_FUNCTION_ARGS)
{
	Relation	heap = (Relation) PG_GETARG_POINTER(0);
	Relation	index = (Relation) PG_GETARG_POINTER(1);
	IndexInfo  *indexInfo = (IndexInfo *) PG_GETARG_POINTER(2);
	IndexBuildResult *result;
	double		reltuples;
	GISTBuildState buildstate;
	Buffer		buffer;
	Page		page;
	MemoryContext oldcxt = CurrentMemoryContext;
	int			fillfactor;

	buildstate.indexrel = index;
	if (index->rd_options)
	{
		/* Get buffering mode from the options string */
		GiSTOptions *options = (GiSTOptions *) index->rd_options;
		char	   *bufferingMode = (char *) options + options->bufferingModeOffset;

		if (strcmp(bufferingMode, "on") == 0)
			buildstate.bufferingMode = GIST_BUFFERING_STATS;
		else if (strcmp(bufferingMode, "off") == 0)
			buildstate.bufferingMode = GIST_BUFFERING_DISABLED;
		else
			buildstate.bufferingMode = GIST_BUFFERING_AUTO;

		fillfactor = options->fillfactor;
	}
	else
	{
		/*
		 * By default, switch to buffering mode when the index grows too large
		 * to fit in cache.
		 */
		buildstate.bufferingMode = GIST_BUFFERING_AUTO;
		fillfactor = GIST_DEFAULT_FILLFACTOR;
	}
	/* Calculate target amount of free space to leave on pages */
	buildstate.freespace = BLCKSZ * (100 - fillfactor) / 100;

	/*
	 * We expect to be called exactly once for any index relation. If that's
	 * not the case, big trouble's what we have.
	 */
	if (RelationGetNumberOfBlocks(index) != 0)
		elog(ERROR, "index \"%s\" already contains data",
			 RelationGetRelationName(index));

	/* no locking is needed */
	buildstate.giststate = initGISTstate(index);

	/*
	 * Create a temporary memory context that is reset once for each tuple
	 * processed.  (Note: we don't bother to make this a child of the
	 * giststate's scanCxt, so we have to delete it separately at the end.)
	 */
	buildstate.giststate->tempCxt = createTempGistContext();

	/* initialize the root page */
	buffer = gistNewBuffer(index);
	Assert(BufferGetBlockNumber(buffer) == GIST_ROOT_BLKNO);
	page = BufferGetPage(buffer);

	START_CRIT_SECTION();

	GISTInitBuffer(buffer, F_LEAF);

	MarkBufferDirty(buffer);

	if (RelationNeedsWAL(index))
	{
		XLogRecPtr	recptr;
		XLogRecData rdata;

		rdata.data = (char *) &(index->rd_node);
		rdata.len = sizeof(RelFileNode);
		rdata.buffer = InvalidBuffer;
		rdata.next = NULL;

		recptr = XLogInsert(RM_GIST_ID, XLOG_GIST_CREATE_INDEX, &rdata);
		PageSetLSN(page, recptr);
	}
	else
		PageSetLSN(page, gistGetFakeLSN(heap));

	UnlockReleaseBuffer(buffer);

	END_CRIT_SECTION();

	/* build the index */
	buildstate.indtuples = 0;
	buildstate.indtuplesSize = 0;

//.........这里部分代码省略.........
开发者ID:amulsul,项目名称:postgres,代码行数:101,代码来源:gistbuild.c


示例2: g_int_compress

/*
** GiST Compress and Decompress methods
*/
Datum
g_int_compress(PG_FUNCTION_ARGS)
{
    GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
    GISTENTRY  *retval;
    ArrayType  *r;
    int			len;
    int		   *dr;
    int			i,
                min,
                cand;

    if (entry->leafkey)
    {
        r = (ArrayType *) PG_DETOAST_DATUM_COPY(entry->key);
        PREPAREARR(r);
        r->flags |= LEAFKEY;
        retval = palloc(sizeof(GISTENTRY));
        gistentryinit(*retval, PointerGetDatum(r),
                      entry->rel, entry->page, entry->offset, VARSIZE(r), FALSE);

        PG_RETURN_POINTER(retval);
    }

    r = (ArrayType *) PG_DETOAST_DATUM(entry->key);
    if (ISLEAFKEY(r) || ARRISVOID(r))
    {
        if (r != (ArrayType *) DatumGetPointer(entry->key))
            pfree(r);
        PG_RETURN_POINTER(entry);
    }

    if ((len = ARRNELEMS(r)) >= 2 * MAXNUMRANGE)
    {   /* compress */
        if (r == (ArrayType *) DatumGetPointer(entry->key))
            r = (ArrayType *) PG_DETOAST_DATUM_COPY(entry->key);
        r = resize_intArrayType(r, 2 * (len));

        dr = ARRPTR(r);

        for (i = len - 1; i >= 0; i--)
            dr[2 * i] = dr[2 * i + 1] = dr[i];

        len *= 2;
        cand = 1;
        while (len > MAXNUMRANGE * 2)
        {
            min = 0x7fffffff;
            for (i = 2; i < len; i += 2)
                if (min > (dr[i] - dr[i - 1]))
                {
                    min = (dr[i] - dr[i - 1]);
                    cand = i;
                }
            memmove((void *) &dr[cand - 1], (void *) &dr[cand + 1], (len - cand - 1) * sizeof(int));
            len -= 2;
        }
        r = resize_intArrayType(r, len);
        retval = palloc(sizeof(GISTENTRY));
        gistentryinit(*retval, PointerGetDatum(r),
                      entry->rel, entry->page, entry->offset, VARSIZE(r), FALSE);
        PG_RETURN_POINTER(retval);
    }
    else
        PG_RETURN_POINTER(entry);

    PG_RETURN_POINTER(entry);
}
开发者ID:shubham2094,项目名称:postgresql_8.1,代码行数:71,代码来源:_int_gist.c


示例3: ltxtq_in

/*
 * in without morphology
 */
Datum
ltxtq_in(PG_FUNCTION_ARGS)
{
	PG_RETURN_POINTER(queryin((char *) PG_GETARG_POINTER(0)));
}
开发者ID:ASchurman,项目名称:BufStrat,代码行数:8,代码来源:ltxtquery_io.c


示例4: record_recv

/*
 * record_recv		- binary input routine for any composite type.
 */
Datum
record_recv(PG_FUNCTION_ARGS)
{
	StringInfo	buf = (StringInfo) PG_GETARG_POINTER(0);
	Oid			tupType = PG_GETARG_OID(1);

#ifdef NOT_USED
	int32		typmod = PG_GETARG_INT32(2);
#endif
	HeapTupleHeader result;
	int32		tupTypmod;
	TupleDesc	tupdesc;
	HeapTuple	tuple;
	RecordIOData *my_extra;
	int			ncolumns;
	int			usercols;
	int			validcols;
	int			i;
	Datum	   *values;
	bool	   *nulls;

	/*
	 * Use the passed type unless it's RECORD; we can't support input of
	 * anonymous types, mainly because there's no good way to figure out which
	 * anonymous type is wanted.  Note that for RECORD, what we'll probably
	 * actually get is RECORD's typelem, ie, zero.
	 */
	if (tupType == InvalidOid || tupType == RECORDOID)
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
		   errmsg("input of anonymous composite types is not implemented")));
	tupTypmod = -1;				/* for all non-anonymous types */
	tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
	ncolumns = tupdesc->natts;

	/*
	 * We arrange to look up the needed I/O info just once per series of
	 * calls, assuming the record type doesn't change underneath us.
	 */
	my_extra = (RecordIOData *) fcinfo->flinfo->fn_extra;
	if (my_extra == NULL ||
		my_extra->ncolumns != ncolumns)
	{
		fcinfo->flinfo->fn_extra =
			MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
							   sizeof(RecordIOData) - sizeof(ColumnIOData)
							   + ncolumns * sizeof(ColumnIOData));
		my_extra = (RecordIOData *) fcinfo->flinfo->fn_extra;
		my_extra->record_type = InvalidOid;
		my_extra->record_typmod = 0;
	}

	if (my_extra->record_type != tupType ||
		my_extra->record_typmod != tupTypmod)
	{
		MemSet(my_extra, 0,
			   sizeof(RecordIOData) - sizeof(ColumnIOData)
			   + ncolumns * sizeof(ColumnIOData));
		my_extra->record_type = tupType;
		my_extra->record_typmod = tupTypmod;
		my_extra->ncolumns = ncolumns;
	}

	values = (Datum *) palloc(ncolumns * sizeof(Datum));
	nulls = (bool *) palloc(ncolumns * sizeof(bool));

	/* Fetch number of columns user thinks it has */
	usercols = pq_getmsgint(buf, 4);

	/* Need to scan to count nondeleted columns */
	validcols = 0;
	for (i = 0; i < ncolumns; i++)
	{
		if (!tupdesc->attrs[i]->attisdropped)
			validcols++;
	}
	if (usercols != validcols)
		ereport(ERROR,
				(errcode(ERRCODE_DATATYPE_MISMATCH),
				 errmsg("wrong number of columns: %d, expected %d",
						usercols, validcols)));

	/* Process each column */
	for (i = 0; i < ncolumns; i++)
	{
		ColumnIOData *column_info = &my_extra->columns[i];
		Oid			column_type = tupdesc->attrs[i]->atttypid;
		Oid			coltypoid;
		int			itemlen;
		StringInfoData item_buf;
		StringInfo	bufptr;
		char		csave;

		/* Ignore dropped columns in datatype, but fill with nulls */
		if (tupdesc->attrs[i]->attisdropped)
		{
			values[i] = (Datum) 0;
//.........这里部分代码省略.........
开发者ID:AnLingm,项目名称:gpdb,代码行数:101,代码来源:rowtypes.c


示例5: ghstore_compress

Datum
ghstore_compress(PG_FUNCTION_ARGS)
{
	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
	GISTENTRY  *retval = entry;

	if (entry->leafkey)
	{
		GISTTYPE   *res = (GISTTYPE *) palloc0(CALCGTSIZE(0));
		HStore	   *toastedval = (HStore *) DatumGetPointer(entry->key);
		HStore	   *val = (HStore *) DatumGetPointer(PG_DETOAST_DATUM(entry->key));
		HEntry	   *ptr = ARRPTR(val);
		char	   *words = STRPTR(val);

		SET_VARSIZE(res, CALCGTSIZE(0));

		while (ptr - ARRPTR(val) < val->size)
		{
			int			h;

			h = crc32_sz((char *) (words + ptr->pos), ptr->keylen);
			HASH(GETSIGN(res), h);
			if (!ptr->valisnull)
			{
				h = crc32_sz((char *) (words + ptr->pos + ptr->keylen), ptr->vallen);
				HASH(GETSIGN(res), h);
			}
			ptr++;
		}

		if (val != toastedval)
			pfree(val);

		retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
		gistentryinit(*retval, PointerGetDatum(res),
					  entry->rel, entry->page,
					  entry->offset,
					  FALSE);
	}
	else if (!ISALLTRUE(DatumGetPointer(entry->key)))
	{
		int4		i;
		GISTTYPE   *res;
		BITVECP		sign = GETSIGN(DatumGetPointer(entry->key));

		LOOPBYTE
		{
			if ((sign[i] & 0xff) != 0xff)
				PG_RETURN_POINTER(retval);
		}

		res = (GISTTYPE *) palloc(CALCGTSIZE(ALLISTRUE));
		SET_VARSIZE(res, CALCGTSIZE(ALLISTRUE));
		res->flag = ALLISTRUE;

		retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
		gistentryinit(*retval, PointerGetDatum(res),
					  entry->rel, entry->page,
					  entry->offset,
					  FALSE);
	}
开发者ID:AnLingm,项目名称:gpdb,代码行数:61,代码来源:hstore_gist.c


示例6: gistgettuple

/*
 * gistgettuple() -- Get the next tuple in the scan
 */
Datum
gistgettuple(PG_FUNCTION_ARGS)
{
	IndexScanDesc scan = (IndexScanDesc) PG_GETARG_POINTER(0);
	ScanDirection dir = (ScanDirection) PG_GETARG_INT32(1);
	GISTScanOpaque so = (GISTScanOpaque) scan->opaque;

	if (dir != ForwardScanDirection)
		elog(ERROR, "GiST only supports forward scan direction");

	if (!so->qual_ok)
		PG_RETURN_BOOL(false);

	if (so->firstCall)
	{
		/* Begin the scan by processing the root page */
		GISTSearchItem fakeItem;

		pgstat_count_index_scan(scan->indexRelation);

		so->firstCall = false;
		so->curTreeItem = NULL;
		so->curPageData = so->nPageData = 0;

		fakeItem.blkno = GIST_ROOT_BLKNO;
		memset(&fakeItem.data.parentlsn, 0, sizeof(GistNSN));
		gistScanPage(scan, &fakeItem, NULL, NULL, NULL);
	}

	if (scan->numberOfOrderBys > 0)
	{
		/* Must fetch tuples in strict distance order */
		PG_RETURN_BOOL(getNextNearest(scan));
	}
	else
	{
		/* Fetch tuples index-page-at-a-time */
		for (;;)
		{
			if (so->curPageData < so->nPageData)
			{
				/* continuing to return tuples from a leaf page */
				scan->xs_ctup.t_self = so->pageData[so->curPageData].heapPtr;
				scan->xs_recheck = so->pageData[so->curPageData].recheck;
				so->curPageData++;
				PG_RETURN_BOOL(true);
			}

			/* find and process the next index page */
			do
			{
				GISTSearchItem *item = getNextGISTSearchItem(so);

				if (!item)
					PG_RETURN_BOOL(false);

				CHECK_FOR_INTERRUPTS();

				/*
				 * While scanning a leaf page, ItemPointers of matching heap
				 * tuples are stored in so->pageData.  If there are any on
				 * this page, we fall out of the inner "do" and loop around to
				 * return them.
				 */
				gistScanPage(scan, item, so->curTreeItem->distances, NULL, NULL);

				pfree(item);
			} while (so->nPageData == 0);
		}
	}

	PG_RETURN_BOOL(false);		/* keep compiler quiet */
}
开发者ID:a1exsh,项目名称:postgres,代码行数:76,代码来源:gistget.c


示例7: spheretrans_out

Datum
spheretrans_out(PG_FUNCTION_ARGS)
{
	SEuler	   *se = (SEuler *) PG_GETARG_POINTER(0);
	char	   *buffer = (char *) palloc(255);
	char		buf[100];
	char		etype[4];
	SPoint		val[3];
	unsigned char i,
				t = 0;
	unsigned int rdeg,
				rmin;
	double		rsec;

	val[0].lat = val[1].lat = val[2].lat = 0.0;
	val[0].lng = se->phi;
	val[1].lng = se->theta;
	val[2].lng = se->psi;

	spoint_check(&val[0]);
	spoint_check(&val[1]);
	spoint_check(&val[2]);

	buffer[0] = '\0';
	for (i = 0; i < 3; i++)
	{

		rdeg = rmin = 0;
		rsec = 0.0;
		switch (sphere_output)
		{

			case OUTPUT_DEG:
				sprintf(&buf[0],
						"%.*gd",
						sphere_output_precision, RADIANS * val[i].lng);
				break;

			case OUTPUT_HMS:
			case OUTPUT_DMS:
				rad_to_dms(val[i].lng, &rdeg, &rmin, &rsec);
				sprintf(&buf[0],
						"%2ud %2um %.*gs",
						rdeg, rmin, sphere_output_precision, rsec);
				break;

			default:
				sprintf(&buf[0], "%.*g", sphere_output_precision, val[i].lng);
				break;
		}
		strcat(&buf[0], ", ");
		strcat(buffer, &buf[0]);
	}
	for (i = 0; i < 3; i++)
	{
		switch (i)
		{
			case 0:
				t = se->phi_a;
				break;
			case 1:
				t = se->theta_a;
				break;
			case 2:
				t = se->psi_a;
				break;
		}
		switch (t)
		{
			case EULER_AXIS_X:
				etype[i] = 'X';
				break;
			case EULER_AXIS_Y:
				etype[i] = 'Y';
				break;
			case EULER_AXIS_Z:
				etype[i] = 'Z';
				break;
		}
	}
	etype[3] = '\0';
	strcat(buffer, etype);

	PG_RETURN_CSTRING(buffer);
}
开发者ID:yuejiesong1900,项目名称:pgsphere,代码行数:85,代码来源:output.c


示例8: g_intbig_compress

Datum
g_intbig_compress(PG_FUNCTION_ARGS)
{
	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);

	if (entry->leafkey)
	{
		GISTENTRY  *retval;
		ArrayType  *in = DatumGetArrayTypeP(entry->key);
		int4	   *ptr;
		int			num;
		GISTTYPE   *res = (GISTTYPE *) palloc0(CALCGTSIZE(0));

		CHECKARRVALID(in);
		if (ARRISEMPTY(in))
		{
			ptr = NULL;
			num = 0;
		}
		else
		{
			ptr = ARRPTR(in);
			num = ARRNELEMS(in);
		}
		SET_VARSIZE(res, CALCGTSIZE(0));

		while (num--)
		{
			HASH(GETSIGN(res), *ptr);
			ptr++;
		}

		retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
		gistentryinit(*retval, PointerGetDatum(res),
					  entry->rel, entry->page,
					  entry->offset, FALSE);

		if (in != DatumGetArrayTypeP(entry->key))
			pfree(in);

		PG_RETURN_POINTER(retval);
	}
	else if (!ISALLTRUE(DatumGetPointer(entry->key)))
	{
		GISTENTRY  *retval;
		int			i;
		BITVECP		sign = GETSIGN(DatumGetPointer(entry->key));
		GISTTYPE   *res;

		LOOPBYTE
		{
			if ((sign[i] & 0xff) != 0xff)
				PG_RETURN_POINTER(entry);
		}

		res = (GISTTYPE *) palloc(CALCGTSIZE(ALLISTRUE));
		SET_VARSIZE(res, CALCGTSIZE(ALLISTRUE));
		res->flag = ALLISTRUE;

		retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
		gistentryinit(*retval, PointerGetDatum(res),
					  entry->rel, entry->page,
					  entry->offset, FALSE);

		PG_RETURN_POINTER(retval);
	}
开发者ID:ASchurman,项目名称:BufStrat,代码行数:66,代码来源:_intbig_gist.c


示例9: extract_variadic_args

/*
 * extract_variadic_args
 *
 * Extract a set of argument values, types and NULL markers for a given
 * input function which makes use of a VARIADIC input whose argument list
 * depends on the caller context. When doing a VARIADIC call, the caller
 * has provided one argument made of an array of values, so deconstruct the
 * array data before using it for the next processing. If no VARIADIC call
 * is used, just fill in the status data based on all the arguments given
 * by the caller.
 *
 * This function returns the number of arguments generated, or -1 in the
 * case of "VARIADIC NULL".
 */
int
extract_variadic_args(FunctionCallInfo fcinfo, int variadic_start,
					  bool convert_unknown, Datum **args, Oid **types,
					  bool **nulls)
{
	bool		variadic = get_fn_expr_variadic(fcinfo->flinfo);
	Datum	   *args_res;
	bool	   *nulls_res;
	Oid		   *types_res;
	int			nargs,
				i;

	*args = NULL;
	*types = NULL;
	*nulls = NULL;

	if (variadic)
	{
		ArrayType  *array_in;
		Oid			element_type;
		bool		typbyval;
		char		typalign;
		int16		typlen;

		Assert(PG_NARGS() == variadic_start + 1);

		if (PG_ARGISNULL(variadic_start))
			return -1;

		array_in = PG_GETARG_ARRAYTYPE_P(variadic_start);
		element_type = ARR_ELEMTYPE(array_in);

		get_typlenbyvalalign(element_type,
							 &typlen, &typbyval, &typalign);
		deconstruct_array(array_in, element_type, typlen, typbyval,
						  typalign, &args_res, &nulls_res,
						  &nargs);

		/* All the elements of the array have the same type */
		types_res = (Oid *) palloc0(nargs * sizeof(Oid));
		for (i = 0; i < nargs; i++)
			types_res[i] = element_type;
	}
	else
	{
		nargs = PG_NARGS() - variadic_start;
		Assert(nargs > 0);
		nulls_res = (bool *) palloc0(nargs * sizeof(bool));
		args_res = (Datum *) palloc0(nargs * sizeof(Datum));
		types_res = (Oid *) palloc0(nargs * sizeof(Oid));

		for (i = 0; i < nargs; i++)
		{
			nulls_res[i] = PG_ARGISNULL(i + variadic_start);
			types_res[i] = get_fn_expr_argtype(fcinfo->flinfo,
											   i + variadic_start);

			/*
			 * Turn a constant (more or less literal) value that's of unknown
			 * type into text if required. Unknowns come in as a cstring
			 * pointer. Note: for functions declared as taking type "any", the
			 * parser will not do any type conversion on unknown-type literals
			 * (that is, undecorated strings or NULLs).
			 */
			if (convert_unknown &&
				types_res[i] == UNKNOWNOID &&
				get_fn_expr_arg_stable(fcinfo->flinfo, i + variadic_start))
			{
				types_res[i] = TEXTOID;

				if (PG_ARGISNULL(i + variadic_start))
					args_res[i] = (Datum) 0;
				else
					args_res[i] =
						CStringGetTextDatum(PG_GETARG_POINTER(i + variadic_start));
			}
			else
			{
				/* no conversion needed, just take the datum as given */
				args_res[i] = PG_GETARG_DATUM(i + variadic_start);
			}

			if (!OidIsValid(types_res[i]) ||
				(convert_unknown && types_res[i] == UNKNOWNOID))
				ereport(ERROR,
						(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
//.........这里部分代码省略.........
开发者ID:maksm90,项目名称:postgresql,代码行数:101,代码来源:funcapi.c


示例10: jsonb_object_agg_transfn

/*
 * jsonb_object_agg aggregate function
 */
Datum
jsonb_object_agg_transfn(PG_FUNCTION_ARGS)
{
	MemoryContext oldcontext,
				aggcontext;
	JsonbInState elem;
	JsonbAggState *state;
	Datum		val;
	JsonbInState *result;
	bool		single_scalar;
	JsonbIterator *it;
	Jsonb	   *jbkey,
			   *jbval;
	JsonbValue	v;
	JsonbIteratorToken type;

	if (!AggCheckCallContext(fcinfo, &aggcontext))
	{
		/* cannot be called directly because of internal-type argument */
		elog(ERROR, "jsonb_object_agg_transfn called in non-aggregate context");
	}

	/* set up the accumulator on the first go round */

	if (PG_ARGISNULL(0))
	{
		Oid			arg_type;

		oldcontext = MemoryContextSwitchTo(aggcontext);
		state = palloc(sizeof(JsonbAggState));
		result = palloc0(sizeof(JsonbInState));
		state->res = result;
		result->res = pushJsonbValue(&result->parseState,
									 WJB_BEGIN_OBJECT, NULL);
		MemoryContextSwitchTo(oldcontext);

		arg_type = get_fn_expr_argtype(fcinfo->flinfo, 1);

		if (arg_type == InvalidOid)
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
					 errmsg("could not determine input data type")));

		jsonb_categorize_type(arg_type, &state->key_category,
							  &state->key_output_func);

		arg_type = get_fn_expr_argtype(fcinfo->flinfo, 2);

		if (arg_type == InvalidOid)
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
					 errmsg("could not determine input data type")));

		jsonb_categorize_type(arg_type, &state->val_category,
							  &state->val_output_func);
	}
	else
	{
		state = (JsonbAggState *) PG_GETARG_POINTER(0);
		result = state->res;
	}

	/* turn the argument into jsonb in the normal function context */

	if (PG_ARGISNULL(1))
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				 errmsg("field name must not be null")));

	val = PG_GETARG_DATUM(1);

	memset(&elem, 0, sizeof(JsonbInState));

	datum_to_jsonb(val, false, &elem, state->key_category,
				   state->key_output_func, true);

	jbkey = JsonbValueToJsonb(elem.res);

	val = PG_ARGISNULL(2) ? (Datum) 0 : PG_GETARG_DATUM(2);

	memset(&elem, 0, sizeof(JsonbInState));

	datum_to_jsonb(val, PG_ARGISNULL(2), &elem, state->val_category,
				   state->val_output_func, false);

	jbval = JsonbValueToJsonb(elem.res);

	it = JsonbIteratorInit(&jbkey->root);

	/* switch to the aggregate context for accumulation operations */

	oldcontext = MemoryContextSwitchTo(aggcontext);

	/*
	 * keys should be scalar, and we should have already checked for that
	 * above when calling datum_to_jsonb, so we only need to look for these
	 * things.
//.........这里部分代码省略.........
开发者ID:jianlirong,项目名称:postgres,代码行数:101,代码来源:jsonb.c


示例11: tsa_rewrite_accum

Datum
tsa_rewrite_accum(PG_FUNCTION_ARGS)
{
	TSQuery		acc;
	ArrayType  *qa;
	TSQuery		q;
	QTNode	   *qex = NULL,
			   *subs = NULL,
			   *acctree = NULL;
	bool		isfind = false;
	Datum	   *elemsp;
	int			nelemsp;
	MemoryContext aggcontext;
	MemoryContext oldcontext;

	if (!AggCheckCallContext(fcinfo, &aggcontext))
		elog(ERROR, "tsa_rewrite_accum called in non-aggregate context");

	if (PG_ARGISNULL(0) || PG_GETARG_POINTER(0) == NULL)
	{
		acc = (TSQuery) MemoryContextAlloc(aggcontext, HDRSIZETQ);
		SET_VARSIZE(acc, HDRSIZETQ);
		acc->size = 0;
	}
	else
		acc = PG_GETARG_TSQUERY(0);

	if (PG_ARGISNULL(1) || PG_GETARG_POINTER(1) == NULL)
		PG_RETURN_TSQUERY(acc);
	else
		qa = PG_GETARG_ARRAYTYPE_P_COPY(1);

	if (ARR_NDIM(qa) != 1)
		elog(ERROR, "array must be one-dimensional, not %d dimensions",
			 ARR_NDIM(qa));
	if (ArrayGetNItems(ARR_NDIM(qa), ARR_DIMS(qa)) != 3)
		elog(ERROR, "array must have three elements");
	if (ARR_ELEMTYPE(qa) != TSQUERYOID)
		elog(ERROR, "array must contain tsquery elements");

	deconstruct_array(qa, TSQUERYOID, -1, false, 'i', &elemsp, NULL, &nelemsp);

	q = DatumGetTSQuery(elemsp[0]);
	if (q->size == 0)
	{
		pfree(elemsp);
		PG_RETURN_POINTER(acc);
	}

	if (!acc->size)
	{
		if (VARSIZE(acc) > HDRSIZETQ)
		{
			pfree(elemsp);
			PG_RETURN_POINTER(acc);
		}
		else
			acctree = QT2QTN(GETQUERY(q), GETOPERAND(q));
	}
	else
		acctree = QT2QTN(GETQUERY(acc), GETOPERAND(acc));

	QTNTernary(acctree);
	QTNSort(acctree);

	q = DatumGetTSQuery(elemsp[1]);
	if (q->size == 0)
	{
		pfree(elemsp);
		PG_RETURN_POINTER(acc);
	}
	qex = QT2QTN(GETQUERY(q), GETOPERAND(q));
	QTNTernary(qex);
	QTNSort(qex);

	q = DatumGetTSQuery(elemsp[2]);
	if (q->size)
		subs = QT2QTN(GETQUERY(q), GETOPERAND(q));

	acctree = findsubquery(acctree, qex, subs, &isfind);

	if (isfind || !acc->size)
	{
		/* pfree( acc ); do not pfree(p), because nodeAgg.c will */
		if (acctree)
		{
			QTNBinary(acctree);
			oldcontext = MemoryContextSwitchTo(aggcontext);
			acc = QTN2QT(acctree);
			MemoryContextSwitchTo(oldcontext);
		}
		else
		{
			acc = (TSQuery) MemoryContextAlloc(aggcontext, HDRSIZETQ);
			SET_VARSIZE(acc, HDRSIZETQ);
			acc->size = 0;
		}
	}

	pfree(elemsp);
//.........这里部分代码省略.........
开发者ID:Distrotech,项目名称:postgresql,代码行数:101,代码来源:tsearch2.c


示例12: jsonb_agg_transfn

/*
 * jsonb_agg aggregate function
 */
Datum
jsonb_agg_transfn(PG_FUNCTION_ARGS)
{
	MemoryContext oldcontext,
				aggcontext;
	JsonbAggState *state;
	JsonbInState elem;
	Datum		val;
	JsonbInState *result;
	bool		single_scalar = false;
	JsonbIterator *it;
	Jsonb	   *jbelem;
	JsonbValue	v;
	JsonbIteratorToken type;

	if (!AggCheckCallContext(fcinfo, &aggcontext))
	{
		/* cannot be called directly because of internal-type argument */
		elog(ERROR, "jsonb_agg_transfn called in non-aggregate context");
	}

	/* set up the accumulator on the first go round */

	if (PG_ARGISNULL(0))
	{
		Oid			arg_type = get_fn_expr_argtype(fcinfo->flinfo, 1);

		if (arg_type == InvalidOid)
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
					 errmsg("could not determine input data type")));

		oldcontext = MemoryContextSwitchTo(aggcontext);
		state = palloc(sizeof(JsonbAggState));
		result = palloc0(sizeof(JsonbInState));
		state->res = result;
		result->res = pushJsonbValue(&result->parseState,
									 WJB_BEGIN_ARRAY, NULL);
		MemoryContextSwitchTo(oldcontext);

		jsonb_categorize_type(arg_type, &state->val_category,
							  &state->val_output_func);
	}
	else
	{
		state = (JsonbAggState *) PG_GETARG_POINTER(0);
		result = state->res;
	}

	/* turn the argument into jsonb in the normal function context */

	val = PG_ARGISNULL(1) ? (Datum) 0 : PG_GETARG_DATUM(1);

	memset(&elem, 0, sizeof(JsonbInState));

	datum_to_jsonb(val, PG_ARGISNULL(1), &elem, state->val_category,
				   state->val_output_func, false);

	jbelem = JsonbValueToJsonb(elem.res);

	/* switch to the aggregate context for accumulation operations */

	oldcontext = MemoryContextSwitchTo(aggcontext);

	it = JsonbIteratorInit(&jbelem->root);

	while ((type = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)
	{
		switch (type)
		{
			case WJB_BEGIN_ARRAY:
				if (v.val.array.rawScalar)
					single_scalar = true;
				else
					result->res = pushJsonbValue(&result->parseState,
												 type, NULL);
				break;
			case WJB_END_ARRAY:
				if (!single_scalar)
					result->res = pushJsonbValue(&result->parseState,
												 type, NULL);
				break;
			case WJB_BEGIN_OBJECT:
			case WJB_END_OBJECT:
				result->res = pushJsonbValue(&result->parseState,
											 type, NULL);
				break;
			case WJB_ELEM:
			case WJB_KEY:
			case WJB_VALUE:
				if (v.type == jbvString)
				{
					/* copy string values in the aggregate context */
					char	   *buf = palloc(v.val.string.len + 1);

					snprintf(buf, v.val.string.len + 1, "%s", v.val.string.val);
					v.val.string.val = buf;
//.........这里部分代码省略.........
开发者ID:jianlirong,项目名称:postgres,代码行数:101,代码来源:jsonb.c


示例13: jsonb_build_object

/*
 * SQL function jsonb_build_object(variadic "any")
 */
Datum
jsonb_build_object(PG_FUNCTION_ARGS)
{
	int			nargs = PG_NARGS();
	int			i;
	Datum		arg;
	Oid			val_type;
	JsonbInState result;

	if (nargs % 2 != 0)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				 errmsg("invalid number or arguments: object must be matched key value pairs")));

	memset(&result, 0, sizeof(JsonbInState));

	result.res = pushJsonbValue(&result.parseState, WJB_BEGIN_OBJECT, NULL);

	for (i = 0; i < nargs; i += 2)
	{

		/* process key */

		if (PG_ARGISNULL(i))
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
					 errmsg("arg %d: key cannot be null", i + 1)));
		val_type = get_fn_expr_argtype(fcinfo->flinfo, i);

		/*
		 * turn a constant (more or less literal) value that's of unknown type
		 * into text. Unknowns come in as a cstring pointer.
		 */
		if (val_type == UNKNOWNOID && get_fn_expr_arg_stable(fcinfo->flinfo, i))
		{
			val_type = TEXTOID;
			if (PG_ARGISNULL(i))
				arg = (Datum) 0;
			else
				arg = CStringGetTextDatum(PG_GETARG_POINTER(i));
		}
		else
		{
			arg = PG_GETARG_DATUM(i);
		}
		if (val_type == InvalidOid || val_type == UNKNOWNOID)
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
					 errmsg("arg %d: could not determine data type", i + 1)));

		add_jsonb(arg, false, &result, val_type, true);

		/* process value */

		val_type = get_fn_expr_argtype(fcinfo->flinfo, i + 1);
		/* see comments above */
		if (val_type == UNKNOWNOID && get_fn_expr_arg_stable(fcinfo->flinfo, i + 1))
		{
			val_type = TEXTOID;
			if (PG_ARGISNULL(i + 1))
				arg = (Datum) 0;
			else
				arg = CStringGetTextDatum(PG_GETARG_POINTER(i + 1));
		}
		else
		{
			arg = PG_GETARG_DATUM(i + 1);
		}
		if (val_type == InvalidOid || val_type == UNKNOWNOID)
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
					 errmsg("arg %d: could not determine data type", i + 2)));
		add_jsonb(arg, PG_ARGISNULL(i + 1), &result, val_type, false);

	}

	result.res = pushJsonbValue(&result.parseState, WJB_END_OBJECT, NULL);

	PG_RETURN_POINTER(JsonbValueToJsonb(result.res));
}
开发者ID:jianlirong,项目名称:postgres,代码行数:83,代码来源:jsonb.c


示例14: tsmatchsel

/*
 *	tsmatchsel -- Selectivity of "@@"
 *
 * restriction selectivity function for tsvector @@ tsquery and
 * tsquery @@ tsvector
 */
Datum
tsmatchsel(PG_FUNCTION_ARGS)
{
	PlannerInfo *root = (PlannerInfo *) PG_GETARG_POINTER(0);

#ifdef NOT_USED
	Oid			operator = PG_GETARG_OID(1);
#endif
	List	   *args = (List *) PG_GETARG_POINTER(2);
	int			varRelid = PG_GETARG_INT32(3);
	VariableStatData vardata;
	Node	   *other;
	bool		varonleft;
	Selectivity selec;

	/*
	 * If expression is not variable = something or something = variable, then
	 * punt and return a default estimate.
	 */
	if (!get_restriction_variable(root, args, varRelid,
								  &vardata, &other, &varonleft))
		PG_RETURN_FLOAT8(DEFAULT_TS_MATCH_SEL);

	/*
	 * Can't do anything useful if the something is not a constant, either.
	 */
	if (!IsA(other, Const))
	{
		ReleaseVariableStats(vardata);
		PG_RETURN_FLOAT8(DEFAULT_TS_MATCH_SEL);
	}

	/*
	 * The "@@" operator is strict, so we can cope with NULL right away
	 */
	if (((Const *) other)->constisnull)
	{
		ReleaseVariableStats(vardata);
		PG_RETURN_FLOAT8(0.0);
	}

	/*
	 * OK, there's a Var and a Const we're dealing with here.  We need the
	 * Const to be a TSQuery, else we can't do anything useful.  We have to
	 * check this because the Var might be the TSQuery not the TSVector.
	 */
	if (((Const *) other)->consttype == TSQUERYOID)
	{
		/* tsvector @@ tsquery or the other way around */
		Assert(vardata.vartype == TSVECTOROID);

		selec = tsquerysel(&vardata, ((Const *) other)->constvalue);
	}
	else
	{
		/* If we can't see the query structure, must punt */
		selec = DEFAULT_TS_MATCH_SEL;
	}

	ReleaseVariableStats(vardata);

	CLAMP_PROBABILITY(selec);

	PG_RETURN_FLOAT8((float8) selec);
}
开发者ID:markwkm,项目名称:postgres,代码行数:71,代码来源:ts_selfuncs.c


示例15: gin_consistent_jsonb

Datum
gin_consistent_jsonb(PG_FUNCTION_ARGS)
{
	bool	   *check = (bool *) PG_GETARG_POINTER(0);
	StrategyNumber strategy = PG_GETARG_UINT16(1);

	/* Jsonb	   *query = PG_GETARG_JSONB(2); */
	int32		nkeys = PG_GETARG_INT32(3);

	/* Pointer	   *extra_data = (Pointer *) PG_GETARG_POINTER(4); */
	bool	   *recheck = (bool *) PG_GETARG_POINTER(5);
	bool		res = true;
	int32		i;

	if (strategy == JsonbContainsStrategyNumber)
	{
		/*
		 * We must always recheck, since we can't tell from the index whether
		 * the positions of the matched items match the structure of the query
		 * object.  (Even if we could, we'd also have to worry about hashed
		 * keys and the index's failure to distinguish keys from string array
		 * elements.)  However, the tuple certainly doesn't match unless it
		 * contains all the query keys.
		 */
		*recheck = true;
		for (i = 0; i < nkeys; i++)
		{
			if (!check[i])
			{
				res = false;
				break;
			}
		}
	}
	else if (strategy == JsonbExistsStrategyNumber)
	{
		/*
		 * Although the key is certainly present in the index, we must recheck
		 * because (1) the key might be hashed, and (2) the index match might
		 * be for a key that's not at top level of the JSON object.  For (1),
		 * we could look at the query key to see if it's hashed and not
		 * recheck if not, but the index lacks enough info to tell about (2).
		 */
		*recheck = true;
		res = true;
	}
	else if (strategy == JsonbExistsAnyStrategyNumber)
	{
		/* As for plain exists, we must recheck */
		*recheck = true;
		res = true;
	}
	else if (strategy == JsonbExistsAllStrategyNumber)
	{
		/* As for plain exists, we must recheck */
		*recheck = true;
		/* ... but unless all the keys are present, we can say "false" */
		for (i = 0; i < nkeys; i++)
		{
			if (!check[i])
			{
				res = false;
				break;
			}
		}
	}
	else
		elog(ERROR, "unrecognized strategy number: %d", strategy);

	PG_RETURN_BOOL(res);
}
开发者ID:RCheungIT,项目名称:postgres,代码行数:71,代码来源:jsonb_gin.c


示例16: spg_text_choose

Datum
spg_text_choose(PG_FUNCTION_ARGS)
{
	spgChooseIn *in = (spgChooseIn *) PG_GETARG_POINTER(0);
	spgChooseOut *out = (spgChooseOut *) PG_GETARG_POINTER(1);
	text	   *inText = DatumGetTextPP(in->datum);
	char	   *inStr = VARDATA_ANY(inText);
	int			inSize = VARSIZE_ANY_EXHDR(inText);
	uint8		nodeChar = '\0';
	int			i = 0;
	int			commonLen = 0;

	/* Check for prefix match, set nodeChar to first byte after prefix */
	if (in->hasPrefix)
	{
		text	   *prefixText = DatumGetTextPP(in->prefixDatum);
		char	   *prefixStr = VARDATA_ANY(prefixText);
		int			prefixSize = VARSIZE_ANY_EXHDR(prefixText);

		commonLen = commonPrefix(inStr + in->level,
								 prefixStr,
								 inSize - in->level,
								 prefixSize);

		if (commonLen == prefixSize)
		{
			if (inSize - in->level > commonLen)
				nodeChar = *(uint8 *) (inStr + in->level + commonLen);
			else
				nodeChar = '\0';
		}
		else
		{
			/* Must split tuple because incoming value doesn't match prefix */
			out->resultType = spgSplitTuple;

			if (commonLen == 0)
			{
				out->result.splitTuple.prefixHasPrefix = false;
			}
			else
			{
				out->result.splitTuple.prefixHasPrefix = true;
				out->result.splitTuple.prefixPrefixDatum =
					formTextDatum(prefixStr, commonLen);
			}
			out->result.splitTuple.nodeLabel =
				UInt8GetDatum(*(prefixStr + commonLen));

			if (prefixSize - commonLen == 1)
			{
				out->result.splitTuple.postfixHasPrefix = false;
			}
			else
			{
				out->result.splitTuple.postfixHasPrefix = true;
				out->result.splitTuple.postfixPrefixDatum =
					formTextDatum(prefixStr + commonLen + 1,
								  prefixSize - commonLen - 1);
			}

			PG_RETURN_VOID();
		}
	}
	else if (inSize > in->level)
	{
		nodeChar = *(uint8 *) (inStr + in->level);
	}
	else
	{
		nodeChar = '\0';
	}

	/* Look up nodeChar in the node label array */
	if (searchChar(in->nodeLabels, in->nNodes, nodeChar, &i))
	{
		/*
		 * Descend to existing node.  (If in->allTheSame, the core code will
		 * ignore our nodeN specification here, but that's OK.  We still have
		 * to provide the correct levelAdd and restDatum values, and those are
		 * the same regardless of which node gets chosen by core.)
		 */
		out->resultType = spgMatchNode;
		out->result.matchNode.nodeN = i;
		out->result.matchNode.levelAdd = commonLen + 1;
		if (inSize - in->level - commonLen - 1 > 0)
			out->result.matchNode.restDatum =
				formTextDatum(inStr + in->level + commonLen + 1,
							  inSize - in->level - commonLen - 1);
		else
			out->result.matchNode.restDatum =
				formTextDatum(NULL, 0);
	}
	else if (in->allTheSame)
	{
		/*
		 * Can't use AddNode action, so split the tuple.  The upper tuple has
		 * the same prefix as before and uses an empty node label for the
		 * lower tuple.  The lower tuple has no prefix and the same node
		 * labels as the original tuple.
//.........这里部分代码省略.........
开发者ID:ASchurman,项目名称:BufStrat,代码行数:101,代码来源:spgtextproc.c


示例17: gin_extract_jsonb_hash

Datum
gin_extract_jsonb_hash(PG_FUNCTION_ARGS)
{
	Jsonb	   *jb = PG_GETARG_JSONB(0);
	int32	   *nentries = (int32 *) PG_GETARG_POINTER(1);
	int			total = 2 * JB_ROOT_COUNT(jb);
	JsonbIterator *it;
	JsonbValue	v;
	PathHashStack tail;
	PathHashStack *stack;
	int			i = 0,
				r;
	Datum	   *entries;

	/* If the root level is empty, we certainly have no keys */
	if (total == 0)
	{
		*nentries = 0;
		PG_RETURN_POINTER(NULL);
	}

	/* Otherwise, use 2 * root count as initial estimate of result size */
	entries = (Datum *) palloc(sizeof(Datum) * total);

	/* We keep a stack of hashes corresponding to parent key levels */
	tail.parent = NULL;
	tail.hash = 0;
	stack = &tail;

	it = JsonbIteratorInit(&jb->root);

	while ((r = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)
	{
		PathHashStack *parent;

		/* Since we recurse into the object, we might need more space */
		if (i >= total)
		{
			total *= 2;
			entries = (Datum *) repalloc(entries, sizeof(Datum) * total);
		}

		switch (r)
		{
			case WJB_BEGIN_ARRAY:
			case WJB_BEGIN_OBJECT:
				/* Push a stack level for this object */
				parent = stack;
				stack = (PathHashStack *) palloc(sizeof(PathHashStack));

				if (parent->parent)
				{
					/*
					 * We pass forward hashes from previous container nesting
					 * levels so that nested arrays with an outermost nested
					 * object will have element hashes mixed with the
					 * outermost key.  It's also somewhat useful to have
					 * nested objects' innermost values have hashes that are a
					 * function of not just their own key, but outer keys too.
					 *
					 * Nesting an array within another array will not alter
					 * innermost scalar element hash values, but that seems
					 * inconsequential.
					 */
					stack->hash = parent->hash;
				}
				else
				{
					/*
					 * At the outermost level, initialize hash with container
					 * type proxy value.  Note that this makes JB_FARRAY and
					 * JB_FOBJECT part of the on-disk representation, but they
					 * are that in the base jsonb object storage already.
					 */
					stack->hash = (r == WJB_BEGIN_ARRAY) ? JB_FARRAY : JB_FOBJECT;
				}
				stack->parent = parent;
				break;
			case WJB_KEY:
				/* initialize hash from parent */
				stack->hash = stack->parent->hash;
				/* and mix in this key */
				JsonbHashScalarValue(&v, &stack->hash);
				/* hash is now ready to incorporate the value */
				break;
			case WJB_ELEM:
				/* array elements use parent hash mixed with element's hash */
				stack->hash = stack->parent->hash;
				/* FALL THRU */
			case WJB_VALUE:
				/* mix the element or value's hash into the prepared hash */
				JsonbHashScalarValue(&v, &stack->hash);
				/* and emit an index entry */
				entries[i++] = UInt32GetDatum(stack->hash);
				/* Note: we assume we'll see KEY before another VALUE */
				break;
			case WJB_END_ARRAY:
			case WJB_END_OBJECT:
				/* Pop the stack */
				parent = stack->parent;
//.........这里部分代码省略.........
开发者ID:RCheungIT,项目名称:postgres,代码行数:101,代码来源:jsonb_gin.c


示例18: spg_text_picksplit

Datum
spg_text_picksplit(PG_FUNCTION_ARGS)
{
	spgPickSplitIn *in = (spgPickSplitIn *) PG_GETARG_POINTER(0);
	spgPickSplitOut *out = (spgPickSplitOut *) PG_GETARG_POINTER(1);
	text	   *text0 = DatumGetTextPP(in->datums[0]);
	int			i,
				commonLen;
	spgNodePtr *nodes;

	/* Identify longest common prefix, if any */
	commonLen = VARSIZE_ANY_EXHDR(text0);
	for (i = 1; i < in->nTuples && commonLen > 0; i++)
	{
		text	   *texti = DatumGetTextPP(in->datums[i]);
		int			tmp = commonPrefix(VARDATA_ANY(text0),
									   VARDATA_ANY(texti),
									   VARSIZE_ANY_EXHDR(text0),
									   VARSIZE_ANY_EXHDR(texti));

		if (tmp < commonLen)
			commonLen = tmp;
	}

	/*
	 * Limit the prefix length, if necessary, to ensure that the resulting
	 * inner tuple will fit on a page.
	 */
	commonLen = Min(commonLen, SPGIST_MAX_PREFIX_LENGTH);

	/* Set node prefix to be that string, if it's not empty */
	if (commonLen == 0)
	{
		out->hasPrefix = false;
	}
	else
	{
		out->hasPrefix = true;
		out->prefixDatum = formTextDatum(VARDATA_ANY(text0), commonLen);
	}

	/* Extract the node label (first non-common byte) from each value */
	nodes = (spgNodePtr *) palloc(sizeof(spgNodePtr) * in->nTuples);

	for (i = 0; i < in->nTuples; i++)
	{
		text	   *texti = DatumGetTextPP(in->datums[i]);

		if (commonLen < VARSIZE_ANY_EXHDR(texti))
			nodes[i].c = *(uint8 *) (VARDATA_ANY(texti) + commonLen);
		else
			nodes[i].c = '\0';	/* use \0 if string is all common */
		nodes[i].i = i;
		nodes[i].d = in->datums[i];
	}

	/*
	 * Sort by label bytes so that we can group the values into nodes.	This
	 * also ensures that the nodes are ordered by label value, allowing the
	 * use of binary search in searchChar.
	 */
	qsort(nodes, in->nTuples, sizeof(*nodes), cmpNodePtr);

	/* And emit results */
	out->nNodes = 0;
	out->nodeLabels = (Datum *) palloc(sizeof(Datum) * in->nTuples);
	out->mapTuplesToNodes = (int *) palloc(sizeof(int) * in->nTuples);
	out->leafTupleDatums = (Datum *) palloc(sizeof(Datum)  

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
C++ PG_GETARG_SPOLY函数代码示例发布时间:2022-05-30
下一篇:
C++ PG_GETARG_OID函数代码示例发布时间:2022-05-30
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap