Beispiel #1
0
void
test_add_tuple_desc_httpheader(void **state)
{

	/* setup mock data and expectations */
	CHURL_HEADERS headers = (CHURL_HEADERS) palloc0(sizeof(CHURL_HEADERS));
	Relation	rel = (Relation) palloc0(sizeof(RelationData));

	struct tupleDesc tuple;

	tuple.natts = 4;
	rel->rd_id = 56;
	rel->rd_att = &tuple;
	expect_headers_append(headers, "X-GP-ATTRS", "4");

	FormData_pg_attribute attrs[4];
	Form_pg_attribute attrs_ptr[4];

	tuple.attrs = attrs_ptr;

	/* define first attribute */
	attrs_ptr[0] = &attrs[0];
	char		data0[10] = "name0";

	snprintf(NameStr(attrs[0].attname), sizeof(data0), data0);
	char		typename0[12] = "NUMERICOID";

	attrs[0].atttypid = NUMERICOID;
	attrs[0].atttypmod = 10;
	char		typecode0[10];

	pg_ltoa(attrs[0].atttypid, typecode0);
	expect_value(TypeOidGetTypename, typid, NUMERICOID);
	will_return(TypeOidGetTypename, &typename0);
	expect_headers_append(headers, "X-GP-ATTR-NAME0", data0);
	expect_headers_append(headers, "X-GP-ATTR-TYPECODE0", typecode0);
	expect_headers_append(headers, "X-GP-ATTR-TYPENAME0", typename0);
	expect_headers_append(headers, "X-GP-ATTR-TYPEMOD0-COUNT", "2");
	char		typemod00[10];

	pg_ltoa((attrs[0].atttypmod >> 16) & 0xffff, typemod00);
	expect_headers_append(headers, "X-GP-ATTR-TYPEMOD0-0", typemod00);
	char		typemod01[10];

	pg_ltoa((attrs[0].atttypmod - VARHDRSZ) & 0xffff, typemod01);
	expect_headers_append(headers, "X-GP-ATTR-TYPEMOD0-1", typemod01);

	/* define second attribute */
	attrs_ptr[1] = &attrs[1];
	char		data1[10] = "name1";

	snprintf(NameStr(attrs[1].attname), sizeof(data1), data1);
	char		typename1[12] = "CHAROID";

	attrs[1].atttypid = CHAROID;
	attrs[1].atttypmod = 10;
	char		typecode1[10];

	pg_ltoa(attrs[1].atttypid, typecode1);
	expect_value(TypeOidGetTypename, typid, CHAROID);
	will_return(TypeOidGetTypename, &typename1);
	expect_headers_append(headers, "X-GP-ATTR-NAME1", data1);
	expect_headers_append(headers, "X-GP-ATTR-TYPECODE1", typecode1);
	expect_headers_append(headers, "X-GP-ATTR-TYPENAME1", typename1);
	expect_headers_append(headers, "X-GP-ATTR-TYPEMOD1-COUNT", "1");
	char		typemod10[10];

	pg_ltoa((attrs[1].atttypmod - VARHDRSZ), typemod10);
	expect_headers_append(headers, "X-GP-ATTR-TYPEMOD1-0", typemod10);

	/* define third attribute */
	attrs_ptr[2] = &attrs[2];
	char		data2[10] = "name2";

	snprintf(NameStr(attrs[2].attname), sizeof(data2), data2);
	char		typename2[12] = "TIMEOID";

	attrs[2].atttypid = TIMEOID;
	attrs[2].atttypmod = 10;
	char		typecode2[10];

	pg_ltoa(attrs[2].atttypid, typecode2);
	expect_value(TypeOidGetTypename, typid, TIMEOID);
	will_return(TypeOidGetTypename, &typename2);
	expect_headers_append(headers, "X-GP-ATTR-NAME2", data2);
	expect_headers_append(headers, "X-GP-ATTR-TYPECODE2", typecode2);
	expect_headers_append(headers, "X-GP-ATTR-TYPENAME2", typename2);
	expect_headers_append(headers, "X-GP-ATTR-TYPEMOD2-COUNT", "1");
	char		typemod20[10];

	pg_ltoa(attrs[2].atttypmod, typemod20);
	expect_headers_append(headers, "X-GP-ATTR-TYPEMOD2-0", typemod20);

	/* define fourth attribute */
	attrs_ptr[3] = &attrs[3];
	char		data3[10] = "name3";

	snprintf(NameStr(attrs[3].attname), sizeof(data3), data3);
	char		typename3[12] = "INTERVALOID";

	attrs[3].atttypid = INTERVALOID;
	attrs[3].atttypmod = 10;
	char		typecode3[10];

	pg_ltoa(attrs[3].atttypid, typecode3);
	expect_value(TypeOidGetTypename, typid, INTERVALOID);
	will_return(TypeOidGetTypename, &typename3);
	expect_headers_append(headers, "X-GP-ATTR-NAME3", data3);
	expect_headers_append(headers, "X-GP-ATTR-TYPECODE3", typecode3);
	expect_headers_append(headers, "X-GP-ATTR-TYPENAME3", typename3);
	expect_headers_append(headers, "X-GP-ATTR-TYPEMOD3-COUNT", "1");
	char		typemod30[10];

	pg_ltoa(INTERVAL_PRECISION(attrs[3].atttypmod), typemod30);
	expect_headers_append(headers, "X-GP-ATTR-TYPEMOD3-0", typemod30);

	/* call function under test */
	add_tuple_desc_httpheader(headers, rel);

	/* no asserts as the function just calls to set headers */

	/* cleanup */
	pfree(rel);
	pfree(headers);
}
Beispiel #2
0
/* 
 * Report tuple description to remote component 
 * Currently, number of attributes, attributes names, types and types modifiers
 * Each attribute has a pair of key/value 
 * where X is the number of the attribute
 * X-GP-ATTR-NAMEX - attribute X's name 
 * X-GP-ATTR-TYPECODEX - attribute X's type OID (e.g, 16)
 * X-GP-ATTR-TYPENAMEX - attribute X's type name (e.g, "boolean")
 * optional - X-GP-ATTR-TYPEMODX-COUNT - total number of modifier for attribute X
 * optional - X-GP-ATTR-TYPEMODX-Y - attribute X's modifiers Y (types which have precision info, like numeric(p,s))
 */
static void add_tuple_desc_httpheader(CHURL_HEADERS headers, Relation rel)
{	
    char long_number[INT32_CHAR_SIZE];
    StringInfoData formatter;	
    TupleDesc tuple;		
    initStringInfo(&formatter);
	
    /* Get tuple description itself */	
    tuple = RelationGetDescr(rel);	
	
    /* Convert the number of attributes to a string */	
    pg_ltoa(tuple->natts, long_number);	
    churl_headers_append(headers, "X-GP-ATTRS", long_number);
	
    /* Iterate attributes */	
    for (int i = 0; i < tuple->natts; ++i)		
    {		
        /* Add a key/value pair for attribute name */		
        resetStringInfo(&formatter);		
        appendStringInfo(&formatter, "X-GP-ATTR-NAME%u", i);		
        churl_headers_append(headers, formatter.data, tuple->attrs[i]->attname.data);
		
		/* Add a key/value pair for attribute type */		
        resetStringInfo(&formatter);		
        appendStringInfo(&formatter, "X-GP-ATTR-TYPECODE%u", i);
        pg_ltoa(tuple->attrs[i]->atttypid, long_number);		
        churl_headers_append(headers, formatter.data, long_number);

        /* Add a key/value pair for attribute type name */
        resetStringInfo(&formatter);
        appendStringInfo(&formatter, "X-GP-ATTR-TYPENAME%u", i);
        churl_headers_append(headers, formatter.data, TypeOidGetTypename(tuple->attrs[i]->atttypid));

		/* Add attribute type modifiers if any*/
		if (tuple->attrs[i]->atttypmod > -1)
		{
			switch (tuple->attrs[i]->atttypid)
			{
				case NUMERICOID:
				{
					resetStringInfo(&formatter);
					appendStringInfo(&formatter, "X-GP-ATTR-TYPEMOD%u-COUNT", i);
					pg_ltoa(2, long_number);
					churl_headers_append(headers, formatter.data, long_number);


					/* precision */
					resetStringInfo(&formatter);
					appendStringInfo(&formatter, "X-GP-ATTR-TYPEMOD%u-%u", i, 0);
					pg_ltoa((tuple->attrs[i]->atttypmod >> 16) & 0xffff, long_number);
					churl_headers_append(headers, formatter.data, long_number);

					/* scale */
					resetStringInfo(&formatter);
					appendStringInfo(&formatter, "X-GP-ATTR-TYPEMOD%u-%u", i, 1);
					pg_ltoa((tuple->attrs[i]->atttypmod - VARHDRSZ) & 0xffff, long_number);
					churl_headers_append(headers, formatter.data, long_number);
					break;
				}
				case CHAROID:
				case BPCHAROID:
				case VARCHAROID:
				{
					resetStringInfo(&formatter);
					appendStringInfo(&formatter, "X-GP-ATTR-TYPEMOD%u-COUNT", i);
					pg_ltoa(1, long_number);
					churl_headers_append(headers, formatter.data, long_number);

					resetStringInfo(&formatter);
					appendStringInfo(&formatter, "X-GP-ATTR-TYPEMOD%u-%u", i, 0);
					pg_ltoa((tuple->attrs[i]->atttypmod - VARHDRSZ), long_number);
					churl_headers_append(headers, formatter.data, long_number);
					break;
				}
				case VARBITOID:
				case BITOID:
				case TIMESTAMPOID:
				case TIMESTAMPTZOID:
				case TIMEOID:
				case TIMETZOID:
				{
					resetStringInfo(&formatter);
					appendStringInfo(&formatter, "X-GP-ATTR-TYPEMOD%u-COUNT", i);
					pg_ltoa(1, long_number);
					churl_headers_append(headers, formatter.data, long_number);

					resetStringInfo(&formatter);
					appendStringInfo(&formatter, "X-GP-ATTR-TYPEMOD%u-%u", i, 0);
					pg_ltoa((tuple->attrs[i]->atttypmod), long_number);
					churl_headers_append(headers, formatter.data, long_number);
					break;
				}
				case INTERVALOID:
				{
					resetStringInfo(&formatter);
					appendStringInfo(&formatter, "X-GP-ATTR-TYPEMOD%u-COUNT", i);
					pg_ltoa(1, long_number);
					churl_headers_append(headers, formatter.data, long_number);

					resetStringInfo(&formatter);
					appendStringInfo(&formatter, "X-GP-ATTR-TYPEMOD%u-%u", i, 0);
					pg_ltoa(INTERVAL_PRECISION(tuple->attrs[i]->atttypmod), long_number);
					churl_headers_append(headers, formatter.data, long_number);
					break;
				}
				default:
					elog(DEBUG5, "add_tuple_desc_httpheader: unsupported type %d ", tuple->attrs[i]->atttypid);
					break;
			}
		}
	}
	
	pfree(formatter.data);
}