PostgreSQL Source Code  git master
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 *stmt)
 

Function Documentation

◆ CreateConversionCommand()

ObjectAddress CreateConversionCommand ( CreateConversionStmt stmt)

Definition at line 39 of file conversioncmds.c.

40 {
41  Oid namespaceId;
42  char *conversion_name;
43  AclResult aclresult;
44  int from_encoding;
45  int to_encoding;
46  Oid funcoid;
47  const char *from_encoding_name = stmt->for_encoding_name;
48  const char *to_encoding_name = stmt->to_encoding_name;
49  List *func_name = stmt->func_name;
50  static const Oid funcargs[] = {INT4OID, INT4OID, CSTRINGOID, INTERNALOID, INT4OID, BOOLOID};
51  char result[1];
52  Datum funcresult;
53 
54  /* Convert list of names to a name and namespace */
55  namespaceId = QualifiedNameGetCreationNamespace(stmt->conversion_name,
56  &conversion_name);
57 
58  /* Check we have creation rights in target namespace */
59  aclresult = object_aclcheck(NamespaceRelationId, namespaceId, GetUserId(), ACL_CREATE);
60  if (aclresult != ACLCHECK_OK)
61  aclcheck_error(aclresult, OBJECT_SCHEMA,
62  get_namespace_name(namespaceId));
63 
64  /* Check the encoding names */
65  from_encoding = pg_char_to_encoding(from_encoding_name);
66  if (from_encoding < 0)
67  ereport(ERROR,
68  (errcode(ERRCODE_UNDEFINED_OBJECT),
69  errmsg("source encoding \"%s\" does not exist",
70  from_encoding_name)));
71 
72  to_encoding = pg_char_to_encoding(to_encoding_name);
73  if (to_encoding < 0)
74  ereport(ERROR,
75  (errcode(ERRCODE_UNDEFINED_OBJECT),
76  errmsg("destination encoding \"%s\" does not exist",
77  to_encoding_name)));
78 
79  /*
80  * We consider conversions to or from SQL_ASCII to be meaningless. (If
81  * you wish to change this, note that pg_do_encoding_conversion() and its
82  * sister functions have hard-wired fast paths for any conversion in which
83  * the source or target encoding is SQL_ASCII, so that an encoding
84  * conversion function declared for such a case will never be used.)
85  */
86  if (from_encoding == PG_SQL_ASCII || to_encoding == PG_SQL_ASCII)
87  ereport(ERROR,
88  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
89  errmsg("encoding conversion to or from \"SQL_ASCII\" is not supported")));
90 
91  /*
92  * Check the existence of the conversion function. Function name could be
93  * a qualified name.
94  */
95  funcoid = LookupFuncName(func_name, sizeof(funcargs) / sizeof(Oid),
96  funcargs, false);
97 
98  /* Check it returns int4, else it's probably the wrong function */
99  if (get_func_rettype(funcoid) != INT4OID)
100  ereport(ERROR,
101  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
102  errmsg("encoding conversion function %s must return type %s",
103  NameListToString(func_name), "integer")));
104 
105  /* Check we have EXECUTE rights for the function */
106  aclresult = object_aclcheck(ProcedureRelationId, funcoid, GetUserId(), ACL_EXECUTE);
107  if (aclresult != ACLCHECK_OK)
108  aclcheck_error(aclresult, OBJECT_FUNCTION,
109  NameListToString(func_name));
110 
111  /*
112  * Check that the conversion function is suitable for the requested source
113  * and target encodings. We do that by calling the function with an empty
114  * string; the conversion function should throw an error if it can't
115  * perform the requested conversion.
116  */
117  funcresult = OidFunctionCall6(funcoid,
118  Int32GetDatum(from_encoding),
119  Int32GetDatum(to_encoding),
120  CStringGetDatum(""),
121  CStringGetDatum(result),
122  Int32GetDatum(0),
123  BoolGetDatum(false));
124 
125  /*
126  * The function should return 0 for empty input. Might as well check that,
127  * too.
128  */
129  if (DatumGetInt32(funcresult) != 0)
130  ereport(ERROR,
131  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
132  errmsg("encoding conversion function %s returned incorrect result for empty input",
133  NameListToString(func_name))));
134 
135  /*
136  * All seem ok, go ahead (possible failure would be a duplicate conversion
137  * name)
138  */
139  return ConversionCreate(conversion_name, namespaceId, GetUserId(),
140  from_encoding, to_encoding, funcoid, stmt->def);
141 }
AclResult
Definition: acl.h:181
@ ACLCHECK_OK
Definition: acl.h:182
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:2695
AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
Definition: aclchk.c:3843
int errcode(int sqlerrcode)
Definition: elog.c:858
int errmsg(const char *fmt,...)
Definition: elog.c:1069
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
#define OidFunctionCall6(functionId, arg1, arg2, arg3, arg4, arg5, arg6)
Definition: fmgr.h:690
#define stmt
Definition: indent_codes.h:59
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3348
Oid get_func_rettype(Oid funcid)
Definition: lsyscache.c:1659
Oid GetUserId(void)
Definition: miscinit.c:508
Oid QualifiedNameGetCreationNamespace(const List *names, char **objname_p)
Definition: namespace.c:3454
char * NameListToString(const List *names)
Definition: namespace.c:3561
Oid LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool missing_ok)
Definition: parse_func.c:2143
@ OBJECT_SCHEMA
Definition: parsenodes.h:2132
@ OBJECT_FUNCTION
Definition: parsenodes.h:2115
#define ACL_EXECUTE
Definition: parsenodes.h:83
#define ACL_CREATE
Definition: parsenodes.h:85
ObjectAddress ConversionCreate(const char *conname, Oid connamespace, Oid conowner, int32 conforencoding, int32 contoencoding, Oid conproc, bool def)
Definition: pg_conversion.c:41
@ PG_SQL_ASCII
Definition: pg_wchar.h:229
#define pg_char_to_encoding
Definition: pg_wchar.h:562
uintptr_t Datum
Definition: postgres.h:64
static Datum BoolGetDatum(bool X)
Definition: postgres.h:102
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:350
static Datum Int32GetDatum(int32 X)
Definition: postgres.h:212
static int32 DatumGetInt32(Datum X)
Definition: postgres.h:202
unsigned int Oid
Definition: postgres_ext.h:31
Definition: pg_list.h:54

References ACL_CREATE, ACL_EXECUTE, aclcheck_error(), ACLCHECK_OK, BoolGetDatum(), ConversionCreate(), CStringGetDatum(), DatumGetInt32(), ereport, errcode(), errmsg(), ERROR, get_func_rettype(), get_namespace_name(), GetUserId(), Int32GetDatum(), LookupFuncName(), NameListToString(), object_aclcheck(), OBJECT_FUNCTION, OBJECT_SCHEMA, OidFunctionCall6, pg_char_to_encoding, PG_SQL_ASCII, QualifiedNameGetCreationNamespace(), and stmt.

Referenced by ProcessUtilitySlow().