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)
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