A composite is put using the PGparam structure. Each attribute of a composite is put into a PGparam.
When all attributes have been put, the PGparam is put into another PGparam. Composites must be
registered on a per connection basis, `man pqt-handlers(3)´.
To get a composite, a PGresult structure is used. Each composite attribute is a field of the result.
For non-array composites, there is always only one tuple.
Composites are only handled using binary format. This means that any type used as a composite attribute
must be put and gotten in binary format. If a user-defined type does not implement a send and recv
function in the backend, it can not be used as a composite attribute.
SimpleCompositeExample
This example demostrates the basics of putting and getting a composite type.
CREATETYPEsimpleAS(aint4,ttext);PGregisterTypetype={"simple",NULL,NULL};/*needtoregisterthesimplecomposite*/PQregisterTypes(conn,PQT_COMPOSITE,&type,1,0);/*CompositeattributesareputintoPGparamstructures*/PGparam*simple=PQparamCreate(conn);/*putthesimplecompositeattributes*/PQputf(simple,"%int4%text*",45,"foobar");/*Putanint4andasimplecomposite*/PGparam*param=PQparamCreate(conn);PQputf(param,"%int4%simple",10,simple);PQparamClear(simple);/*execaninsert*/res=PQparamExec(conn,param,"INSERTINTOtVALUES($1,$2)",resfmt);PQparamClear(param);/*-------------------------*Gettingacomposite*/PGint4i4;PGtexttextp;chartext[80];PGresult*simple;/*Getasimplecomposite,provideaptrtoaPGresultptr.*/PQgetf(result,0,"%simple",0,&simple);/*nolongerneeded*/PQclear(result);/*Getthesimplecompositeattributesfromthesimpleresult.*Referencefieldsbynamebyusinga'#'ratherthana'%'.*Thefieldnamesarethecompositeattributes.*/PQgetf(simple,0,"#int4#text","a",&i4,"t",&textp);strcpy(text,textp);PQclear(simple);
In the above example, we used the ´#´ specifier mark to reference
fields by their name. The field names for a composite result object
are the composite attribute names.
NestedCompositeexample:
The below example puts and gets a nested composite. The simple composite is used as an attribute within
the complex composite.
CREATETYPEsimpleAS(aint4,ttext)CREATETYPEcomplexAS(f8float8,ssimple);/*needtoregistersimpleandcomplex*/PGregisterTypetypes[]={{"simple",NULL,NULL},{"complex",NULL,NULL}};PQregisterTypes(conn,PQT_COMPOSITE,types,2,0);/*CompositeattributesareputintoPGparamstructures*/PGparam*simple=PQparamCreate(conn);PGparam*complex=PQparamCreate(conn);/*putthesimplecompositeattributes*/PQputf(simple,"%int4%text*",45,"foobar");/*putthecomplexcompositeattributes,whichincludes*anestedcomposite.*/PQputf(complex,"%float8%simple",111.2223334,simple);/*nolongerneeded*/PQparamClear(simple);/*Putanint4andacomplexcomposite*/PGparam*param=PQparamCreate(conn);PQputf(param,"%int4%complex",10,complex);PQparamClear(complex);/*execaninsert*/res=PQparamExec(conn,param,"INSERTINTOtVALUES($1,$2)",resfmt);PQparamClear(param);/*-------------------------*Gettinganestedcomposite*/PGfloat8f8;PGint4i4;PGtexttextp;chartext[80];PGresult*complex;PGresult*simple;/*Getthecomplexcomposite,provideaptrtoaPGresultptr.*/PQgetf(result,0,"%complex",0,&complex);/*nolongerneeded*/PQclear(result);/*Getthecomplexcompositeattributesfromthecomplexresult.*Compositeattributesaretheresultfields.Whengetting*asinglecomposite,non-array,onlytuple0willexist.*Forthenestedsimplecomposite,weagainprovideaptrto*aPGresultptr.*/PQgetf(complex,0,"%float8%simple",0,&f8,1,&simple);/*nolongerneeded*/PQclear(complex);/*Getthesimplecompositeattributesfromthesimpleresult.*Referencefieldsbynamebyusinga'#'ratherthana'%'.*/PQgetf(simple,0,"#int4#text","a",&i4,"t",&textp);strcpy(text,textp);PQclear(simple);Anarrayofcomposites:
This example makes an array of complex composites. It builds off the previous example.
inti;PGarraycomplex_arr;PGparam*simple=PQparamCreate(conn);PGparam*complex=PQparamCreate(conn);complex_arr.ndims=0;complex_arr.param=PQparamCreate(conn);for(i=0;i<100;i++){/*putthesimplecompositeattributes*/PQputf(simple,"%int4%text*",45,"foobar");/*putthecomplexcompositeattributes,whichincludes*anestedcomposite.*/PQputf(complex,"%float8%simple",111.2223334,simple);/*putthecomplexcomposite*/PQputf(complex_arr.param,"%complex",complex);/*Youmustresetthesimpleandcomplexcompositesfor*thenextloopiteration.*/PQparamReset(simple);PQparamReset(complex);}/*notneededanymore*/PQparamClear(simple);PQparamClear(complex);/*Putacomplexcompositearray*/PGparam*param=PQparamCreate(conn);PQputf(param,"%complex[]",&complex_arr);PQparamClear(complex_arr.param);/*execaninsert*/res=PQparamExec(conn,param,"INSERTINTOtVALUES($1)",resfmt);PQparamClear(param);/*-------------------------*Gettinganarrayofcomposites*/inti;intntups;PGfloat8f8;PGint4i4;PGtexttextp;PGresult*simple;PGarraycomplex_arr;/*Getthecomplex[],provideaptrtoaPGarray.*/PQgetf(exec_result,0,"%complex[]",0,&complex_arr);/*nolongerneeded*/PQclear(exec_result);ntups=PQntuples(complex_arr.res);for(i=0;i<ntups;i++){PQgetf(complex_arr.res,i,"%float8%simple",0,&f8,1,&simple);/*Nestedcompositesarelikeanyothercomposite,tuple0!Unless,*itsanestedcompositearray.*/PQgetf(simple,0,"#int4#text","a",&i4,"t",&textp);printf("(%f,(%d,%s))\n",f8,i4,textp);PQclear(simple);}PQclear(complex_arr.res);