Commit 69946411 authored by Tom Lane's avatar Tom Lane

Add hooks for type-specific calculation of ANALYZE statistics. Idea and

coding by Mark Cave-Ayland, some kibitzing by Tom Lane.  initdb forced
due to new column in pg_type.
parent d27471fe
<!-- <!--
Documentation of the system catalogs, directed toward PostgreSQL developers Documentation of the system catalogs, directed toward PostgreSQL developers
$PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.82 2004/01/06 23:55:18 tgl Exp $ $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.83 2004/02/12 23:41:00 tgl Exp $
--> -->
<chapter id="catalogs"> <chapter id="catalogs">
...@@ -3524,6 +3524,13 @@ ...@@ -3524,6 +3524,13 @@
<entry>Output conversion function (binary format), or 0 if none</entry> <entry>Output conversion function (binary format), or 0 if none</entry>
</row> </row>
<row>
<entry><structfield>typanalyze</structfield></entry>
<entry><type>regproc</type></entry>
<entry><literal><link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.oid</literal></entry>
<entry>Custom ANALYZE function, or 0 to use the standard function</entry>
</row>
<row> <row>
<entry><structfield>typalign</structfield></entry> <entry><structfield>typalign</structfield></entry>
<entry><type>char</type></entry> <entry><type>char</type></entry>
......
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/ref/create_type.sgml,v 1.48 2003/11/29 19:51:38 pgsql Exp $ $PostgreSQL: pgsql/doc/src/sgml/ref/create_type.sgml,v 1.49 2004/02/12 23:41:02 tgl Exp $
PostgreSQL documentation PostgreSQL documentation
--> -->
...@@ -28,6 +28,7 @@ CREATE TYPE <replaceable class="parameter">name</replaceable> ( ...@@ -28,6 +28,7 @@ CREATE TYPE <replaceable class="parameter">name</replaceable> (
OUTPUT = <replaceable class="parameter">output_function</replaceable> OUTPUT = <replaceable class="parameter">output_function</replaceable>
[ , RECEIVE = <replaceable class="parameter">receive_function</replaceable> ] [ , RECEIVE = <replaceable class="parameter">receive_function</replaceable> ]
[ , SEND = <replaceable class="parameter">send_function</replaceable> ] [ , SEND = <replaceable class="parameter">send_function</replaceable> ]
[ , ANALYZE = <replaceable class="parameter">analyze_function</replaceable> ]
[ , INTERNALLENGTH = { <replaceable class="parameter">internallength</replaceable> | VARIABLE } ] [ , INTERNALLENGTH = { <replaceable class="parameter">internallength</replaceable> | VARIABLE } ]
[ , PASSEDBYVALUE ] [ , PASSEDBYVALUE ]
[ , ALIGNMENT = <replaceable class="parameter">alignment</replaceable> ] [ , ALIGNMENT = <replaceable class="parameter">alignment</replaceable> ]
...@@ -83,8 +84,9 @@ CREATE TYPE <replaceable class="parameter">name</replaceable> ( ...@@ -83,8 +84,9 @@ CREATE TYPE <replaceable class="parameter">name</replaceable> (
<replaceable class="parameter">input_function</replaceable> and <replaceable class="parameter">input_function</replaceable> and
<replaceable class="parameter">output_function</replaceable> <replaceable class="parameter">output_function</replaceable>
are required, while the functions are required, while the functions
<replaceable class="parameter">receive_function</replaceable> and <replaceable class="parameter">receive_function</replaceable>,
<replaceable class="parameter">send_function</replaceable> <replaceable class="parameter">send_function</replaceable> and
<replaceable class="parameter">analyze_function</replaceable>
are optional. Generally these functions have to be coded in C are optional. Generally these functions have to be coded in C
or another low-level language. or another low-level language.
</para> </para>
...@@ -152,6 +154,19 @@ CREATE TYPE <replaceable class="parameter">name</replaceable> ( ...@@ -152,6 +154,19 @@ CREATE TYPE <replaceable class="parameter">name</replaceable> (
shell entry with a complete type definition, and the new type can be used. shell entry with a complete type definition, and the new type can be used.
</para> </para>
<para>
The optional <replaceable class="parameter">analyze_function</replaceable>
performs type-specific statistics collection for columns of the data type.
By default, <command>ANALYZE</> will attempt to gather statistics using
the type's <quote>equals</> and <quote>less-than</> operators, if there
is a default b-tree operator class for the type. For non-scalar types
this behavior is likely to be unsuitable, so it can be overridden by
specifying a custom analysis function. The analysis function must be
declared to take a single argument of type <type>internal</>, and return
a <type>boolean</> result. The detailed API for analysis functions appears
in <filename>src/include/commands/vacuum.h</>.
</para>
<para> <para>
While the details of the new type's internal representation are only While the details of the new type's internal representation are only
known to the I/O functions and other functions you create to work with known to the I/O functions and other functions you create to work with
...@@ -341,6 +356,16 @@ CREATE TYPE <replaceable class="parameter">name</replaceable> ( ...@@ -341,6 +356,16 @@ CREATE TYPE <replaceable class="parameter">name</replaceable> (
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><replaceable class="parameter">analyze_function</replaceable></term>
<listitem>
<para>
The name of a function that performs statistical analysis for the
data type.
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><replaceable class="parameter">internallength</replaceable></term> <term><replaceable class="parameter">internallength</replaceable></term>
<listitem> <listitem>
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.258 2004/02/10 01:55:24 tgl Exp $ * $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.259 2004/02/12 23:41:02 tgl Exp $
* *
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
...@@ -689,6 +689,7 @@ AddNewRelationType(const char *typeName, ...@@ -689,6 +689,7 @@ AddNewRelationType(const char *typeName,
F_RECORD_OUT, /* output procedure */ F_RECORD_OUT, /* output procedure */
F_RECORD_RECV, /* receive procedure */ F_RECORD_RECV, /* receive procedure */
F_RECORD_SEND, /* send procedure */ F_RECORD_SEND, /* send procedure */
InvalidOid, /* analyze procedure - default */
InvalidOid, /* array element type - irrelevant */ InvalidOid, /* array element type - irrelevant */
InvalidOid, /* domain base type - irrelevant */ InvalidOid, /* domain base type - irrelevant */
NULL, /* default type value - none */ NULL, /* default type value - none */
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/pg_type.c,v 1.92 2004/01/07 18:56:25 neilc Exp $ * $PostgreSQL: pgsql/src/backend/catalog/pg_type.c,v 1.93 2004/02/12 23:41:02 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -86,6 +86,7 @@ TypeShellMake(const char *typeName, Oid typeNamespace) ...@@ -86,6 +86,7 @@ TypeShellMake(const char *typeName, Oid typeNamespace)
values[i++] = ObjectIdGetDatum(InvalidOid); /* typoutput */ values[i++] = ObjectIdGetDatum(InvalidOid); /* typoutput */
values[i++] = ObjectIdGetDatum(InvalidOid); /* typreceive */ values[i++] = ObjectIdGetDatum(InvalidOid); /* typreceive */
values[i++] = ObjectIdGetDatum(InvalidOid); /* typsend */ values[i++] = ObjectIdGetDatum(InvalidOid); /* typsend */
values[i++] = ObjectIdGetDatum(InvalidOid); /* typanalyze */
values[i++] = CharGetDatum('i'); /* typalign */ values[i++] = CharGetDatum('i'); /* typalign */
values[i++] = CharGetDatum('p'); /* typstorage */ values[i++] = CharGetDatum('p'); /* typstorage */
values[i++] = BoolGetDatum(false); /* typnotnull */ values[i++] = BoolGetDatum(false); /* typnotnull */
...@@ -121,6 +122,7 @@ TypeShellMake(const char *typeName, Oid typeNamespace) ...@@ -121,6 +122,7 @@ TypeShellMake(const char *typeName, Oid typeNamespace)
InvalidOid, InvalidOid,
InvalidOid, InvalidOid,
InvalidOid, InvalidOid,
InvalidOid,
NULL, NULL,
false); false);
...@@ -157,6 +159,7 @@ TypeCreate(const char *typeName, ...@@ -157,6 +159,7 @@ TypeCreate(const char *typeName,
Oid outputProcedure, Oid outputProcedure,
Oid receiveProcedure, Oid receiveProcedure,
Oid sendProcedure, Oid sendProcedure,
Oid analyzeProcedure,
Oid elementType, Oid elementType,
Oid baseType, Oid baseType,
const char *defaultTypeValue, /* human readable rep */ const char *defaultTypeValue, /* human readable rep */
...@@ -236,6 +239,7 @@ TypeCreate(const char *typeName, ...@@ -236,6 +239,7 @@ TypeCreate(const char *typeName,
values[i++] = ObjectIdGetDatum(outputProcedure); /* typoutput */ values[i++] = ObjectIdGetDatum(outputProcedure); /* typoutput */
values[i++] = ObjectIdGetDatum(receiveProcedure); /* typreceive */ values[i++] = ObjectIdGetDatum(receiveProcedure); /* typreceive */
values[i++] = ObjectIdGetDatum(sendProcedure); /* typsend */ values[i++] = ObjectIdGetDatum(sendProcedure); /* typsend */
values[i++] = ObjectIdGetDatum(analyzeProcedure); /* typanalyze */
values[i++] = CharGetDatum(alignment); /* typalign */ values[i++] = CharGetDatum(alignment); /* typalign */
values[i++] = CharGetDatum(storage); /* typstorage */ values[i++] = CharGetDatum(storage); /* typstorage */
values[i++] = BoolGetDatum(typeNotNull); /* typnotnull */ values[i++] = BoolGetDatum(typeNotNull); /* typnotnull */
...@@ -332,6 +336,7 @@ TypeCreate(const char *typeName, ...@@ -332,6 +336,7 @@ TypeCreate(const char *typeName,
outputProcedure, outputProcedure,
receiveProcedure, receiveProcedure,
sendProcedure, sendProcedure,
analyzeProcedure,
elementType, elementType,
baseType, baseType,
(defaultTypeBin ? (defaultTypeBin ?
...@@ -366,6 +371,7 @@ GenerateTypeDependencies(Oid typeNamespace, ...@@ -366,6 +371,7 @@ GenerateTypeDependencies(Oid typeNamespace,
Oid outputProcedure, Oid outputProcedure,
Oid receiveProcedure, Oid receiveProcedure,
Oid sendProcedure, Oid sendProcedure,
Oid analyzeProcedure,
Oid elementType, Oid elementType,
Oid baseType, Oid baseType,
Node *defaultExpr, Node *defaultExpr,
...@@ -425,6 +431,14 @@ GenerateTypeDependencies(Oid typeNamespace, ...@@ -425,6 +431,14 @@ GenerateTypeDependencies(Oid typeNamespace,
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
} }
if (OidIsValid(analyzeProcedure))
{
referenced.classId = RelOid_pg_proc;
referenced.objectId = analyzeProcedure;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
/* /*
* If the type is a rowtype for a relation, mark it as internally * If the type is a rowtype for a relation, mark it as internally
* dependent on the relation, *unless* it is a stand-alone composite * dependent on the relation, *unless* it is a stand-alone composite
......
This diff is collapsed.
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.52 2004/01/10 23:28:44 neilc Exp $ * $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.53 2004/02/12 23:41:02 tgl Exp $
* *
* DESCRIPTION * DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the * The "DefineFoo" routines take the parse tree and pick out the
...@@ -77,6 +77,7 @@ static Oid findTypeInputFunction(List *procname, Oid typeOid); ...@@ -77,6 +77,7 @@ static Oid findTypeInputFunction(List *procname, Oid typeOid);
static Oid findTypeOutputFunction(List *procname, Oid typeOid); static Oid findTypeOutputFunction(List *procname, Oid typeOid);
static Oid findTypeReceiveFunction(List *procname, Oid typeOid); static Oid findTypeReceiveFunction(List *procname, Oid typeOid);
static Oid findTypeSendFunction(List *procname, Oid typeOid); static Oid findTypeSendFunction(List *procname, Oid typeOid);
static Oid findTypeAnalyzeFunction(List *procname, Oid typeOid);
static List *get_rels_with_domain(Oid domainOid, LOCKMODE lockmode); static List *get_rels_with_domain(Oid domainOid, LOCKMODE lockmode);
static void domainOwnerCheck(HeapTuple tup, TypeName *typename); static void domainOwnerCheck(HeapTuple tup, TypeName *typename);
static char *domainAddConstraint(Oid domainOid, Oid domainNamespace, static char *domainAddConstraint(Oid domainOid, Oid domainNamespace,
...@@ -101,6 +102,7 @@ DefineType(List *names, List *parameters) ...@@ -101,6 +102,7 @@ DefineType(List *names, List *parameters)
List *outputName = NIL; List *outputName = NIL;
List *receiveName = NIL; List *receiveName = NIL;
List *sendName = NIL; List *sendName = NIL;
List *analyzeName = NIL;
char *defaultValue = NULL; char *defaultValue = NULL;
bool byValue = false; bool byValue = false;
char delimiter = DEFAULT_TYPDELIM; char delimiter = DEFAULT_TYPDELIM;
...@@ -110,6 +112,7 @@ DefineType(List *names, List *parameters) ...@@ -110,6 +112,7 @@ DefineType(List *names, List *parameters)
Oid outputOid; Oid outputOid;
Oid receiveOid = InvalidOid; Oid receiveOid = InvalidOid;
Oid sendOid = InvalidOid; Oid sendOid = InvalidOid;
Oid analyzeOid = InvalidOid;
char *shadow_type; char *shadow_type;
List *pl; List *pl;
Oid typoid; Oid typoid;
...@@ -151,6 +154,9 @@ DefineType(List *names, List *parameters) ...@@ -151,6 +154,9 @@ DefineType(List *names, List *parameters)
receiveName = defGetQualifiedName(defel); receiveName = defGetQualifiedName(defel);
else if (strcasecmp(defel->defname, "send") == 0) else if (strcasecmp(defel->defname, "send") == 0)
sendName = defGetQualifiedName(defel); sendName = defGetQualifiedName(defel);
else if (strcasecmp(defel->defname, "analyze") == 0 ||
strcasecmp(defel->defname, "analyse") == 0)
analyzeName = defGetQualifiedName(defel);
else if (strcasecmp(defel->defname, "delimiter") == 0) else if (strcasecmp(defel->defname, "delimiter") == 0)
{ {
char *p = defGetString(defel); char *p = defGetString(defel);
...@@ -318,6 +324,13 @@ DefineType(List *names, List *parameters) ...@@ -318,6 +324,13 @@ DefineType(List *names, List *parameters)
NameListToString(sendName)))); NameListToString(sendName))));
} }
/*
* Convert analysis function proc name to an OID. If no analysis function
* is specified, we'll use zero to select the built-in default algorithm.
*/
if (analyzeName)
analyzeOid = findTypeAnalyzeFunction(analyzeName, typoid);
/* /*
* now have TypeCreate do all the real work. * now have TypeCreate do all the real work.
*/ */
...@@ -334,6 +347,7 @@ DefineType(List *names, List *parameters) ...@@ -334,6 +347,7 @@ DefineType(List *names, List *parameters)
outputOid, /* output procedure */ outputOid, /* output procedure */
receiveOid, /* receive procedure */ receiveOid, /* receive procedure */
sendOid, /* send procedure */ sendOid, /* send procedure */
analyzeOid, /* analyze procedure */
elemType, /* element type ID */ elemType, /* element type ID */
InvalidOid, /* base type ID (only for domains) */ InvalidOid, /* base type ID (only for domains) */
defaultValue, /* default type value */ defaultValue, /* default type value */
...@@ -366,6 +380,7 @@ DefineType(List *names, List *parameters) ...@@ -366,6 +380,7 @@ DefineType(List *names, List *parameters)
F_ARRAY_OUT, /* output procedure */ F_ARRAY_OUT, /* output procedure */
F_ARRAY_RECV, /* receive procedure */ F_ARRAY_RECV, /* receive procedure */
F_ARRAY_SEND, /* send procedure */ F_ARRAY_SEND, /* send procedure */
InvalidOid, /* analyze procedure - default */
typoid, /* element type ID */ typoid, /* element type ID */
InvalidOid, /* base type ID */ InvalidOid, /* base type ID */
NULL, /* never a default type value */ NULL, /* never a default type value */
...@@ -473,6 +488,7 @@ DefineDomain(CreateDomainStmt *stmt) ...@@ -473,6 +488,7 @@ DefineDomain(CreateDomainStmt *stmt)
Oid outputProcedure; Oid outputProcedure;
Oid receiveProcedure; Oid receiveProcedure;
Oid sendProcedure; Oid sendProcedure;
Oid analyzeProcedure;
bool byValue; bool byValue;
char delimiter; char delimiter;
char alignment; char alignment;
...@@ -562,6 +578,9 @@ DefineDomain(CreateDomainStmt *stmt) ...@@ -562,6 +578,9 @@ DefineDomain(CreateDomainStmt *stmt)
receiveProcedure = baseType->typreceive; receiveProcedure = baseType->typreceive;
sendProcedure = baseType->typsend; sendProcedure = baseType->typsend;
/* Analysis function */
analyzeProcedure = baseType->typanalyze;
/* Inherited default value */ /* Inherited default value */
datum = SysCacheGetAttr(TYPEOID, typeTup, datum = SysCacheGetAttr(TYPEOID, typeTup,
Anum_pg_type_typdefault, &isnull); Anum_pg_type_typdefault, &isnull);
...@@ -714,6 +733,7 @@ DefineDomain(CreateDomainStmt *stmt) ...@@ -714,6 +733,7 @@ DefineDomain(CreateDomainStmt *stmt)
outputProcedure, /* output procedure */ outputProcedure, /* output procedure */
receiveProcedure, /* receive procedure */ receiveProcedure, /* receive procedure */
sendProcedure, /* send procedure */ sendProcedure, /* send procedure */
analyzeProcedure, /* analyze procedure */
basetypelem, /* element type ID */ basetypelem, /* element type ID */
basetypeoid, /* base type ID */ basetypeoid, /* base type ID */
defaultValue, /* default type value (text) */ defaultValue, /* default type value (text) */
...@@ -1033,6 +1053,35 @@ findTypeSendFunction(List *procname, Oid typeOid) ...@@ -1033,6 +1053,35 @@ findTypeSendFunction(List *procname, Oid typeOid)
return InvalidOid; /* keep compiler quiet */ return InvalidOid; /* keep compiler quiet */
} }
static Oid
findTypeAnalyzeFunction(List *procname, Oid typeOid)
{
Oid argList[FUNC_MAX_ARGS];
Oid procOid;
/*
* Analyze functions always take one INTERNAL argument and return bool.
*/
MemSet(argList, 0, FUNC_MAX_ARGS * sizeof(Oid));
argList[0] = INTERNALOID;
procOid = LookupFuncName(procname, 1, argList, true);
if (!OidIsValid(procOid))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_FUNCTION),
errmsg("function %s does not exist",
func_signature_string(procname, 1, argList))));
if (get_func_rettype(procOid) != BOOLOID)
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("type analyze function %s must return type \"boolean\"",
NameListToString(procname))));
return procOid;
}
/*------------------------------------------------------------------- /*-------------------------------------------------------------------
* DefineCompositeType * DefineCompositeType
...@@ -1192,6 +1241,7 @@ AlterDomainDefault(List *names, Node *defaultRaw) ...@@ -1192,6 +1241,7 @@ AlterDomainDefault(List *names, Node *defaultRaw)
typTup->typoutput, typTup->typoutput,
typTup->typreceive, typTup->typreceive,
typTup->typsend, typTup->typsend,
typTup->typanalyze,
typTup->typelem, typTup->typelem,
typTup->typbasetype, typTup->typbasetype,
defaultExpr, defaultExpr,
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
* by PostgreSQL * by PostgreSQL
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.363 2004/01/22 19:09:32 tgl Exp $ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.364 2004/02/12 23:41:03 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1648,9 +1648,9 @@ getTypes(int *numTypes) ...@@ -1648,9 +1648,9 @@ getTypes(int *numTypes)
/* /*
* Make sure there are dependencies from the type to its input and * Make sure there are dependencies from the type to its input and
* output functions. (We don't worry about typsend/typreceive since * output functions. (We don't worry about typsend, typreceive, or
* those are only valid in 7.4 and later, wherein the standard * typanalyze since those are only valid in 7.4 and later, wherein
* dependency mechanism will pick them up.) * the standard dependency mechanism will pick them up.)
*/ */
funcInfo = findFuncByOid(tinfo[i].typinput); funcInfo = findFuncByOid(tinfo[i].typinput);
if (funcInfo) if (funcInfo)
...@@ -4148,10 +4148,12 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo) ...@@ -4148,10 +4148,12 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
char *typoutput; char *typoutput;
char *typreceive; char *typreceive;
char *typsend; char *typsend;
char *typanalyze;
Oid typinputoid; Oid typinputoid;
Oid typoutputoid; Oid typoutputoid;
Oid typreceiveoid; Oid typreceiveoid;
Oid typsendoid; Oid typsendoid;
Oid typanalyzeoid;
char *typdelim; char *typdelim;
char *typdefault; char *typdefault;
char *typbyval; char *typbyval;
...@@ -4162,14 +4164,32 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo) ...@@ -4162,14 +4164,32 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
selectSourceSchema(tinfo->typnamespace->nspname); selectSourceSchema(tinfo->typnamespace->nspname);
/* Fetch type-specific details */ /* Fetch type-specific details */
if (fout->remoteVersion >= 70400) if (fout->remoteVersion >= 70500)
{ {
appendPQExpBuffer(query, "SELECT typlen, " appendPQExpBuffer(query, "SELECT typlen, "
"typinput, typoutput, typreceive, typsend, " "typinput, typoutput, typreceive, typsend, "
"typanalyze, "
"typinput::pg_catalog.oid as typinputoid, " "typinput::pg_catalog.oid as typinputoid, "
"typoutput::pg_catalog.oid as typoutputoid, " "typoutput::pg_catalog.oid as typoutputoid, "
"typreceive::pg_catalog.oid as typreceiveoid, " "typreceive::pg_catalog.oid as typreceiveoid, "
"typsend::pg_catalog.oid as typsendoid, " "typsend::pg_catalog.oid as typsendoid, "
"typanalyze::pg_catalog.oid as typanalyzeoid, "
"typdelim, typdefault, typbyval, typalign, "
"typstorage "
"FROM pg_catalog.pg_type "
"WHERE oid = '%u'::pg_catalog.oid",
tinfo->dobj.catId.oid);
}
else if (fout->remoteVersion >= 70400)
{
appendPQExpBuffer(query, "SELECT typlen, "
"typinput, typoutput, typreceive, typsend, "
"'-' as typanalyze, "
"typinput::pg_catalog.oid as typinputoid, "
"typoutput::pg_catalog.oid as typoutputoid, "
"typreceive::pg_catalog.oid as typreceiveoid, "
"typsend::pg_catalog.oid as typsendoid, "
"0 as typanalyzeoid, "
"typdelim, typdefault, typbyval, typalign, " "typdelim, typdefault, typbyval, typalign, "
"typstorage " "typstorage "
"FROM pg_catalog.pg_type " "FROM pg_catalog.pg_type "
...@@ -4181,9 +4201,11 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo) ...@@ -4181,9 +4201,11 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
appendPQExpBuffer(query, "SELECT typlen, " appendPQExpBuffer(query, "SELECT typlen, "
"typinput, typoutput, " "typinput, typoutput, "
"'-' as typreceive, '-' as typsend, " "'-' as typreceive, '-' as typsend, "
"'-' as typanalyze, "
"typinput::pg_catalog.oid as typinputoid, " "typinput::pg_catalog.oid as typinputoid, "
"typoutput::pg_catalog.oid as typoutputoid, " "typoutput::pg_catalog.oid as typoutputoid, "
"0 as typreceiveoid, 0 as typsendoid, " "0 as typreceiveoid, 0 as typsendoid, "
"0 as typanalyzeoid, "
"typdelim, typdefault, typbyval, typalign, " "typdelim, typdefault, typbyval, typalign, "
"typstorage " "typstorage "
"FROM pg_catalog.pg_type " "FROM pg_catalog.pg_type "
...@@ -4199,9 +4221,11 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo) ...@@ -4199,9 +4221,11 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
appendPQExpBuffer(query, "SELECT typlen, " appendPQExpBuffer(query, "SELECT typlen, "
"typinput, typoutput, " "typinput, typoutput, "
"'-' as typreceive, '-' as typsend, " "'-' as typreceive, '-' as typsend, "
"'-' as typanalyze, "
"typinput::oid as typinputoid, " "typinput::oid as typinputoid, "
"typoutput::oid as typoutputoid, " "typoutput::oid as typoutputoid, "
"0 as typreceiveoid, 0 as typsendoid, " "0 as typreceiveoid, 0 as typsendoid, "
"0 as typanalyzeoid, "
"typdelim, typdefault, typbyval, typalign, " "typdelim, typdefault, typbyval, typalign, "
"typstorage " "typstorage "
"FROM pg_type " "FROM pg_type "
...@@ -4213,9 +4237,11 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo) ...@@ -4213,9 +4237,11 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
appendPQExpBuffer(query, "SELECT typlen, " appendPQExpBuffer(query, "SELECT typlen, "
"typinput, typoutput, " "typinput, typoutput, "
"'-' as typreceive, '-' as typsend, " "'-' as typreceive, '-' as typsend, "
"'-' as typanalyze, "
"typinput::oid as typinputoid, " "typinput::oid as typinputoid, "
"typoutput::oid as typoutputoid, " "typoutput::oid as typoutputoid, "
"0 as typreceiveoid, 0 as typsendoid, " "0 as typreceiveoid, 0 as typsendoid, "
"0 as typanalyzeoid, "
"typdelim, typdefault, typbyval, typalign, " "typdelim, typdefault, typbyval, typalign, "
"'p'::char as typstorage " "'p'::char as typstorage "
"FROM pg_type " "FROM pg_type "
...@@ -4240,10 +4266,12 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo) ...@@ -4240,10 +4266,12 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
typoutput = PQgetvalue(res, 0, PQfnumber(res, "typoutput")); typoutput = PQgetvalue(res, 0, PQfnumber(res, "typoutput"));
typreceive = PQgetvalue(res, 0, PQfnumber(res, "typreceive")); typreceive = PQgetvalue(res, 0, PQfnumber(res, "typreceive"));
typsend = PQgetvalue(res, 0, PQfnumber(res, "typsend")); typsend = PQgetvalue(res, 0, PQfnumber(res, "typsend"));
typanalyze = PQgetvalue(res, 0, PQfnumber(res, "typanalyze"));
typinputoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typinputoid"))); typinputoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typinputoid")));
typoutputoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typoutputoid"))); typoutputoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typoutputoid")));
typreceiveoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typreceiveoid"))); typreceiveoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typreceiveoid")));
typsendoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typsendoid"))); typsendoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typsendoid")));
typanalyzeoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typanalyzeoid")));
typdelim = PQgetvalue(res, 0, PQfnumber(res, "typdelim")); typdelim = PQgetvalue(res, 0, PQfnumber(res, "typdelim"));
if (PQgetisnull(res, 0, PQfnumber(res, "typdefault"))) if (PQgetisnull(res, 0, PQfnumber(res, "typdefault")))
typdefault = NULL; typdefault = NULL;
...@@ -4270,13 +4298,15 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo) ...@@ -4270,13 +4298,15 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
if (fout->remoteVersion >= 70300) if (fout->remoteVersion >= 70300)
{ {
/* regproc result is correctly quoted in 7.3 */ /* regproc result is correctly quoted as of 7.3 */
appendPQExpBuffer(q, ",\n INPUT = %s", typinput); appendPQExpBuffer(q, ",\n INPUT = %s", typinput);
appendPQExpBuffer(q, ",\n OUTPUT = %s", typoutput); appendPQExpBuffer(q, ",\n OUTPUT = %s", typoutput);
if (OidIsValid(typreceiveoid)) if (OidIsValid(typreceiveoid))
appendPQExpBuffer(q, ",\n RECEIVE = %s", typreceive); appendPQExpBuffer(q, ",\n RECEIVE = %s", typreceive);
if (OidIsValid(typsendoid)) if (OidIsValid(typsendoid))
appendPQExpBuffer(q, ",\n SEND = %s", typsend); appendPQExpBuffer(q, ",\n SEND = %s", typsend);
if (OidIsValid(typanalyzeoid))
appendPQExpBuffer(q, ",\n ANALYZE = %s", typanalyze);
} }
else else
{ {
...@@ -4284,7 +4314,7 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo) ...@@ -4284,7 +4314,7 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
/* cannot combine these because fmtId uses static result area */ /* cannot combine these because fmtId uses static result area */
appendPQExpBuffer(q, ",\n INPUT = %s", fmtId(typinput)); appendPQExpBuffer(q, ",\n INPUT = %s", fmtId(typinput));
appendPQExpBuffer(q, ",\n OUTPUT = %s", fmtId(typoutput)); appendPQExpBuffer(q, ",\n OUTPUT = %s", fmtId(typoutput));
/* no chance that receive/send need be printed */ /* no chance that receive/send/analyze need be printed */
} }
if (typdefault != NULL) if (typdefault != NULL)
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2003, 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/catalog/catversion.h,v 1.217 2004/02/03 08:29:56 joe Exp $ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.218 2004/02/12 23:41:03 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -53,6 +53,6 @@ ...@@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 200402021 #define CATALOG_VERSION_NO 200402121
#endif #endif
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2003, 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/catalog/pg_attribute.h,v 1.107 2004/01/06 23:55:19 tgl Exp $ * $PostgreSQL: pgsql/src/include/catalog/pg_attribute.h,v 1.108 2004/02/12 23:41:04 tgl Exp $
* *
* NOTES * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
...@@ -240,14 +240,15 @@ typedef FormData_pg_attribute *Form_pg_attribute; ...@@ -240,14 +240,15 @@ typedef FormData_pg_attribute *Form_pg_attribute;
{ 1247, {"typoutput"}, 24, -1, 4, 12, 0, -1, -1, true, 'p', false, 'i', true, false, false, true, 0 }, \ { 1247, {"typoutput"}, 24, -1, 4, 12, 0, -1, -1, true, 'p', false, 'i', true, false, false, true, 0 }, \
{ 1247, {"typreceive"}, 24, -1, 4, 13, 0, -1, -1, true, 'p', false, 'i', true, false, false, true, 0 }, \ { 1247, {"typreceive"}, 24, -1, 4, 13, 0, -1, -1, true, 'p', false, 'i', true, false, false, true, 0 }, \
{ 1247, {"typsend"}, 24, -1, 4, 14, 0, -1, -1, true, 'p', false, 'i', true, false, false, true, 0 }, \ { 1247, {"typsend"}, 24, -1, 4, 14, 0, -1, -1, true, 'p', false, 'i', true, false, false, true, 0 }, \
{ 1247, {"typalign"}, 18, -1, 1, 15, 0, -1, -1, true, 'p', false, 'c', true, false, false, true, 0 }, \ { 1247, {"typanalyze"}, 24, -1, 4, 15, 0, -1, -1, true, 'p', false, 'i', true, false, false, true, 0 }, \
{ 1247, {"typstorage"}, 18, -1, 1, 16, 0, -1, -1, true, 'p', false, 'c', true, false, false, true, 0 }, \ { 1247, {"typalign"}, 18, -1, 1, 16, 0, -1, -1, true, 'p', false, 'c', true, false, false, true, 0 }, \
{ 1247, {"typnotnull"}, 16, -1, 1, 17, 0, -1, -1, true, 'p', false, 'c', true, false, false, true, 0 }, \ { 1247, {"typstorage"}, 18, -1, 1, 17, 0, -1, -1, true, 'p', false, 'c', true, false, false, true, 0 }, \
{ 1247, {"typbasetype"}, 26, -1, 4, 18, 0, -1, -1, true, 'p', false, 'i', true, false, false, true, 0 }, \ { 1247, {"typnotnull"}, 16, -1, 1, 18, 0, -1, -1, true, 'p', false, 'c', true, false, false, true, 0 }, \
{ 1247, {"typtypmod"}, 23, -1, 4, 19, 0, -1, -1, true, 'p', false, 'i', true, false, false, true, 0 }, \ { 1247, {"typbasetype"}, 26, -1, 4, 19, 0, -1, -1, true, 'p', false, 'i', true, false, false, true, 0 }, \
{ 1247, {"typndims"}, 23, -1, 4, 20, 0, -1, -1, true, 'p', false, 'i', true, false, false, true, 0 }, \ { 1247, {"typtypmod"}, 23, -1, 4, 20, 0, -1, -1, true, 'p', false, 'i', true, false, false, true, 0 }, \
{ 1247, {"typdefaultbin"}, 25, -1, -1, 21, 0, -1, -1, false, 'x', false, 'i', false, false, false, true, 0 }, \ { 1247, {"typndims"}, 23, -1, 4, 21, 0, -1, -1, true, 'p', false, 'i', true, false, false, true, 0 }, \
{ 1247, {"typdefault"}, 25, -1, -1, 22, 0, -1, -1, false, 'x', false, 'i', false, false, false, true, 0 } { 1247, {"typdefaultbin"}, 25, -1, -1, 22, 0, -1, -1, false, 'x', false, 'i', false, false, false, true, 0 }, \
{ 1247, {"typdefault"}, 25, -1, -1, 23, 0, -1, -1, false, 'x', false, 'i', false, false, false, true, 0 }
DATA(insert ( 1247 typname 19 -1 NAMEDATALEN 1 0 -1 -1 f p f i t f f t 0)); DATA(insert ( 1247 typname 19 -1 NAMEDATALEN 1 0 -1 -1 f p f i t f f t 0));
...@@ -264,14 +265,15 @@ DATA(insert ( 1247 typinput 24 -1 4 11 0 -1 -1 t p f i t f f t 0)); ...@@ -264,14 +265,15 @@ DATA(insert ( 1247 typinput 24 -1 4 11 0 -1 -1 t p f i t f f t 0));
DATA(insert ( 1247 typoutput 24 -1 4 12 0 -1 -1 t p f i t f f t 0)); DATA(insert ( 1247 typoutput 24 -1 4 12 0 -1 -1 t p f i t f f t 0));
DATA(insert ( 1247 typreceive 24 -1 4 13 0 -1 -1 t p f i t f f t 0)); DATA(insert ( 1247 typreceive 24 -1 4 13 0 -1 -1 t p f i t f f t 0));
DATA(insert ( 1247 typsend 24 -1 4 14 0 -1 -1 t p f i t f f t 0)); DATA(insert ( 1247 typsend 24 -1 4 14 0 -1 -1 t p f i t f f t 0));
DATA(insert ( 1247 typalign 18 -1 1 15 0 -1 -1 t p f c t f f t 0)); DATA(insert ( 1247 typanalyze 24 -1 4 15 0 -1 -1 t p f i t f f t 0));
DATA(insert ( 1247 typstorage 18 -1 1 16 0 -1 -1 t p f c t f f t 0)); DATA(insert ( 1247 typalign 18 -1 1 16 0 -1 -1 t p f c t f f t 0));
DATA(insert ( 1247 typnotnull 16 -1 1 17 0 -1 -1 t p f c t f f t 0)); DATA(insert ( 1247 typstorage 18 -1 1 17 0 -1 -1 t p f c t f f t 0));
DATA(insert ( 1247 typbasetype 26 -1 4 18 0 -1 -1 t p f i t f f t 0)); DATA(insert ( 1247 typnotnull 16 -1 1 18 0 -1 -1 t p f c t f f t 0));
DATA(insert ( 1247 typtypmod 23 -1 4 19 0 -1 -1 t p f i t f f t 0)); DATA(insert ( 1247 typbasetype 26 -1 4 19 0 -1 -1 t p f i t f f t 0));
DATA(insert ( 1247 typndims 23 -1 4 20 0 -1 -1 t p f i t f f t 0)); DATA(insert ( 1247 typtypmod 23 -1 4 20 0 -1 -1 t p f i t f f t 0));
DATA(insert ( 1247 typdefaultbin 25 -1 -1 21 0 -1 -1 f x f i f f f t 0)); DATA(insert ( 1247 typndims 23 -1 4 21 0 -1 -1 t p f i t f f t 0));
DATA(insert ( 1247 typdefault 25 -1 -1 22 0 -1 -1 f x f i f f f t 0)); DATA(insert ( 1247 typdefaultbin 25 -1 -1 22 0 -1 -1 f x f i f f f t 0));
DATA(insert ( 1247 typdefault 25 -1 -1 23 0 -1 -1 f x f i f f f t 0));
DATA(insert ( 1247 ctid 27 0 6 -1 0 -1 -1 f p f i t f f t 0)); DATA(insert ( 1247 ctid 27 0 6 -1 0 -1 -1 f p f i t f f t 0));
DATA(insert ( 1247 oid 26 0 4 -2 0 -1 -1 t p f i t f f t 0)); DATA(insert ( 1247 oid 26 0 4 -2 0 -1 -1 t p f i t f f t 0));
DATA(insert ( 1247 xmin 28 0 4 -3 0 -1 -1 t p f i t f f t 0)); DATA(insert ( 1247 xmin 28 0 4 -3 0 -1 -1 t p f i t f f t 0));
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2003, 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/catalog/pg_class.h,v 1.79 2004/01/06 23:55:19 tgl Exp $ * $PostgreSQL: pgsql/src/include/catalog/pg_class.h,v 1.80 2004/02/12 23:41:04 tgl Exp $
* *
* NOTES * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
...@@ -134,7 +134,7 @@ typedef FormData_pg_class *Form_pg_class; ...@@ -134,7 +134,7 @@ typedef FormData_pg_class *Form_pg_class;
* ---------------- * ----------------
*/ */
DATA(insert OID = 1247 ( pg_type PGNSP 71 PGUID 0 1247 0 0 0 0 f f r 22 0 0 0 0 0 t f f f _null_ )); DATA(insert OID = 1247 ( pg_type PGNSP 71 PGUID 0 1247 0 0 0 0 f f r 23 0 0 0 0 0 t f f f _null_ ));
DESCR(""); DESCR("");
DATA(insert OID = 1249 ( pg_attribute PGNSP 75 PGUID 0 1249 0 0 0 0 f f r 18 0 0 0 0 0 f f f f _null_ )); DATA(insert OID = 1249 ( pg_attribute PGNSP 75 PGUID 0 1249 0 0 0 0 f f r 18 0 0 0 0 0 f f f f _null_ ));
DESCR(""); DESCR("");
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2003, 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/catalog/pg_statistic.h,v 1.23 2003/11/29 22:40:58 pgsql Exp $ * $PostgreSQL: pgsql/src/include/catalog/pg_statistic.h,v 1.24 2004/02/12 23:41:04 tgl Exp $
* *
* NOTES * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
...@@ -164,11 +164,30 @@ typedef FormData_pg_statistic *Form_pg_statistic; ...@@ -164,11 +164,30 @@ typedef FormData_pg_statistic *Form_pg_statistic;
/* /*
* Currently, three statistical slot "kinds" are defined: most common values, * Currently, three statistical slot "kinds" are defined: most common values,
* histogram, and correlation. Additional "kinds" will probably appear in * histogram, and correlation. Additional "kinds" will probably appear in
* future to help cope with non-scalar datatypes. * future to help cope with non-scalar datatypes. Also, custom data types
* can define their own "kind" codes by mutual agreement between a custom
* typanalyze routine and the selectivity estimation functions of the type's
* operators.
* *
* Code reading the pg_statistic relation should not assume that a particular * Code reading the pg_statistic relation should not assume that a particular
* data "kind" will appear in any particular slot. Instead, search the * data "kind" will appear in any particular slot. Instead, search the
* stakind fields to see if the desired data is available. * stakind fields to see if the desired data is available. (The standard
* function get_attstatsslot() may be used for this.)
*/
/*
* The present allocation of "kind" codes is:
*
* 1-99: reserved for assignment by the core PostgreSQL project
* (values in this range will be documented in this file)
* 100-199: reserved for assignment by the PostGIS project
* (values to be documented in PostGIS documentation)
* 200-9999: reserved for future public assignments
*
* For private use you may choose a "kind" code at random in the range
* 10000-30000. However, for code that is to be widely disseminated it is
* better to obtain a publicly defined "kind" code by request from the
* PostgreSQL Global Development Group.
*/ */
/* /*
......
This diff is collapsed.
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2003, 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/commands/vacuum.h,v 1.48 2004/02/10 03:42:45 tgl Exp $ * $PostgreSQL: pgsql/src/include/commands/vacuum.h,v 1.49 2004/02/12 23:41:04 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -23,10 +23,86 @@ ...@@ -23,10 +23,86 @@
#include "rusagestub.h" #include "rusagestub.h"
#endif #endif
#include "access/htup.h"
#include "catalog/pg_attribute.h"
#include "catalog/pg_statistic.h"
#include "catalog/pg_type.h"
#include "nodes/parsenodes.h" #include "nodes/parsenodes.h"
#include "utils/rel.h" #include "utils/rel.h"
/*----------
* ANALYZE builds one of these structs for each attribute (column) that is
* to be analyzed. The struct and subsidiary data are in anl_context,
* so they live until the end of the ANALYZE operation.
*
* The type-specific typanalyze function is passed a pointer to this struct
* and must return TRUE to continue analysis, FALSE to skip analysis of this
* column. In the TRUE case it must set the compute_stats and minrows fields,
* and can optionally set extra_data to pass additional info to compute_stats.
*
* The compute_stats routine will be called after sample rows have been
* gathered. Aside from this struct, it is passed:
* attnum: attribute number within the supplied tuples
* tupDesc: tuple descriptor for the supplied tuples
* totalrows: estimated total number of rows in relation
* rows: an array of the sample tuples
* numrows: the number of sample tuples
* Note that the passed attnum and tupDesc could possibly be different from
* what one would expect by looking at the pg_attribute row. It is important
* to use these values for extracting attribute values from the given rows
* (and not for any other purpose).
*
* compute_stats should set stats_valid TRUE if it is able to compute
* any useful statistics. If it does, the remainder of the struct holds
* the information to be stored in a pg_statistic row for the column. Be
* careful to allocate any pointed-to data in anl_context, which will NOT
* be CurrentMemoryContext when compute_stats is called.
*----------
*/
typedef struct VacAttrStats
{
/*
* These fields are set up by the main ANALYZE code before invoking
* the type-specific typanalyze function.
*/
Form_pg_attribute attr; /* copy of pg_attribute row for column */
Form_pg_type attrtype; /* copy of pg_type row for column */
MemoryContext anl_context; /* where to save long-lived data */
/*
* These fields must be filled in by the typanalyze routine,
* unless it returns FALSE.
*/
void (*compute_stats) (struct VacAttrStats *stats, int attnum,
TupleDesc tupDesc, double totalrows,
HeapTuple *rows, int numrows);
int minrows; /* Minimum # of rows wanted for stats */
void *extra_data; /* for extra type-specific data */
/*
* These fields are to be filled in by the compute_stats routine.
* (They are initialized to zero when the struct is created.)
*/
bool stats_valid;
float4 stanullfrac; /* fraction of entries that are NULL */
int4 stawidth; /* average width of column values */
float4 stadistinct; /* # distinct values */
int2 stakind[STATISTIC_NUM_SLOTS];
Oid staop[STATISTIC_NUM_SLOTS];
int numnumbers[STATISTIC_NUM_SLOTS];
float4 *stanumbers[STATISTIC_NUM_SLOTS];
int numvalues[STATISTIC_NUM_SLOTS];
Datum *stavalues[STATISTIC_NUM_SLOTS];
/*
* These fields are private to the main ANALYZE code and should not
* be looked at by type-specific functions.
*/
int tupattnum; /* attribute number within tuples */
} VacAttrStats;
/* State structure for vac_init_rusage/vac_show_rusage */ /* State structure for vac_init_rusage/vac_show_rusage */
typedef struct VacRUsage typedef struct VacRUsage
{ {
......
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