1 /*-------------------------------------------------------------------------
4 * handle type operations for parser
6 * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
13 *-------------------------------------------------------------------------
17 #include "catalog/namespace.h"
18 #include "catalog/pg_type.h"
19 #include "lib/stringinfo.h"
20 #include "nodes/makefuncs.h"
21 #include "parser/parser.h"
22 #include "parser/parse_type.h"
23 #include "utils/array.h"
24 #include "utils/builtins.h"
25 #include "utils/datum.h"
26 #include "utils/lsyscache.h"
27 #include "utils/syscache.h"
30 static int32
typenameTypeMod(ParseState
*pstate
, const TypeName
*typename
,
36 * Given a TypeName object, lookup the pg_type syscache entry of the type.
37 * Returns NULL if no such type can be found. If the type is found,
38 * the typmod value represented in the TypeName struct is computed and
39 * stored into *typmod_p.
41 * NB: on success, the caller must ReleaseSysCache the type tuple when done
44 * NB: direct callers of this function MUST check typisdefined before assuming
45 * that the type is fully valid. Most code should go through typenameType
46 * or typenameTypeId instead.
48 * typmod_p can be passed as NULL if the caller does not care to know the
49 * typmod value, but the typmod decoration (if any) will be validated anyway,
50 * except in the case where the type is not found. Note that if the type is
51 * found but is a shell, and there is typmod decoration, an error will be
52 * thrown --- this is intentional.
54 * pstate is only used for error location info, and may be NULL.
57 LookupTypeName(ParseState
*pstate
, const TypeName
*typename
,
64 if (typename
->names
== NIL
)
66 /* We have the OID already if it's an internally generated TypeName */
67 typoid
= typename
->typeid;
69 else if (typename
->pct_type
)
71 /* Handle %TYPE reference to type of an existing field */
72 RangeVar
*rel
= makeRangeVar(NULL
, NULL
, typename
->location
);
77 /* deconstruct the name list */
78 switch (list_length(typename
->names
))
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
)));
88 rel
->relname
= strVal(linitial(typename
->names
));
89 field
= strVal(lsecond(typename
->names
));
92 rel
->schemaname
= strVal(linitial(typename
->names
));
93 rel
->relname
= strVal(lsecond(typename
->names
));
94 field
= strVal(lthird(typename
->names
));
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
));
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
)));
111 /* look up the field */
112 relid
= RangeVarGetRelid(rel
, false);
113 attnum
= get_attnum(relid
, field
);
114 if (attnum
== InvalidAttrNumber
)
116 (errcode(ERRCODE_UNDEFINED_COLUMN
),
117 errmsg("column \"%s\" of relation \"%s\" does not exist",
118 field
, rel
->relname
),
119 parser_errposition(pstate
, typename
->location
)));
120 typoid
= get_atttype(relid
, attnum
);
122 /* this construct should never have an array indicator */
123 Assert(typename
->arrayBounds
== NIL
);
125 /* emit nuisance notice (intentionally not errposition'd) */
127 (errmsg("type reference %s converted to %s",
128 TypeNameToString(typename
),
129 format_type_be(typoid
))));
133 /* Normal reference to a type name */
137 /* deconstruct the name list */
138 DeconstructQualifiedName(typename
->names
, &schemaname
, &typname
);
142 /* Look in specific schema only */
145 namespaceId
= LookupExplicitNamespace(schemaname
);
146 typoid
= GetSysCacheOid(TYPENAMENSP
,
147 PointerGetDatum(typname
),
148 ObjectIdGetDatum(namespaceId
),
153 /* Unqualified type name, so search the search path */
154 typoid
= TypenameGetTypid(typname
);
157 /* If an array reference, return the array type instead */
158 if (typename
->arrayBounds
!= NIL
)
159 typoid
= get_array_type(typoid
);
162 if (!OidIsValid(typoid
))
169 tup
= SearchSysCache(TYPEOID
,
170 ObjectIdGetDatum(typoid
),
172 if (!HeapTupleIsValid(tup
)) /* should not happen */
173 elog(ERROR
, "cache lookup failed for type %u", typoid
);
175 typmod
= typenameTypeMod(pstate
, typename
, (Type
) tup
);
184 * typenameType - given a TypeName, return a Type structure and typmod
186 * This is equivalent to LookupTypeName, except that this will report
187 * a suitable error message if the type cannot be found or is not defined.
188 * Callers of this can therefore assume the result is a fully valid type.
191 typenameType(ParseState
*pstate
, const TypeName
*typename
, int32
*typmod_p
)
195 tup
= LookupTypeName(pstate
, typename
, typmod_p
);
198 (errcode(ERRCODE_UNDEFINED_OBJECT
),
199 errmsg("type \"%s\" does not exist",
200 TypeNameToString(typename
)),
201 parser_errposition(pstate
, typename
->location
)));
202 if (!((Form_pg_type
) GETSTRUCT(tup
))->typisdefined
)
204 (errcode(ERRCODE_UNDEFINED_OBJECT
),
205 errmsg("type \"%s\" is only a shell",
206 TypeNameToString(typename
)),
207 parser_errposition(pstate
, typename
->location
)));
212 * typenameTypeId - given a TypeName, return the type's OID and typmod
214 * This is equivalent to typenameType, but we only hand back the type OID
215 * not the syscache entry.
218 typenameTypeId(ParseState
*pstate
, const TypeName
*typename
, int32
*typmod_p
)
223 tup
= typenameType(pstate
, typename
, typmod_p
);
224 typoid
= HeapTupleGetOid(tup
);
225 ReleaseSysCache(tup
);
231 * typenameTypeMod - given a TypeName, return the internal typmod value
233 * This will throw an error if the TypeName includes type modifiers that are
234 * illegal for the data type.
236 * The actual type OID represented by the TypeName must already have been
237 * looked up, and is passed as "typ".
239 * pstate is only used for error location info, and may be NULL.
242 typenameTypeMod(ParseState
*pstate
, const TypeName
*typename
, Type typ
)
249 ArrayType
*arrtypmod
;
250 ParseCallbackState pcbstate
;
252 /* Return prespecified typmod if no typmod expressions */
253 if (typename
->typmods
== NIL
)
254 return typename
->typemod
;
257 * Else, type had better accept typmods. We give a special error message
258 * for the shell-type case, since a shell couldn't possibly have a
261 if (!((Form_pg_type
) GETSTRUCT(typ
))->typisdefined
)
263 (errcode(ERRCODE_SYNTAX_ERROR
),
264 errmsg("type modifier cannot be specified for shell type \"%s\"",
265 TypeNameToString(typename
)),
266 parser_errposition(pstate
, typename
->location
)));
268 typmodin
= ((Form_pg_type
) GETSTRUCT(typ
))->typmodin
;
270 if (typmodin
== InvalidOid
)
272 (errcode(ERRCODE_SYNTAX_ERROR
),
273 errmsg("type modifier is not allowed for type \"%s\"",
274 TypeNameToString(typename
)),
275 parser_errposition(pstate
, typename
->location
)));
278 * Convert the list of raw-grammar-output expressions to a cstring array.
279 * Currently, we allow simple numeric constants, string literals, and
280 * identifiers; possibly this list could be extended.
282 datums
= (Datum
*) palloc(list_length(typename
->typmods
) * sizeof(Datum
));
284 foreach(l
, typename
->typmods
)
286 Node
*tm
= (Node
*) lfirst(l
);
289 if (IsA(tm
, A_Const
))
291 A_Const
*ac
= (A_Const
*) tm
;
293 if (IsA(&ac
->val
, Integer
))
295 cstr
= (char *) palloc(32);
296 snprintf(cstr
, 32, "%ld", (long) ac
->val
.val
.ival
);
298 else if (IsA(&ac
->val
, Float
) ||
299 IsA(&ac
->val
, String
))
301 /* we can just use the str field directly. */
302 cstr
= ac
->val
.val
.str
;
305 else if (IsA(tm
, ColumnRef
))
307 ColumnRef
*cr
= (ColumnRef
*) tm
;
309 if (list_length(cr
->fields
) == 1 &&
310 IsA(linitial(cr
->fields
), String
))
311 cstr
= strVal(linitial(cr
->fields
));
315 (errcode(ERRCODE_SYNTAX_ERROR
),
316 errmsg("type modifiers must be simple constants or identifiers"),
317 parser_errposition(pstate
, typename
->location
)));
318 datums
[n
++] = CStringGetDatum(cstr
);
321 /* hardwired knowledge about cstring's representation details here */
322 arrtypmod
= construct_array(datums
, n
, CSTRINGOID
,
325 /* arrange to report location if type's typmodin function fails */
326 setup_parser_errposition_callback(&pcbstate
, pstate
, typename
->location
);
328 result
= DatumGetInt32(OidFunctionCall1(typmodin
,
329 PointerGetDatum(arrtypmod
)));
331 cancel_parser_errposition_callback(&pcbstate
);
340 * appendTypeNameToBuffer
341 * Append a string representing the name of a TypeName to a StringInfo.
342 * This is the shared guts of TypeNameToString and TypeNameListToString.
344 * NB: this must work on TypeNames that do not describe any actual type;
345 * it is mostly used for reporting lookup errors.
348 appendTypeNameToBuffer(const TypeName
*typename
, StringInfo string
)
350 if (typename
->names
!= NIL
)
352 /* Emit possibly-qualified name as-is */
355 foreach(l
, typename
->names
)
357 if (l
!= list_head(typename
->names
))
358 appendStringInfoChar(string
, '.');
359 appendStringInfoString(string
, strVal(lfirst(l
)));
364 /* Look up internally-specified type */
365 appendStringInfoString(string
, format_type_be(typename
->typeid));
369 * Add decoration as needed, but only for fields considered by
372 if (typename
->pct_type
)
373 appendStringInfoString(string
, "%TYPE");
375 if (typename
->arrayBounds
!= NIL
)
376 appendStringInfoString(string
, "[]");
381 * Produce a string representing the name of a TypeName.
383 * NB: this must work on TypeNames that do not describe any actual type;
384 * it is mostly used for reporting lookup errors.
387 TypeNameToString(const TypeName
*typename
)
389 StringInfoData string
;
391 initStringInfo(&string
);
392 appendTypeNameToBuffer(typename
, &string
);
397 * TypeNameListToString
398 * Produce a string representing the name(s) of a List of TypeNames
401 TypeNameListToString(List
*typenames
)
403 StringInfoData string
;
406 initStringInfo(&string
);
407 foreach(l
, typenames
)
409 TypeName
*typename
= (TypeName
*) lfirst(l
);
411 Assert(IsA(typename
, TypeName
));
412 if (l
!= list_head(typenames
))
413 appendStringInfoChar(&string
, ',');
414 appendTypeNameToBuffer(typename
, &string
);
419 /* return a Type structure, given a type id */
420 /* NB: caller must ReleaseSysCache the type tuple when done with it */
426 tup
= SearchSysCache(TYPEOID
,
427 ObjectIdGetDatum(id
),
429 if (!HeapTupleIsValid(tup
))
430 elog(ERROR
, "cache lookup failed for type %u", id
);
434 /* given type (as type struct), return the type OID */
438 if (tp
== NULL
) /* probably useless */
439 elog(ERROR
, "typeTypeId() called with NULL type struct");
440 return HeapTupleGetOid(tp
);
443 /* given type (as type struct), return the length of type */
449 typ
= (Form_pg_type
) GETSTRUCT(t
);
453 /* given type (as type struct), return the value of its 'byval' attribute.*/
459 typ
= (Form_pg_type
) GETSTRUCT(t
);
460 return typ
->typbyval
;
463 /* given type (as type struct), return the name of type */
469 typ
= (Form_pg_type
) GETSTRUCT(t
);
470 /* pstrdup here because result may need to outlive the syscache entry */
471 return pstrdup(NameStr(typ
->typname
));
475 typeTypeRelid(Type typ
)
479 typtup
= (Form_pg_type
) GETSTRUCT(typ
);
481 return typtup
->typrelid
;
485 * Given a type structure and a string, returns the internal representation
486 * of that string. The "string" can be NULL to perform conversion of a NULL
487 * (which might result in failure, if the input function rejects NULLs).
490 stringTypeDatum(Type tp
, char *string
, int32 atttypmod
)
492 Form_pg_type typform
= (Form_pg_type
) GETSTRUCT(tp
);
493 Oid typinput
= typform
->typinput
;
494 Oid typioparam
= getTypeIOParam(tp
);
497 result
= OidInputFunctionCall(typinput
, string
,
498 typioparam
, atttypmod
);
500 #ifdef RANDOMIZE_ALLOCATED_MEMORY
503 * For pass-by-reference data types, repeat the conversion to see if the
504 * input function leaves any uninitialized bytes in the result. We can
505 * only detect that reliably if RANDOMIZE_ALLOCATED_MEMORY is enabled, so
506 * we don't bother testing otherwise. The reason we don't want any
507 * instability in the input function is that comparison of Const nodes
508 * relies on bytewise comparison of the datums, so if the input function
509 * leaves garbage then subexpressions that should be identical may not get
510 * recognized as such. See pgsql-hackers discussion of 2008-04-04.
512 if (string
&& !typform
->typbyval
)
516 result2
= OidInputFunctionCall(typinput
, string
,
517 typioparam
, atttypmod
);
518 if (!datumIsEqual(result
, result2
, typform
->typbyval
, typform
->typlen
))
519 elog(WARNING
, "type %s has unstable input conversion for \"%s\"",
520 NameStr(typform
->typname
), string
);
527 /* given a typeid, return the type's typrelid (associated relation, if any) */
529 typeidTypeRelid(Oid type_id
)
535 typeTuple
= SearchSysCache(TYPEOID
,
536 ObjectIdGetDatum(type_id
),
538 if (!HeapTupleIsValid(typeTuple
))
539 elog(ERROR
, "cache lookup failed for type %u", type_id
);
541 type
= (Form_pg_type
) GETSTRUCT(typeTuple
);
542 result
= type
->typrelid
;
543 ReleaseSysCache(typeTuple
);
548 * error context callback for parse failure during parseTypeString()
551 pts_error_callback(void *arg
)
553 const char *str
= (const char *) arg
;
555 errcontext("invalid type name \"%s\"", str
);
558 * Currently we just suppress any syntax error position report, rather
559 * than transforming to an "internal query" error. It's unlikely that a
560 * type name is complex enough to need positioning.
566 * Given a string that is supposed to be a SQL-compatible type declaration,
567 * such as "int4" or "integer" or "character varying(32)", parse
568 * the string and convert it to a type OID and type modifier.
571 parseTypeString(const char *str
, Oid
*type_id
, int32
*typmod_p
)
574 List
*raw_parsetree_list
;
576 ResTarget
*restarget
;
579 ErrorContextCallback ptserrcontext
;
581 /* make sure we give useful error for empty input */
582 if (strspn(str
, " \t\n\r\f") == strlen(str
))
585 initStringInfo(&buf
);
586 appendStringInfo(&buf
, "SELECT NULL::%s", str
);
589 * Setup error traceback support in case of ereport() during parse
591 ptserrcontext
.callback
= pts_error_callback
;
592 ptserrcontext
.arg
= (void *) str
;
593 ptserrcontext
.previous
= error_context_stack
;
594 error_context_stack
= &ptserrcontext
;
596 raw_parsetree_list
= raw_parser(buf
.data
);
598 error_context_stack
= ptserrcontext
.previous
;
601 * Make sure we got back exactly what we expected and no more; paranoia is
602 * justified since the string might contain anything.
604 if (list_length(raw_parsetree_list
) != 1)
606 stmt
= (SelectStmt
*) linitial(raw_parsetree_list
);
608 !IsA(stmt
, SelectStmt
) ||
609 stmt
->distinctClause
!= NIL
||
610 stmt
->intoClause
!= NULL
||
611 stmt
->fromClause
!= NIL
||
612 stmt
->whereClause
!= NULL
||
613 stmt
->groupClause
!= NIL
||
614 stmt
->havingClause
!= NULL
||
615 stmt
->windowClause
!= NIL
||
616 stmt
->withClause
!= NULL
||
617 stmt
->valuesLists
!= NIL
||
618 stmt
->sortClause
!= NIL
||
619 stmt
->limitOffset
!= NULL
||
620 stmt
->limitCount
!= NULL
||
621 stmt
->lockingClause
!= NIL
||
622 stmt
->op
!= SETOP_NONE
)
624 if (list_length(stmt
->targetList
) != 1)
626 restarget
= (ResTarget
*) linitial(stmt
->targetList
);
627 if (restarget
== NULL
||
628 !IsA(restarget
, ResTarget
) ||
629 restarget
->name
!= NULL
||
630 restarget
->indirection
!= NIL
)
632 typecast
= (TypeCast
*) restarget
->val
;
633 if (typecast
== NULL
||
634 !IsA(typecast
, TypeCast
) ||
635 typecast
->arg
== NULL
||
636 !IsA(typecast
->arg
, A_Const
))
638 typename
= typecast
->typename
;
639 if (typename
== NULL
||
640 !IsA(typename
, TypeName
))
645 *type_id
= typenameTypeId(NULL
, typename
, typmod_p
);
653 (errcode(ERRCODE_SYNTAX_ERROR
),
654 errmsg("invalid type name \"%s\"", str
)));