Commit 8d9e025e authored by Tom Lane's avatar Tom Lane

Instead of storing pg_statistic stavalues entries as text strings, store

them as arrays of the internal datatype.  This requires treating the
stavalues columns as 'anyarray' rather than 'text[]', which is not 100%
kosher but seems to work fine for the purposes we need for pg_statistic.
Perhaps in the future 'anyarray' will be allowed more generally.
parent efeffae2
<!--
Documentation of the system catalogs, directed toward PostgreSQL developers
$Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.66 2003/02/22 00:45:03 tgl Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.67 2003/03/23 05:14:36 tgl Exp $
-->
<chapter id="catalogs">
......@@ -3050,12 +3050,14 @@
<row>
<entry>stavaluesN</entry>
<entry><type>text[]</type></entry>
<entry><type>anyarray</type></entry>
<entry></entry>
<entry>Column data values of the appropriate kind for the Nth
<quote>slot</quote>, or NULL if the slot kind does not store any data values.
For data-type independence, all column data values are converted
to external textual form and stored as TEXT datums.
<quote>slot</quote>, or NULL if the slot kind does not store any data
values.
Each array's element values are actually of the specific column's
datatype, so there is no way to define these columns' type more
specifically than <quote>anyarray</>.
</entry>
</row>
</tbody>
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.240 2003/03/20 03:34:55 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.241 2003/03/23 05:14:36 tgl Exp $
*
*
* INTERFACE ROUTINES
......@@ -421,8 +421,12 @@ CheckAttributeType(const char *attname, Oid atttypid)
"\n\tProceeding with relation creation anyway",
attname);
else if (att_typtype == 'p')
elog(ERROR, "Attribute \"%s\" has pseudo-type %s",
attname, format_type_be(atttypid));
{
/* Special hack for pg_statistic: allow ANYARRAY during initdb */
if (atttypid != ANYARRAYOID || IsUnderPostmaster)
elog(ERROR, "Attribute \"%s\" has pseudo-type %s",
attname, format_type_be(atttypid));
}
else if (att_typtype == 'c')
{
Oid typrelid = get_typ_typrelid(atttypid);
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/analyze.c,v 1.51 2002/11/29 21:39:10 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/analyze.c,v 1.52 2003/03/23 05:14:36 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -1694,7 +1694,6 @@ update_attstats(Oid relid, int natts, VacAttrStats **vacattrstats)
for (attno = 0; attno < natts; attno++)
{
VacAttrStats *stats = vacattrstats[attno];
FmgrInfo out_function;
HeapTuple stup,
oldtup;
int i,
......@@ -1708,8 +1707,6 @@ update_attstats(Oid relid, int natts, VacAttrStats **vacattrstats)
if (!stats->stats_valid)
continue;
fmgr_info(stats->attrtype->typoutput, &out_function);
/*
* Construct a new pg_statistic tuple
*/
......@@ -1758,33 +1755,16 @@ update_attstats(Oid relid, int natts, VacAttrStats **vacattrstats)
}
for (k = 0; k < STATISTIC_NUM_SLOTS; k++)
{
int ntxt = stats->numvalues[k];
if (ntxt > 0)
if (stats->numvalues[k] > 0)
{
Datum *txtdatums = (Datum *) palloc(ntxt * sizeof(Datum));
ArrayType *arry;
for (n = 0; n < ntxt; n++)
{
/*
* Convert data values to a text string to be inserted
* into the text array.
*/
Datum stringdatum;
stringdatum =
FunctionCall3(&out_function,
stats->stavalues[k][n],
ObjectIdGetDatum(stats->attrtype->typelem),
Int32GetDatum(stats->attr->atttypmod));
txtdatums[n] = DirectFunctionCall1(textin, stringdatum);
pfree(DatumGetPointer(stringdatum));
}
/* XXX knows more than it should about type text: */
arry = construct_array(txtdatums, ntxt,
TEXTOID,
-1, false, 'i');
arry = construct_array(stats->stavalues[k],
stats->numvalues[k],
stats->attr->atttypid,
stats->attrtype->typlen,
stats->attrtype->typbyval,
stats->attrtype->typalign);
values[i++] = PointerGetDatum(arry); /* stavaluesN */
}
else
......
......@@ -15,7 +15,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.133 2003/03/23 01:49:02 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.134 2003/03/23 05:14:36 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -1826,16 +1826,11 @@ mergejoinscansel(Query *root, Node *clause,
/*
* Now skip any binary-compatible relabeling; there can only be one level
* since constant-expression folder eliminates adjacent RelabelTypes.
*
* XXX can't enable this quite yet, it exposes regproc uncertainty problems
* in regression tests. FIXME soon.
*/
#if 0
if (IsA(left, RelabelType))
left = (Var *) ((RelabelType *) left)->arg;
if (IsA(right, RelabelType))
right = (Var *) ((RelabelType *) right)->arg;
#endif
/* Can't do anything if inputs are not Vars */
if (!IsA(left, Var) ||
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.90 2003/02/03 21:15:44 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.91 2003/03/23 05:14:36 tgl Exp $
*
* NOTES
* Eventually, the index information should go through here, too.
......@@ -28,6 +28,7 @@
#include "nodes/makefuncs.h"
#include "utils/array.h"
#include "utils/builtins.h"
#include "utils/datum.h"
#include "utils/lsyscache.h"
#include "utils/syscache.h"
......@@ -1387,8 +1388,7 @@ get_attstatsslot(HeapTuple statstuple,
ArrayType *statarray;
int narrayelem;
HeapTuple typeTuple;
FmgrInfo inputproc;
Oid typelem;
Form_pg_type typeForm;
for (i = 0; i < STATISTIC_NUM_SLOTS; i++)
{
......@@ -1408,48 +1408,40 @@ get_attstatsslot(HeapTuple statstuple,
elog(ERROR, "get_attstatsslot: stavalues is null");
statarray = DatumGetArrayTypeP(val);
/*
* Do initial examination of the array. This produces a list of
* text Datums --- ie, pointers into the text array value.
*/
deconstruct_array(statarray,
TEXTOID, -1, false, 'i',
values, nvalues);
narrayelem = *nvalues;
/*
* We now need to replace each text Datum by its internal
* equivalent.
*
* Get the type input proc and typelem for the column datatype.
*/
/* Need to get info about the array element type */
typeTuple = SearchSysCache(TYPEOID,
ObjectIdGetDatum(atttype),
0, 0, 0);
if (!HeapTupleIsValid(typeTuple))
elog(ERROR, "get_attstatsslot: Cache lookup failed for type %u",
atttype);
fmgr_info(((Form_pg_type) GETSTRUCT(typeTuple))->typinput, &inputproc);
typelem = ((Form_pg_type) GETSTRUCT(typeTuple))->typelem;
ReleaseSysCache(typeTuple);
typeForm = (Form_pg_type) GETSTRUCT(typeTuple);
/* Deconstruct array into Datum elements */
deconstruct_array(statarray,
atttype,
typeForm->typlen,
typeForm->typbyval,
typeForm->typalign,
values, nvalues);
/*
* Do the conversions. The palloc'd array of Datums is reused in
* place.
* If the element type is pass-by-reference, we now have a bunch
* of Datums that are pointers into the syscache value. Copy them
* to avoid problems if syscache decides to drop the entry.
*/
for (j = 0; j < narrayelem; j++)
if (!typeForm->typbyval)
{
char *strval;
strval = DatumGetCString(DirectFunctionCall1(textout,
(*values)[j]));
(*values)[j] = FunctionCall3(&inputproc,
CStringGetDatum(strval),
ObjectIdGetDatum(typelem),
Int32GetDatum(atttypmod));
pfree(strval);
for (j = 0; j < *nvalues; j++)
{
(*values)[j] = datumCopy((*values)[j],
typeForm->typbyval,
typeForm->typlen);
}
}
ReleaseSysCache(typeTuple);
/*
* Free statarray if it's a detoasted copy.
*/
......
......@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: catversion.h,v 1.182 2003/03/21 01:58:04 tgl Exp $
* $Id: catversion.h,v 1.183 2003/03/23 05:14:37 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 200303201
#define CATALOG_VERSION_NO 200303221
#endif
......@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_statistic.h,v 1.19 2003/03/10 22:28:21 tgl Exp $
* $Id: pg_statistic.h,v 1.20 2003/03/23 05:14:37 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
......@@ -26,6 +26,12 @@
* ----------------
*/
/*
* Keep C compiler happy with anyarray, below. This will need to go elsewhere
* if we ever use anyarray for more than pg_statistic.
*/
typedef struct varlena anyarray;
/* ----------------
* pg_statistic definition. cpp turns this into
* typedef struct FormData_pg_statistic
......@@ -109,14 +115,14 @@ CATALOG(pg_statistic) BKI_WITHOUT_OIDS
float4 stanumbers4[1];
/*
* Values in these text arrays are external representations of values
* of the column's data type. To re-create the actual Datum, do
* datatypein(textout(arrayelement)).
* Values in these arrays are values of the column's data type. We
* presently have to cheat quite a bit to allow polymorphic arrays
* of this kind, but perhaps someday it'll be a less bogus facility.
*/
text stavalues1[1];
text stavalues2[1];
text stavalues3[1];
text stavalues4[1];
anyarray stavalues1;
anyarray stavalues2;
anyarray stavalues3;
anyarray stavalues4;
} FormData_pg_statistic;
#define STATISTIC_NUM_SLOTS 4
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment