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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy