Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 6c91eef

Browse files
committed
Fix handling of pg_type.typdefault per bug report from Dave Blasby.
If there's anyone out there who's actually using datatype-defined default values, this will be an incompatible change in behavior ... but the old behavior was so broken that I doubt anyone was using it.
1 parent f2b604e commit 6c91eef

File tree

11 files changed

+209
-146
lines changed

11 files changed

+209
-146
lines changed

doc/src/sgml/catalogs.sgml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<!--
22
Documentation of the system catalogs, directed toward PostgreSQL developers
3-
$Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.22 2001/08/26 16:55:58 tgl Exp $
3+
$Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.23 2001/09/06 02:07:41 tgl Exp $
44
-->
55

66
<chapter id="catalogs">
@@ -243,7 +243,9 @@
243243
<entry></entry>
244244
<entry>
245245
The initial value of the transition state. This is a text
246-
field which will be cast to the type of aggtranstype.
246+
field containing the initial value in its external string
247+
representation. If the field is NULL, the transition state
248+
value starts out NULL.
247249
</entry>
248250
</row>
249251
</tbody>
@@ -2071,7 +2073,11 @@
20712073
<entry>typdefault</entry>
20722074
<entry><type>text</type></entry>
20732075
<entry></entry>
2074-
<entry>???</entry>
2076+
<entry><para>
2077+
<structfield>typdefault</structfield> is NULL for types without a
2078+
default value. If it's not NULL, it contains the external string
2079+
representation of the type's default value.
2080+
</para></entry>
20752081
</row>
20762082
</tbody>
20772083
</tgroup>

src/backend/catalog/heap.c

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.175 2001/08/25 18:52:41 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.176 2001/09/06 02:07:42 tgl Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -657,7 +657,6 @@ AddNewRelationTuple(Relation pg_class_desc,
657657
static void
658658
AddNewRelationType(char *typeName, Oid new_rel_oid, Oid new_type_oid)
659659
{
660-
661660
/*
662661
* The sizes are set to oid size because it makes implementing sets
663662
* MUCH easier, and no one (we hope) uses these fields to figure out
@@ -666,24 +665,22 @@ AddNewRelationType(char *typeName, Oid new_rel_oid, Oid new_type_oid)
666665
* actually get is the oid of a tuple in the pg_proc catalog, so the
667666
* size of the "set" is the size of an oid. Similarly, byval being
668667
* true makes sets much easier, and it isn't used by anything else.
669-
*
670-
* XXX Note the assumption that OIDs are the same size as int4s.
671668
*/
672669
TypeCreate(typeName, /* type name */
673670
new_type_oid, /* preassigned oid for type */
674671
new_rel_oid, /* relation oid */
675672
sizeof(Oid), /* internal size */
676-
sizeof(Oid), /* external size */
673+
-1, /* external size */
677674
'c', /* type-type (catalog) */
678675
',', /* default array delimiter */
679-
"int4in", /* input procedure */
680-
"int4out", /* output procedure */
681-
"int4in", /* receive procedure */
682-
"int4out", /* send procedure */
676+
"oidin", /* input procedure */
677+
"oidout", /* output procedure */
678+
"oidin", /* receive procedure */
679+
"oidout", /* send procedure */
683680
NULL, /* array element type - irrelevant */
684-
"-", /* default type value */
681+
NULL, /* default type value - none */
685682
true, /* passed by value */
686-
'i', /* default alignment */
683+
'i', /* default alignment - same as for OID */
687684
'p'); /* Not TOASTable */
688685
}
689686

src/backend/catalog/pg_type.c

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.62 2001/08/10 15:49:39 petere Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.63 2001/09/06 02:07:42 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -51,7 +51,7 @@ TypeGetWithOpenRelation(Relation pg_type_desc,
5151
/*
5252
* initialize the scan key and begin a scan of pg_type
5353
*/
54-
ScanKeyEntryInitialize(typeKey,
54+
ScanKeyEntryInitialize(&typeKey[0],
5555
0,
5656
Anum_pg_type_typname,
5757
F_NAMEEQ,
@@ -318,10 +318,18 @@ TypeCreate(char *typeName,
318318
}
319319

320320
/*
321-
* XXX comment me
321+
* validate size specifications: either positive (fixed-length) or
322+
* -1 (variable-length).
322323
*/
323-
if (externalSize == 0)
324-
externalSize = -1; /* variable length */
324+
if (! (internalSize > 0 || internalSize == -1))
325+
elog(ERROR, "TypeCreate: invalid type internal size %d",
326+
internalSize);
327+
if (! (externalSize > 0 || externalSize == -1))
328+
elog(ERROR, "TypeCreate: invalid type external size %d",
329+
externalSize);
330+
331+
if (internalSize != -1 && storage != 'p')
332+
elog(ERROR, "TypeCreate: fixed size types must have storage PLAIN");
325333

326334
/*
327335
* initialize arrays needed by FormHeapTuple
@@ -330,20 +338,9 @@ TypeCreate(char *typeName,
330338
{
331339
nulls[i] = ' ';
332340
replaces[i] = 'r';
333-
values[i] = (Datum) NULL; /* redundant, but nice */
341+
values[i] = (Datum) 0;
334342
}
335343

336-
/*
337-
* XXX
338-
*
339-
* Do this so that user-defined types have size -1 instead of zero if
340-
* they are variable-length - this is so that everything else in the
341-
* backend works.
342-
*/
343-
344-
if (internalSize == 0)
345-
internalSize = -1;
346-
347344
/*
348345
* initialize the *values information
349346
*/
@@ -435,15 +432,19 @@ TypeCreate(char *typeName,
435432
/*
436433
* initialize the default value for this type.
437434
*/
438-
values[i] = DirectFunctionCall1(textin, /* 17 */
439-
CStringGetDatum(defaultTypeValue ? defaultTypeValue : "-"));
435+
if (defaultTypeValue)
436+
values[i] = DirectFunctionCall1(textin,
437+
CStringGetDatum(defaultTypeValue));
438+
else
439+
nulls[i] = 'n';
440+
i++; /* 17 */
440441

441442
/*
442443
* open pg_type and begin a scan for the type name.
443444
*/
444445
pg_type_desc = heap_openr(TypeRelationName, RowExclusiveLock);
445446

446-
ScanKeyEntryInitialize(typeKey,
447+
ScanKeyEntryInitialize(&typeKey[0],
447448
0,
448449
Anum_pg_type_typname,
449450
F_NAMEEQ,

src/backend/commands/define.c

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.58 2001/08/03 20:47:40 tgl Exp $
13+
* $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.59 2001/09/06 02:07:42 tgl Exp $
1414
*
1515
* DESCRIPTION
1616
* The "DefineFoo" routines take the parse tree and pick out the
@@ -535,31 +535,29 @@ DefineAggregate(char *aggName, List *parameters)
535535
void
536536
DefineType(char *typeName, List *parameters)
537537
{
538-
int16 internalLength = 0; /* int2 */
539-
int16 externalLength = 0; /* int2 */
538+
int16 internalLength = -1; /* int2 */
539+
int16 externalLength = -1; /* int2 */
540540
char *elemName = NULL;
541541
char *inputName = NULL;
542542
char *outputName = NULL;
543543
char *sendName = NULL;
544544
char *receiveName = NULL;
545-
char *defaultValue = NULL; /* Datum */
545+
char *defaultValue = NULL;
546546
bool byValue = false;
547547
char delimiter = DEFAULT_TYPDELIM;
548548
char *shadow_type;
549549
List *pl;
550550
char alignment = 'i'; /* default alignment */
551-
char storage = 'p'; /* default storage in TOAST */
551+
char storage = 'p'; /* default TOAST storage method */
552552

553553
/*
554554
* Type names must be one character shorter than other names, allowing
555555
* room to create the corresponding array type name with prepended
556556
* "_".
557557
*/
558558
if (strlen(typeName) > (NAMEDATALEN - 2))
559-
{
560559
elog(ERROR, "DefineType: type names must be %d characters or less",
561560
NAMEDATALEN - 2);
562-
}
563561

564562
foreach(pl, parameters)
565563
{
@@ -645,9 +643,6 @@ DefineType(char *typeName, List *parameters)
645643
if (outputName == NULL)
646644
elog(ERROR, "Define: \"output\" unspecified");
647645

648-
if (internalLength != -1 && storage != 'p')
649-
elog(ERROR, "Define: fixed size types must have storage PLAIN");
650-
651646
/*
652647
* now have TypeCreate do all the real work.
653648
*/
@@ -674,6 +669,9 @@ DefineType(char *typeName, List *parameters)
674669
*/
675670
shadow_type = makeArrayTypeName(typeName);
676671

672+
/* alignment must be 'i' or 'd' for arrays */
673+
alignment = (alignment == 'd') ? 'd' : 'i';
674+
677675
TypeCreate(shadow_type, /* type name */
678676
InvalidOid, /* preassigned type oid (not done here) */
679677
InvalidOid, /* relation oid (n/a here) */
@@ -688,7 +686,7 @@ DefineType(char *typeName, List *parameters)
688686
typeName, /* element type name */
689687
NULL, /* never a default type value */
690688
false, /* never passed by value */
691-
alignment, /* NB: must be 'i' or 'd' for arrays... */
689+
alignment, /* see above */
692690
'x'); /* ARRAY is always toastable */
693691

694692
pfree(shadow_type);

src/backend/optimizer/prep/preptlist.c

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* Portions Copyright (c) 1994, Regents of the University of California
1616
*
1717
* IDENTIFICATION
18-
* $Header: /cvsroot/pgsql/src/backend/optimizer/prep/preptlist.c,v 1.42 2001/03/22 03:59:38 momjian Exp $
18+
* $Header: /cvsroot/pgsql/src/backend/optimizer/prep/preptlist.c,v 1.43 2001/09/06 02:07:42 tgl Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -192,45 +192,54 @@ expand_targetlist(List *tlist, int command_type,
192192
{
193193
case CMD_INSERT:
194194
{
195-
Datum typedefault = get_typdefault(atttype);
196-
int typlen;
197-
Const *temp_const;
195+
bool hasdefault;
196+
Datum typedefault;
197+
int16 typlen;
198+
bool typbyval;
199+
Const *def_const;
198200

199-
#ifdef _DROP_COLUMN_HACK__
200-
if (COLUMN_IS_DROPPED(att_tup))
201-
typedefault = PointerGetDatum(NULL);
202-
#endif /* _DROP_COLUMN_HACK__ */
203-
204-
if (typedefault == PointerGetDatum(NULL))
205-
typlen = 0;
206-
else
201+
if (att_tup->attisset)
207202
{
208-
209203
/*
210-
* Since this is an append or replace, the
211-
* size of any set attribute is the size of
212-
* the OID used to represent it.
204+
* Set attributes are represented as OIDs no
205+
* matter what the set element type is, and
206+
* the element type's default is irrelevant too.
213207
*/
214-
if (att_tup->attisset)
215-
typlen = get_typlen(OIDOID);
208+
hasdefault = false;
209+
typedefault = (Datum) 0;
210+
typlen = sizeof(Oid);
211+
typbyval = true;
212+
}
213+
else
214+
{
215+
#ifdef _DROP_COLUMN_HACK__
216+
if (COLUMN_IS_DROPPED(att_tup))
217+
{
218+
hasdefault = false;
219+
typedefault = (Datum) 0;
220+
}
216221
else
217-
typlen = get_typlen(atttype);
222+
#endif /* _DROP_COLUMN_HACK__ */
223+
hasdefault = get_typdefault(atttype,
224+
&typedefault);
225+
226+
get_typlenbyval(atttype, &typlen, &typbyval);
218227
}
219228

220-
temp_const = makeConst(atttype,
221-
typlen,
222-
typedefault,
223-
(typedefault == PointerGetDatum(NULL)),
224-
false,
225-
false, /* not a set */
226-
false);
229+
def_const = makeConst(atttype,
230+
typlen,
231+
typedefault,
232+
!hasdefault,
233+
typbyval,
234+
false, /* not a set */
235+
false);
227236

228237
new_tle = makeTargetEntry(makeResdom(attrno,
229238
atttype,
230239
-1,
231240
pstrdup(attrname),
232241
false),
233-
(Node *) temp_const);
242+
(Node *) def_const);
234243
break;
235244
}
236245
case CMD_UPDATE:

0 commit comments

Comments
 (0)