mirror of
https://github.com/postgres/postgres.git
synced 2025-05-23 00:02:38 -04:00
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.
This commit is contained in:
parent
355865c5a7
commit
1395ac6c67
@ -8,7 +8,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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)
|
if (Typ == NULL)
|
||||||
{
|
{
|
||||||
|
/* We can now load the pg_type data */
|
||||||
rel = heap_open(TypeRelationId, NoLock);
|
rel = heap_open(TypeRelationId, NoLock);
|
||||||
scan = heap_beginscan(rel, SnapshotNow, 0, NULL);
|
scan = heap_beginscan(rel, SnapshotNow, 0, NULL);
|
||||||
i = 0;
|
i = 0;
|
||||||
@ -806,6 +807,10 @@ void
|
|||||||
InsertOneValue(char *value, int i)
|
InsertOneValue(char *value, int i)
|
||||||
{
|
{
|
||||||
Oid typoid;
|
Oid typoid;
|
||||||
|
int16 typlen;
|
||||||
|
bool typbyval;
|
||||||
|
char typalign;
|
||||||
|
char typdelim;
|
||||||
Oid typioparam;
|
Oid typioparam;
|
||||||
Oid typinput;
|
Oid typinput;
|
||||||
Oid typoutput;
|
Oid typoutput;
|
||||||
@ -817,51 +822,18 @@ InsertOneValue(char *value, int i)
|
|||||||
|
|
||||||
if (Typ != NULL)
|
if (Typ != NULL)
|
||||||
{
|
{
|
||||||
struct typmap **app;
|
|
||||||
struct typmap *ap;
|
|
||||||
|
|
||||||
elog(DEBUG5, "Typ != NULL");
|
|
||||||
typoid = boot_reldesc->rd_att->attrs[i]->atttypid;
|
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
|
else
|
||||||
{
|
{
|
||||||
int typeindex;
|
/* XXX why is typoid determined differently in this case? */
|
||||||
|
|
||||||
/* XXX why is typoid determined differently in this path? */
|
|
||||||
typoid = attrtypes[i]->atttypid;
|
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() */
|
boot_get_type_io_data(typoid,
|
||||||
if (OidIsValid(TypInfo[typeindex].elem))
|
&typlen, &typbyval, &typalign,
|
||||||
typioparam = TypInfo[typeindex].elem;
|
&typdelim, &typioparam,
|
||||||
else
|
&typinput, &typoutput);
|
||||||
typioparam = typoid;
|
|
||||||
|
|
||||||
typinput = TypInfo[typeindex].inproc;
|
|
||||||
typoutput = TypInfo[typeindex].outproc;
|
|
||||||
}
|
|
||||||
|
|
||||||
values[i] = OidInputFunctionCall(typinput, value, typioparam, -1);
|
values[i] = OidInputFunctionCall(typinput, value, typioparam, -1);
|
||||||
prt = OidOutputFunctionCall(typoutput, values[i]);
|
prt = OidOutputFunctionCall(typoutput, values[i]);
|
||||||
@ -972,6 +944,83 @@ gettype(char *type)
|
|||||||
return 0;
|
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
|
* AllocateAttribute
|
||||||
* ----------------
|
* ----------------
|
||||||
|
38
src/backend/utils/cache/lsyscache.c
vendored
38
src/backend/utils/cache/lsyscache.c
vendored
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* NOTES
|
||||||
* Eventually, the index information should go through here, too.
|
* Eventually, the index information should go through here, too.
|
||||||
@ -16,6 +16,7 @@
|
|||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include "access/hash.h"
|
#include "access/hash.h"
|
||||||
|
#include "bootstrap/bootstrap.h"
|
||||||
#include "catalog/pg_amop.h"
|
#include "catalog/pg_amop.h"
|
||||||
#include "catalog/pg_amproc.h"
|
#include "catalog/pg_amproc.h"
|
||||||
#include "catalog/pg_namespace.h"
|
#include "catalog/pg_namespace.h"
|
||||||
@ -24,6 +25,7 @@
|
|||||||
#include "catalog/pg_proc.h"
|
#include "catalog/pg_proc.h"
|
||||||
#include "catalog/pg_statistic.h"
|
#include "catalog/pg_statistic.h"
|
||||||
#include "catalog/pg_type.h"
|
#include "catalog/pg_type.h"
|
||||||
|
#include "miscadmin.h"
|
||||||
#include "nodes/makefuncs.h"
|
#include "nodes/makefuncs.h"
|
||||||
#include "utils/array.h"
|
#include "utils/array.h"
|
||||||
#include "utils/builtins.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
|
* This knowledge is intended to be centralized here --- direct references
|
||||||
* to typelem elsewhere in the code are wrong, if they are associated with
|
* to typelem elsewhere in the code are wrong, if they are associated with
|
||||||
* I/O calls and not with actual subscripting operations! (But see
|
* 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
|
* 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
|
* 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;
|
HeapTuple typeTuple;
|
||||||
Form_pg_type typeStruct;
|
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,
|
typeTuple = SearchSysCache(TYPEOID,
|
||||||
ObjectIdGetDatum(typid),
|
ObjectIdGetDatum(typid),
|
||||||
0, 0, 0);
|
0, 0, 0);
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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 int EnterString(char *str);
|
||||||
extern void build_indices(void);
|
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_yyparse(void);
|
||||||
|
|
||||||
extern int boot_yylex(void);
|
extern int boot_yylex(void);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user