static void deparseTypeName()

in ext/pg_query/pg_query_deparse.c [3251:3453]


static void deparseTypeName(StringInfo str, TypeName *type_name)
{
	ListCell *lc;
	bool skip_typmods = false;

	if (type_name->setof)
		appendStringInfoString(str, "SETOF ");

	if (list_length(type_name->names) == 2 && strcmp(strVal(linitial(type_name->names)), "pg_catalog") == 0)
	{
		const char *name = strVal(lsecond(type_name->names));
		if (strcmp(name, "bpchar") == 0)
		{
			appendStringInfoString(str, "char");
		}
		else if (strcmp(name, "varchar") == 0)
		{
			appendStringInfoString(str, "varchar");
		}
		else if (strcmp(name, "numeric") == 0)
		{
			appendStringInfoString(str, "numeric");
		}
		else if (strcmp(name, "bool") == 0)
		{
			appendStringInfoString(str, "boolean");
		}
		else if (strcmp(name, "int2") == 0)
		{
			appendStringInfoString(str, "smallint");
		}
		else if (strcmp(name, "int4") == 0)
		{
			appendStringInfoString(str, "int");
		}
		else if (strcmp(name, "int8") == 0)
		{
			appendStringInfoString(str, "bigint");
		}
		else if (strcmp(name, "real") == 0 || strcmp(name, "float4") == 0)
		{
			appendStringInfoString(str, "real");
		}
		else if (strcmp(name, "float8") == 0)
		{
			appendStringInfoString(str, "double precision");
		}
		else if (strcmp(name, "time") == 0)
		{
			appendStringInfoString(str, "time");
		}
		else if (strcmp(name, "timetz") == 0)
		{
			appendStringInfoString(str, "time ");
			if (list_length(type_name->typmods) > 0)
			{
				appendStringInfoChar(str, '(');
				foreach(lc, type_name->typmods)
				{
					deparseSignedIconst(str, (Node *) &castNode(A_Const, lfirst(lc))->val);
					if (lnext(type_name->typmods, lc))
						appendStringInfoString(str, ", ");
				}
				appendStringInfoString(str, ") ");
			}
			appendStringInfoString(str, "with time zone");
			skip_typmods = true;
		}
		else if (strcmp(name, "timestamp") == 0)
		{
			appendStringInfoString(str, "timestamp");
		}
		else if (strcmp(name, "timestamptz") == 0)
		{
			appendStringInfoString(str, "timestamp ");
			if (list_length(type_name->typmods) > 0)
			{
				appendStringInfoChar(str, '(');
				foreach(lc, type_name->typmods)
				{
					deparseSignedIconst(str, (Node *) &castNode(A_Const, lfirst(lc))->val);
					if (lnext(type_name->typmods, lc))
						appendStringInfoString(str, ", ");
				}
				appendStringInfoString(str, ") ");
			}
			appendStringInfoString(str, "with time zone");
			skip_typmods = true;
		}
		else if (strcmp(name, "interval") == 0 && list_length(type_name->typmods) == 0)
		{
			appendStringInfoString(str, "interval");
		}
		else if (strcmp(name, "interval") == 0 && list_length(type_name->typmods) >= 1)
		{
			Assert(IsA(linitial(type_name->typmods), A_Const));
			Assert(IsA(&castNode(A_Const, linitial(type_name->typmods))->val, Integer));

			int fields = intVal(&castNode(A_Const, linitial(type_name->typmods))->val);

			appendStringInfoString(str, "interval");

			// This logic is based on intervaltypmodout in timestamp.c
			switch (fields)
			{
				case INTERVAL_MASK(YEAR):
					appendStringInfoString(str, " year");
					break;
				case INTERVAL_MASK(MONTH):
					appendStringInfoString(str, " month");
					break;
				case INTERVAL_MASK(DAY):
					appendStringInfoString(str, " day");
					break;
				case INTERVAL_MASK(HOUR):
					appendStringInfoString(str, " hour");
					break;
				case INTERVAL_MASK(MINUTE):
					appendStringInfoString(str, " minute");
					break;
				case INTERVAL_MASK(SECOND):
					appendStringInfoString(str, " second");
					break;
				case INTERVAL_MASK(YEAR) | INTERVAL_MASK(MONTH):
					appendStringInfoString(str, " year to month");
					break;
				case INTERVAL_MASK(DAY) | INTERVAL_MASK(HOUR):
					appendStringInfoString(str, " day to hour");
					break;
				case INTERVAL_MASK(DAY) | INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE):
					appendStringInfoString(str, " day to minute");
					break;
				case INTERVAL_MASK(DAY) | INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE) | INTERVAL_MASK(SECOND):
					appendStringInfoString(str, " day to second");
					break;
				case INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE):
					appendStringInfoString(str, " hour to minute");
					break;
				case INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE) | INTERVAL_MASK(SECOND):
					appendStringInfoString(str, " hour to second");
					break;
				case INTERVAL_MASK(MINUTE) | INTERVAL_MASK(SECOND):
					appendStringInfoString(str, " minute to second");
					break;
				case INTERVAL_FULL_RANGE:
					// Nothing
					break;
				default:
					Assert(false);
					break;
			}

			if (list_length(type_name->typmods) == 2)
			{
				int precision = intVal(&castNode(A_Const, lsecond(type_name->typmods))->val);
				if (precision != INTERVAL_FULL_PRECISION)
					appendStringInfo(str, "(%d)", precision);
			}
			
			skip_typmods = true;
		}
		else
		{
			appendStringInfoString(str, "pg_catalog.");
			appendStringInfoString(str, name);
		}
	}
	else
	{
		deparseAnyName(str, type_name->names);
	}

	if (list_length(type_name->typmods) > 0 && !skip_typmods)
	{
		appendStringInfoChar(str, '(');
		foreach(lc, type_name->typmods)
		{
			if (IsA(lfirst(lc), A_Const))
				deparseAConst(str, lfirst(lc));
			else if (IsA(lfirst(lc), ParamRef))
				deparseParamRef(str, lfirst(lc));
			else if (IsA(lfirst(lc), ColumnRef))
				deparseColumnRef(str, lfirst(lc));
			else
				Assert(false);

			if (lnext(type_name->typmods, lc))
				appendStringInfoString(str, ", ");
		}
		appendStringInfoChar(str, ')');
	}

	foreach(lc, type_name->arrayBounds)
	{
		appendStringInfoChar(str, '[');
		if (IsA(lfirst(lc), Integer) && intVal(lfirst(lc)) != -1)
			deparseSignedIconst(str, lfirst(lc));
		appendStringInfoChar(str, ']');
	}

	if (type_name->pct_type)
		appendStringInfoString(str, "%type");
}