當前位置: 首頁>>代碼示例>>C++>>正文


C++ BlessTupleDesc函數代碼示例

本文整理匯總了C++中BlessTupleDesc函數的典型用法代碼示例。如果您正苦於以下問題:C++ BlessTupleDesc函數的具體用法?C++ BlessTupleDesc怎麽用?C++ BlessTupleDesc使用的例子?那麽, 這裏精選的函數代碼示例或許可以為您提供幫助。


在下文中一共展示了BlessTupleDesc函數的15個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的C++代碼示例。

示例1: convert_to_UTF8

Datum
convert_to_UTF8(PG_FUNCTION_ARGS)
{
    // things we need to deal with constructing our composite type
    TupleDesc   tupdesc;
    Datum       values[3];
    bool        nulls[3];
    HeapTuple   tuple;

    // for char_set_detect function returns
    text    *encoding = NULL;
    text    *lang = NULL;
    int32_t confidence = 0;

    UErrorCode status = U_ZERO_ERROR;

    // output buffer for conversion to Unicode
    UChar* uBuf = NULL;
    int32_t uBuf_len = 0;

    // output of this function
    text *text_out;
    bool converted = false;
    bool dropped_bytes = false;
    bool dropped_bytes_toU = false;
    bool dropped_bytes_fromU = false;

    // temporary buffer for converted string
    char* converted_buf = NULL;

    // input args
    const text  *buffer = PG_GETARG_TEXT_P(0);
    const bool  force   = PG_GETARG_BOOL(1);

    // C string of text* buffer
    const char* cbuffer = NULL;
    int cbuffer_len = 0;

    // Convert output values into a PostgreSQL composite type.
    if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
        ereport(ERROR,
            (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
              errmsg("function returning record called in context "
                     "that cannot accept type record.\n")));

    // BlessTupleDesc for Datums
    BlessTupleDesc(tupdesc);

    // return if string to convert is NULL
    if (NULL == buffer)
    {
        // return input string,
        // converted to true,
        // dropped_bytes to false
        text_out = (text *) buffer;
        converted = true;
        dropped_bytes = false;
    }
    else
    {
        // extract string from text* to C string
        cbuffer = text_to_cstring(buffer);
        cbuffer_len = strlen(cbuffer);

        // bail on zero-length strings
        // return if cbuffer has zero length or contains a blank space
        if ((0 == cbuffer_len) || (0 == strcmp("", cbuffer)))
        {
            text_out = (text *) buffer;
            converted = true;
            dropped_bytes = false;
        }
        else
        {
            // UTF8 output can be up to 6 bytes per input byte
            // palloc0 allocates and zeros bytes in array
            int32_t converted_buf_len = cbuffer_len * 6 * sizeof(char);
            converted_buf = (char *) palloc0(converted_buf_len);
            // int32_t converted_len = 0;

            // detect encoding with ICU
            status = detect_ICU(buffer, &encoding, &lang, &confidence);

            ereport(DEBUG1,
                (errcode(ERRCODE_SUCCESSFUL_COMPLETION),
                 errmsg("ICU detection status: %d\n", status)));

            ereport(DEBUG1,
                (errcode(ERRCODE_SUCCESSFUL_COMPLETION),
                 errmsg("Detected encoding: %s, language: %s, confidence: %d\n",
                 text_to_cstring(encoding),
                 text_to_cstring(lang),
                         confidence)));

            // return without attempting a conversion if UTF8 is detected
            if (
                (0 == strcmp("UTF-8", text_to_cstring(encoding))) ||
                (0 == strcmp("utf-8", text_to_cstring(encoding))) ||
                (0 == strcmp("UTF8", text_to_cstring(encoding)))  ||
                (0 == strcmp("utf8", text_to_cstring(encoding)))
//.........這裏部分代碼省略.........
開發者ID:aweber,項目名稱:pg_chardetect,代碼行數:101,代碼來源:pg_chardetect.c

示例2: gp_pgdatabase__

/*
 * pgdatabasev - produce a view of pgdatabase to include transient state
 */
Datum
gp_pgdatabase__(PG_FUNCTION_ARGS)
{
	FuncCallContext *funcctx;
	Working_State *mystatus;

	if (SRF_IS_FIRSTCALL())
	{
		TupleDesc	tupdesc;
		MemoryContext oldcontext;

		/* create a function context for cross-call persistence */
		funcctx = SRF_FIRSTCALL_INIT();

		/*
		 * switch to memory context appropriate for multiple function
		 * calls
		 */
		oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);

		/* build tupdesc for result tuples */
		/* this had better match pg_prepared_xacts view in	system_views.sql */
		tupdesc = CreateTemplateTupleDesc(5, false);
		TupleDescInitEntry(tupdesc, (AttrNumber) 1, "dbid",
						   INT2OID, -1, 0);
		TupleDescInitEntry(tupdesc, (AttrNumber) 2, "isprimary",
						   BOOLOID, -1, 0);
		TupleDescInitEntry(tupdesc, (AttrNumber) 3, "content",
						   INT2OID, -1, 0);
		TupleDescInitEntry(tupdesc, (AttrNumber) 4, "valid",
						   BOOLOID, -1, 0);
		TupleDescInitEntry(tupdesc, (AttrNumber) 5, "definedprimary",
						   BOOLOID, -1, 0);

		funcctx->tuple_desc = BlessTupleDesc(tupdesc);

		/*
		 * Collect all the locking information that we will format and
		 * send out as a result set.
		 */
		mystatus = (Working_State *) palloc(sizeof(Working_State));
		funcctx->user_fctx = (void *) mystatus;

		mystatus->master = GetMasterSegment();
		mystatus->standby = GetStandbySegment();
		mystatus->segments = GetSegmentList();
		mystatus->idx = 0;

		MemoryContextSwitchTo(oldcontext);
	}

	funcctx = SRF_PERCALL_SETUP();
	mystatus = (Working_State *) funcctx->user_fctx;

	while (mystatus->master || mystatus->standby || (mystatus->idx < list_length(mystatus->segments)))
	{
		Datum		values[6];
		bool		nulls[6];
		HeapTuple	tuple;
		Datum		result;
		Segment 	*current = NULL;

		if (mystatus->master)
		{
			current = mystatus->master;
			mystatus->master = NULL;
		}
		else if (mystatus->standby)
		{
			current = mystatus->standby;
			mystatus->standby = NULL;
		}
		else
		{
			current = list_nth(mystatus->segments, mystatus->idx);
			mystatus->idx++;
		}

		/*
		 * Form tuple with appropriate data.
		 */
		MemSet(values, 0, sizeof(values));
		MemSet(nulls, false, sizeof(nulls));

		//values[0] = UInt16GetDatum(current->dbid);
		values[1] = current->standby ? false : true;;
		values[2] = UInt16GetDatum(current->segindex);

		values[3] = BoolGetDatum(true);
		values[4] = values[1];

		tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
		result = HeapTupleGetDatum(tuple);
		SRF_RETURN_NEXT(funcctx, result);
	}

	SRF_RETURN_DONE(funcctx);
//.........這裏部分代碼省略.........
開發者ID:BALDELab,項目名稱:incubator-hawq,代碼行數:101,代碼來源:cdbpgdatabase.c

示例3: pg_stat_file

/*
 * stat a file
 */
Datum
pg_stat_file(PG_FUNCTION_ARGS)
{
	text	   *filename_t = PG_GETARG_TEXT_P(0);
	char	   *filename;
	struct stat fst;
	Datum		values[6];
	bool		isnull[6];
	HeapTuple	tuple;
	TupleDesc	tupdesc;

	if (!superuser())
		ereport(ERROR,
				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
				 (errmsg("must be superuser to get file information"))));

	filename = convert_and_check_filename(filename_t);

	if (stat(filename, &fst) < 0)
		ereport(ERROR,
				(errcode_for_file_access(),
				 errmsg("could not stat file \"%s\": %m", filename)));

	/*
	 * This record type had better match the output parameters declared for me
	 * in pg_proc.h.
	 */
	tupdesc = CreateTemplateTupleDesc(6, false);
	TupleDescInitEntry(tupdesc, (AttrNumber) 1,
					   "size", INT8OID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 2,
					   "access", TIMESTAMPTZOID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 3,
					   "modification", TIMESTAMPTZOID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 4,
					   "change", TIMESTAMPTZOID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 5,
					   "creation", TIMESTAMPTZOID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 6,
					   "isdir", BOOLOID, -1, 0);
	BlessTupleDesc(tupdesc);

	memset(isnull, false, sizeof(isnull));

	values[0] = Int64GetDatum((int64) fst.st_size);
	values[1] = TimestampTzGetDatum(time_t_to_timestamptz(fst.st_atime));
	values[2] = TimestampTzGetDatum(time_t_to_timestamptz(fst.st_mtime));
	/* Unix has file status change time, while Win32 has creation time */
#if !defined(WIN32) && !defined(__CYGWIN__)
	values[3] = TimestampTzGetDatum(time_t_to_timestamptz(fst.st_ctime));
	isnull[4] = true;
#else
	isnull[3] = true;
	values[4] = TimestampTzGetDatum(time_t_to_timestamptz(fst.st_ctime));
#endif
	values[5] = BoolGetDatum(S_ISDIR(fst.st_mode));

	tuple = heap_form_tuple(tupdesc, values, isnull);

	pfree(filename);

	PG_RETURN_DATUM(HeapTupleGetDatum(tuple));
}
開發者ID:BioBD,項目名稱:Hypothetical_Indexes,代碼行數:66,代碼來源:genfile.c

示例4: extractGridData

Datum extractGridData(PG_FUNCTION_ARGS)
{
    FuncCallContext     *funcctx;

     /* stuff done only on the first call of the function */
     if (SRF_IS_FIRSTCALL())
     {
		TupleDesc tupdesc;

        /* create a function context for cross-call persistence */
        funcctx = SRF_FIRSTCALL_INIT();

        /* Build a tuple descriptor for our result type */
        if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
            ereport(ERROR,
                    (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                     errmsg("function returning record called in context "
                            "that cannot accept type record")));


        /* switch to memory context appropriate for multiple function calls */
        MemoryContext oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);

        funcctx->tuple_desc = BlessTupleDesc(tupdesc);

        // Initalize geos
        static int geosInitialized = 0;
        if ( ! geosInitialized )
        {
        	initGEOS(logInfo, logError);
        	geosInitialized = 1;
        }

        // Get the data to be returned
        struct GridPointDataListIterator * points = getExtractGridDataReturnValues(fcinfo);

        // Convert data into a set of Datums
        funcctx->max_calls = points->list->count;
        Datum * returnValues = palloc(sizeof(Datum) * funcctx->max_calls);
        int i;
        for ( i = 0; i < funcctx->max_calls; ++ i )
        	returnValues[i] = getNextReturnTupleViaDatums(GridPointDataListIteratorNext(points), funcctx->tuple_desc);
        funcctx->user_fctx = (void *) returnValues;

        // Delete intermediate data
//        GridPointDataListDelete(points->list);
//        GridPointDataListIteratorDelete(points);

        MemoryContextSwitchTo(oldcontext);
     }

    /* stuff done on every call of the function */
    funcctx = SRF_PERCALL_SETUP();

    if ( funcctx->call_cntr < funcctx->max_calls )
    {
    	Datum * ret = (Datum *) funcctx->user_fctx;
    	Datum result = ret[funcctx->call_cntr];

        SRF_RETURN_NEXT(funcctx, result);
    }
    else
    {
    	//GridPointDataListDelete(iterator->list);
        SRF_RETURN_DONE(funcctx);
    }
}
開發者ID:metno,項目名稱:wdb,代碼行數:67,代碼來源:extractGridData.c

示例5: json_populate_recordset

/*
 * SQL function json_populate_recordset
 *
 * set fields in a set of records from the argument json,
 * which must be an array of objects.
 *
 * similar to json_populate_record, but the tuple-building code
 * is pushed down into the semantic action handlers so it's done
 * per object in the array.
 */
Datum
json_populate_recordset(PG_FUNCTION_ARGS)
{
	Oid			argtype = get_fn_expr_argtype(fcinfo->flinfo, 0);
	text	   *json = PG_GETARG_TEXT_P(1);
	bool		use_json_as_text = PG_GETARG_BOOL(2);
	ReturnSetInfo *rsi;
	MemoryContext old_cxt;
	Oid			tupType;
	int32		tupTypmod;
	HeapTupleHeader rec;
	TupleDesc	tupdesc;
	RecordIOData *my_extra;
	int			ncolumns;
	JsonLexContext *lex;
	JsonSemAction sem;
	PopulateRecordsetState state;

	if (!type_is_rowtype(argtype))
		ereport(ERROR,
				(errcode(ERRCODE_DATATYPE_MISMATCH),
				 errmsg("first argument must be a rowtype")));

	rsi = (ReturnSetInfo *) fcinfo->resultinfo;

	if (!rsi || !IsA(rsi, ReturnSetInfo) ||
		(rsi->allowedModes & SFRM_Materialize) == 0 ||
		rsi->expectedDesc == NULL)
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("set-valued function called in context that "
						"cannot accept a set")));


	rsi->returnMode = SFRM_Materialize;

	/*
	 * get the tupdesc from the result set info - it must be a record type
	 * because we already checked that arg1 is a record type.
	 */
	(void) get_call_result_type(fcinfo, NULL, &tupdesc);

	state = palloc0(sizeof(populateRecordsetState));
	sem = palloc0(sizeof(jsonSemAction));


	/* make these in a sufficiently long-lived memory context */
	old_cxt = MemoryContextSwitchTo(rsi->econtext->ecxt_per_query_memory);

	state->ret_tdesc = CreateTupleDescCopy(tupdesc);
	BlessTupleDesc(state->ret_tdesc);
	state->tuple_store =
		tuplestore_begin_heap(rsi->allowedModes & SFRM_Materialize,
							  false, work_mem);

	MemoryContextSwitchTo(old_cxt);

	/* if the json is null send back an empty set */
	if (PG_ARGISNULL(1))
		PG_RETURN_NULL();

	if (PG_ARGISNULL(0))
		rec = NULL;
	else
		rec = PG_GETARG_HEAPTUPLEHEADER(0);

	tupType = tupdesc->tdtypeid;
	tupTypmod = tupdesc->tdtypmod;
	ncolumns = tupdesc->natts;

	lex = makeJsonLexContext(json, true);

	/*
	 * 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 ||
//.........這裏部分代碼省略.........
開發者ID:50wu,項目名稱:gpdb,代碼行數:101,代碼來源:jsonfuncs.c

示例6: ExecInitFunctionScan


//.........這裏部分代碼省略.........
	/*
	 * tuple table initialization
	 */
	ExecInitResultTupleSlot(estate, &scanstate->ss.ps);
	ExecInitScanTupleSlot(estate, &scanstate->ss);

	/*
	 * initialize child expressions
	 */
	scanstate->ss.ps.targetlist = (List *)
		ExecInitExpr((Expr *) node->scan.plan.targetlist,
					 (PlanState *) scanstate);
	scanstate->ss.ps.qual = (List *)
		ExecInitExpr((Expr *) node->scan.plan.qual,
					 (PlanState *) scanstate);

	/* Check if targetlist or qual contains a var node referencing the ctid column */
	scanstate->cdb_want_ctid = contain_ctid_var_reference(&node->scan);

    ItemPointerSet(&scanstate->cdb_fake_ctid, 0, 0);
    ItemPointerSet(&scanstate->cdb_mark_ctid, 0, 0);

	/*
	 * get info about function
	 */
	rte = rt_fetch(node->scan.scanrelid, estate->es_range_table);
	Assert(rte->rtekind == RTE_FUNCTION);

	/*
	 * Now determine if the function returns a simple or composite type, and
	 * build an appropriate tupdesc.
	 */
	functypclass = get_expr_result_type(rte->funcexpr,
										&funcrettype,
										&tupdesc);

	if (functypclass == TYPEFUNC_COMPOSITE)
	{
		/* Composite data type, e.g. a table's row type */
		Assert(tupdesc);
		/* Must copy it out of typcache for safety */
		tupdesc = CreateTupleDescCopy(tupdesc);
	}
	else if (functypclass == TYPEFUNC_SCALAR)
	{
		/* Base data type, i.e. scalar */
		char	   *attname = strVal(linitial(rte->eref->colnames));

		tupdesc = CreateTemplateTupleDesc(1, false);
		TupleDescInitEntry(tupdesc,
						   (AttrNumber) 1,
						   attname,
						   funcrettype,
						   -1,
						   0);
	}
	else if (functypclass == TYPEFUNC_RECORD)
	{
		tupdesc = BuildDescFromLists(rte->eref->colnames,
									 rte->funccoltypes,
									 rte->funccoltypmods);
	}
	else
	{
		/* crummy error message, but parser should have caught this */
		elog(ERROR, "function in FROM has unsupported return type");
	}

	/*
	 * For RECORD results, make sure a typmod has been assigned.  (The
	 * function should do this for itself, but let's cover things in case it
	 * doesn't.)
	 */
	BlessTupleDesc(tupdesc);

	scanstate->tupdesc = tupdesc;
	ExecAssignScanType(&scanstate->ss, tupdesc);

	/*
	 * Other node-specific setup
	 */
	scanstate->tuplestorestate = NULL;
	scanstate->funcexpr = ExecInitExpr((Expr *) rte->funcexpr,
									   (PlanState *) scanstate);

	/*
	 * Initialize result tuple type and projection info.
	 */
	ExecAssignResultTypeFromTL(&scanstate->ss.ps);
	ExecAssignScanProjectionInfo(&scanstate->ss);

	initGpmonPktForFunctionScan((Plan *)node, &scanstate->ss.ps.gpmon_pkt, estate);
	
	if (gp_resqueue_memory_policy != RESQUEUE_MEMORY_POLICY_NONE)
	{
		SPI_ReserveMemory(((Plan *)node)->operatorMemKB * 1024L);
	}

	return scanstate;
}
開發者ID:qiuyesuifeng,項目名稱:gpdb,代碼行數:101,代碼來源:nodeFunctionscan.c

示例7: pg_lock_status

/*
 * pg_lock_status - produce a view with one row per held or awaited lock mode
 */
Datum
pg_lock_status(PG_FUNCTION_ARGS)
{
	FuncCallContext *funcctx;
	PG_Lock_Status *mystatus;
	LockData   *lockData;
	PredicateLockData *predLockData;

	if (SRF_IS_FIRSTCALL())
	{
		TupleDesc	tupdesc;
		MemoryContext oldcontext;

		/* create a function context for cross-call persistence */
		funcctx = SRF_FIRSTCALL_INIT();

		/*
		 * switch to memory context appropriate for multiple function calls
		 */
		oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);

		/* build tupdesc for result tuples */
		/* this had better match pg_locks view in system_views.sql */
		tupdesc = CreateTemplateTupleDesc(NUM_LOCK_STATUS_COLUMNS, false);
		TupleDescInitEntry(tupdesc, (AttrNumber) 1, "locktype",
						   TEXTOID, -1, 0);
		TupleDescInitEntry(tupdesc, (AttrNumber) 2, "database",
						   OIDOID, -1, 0);
		TupleDescInitEntry(tupdesc, (AttrNumber) 3, "relation",
						   OIDOID, -1, 0);
		TupleDescInitEntry(tupdesc, (AttrNumber) 4, "page",
						   INT4OID, -1, 0);
		TupleDescInitEntry(tupdesc, (AttrNumber) 5, "tuple",
						   INT2OID, -1, 0);
		TupleDescInitEntry(tupdesc, (AttrNumber) 6, "virtualxid",
						   TEXTOID, -1, 0);
		TupleDescInitEntry(tupdesc, (AttrNumber) 7, "transactionid",
						   XIDOID, -1, 0);
		TupleDescInitEntry(tupdesc, (AttrNumber) 8, "classid",
						   OIDOID, -1, 0);
		TupleDescInitEntry(tupdesc, (AttrNumber) 9, "objid",
						   OIDOID, -1, 0);
		TupleDescInitEntry(tupdesc, (AttrNumber) 10, "objsubid",
						   INT2OID, -1, 0);
		TupleDescInitEntry(tupdesc, (AttrNumber) 11, "virtualtransaction",
						   TEXTOID, -1, 0);
		TupleDescInitEntry(tupdesc, (AttrNumber) 12, "pid",
						   INT4OID, -1, 0);
		TupleDescInitEntry(tupdesc, (AttrNumber) 13, "mode",
						   TEXTOID, -1, 0);
		TupleDescInitEntry(tupdesc, (AttrNumber) 14, "granted",
						   BOOLOID, -1, 0);
		TupleDescInitEntry(tupdesc, (AttrNumber) 15, "fastpath",
						   BOOLOID, -1, 0);

		funcctx->tuple_desc = BlessTupleDesc(tupdesc);

		/*
		 * Collect all the locking information that we will format and send
		 * out as a result set.
		 */
		mystatus = (PG_Lock_Status *) palloc(sizeof(PG_Lock_Status));
		funcctx->user_fctx = (void *) mystatus;

		mystatus->lockData = GetLockStatusData();
		mystatus->currIdx = 0;
		mystatus->predLockData = GetPredicateLockStatusData();
		mystatus->predLockIdx = 0;

		MemoryContextSwitchTo(oldcontext);
	}

	funcctx = SRF_PERCALL_SETUP();
	mystatus = (PG_Lock_Status *) funcctx->user_fctx;
	lockData = mystatus->lockData;

	while (mystatus->currIdx < lockData->nelements)
	{
		bool		granted;
		LOCKMODE	mode = 0;
		const char *locktypename;
		char		tnbuf[32];
		Datum		values[NUM_LOCK_STATUS_COLUMNS];
		bool		nulls[NUM_LOCK_STATUS_COLUMNS];
		HeapTuple	tuple;
		Datum		result;
		LockInstanceData   *instance;

		instance = &(lockData->locks[mystatus->currIdx]);

		/*
		 * Look to see if there are any held lock modes in this PROCLOCK. If
		 * so, report, and destructively modify lockData so we don't report
		 * again.
		 */
		granted = false;
		if (instance->holdMask)
//.........這裏部分代碼省略.........
開發者ID:a1exsh,項目名稱:postgres,代碼行數:101,代碼來源:lockfuncs.c

示例8: sampleNewTopics

Datum sampleNewTopics(PG_FUNCTION_ARGS)
{
	int32 i, widx, wtopic, rtopic;

	ArrayType * doc_arr = PG_GETARG_ARRAYTYPE_P(0);
	ArrayType * topics_arr = PG_GETARG_ARRAYTYPE_P(1);
	ArrayType * topic_d_arr = PG_GETARG_ARRAYTYPE_P(2);
	ArrayType * global_count_arr = PG_GETARG_ARRAYTYPE_P(3);
	ArrayType * topic_counts_arr = PG_GETARG_ARRAYTYPE_P(4);
	int32 num_topics = PG_GETARG_INT32(5);
	int32 dsize = PG_GETARG_INT32(6);
	float8 alpha = PG_GETARG_FLOAT8(7);
	float8 eta = PG_GETARG_FLOAT8(8);

	if (ARR_NULLBITMAP(doc_arr) || ARR_NDIM(doc_arr) != 1 || 
	    ARR_ELEMTYPE(doc_arr) != INT4OID ||
	    ARR_NDIM(topics_arr) != 1 || ARR_ELEMTYPE(topics_arr) != INT4OID ||
	    ARR_NULLBITMAP(topic_d_arr) || ARR_NDIM(topic_d_arr) != 1 || 
	    ARR_ELEMTYPE(topic_d_arr) != INT4OID ||
	    ARR_NULLBITMAP(global_count_arr) || ARR_NDIM(global_count_arr) != 1
	    || ARR_ELEMTYPE(global_count_arr) != INT4OID ||
	    ARR_NULLBITMAP(topic_counts_arr) || ARR_NDIM(topic_counts_arr) != 1
	    || ARR_ELEMTYPE(topic_counts_arr) != INT4OID)
		ereport(ERROR,
		       (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
			errmsg("function \"%s\" called with invalid parameters",
			       format_procedure(fcinfo->flinfo->fn_oid))));

	// the document array
	int32 * doc = (int32 *)ARR_DATA_PTR(doc_arr);
	int32 len = ARR_DIMS(doc_arr)[0];

	// array giving topic assignment to each word in document
	int32 * topics = (int32 *)ARR_DATA_PTR(topics_arr);

	// distribution of topics in document
	int32 * topic_d = (int32 *)ARR_DATA_PTR(topic_d_arr);

	// the word-topic count matrix
	int32 * global_count = (int32 *)ARR_DATA_PTR(global_count_arr);

	// total number of words assigned to each topic in the whole corpus
	int32 * topic_counts = (int32 *)ARR_DATA_PTR(topic_counts_arr);

	ArrayType * ret_topics_arr, * ret_topic_d_arr;
	int32 * ret_topics, * ret_topic_d;

	Datum * arr1 = palloc0(len * sizeof(Datum));
	ret_topics_arr = construct_array(arr1,len,INT4OID,4,true,'i');
	ret_topics = (int32 *)ARR_DATA_PTR(ret_topics_arr);

	Datum * arr2 = palloc0(num_topics * sizeof(Datum));
	ret_topic_d_arr = construct_array(arr2,num_topics,INT4OID,4,true,'i');
	ret_topic_d = (int32 *)ARR_DATA_PTR(ret_topic_d_arr);

	for (i=0; i!=len; i++) {
		widx = doc[i];

		if (widx < 1 || widx > dsize)
		     ereport
		      (ERROR,
		       (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
			errmsg("function \"%s\" called with invalid parameters",
			       format_procedure(fcinfo->flinfo->fn_oid))));

		wtopic = topics[i];
		rtopic = sampleTopic(num_topics,widx,wtopic,global_count,
				     topic_d,topic_counts,alpha,eta);

		// <sampleNewTopics error checking> 

		ret_topics[i] = rtopic;
		ret_topic_d[rtopic-1]++;
	}

	Datum values[2];
	values[0] = PointerGetDatum(ret_topics_arr);
	values[1] = PointerGetDatum(ret_topic_d_arr);

	TupleDesc tuple;
	if (get_call_result_type(fcinfo, NULL, &tuple) != TYPEFUNC_COMPOSITE)
		ereport(ERROR,
			(errcode( ERRCODE_FEATURE_NOT_SUPPORTED ),
			 errmsg( "function returning record called in context "
				 "that cannot accept type record" )));
	tuple = BlessTupleDesc(tuple);

	bool * isnulls = palloc0(2 * sizeof(bool));
	HeapTuple ret = heap_form_tuple(tuple, values, isnulls);

	if (isnulls[0] || isnulls[1])
		ereport(ERROR,
			(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
			 errmsg("function \"%s\" produced null results",
				format_procedure(fcinfo->flinfo->fn_oid),i)));

	PG_RETURN_DATUM(HeapTupleGetDatum(ret));
}
開發者ID:dcking,項目名稱:madlib,代碼行數:98,代碼來源:plda.c

示例9: pg_control_init

Datum
pg_control_init(PG_FUNCTION_ARGS)
{
	Datum		values[12];
	bool		nulls[12];
	TupleDesc	tupdesc;
	HeapTuple	htup;
	ControlFileData *ControlFile;
	bool		crc_ok;

	/*
	 * Construct a tuple descriptor for the result row.  This must match this
	 * function's pg_proc entry!
	 */
	tupdesc = CreateTemplateTupleDesc(12);
	TupleDescInitEntry(tupdesc, (AttrNumber) 1, "max_data_alignment",
					   INT4OID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 2, "database_block_size",
					   INT4OID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 3, "blocks_per_segment",
					   INT4OID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 4, "wal_block_size",
					   INT4OID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 5, "bytes_per_wal_segment",
					   INT4OID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 6, "max_identifier_length",
					   INT4OID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 7, "max_index_columns",
					   INT4OID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 8, "max_toast_chunk_size",
					   INT4OID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 9, "large_object_chunk_size",
					   INT4OID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 10, "float4_pass_by_value",
					   BOOLOID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 11, "float8_pass_by_value",
					   BOOLOID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 12, "data_page_checksum_version",
					   INT4OID, -1, 0);
	tupdesc = BlessTupleDesc(tupdesc);

	/* read the control file */
	ControlFile = get_controlfile(DataDir, NULL, &crc_ok);
	if (!crc_ok)
		ereport(ERROR,
				(errmsg("calculated CRC checksum does not match value stored in file")));

	values[0] = Int32GetDatum(ControlFile->maxAlign);
	nulls[0] = false;

	values[1] = Int32GetDatum(ControlFile->blcksz);
	nulls[1] = false;

	values[2] = Int32GetDatum(ControlFile->relseg_size);
	nulls[2] = false;

	values[3] = Int32GetDatum(ControlFile->xlog_blcksz);
	nulls[3] = false;

	values[4] = Int32GetDatum(ControlFile->xlog_seg_size);
	nulls[4] = false;

	values[5] = Int32GetDatum(ControlFile->nameDataLen);
	nulls[5] = false;

	values[6] = Int32GetDatum(ControlFile->indexMaxKeys);
	nulls[6] = false;

	values[7] = Int32GetDatum(ControlFile->toast_max_chunk_size);
	nulls[7] = false;

	values[8] = Int32GetDatum(ControlFile->loblksize);
	nulls[8] = false;

	values[9] = BoolGetDatum(ControlFile->float4ByVal);
	nulls[9] = false;

	values[10] = BoolGetDatum(ControlFile->float8ByVal);
	nulls[10] = false;

	values[11] = Int32GetDatum(ControlFile->data_checksum_version);
	nulls[11] = false;

	htup = heap_form_tuple(tupdesc, values, nulls);

	PG_RETURN_DATUM(HeapTupleGetDatum(htup));
}
開發者ID:MasahikoSawada,項目名稱:postgresql,代碼行數:87,代碼來源:pg_controldata.c

示例10: pg_control_checkpoint

Datum
pg_control_checkpoint(PG_FUNCTION_ARGS)
{
	Datum		values[19];
	bool		nulls[19];
	TupleDesc	tupdesc;
	HeapTuple	htup;
	ControlFileData *ControlFile;
	XLogSegNo	segno;
	char		xlogfilename[MAXFNAMELEN];
	bool		crc_ok;

	/*
	 * Construct a tuple descriptor for the result row.  This must match this
	 * function's pg_proc entry!
	 */
	tupdesc = CreateTemplateTupleDesc(18);
	TupleDescInitEntry(tupdesc, (AttrNumber) 1, "checkpoint_lsn",
					   LSNOID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 2, "redo_lsn",
					   LSNOID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 3, "redo_wal_file",
					   TEXTOID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 4, "timeline_id",
					   INT4OID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 5, "prev_timeline_id",
					   INT4OID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 6, "full_page_writes",
					   BOOLOID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 7, "next_xid",
					   TEXTOID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 8, "next_oid",
					   OIDOID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 9, "next_multixact_id",
					   XIDOID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 10, "next_multi_offset",
					   XIDOID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 11, "oldest_xid",
					   XIDOID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 12, "oldest_xid_dbid",
					   OIDOID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 13, "oldest_active_xid",
					   XIDOID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 14, "oldest_multi_xid",
					   XIDOID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 15, "oldest_multi_dbid",
					   OIDOID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 16, "oldest_commit_ts_xid",
					   XIDOID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 17, "newest_commit_ts_xid",
					   XIDOID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 18, "checkpoint_time",
					   TIMESTAMPTZOID, -1, 0);
	tupdesc = BlessTupleDesc(tupdesc);

	/* Read the control file. */
	ControlFile = get_controlfile(DataDir, NULL, &crc_ok);
	if (!crc_ok)
		ereport(ERROR,
				(errmsg("calculated CRC checksum does not match value stored in file")));

	/*
	 * Calculate name of the WAL file containing the latest checkpoint's REDO
	 * start point.
	 */
	XLByteToSeg(ControlFile->checkPointCopy.redo, segno, wal_segment_size);
	XLogFileName(xlogfilename, ControlFile->checkPointCopy.ThisTimeLineID,
				 segno, wal_segment_size);

	/* Populate the values and null arrays */
	values[0] = LSNGetDatum(ControlFile->checkPoint);
	nulls[0] = false;

	values[1] = LSNGetDatum(ControlFile->checkPointCopy.redo);
	nulls[1] = false;

	values[2] = CStringGetTextDatum(xlogfilename);
	nulls[2] = false;

	values[3] = Int32GetDatum(ControlFile->checkPointCopy.ThisTimeLineID);
	nulls[3] = false;

	values[4] = Int32GetDatum(ControlFile->checkPointCopy.PrevTimeLineID);
	nulls[4] = false;

	values[5] = BoolGetDatum(ControlFile->checkPointCopy.fullPageWrites);
	nulls[5] = false;

	values[6] = CStringGetTextDatum(psprintf("%u:%u",
											 ControlFile->checkPointCopy.nextXidEpoch,
											 ControlFile->checkPointCopy.nextXid));
	nulls[6] = false;

	values[7] = ObjectIdGetDatum(ControlFile->checkPointCopy.nextOid);
	nulls[7] = false;

	values[8] = TransactionIdGetDatum(ControlFile->checkPointCopy.nextMulti);
	nulls[8] = false;

	values[9] = TransactionIdGetDatum(ControlFile->checkPointCopy.nextMultiOffset);
//.........這裏部分代碼省略.........
開發者ID:MasahikoSawada,項目名稱:postgresql,代碼行數:101,代碼來源:pg_controldata.c

示例11: text_unpivot

Datum 
text_unpivot(PG_FUNCTION_ARGS)
{
	FuncCallContext      *funcctx;
	unpivot_fctx         *fctx;
	MemoryContext         oldcontext;
	Datum                 d[2];
	bool                  isna[2];

	/* stuff done only on the first call of the function */
	if (SRF_IS_FIRSTCALL())
	{
		TupleDesc  tupdesc;
		ArrayType *labels;
		ArrayType *data;
		Oid        eltype1;
		Oid        eltype2;

		/* see if we were given an explicit step size */
		if (PG_NARGS() != 2)
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
					 errmsg("number of parameters != 2")));

		/* 
		 * Type check inputs:
		 *    0: label text[]
		 *    1: value anyarray
		 */
		eltype1 = get_fn_expr_argtype(fcinfo->flinfo, 0);
		eltype2 = get_fn_expr_argtype(fcinfo->flinfo, 1);

		if (!OidIsValid(eltype1))
			elog(ERROR, "could not determine data type of input 'label'");
		if (!OidIsValid(eltype2))
			elog(ERROR, "could not determine data type of input 'value'");

		/* Strict function, return null on null input */
		if (PG_ARGISNULL(0) || PG_ARGISNULL(1))
			PG_RETURN_NULL();
		
		/* create a function context for cross-call persistence */
		funcctx = SRF_FIRSTCALL_INIT();

		/* switch to memory context appropriate for multiple function calls */
		oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);

        /* Build a tuple descriptor for our result type */
        if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
            ereport(ERROR,
                    (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                     errmsg("function returning record called in context "
                            "that cannot accept type record")));
		funcctx->tuple_desc = BlessTupleDesc(tupdesc);

		/* allocate memory for user context */
		fctx = (unpivot_fctx *) palloc(sizeof(unpivot_fctx));

		/* Use fctx to keep state from call to call */
		labels = PG_GETARG_ARRAYTYPE_P(0);
		data   = PG_GETARG_ARRAYTYPE_P(1);
		array_loop(labels, ARR_LBOUND(labels)[0], &fctx->label_iter);
		array_loop(data,   ARR_LBOUND(labels)[0], &fctx->data_iter);		

		funcctx->user_fctx = fctx;
		MemoryContextSwitchTo(oldcontext);
	}

	/* stuff done on every call of the function */
	funcctx = SRF_PERCALL_SETUP();

	/* get the saved state and use current as the result for this iteration */
	fctx = (unpivot_fctx*) funcctx->user_fctx;

	if (array_next(&fctx->label_iter, &d[0], &isna[0]))
	{
		HeapTuple tuple;

		array_next(&fctx->data_iter, &d[1], &isna[1]);
		tuple = heap_form_tuple(funcctx->tuple_desc, d, isna);
		SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple));		
	}
	else
	{
		SRF_RETURN_DONE(funcctx);
	}
}
開發者ID:BALDELab,項目名稱:incubator-hawq,代碼行數:87,代碼來源:pivot.c

示例12: exec_get_datum_type

/*
 * Similar function exec_get_datum_type is in 9nth line
 */
static Oid
exec_get_datum_type(PLpgSQL_execstate *estate,
				    PLpgSQL_datum *datum)
{
	Oid typoid = InvalidOid;

	switch (datum->dtype)
	{
		case PLPGSQL_DTYPE_VAR:
			typoid = ((PLpgSQL_var *) datum)->datatype->typoid;
			break;

		case PLPGSQL_DTYPE_ROW:
			typoid = ((PLpgSQL_row *) datum)->rowtupdesc->tdtypeid;
			break;

		case PLPGSQL_DTYPE_REC:
			{
				PLpgSQL_rec *rec = (PLpgSQL_rec *) datum;

				if (!HeapTupleIsValid(rec->tup))
					ereport(ERROR,
						  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
						   errmsg("record \"%s\" is not assigned yet",
								  rec->refname),
						   errdetail("The tuple structure of a not-yet-assigned record is indeterminate.")));
				Assert(rec->tupdesc != NULL);
				/* Make sure we have a valid type/typmod setting */
				BlessTupleDesc(rec->tupdesc);

				typoid = rec->tupdesc->tdtypeid;
			}
			break;

		case PLPGSQL_DTYPE_RECFIELD:
			{
				PLpgSQL_recfield *recfield = (PLpgSQL_recfield *) datum;
				PLpgSQL_rec *rec;
				int			fno;

				rec = (PLpgSQL_rec *) (estate->datums[recfield->recparentno]);
				if (!HeapTupleIsValid(rec->tup))
					ereport(ERROR,
						  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
						   errmsg("record \"%s\" is not assigned yet",
								  rec->refname),
						   errdetail("The tuple structure of a not-yet-assigned record is indeterminate.")));
				fno = SPI_fnumber(rec->tupdesc, recfield->fieldname);
				if (fno == SPI_ERROR_NOATTRIBUTE)
					ereport(ERROR,
							(errcode(ERRCODE_UNDEFINED_COLUMN),
							 errmsg("record \"%s\" has no field \"%s\"",
									rec->refname, recfield->fieldname)));
				typoid = SPI_gettypeid(rec->tupdesc, fno);
			}
			break;

		case PLPGSQL_DTYPE_TRIGARG:
			typoid = TEXTOID;
			break;
	}

	return typoid;
}
開發者ID:denishpatel,項目名稱:plpgsql_lint,代碼行數:67,代碼來源:plpgsql_lint.c

示例13: pg_stat_get_archiver

Datum
pg_stat_get_archiver(PG_FUNCTION_ARGS)
{
	TupleDesc	tupdesc;
	Datum		values[7];
	bool		nulls[7];
	PgStat_ArchiverStats *archiver_stats;

	/* Initialise values and NULL flags arrays */
	MemSet(values, 0, sizeof(values));
	MemSet(nulls, 0, sizeof(nulls));

	/* Initialise attributes information in the tuple descriptor */
	tupdesc = CreateTemplateTupleDesc(7, false);
	TupleDescInitEntry(tupdesc, (AttrNumber) 1, "archived_count",
					   INT8OID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 2, "last_archived_wal",
					   TEXTOID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 3, "last_archived_time",
					   TIMESTAMPTZOID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 4, "failed_count",
					   INT8OID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 5, "last_failed_wal",
					   TEXTOID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 6, "last_failed_time",
					   TIMESTAMPTZOID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 7, "stats_reset",
					   TIMESTAMPTZOID, -1, 0);

	BlessTupleDesc(tupdesc);

	/* Get statistics about the archiver process */
	archiver_stats = pgstat_fetch_stat_archiver();

	/* Fill values and NULLs */
	values[0] = Int64GetDatum(archiver_stats->archived_count);
	if (*(archiver_stats->last_archived_wal) == '\0')
		nulls[1] = true;
	else
		values[1] = CStringGetTextDatum(archiver_stats->last_archived_wal);

	if (archiver_stats->last_archived_timestamp == 0)
		nulls[2] = true;
	else
		values[2] = TimestampTzGetDatum(archiver_stats->last_archived_timestamp);

	values[3] = Int64GetDatum(archiver_stats->failed_count);
	if (*(archiver_stats->last_failed_wal) == '\0')
		nulls[4] = true;
	else
		values[4] = CStringGetTextDatum(archiver_stats->last_failed_wal);

	if (archiver_stats->last_failed_timestamp == 0)
		nulls[5] = true;
	else
		values[5] = TimestampTzGetDatum(archiver_stats->last_failed_timestamp);

	if (archiver_stats->stat_reset_timestamp == 0)
		nulls[6] = true;
	else
		values[6] = TimestampTzGetDatum(archiver_stats->stat_reset_timestamp);

	/* Returns the record as Datum */
	PG_RETURN_DATUM(HeapTupleGetDatum(
								   heap_form_tuple(tupdesc, values, nulls)));
}
開發者ID:EccentricLoggers,項目名稱:peloton,代碼行數:66,代碼來源:pgstatfuncs.cpp

示例14: master_get_active_worker_nodes

/*
 * master_get_active_worker_nodes returns a set of active worker host names and
 * port numbers in deterministic order. Currently we assume that all worker
 * nodes in pg_worker_list.conf are active.
 */
Datum
master_get_active_worker_nodes(PG_FUNCTION_ARGS)
{
	FuncCallContext *functionContext = NULL;
	uint32 workerNodeIndex = 0;
	uint32 workerNodeCount = 0;

	if (SRF_IS_FIRSTCALL())
	{
		MemoryContext oldContext = NULL;
		List *workerNodeList = NIL;
		uint32 workerNodeCount = 0;
		TupleDesc tupleDescriptor = NULL;
		bool hasOid = false;

		/* create a function context for cross-call persistence */
		functionContext = SRF_FIRSTCALL_INIT();

		/* switch to memory context appropriate for multiple function calls */
		oldContext = MemoryContextSwitchTo(functionContext->multi_call_memory_ctx);

		workerNodeList = WorkerNodeList();
		workerNodeCount = (uint32) list_length(workerNodeList);

		functionContext->user_fctx = workerNodeList;
		functionContext->max_calls = workerNodeCount;

		/*
		 * This tuple descriptor must match the output parameters declared for
		 * the function in pg_proc.
		 */
		tupleDescriptor = CreateTemplateTupleDesc(WORKER_NODE_FIELDS, hasOid);
		TupleDescInitEntry(tupleDescriptor, (AttrNumber) 1, "node_name",
						   TEXTOID, -1, 0);
		TupleDescInitEntry(tupleDescriptor, (AttrNumber) 2, "node_port",
						   INT8OID, -1, 0);

		functionContext->tuple_desc = BlessTupleDesc(tupleDescriptor);

		MemoryContextSwitchTo(oldContext);
	}

	functionContext = SRF_PERCALL_SETUP();
	workerNodeIndex = functionContext->call_cntr;
	workerNodeCount = functionContext->max_calls;

	if (workerNodeIndex < workerNodeCount)
	{
		List *workerNodeList = functionContext->user_fctx;
		WorkerNode *workerNode = list_nth(workerNodeList, workerNodeIndex);

		Datum workerNodeDatum = WorkerNodeGetDatum(workerNode,
												   functionContext->tuple_desc);

		SRF_RETURN_NEXT(functionContext, workerNodeDatum);
	}
	else
	{
		SRF_RETURN_DONE(functionContext);
	}
}
開發者ID:amosbird,項目名稱:citus,代碼行數:66,代碼來源:master_node_protocol.c

示例15: compute_driving_distance


//.........這裏部分代碼省略.........
  int                  max_calls;
  TupleDesc            tuple_desc;
  path_element_t      *path = 0;

  /* stuff done only on the first call of the function */
  if (SRF_IS_FIRSTCALL()) {
    MemoryContext   oldcontext;
    int path_count = 0;
    int ret;
    
    // XXX profiling messages are not thread safe
    profstart(prof_total);
    profstart(prof_extract);
    
    /* create a function context for cross-call persistence */
    funcctx = SRF_FIRSTCALL_INIT();
    
    /* switch to memory context appropriate for multiple function calls */
    oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
    
    ret = compute_driving_distance(text2char(PG_GETARG_TEXT_P(0)), // sql
                                PG_GETARG_INT32(1),   // source vertex
                                PG_GETARG_FLOAT8(2),  // distance or time
                                PG_GETARG_BOOL(3),
                                PG_GETARG_BOOL(4), &path, &path_count);
    if (ret < 0) {
        elog(ERROR, "Error computing path");
    } 
    

#ifdef DEBUG
    DBG("Ret is %i", ret);
    int i;
    for (i = 0; i < path_count; i++) {
        DBG("Step %i vertex_id  %i ", i, path[i].vertex_id);
        DBG("        edge_id    %i ", path[i].edge_id);
        DBG("        cost       %f ", path[i].cost);
    }
#endif

    /* total number of tuples to be returned */
    funcctx->max_calls = path_count;
    funcctx->user_fctx = path;

    funcctx->tuple_desc = BlessTupleDesc(
                             RelationNameGetTupleDesc("pgr_costResult"));
    
    MemoryContextSwitchTo(oldcontext);
  }
  
  /* stuff done on every call of the function */
  funcctx = SRF_PERCALL_SETUP();

  call_cntr = funcctx->call_cntr;
  max_calls = funcctx->max_calls;
  tuple_desc = funcctx->tuple_desc;
  path = (path_element_t*) funcctx->user_fctx;
  
  if (call_cntr < max_calls) {   /* do when there is more left to send */
    HeapTuple    tuple;
    Datum        result;
    Datum *values;
    char* nulls;
    
    values = palloc(4 * sizeof(Datum));
    nulls = palloc(4 * sizeof(char));

    values[0] = Int32GetDatum(call_cntr);
    nulls[0] = ' ';
    values[1] = Int32GetDatum(path[call_cntr].vertex_id);
    nulls[1] = ' ';
    values[2] = Int32GetDatum(path[call_cntr].edge_id);
    nulls[2] = ' ';
    values[3] = Float8GetDatum(path[call_cntr].cost);
    nulls[3] = ' ';
      
    tuple = heap_formtuple(tuple_desc, values, nulls);
    

    /* make the tuple into a datum */
    result = HeapTupleGetDatum(tuple);
    
    /* clean up (this is not really necessary) */
    pfree(values);
    pfree(nulls);

    SRF_RETURN_NEXT(funcctx, result);
  }
  else {    /* do when there is no more left */
    if (path) free(path);
    profstop("store", prof_store);
    profstop("total", prof_total);
#ifdef PROFILE
    elog(NOTICE, "_________");
#endif
    DBG("Returning value");

    SRF_RETURN_DONE(funcctx);
  }
}
開發者ID:CCheng1231,項目名稱:pgrouting,代碼行數:101,代碼來源:drivedist.c


注:本文中的BlessTupleDesc函數示例由純淨天空整理自Github/MSDocs等開源代碼及文檔管理平台,相關代碼片段篩選自各路編程大神貢獻的開源項目,源碼版權歸原作者所有,傳播和使用請參考對應項目的License;未經允許,請勿轉載。