Skip to content

Commit 1395ac6

Browse files
committed
Add a hack so that get_type_io_data() can work from bootstrap.c's
internal TypInfo table in bootstrap mode. This allows array_in and array_out to be used during early bootstrap, which eliminates the former obstacle to giving OUT parameters to built-in functions.
1 parent 355865c commit 1395ac6

File tree

3 files changed

+135
-43
lines changed

3 files changed

+135
-43
lines changed

src/backend/bootstrap/bootstrap.c

Lines changed: 89 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.223 2006/07/31 20:09:00 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.224 2006/08/15 22:36:17 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -590,6 +590,7 @@ boot_openrel(char *relname)
590590

591591
if (Typ == NULL)
592592
{
593+
/* We can now load the pg_type data */
593594
rel = heap_open(TypeRelationId, NoLock);
594595
scan = heap_beginscan(rel, SnapshotNow, 0, NULL);
595596
i = 0;
@@ -806,6 +807,10 @@ void
806807
InsertOneValue(char *value, int i)
807808
{
808809
Oid typoid;
810+
int16 typlen;
811+
bool typbyval;
812+
char typalign;
813+
char typdelim;
809814
Oid typioparam;
810815
Oid typinput;
811816
Oid typoutput;
@@ -817,52 +822,19 @@ InsertOneValue(char *value, int i)
817822

818823
if (Typ != NULL)
819824
{
820-
struct typmap **app;
821-
struct typmap *ap;
822-
823-
elog(DEBUG5, "Typ != NULL");
824825
typoid = boot_reldesc->rd_att->attrs[i]->atttypid;
825-
app = Typ;
826-
while (*app && (*app)->am_oid != typoid)
827-
++app;
828-
ap = *app;
829-
if (ap == NULL)
830-
elog(ERROR, "could not find atttypid %u in Typ list", typoid);
831-
832-
/* XXX this logic should match getTypeIOParam() */
833-
if (OidIsValid(ap->am_typ.typelem))
834-
typioparam = ap->am_typ.typelem;
835-
else
836-
typioparam = typoid;
837-
838-
typinput = ap->am_typ.typinput;
839-
typoutput = ap->am_typ.typoutput;
840826
}
841827
else
842828
{
843-
int typeindex;
844-
845-
/* XXX why is typoid determined differently in this path? */
829+
/* XXX why is typoid determined differently in this case? */
846830
typoid = attrtypes[i]->atttypid;
847-
for (typeindex = 0; typeindex < n_types; typeindex++)
848-
{
849-
if (TypInfo[typeindex].oid == typoid)
850-
break;
851-
}
852-
if (typeindex >= n_types)
853-
elog(ERROR, "type oid %u not found", typoid);
854-
elog(DEBUG5, "Typ == NULL, typeindex = %u", typeindex);
855-
856-
/* XXX this logic should match getTypeIOParam() */
857-
if (OidIsValid(TypInfo[typeindex].elem))
858-
typioparam = TypInfo[typeindex].elem;
859-
else
860-
typioparam = typoid;
861-
862-
typinput = TypInfo[typeindex].inproc;
863-
typoutput = TypInfo[typeindex].outproc;
864831
}
865832

833+
boot_get_type_io_data(typoid,
834+
&typlen, &typbyval, &typalign,
835+
&typdelim, &typioparam,
836+
&typinput, &typoutput);
837+
866838
values[i] = OidInputFunctionCall(typinput, value, typioparam, -1);
867839
prt = OidOutputFunctionCall(typoutput, values[i]);
868840
elog(DEBUG4, "inserted -> %s", prt);
@@ -972,6 +944,83 @@ gettype(char *type)
972944
return 0;
973945
}
974946

947+
/* ----------------
948+
* boot_get_type_io_data
949+
*
950+
* Obtain type I/O information at bootstrap time. This intentionally has
951+
* almost the same API as lsyscache.c's get_type_io_data, except that
952+
* we only support obtaining the typinput and typoutput routines, not
953+
* the binary I/O routines. It is exported so that array_in and array_out
954+
* can be made to work during early bootstrap.
955+
* ----------------
956+
*/
957+
void
958+
boot_get_type_io_data(Oid typid,
959+
int16 *typlen,
960+
bool *typbyval,
961+
char *typalign,
962+
char *typdelim,
963+
Oid *typioparam,
964+
Oid *typinput,
965+
Oid *typoutput)
966+
{
967+
if (Typ != NULL)
968+
{
969+
/* We have the boot-time contents of pg_type, so use it */
970+
struct typmap **app;
971+
struct typmap *ap;
972+
973+
app = Typ;
974+
while (*app && (*app)->am_oid != typid)
975+
++app;
976+
ap = *app;
977+
if (ap == NULL)
978+
elog(ERROR, "type OID %u not found in Typ list", typid);
979+
980+
*typlen = ap->am_typ.typlen;
981+
*typbyval = ap->am_typ.typbyval;
982+
*typalign = ap->am_typ.typalign;
983+
*typdelim = ap->am_typ.typdelim;
984+
985+
/* XXX this logic must match getTypeIOParam() */
986+
if (OidIsValid(ap->am_typ.typelem))
987+
*typioparam = ap->am_typ.typelem;
988+
else
989+
*typioparam = typid;
990+
991+
*typinput = ap->am_typ.typinput;
992+
*typoutput = ap->am_typ.typoutput;
993+
}
994+
else
995+
{
996+
/* We don't have pg_type yet, so use the hard-wired TypInfo array */
997+
int typeindex;
998+
999+
for (typeindex = 0; typeindex < n_types; typeindex++)
1000+
{
1001+
if (TypInfo[typeindex].oid == typid)
1002+
break;
1003+
}
1004+
if (typeindex >= n_types)
1005+
elog(ERROR, "type OID %u not found in TypInfo", typid);
1006+
1007+
*typlen = TypInfo[typeindex].len;
1008+
*typbyval = TypInfo[typeindex].byval;
1009+
*typalign = TypInfo[typeindex].align;
1010+
/* We assume typdelim is ',' for all boot-time types */
1011+
*typdelim = ',';
1012+
1013+
/* XXX this logic must match getTypeIOParam() */
1014+
if (OidIsValid(TypInfo[typeindex].elem))
1015+
*typioparam = TypInfo[typeindex].elem;
1016+
else
1017+
*typioparam = typid;
1018+
1019+
*typinput = TypInfo[typeindex].inproc;
1020+
*typoutput = TypInfo[typeindex].outproc;
1021+
}
1022+
}
1023+
9751024
/* ----------------
9761025
* AllocateAttribute
9771026
* ----------------

src/backend/utils/cache/lsyscache.c

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.135 2006/07/14 14:52:25 momjian Exp $
10+
* $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.136 2006/08/15 22:36:17 tgl Exp $
1111
*
1212
* NOTES
1313
* Eventually, the index information should go through here, too.
@@ -16,6 +16,7 @@
1616
#include "postgres.h"
1717

1818
#include "access/hash.h"
19+
#include "bootstrap/bootstrap.h"
1920
#include "catalog/pg_amop.h"
2021
#include "catalog/pg_amproc.h"
2122
#include "catalog/pg_namespace.h"
@@ -24,6 +25,7 @@
2425
#include "catalog/pg_proc.h"
2526
#include "catalog/pg_statistic.h"
2627
#include "catalog/pg_type.h"
28+
#include "miscadmin.h"
2729
#include "nodes/makefuncs.h"
2830
#include "utils/array.h"
2931
#include "utils/builtins.h"
@@ -1350,7 +1352,7 @@ get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval,
13501352
* This knowledge is intended to be centralized here --- direct references
13511353
* to typelem elsewhere in the code are wrong, if they are associated with
13521354
* I/O calls and not with actual subscripting operations! (But see
1353-
* bootstrap.c, which can't conveniently use this routine.)
1355+
* bootstrap.c's boot_get_type_io_data() if you need to change this.)
13541356
*
13551357
* As of PostgreSQL 8.1, output functions receive only the value itself
13561358
* and not any auxiliary parameters, so the name of this routine is now
@@ -1392,6 +1394,38 @@ get_type_io_data(Oid typid,
13921394
HeapTuple typeTuple;
13931395
Form_pg_type typeStruct;
13941396

1397+
/*
1398+
* In bootstrap mode, pass it off to bootstrap.c. This hack allows
1399+
* us to use array_in and array_out during bootstrap.
1400+
*/
1401+
if (IsBootstrapProcessingMode())
1402+
{
1403+
Oid typinput;
1404+
Oid typoutput;
1405+
1406+
boot_get_type_io_data(typid,
1407+
typlen,
1408+
typbyval,
1409+
typalign,
1410+
typdelim,
1411+
typioparam,
1412+
&typinput,
1413+
&typoutput);
1414+
switch (which_func)
1415+
{
1416+
case IOFunc_input:
1417+
*func = typinput;
1418+
break;
1419+
case IOFunc_output:
1420+
*func = typoutput;
1421+
break;
1422+
default:
1423+
elog(ERROR, "binary I/O not supported during bootstrap");
1424+
break;
1425+
}
1426+
return;
1427+
}
1428+
13951429
typeTuple = SearchSysCache(TYPEOID,
13961430
ObjectIdGetDatum(typid),
13971431
0, 0, 0);

src/include/bootstrap/bootstrap.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/bootstrap/bootstrap.h,v 1.42 2006/07/13 16:49:19 momjian Exp $
10+
* $PostgreSQL: pgsql/src/include/bootstrap/bootstrap.h,v 1.43 2006/08/15 22:36:17 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -50,6 +50,15 @@ extern char *CleanUpStr(char *s);
5050
extern int EnterString(char *str);
5151
extern void build_indices(void);
5252

53+
extern void boot_get_type_io_data(Oid typid,
54+
int16 *typlen,
55+
bool *typbyval,
56+
char *typalign,
57+
char *typdelim,
58+
Oid *typioparam,
59+
Oid *typinput,
60+
Oid *typoutput);
61+
5362
extern int boot_yyparse(void);
5463

5564
extern int boot_yylex(void);

0 commit comments

Comments
 (0)