diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2006-08-15 22:36:17 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2006-08-15 22:36:17 +0000 |
commit | 1395ac6c67db2f91a78f8f765015ab51ddc03c85 (patch) | |
tree | bf882549cd8372bd85f5ca62a25b26b87e392adb /src/backend/bootstrap/bootstrap.c | |
parent | 355865c5a7c76238731fe71071c3cc73427ea570 (diff) | |
download | postgresql-1395ac6c67db2f91a78f8f765015ab51ddc03c85.tar.gz postgresql-1395ac6c67db2f91a78f8f765015ab51ddc03c85.zip |
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.
Diffstat (limited to 'src/backend/bootstrap/bootstrap.c')
-rw-r--r-- | src/backend/bootstrap/bootstrap.c | 129 |
1 files changed, 89 insertions, 40 deletions
diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c index 08189bf07b2..06d8a5ca4fc 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); @@ -973,6 +945,83 @@ gettype(char *type) } /* ---------------- + * 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 * ---------------- */ |