PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
conversioncmds.h File Reference
Include dependency graph for conversioncmds.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

ObjectAddress CreateConversionCommand (CreateConversionStmt *parsetree)
 

Function Documentation

ObjectAddress CreateConversionCommand ( CreateConversionStmt parsetree)

Definition at line 37 of file conversioncmds.c.

References ACL_CREATE, ACL_EXECUTE, ACL_KIND_NAMESPACE, ACL_KIND_PROC, aclcheck_error(), ACLCHECK_OK, CreateConversionStmt::conversion_name, ConversionCreate(), CStringGetDatum, CSTRINGOID, CreateConversionStmt::def, ereport, errcode(), errmsg(), ERROR, CreateConversionStmt::for_encoding_name, CreateConversionStmt::func_name, get_func_rettype(), get_namespace_name(), GetUserId(), Int32GetDatum, INT4OID, INTERNALOID, LookupFuncName(), NameListToString(), OidFunctionCall5, pg_char_to_encoding(), pg_namespace_aclcheck(), pg_proc_aclcheck(), QualifiedNameGetCreationNamespace(), result, CreateConversionStmt::to_encoding_name, and VOIDOID.

Referenced by ProcessUtilitySlow().

38 {
39  Oid namespaceId;
40  char *conversion_name;
41  AclResult aclresult;
42  int from_encoding;
43  int to_encoding;
44  Oid funcoid;
45  const char *from_encoding_name = stmt->for_encoding_name;
46  const char *to_encoding_name = stmt->to_encoding_name;
47  List *func_name = stmt->func_name;
48  static const Oid funcargs[] = {INT4OID, INT4OID, CSTRINGOID, INTERNALOID, INT4OID};
49  char result[1];
50 
51  /* Convert list of names to a name and namespace */
52  namespaceId = QualifiedNameGetCreationNamespace(stmt->conversion_name,
53  &conversion_name);
54 
55  /* Check we have creation rights in target namespace */
56  aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_CREATE);
57  if (aclresult != ACLCHECK_OK)
59  get_namespace_name(namespaceId));
60 
61  /* Check the encoding names */
62  from_encoding = pg_char_to_encoding(from_encoding_name);
63  if (from_encoding < 0)
64  ereport(ERROR,
65  (errcode(ERRCODE_UNDEFINED_OBJECT),
66  errmsg("source encoding \"%s\" does not exist",
67  from_encoding_name)));
68 
69  to_encoding = pg_char_to_encoding(to_encoding_name);
70  if (to_encoding < 0)
71  ereport(ERROR,
72  (errcode(ERRCODE_UNDEFINED_OBJECT),
73  errmsg("destination encoding \"%s\" does not exist",
74  to_encoding_name)));
75 
76  /*
77  * Check the existence of the conversion function. Function name could be
78  * a qualified name.
79  */
80  funcoid = LookupFuncName(func_name, sizeof(funcargs) / sizeof(Oid),
81  funcargs, false);
82 
83  /* Check it returns VOID, else it's probably the wrong function */
84  if (get_func_rettype(funcoid) != VOIDOID)
85  ereport(ERROR,
86  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
87  errmsg("encoding conversion function %s must return type %s",
88  NameListToString(func_name), "void")));
89 
90  /* Check we have EXECUTE rights for the function */
91  aclresult = pg_proc_aclcheck(funcoid, GetUserId(), ACL_EXECUTE);
92  if (aclresult != ACLCHECK_OK)
93  aclcheck_error(aclresult, ACL_KIND_PROC,
94  NameListToString(func_name));
95 
96  /*
97  * Check that the conversion function is suitable for the requested source
98  * and target encodings. We do that by calling the function with an empty
99  * string; the conversion function should throw an error if it can't
100  * perform the requested conversion.
101  */
102  OidFunctionCall5(funcoid,
103  Int32GetDatum(from_encoding),
104  Int32GetDatum(to_encoding),
105  CStringGetDatum(""),
106  CStringGetDatum(result),
107  Int32GetDatum(0));
108 
109  /*
110  * All seem ok, go ahead (possible failure would be a duplicate conversion
111  * name)
112  */
113  return ConversionCreate(conversion_name, namespaceId, GetUserId(),
114  from_encoding, to_encoding, funcoid, stmt->def);
115 }
int pg_char_to_encoding(const char *name)
Definition: encnames.c:551
Oid GetUserId(void)
Definition: miscinit.c:283
Oid QualifiedNameGetCreationNamespace(List *names, char **objname_p)
Definition: namespace.c:2846
#define INT4OID
Definition: pg_type.h:316
int errcode(int sqlerrcode)
Definition: elog.c:575
return result
Definition: formatting.c:1618
unsigned int Oid
Definition: postgres_ext.h:31
AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4467
Oid get_func_rettype(Oid funcid)
Definition: lsyscache.c:1427
#define VOIDOID
Definition: pg_type.h:686
#define ERROR
Definition: elog.h:43
#define ACL_CREATE
Definition: parsenodes.h:75
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3006
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3382
#define CStringGetDatum(X)
Definition: postgres.h:584
#define ereport(elevel, rest)
Definition: elog.h:122
char * NameListToString(List *names)
Definition: namespace.c:2953
ObjectAddress ConversionCreate(const char *conname, Oid connamespace, Oid conowner, int32 conforencoding, int32 contoencoding, Oid conproc, bool def)
Definition: pg_conversion.c:41
AclResult
Definition: acl.h:170
#define INTERNALOID
Definition: pg_type.h:694
#define CSTRINGOID
Definition: pg_type.h:680
Oid LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool noError)
Definition: parse_func.c:1910
#define Int32GetDatum(X)
Definition: postgres.h:485
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define ACL_EXECUTE
Definition: parsenodes.h:72
AclResult pg_proc_aclcheck(Oid proc_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4429
Definition: pg_list.h:45
#define OidFunctionCall5(functionId, arg1, arg2, arg3, arg4, arg5)
Definition: fmgr.h:622