mirror of https://github.com/citusdata/citus.git
132 lines
3.4 KiB
C
132 lines
3.4 KiB
C
/*-------------------------------------------------------------------------
|
|
*
|
|
* executor_util_tuples.c
|
|
*
|
|
* Utility functions for handling tuples during remote execution.
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
|
|
#include "postgres.h"
|
|
|
|
#include "funcapi.h"
|
|
#include "miscadmin.h"
|
|
|
|
#include "utils/lsyscache.h"
|
|
|
|
#include "distributed/executor_util.h"
|
|
|
|
|
|
/*
|
|
* TupleDescGetAttBinaryInMetadata - Build an AttInMetadata structure based on
|
|
* the supplied TupleDesc. AttInMetadata can be used in conjunction with
|
|
* fmStringInfos containing binary encoded types to produce a properly formed
|
|
* tuple.
|
|
*
|
|
* NOTE: This function is a copy of the PG function TupleDescGetAttInMetadata,
|
|
* except that it uses getTypeBinaryInputInfo instead of getTypeInputInfo.
|
|
*/
|
|
AttInMetadata *
|
|
TupleDescGetAttBinaryInMetadata(TupleDesc tupdesc)
|
|
{
|
|
int natts = tupdesc->natts;
|
|
int i;
|
|
Oid atttypeid;
|
|
Oid attinfuncid;
|
|
|
|
AttInMetadata *attinmeta = (AttInMetadata *) palloc(sizeof(AttInMetadata));
|
|
|
|
/* "Bless" the tupledesc so that we can make rowtype datums with it */
|
|
attinmeta->tupdesc = BlessTupleDesc(tupdesc);
|
|
|
|
/*
|
|
* Gather info needed later to call the "in" function for each attribute
|
|
*/
|
|
FmgrInfo *attinfuncinfo = (FmgrInfo *) palloc0(natts * sizeof(FmgrInfo));
|
|
Oid *attioparams = (Oid *) palloc0(natts * sizeof(Oid));
|
|
int32 *atttypmods = (int32 *) palloc0(natts * sizeof(int32));
|
|
|
|
for (i = 0; i < natts; i++)
|
|
{
|
|
Form_pg_attribute att = TupleDescAttr(tupdesc, i);
|
|
|
|
/* Ignore dropped attributes */
|
|
if (!att->attisdropped)
|
|
{
|
|
atttypeid = att->atttypid;
|
|
getTypeBinaryInputInfo(atttypeid, &attinfuncid, &attioparams[i]);
|
|
fmgr_info(attinfuncid, &attinfuncinfo[i]);
|
|
atttypmods[i] = att->atttypmod;
|
|
}
|
|
}
|
|
attinmeta->attinfuncs = attinfuncinfo;
|
|
attinmeta->attioparams = attioparams;
|
|
attinmeta->atttypmods = atttypmods;
|
|
|
|
return attinmeta;
|
|
}
|
|
|
|
|
|
/*
|
|
* BuildTupleFromBytes - build a HeapTuple given user data in binary form.
|
|
* values is an array of StringInfos, one for each attribute of the return
|
|
* tuple. A NULL StringInfo pointer indicates we want to create a NULL field.
|
|
*
|
|
* NOTE: This function is a copy of the PG function BuildTupleFromCStrings,
|
|
* except that it uses ReceiveFunctionCall instead of InputFunctionCall.
|
|
*/
|
|
HeapTuple
|
|
BuildTupleFromBytes(AttInMetadata *attinmeta, fmStringInfo *values)
|
|
{
|
|
TupleDesc tupdesc = attinmeta->tupdesc;
|
|
int natts = tupdesc->natts;
|
|
int i;
|
|
|
|
Datum *dvalues = (Datum *) palloc(natts * sizeof(Datum));
|
|
bool *nulls = (bool *) palloc(natts * sizeof(bool));
|
|
|
|
/*
|
|
* Call the "in" function for each non-dropped attribute, even for nulls,
|
|
* to support domains.
|
|
*/
|
|
for (i = 0; i < natts; i++)
|
|
{
|
|
if (!TupleDescAttr(tupdesc, i)->attisdropped)
|
|
{
|
|
/* Non-dropped attributes */
|
|
dvalues[i] = ReceiveFunctionCall(&attinmeta->attinfuncs[i],
|
|
values[i],
|
|
attinmeta->attioparams[i],
|
|
attinmeta->atttypmods[i]);
|
|
if (values[i] != NULL)
|
|
{
|
|
nulls[i] = false;
|
|
}
|
|
else
|
|
{
|
|
nulls[i] = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Handle dropped attributes by setting to NULL */
|
|
dvalues[i] = (Datum) 0;
|
|
nulls[i] = true;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Form a tuple
|
|
*/
|
|
HeapTuple tuple = heap_form_tuple(tupdesc, dvalues, nulls);
|
|
|
|
/*
|
|
* Release locally palloc'd space. XXX would probably be good to pfree
|
|
* values of pass-by-reference datums, as well.
|
|
*/
|
|
pfree(dvalues);
|
|
pfree(nulls);
|
|
|
|
return tuple;
|
|
}
|