#include "access/htup.h"#include "parser/parse_node.h"

Go to the source code of this file.
Defines | |
| #define | ISCOMPLEX(typeid) (typeidTypeRelid(typeid) != InvalidOid) |
Typedefs | |
| typedef HeapTuple | Type |
Functions | |
| Type | LookupTypeName (ParseState *pstate, const TypeName *typeName, int32 *typmod_p) |
| Type | typenameType (ParseState *pstate, const TypeName *typeName, int32 *typmod_p) |
| Oid | typenameTypeId (ParseState *pstate, const TypeName *typeName) |
| void | typenameTypeIdAndMod (ParseState *pstate, const TypeName *typeName, Oid *typeid_p, int32 *typmod_p) |
| char * | TypeNameToString (const TypeName *typeName) |
| char * | TypeNameListToString (List *typenames) |
| Oid | LookupCollation (ParseState *pstate, List *collnames, int location) |
| Oid | GetColumnDefCollation (ParseState *pstate, ColumnDef *coldef, Oid typeOid) |
| Type | typeidType (Oid id) |
| Oid | typeTypeId (Type tp) |
| int16 | typeLen (Type t) |
| bool | typeByVal (Type t) |
| char * | typeTypeName (Type t) |
| Oid | typeTypeRelid (Type typ) |
| Oid | typeTypeCollation (Type typ) |
| Datum | stringTypeDatum (Type tp, char *string, int32 atttypmod) |
| Oid | typeidTypeRelid (Oid type_id) |
| void | parseTypeString (const char *str, Oid *typeid_p, int32 *typmod_p) |
| #define ISCOMPLEX | ( | typeid | ) | (typeidTypeRelid(typeid) != InvalidOid) |
Definition at line 50 of file parse_type.h.
Referenced by can_coerce_type(), coerce_type(), func_get_detail(), is_complex_array(), IsBinaryCoercible(), ParseFuncOrColumn(), and unknown_attribute().
Definition at line 20 of file parse_type.h.
| Oid GetColumnDefCollation | ( | ParseState * | pstate, | |
| ColumnDef * | coldef, | |||
| Oid | typeOid | |||
| ) |
Definition at line 471 of file parse_type.c.
References ColumnDef::collClause, CollateClause::collname, ColumnDef::collOid, ereport, errcode(), errmsg(), ERROR, format_type_be(), get_typcollation(), CollateClause::location, LookupCollation(), OidIsValid, and parser_errposition().
Referenced by addRangeTableEntryForFunction(), ATExecAddColumn(), ATExecAlterColumnType(), ATPrepAlterColumnType(), BuildDescForRelation(), and MergeAttributes().
{
Oid result;
Oid typcollation = get_typcollation(typeOid);
int location = -1;
if (coldef->collClause)
{
/* We have a raw COLLATE clause, so look up the collation */
location = coldef->collClause->location;
result = LookupCollation(pstate, coldef->collClause->collname,
location);
}
else if (OidIsValid(coldef->collOid))
{
/* Precooked collation spec, use that */
result = coldef->collOid;
}
else
{
/* Use the type's default collation if any */
result = typcollation;
}
/* Complain if COLLATE is applied to an uncollatable type */
if (OidIsValid(result) && !OidIsValid(typcollation))
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("collations are not supported by type %s",
format_type_be(typeOid)),
parser_errposition(pstate, location)));
return result;
}
| Oid LookupCollation | ( | ParseState * | pstate, | |
| List * | collnames, | |||
| int | location | |||
| ) |
Definition at line 446 of file parse_type.c.
References cancel_parser_errposition_callback(), get_collation_oid(), and setup_parser_errposition_callback().
Referenced by GetColumnDefCollation(), transformCollateClause(), and transformColumnType().
{
Oid colloid;
ParseCallbackState pcbstate;
if (pstate)
setup_parser_errposition_callback(&pcbstate, pstate, location);
colloid = get_collation_oid(collnames, false);
if (pstate)
cancel_parser_errposition_callback(&pcbstate);
return colloid;
}
| Type LookupTypeName | ( | ParseState * | pstate, | |
| const TypeName * | typeName, | |||
| int32 * | typmod_p | |||
| ) |
Definition at line 58 of file parse_type.c.
References TypeName::arrayBounds, Assert, RangeVar::catalogname, DeconstructQualifiedName(), elog, ereport, errcode(), errmsg(), ERROR, format_type_be(), get_array_type(), get_attnum(), get_atttype(), GetSysCacheOid2, HeapTupleIsValid, InvalidAttrNumber, lfourth, linitial, list_length(), TypeName::location, LookupExplicitNamespace(), lsecond, lthird, makeRangeVar(), NameListToString(), TypeName::names, NIL, NoLock, NOTICE, NULL, ObjectIdGetDatum, OidIsValid, parser_errposition(), TypeName::pct_type, PointerGetDatum, RangeVarGetRelid, RangeVar::relname, RangeVar::schemaname, SearchSysCache1, strVal, TypenameGetTypid(), TYPENAMENSP, TypeNameToString(), typenameTypeMod(), TYPEOID, and TypeName::typeOid.
Referenced by AlterTypeOwner(), compute_return_type(), examine_parameter_list(), FuncNameAsType(), get_object_address_type(), LookupTypeNameOid(), plpgsql_parse_wordtype(), and typenameType().
{
Oid typoid;
HeapTuple tup;
int32 typmod;
if (typeName->names == NIL)
{
/* We have the OID already if it's an internally generated TypeName */
typoid = typeName->typeOid;
}
else if (typeName->pct_type)
{
/* Handle %TYPE reference to type of an existing field */
RangeVar *rel = makeRangeVar(NULL, NULL, typeName->location);
char *field = NULL;
Oid relid;
AttrNumber attnum;
/* deconstruct the name list */
switch (list_length(typeName->names))
{
case 1:
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("improper %%TYPE reference (too few dotted names): %s",
NameListToString(typeName->names)),
parser_errposition(pstate, typeName->location)));
break;
case 2:
rel->relname = strVal(linitial(typeName->names));
field = strVal(lsecond(typeName->names));
break;
case 3:
rel->schemaname = strVal(linitial(typeName->names));
rel->relname = strVal(lsecond(typeName->names));
field = strVal(lthird(typeName->names));
break;
case 4:
rel->catalogname = strVal(linitial(typeName->names));
rel->schemaname = strVal(lsecond(typeName->names));
rel->relname = strVal(lthird(typeName->names));
field = strVal(lfourth(typeName->names));
break;
default:
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("improper %%TYPE reference (too many dotted names): %s",
NameListToString(typeName->names)),
parser_errposition(pstate, typeName->location)));
break;
}
/*
* Look up the field.
*
* XXX: As no lock is taken here, this might fail in the presence of
* concurrent DDL. But taking a lock would carry a performance
* penalty and would also require a permissions check.
*/
relid = RangeVarGetRelid(rel, NoLock, false);
attnum = get_attnum(relid, field);
if (attnum == InvalidAttrNumber)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg("column \"%s\" of relation \"%s\" does not exist",
field, rel->relname),
parser_errposition(pstate, typeName->location)));
typoid = get_atttype(relid, attnum);
/* this construct should never have an array indicator */
Assert(typeName->arrayBounds == NIL);
/* emit nuisance notice (intentionally not errposition'd) */
ereport(NOTICE,
(errmsg("type reference %s converted to %s",
TypeNameToString(typeName),
format_type_be(typoid))));
}
else
{
/* Normal reference to a type name */
char *schemaname;
char *typname;
/* deconstruct the name list */
DeconstructQualifiedName(typeName->names, &schemaname, &typname);
if (schemaname)
{
/* Look in specific schema only */
Oid namespaceId;
namespaceId = LookupExplicitNamespace(schemaname, false);
typoid = GetSysCacheOid2(TYPENAMENSP,
PointerGetDatum(typname),
ObjectIdGetDatum(namespaceId));
}
else
{
/* Unqualified type name, so search the search path */
typoid = TypenameGetTypid(typname);
}
/* If an array reference, return the array type instead */
if (typeName->arrayBounds != NIL)
typoid = get_array_type(typoid);
}
if (!OidIsValid(typoid))
{
if (typmod_p)
*typmod_p = -1;
return NULL;
}
tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typoid));
if (!HeapTupleIsValid(tup)) /* should not happen */
elog(ERROR, "cache lookup failed for type %u", typoid);
typmod = typenameTypeMod(pstate, typeName, (Type) tup);
if (typmod_p)
*typmod_p = typmod;
return (Type) tup;
}
Definition at line 664 of file parse_type.c.
References appendStringInfo(), TypeCast::arg, ErrorContextCallback::arg, buf, ErrorContextCallback::callback, StringInfoData::data, SelectStmt::distinctClause, ereport, errcode(), errmsg(), ERROR, error_context_stack, SelectStmt::fromClause, SelectStmt::groupClause, SelectStmt::havingClause, ResTarget::indirection, initStringInfo(), SelectStmt::intoClause, IsA, SelectStmt::limitCount, SelectStmt::limitOffset, linitial, list_length(), SelectStmt::lockingClause, ResTarget::name, NIL, NULL, SelectStmt::op, pfree(), ErrorContextCallback::previous, raw_parser(), TypeName::setof, SelectStmt::sortClause, SelectStmt::targetList, TypeCast::typeName, typenameTypeIdAndMod(), ResTarget::val, SelectStmt::valuesLists, SelectStmt::whereClause, SelectStmt::windowClause, and SelectStmt::withClause.
Referenced by parseNameAndArgTypes(), plperl_spi_prepare(), pltcl_SPI_prepare(), PLy_spi_prepare(), and regtypein().
{
StringInfoData buf;
List *raw_parsetree_list;
SelectStmt *stmt;
ResTarget *restarget;
TypeCast *typecast;
TypeName *typeName;
ErrorContextCallback ptserrcontext;
/* make sure we give useful error for empty input */
if (strspn(str, " \t\n\r\f") == strlen(str))
goto fail;
initStringInfo(&buf);
appendStringInfo(&buf, "SELECT NULL::%s", str);
/*
* Setup error traceback support in case of ereport() during parse
*/
ptserrcontext.callback = pts_error_callback;
ptserrcontext.arg = (void *) str;
ptserrcontext.previous = error_context_stack;
error_context_stack = &ptserrcontext;
raw_parsetree_list = raw_parser(buf.data);
error_context_stack = ptserrcontext.previous;
/*
* Make sure we got back exactly what we expected and no more; paranoia is
* justified since the string might contain anything.
*/
if (list_length(raw_parsetree_list) != 1)
goto fail;
stmt = (SelectStmt *) linitial(raw_parsetree_list);
if (stmt == NULL ||
!IsA(stmt, SelectStmt) ||
stmt->distinctClause != NIL ||
stmt->intoClause != NULL ||
stmt->fromClause != NIL ||
stmt->whereClause != NULL ||
stmt->groupClause != NIL ||
stmt->havingClause != NULL ||
stmt->windowClause != NIL ||
stmt->valuesLists != NIL ||
stmt->sortClause != NIL ||
stmt->limitOffset != NULL ||
stmt->limitCount != NULL ||
stmt->lockingClause != NIL ||
stmt->withClause != NULL ||
stmt->op != SETOP_NONE)
goto fail;
if (list_length(stmt->targetList) != 1)
goto fail;
restarget = (ResTarget *) linitial(stmt->targetList);
if (restarget == NULL ||
!IsA(restarget, ResTarget) ||
restarget->name != NULL ||
restarget->indirection != NIL)
goto fail;
typecast = (TypeCast *) restarget->val;
if (typecast == NULL ||
!IsA(typecast, TypeCast) ||
typecast->arg == NULL ||
!IsA(typecast->arg, A_Const))
goto fail;
typeName = typecast->typeName;
if (typeName == NULL ||
!IsA(typeName, TypeName))
goto fail;
if (typeName->setof)
goto fail;
typenameTypeIdAndMod(NULL, typeName, typeid_p, typmod_p);
pfree(buf.data);
return;
fail:
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("invalid type name \"%s\"", str)));
}
Definition at line 585 of file parse_type.c.
References datumIsEqual(), elog, GETSTRUCT, getTypeIOParam(), NameStr, OidInputFunctionCall(), and WARNING.
Referenced by coerce_type().
{
Form_pg_type typform = (Form_pg_type) GETSTRUCT(tp);
Oid typinput = typform->typinput;
Oid typioparam = getTypeIOParam(tp);
Datum result;
result = OidInputFunctionCall(typinput, string,
typioparam, atttypmod);
#ifdef RANDOMIZE_ALLOCATED_MEMORY
/*
* For pass-by-reference data types, repeat the conversion to see if the
* input function leaves any uninitialized bytes in the result. We can
* only detect that reliably if RANDOMIZE_ALLOCATED_MEMORY is enabled, so
* we don't bother testing otherwise. The reason we don't want any
* instability in the input function is that comparison of Const nodes
* relies on bytewise comparison of the datums, so if the input function
* leaves garbage then subexpressions that should be identical may not get
* recognized as such. See pgsql-hackers discussion of 2008-04-04.
*/
if (string && !typform->typbyval)
{
Datum result2;
result2 = OidInputFunctionCall(typinput, string,
typioparam, atttypmod);
if (!datumIsEqual(result, result2, typform->typbyval, typform->typlen))
elog(WARNING, "type %s has unstable input conversion for \"%s\"",
NameStr(typform->typname), string);
}
#endif
return result;
}
Definition at line 540 of file parse_type.c.
References GETSTRUCT.
Referenced by coerce_type().
{
Form_pg_type typ;
typ = (Form_pg_type) GETSTRUCT(t);
return typ->typbyval;
}
Definition at line 509 of file parse_type.c.
References elog, ERROR, HeapTupleIsValid, ObjectIdGetDatum, SearchSysCache1, and TYPEOID.
Referenced by coerce_type(), and find_typmod_coercion_function().
{
HeapTuple tup;
tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(id));
if (!HeapTupleIsValid(tup))
elog(ERROR, "cache lookup failed for type %u", id);
return (Type) tup;
}
Definition at line 624 of file parse_type.c.
References elog, ERROR, GETSTRUCT, HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), SearchSysCache1, and TYPEOID.
Referenced by get_rte_attribute_is_dropped(), PLy_input_tuple_funcs(), PLy_output_tuple_funcs(), ProcedureCreate(), transformAssignmentIndirection(), typeInheritsFrom(), and typeIsOfTypedTable().
{
HeapTuple typeTuple;
Form_pg_type type;
Oid result;
typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type_id));
if (!HeapTupleIsValid(typeTuple))
elog(ERROR, "cache lookup failed for type %u", type_id);
type = (Form_pg_type) GETSTRUCT(typeTuple);
result = type->typrelid;
ReleaseSysCache(typeTuple);
return result;
}
Definition at line 530 of file parse_type.c.
References GETSTRUCT.
Referenced by coerce_type().
{
Form_pg_type typ;
typ = (Form_pg_type) GETSTRUCT(t);
return typ->typlen;
}
| char* TypeNameListToString | ( | List * | typenames | ) |
Definition at line 422 of file parse_type.c.
References appendStringInfoChar(), appendTypeNameToBuffer(), Assert, initStringInfo(), IsA, lfirst, and list_head().
Referenced by does_not_exist_skipping().
{
StringInfoData string;
ListCell *l;
initStringInfo(&string);
foreach(l, typenames)
{
TypeName *typeName = (TypeName *) lfirst(l);
Assert(IsA(typeName, TypeName));
if (l != list_head(typenames))
appendStringInfoChar(&string, ',');
appendTypeNameToBuffer(typeName, &string);
}
return string.data;
}
| char* TypeNameToString | ( | const TypeName * | typeName | ) |
Definition at line 408 of file parse_type.c.
References appendTypeNameToBuffer(), and initStringInfo().
Referenced by AlterDomainDropConstraint(), AlterDomainValidateConstraint(), AlterTypeOwner(), compute_return_type(), CreateCast(), defGetString(), defGetTypeLength(), DefineAggregate(), DefineDomain(), DefineOpClass(), does_not_exist_skipping(), examine_parameter_list(), get_object_address_type(), LookupTypeName(), LookupTypeNameOid(), MergeAttributes(), typenameType(), and typenameTypeMod().
{
StringInfoData string;
initStringInfo(&string);
appendTypeNameToBuffer(typeName, &string);
return string.data;
}
| Type typenameType | ( | ParseState * | pstate, | |
| const TypeName * | typeName, | |||
| int32 * | typmod_p | |||
| ) |
Definition at line 195 of file parse_type.c.
References ereport, errcode(), errmsg(), ERROR, GETSTRUCT, TypeName::location, LookupTypeName(), NULL, parser_errposition(), and TypeNameToString().
Referenced by ATExecAddColumn(), ATExecAddOf(), ATExecAlterColumnType(), DefineDomain(), DefineType(), transformColumnType(), transformOfType(), typenameTypeId(), and typenameTypeIdAndMod().
{
Type tup;
tup = LookupTypeName(pstate, typeName, typmod_p);
if (tup == NULL)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("type \"%s\" does not exist",
TypeNameToString(typeName)),
parser_errposition(pstate, typeName->location)));
if (!((Form_pg_type) GETSTRUCT(tup))->typisdefined)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("type \"%s\" is only a shell",
TypeNameToString(typeName)),
parser_errposition(pstate, typeName->location)));
return tup;
}
| Oid typenameTypeId | ( | ParseState * | pstate, | |
| const TypeName * | typeName | |||
| ) |
Definition at line 222 of file parse_type.c.
References HeapTupleGetOid, NULL, ReleaseSysCache(), and typenameType().
Referenced by AlterDomainAddConstraint(), AlterDomainDefault(), AlterDomainDropConstraint(), AlterDomainNotNull(), AlterDomainValidateConstraint(), AlterEnum(), AlterTypeNamespace(), check_object_ownership(), CreateCast(), DefineAggregate(), DefineOpClass(), DefineOperator(), DefineRange(), DefineRelation(), DefineType(), does_not_exist_skipping(), get_object_address(), LookupOperNameTypeNames(), objectNamesToOids(), PrepareQuery(), processTypesSpec(), RenameConstraint(), RenameType(), and transformAExprOf().
{
Oid typoid;
Type tup;
tup = typenameType(pstate, typeName, NULL);
typoid = HeapTupleGetOid(tup);
ReleaseSysCache(tup);
return typoid;
}
| void typenameTypeIdAndMod | ( | ParseState * | pstate, | |
| const TypeName * | typeName, | |||
| Oid * | typeid_p, | |||
| int32 * | typmod_p | |||
| ) |
Definition at line 241 of file parse_type.c.
References HeapTupleGetOid, ReleaseSysCache(), and typenameType().
Referenced by addRangeTableEntryForFunction(), ATExecAddColumn(), ATPrepAlterColumnType(), BuildDescForRelation(), flatten_set_variable_args(), MergeAttributes(), parseTypeString(), transformExprRecurse(), transformTypeCast(), and transformXmlSerialize().
{
Type tup;
tup = typenameType(pstate, typeName, typmod_p);
*typeid_p = HeapTupleGetOid(tup);
ReleaseSysCache(tup);
}
Definition at line 571 of file parse_type.c.
References GETSTRUCT.
Referenced by coerce_type().
{
Form_pg_type typtup;
typtup = (Form_pg_type) GETSTRUCT(typ);
return typtup->typcollation;
}
Definition at line 521 of file parse_type.c.
References elog, ERROR, HeapTupleGetOid, and NULL.
Referenced by AlterTypeOwner(), compute_return_type(), examine_parameter_list(), FuncNameAsType(), get_object_address_type(), and LookupTypeNameOid().
{
if (tp == NULL) /* probably useless */
elog(ERROR, "typeTypeId() called with NULL type struct");
return HeapTupleGetOid(tp);
}
| char* typeTypeName | ( | Type | t | ) |
Definition at line 550 of file parse_type.c.
References GETSTRUCT, NameStr, and pstrdup().
{
Form_pg_type typ;
typ = (Form_pg_type) GETSTRUCT(t);
/* pstrdup here because result may need to outlive the syscache entry */
return pstrdup(NameStr(typ->typname));
}
Definition at line 561 of file parse_type.c.
References GETSTRUCT.
Referenced by FuncNameAsType().
{
Form_pg_type typtup;
typtup = (Form_pg_type) GETSTRUCT(typ);
return typtup->typrelid;
}
1.7.1