PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
parse_type.c File Reference
#include "postgres.h"
#include "access/htup_details.h"
#include "catalog/namespace.h"
#include "catalog/pg_type.h"
#include "lib/stringinfo.h"
#include "nodes/makefuncs.h"
#include "parser/parser.h"
#include "parser/parse_type.h"
#include "utils/array.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
#include "utils/syscache.h"
Include dependency graph for parse_type.c:

Go to the source code of this file.

Functions

static int32 typenameTypeMod (ParseState *pstate, const TypeName *typeName, Type typ)
 
Type LookupTypeName (ParseState *pstate, const TypeName *typeName, int32 *typmod_p, bool missing_ok)
 
Oid LookupTypeNameOid (ParseState *pstate, const TypeName *typeName, bool missing_ok)
 
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)
 
static void appendTypeNameToBuffer (const TypeName *typeName, StringInfo string)
 
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)
 
static void pts_error_callback (void *arg)
 
TypeNametypeStringToTypeName (const char *str)
 
void parseTypeString (const char *str, Oid *typeid_p, int32 *typmod_p, bool missing_ok)
 

Function Documentation

static void appendTypeNameToBuffer ( const TypeName typeName,
StringInfo  string 
)
static

Definition at line 420 of file parse_type.c.

References appendStringInfoChar(), appendStringInfoString(), TypeName::arrayBounds, format_type_be(), lfirst, list_head(), TypeName::names, NIL, TypeName::pct_type, strVal, and TypeName::typeOid.

Referenced by TypeNameListToString(), and TypeNameToString().

421 {
422  if (typeName->names != NIL)
423  {
424  /* Emit possibly-qualified name as-is */
425  ListCell *l;
426 
427  foreach(l, typeName->names)
428  {
429  if (l != list_head(typeName->names))
430  appendStringInfoChar(string, '.');
431  appendStringInfoString(string, strVal(lfirst(l)));
432  }
433  }
434  else
435  {
436  /* Look up internally-specified type */
437  appendStringInfoString(string, format_type_be(typeName->typeOid));
438  }
439 
440  /*
441  * Add decoration as needed, but only for fields considered by
442  * LookupTypeName
443  */
444  if (typeName->pct_type)
445  appendStringInfoString(string, "%TYPE");
446 
447  if (typeName->arrayBounds != NIL)
448  appendStringInfoString(string, "[]");
449 }
#define NIL
Definition: pg_list.h:69
Oid typeOid
Definition: parsenodes.h:209
List * names
Definition: parsenodes.h:208
#define strVal(v)
Definition: value.h:54
char * format_type_be(Oid type_oid)
Definition: format_type.c:94
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:157
static ListCell * list_head(const List *l)
Definition: pg_list.h:77
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:169
#define lfirst(lc)
Definition: pg_list.h:106
List * arrayBounds
Definition: parsenodes.h:214
bool pct_type
Definition: parsenodes.h:211
Oid GetColumnDefCollation ( ParseState pstate,
ColumnDef coldef,
Oid  typeOid 
)

Definition at line 521 of file parse_type.c.

References ColumnDef::collClause, CollateClause::collname, ColumnDef::collOid, ereport, errcode(), errmsg(), ERROR, format_type_be(), get_typcollation(), CollateClause::location, ColumnDef::location, LookupCollation(), OidIsValid, and parser_errposition().

Referenced by addRangeTableEntryForFunction(), ATExecAddColumn(), ATExecAlterColumnType(), ATPrepAlterColumnType(), BuildDescForRelation(), and MergeAttributes().

522 {
523  Oid result;
524  Oid typcollation = get_typcollation(typeOid);
525  int location = coldef->location;
526 
527  if (coldef->collClause)
528  {
529  /* We have a raw COLLATE clause, so look up the collation */
530  location = coldef->collClause->location;
531  result = LookupCollation(pstate, coldef->collClause->collname,
532  location);
533  }
534  else if (OidIsValid(coldef->collOid))
535  {
536  /* Precooked collation spec, use that */
537  result = coldef->collOid;
538  }
539  else
540  {
541  /* Use the type's default collation if any */
542  result = typcollation;
543  }
544 
545  /* Complain if COLLATE is applied to an uncollatable type */
546  if (OidIsValid(result) && !OidIsValid(typcollation))
547  ereport(ERROR,
548  (errcode(ERRCODE_DATATYPE_MISMATCH),
549  errmsg("collations are not supported by type %s",
550  format_type_be(typeOid)),
551  parser_errposition(pstate, location)));
552 
553  return result;
554 }
int errcode(int sqlerrcode)
Definition: elog.c:575
char * format_type_be(Oid type_oid)
Definition: format_type.c:94
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:532
#define ERROR
Definition: elog.h:43
Oid collOid
Definition: parsenodes.h:651
int location
Definition: parsenodes.h:654
#define ereport(elevel, rest)
Definition: elog.h:122
Oid LookupCollation(ParseState *pstate, List *collnames, int location)
Definition: parse_type.c:496
Oid get_typcollation(Oid typid)
Definition: lsyscache.c:2781
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:111
CollateClause * collClause
Definition: parsenodes.h:650
List * collname
Definition: parsenodes.h:309
int errmsg(const char *fmt,...)
Definition: elog.c:797
Oid LookupCollation ( ParseState pstate,
List collnames,
int  location 
)

Definition at line 496 of file parse_type.c.

References cancel_parser_errposition_callback(), get_collation_oid(), and setup_parser_errposition_callback().

Referenced by GetColumnDefCollation(), resolve_unique_index_expr(), transformCollateClause(), and transformColumnType().

497 {
498  Oid colloid;
499  ParseCallbackState pcbstate;
500 
501  if (pstate)
502  setup_parser_errposition_callback(&pcbstate, pstate, location);
503 
504  colloid = get_collation_oid(collnames, false);
505 
506  if (pstate)
508 
509  return colloid;
510 }
unsigned int Oid
Definition: postgres_ext.h:31
void cancel_parser_errposition_callback(ParseCallbackState *pcbstate)
Definition: parse_node.c:161
void setup_parser_errposition_callback(ParseCallbackState *pcbstate, ParseState *pstate, int location)
Definition: parse_node.c:145
Oid get_collation_oid(List *name, bool missing_ok)
Definition: namespace.c:3493
Type LookupTypeName ( ParseState pstate,
const TypeName typeName,
int32 typmod_p,
bool  missing_ok 
)

Definition at line 57 of file parse_type.c.

References TypeName::arrayBounds, Assert, cancel_parser_errposition_callback(), RangeVar::catalogname, DeconstructQualifiedName(), elog, ereport, errcode(), errmsg(), ERROR, format_type_be(), get_array_type(), get_attnum(), get_atttype(), GetSysCacheOid2, HeapTupleIsValid, InvalidAttrNumber, InvalidOid, lfourth, linitial, list_length(), TypeName::location, LookupExplicitNamespace(), lsecond, lthird, makeRangeVar(), NameListToString(), TypeName::names, NIL, NoLock, NOTICE, ObjectIdGetDatum, OidIsValid, parser_errposition(), TypeName::pct_type, PointerGetDatum, RangeVarGetRelid, RangeVar::relname, RangeVar::schemaname, SearchSysCache1(), setup_parser_errposition_callback(), strVal, TypenameGetTypid(), TYPENAMENSP, TypeNameToString(), typenameTypeMod(), TYPEOID, and TypeName::typeOid.

Referenced by AlterTypeOwner(), compute_return_type(), FuncNameAsType(), get_object_address_type(), interpret_function_parameter_list(), LookupTypeNameOid(), parseTypeString(), plpgsql_parse_wordtype(), and typenameType().

59 {
60  Oid typoid;
61  HeapTuple tup;
62  int32 typmod;
63 
64  if (typeName->names == NIL)
65  {
66  /* We have the OID already if it's an internally generated TypeName */
67  typoid = typeName->typeOid;
68  }
69  else if (typeName->pct_type)
70  {
71  /* Handle %TYPE reference to type of an existing field */
72  RangeVar *rel = makeRangeVar(NULL, NULL, typeName->location);
73  char *field = NULL;
74  Oid relid;
75  AttrNumber attnum;
76 
77  /* deconstruct the name list */
78  switch (list_length(typeName->names))
79  {
80  case 1:
81  ereport(ERROR,
82  (errcode(ERRCODE_SYNTAX_ERROR),
83  errmsg("improper %%TYPE reference (too few dotted names): %s",
84  NameListToString(typeName->names)),
85  parser_errposition(pstate, typeName->location)));
86  break;
87  case 2:
88  rel->relname = strVal(linitial(typeName->names));
89  field = strVal(lsecond(typeName->names));
90  break;
91  case 3:
92  rel->schemaname = strVal(linitial(typeName->names));
93  rel->relname = strVal(lsecond(typeName->names));
94  field = strVal(lthird(typeName->names));
95  break;
96  case 4:
97  rel->catalogname = strVal(linitial(typeName->names));
98  rel->schemaname = strVal(lsecond(typeName->names));
99  rel->relname = strVal(lthird(typeName->names));
100  field = strVal(lfourth(typeName->names));
101  break;
102  default:
103  ereport(ERROR,
104  (errcode(ERRCODE_SYNTAX_ERROR),
105  errmsg("improper %%TYPE reference (too many dotted names): %s",
106  NameListToString(typeName->names)),
107  parser_errposition(pstate, typeName->location)));
108  break;
109  }
110 
111  /*
112  * Look up the field.
113  *
114  * XXX: As no lock is taken here, this might fail in the presence of
115  * concurrent DDL. But taking a lock would carry a performance
116  * penalty and would also require a permissions check.
117  */
118  relid = RangeVarGetRelid(rel, NoLock, missing_ok);
119  attnum = get_attnum(relid, field);
120  if (attnum == InvalidAttrNumber)
121  {
122  if (missing_ok)
123  typoid = InvalidOid;
124  else
125  ereport(ERROR,
126  (errcode(ERRCODE_UNDEFINED_COLUMN),
127  errmsg("column \"%s\" of relation \"%s\" does not exist",
128  field, rel->relname),
129  parser_errposition(pstate, typeName->location)));
130  }
131  else
132  {
133  typoid = get_atttype(relid, attnum);
134 
135  /* this construct should never have an array indicator */
136  Assert(typeName->arrayBounds == NIL);
137 
138  /* emit nuisance notice (intentionally not errposition'd) */
139  ereport(NOTICE,
140  (errmsg("type reference %s converted to %s",
141  TypeNameToString(typeName),
142  format_type_be(typoid))));
143  }
144  }
145  else
146  {
147  /* Normal reference to a type name */
148  char *schemaname;
149  char *typname;
150 
151  /* deconstruct the name list */
152  DeconstructQualifiedName(typeName->names, &schemaname, &typname);
153 
154  if (schemaname)
155  {
156  /* Look in specific schema only */
157  Oid namespaceId;
158  ParseCallbackState pcbstate;
159 
160  setup_parser_errposition_callback(&pcbstate, pstate, typeName->location);
161 
162  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
163  if (OidIsValid(namespaceId))
164  typoid = GetSysCacheOid2(TYPENAMENSP,
165  PointerGetDatum(typname),
166  ObjectIdGetDatum(namespaceId));
167  else
168  typoid = InvalidOid;
169 
171  }
172  else
173  {
174  /* Unqualified type name, so search the search path */
175  typoid = TypenameGetTypid(typname);
176  }
177 
178  /* If an array reference, return the array type instead */
179  if (typeName->arrayBounds != NIL)
180  typoid = get_array_type(typoid);
181  }
182 
183  if (!OidIsValid(typoid))
184  {
185  if (typmod_p)
186  *typmod_p = -1;
187  return NULL;
188  }
189 
190  tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typoid));
191  if (!HeapTupleIsValid(tup)) /* should not happen */
192  elog(ERROR, "cache lookup failed for type %u", typoid);
193 
194  typmod = typenameTypeMod(pstate, typeName, (Type) tup);
195 
196  if (typmod_p)
197  *typmod_p = typmod;
198 
199  return (Type) tup;
200 }
#define NIL
Definition: pg_list.h:69
Oid typeOid
Definition: parsenodes.h:209
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2853
List * names
Definition: parsenodes.h:208
Oid TypenameGetTypid(const char *typname)
Definition: namespace.c:748
#define PointerGetDatum(X)
Definition: postgres.h:562
#define RangeVarGetRelid(relation, lockmode, missing_ok)
Definition: namespace.h:53
char * TypeNameToString(const TypeName *typeName)
Definition: parse_type.c:459
Oid get_array_type(Oid typid)
Definition: lsyscache.c:2512
#define strVal(v)
Definition: value.h:54
int errcode(int sqlerrcode)
Definition: elog.c:575
char * format_type_be(Oid type_oid)
Definition: format_type.c:94
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2769
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:532
#define lsecond(l)
Definition: pg_list.h:116
signed int int32
Definition: c.h:246
#define GetSysCacheOid2(cacheId, key1, key2)
Definition: syscache.h:193
char * schemaname
Definition: primnodes.h:67
char * relname
Definition: primnodes.h:68
void cancel_parser_errposition_callback(ParseCallbackState *pcbstate)
Definition: parse_node.c:161
#define linitial(l)
Definition: pg_list.h:111
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define NoLock
Definition: lockdefs.h:34
AttrNumber get_attnum(Oid relid, const char *attname)
Definition: lsyscache.c:821
Oid get_atttype(Oid relid, AttrNumber attnum)
Definition: lsyscache.c:878
#define ereport(elevel, rest)
Definition: elog.h:122
void setup_parser_errposition_callback(ParseCallbackState *pcbstate, ParseState *pstate, int location)
Definition: parse_node.c:145
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
char * NameListToString(List *names)
Definition: namespace.c:3063
#define InvalidOid
Definition: postgres_ext.h:36
#define NOTICE
Definition: elog.h:37
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define Assert(condition)
Definition: c.h:681
#define lfourth(l)
Definition: pg_list.h:126
int location
Definition: parsenodes.h:215
static int list_length(const List *l)
Definition: pg_list.h:89
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:111
#define InvalidAttrNumber
Definition: attnum.h:23
List * arrayBounds
Definition: parsenodes.h:214
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define lthird(l)
Definition: pg_list.h:121
#define elog
Definition: elog.h:219
int16 AttrNumber
Definition: attnum.h:21
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
Definition: makefuncs.c:419
char * catalogname
Definition: primnodes.h:66
static int32 typenameTypeMod(ParseState *pstate, const TypeName *typeName, Type typ)
Definition: parse_type.c:315
bool pct_type
Definition: parsenodes.h:211
Oid LookupTypeNameOid ( ParseState pstate,
const TypeName typeName,
bool  missing_ok 
)

Definition at line 215 of file parse_type.c.

References ereport, errcode(), errmsg(), ERROR, HeapTupleGetOid, InvalidOid, TypeName::location, LookupTypeName(), parser_errposition(), ReleaseSysCache(), and TypeNameToString().

Referenced by get_object_address(), LookupAggWithArgs(), LookupFuncWithArgs(), LookupOperWithArgs(), and type_in_list_does_not_exist_skipping().

216 {
217  Oid typoid;
218  Type tup;
219 
220  tup = LookupTypeName(pstate, typeName, NULL, missing_ok);
221  if (tup == NULL)
222  {
223  if (!missing_ok)
224  ereport(ERROR,
225  (errcode(ERRCODE_UNDEFINED_OBJECT),
226  errmsg("type \"%s\" does not exist",
227  TypeNameToString(typeName)),
228  parser_errposition(pstate, typeName->location)));
229 
230  return InvalidOid;
231  }
232 
233  typoid = HeapTupleGetOid(tup);
234  ReleaseSysCache(tup);
235 
236  return typoid;
237 }
Type LookupTypeName(ParseState *pstate, const TypeName *typeName, int32 *typmod_p, bool missing_ok)
Definition: parse_type.c:57
char * TypeNameToString(const TypeName *typeName)
Definition: parse_type.c:459
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
#define InvalidOid
Definition: postgres_ext.h:36
int location
Definition: parsenodes.h:215
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:111
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
void parseTypeString ( const char *  str,
Oid typeid_p,
int32 typmod_p,
bool  missing_ok 
)

Definition at line 781 of file parse_type.c.

References ereport, errcode(), errmsg(), ERROR, GETSTRUCT, HeapTupleGetOid, InvalidOid, TypeName::location, LookupTypeName(), parser_errposition(), ReleaseSysCache(), TypeNameToString(), and typeStringToTypeName().

Referenced by parseNameAndArgTypes(), plperl_spi_prepare(), pltcl_SPI_prepare(), PLy_spi_prepare(), regtypein(), and to_regtype().

782 {
783  TypeName *typeName;
784  Type tup;
785 
786  typeName = typeStringToTypeName(str);
787 
788  tup = LookupTypeName(NULL, typeName, typmod_p, missing_ok);
789  if (tup == NULL)
790  {
791  if (!missing_ok)
792  ereport(ERROR,
793  (errcode(ERRCODE_UNDEFINED_OBJECT),
794  errmsg("type \"%s\" does not exist",
795  TypeNameToString(typeName)),
796  parser_errposition(NULL, typeName->location)));
797  *typeid_p = InvalidOid;
798  }
799  else
800  {
801  if (!((Form_pg_type) GETSTRUCT(tup))->typisdefined)
802  ereport(ERROR,
803  (errcode(ERRCODE_UNDEFINED_OBJECT),
804  errmsg("type \"%s\" is only a shell",
805  TypeNameToString(typeName)),
806  parser_errposition(NULL, typeName->location)));
807  *typeid_p = HeapTupleGetOid(tup);
808  ReleaseSysCache(tup);
809  }
810 }
Type LookupTypeName(ParseState *pstate, const TypeName *typeName, int32 *typmod_p, bool missing_ok)
Definition: parse_type.c:57
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
char * TypeNameToString(const TypeName *typeName)
Definition: parse_type.c:459
int errcode(int sqlerrcode)
Definition: elog.c:575
FormData_pg_type * Form_pg_type
Definition: pg_type.h:233
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
TypeName * typeStringToTypeName(const char *str)
Definition: parse_type.c:687
#define InvalidOid
Definition: postgres_ext.h:36
int location
Definition: parsenodes.h:215
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:111
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
static void pts_error_callback ( void *  arg)
static

Definition at line 666 of file parse_type.c.

References errcontext, and errposition().

Referenced by typeStringToTypeName().

667 {
668  const char *str = (const char *) arg;
669 
670  errcontext("invalid type name \"%s\"", str);
671 
672  /*
673  * Currently we just suppress any syntax error position report, rather
674  * than transforming to an "internal query" error. It's unlikely that a
675  * type name is complex enough to need positioning.
676  */
677  errposition(0);
678 }
#define errcontext
Definition: elog.h:164
void * arg
int errposition(int cursorpos)
Definition: elog.c:1125
Datum stringTypeDatum ( Type  tp,
char *  string,
int32  atttypmod 
)

Definition at line 635 of file parse_type.c.

References GETSTRUCT, getTypeIOParam(), and OidInputFunctionCall().

Referenced by coerce_type().

636 {
637  Form_pg_type typform = (Form_pg_type) GETSTRUCT(tp);
638  Oid typinput = typform->typinput;
639  Oid typioparam = getTypeIOParam(tp);
640 
641  return OidInputFunctionCall(typinput, string, typioparam, atttypmod);
642 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
FormData_pg_type * Form_pg_type
Definition: pg_type.h:233
unsigned int Oid
Definition: postgres_ext.h:31
Oid getTypeIOParam(HeapTuple typeTuple)
Definition: lsyscache.c:2053
Datum OidInputFunctionCall(Oid functionId, char *str, Oid typioparam, int32 typmod)
Definition: fmgr.c:1733
bool typeByVal ( Type  t)

Definition at line 590 of file parse_type.c.

References GETSTRUCT.

Referenced by coerce_type().

591 {
592  Form_pg_type typ;
593 
594  typ = (Form_pg_type) GETSTRUCT(t);
595  return typ->typbyval;
596 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
FormData_pg_type * Form_pg_type
Definition: pg_type.h:233
Type typeidType ( Oid  id)

Definition at line 559 of file parse_type.c.

References elog, ERROR, HeapTupleIsValid, ObjectIdGetDatum, SearchSysCache1(), and TYPEOID.

Referenced by coerce_type(), and find_typmod_coercion_function().

560 {
561  HeapTuple tup;
562 
564  if (!HeapTupleIsValid(tup))
565  elog(ERROR, "cache lookup failed for type %u", id);
566  return (Type) tup;
567 }
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define elog
Definition: elog.h:219
Oid typeidTypeRelid ( Oid  type_id)

Definition at line 646 of file parse_type.c.

References elog, ERROR, GETSTRUCT, HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), SearchSysCache1(), and TYPEOID.

Referenced by PLy_input_tuple_funcs(), PLy_output_tuple_funcs(), ProcedureCreate(), transformAssignmentIndirection(), typeInheritsFrom(), and typeIsOfTypedTable().

647 {
648  HeapTuple typeTuple;
649  Form_pg_type type;
650  Oid result;
651 
652  typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type_id));
653  if (!HeapTupleIsValid(typeTuple))
654  elog(ERROR, "cache lookup failed for type %u", type_id);
655 
656  type = (Form_pg_type) GETSTRUCT(typeTuple);
657  result = type->typrelid;
658  ReleaseSysCache(typeTuple);
659  return result;
660 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
FormData_pg_type * Form_pg_type
Definition: pg_type.h:233
unsigned int Oid
Definition: postgres_ext.h:31
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define elog
Definition: elog.h:219
int16 typeLen ( Type  t)

Definition at line 580 of file parse_type.c.

References GETSTRUCT.

Referenced by coerce_type().

581 {
582  Form_pg_type typ;
583 
584  typ = (Form_pg_type) GETSTRUCT(t);
585  return typ->typlen;
586 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
FormData_pg_type * Form_pg_type
Definition: pg_type.h:233
char* TypeNameListToString ( List typenames)

Definition at line 473 of file parse_type.c.

References appendStringInfoChar(), appendTypeNameToBuffer(), initStringInfo(), lfirst_node, and list_head().

Referenced by does_not_exist_skipping().

474 {
476  ListCell *l;
477 
478  initStringInfo(&string);
479  foreach(l, typenames)
480  {
481  TypeName *typeName = lfirst_node(TypeName, l);
482 
483  if (l != list_head(typenames))
484  appendStringInfoChar(&string, ',');
485  appendTypeNameToBuffer(typeName, &string);
486  }
487  return string.data;
488 }
#define lfirst_node(type, lc)
Definition: pg_list.h:109
char string[11]
Definition: preproc-type.c:46
static ListCell * list_head(const List *l)
Definition: pg_list.h:77
static void appendTypeNameToBuffer(const TypeName *typeName, StringInfo string)
Definition: parse_type.c:420
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:169
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
Type typenameType ( ParseState pstate,
const TypeName typeName,
int32 typmod_p 
)

Definition at line 247 of file parse_type.c.

References ereport, errcode(), errmsg(), ERROR, GETSTRUCT, TypeName::location, LookupTypeName(), parser_errposition(), and TypeNameToString().

Referenced by ATExecAddColumn(), ATExecAddOf(), ATExecAlterColumnType(), DefineDomain(), DefineType(), transformColumnDefinition(), transformColumnType(), transformOfType(), typenameTypeId(), and typenameTypeIdAndMod().

248 {
249  Type tup;
250 
251  tup = LookupTypeName(pstate, typeName, typmod_p, false);
252  if (tup == NULL)
253  ereport(ERROR,
254  (errcode(ERRCODE_UNDEFINED_OBJECT),
255  errmsg("type \"%s\" does not exist",
256  TypeNameToString(typeName)),
257  parser_errposition(pstate, typeName->location)));
258  if (!((Form_pg_type) GETSTRUCT(tup))->typisdefined)
259  ereport(ERROR,
260  (errcode(ERRCODE_UNDEFINED_OBJECT),
261  errmsg("type \"%s\" is only a shell",
262  TypeNameToString(typeName)),
263  parser_errposition(pstate, typeName->location)));
264  return tup;
265 }
Type LookupTypeName(ParseState *pstate, const TypeName *typeName, int32 *typmod_p, bool missing_ok)
Definition: parse_type.c:57
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
char * TypeNameToString(const TypeName *typeName)
Definition: parse_type.c:459
int errcode(int sqlerrcode)
Definition: elog.c:575
FormData_pg_type * Form_pg_type
Definition: pg_type.h:233
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
int location
Definition: parsenodes.h:215
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:111
int errmsg(const char *fmt,...)
Definition: elog.c:797
Oid typenameTypeId ( ParseState pstate,
const TypeName typeName 
)

Definition at line 274 of file parse_type.c.

References HeapTupleGetOid, ReleaseSysCache(), and typenameType().

Referenced by AlterDomainAddConstraint(), AlterDomainDefault(), AlterDomainDropConstraint(), AlterDomainNotNull(), AlterDomainValidateConstraint(), AlterEnum(), AlterTypeNamespace(), check_object_ownership(), CreateCast(), CreateFunction(), CreateTransform(), DefineAggregate(), DefineOpClass(), DefineOperator(), DefineRange(), DefineRelation(), DefineType(), init_params(), objectNamesToOids(), PrepareQuery(), processTypesSpec(), RenameConstraint(), RenameType(), transformAExprOf(), and transformAlterTableStmt().

275 {
276  Oid typoid;
277  Type tup;
278 
279  tup = typenameType(pstate, typeName, NULL);
280  typoid = HeapTupleGetOid(tup);
281  ReleaseSysCache(tup);
282 
283  return typoid;
284 }
Type typenameType(ParseState *pstate, const TypeName *typeName, int32 *typmod_p)
Definition: parse_type.c:247
unsigned int Oid
Definition: postgres_ext.h:31
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
void typenameTypeIdAndMod ( ParseState pstate,
const TypeName typeName,
Oid typeid_p,
int32 typmod_p 
)

Definition at line 293 of file parse_type.c.

References HeapTupleGetOid, ReleaseSysCache(), and typenameType().

Referenced by addRangeTableEntryForFunction(), ATExecAddColumn(), ATPrepAlterColumnType(), BuildDescForRelation(), flatten_set_variable_args(), MergeAttributes(), transformRangeTableFunc(), transformTypeCast(), and transformXmlSerialize().

295 {
296  Type tup;
297 
298  tup = typenameType(pstate, typeName, typmod_p);
299  *typeid_p = HeapTupleGetOid(tup);
300  ReleaseSysCache(tup);
301 }
Type typenameType(ParseState *pstate, const TypeName *typeName, int32 *typmod_p)
Definition: parse_type.c:247
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
static int32 typenameTypeMod ( ParseState pstate,
const TypeName typeName,
Type  typ 
)
static

Definition at line 315 of file parse_type.c.

References cancel_parser_errposition_callback(), construct_array(), CStringGetDatum, CSTRINGOID, DatumGetInt32, ereport, errcode(), errmsg(), ERROR, ColumnRef::fields, GETSTRUCT, InvalidOid, IsA, Value::ValUnion::ival, lfirst, linitial, list_length(), TypeName::location, NIL, OidFunctionCall1, palloc(), parser_errposition(), pfree(), PointerGetDatum, psprintf(), setup_parser_errposition_callback(), Value::ValUnion::str, strVal, tm, TypeName::typemod, TypeNameToString(), TypeName::typmods, Value::val, and A_Const::val.

Referenced by LookupTypeName().

316 {
317  int32 result;
318  Oid typmodin;
319  Datum *datums;
320  int n;
321  ListCell *l;
322  ArrayType *arrtypmod;
323  ParseCallbackState pcbstate;
324 
325  /* Return prespecified typmod if no typmod expressions */
326  if (typeName->typmods == NIL)
327  return typeName->typemod;
328 
329  /*
330  * Else, type had better accept typmods. We give a special error message
331  * for the shell-type case, since a shell couldn't possibly have a
332  * typmodin function.
333  */
334  if (!((Form_pg_type) GETSTRUCT(typ))->typisdefined)
335  ereport(ERROR,
336  (errcode(ERRCODE_SYNTAX_ERROR),
337  errmsg("type modifier cannot be specified for shell type \"%s\"",
338  TypeNameToString(typeName)),
339  parser_errposition(pstate, typeName->location)));
340 
341  typmodin = ((Form_pg_type) GETSTRUCT(typ))->typmodin;
342 
343  if (typmodin == InvalidOid)
344  ereport(ERROR,
345  (errcode(ERRCODE_SYNTAX_ERROR),
346  errmsg("type modifier is not allowed for type \"%s\"",
347  TypeNameToString(typeName)),
348  parser_errposition(pstate, typeName->location)));
349 
350  /*
351  * Convert the list of raw-grammar-output expressions to a cstring array.
352  * Currently, we allow simple numeric constants, string literals, and
353  * identifiers; possibly this list could be extended.
354  */
355  datums = (Datum *) palloc(list_length(typeName->typmods) * sizeof(Datum));
356  n = 0;
357  foreach(l, typeName->typmods)
358  {
359  Node *tm = (Node *) lfirst(l);
360  char *cstr = NULL;
361 
362  if (IsA(tm, A_Const))
363  {
364  A_Const *ac = (A_Const *) tm;
365 
366  if (IsA(&ac->val, Integer))
367  {
368  cstr = psprintf("%ld", (long) ac->val.val.ival);
369  }
370  else if (IsA(&ac->val, Float) ||
371  IsA(&ac->val, String))
372  {
373  /* we can just use the str field directly. */
374  cstr = ac->val.val.str;
375  }
376  }
377  else if (IsA(tm, ColumnRef))
378  {
379  ColumnRef *cr = (ColumnRef *) tm;
380 
381  if (list_length(cr->fields) == 1 &&
382  IsA(linitial(cr->fields), String))
383  cstr = strVal(linitial(cr->fields));
384  }
385  if (!cstr)
386  ereport(ERROR,
387  (errcode(ERRCODE_SYNTAX_ERROR),
388  errmsg("type modifiers must be simple constants or identifiers"),
389  parser_errposition(pstate, typeName->location)));
390  datums[n++] = CStringGetDatum(cstr);
391  }
392 
393  /* hardwired knowledge about cstring's representation details here */
394  arrtypmod = construct_array(datums, n, CSTRINGOID,
395  -2, false, 'c');
396 
397  /* arrange to report location if type's typmodin function fails */
398  setup_parser_errposition_callback(&pcbstate, pstate, typeName->location);
399 
400  result = DatumGetInt32(OidFunctionCall1(typmodin,
401  PointerGetDatum(arrtypmod)));
402 
404 
405  pfree(datums);
406  pfree(arrtypmod);
407 
408  return result;
409 }
#define NIL
Definition: pg_list.h:69
#define IsA(nodeptr, _type_)
Definition: nodes.h:561
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define DatumGetInt32(X)
Definition: postgres.h:478
long ival
Definition: value.h:47
#define PointerGetDatum(X)
Definition: postgres.h:562
char * TypeNameToString(const TypeName *typeName)
Definition: parse_type.c:459
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
ArrayType * construct_array(Datum *elems, int nelems, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:3279
Definition: nodes.h:510
#define strVal(v)
Definition: value.h:54
int errcode(int sqlerrcode)
Definition: elog.c:575
FormData_pg_type * Form_pg_type
Definition: pg_type.h:233
unsigned int Oid
Definition: postgres_ext.h:31
signed int int32
Definition: c.h:246
static struct pg_tm tm
Definition: localtime.c:107
void pfree(void *pointer)
Definition: mcxt.c:949
void cancel_parser_errposition_callback(ParseCallbackState *pcbstate)
Definition: parse_node.c:161
#define linitial(l)
Definition: pg_list.h:111
#define ERROR
Definition: elog.h:43
#define OidFunctionCall1(functionId, arg1)
Definition: fmgr.h:623
union Value::ValUnion val
#define CStringGetDatum(X)
Definition: postgres.h:584
#define ereport(elevel, rest)
Definition: elog.h:122
void setup_parser_errposition_callback(ParseCallbackState *pcbstate, ParseState *pstate, int location)
Definition: parse_node.c:145
uintptr_t Datum
Definition: postgres.h:372
List * typmods
Definition: parsenodes.h:212
#define InvalidOid
Definition: postgres_ext.h:36
#define CSTRINGOID
Definition: pg_type.h:684
#define lfirst(lc)
Definition: pg_list.h:106
int location
Definition: parsenodes.h:215
static int list_length(const List *l)
Definition: pg_list.h:89
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:111
int32 typemod
Definition: parsenodes.h:213
void * palloc(Size size)
Definition: mcxt.c:848
int errmsg(const char *fmt,...)
Definition: elog.c:797
char * str
Definition: value.h:48
Value val
Definition: parsenodes.h:287
List * fields
Definition: parsenodes.h:234
TypeName* typeStringToTypeName ( const char *  str)

Definition at line 687 of file parse_type.c.

References appendStringInfo(), ErrorContextCallback::arg, TypeCast::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, linitial_node, list_length(), SelectStmt::lockingClause, ResTarget::name, NIL, SelectStmt::op, pfree(), ErrorContextCallback::previous, pts_error_callback(), raw_parser(), TypeName::setof, SETOP_NONE, SelectStmt::sortClause, SelectStmt::targetList, TypeCast::typeName, ResTarget::val, SelectStmt::valuesLists, SelectStmt::whereClause, SelectStmt::windowClause, and SelectStmt::withClause.

Referenced by parseTypeString(), and pg_get_object_address().

688 {
690  List *raw_parsetree_list;
691  SelectStmt *stmt;
692  ResTarget *restarget;
693  TypeCast *typecast;
694  TypeName *typeName;
695  ErrorContextCallback ptserrcontext;
696 
697  /* make sure we give useful error for empty input */
698  if (strspn(str, " \t\n\r\f") == strlen(str))
699  goto fail;
700 
701  initStringInfo(&buf);
702  appendStringInfo(&buf, "SELECT NULL::%s", str);
703 
704  /*
705  * Setup error traceback support in case of ereport() during parse
706  */
707  ptserrcontext.callback = pts_error_callback;
708  ptserrcontext.arg = (void *) str;
709  ptserrcontext.previous = error_context_stack;
710  error_context_stack = &ptserrcontext;
711 
712  raw_parsetree_list = raw_parser(buf.data);
713 
714  error_context_stack = ptserrcontext.previous;
715 
716  /*
717  * Make sure we got back exactly what we expected and no more; paranoia is
718  * justified since the string might contain anything.
719  */
720  if (list_length(raw_parsetree_list) != 1)
721  goto fail;
722  stmt = (SelectStmt *) linitial_node(RawStmt, raw_parsetree_list)->stmt;
723  if (stmt == NULL ||
724  !IsA(stmt, SelectStmt) ||
725  stmt->distinctClause != NIL ||
726  stmt->intoClause != NULL ||
727  stmt->fromClause != NIL ||
728  stmt->whereClause != NULL ||
729  stmt->groupClause != NIL ||
730  stmt->havingClause != NULL ||
731  stmt->windowClause != NIL ||
732  stmt->valuesLists != NIL ||
733  stmt->sortClause != NIL ||
734  stmt->limitOffset != NULL ||
735  stmt->limitCount != NULL ||
736  stmt->lockingClause != NIL ||
737  stmt->withClause != NULL ||
738  stmt->op != SETOP_NONE)
739  goto fail;
740  if (list_length(stmt->targetList) != 1)
741  goto fail;
742  restarget = (ResTarget *) linitial(stmt->targetList);
743  if (restarget == NULL ||
744  !IsA(restarget, ResTarget) ||
745  restarget->name != NULL ||
746  restarget->indirection != NIL)
747  goto fail;
748  typecast = (TypeCast *) restarget->val;
749  if (typecast == NULL ||
750  !IsA(typecast, TypeCast) ||
751  typecast->arg == NULL ||
752  !IsA(typecast->arg, A_Const))
753  goto fail;
754 
755  typeName = typecast->typeName;
756  if (typeName == NULL ||
757  !IsA(typeName, TypeName))
758  goto fail;
759  if (typeName->setof)
760  goto fail;
761 
762  pfree(buf.data);
763 
764  return typeName;
765 
766 fail:
767  ereport(ERROR,
768  (errcode(ERRCODE_SYNTAX_ERROR),
769  errmsg("invalid type name \"%s\"", str)));
770  return NULL; /* keep compiler quiet */
771 }
List * indirection
Definition: parsenodes.h:440
#define NIL
Definition: pg_list.h:69
#define IsA(nodeptr, _type_)
Definition: nodes.h:561
Node * val
Definition: parsenodes.h:441
List * raw_parser(const char *str)
Definition: parser.c:36
IntoClause * intoClause
Definition: parsenodes.h:1513
List * fromClause
Definition: parsenodes.h:1515
char * name
Definition: parsenodes.h:439
Node * limitOffset
Definition: parsenodes.h:1536
int errcode(int sqlerrcode)
Definition: elog.c:575
#define linitial_node(type, l)
Definition: pg_list.h:114
struct ErrorContextCallback * previous
Definition: elog.h:238
ErrorContextCallback * error_context_stack
Definition: elog.c:88
List * distinctClause
Definition: parsenodes.h:1511
void pfree(void *pointer)
Definition: mcxt.c:949
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
#define linitial(l)
Definition: pg_list.h:111
#define ERROR
Definition: elog.h:43
bool setof
Definition: parsenodes.h:210
static char * buf
Definition: pg_test_fsync.c:67
List * sortClause
Definition: parsenodes.h:1535
static void pts_error_callback(void *arg)
Definition: parse_type.c:666
List * targetList
Definition: parsenodes.h:1514
List * valuesLists
Definition: parsenodes.h:1529
#define ereport(elevel, rest)
Definition: elog.h:122
List * lockingClause
Definition: parsenodes.h:1538
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
TypeName * typeName
Definition: parsenodes.h:298
List * windowClause
Definition: parsenodes.h:1519
SetOperation op
Definition: parsenodes.h:1544
static int list_length(const List *l)
Definition: pg_list.h:89
List * groupClause
Definition: parsenodes.h:1517
void(* callback)(void *arg)
Definition: elog.h:239
int errmsg(const char *fmt,...)
Definition: elog.c:797
Node * havingClause
Definition: parsenodes.h:1518
WithClause * withClause
Definition: parsenodes.h:1539
Definition: pg_list.h:45
Node * limitCount
Definition: parsenodes.h:1537
Node * whereClause
Definition: parsenodes.h:1516
Node * arg
Definition: parsenodes.h:297
Oid typeTypeCollation ( Type  typ)

Definition at line 621 of file parse_type.c.

References GETSTRUCT.

Referenced by coerce_type().

622 {
623  Form_pg_type typtup;
624 
625  typtup = (Form_pg_type) GETSTRUCT(typ);
626  return typtup->typcollation;
627 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
FormData_pg_type * Form_pg_type
Definition: pg_type.h:233
Oid typeTypeId ( Type  tp)

Definition at line 571 of file parse_type.c.

References elog, ERROR, and HeapTupleGetOid.

Referenced by AlterTypeOwner(), compute_return_type(), FuncNameAsType(), get_object_address_type(), and interpret_function_parameter_list().

572 {
573  if (tp == NULL) /* probably useless */
574  elog(ERROR, "typeTypeId() called with NULL type struct");
575  return HeapTupleGetOid(tp);
576 }
#define ERROR
Definition: elog.h:43
#define elog
Definition: elog.h:219
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
char* typeTypeName ( Type  t)

Definition at line 600 of file parse_type.c.

References GETSTRUCT, NameStr, and pstrdup().

Referenced by coerce_type().

601 {
602  Form_pg_type typ;
603 
604  typ = (Form_pg_type) GETSTRUCT(t);
605  /* pstrdup here because result may need to outlive the syscache entry */
606  return pstrdup(NameStr(typ->typname));
607 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
char * pstrdup(const char *in)
Definition: mcxt.c:1076
FormData_pg_type * Form_pg_type
Definition: pg_type.h:233
#define NameStr(name)
Definition: c.h:493
Oid typeTypeRelid ( Type  typ)

Definition at line 611 of file parse_type.c.

References GETSTRUCT.

Referenced by FuncNameAsType().

612 {
613  Form_pg_type typtup;
614 
615  typtup = (Form_pg_type) GETSTRUCT(typ);
616  return typtup->typrelid;
617 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
FormData_pg_type * Form_pg_type
Definition: pg_type.h:233