8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $PostgreSQL: pgsql/src/backend/catalog/pg_type.c,v 1.104 2005/10/15 02:49:14 momjian Exp $
11
+ * $PostgreSQL: pgsql/src/backend/catalog/pg_type.c,v 1.105 2006/02/28 22:37:25 tgl Exp $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
20
20
#include "catalog/pg_namespace.h"
21
21
#include "catalog/pg_proc.h"
22
22
#include "catalog/pg_type.h"
23
+ #include "commands/typecmds.h"
23
24
#include "miscadmin.h"
25
+ #include "utils/acl.h"
24
26
#include "utils/builtins.h"
27
+ #include "utils/fmgroids.h"
25
28
#include "utils/lsyscache.h"
26
29
#include "utils/syscache.h"
27
30
28
31
29
32
/* ----------------------------------------------------------------
30
33
* TypeShellMake
31
34
*
32
- * This procedure inserts a "shell" tuple into the type
33
- * relation. The type tuple inserted has invalid values
34
- * and in particular, the "typisdefined" field is false.
35
+ * This procedure inserts a "shell" tuple into the pg_type relation.
36
+ * The type tuple inserted has valid but dummy values, and its
37
+ * "typisdefined" field is false indicating it's not really defined .
35
38
*
36
- * This is used so that a tuple exists in the catalogs.
37
- * The invalid fields should be fixed up sometime after
38
- * this routine is called, and then the "typeisdefined"
39
- * field is set to true. -cim 6/15/90
39
+ * This is used so that a tuple exists in the catalogs. The I/O
40
+ * functions for the type will link to this tuple. When the full
41
+ * CREATE TYPE command is issued, the bogus values will be replaced
42
+ * with correct ones, and "typisdefined" will be set to true.
40
43
* ----------------------------------------------------------------
41
44
*/
42
45
Oid
@@ -70,30 +73,35 @@ TypeShellMake(const char *typeName, Oid typeNamespace)
70
73
71
74
/*
72
75
* initialize *values with the type name and dummy values
76
+ *
77
+ * The representational details are the same as int4 ... it doesn't
78
+ * really matter what they are so long as they are consistent. Also
79
+ * note that we give it typtype = 'p' (pseudotype) as extra insurance
80
+ * that it won't be mistaken for a usable type.
73
81
*/
74
82
i = 0 ;
75
83
namestrcpy (& name , typeName );
76
84
values [i ++ ] = NameGetDatum (& name ); /* typname */
77
85
values [i ++ ] = ObjectIdGetDatum (typeNamespace ); /* typnamespace */
78
86
values [i ++ ] = ObjectIdGetDatum (GetUserId ()); /* typowner */
79
- values [i ++ ] = Int16GetDatum (0 ); /* typlen */
80
- values [i ++ ] = BoolGetDatum (false); /* typbyval */
81
- values [i ++ ] = CharGetDatum (0 ); /* typtype */
82
- values [i ++ ] = BoolGetDatum (false); /* typisdefined */
83
- values [i ++ ] = CharGetDatum (0 ); /* typdelim */
84
- values [i ++ ] = ObjectIdGetDatum (InvalidOid ); /* typrelid */
85
- values [i ++ ] = ObjectIdGetDatum (InvalidOid ); /* typelem */
86
- values [i ++ ] = ObjectIdGetDatum (InvalidOid ); /* typinput */
87
- values [i ++ ] = ObjectIdGetDatum (InvalidOid ); /* typoutput */
88
- values [i ++ ] = ObjectIdGetDatum (InvalidOid ); /* typreceive */
89
- values [i ++ ] = ObjectIdGetDatum (InvalidOid ); /* typsend */
90
- values [i ++ ] = ObjectIdGetDatum (InvalidOid ); /* typanalyze */
91
- values [i ++ ] = CharGetDatum ('i' ); /* typalign */
92
- values [i ++ ] = CharGetDatum ('p' ); /* typstorage */
93
- values [i ++ ] = BoolGetDatum (false); /* typnotnull */
94
- values [i ++ ] = ObjectIdGetDatum (InvalidOid ); /* typbasetype */
95
- values [i ++ ] = Int32GetDatum (-1 ); /* typtypmod */
96
- values [i ++ ] = Int32GetDatum (0 ); /* typndims */
87
+ values [i ++ ] = Int16GetDatum (sizeof ( int4 )); /* typlen */
88
+ values [i ++ ] = BoolGetDatum (true); /* typbyval */
89
+ values [i ++ ] = CharGetDatum ('p' ); /* typtype */
90
+ values [i ++ ] = BoolGetDatum (false); /* typisdefined */
91
+ values [i ++ ] = CharGetDatum (DEFAULT_TYPDELIM ); /* typdelim */
92
+ values [i ++ ] = ObjectIdGetDatum (InvalidOid ); /* typrelid */
93
+ values [i ++ ] = ObjectIdGetDatum (InvalidOid ); /* typelem */
94
+ values [i ++ ] = ObjectIdGetDatum (F_SHELL_IN ); /* typinput */
95
+ values [i ++ ] = ObjectIdGetDatum (F_SHELL_OUT ); /* typoutput */
96
+ values [i ++ ] = ObjectIdGetDatum (InvalidOid ); /* typreceive */
97
+ values [i ++ ] = ObjectIdGetDatum (InvalidOid ); /* typsend */
98
+ values [i ++ ] = ObjectIdGetDatum (InvalidOid ); /* typanalyze */
99
+ values [i ++ ] = CharGetDatum ('i' ); /* typalign */
100
+ values [i ++ ] = CharGetDatum ('p' ); /* typstorage */
101
+ values [i ++ ] = BoolGetDatum (false); /* typnotnull */
102
+ values [i ++ ] = ObjectIdGetDatum (InvalidOid ); /* typbasetype */
103
+ values [i ++ ] = Int32GetDatum (-1 ); /* typtypmod */
104
+ values [i ++ ] = Int32GetDatum (0 ); /* typndims */
97
105
nulls [i ++ ] = 'n' ; /* typdefaultbin */
98
106
nulls [i ++ ] = 'n' ; /* typdefault */
99
107
@@ -118,8 +126,8 @@ TypeShellMake(const char *typeName, Oid typeNamespace)
118
126
InvalidOid ,
119
127
0 ,
120
128
GetUserId (),
121
- InvalidOid ,
122
- InvalidOid ,
129
+ F_SHELL_IN ,
130
+ F_SHELL_OUT ,
123
131
InvalidOid ,
124
132
InvalidOid ,
125
133
InvalidOid ,
@@ -289,7 +297,13 @@ TypeCreate(const char *typeName,
289
297
errmsg ("type \"%s\" already exists" , typeName )));
290
298
291
299
/*
292
- * Okay to update existing "shell" type tuple
300
+ * shell type must have been created by same owner
301
+ */
302
+ if (((Form_pg_type ) GETSTRUCT (tup ))-> typowner != GetUserId ())
303
+ aclcheck_error (ACLCHECK_NOT_OWNER , ACL_KIND_TYPE , typeName );
304
+
305
+ /*
306
+ * Okay to update existing shell type tuple
293
307
*/
294
308
tup = heap_modifytuple (tup ,
295
309
RelationGetDescr (pg_type_desc ),
@@ -350,8 +364,6 @@ TypeCreate(const char *typeName,
350
364
* If rebuild is true, we remove existing dependencies and rebuild them
351
365
* from scratch. This is needed for ALTER TYPE, and also when replacing
352
366
* a shell type.
353
- *
354
- * NOTE: a shell type will have a dependency to its namespace, and no others.
355
367
*/
356
368
void
357
369
GenerateTypeDependencies (Oid typeNamespace ,
0 commit comments