From 1395ac6c67db2f91a78f8f765015ab51ddc03c85 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Tue, 15 Aug 2006 22:36:17 +0000 Subject: [PATCH] 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. --- src/backend/bootstrap/bootstrap.c | 129 +++++++++++++++++++--------- src/backend/utils/cache/lsyscache.c | 38 +++++++- src/include/bootstrap/bootstrap.h | 11 ++- 3 files changed, 135 insertions(+), 43 deletions(-) diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c index 08189bf07b..06d8a5ca4f 100644 --- a/src/backend/bootstrap/bootstrap.c +++ b/src/backend/bootstrap/bootstrap.c @@ -8,7 +8,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.223 2006/07/31 20:09:00 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.224 2006/08/15 22:36:17 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -590,6 +590,7 @@ boot_openrel(char *relname) if (Typ == NULL) { + /* We can now load the pg_type data */ rel = heap_open(TypeRelationId, NoLock); scan = heap_beginscan(rel, SnapshotNow, 0, NULL); i = 0; @@ -806,6 +807,10 @@ void InsertOneValue(char *value, int i) { Oid typoid; + int16 typlen; + bool typbyval; + char typalign; + char typdelim; Oid typioparam; Oid typinput; Oid typoutput; @@ -817,52 +822,19 @@ InsertOneValue(char *value, int i) if (Typ != NULL) { - struct typmap **app; - struct typmap *ap; - - elog(DEBUG5, "Typ != NULL"); typoid = boot_reldesc->rd_att->attrs[i]->atttypid; - app = Typ; - while (*app && (*app)->am_oid != typoid) - ++app; - ap = *app; - if (ap == NULL) - elog(ERROR, "could not find atttypid %u in Typ list", typoid); - - /* XXX this logic should match getTypeIOParam() */ - if (OidIsValid(ap->am_typ.typelem)) - typioparam = ap->am_typ.typelem; - else - typioparam = typoid; - - typinput = ap->am_typ.typinput; - typoutput = ap->am_typ.typoutput; } else { - int typeindex; - - /* XXX why is typoid determined differently in this path? */ + /* XXX why is typoid determined differently in this case? */ typoid = attrtypes[i]->atttypid; - for (typeindex = 0; typeindex < n_types; typeindex++) - { - if (TypInfo[typeindex].oid == typoid) - break; - } - if (typeindex >= n_types) - elog(ERROR, "type oid %u not found", typoid); - elog(DEBUG5, "Typ == NULL, typeindex = %u", typeindex); - - /* XXX this logic should match getTypeIOParam() */ - if (OidIsValid(TypInfo[typeindex].elem)) - typioparam = TypInfo[typeindex].elem; - else - typioparam = typoid; - - typinput = TypInfo[typeindex].inproc; - typoutput = TypInfo[typeindex].outproc; } + boot_get_type_io_data(typoid, + &typlen, &typbyval, &typalign, + &typdelim, &typioparam, + &typinput, &typoutput); + values[i] = OidInputFunctionCall(typinput, value, typioparam, -1); prt = OidOutputFunctionCall(typoutput, values[i]); elog(DEBUG4, "inserted -> %s", prt); @@ -972,6 +944,83 @@ gettype(char *type) return 0; } +/* ---------------- + * boot_get_type_io_data + * + * Obtain type I/O information at bootstrap time. This intentionally has + * almost the same API as lsyscache.c's get_type_io_data, except that + * we only support obtaining the typinput and typoutput routines, not + * the binary I/O routines. It is exported so that array_in and array_out + * can be made to work during early bootstrap. + * ---------------- + */ +void +boot_get_type_io_data(Oid typid, + int16 *typlen, + bool *typbyval, + char *typalign, + char *typdelim, + Oid *typioparam, + Oid *typinput, + Oid *typoutput) +{ + if (Typ != NULL) + { + /* We have the boot-time contents of pg_type, so use it */ + struct typmap **app; + struct typmap *ap; + + app = Typ; + while (*app && (*app)->am_oid != typid) + ++app; + ap = *app; + if (ap == NULL) + elog(ERROR, "type OID %u not found in Typ list", typid); + + *typlen = ap->am_typ.typlen; + *typbyval = ap->am_typ.typbyval; + *typalign = ap->am_typ.typalign; + *typdelim = ap->am_typ.typdelim; + + /* XXX this logic must match getTypeIOParam() */ + if (OidIsValid(ap->am_typ.typelem)) + *typioparam = ap->am_typ.typelem; + else + *typioparam = typid; + + *typinput = ap->am_typ.typinput; + *typoutput = ap->am_typ.typoutput; + } + else + { + /* We don't have pg_type yet, so use the hard-wired TypInfo array */ + int typeindex; + + for (typeindex = 0; typeindex < n_types; typeindex++) + { + if (TypInfo[typeindex].oid == typid) + break; + } + if (typeindex >= n_types) + elog(ERROR, "type OID %u not found in TypInfo", typid); + + *typlen = TypInfo[typeindex].len; + *typbyval = TypInfo[typeindex].byval; + *typalign = TypInfo[typeindex].align; + /* We assume typdelim is ',' for all boot-time types */ + *typdelim = ','; + + /* XXX this logic must match getTypeIOParam() */ + if (OidIsValid(TypInfo[typeindex].elem)) + *typioparam = TypInfo[typeindex].elem; + else + *typioparam = typid; + + *typinput = TypInfo[typeindex].inproc; + *typoutput = TypInfo[typeindex].outproc; + } +} + /* ---------------- * AllocateAttribute * ---------------- diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c index 93fa1f029f..769206e02c 100644 --- a/src/backend/utils/cache/lsyscache.c +++ b/src/backend/utils/cache/lsyscache.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.135 2006/07/14 14:52:25 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.136 2006/08/15 22:36:17 tgl Exp $ * * NOTES * Eventually, the index information should go through here, too. @@ -16,6 +16,7 @@ #include "postgres.h" #include "access/hash.h" +#include "bootstrap/bootstrap.h" #include "catalog/pg_amop.h" #include "catalog/pg_amproc.h" #include "catalog/pg_namespace.h" @@ -24,6 +25,7 @@ #include "catalog/pg_proc.h" #include "catalog/pg_statistic.h" #include "catalog/pg_type.h" +#include "miscadmin.h" #include "nodes/makefuncs.h" #include "utils/array.h" #include "utils/builtins.h" @@ -1350,7 +1352,7 @@ get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, * This knowledge is intended to be centralized here --- direct references * to typelem elsewhere in the code are wrong, if they are associated with * I/O calls and not with actual subscripting operations! (But see - * bootstrap.c, which can't conveniently use this routine.) + * bootstrap.c's boot_get_type_io_data() if you need to change this.) * * As of PostgreSQL 8.1, output functions receive only the value itself * and not any auxiliary parameters, so the name of this routine is now @@ -1392,6 +1394,38 @@ get_type_io_data(Oid typid, HeapTuple typeTuple; Form_pg_type typeStruct; + /* + * In bootstrap mode, pass it off to bootstrap.c. This hack allows + * us to use array_in and array_out during bootstrap. + */ + if (IsBootstrapProcessingMode()) + { + Oid typinput; + Oid typoutput; + + boot_get_type_io_data(typid, + typlen, + typbyval, + typalign, + typdelim, + typioparam, + &typinput, + &typoutput); + switch (which_func) + { + case IOFunc_input: + *func = typinput; + break; + case IOFunc_output: + *func = typoutput; + break; + default: + elog(ERROR, "binary I/O not supported during bootstrap"); + break; + } + return; + } + typeTuple = SearchSysCache(TYPEOID, ObjectIdGetDatum(typid), 0, 0, 0); diff --git a/src/include/bootstrap/bootstrap.h b/src/include/bootstrap/bootstrap.h index 807f276646..6713b6df67 100644 --- a/src/include/bootstrap/bootstrap.h +++ b/src/include/bootstrap/bootstrap.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/bootstrap/bootstrap.h,v 1.42 2006/07/13 16:49:19 momjian Exp $ + * $PostgreSQL: pgsql/src/include/bootstrap/bootstrap.h,v 1.43 2006/08/15 22:36:17 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -50,6 +50,15 @@ extern char *CleanUpStr(char *s); extern int EnterString(char *str); extern void build_indices(void); +extern void boot_get_type_io_data(Oid typid, + int16 *typlen, + bool *typbyval, + char *typalign, + char *typdelim, + Oid *typioparam, + Oid *typinput, + Oid *typoutput); + extern int boot_yyparse(void); extern int boot_yylex(void); -- GitLab