Example #1
0
/*
 * Logic for set-returning functions.
 *
 * Currently it uses the simplest, return
 * one value/tuple per call mechanism.
 */
static Datum
handle_ret_set(FunctionCallInfo fcinfo)
{
	ProxyFunction *func;
	FuncCallContext *ret_ctx;

	if (SRF_IS_FIRSTCALL())
	{
		func = compile_and_execute(fcinfo);
		ret_ctx = SRF_FIRSTCALL_INIT();
		ret_ctx->user_fctx = func;
	}

	ret_ctx = SRF_PERCALL_SETUP();
	func = ret_ctx->user_fctx;

	if (func->cur_cluster->ret_total > 0)
	{
		SRF_RETURN_NEXT(ret_ctx, plproxy_result(func, fcinfo));
	}
	else
	{
		plproxy_clean_results(func->cur_cluster);
		SRF_RETURN_DONE(ret_ctx);
	}
}
Example #2
0
Datum
skeys(PG_FUNCTION_ARGS)
{
	FuncCallContext *funcctx;
	AKStore    *st;

	if (SRF_IS_FIRSTCALL())
	{
		HStore	   *hs = PG_GETARG_HS(0);

		funcctx = SRF_FIRSTCALL_INIT();
		setup_firstcall(funcctx, hs);
		PG_FREE_IF_COPY(hs, 0);
	}

	funcctx = SRF_PERCALL_SETUP();
	st = (AKStore *) funcctx->user_fctx;

	if (st->i < st->hs->size)
	{
		HEntry	   *ptr = &(ARRPTR(st->hs)[st->i]);
		text	   *item = (text *) palloc(VARHDRSZ + ptr->keylen);

		SET_VARSIZE(item, VARHDRSZ + ptr->keylen);
		memcpy(VARDATA(item), STRPTR(st->hs) + ptr->pos, ptr->keylen);
		st->i++;

		SRF_RETURN_NEXT(funcctx, PointerGetDatum(item));
	}

	pfree(st->hs);
	pfree(st);

	SRF_RETURN_DONE(funcctx);
}
Datum
hstore_skeys(PG_FUNCTION_ARGS)
{
    FuncCallContext *funcctx;
    HStore	   *hs;
    int			i;

    if (SRF_IS_FIRSTCALL())
    {
        hs = PG_GETARG_HS(0);
        funcctx = SRF_FIRSTCALL_INIT();
        setup_firstcall(funcctx, hs, NULL);
    }

    funcctx = SRF_PERCALL_SETUP();
    hs = (HStore *) funcctx->user_fctx;
    i = funcctx->call_cntr;

    if (i < HS_COUNT(hs))
    {
        HEntry	   *entries = ARRPTR(hs);
        text	   *item;

        item = cstring_to_text_with_len(HS_KEY(entries, STRPTR(hs), i),
                                        HS_KEYLEN(entries, i));

        SRF_RETURN_NEXT(funcctx, PointerGetDatum(item));
    }

    SRF_RETURN_DONE(funcctx);
}
Example #4
0
/*
 * txid_snapshot_xip(txid_snapshot) returns setof int8
 *
 *		return in-progress TXIDs in snapshot.
 */
Datum
txid_snapshot_xip(PG_FUNCTION_ARGS)
{
	FuncCallContext *fctx;
	TxidSnapshot *snap;
	txid		value;

	/* on first call initialize snap_state and get copy of snapshot */
	if (SRF_IS_FIRSTCALL())
	{
		TxidSnapshot *arg = (TxidSnapshot *) PG_GETARG_VARLENA_P(0);

		fctx = SRF_FIRSTCALL_INIT();

		/* make a copy of user snapshot */
		snap = MemoryContextAlloc(fctx->multi_call_memory_ctx, VARSIZE(arg));
		memcpy(snap, arg, VARSIZE(arg));

		fctx->user_fctx = snap;
	}

	/* return values one-by-one */
	fctx = SRF_PERCALL_SETUP();
	snap = fctx->user_fctx;
	if (fctx->call_cntr < snap->nxip)
	{
		value = snap->xip[fctx->call_cntr];
		SRF_RETURN_NEXT(fctx, Int64GetDatum(value));
	}
	else
	{
		SRF_RETURN_DONE(fctx);
	}
}
Example #5
0
/*
 * Return the TIDs of not-all-visible tuples in pages marked all-visible
 * in the visibility map.  We hope no one will ever find any, but there could
 * be bugs, database corruption, etc.
 */
Datum
pg_check_visible(PG_FUNCTION_ARGS)
{
    FuncCallContext *funcctx;
    corrupt_items *items;

    if (SRF_IS_FIRSTCALL())
    {
        Oid			relid = PG_GETARG_OID(0);
        MemoryContext oldcontext;

        funcctx = SRF_FIRSTCALL_INIT();
        oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
        funcctx->user_fctx = collect_corrupt_items(relid, true, false);
        MemoryContextSwitchTo(oldcontext);
    }

    funcctx = SRF_PERCALL_SETUP();
    items = (corrupt_items *) funcctx->user_fctx;

    if (items->next < items->count)
        SRF_RETURN_NEXT(funcctx, PointerGetDatum(&items->tids[items->next++]));

    SRF_RETURN_DONE(funcctx);
}
Example #6
0
Datum
ts_stat2(PG_FUNCTION_ARGS)
{
	FuncCallContext *funcctx;
	Datum		result;

	if (SRF_IS_FIRSTCALL())
	{
		TSVectorStat *stat;
		text	   *txt = PG_GETARG_TEXT_P(0);
		text	   *ws = PG_GETARG_TEXT_P(1);

		funcctx = SRF_FIRSTCALL_INIT();
		SPI_connect();
		stat = ts_stat_sql(funcctx->multi_call_memory_ctx, txt, ws);
		PG_FREE_IF_COPY(txt, 0);
		PG_FREE_IF_COPY(ws, 1);
		ts_setup_firstcall(fcinfo, funcctx, stat);
		SPI_finish();
	}

	funcctx = SRF_PERCALL_SETUP();
	if ((result = ts_process_call(funcctx)) != (Datum) 0)
		SRF_RETURN_NEXT(funcctx, result);
	SRF_RETURN_DONE(funcctx);
}
Example #7
0
Datum
get_next_row(FunctionCallInfo fcinfo)
{
    PlxResult       *plx_result;
    FuncCallContext *funcctx;
    int              call_cntr;

    plx_result = get_plx_result_or_due(fcinfo);
    /* code below will be never executed if pg_result not find */
    if (SRF_IS_FIRSTCALL())
    {
        funcctx = SRF_FIRSTCALL_INIT();
        funcctx->max_calls = PQntuples(plx_result->pg_result);
    }
    funcctx = SRF_PERCALL_SETUP();
    call_cntr = funcctx->call_cntr;
    if (call_cntr < funcctx->max_calls)
        SRF_RETURN_NEXT(funcctx, get_row(fcinfo, plx_result, call_cntr));
    else
    {
        plx_result_cache_delete(fcinfo);
        PQclear(plx_result->pg_result);
        pfree(plx_result);
        SRF_RETURN_DONE(funcctx);
    }
}
Example #8
0
/*
 * master_get_table_ddl_events takes in a relation name, and returns the set of
 * DDL commands needed to reconstruct the relation. The returned DDL commands
 * are similar in flavor to schema definitions that pgdump returns. The function
 * errors if given relation does not exist.
 */
Datum
master_get_table_ddl_events(PG_FUNCTION_ARGS)
{
	FuncCallContext *functionContext = NULL;
	ListCell *tableDDLEventCell = NULL;

	/*
	 * On the very first call to this function, we first use the given relation
	 * name to get to the relation. We then recreate the list of DDL statements
	 * issued for this relation, and save the first statement's position in the
	 * function context.
	 */
	if (SRF_IS_FIRSTCALL())
	{
		text *relationName = PG_GETARG_TEXT_P(0);
		Oid relationId = ResolveRelationId(relationName);

		MemoryContext oldContext = NULL;
		List *tableDDLEventList = NIL;

		/* 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);

		/* allocate DDL statements, and then save position in DDL statements */
		tableDDLEventList = GetTableDDLEvents(relationId);
		tableDDLEventCell = list_head(tableDDLEventList);

		functionContext->user_fctx = tableDDLEventCell;

		MemoryContextSwitchTo(oldContext);
	}

	/*
	 * On every call to this function, we get the current position in the
	 * statement list. We then iterate to the next position in the list and
	 * return the current statement, if we have not yet reached the end of
	 * list.
	 */
	functionContext = SRF_PERCALL_SETUP();

	tableDDLEventCell = (ListCell *) functionContext->user_fctx;
	if (tableDDLEventCell != NULL)
	{
		char *ddlStatement = (char *) lfirst(tableDDLEventCell);
		text *ddlStatementText = cstring_to_text(ddlStatement);

		functionContext->user_fctx = lnext(tableDDLEventCell);

		SRF_RETURN_NEXT(functionContext, PointerGetDatum(ddlStatementText));
	}
	else
	{
		SRF_RETURN_DONE(functionContext);
	}
}
/*
 * gp_partition_inverse
 *   Returns all child partition oids with their constraints for a given parent oid.
 *
 * Currently, this function assumes that the parent partition is the root partition.
 *
 * This function is a set-returning function.
 */
Datum
gp_partition_inverse(PG_FUNCTION_ARGS)
{
	FuncCallContext *funcCallContext = NULL;
	InverseContext *inverseContext = NULL;
	
	/*
	 * Setup the function call context for set-returning functions.
	 * At the first time of calling this function, we create and initialize
	 * necessary context data in inverseContext, such as finding the partition
	 * metadata for the given parent oid.
	 */
	if (SRF_IS_FIRSTCALL())
	{
		funcCallContext = SRF_FIRSTCALL_INIT();

		Oid parentOid = PG_GETARG_OID(0);

		MemoryContext oldContext = MemoryContextSwitchTo(funcCallContext->multi_call_memory_ctx);

		funcCallContext->user_fctx = createInverseContext(parentOid);
		inverseContext = (InverseContext *)funcCallContext->user_fctx;

		Assert(NULL != inverseContext);
		Assert(NULL != inverseContext->partitionIterator);
		Assert(NULL != inverseContext->partitionIterator->partsAndRules);

		Partition *part = inverseContext->partitionIterator->partsAndRules->part;
		Assert(NULL != part);

		Oid typeOid = 0;
		int32 typeMod = 0;
		findPartitionKeyType(parentOid, part->paratts[0], &typeOid, &typeMod);

		TupleDesc tupleDesc = createInverseTupleDesc(typeOid, typeMod);
		funcCallContext->tuple_desc = BlessTupleDesc(tupleDesc);

		MemoryContextSwitchTo(oldContext);
	}
	funcCallContext = SRF_PERCALL_SETUP();

	inverseContext = (InverseContext *)funcCallContext->user_fctx;
	Assert(inverseContext != NULL &&
		   inverseContext->partitionIterator != NULL);

	if (inverseContext->findNextRecord(inverseContext))
	{
		HeapTuple tuple = heap_form_tuple(funcCallContext->tuple_desc,
										  inverseContext->values,
										  inverseContext->nulls);
		Datum result = HeapTupleGetDatum(tuple);
		SRF_RETURN_NEXT(funcCallContext, result);
	}
	
	freeInverseContext(inverseContext);

	SRF_RETURN_DONE(funcCallContext);
}
Example #10
0
/*
 * List a directory (returns the filenames only)
 */
Datum
pg_ls_dir(PG_FUNCTION_ARGS)
{
	FuncCallContext *funcctx;
	struct dirent *de;
	directory_fctx *fctx;

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

	if (SRF_IS_FIRSTCALL())
	{
		MemoryContext oldcontext;

		funcctx = SRF_FIRSTCALL_INIT();
		oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);

		fctx = palloc(sizeof(directory_fctx));
		fctx->location = convert_and_check_filename(PG_GETARG_TEXT_P(0));

		fctx->dirdesc = AllocateDir(fctx->location);

		if (!fctx->dirdesc)
			ereport(ERROR,
					(errcode_for_file_access(),
					 errmsg("could not open directory \"%s\": %m",
							fctx->location)));

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

	funcctx = SRF_PERCALL_SETUP();
	fctx = (directory_fctx *) funcctx->user_fctx;

	while ((de = ReadDir(fctx->dirdesc, fctx->location)) != NULL)
	{
		int			len = strlen(de->d_name);
		text	   *result;

		if (strcmp(de->d_name, ".") == 0 ||
			strcmp(de->d_name, "..") == 0)
			continue;

		result = palloc(len + VARHDRSZ);
		SET_VARSIZE(result, len + VARHDRSZ);
		memcpy(VARDATA(result), de->d_name, len);

		SRF_RETURN_NEXT(funcctx, PointerGetDatum(result));
	}

	FreeDir(fctx->dirdesc);

	SRF_RETURN_DONE(funcctx);
}
Datum
hstore_each(PG_FUNCTION_ARGS)
{
    FuncCallContext *funcctx;
    HStore	   *hs;
    int			i;

    if (SRF_IS_FIRSTCALL())
    {
        hs = PG_GETARG_HS(0);
        funcctx = SRF_FIRSTCALL_INIT();
        setup_firstcall(funcctx, hs, fcinfo);
    }

    funcctx = SRF_PERCALL_SETUP();
    hs = (HStore *) funcctx->user_fctx;
    i = funcctx->call_cntr;

    if (i < HS_COUNT(hs))
    {
        HEntry	   *entries = ARRPTR(hs);
        char	   *ptr = STRPTR(hs);
        Datum		res,
                    dvalues[2];
        bool		nulls[2] = {false, false};
        text	   *item;
        HeapTuple	tuple;

        item = cstring_to_text_with_len(HS_KEY(entries, ptr, i),
                                        HS_KEYLEN(entries, i));
        dvalues[0] = PointerGetDatum(item);

        if (HS_VALISNULL(entries, i))
        {
            dvalues[1] = (Datum) 0;
            nulls[1] = true;
        }
        else
        {
            item = cstring_to_text_with_len(HS_VAL(entries, ptr, i),
                                            HS_VALLEN(entries, i));
            dvalues[1] = PointerGetDatum(item);
        }

        tuple = heap_form_tuple(funcctx->tuple_desc, dvalues, nulls);
        res = HeapTupleGetDatum(tuple);

        SRF_RETURN_NEXT(funcctx, PointerGetDatum(res));
    }

    SRF_RETURN_DONE(funcctx);
}
Example #12
0
/*
 * pgstrom_debug_info
 *
 * shows user's debug information
 */
Datum
pgstrom_debug_info(PG_FUNCTION_ARGS)
{
	FuncCallContext	   *fncxt;
	MemoryContext		oldcxt;
	ListCell   *cell;
	DefElem	   *defel;
	Datum		values[2];
	bool		isnull[2];
	HeapTuple	tuple;

	if (SRF_IS_FIRSTCALL())
	{
		TupleDesc	tupdesc;
		List	   *debug_info_list = NIL;

		fncxt = SRF_FIRSTCALL_INIT();

		oldcxt = MemoryContextSwitchTo(fncxt->multi_call_memory_ctx);

		tupdesc = CreateTemplateTupleDesc(2, false);
		TupleDescInitEntry(tupdesc, (AttrNumber) 1, "key",
						   TEXTOID, -1, 0);
		TupleDescInitEntry(tupdesc, (AttrNumber) 2, "value",
						   TEXTOID, -1, 0);

		debug_info_list = pgstrom_scan_debug_info(debug_info_list);

		fncxt->user_fctx = (void *) debug_info_list;
		fncxt->tuple_desc = BlessTupleDesc(tupdesc);

		MemoryContextSwitchTo(oldcxt);
	}
	fncxt = SRF_PERCALL_SETUP();
	cell = list_head((List *)fncxt->user_fctx);
	if (!cell)
		SRF_RETURN_DONE(fncxt);

	defel = lfirst(cell);
	Assert(IsA(defel, DefElem));

	memset(isnull, false, sizeof(isnull));
	values[0] = CStringGetTextDatum(defel->defname);
	values[1] = CStringGetTextDatum(strVal(defel->arg));

	tuple = heap_form_tuple(fncxt->tuple_desc, values, isnull);

	fncxt->user_fctx = list_delete_ptr((List *)fncxt->user_fctx,
									   lfirst(cell));
	SRF_RETURN_NEXT(fncxt, HeapTupleGetDatum(tuple));
}
Example #13
0
Datum
svals(PG_FUNCTION_ARGS)
{
	FuncCallContext *funcctx;
	AKStore    *st;

	if (SRF_IS_FIRSTCALL())
	{
		HStore	   *hs = PG_GETARG_HS(0);

		funcctx = SRF_FIRSTCALL_INIT();
		setup_firstcall(funcctx, hs);
		PG_FREE_IF_COPY(hs, 0);
	}

	funcctx = SRF_PERCALL_SETUP();
	st = (AKStore *) funcctx->user_fctx;

	if (st->i < st->hs->size)
	{
		HEntry	   *ptr = &(ARRPTR(st->hs)[st->i]);

		if (ptr->valisnull)
		{
			ReturnSetInfo *rsi;

			st->i++;
			(funcctx)->call_cntr++;
			rsi = (ReturnSetInfo *) fcinfo->resultinfo;
			rsi->isDone = ExprMultipleResult;
			PG_RETURN_NULL();
		}
		else
		{
			int			vallen = ptr->vallen;
			text	   *item = (text *) palloc(VARHDRSZ + vallen);

			SET_VARSIZE(item, VARHDRSZ + vallen);
			memcpy(VARDATA(item), STRPTR(st->hs) + ptr->pos + ptr->keylen, vallen);
			st->i++;

			SRF_RETURN_NEXT(funcctx, PointerGetDatum(item));
		}
	}

	pfree(st->hs);
	pfree(st);

	SRF_RETURN_DONE(funcctx);
}
Example #14
0
/*
 * Return the TID array stored in a BRIN revmap page
 */
Datum
brin_revmap_data(PG_FUNCTION_ARGS)
{
    struct
    {
        ItemPointerData *tids;
        int			idx;
    }		   *state;
    FuncCallContext *fctx;

    if (!superuser())
        ereport(ERROR,
                (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
                 (errmsg("must be superuser to use raw page functions"))));

    if (SRF_IS_FIRSTCALL())
    {
        bytea	   *raw_page = PG_GETARG_BYTEA_P(0);
        MemoryContext mctx;
        Page		page;

        /* minimally verify the page we got */
        page = verify_brin_page(raw_page, BRIN_PAGETYPE_REVMAP, "revmap");

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

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

        state = palloc(sizeof(*state));
        state->tids = ((RevmapContents *) PageGetContents(page))->rm_tids;
        state->idx = 0;

        fctx->user_fctx = state;

        MemoryContextSwitchTo(mctx);
    }

    fctx = SRF_PERCALL_SETUP();
    state = fctx->user_fctx;

    if (state->idx < REVMAP_PAGE_MAXITEMS)
        SRF_RETURN_NEXT(fctx, PointerGetDatum(&state->tids[state->idx++]));

    SRF_RETURN_DONE(fctx);
}
Example #15
0
/*
 * Returns Oids of tables in a publication.
 */
Datum
pg_get_publication_tables(PG_FUNCTION_ARGS)
{
	FuncCallContext *funcctx;
	char	   *pubname = text_to_cstring(PG_GETARG_TEXT_PP(0));
	Publication *publication;
	List	   *tables;
	ListCell  **lcp;

	/* stuff done only on the first call of the function */
	if (SRF_IS_FIRSTCALL())
	{
		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);

		publication = GetPublicationByName(pubname, false);
		if (publication->alltables)
			tables = GetAllTablesPublicationRelations();
		else
			tables = GetPublicationRelations(publication->oid);
		lcp = (ListCell **) palloc(sizeof(ListCell *));
		*lcp = list_head(tables);
		funcctx->user_fctx = (void *) lcp;

		MemoryContextSwitchTo(oldcontext);
	}

	/* stuff done on every call of the function */
	funcctx = SRF_PERCALL_SETUP();
	lcp = (ListCell **) funcctx->user_fctx;

	while (*lcp != NULL)
	{
		Oid			relid = lfirst_oid(*lcp);

		*lcp = lnext(*lcp);
		SRF_RETURN_NEXT(funcctx, ObjectIdGetDatum(relid));
	}

	SRF_RETURN_DONE(funcctx);
}
Example #16
0
/*
 * regexp_matches()
 *		Return a table of matches of a pattern within a string.
 */
Datum
regexp_matches(PG_FUNCTION_ARGS)
{
	FuncCallContext *funcctx;
	regexp_matches_ctx *matchctx;

	if (SRF_IS_FIRSTCALL())
	{
		text	   *pattern = PG_GETARG_TEXT_PP(1);
		text	   *flags = PG_GETARG_TEXT_PP_IF_EXISTS(2);
		MemoryContext oldcontext;

		funcctx = SRF_FIRSTCALL_INIT();
		oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);

		/* be sure to copy the input string into the multi-call ctx */
		matchctx = setup_regexp_matches(PG_GETARG_TEXT_P_COPY(0), pattern,
										flags,
										PG_GET_COLLATION(),
										false, true, false);

		/* Pre-create workspace that build_regexp_matches_result needs */
		matchctx->elems = (Datum *) palloc(sizeof(Datum) * matchctx->npatterns);
		matchctx->nulls = (bool *) palloc(sizeof(bool) * matchctx->npatterns);

		MemoryContextSwitchTo(oldcontext);
		funcctx->user_fctx = (void *) matchctx;
	}

	funcctx = SRF_PERCALL_SETUP();
	matchctx = (regexp_matches_ctx *) funcctx->user_fctx;

	if (matchctx->next_match < matchctx->nmatches)
	{
		ArrayType  *result_ary;

		result_ary = build_regexp_matches_result(matchctx);
		matchctx->next_match++;
		SRF_RETURN_NEXT(funcctx, PointerGetDatum(result_ary));
	}

	/* release space in multi-call ctx to avoid intraquery memory leak */
	cleanup_regexp_matches(matchctx);

	SRF_RETURN_DONE(funcctx);
}
Example #17
0
Datum
pg_dirtyread(PG_FUNCTION_ARGS)
{
    FuncCallContext     *funcctx;
    MemoryContext       oldcontext;
    pg_dirtyread_ctx    *usr_ctx;
    Oid                 relid;
    HeapTuple           tuplein, tupleout;
    TupleDesc           tupdesc;

    if (SRF_IS_FIRSTCALL())
    {
        relid = PG_GETARG_OID(0);

        if (OidIsValid(relid))
        {
            funcctx = SRF_FIRSTCALL_INIT();
            oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
            usr_ctx = (pg_dirtyread_ctx *) palloc(sizeof(pg_dirtyread_ctx));
            usr_ctx->rel = heap_open(relid, AccessShareLock);
            usr_ctx->reltupdesc = RelationGetDescr(usr_ctx->rel);
            get_call_result_type(fcinfo, NULL, &tupdesc);
            funcctx->tuple_desc = BlessTupleDesc(tupdesc);
            usr_ctx->map = convert_tuples_by_position(usr_ctx->reltupdesc, funcctx->tuple_desc, "Error converting tuple descriptors!");
            usr_ctx->scan = heap_beginscan(usr_ctx->rel, SnapshotAny, 0, NULL);
            funcctx->user_fctx = (void *) usr_ctx;
            MemoryContextSwitchTo(oldcontext);
        }
    }

    funcctx = SRF_PERCALL_SETUP();
    usr_ctx = (pg_dirtyread_ctx *) funcctx->user_fctx;

    if ((tuplein = heap_getnext(usr_ctx->scan, ForwardScanDirection)) != NULL)
    {
        tupleout = do_convert_tuple(tuplein, usr_ctx->map);
        SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tupleout));
    }
    else
    {
        heap_endscan(usr_ctx->scan);
        heap_close(usr_ctx->rel, AccessShareLock);
        SRF_RETURN_DONE(funcctx);
    }
}
Datum
hstore_svals(PG_FUNCTION_ARGS)
{
    FuncCallContext *funcctx;
    HStore	   *hs;
    int			i;

    if (SRF_IS_FIRSTCALL())
    {
        hs = PG_GETARG_HS(0);
        funcctx = SRF_FIRSTCALL_INIT();
        setup_firstcall(funcctx, hs, NULL);
    }

    funcctx = SRF_PERCALL_SETUP();
    hs = (HStore *) funcctx->user_fctx;
    i = funcctx->call_cntr;

    if (i < HS_COUNT(hs))
    {
        HEntry	   *entries = ARRPTR(hs);

        if (HS_VALISNULL(entries, i))
        {
            ReturnSetInfo *rsi;

            /* ugly ugly ugly. why no macro for this? */
            (funcctx)->call_cntr++;
            rsi = (ReturnSetInfo *) fcinfo->resultinfo;
            rsi->isDone = ExprMultipleResult;
            PG_RETURN_NULL();
        }
        else
        {
            text	   *item;

            item = cstring_to_text_with_len(HS_VAL(entries, STRPTR(hs), i),
                                            HS_VALLEN(entries, i));

            SRF_RETURN_NEXT(funcctx, PointerGetDatum(item));
        }
    }

    SRF_RETURN_DONE(funcctx);
}
Example #19
0
Datum
ts_token_type_byid(PG_FUNCTION_ARGS)
{
	FuncCallContext *funcctx;
	Datum		result;

	if (SRF_IS_FIRSTCALL())
	{
		funcctx = SRF_FIRSTCALL_INIT();
		tt_setup_firstcall(funcctx, PG_GETARG_OID(0));
	}

	funcctx = SRF_PERCALL_SETUP();

	if ((result = tt_process_call(funcctx)) != (Datum) 0)
		SRF_RETURN_NEXT(funcctx, result);
	SRF_RETURN_DONE(funcctx);
}
Example #20
0
Datum
testfunc5(PG_FUNCTION_ARGS)
{
    int64 i = PG_GETARG_INT64(0);
    FuncCallContext *funcctx;
    MemoryContext oldcontext;
    if (SRF_IS_FIRSTCALL())
    {
        TupleDesc tupd;
        funcctx = SRF_FIRSTCALL_INIT();
        oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
        tupd = CreateTemplateTupleDesc(2, false);
        TupleDescInitEntry(tupd, 1, "c1", INT8OID, -1, 0);
        TupleDescInitEntry(tupd, 2, "c2", INT8OID, -1, 0);
        funcctx->max_calls = 3;
        funcctx->user_fctx = tupd;
        MemoryContextSwitchTo(oldcontext);
    }
    funcctx = SRF_PERCALL_SETUP();
    if (funcctx->call_cntr < funcctx->max_calls)
    {
        TupleDesc tupd;
        HeapTupleData tupleData;
        HeapTuple tuple = &tupleData;
        char *values[2];
        Datum result;
        
        tupd = (TupleDesc)funcctx->user_fctx;
         values[0] = palloc(32);
        sprintf(values[0], INT64_FORMAT, i+1+funcctx->call_cntr);
        values[1] = palloc(32);
        sprintf(values[1], INT64_FORMAT, i+2+funcctx->call_cntr);
        tuple = BuildTupleFromCStrings(TupleDescGetAttInMetadata(tupd), values);
        result = TupleGetDatum(TupleDescGetSlot(tuple), tuple);
        
        SRF_RETURN_NEXT(funcctx, result);
    }
    else
    {
        SRF_RETURN_DONE(funcctx);
    }
}
Example #21
0
/*
 * Visibility map information for every block in a relation, plus the page
 * level information for each block.
 */
Datum
pg_visibility_rel(PG_FUNCTION_ARGS)
{
	FuncCallContext *funcctx;
	vbits	   *info;

	if (SRF_IS_FIRSTCALL())
	{
		Oid			relid = PG_GETARG_OID(0);
		MemoryContext oldcontext;

		funcctx = SRF_FIRSTCALL_INIT();
		oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
		funcctx->tuple_desc = pg_visibility_tupdesc(true, true);
		/* collect_visibility_data will verify the relkind */
		funcctx->user_fctx = collect_visibility_data(relid, true);
		MemoryContextSwitchTo(oldcontext);
	}

	funcctx = SRF_PERCALL_SETUP();
	info = (vbits *) funcctx->user_fctx;

	if (info->next < info->count)
	{
		Datum		values[4];
		bool		nulls[4];
		HeapTuple	tuple;

		MemSet(nulls, 0, sizeof(nulls));
		values[0] = Int64GetDatum(info->next);
		values[1] = BoolGetDatum((info->bits[info->next] & (1 << 0)) != 0);
		values[2] = BoolGetDatum((info->bits[info->next] & (1 << 1)) != 0);
		values[3] = BoolGetDatum((info->bits[info->next] & (1 << 2)) != 0);
		info->next++;

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

	SRF_RETURN_DONE(funcctx);
}
Example #22
0
/*
 * regexp_split_to_table()
 *		Split the string at matches of the pattern, returning the
 *		split-out substrings as a table.
 */
Datum
regexp_split_to_table(PG_FUNCTION_ARGS)
{
	FuncCallContext *funcctx;
	regexp_matches_ctx *splitctx;

	if (SRF_IS_FIRSTCALL())
	{
		text	   *pattern = PG_GETARG_TEXT_PP(1);
		text	   *flags = PG_GETARG_TEXT_PP_IF_EXISTS(2);
		MemoryContext oldcontext;

		funcctx = SRF_FIRSTCALL_INIT();
		oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);

		/* be sure to copy the input string into the multi-call ctx */
		splitctx = setup_regexp_matches(PG_GETARG_TEXT_P_COPY(0), pattern,
										flags,
										PG_GET_COLLATION(),
										true, false, true);

		MemoryContextSwitchTo(oldcontext);
		funcctx->user_fctx = (void *) splitctx;
	}

	funcctx = SRF_PERCALL_SETUP();
	splitctx = (regexp_matches_ctx *) funcctx->user_fctx;

	if (splitctx->next_match <= splitctx->nmatches)
	{
		Datum		result = build_regexp_split_result(splitctx);

		splitctx->next_match++;
		SRF_RETURN_NEXT(funcctx, result);
	}

	/* release space in multi-call ctx to avoid intraquery memory leak */
	cleanup_regexp_matches(splitctx);

	SRF_RETURN_DONE(funcctx);
}
Example #23
0
/*
 * regexp_matches()
 *		Return a table of matches of a pattern within a string.
 */
datum_t regexp_matches(PG_FUNC_ARGS)
{
	struct fcall_ctx *funcctx;
	regexp_matches_ctx *matchctx;

	if (SRF_IS_FIRSTCALL()) {
		text *pattern = ARG_TEXT_PP(1);
		text *flags = ARG_TEXT_PP_IF_EXISTS(2);
		struct mctx * oldcontext;

		funcctx = SRF_FIRSTCALL_INIT();
		oldcontext = mctx_switch(funcctx->multi_call_memory_ctx);

		/* be sure to copy the input string into the multi-call ctx */
		matchctx = setup_regexp_matches(ARG_TEXT_P_COPY(0), pattern,
			flags, PG_COLLATION(), false, true, false);

		/* Pre-create workspace that build_regexp_matches_result needs */
		matchctx->elems = (datum_t *) palloc(sizeof(datum_t) * matchctx->npatterns);
		matchctx->nulls = (bool *) palloc(sizeof(bool) * matchctx->npatterns);

		mctx_switch(oldcontext);
		funcctx->user_fctx = (void *)matchctx;
	}

	funcctx = SRF_PERCALL_SETUP();
	matchctx = (regexp_matches_ctx *) funcctx->user_fctx;

	if (matchctx->next_match < matchctx->nmatches) {
		array_s *result_ary;

		result_ary = build_regexp_matches_result(matchctx);
		matchctx->next_match++;
		SRF_RETURN_NEXT(funcctx, PTR_TO_D(result_ary));
	}

	/* release space in multi-call ctx to avoid intraquery memory leak */
	cleanup_regexp_matches(matchctx);

	SRF_RETURN_DONE(funcctx);
}
Example #24
0
Datum
ts_parse_byid(PG_FUNCTION_ARGS)
{
	FuncCallContext *funcctx;
	Datum		result;

	if (SRF_IS_FIRSTCALL())
	{
		text	   *txt = PG_GETARG_TEXT_P(1);

		funcctx = SRF_FIRSTCALL_INIT();
		prs_setup_firstcall(funcctx, PG_GETARG_OID(0), txt);
		PG_FREE_IF_COPY(txt, 1);
	}

	funcctx = SRF_PERCALL_SETUP();

	if ((result = prs_process_call(funcctx)) != (Datum) 0)
		SRF_RETURN_NEXT(funcctx, result);
	SRF_RETURN_DONE(funcctx);
}
Example #25
0
Datum
token_type_current(PG_FUNCTION_ARGS)
{
	FuncCallContext *funcctx;
	Datum		result;

	SET_FUNCOID();
	if (SRF_IS_FIRSTCALL())
	{
		funcctx = SRF_FIRSTCALL_INIT();
		if (current_parser_id == InvalidOid)
			current_parser_id = name2id_prs(char2text("default"));
		setup_firstcall(fcinfo, funcctx, current_parser_id);
	}

	funcctx = SRF_PERCALL_SETUP();

	if ((result = process_call(funcctx)) != (Datum) 0)
		SRF_RETURN_NEXT(funcctx, result);
	SRF_RETURN_DONE(funcctx);
}
Example #26
0
Datum domainname_parents(PG_FUNCTION_ARGS)
{
	FuncCallContext *funcctx;
	text *in = PG_GETARG_TEXT_P(0);
	const char *s = VARDATA(in);
	const char *p = s, *e = s + VARSIZE_ANY_EXHDR(in);
	unsigned i;

	if (SRF_IS_FIRSTCALL())
		funcctx = SRF_FIRSTCALL_INIT();

	funcctx = SRF_PERCALL_SETUP();

	for (i = 0; i < funcctx->call_cntr && ++p < e; i ++)
		STRSEARCH(p, e-p, *p == '.');

	if (i == funcctx->call_cntr)
		SRF_RETURN_NEXT(funcctx, PointerGetDatum(cstring_to_text_with_len(s, p-s)));
	else
		SRF_RETURN_DONE(funcctx);
}
Example #27
0
Datum
ts_token_type_byname(PG_FUNCTION_ARGS)
{
	FuncCallContext *funcctx;
	Datum		result;

	if (SRF_IS_FIRSTCALL())
	{
		text	   *prsname = PG_GETARG_TEXT_P(0);
		Oid			prsId;

		funcctx = SRF_FIRSTCALL_INIT();
		prsId = get_ts_parser_oid(textToQualifiedNameList(prsname), false);
		tt_setup_firstcall(funcctx, prsId);
	}

	funcctx = SRF_PERCALL_SETUP();

	if ((result = tt_process_call(funcctx)) != (Datum) 0)
		SRF_RETURN_NEXT(funcctx, result);
	SRF_RETURN_DONE(funcctx);
}
Example #28
0
Datum
token_type_byname(PG_FUNCTION_ARGS)
{
	FuncCallContext *funcctx;
	Datum		result;

	SET_FUNCOID();
	if (SRF_IS_FIRSTCALL())
	{
		text	   *name = PG_GETARG_TEXT_P(0);

		funcctx = SRF_FIRSTCALL_INIT();
		setup_firstcall(fcinfo, funcctx, name2id_prs(name));
		PG_FREE_IF_COPY(name, 0);
	}

	funcctx = SRF_PERCALL_SETUP();

	if ((result = process_call(funcctx)) != (Datum) 0)
		SRF_RETURN_NEXT(funcctx, result);
	SRF_RETURN_DONE(funcctx);
}
Example #29
0
Datum
pg_stat_get_backend_idset(PG_FUNCTION_ARGS)
{
	FuncCallContext *funcctx;
	int		   *fctx;
	int32		result;

	/* stuff done only on the first call of the function */
	if (SRF_IS_FIRSTCALL())
	{
		/* create a function context for cross-call persistence */
		funcctx = SRF_FIRSTCALL_INIT();

		fctx = MemoryContextAlloc(funcctx->multi_call_memory_ctx,
								  2 * sizeof(int));
		funcctx->user_fctx = fctx;

		fctx[0] = 0;
		fctx[1] = pgstat_fetch_stat_numbackends();
	}

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

	fctx[0] += 1;
	result = fctx[0];

	if (result <= fctx[1])
	{
		/* do when there is more left to send */
		SRF_RETURN_NEXT(funcctx, Int32GetDatum(result));
	}
	else
	{
		/* do when there is no more left */
		SRF_RETURN_DONE(funcctx);
	}
}
Example #30
0
Datum
testfunc4(PG_FUNCTION_ARGS)
{
    int64 i = PG_GETARG_INT64(0);
    FuncCallContext *funcctx;
    MemoryContext oldcontext;
    if (SRF_IS_FIRSTCALL())
    {
        funcctx = SRF_FIRSTCALL_INIT();
        oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
        funcctx->max_calls = 3;
        MemoryContextSwitchTo(oldcontext);
    }
    funcctx = SRF_PERCALL_SETUP();
    if (funcctx->call_cntr < funcctx->max_calls)
    {
        SRF_RETURN_NEXT(funcctx, Int64GetDatum(i + funcctx->call_cntr));
    }
    else
    {
        SRF_RETURN_DONE(funcctx);
    }
}