#include "postgres.h"
#include <ctype.h>
#include "access/htup_details.h"
#include "catalog/namespace.h"
#include "catalog/pg_type.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
#include "utils/numeric.h"
#include "utils/syscache.h"
#include "mb/pg_wchar.h"
Go to the source code of this file.
Defines | |
#define | MAX_INT32_LEN 11 |
Functions | |
static char * | format_type_internal (Oid type_oid, int32 typemod, bool typemod_given, bool allow_invalid, bool force_qualify) |
static char * | printTypmod (const char *typname, int32 typmod, Oid typmodout) |
static char * | psnprintf (size_t len, const char *fmt,...) __attribute__((format(PG_PRINTF_ATTRIBUTE |
static char Datum | format_type (PG_FUNCTION_ARGS) |
char * | format_type_be (Oid type_oid) |
char * | format_type_be_qualified (Oid type_oid) |
char * | format_type_with_typemod (Oid type_oid, int32 typemod) |
int32 | type_maximum_size (Oid type_oid, int32 typemod) |
Datum | oidvectortypes (PG_FUNCTION_ARGS) |
#define MAX_INT32_LEN 11 |
Definition at line 29 of file format_type.c.
Referenced by printTypmod().
static char Datum format_type | ( | PG_FUNCTION_ARGS | ) |
Definition at line 68 of file format_type.c.
References cstring_to_text(), format_type_internal(), PG_ARGISNULL, PG_GETARG_INT32, PG_GETARG_OID, PG_RETURN_NULL, and PG_RETURN_TEXT_P.
{ Oid type_oid; int32 typemod; char *result; /* Since this function is not strict, we must test for null args */ if (PG_ARGISNULL(0)) PG_RETURN_NULL(); type_oid = PG_GETARG_OID(0); if (PG_ARGISNULL(1)) result = format_type_internal(type_oid, -1, false, true, false); else { typemod = PG_GETARG_INT32(1); result = format_type_internal(type_oid, typemod, true, true, false); } PG_RETURN_TEXT_P(cstring_to_text(result)); }
char* format_type_be | ( | Oid | type_oid | ) |
Definition at line 98 of file format_type.c.
References format_type_internal().
Referenced by aclcheck_error_type(), addFamilyMember(), addRangeTableEntryForFunction(), AggregateCreate(), AlterTypeNamespace(), AlterTypeNamespace_oid(), AlterTypeNamespaceInternal(), AlterTypeOwner(), appendTypeNameToBuffer(), array_cat(), array_cmp(), array_contain_compare(), array_eq(), array_recv(), array_replace_internal(), array_send(), ATAddForeignKeyConstraint(), ATExecAlterColumnType(), ATExecSetStorage(), ATPrepAlterColumnType(), build_column_default(), build_subplan(), check_object_ownership(), check_of_type(), check_sql_fn_retval(), CheckAttributeType(), checkDomainOwner(), checkEnumOwner(), coerce_record_to_complex(), coerce_to_boolean(), coerce_to_common_type(), coerce_to_specific_type(), coerce_type(), compare_values_of_enum(), compile_plperl_function(), compile_pltcl_function(), ComputeIndexAttrs(), convert_tuples_by_name(), cookDefault(), CreateCast(), CreateFunction(), DefineAggregate(), DefineDomain(), DefineRange(), DefineType(), do_compile(), does_not_exist_skipping(), domain_check_input(), domain_state_setup(), dropOperators(), dropProcedures(), enforce_generic_type_consistency(), enum_first(), enum_in(), enum_last(), enum_recv(), EvaluateParams(), exec_stmt_foreach_a(), ExecCheckPlanOutput(), ExecEvalArray(), ExecEvalCoerceToDomain(), ExecEvalFieldSelect(), ExecEvalParamExtern(), ExecEvalScalarVar(), ExecEvalWholeRowVar(), ExecInitExpr(), exprType(), fetch_cursor_param_value(), findRangeSubOpclass(), findTypeOutputFunction(), fmgr_sql_validator(), format_operator_internal(), format_procedure_internal(), funcname_signature_string(), get_cast_oid(), get_domain_constraint_oid(), get_range_io_data(), get_rels_with_domain(), get_sort_group_operators(), get_ts_parser_func(), get_ts_template_func(), GetColumnDefCollation(), GetDefaultOpClass(), GetIndexOpClass(), getObjectDescription(), getTypeBinaryInputInfo(), getTypeBinaryOutputInfo(), getTypeInputInfo(), getTypeOutputInfo(), hash_array(), hash_range(), init_sql_fcache(), internal_get_result_type(), intorel_startup(), load_enum_cache_data(), lookup_rowtype_tupdesc_internal(), LookupTypeName(), make_row_comparison_op(), make_scalar_array_op(), MergeAttributes(), op_signature_string(), ParseFuncOrColumn(), pg_collation_for(), plperl_array_to_datum(), plperl_sv_to_datum(), plperl_validator(), plpgsql_build_variable(), plpgsql_validator(), PLy_output_datum_func2(), PLy_procedure_create(), prepare_sql_fn_parse_info(), print_function_arguments(), print_function_rettype(), ProcedureCreate(), processIndirection(), record_cmp(), record_eq(), regtypeout(), RenameConstraintById(), RenameType(), resolve_generic_type(), ri_HashCompareOp(), select_common_type(), storeOperators(), storeProcedures(), transformAggregateCall(), transformArrayExpr(), transformArraySubscripts(), transformArrayType(), transformAssignedExpr(), transformAssignmentIndirection(), transformAssignmentSubscripts(), transformCollateClause(), transformColumnType(), transformTypeCast(), transformXmlSerialize(), tupledesc_match(), unknown_attribute(), validateConnectbyTupleDesc(), and variable_coerce_param_hook().
{ return format_type_internal(type_oid, -1, false, false, false); }
char* format_type_be_qualified | ( | Oid | type_oid | ) |
Definition at line 104 of file format_type.c.
References format_type_internal().
Referenced by format_operator_internal(), format_procedure_internal(), and getObjectIdentity().
{ return format_type_internal(type_oid, -1, false, false, true); }
static char * format_type_internal | ( | Oid | type_oid, | |
int32 | typemod, | |||
bool | typemod_given, | |||
bool | allow_invalid, | |||
bool | force_qualify | |||
) | [static] |
Definition at line 119 of file format_type.c.
References BITOID, BOOLOID, BPCHAROID, buf, elog, ERROR, FLOAT4OID, FLOAT8OID, get_namespace_name(), GETSTRUCT, HeapTupleIsValid, INT2OID, INT4OID, INT8OID, INTERVALOID, InvalidOid, NameStr, NULL, NUMERICOID, ObjectIdGetDatum, printTypmod(), psnprintf(), pstrdup(), quote_qualified_identifier(), ReleaseSysCache(), SearchSysCache1, TIMEOID, TIMESTAMPOID, TIMESTAMPTZOID, TIMETZOID, TypeIsVisible(), TYPEOID, VARBITOID, and VARCHAROID.
Referenced by format_type(), format_type_be(), format_type_be_qualified(), format_type_with_typemod(), and oidvectortypes().
{ bool with_typemod = typemod_given && (typemod >= 0); HeapTuple tuple; Form_pg_type typeform; Oid array_base_type; bool is_array; char *buf; if (type_oid == InvalidOid && allow_invalid) return pstrdup("-"); tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type_oid)); if (!HeapTupleIsValid(tuple)) { if (allow_invalid) return pstrdup("???"); else elog(ERROR, "cache lookup failed for type %u", type_oid); } typeform = (Form_pg_type) GETSTRUCT(tuple); /* * Check if it's a regular (variable length) array type. Fixed-length * array types such as "name" shouldn't get deconstructed. As of Postgres * 8.1, rather than checking typlen we check the toast property, and don't * deconstruct "plain storage" array types --- this is because we don't * want to show oidvector as oid[]. */ array_base_type = typeform->typelem; if (array_base_type != InvalidOid && typeform->typstorage != 'p') { /* Switch our attention to the array element type */ ReleaseSysCache(tuple); tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(array_base_type)); if (!HeapTupleIsValid(tuple)) { if (allow_invalid) return pstrdup("???[]"); else elog(ERROR, "cache lookup failed for type %u", type_oid); } typeform = (Form_pg_type) GETSTRUCT(tuple); type_oid = array_base_type; is_array = true; } else is_array = false; /* * See if we want to special-case the output for certain built-in types. * Note that these special cases should all correspond to special * productions in gram.y, to ensure that the type name will be taken as a * system type, not a user type of the same name. * * If we do not provide a special-case output here, the type name will be * handled the same way as a user type name --- in particular, it will be * double-quoted if it matches any lexer keyword. This behavior is * essential for some cases, such as types "bit" and "char". */ buf = NULL; /* flag for no special case */ switch (type_oid) { case BITOID: if (with_typemod) buf = printTypmod("bit", typemod, typeform->typmodout); else if (typemod_given) { /* * bit with typmod -1 is not the same as BIT, which means * BIT(1) per SQL spec. Report it as the quoted typename so * that parser will not assign a bogus typmod. */ } else buf = pstrdup("bit"); break; case BOOLOID: buf = pstrdup("boolean"); break; case BPCHAROID: if (with_typemod) buf = printTypmod("character", typemod, typeform->typmodout); else if (typemod_given) { /* * bpchar with typmod -1 is not the same as CHARACTER, which * means CHARACTER(1) per SQL spec. Report it as bpchar so * that parser will not assign a bogus typmod. */ } else buf = pstrdup("character"); break; case FLOAT4OID: buf = pstrdup("real"); break; case FLOAT8OID: buf = pstrdup("double precision"); break; case INT2OID: buf = pstrdup("smallint"); break; case INT4OID: buf = pstrdup("integer"); break; case INT8OID: buf = pstrdup("bigint"); break; case NUMERICOID: if (with_typemod) buf = printTypmod("numeric", typemod, typeform->typmodout); else buf = pstrdup("numeric"); break; case INTERVALOID: if (with_typemod) buf = printTypmod("interval", typemod, typeform->typmodout); else buf = pstrdup("interval"); break; case TIMEOID: if (with_typemod) buf = printTypmod("time", typemod, typeform->typmodout); else buf = pstrdup("time without time zone"); break; case TIMETZOID: if (with_typemod) buf = printTypmod("time", typemod, typeform->typmodout); else buf = pstrdup("time with time zone"); break; case TIMESTAMPOID: if (with_typemod) buf = printTypmod("timestamp", typemod, typeform->typmodout); else buf = pstrdup("timestamp without time zone"); break; case TIMESTAMPTZOID: if (with_typemod) buf = printTypmod("timestamp", typemod, typeform->typmodout); else buf = pstrdup("timestamp with time zone"); break; case VARBITOID: if (with_typemod) buf = printTypmod("bit varying", typemod, typeform->typmodout); else buf = pstrdup("bit varying"); break; case VARCHAROID: if (with_typemod) buf = printTypmod("character varying", typemod, typeform->typmodout); else buf = pstrdup("character varying"); break; } if (buf == NULL) { /* * Default handling: report the name as it appears in the catalog. * Here, we must qualify the name if it is not visible in the search * path, and we must double-quote it if it's not a standard identifier * or if it matches any keyword. */ char *nspname; char *typname; if (!force_qualify && TypeIsVisible(type_oid)) nspname = NULL; else nspname = get_namespace_name(typeform->typnamespace); typname = NameStr(typeform->typname); buf = quote_qualified_identifier(nspname, typname); if (with_typemod) buf = printTypmod(buf, typemod, typeform->typmodout); } if (is_array) buf = psnprintf(strlen(buf) + 3, "%s[]", buf); ReleaseSysCache(tuple); return buf; }
Definition at line 113 of file format_type.c.
References format_type_internal().
Referenced by analyzeCTE(), checkViewTupleDesc(), convert_tuples_by_position(), deparseArrayExpr(), deparseConst(), deparseFuncExpr(), deparseParam(), deparseRelabelType(), deparseVar(), get_coercion_expr(), get_const_expr(), get_from_clause_coldeflist(), get_rule_expr(), and get_variable().
{ return format_type_internal(type_oid, typemod, true, false, false); }
Datum oidvectortypes | ( | PG_FUNCTION_ARGS | ) |
Definition at line 413 of file format_type.c.
References cstring_to_text(), oidvector::dim1, format_type_internal(), palloc(), PG_GETARG_POINTER, PG_RETURN_TEXT_P, repalloc(), and oidvector::values.
{ oidvector *oidArray = (oidvector *) PG_GETARG_POINTER(0); char *result; int numargs = oidArray->dim1; int num; size_t total; size_t left; total = 20 * numargs + 1; result = palloc(total); result[0] = '\0'; left = total - 1; for (num = 0; num < numargs; num++) { char *typename = format_type_internal(oidArray->values[num], -1, false, true, false); size_t slen = strlen(typename); if (left < (slen + 2)) { total += slen + 2; result = repalloc(result, total); left += slen + 2; } if (num > 0) { strcat(result, ", "); left -= 2; } strcat(result, typename); left -= slen; } PG_RETURN_TEXT_P(cstring_to_text(result)); }
Definition at line 335 of file format_type.c.
References Assert, DatumGetCString, Int32GetDatum, InvalidOid, MAX_INT32_LEN, OidFunctionCall1, and psnprintf().
Referenced by format_type_internal().
{ char *res; /* Shouldn't be called if typmod is -1 */ Assert(typmod >= 0); if (typmodout == InvalidOid) { /* Default behavior: just print the integer typmod with parens */ res = psnprintf(strlen(typname) + MAX_INT32_LEN + 3, "%s(%d)", typname, (int) typmod); } else { /* Use the type-specific typmodout procedure */ char *tmstr; tmstr = DatumGetCString(OidFunctionCall1(typmodout, Int32GetDatum(typmod))); res = psnprintf(strlen(typname) + strlen(tmstr) + 1, "%s%s", typname, tmstr); } return res; }
static char * psnprintf | ( | size_t | len, | |
const char * | fmt, | |||
... | ||||
) | [static] |
Definition at line 455 of file format_type.c.
References buf, palloc(), and vsnprintf().
Referenced by format_type_internal(), and printTypmod().
Definition at line 378 of file format_type.c.
References BITOID, BITS_PER_BYTE, BPCHAROID, GetDatabaseEncoding(), numeric_maximum_size(), NUMERICOID, pg_encoding_max_length(), VARBITOID, VARCHAROID, and VARHDRSZ.
Referenced by get_typavgwidth(), and needs_toast_table().
{ if (typemod < 0) return -1; switch (type_oid) { case BPCHAROID: case VARCHAROID: /* typemod includes varlena header */ /* typemod is in characters not bytes */ return (typemod - VARHDRSZ) * pg_encoding_max_length(GetDatabaseEncoding()) + VARHDRSZ; case NUMERICOID: return numeric_maximum_size(typemod); case VARBITOID: case BITOID: /* typemod is the (max) number of bits */ return (typemod + (BITS_PER_BYTE - 1)) / BITS_PER_BYTE + 2 * sizeof(int32); } /* Unknown type, or unlimited-width type such as 'text' */ return -1; }