PostgreSQL Source Code git master
Loading...
Searching...
No Matches
conversioncmds.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * conversioncmds.c
4 * conversion creation command support code
5 *
6 * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 *
10 * IDENTIFICATION
11 * src/backend/commands/conversioncmds.c
12 *
13 *-------------------------------------------------------------------------
14 */
15#include "postgres.h"
16
19#include "catalog/pg_proc.h"
20#include "catalog/pg_type.h"
22#include "mb/pg_wchar.h"
23#include "miscadmin.h"
24#include "parser/parse_func.h"
25#include "utils/acl.h"
26#include "utils/lsyscache.h"
27
28/*
29 * CREATE CONVERSION
30 */
33{
35 char *conversion_name;
37 int from_encoding;
38 int to_encoding;
40 const char *from_encoding_name = stmt->for_encoding_name;
41 const char *to_encoding_name = stmt->to_encoding_name;
42 List *func_name = stmt->func_name;
44 char result[1];
46
47 /* Convert list of names to a name and namespace */
49 &conversion_name);
50
51 /* Check we have creation rights in target namespace */
56
57 /* Check the encoding names */
59 if (from_encoding < 0)
62 errmsg("source encoding \"%s\" does not exist",
64
65 to_encoding = pg_char_to_encoding(to_encoding_name);
66 if (to_encoding < 0)
69 errmsg("destination encoding \"%s\" does not exist",
70 to_encoding_name)));
71
72 /*
73 * We consider conversions to or from SQL_ASCII to be meaningless. (If
74 * you wish to change this, note that pg_do_encoding_conversion() and its
75 * sister functions have hard-wired fast paths for any conversion in which
76 * the source or target encoding is SQL_ASCII, so that an encoding
77 * conversion function declared for such a case will never be used.)
78 */
82 errmsg("encoding conversion to or from \"SQL_ASCII\" is not supported")));
83
84 /*
85 * Check the existence of the conversion function. Function name could be
86 * a qualified name.
87 */
88 funcoid = LookupFuncName(func_name, sizeof(funcargs) / sizeof(Oid),
89 funcargs, false);
90
91 /* Check it returns int4, else it's probably the wrong function */
95 errmsg("encoding conversion function %s must return type %s",
96 NameListToString(func_name), "integer")));
97
98 /* Check we have EXECUTE rights for the function */
100 if (aclresult != ACLCHECK_OK)
102 NameListToString(func_name));
103
104 /*
105 * Check that the conversion function is suitable for the requested source
106 * and target encodings. We do that by calling the function with an empty
107 * string; the conversion function should throw an error if it can't
108 * perform the requested conversion.
109 */
113 CStringGetDatum(""),
114 CStringGetDatum(result),
115 Int32GetDatum(0),
116 BoolGetDatum(false));
117
118 /*
119 * The function should return 0 for empty input. Might as well check that,
120 * too.
121 */
122 if (DatumGetInt32(funcresult) != 0)
125 errmsg("encoding conversion function %s returned incorrect result for empty input",
126 NameListToString(func_name))));
127
128 /*
129 * All seem ok, go ahead (possible failure would be a duplicate conversion
130 * name)
131 */
132 return ConversionCreate(conversion_name, namespaceId, GetUserId(),
134}
AclResult
Definition acl.h:182
@ ACLCHECK_OK
Definition acl.h:183
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition aclchk.c:2654
AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
Definition aclchk.c:3836
ObjectAddress CreateConversionCommand(CreateConversionStmt *stmt)
int errcode(int sqlerrcode)
Definition elog.c:863
int errmsg(const char *fmt,...)
Definition elog.c:1080
#define ERROR
Definition elog.h:39
#define ereport(elevel,...)
Definition elog.h:150
#define OidFunctionCall6(functionId, arg1, arg2, arg3, arg4, arg5, arg6)
Definition fmgr.h:732
#define stmt
char * get_namespace_name(Oid nspid)
Definition lsyscache.c:3516
Oid get_func_rettype(Oid funcid)
Definition lsyscache.c:1805
Oid GetUserId(void)
Definition miscinit.c:469
char * NameListToString(const List *names)
Definition namespace.c:3664
Oid QualifiedNameGetCreationNamespace(const List *names, char **objname_p)
Definition namespace.c:3557
Oid LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool missing_ok)
@ OBJECT_SCHEMA
@ OBJECT_FUNCTION
#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)
@ PG_SQL_ASCII
Definition pg_wchar.h:226
#define pg_char_to_encoding
Definition pg_wchar.h:629
static Datum BoolGetDatum(bool X)
Definition postgres.h:112
uint64_t Datum
Definition postgres.h:70
static Datum CStringGetDatum(const char *X)
Definition postgres.h:380
static Datum Int32GetDatum(int32 X)
Definition postgres.h:222
static int32 DatumGetInt32(Datum X)
Definition postgres.h:212
unsigned int Oid
static int fb(int x)
Definition pg_list.h:54