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.
This commit is contained in:
parent
d27471fe0a
commit
69946411d3
@ -1,6 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
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 @@
|
|||||||
<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>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$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> (
|
|||||||
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> (
|
|||||||
<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> (
|
|||||||
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> (
|
|||||||
</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 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* 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,
|
|||||||
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 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* 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)
|
|||||||
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)
|
|||||||
InvalidOid,
|
InvalidOid,
|
||||||
InvalidOid,
|
InvalidOid,
|
||||||
InvalidOid,
|
InvalidOid,
|
||||||
|
InvalidOid,
|
||||||
NULL,
|
NULL,
|
||||||
false);
|
false);
|
||||||
|
|
||||||
@ -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,
|
|||||||
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,
|
|||||||
outputProcedure,
|
outputProcedure,
|
||||||
receiveProcedure,
|
receiveProcedure,
|
||||||
sendProcedure,
|
sendProcedure,
|
||||||
|
analyzeProcedure,
|
||||||
elementType,
|
elementType,
|
||||||
baseType,
|
baseType,
|
||||||
(defaultTypeBin ?
|
(defaultTypeBin ?
|
||||||
@ -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,
|
|||||||
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
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
/*-------------------------------------------------------------------------
|
/*-------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* analyze.c
|
* analyze.c
|
||||||
* the postgres statistics generator
|
* the Postgres statistics generator
|
||||||
*
|
*
|
||||||
* 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
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.67 2004/02/10 03:42:43 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.68 2004/02/12 23:41:02 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -23,8 +23,6 @@
|
|||||||
#include "catalog/indexing.h"
|
#include "catalog/indexing.h"
|
||||||
#include "catalog/namespace.h"
|
#include "catalog/namespace.h"
|
||||||
#include "catalog/pg_operator.h"
|
#include "catalog/pg_operator.h"
|
||||||
#include "catalog/pg_statistic.h"
|
|
||||||
#include "catalog/pg_type.h"
|
|
||||||
#include "commands/vacuum.h"
|
#include "commands/vacuum.h"
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
#include "parser/parse_oper.h"
|
#include "parser/parse_oper.h"
|
||||||
@ -38,91 +36,13 @@
|
|||||||
#include "utils/tuplesort.h"
|
#include "utils/tuplesort.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Analysis algorithms supported
|
|
||||||
*/
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
ALG_MINIMAL = 1, /* Compute only most-common-values */
|
|
||||||
ALG_SCALAR /* Compute MCV, histogram, sort
|
|
||||||
* correlation */
|
|
||||||
} AlgCode;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* To avoid consuming too much memory during analysis and/or too much space
|
|
||||||
* in the resulting pg_statistic rows, we ignore varlena datums that are wider
|
|
||||||
* than WIDTH_THRESHOLD (after detoasting!). This is legitimate for MCV
|
|
||||||
* and distinct-value calculations since a wide value is unlikely to be
|
|
||||||
* duplicated at all, much less be a most-common value. For the same reason,
|
|
||||||
* ignoring wide values will not affect our estimates of histogram bin
|
|
||||||
* boundaries very much.
|
|
||||||
*/
|
|
||||||
#define WIDTH_THRESHOLD 1024
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We build 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.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
/* These fields are set up by examine_attribute */
|
|
||||||
int attnum; /* attribute number */
|
|
||||||
AlgCode algcode; /* Which algorithm to use for this column */
|
|
||||||
int minrows; /* Minimum # of rows wanted for stats */
|
|
||||||
Form_pg_attribute attr; /* copy of pg_attribute row for column */
|
|
||||||
Form_pg_type attrtype; /* copy of pg_type row for column */
|
|
||||||
Oid eqopr; /* '=' operator for datatype, if any */
|
|
||||||
Oid eqfunc; /* and associated function */
|
|
||||||
Oid ltopr; /* '<' operator for datatype, if any */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* These fields are filled in by the actual statistics-gathering
|
|
||||||
* routine
|
|
||||||
*/
|
|
||||||
bool stats_valid;
|
|
||||||
float4 stanullfrac; /* fraction of entries that are NULL */
|
|
||||||
int4 stawidth; /* average width */
|
|
||||||
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];
|
|
||||||
} VacAttrStats;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
Datum value; /* a data value */
|
|
||||||
int tupno; /* position index for tuple it came from */
|
|
||||||
} ScalarItem;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
int count; /* # of duplicates */
|
|
||||||
int first; /* values[] index of first occurrence */
|
|
||||||
} ScalarMCVItem;
|
|
||||||
|
|
||||||
|
|
||||||
#define swapInt(a,b) do {int _tmp; _tmp=a; a=b; b=_tmp;} while(0)
|
|
||||||
#define swapDatum(a,b) do {Datum _tmp; _tmp=a; a=b; b=_tmp;} while(0)
|
|
||||||
|
|
||||||
|
|
||||||
/* Default statistics target (GUC parameter) */
|
/* Default statistics target (GUC parameter) */
|
||||||
int default_statistics_target = 10;
|
int default_statistics_target = 10;
|
||||||
|
|
||||||
|
|
||||||
static int elevel = -1;
|
static int elevel = -1;
|
||||||
|
|
||||||
static MemoryContext anl_context = NULL;
|
static MemoryContext anl_context = NULL;
|
||||||
|
|
||||||
/* context information for compare_scalars() */
|
|
||||||
static FmgrInfo *datumCmpFn;
|
|
||||||
static SortFunctionKind datumCmpFnKind;
|
|
||||||
static int *datumCmpTupnoLink;
|
|
||||||
|
|
||||||
|
|
||||||
static VacAttrStats *examine_attribute(Relation onerel, int attnum);
|
static VacAttrStats *examine_attribute(Relation onerel, int attnum);
|
||||||
static int acquire_sample_rows(Relation onerel, HeapTuple *rows,
|
static int acquire_sample_rows(Relation onerel, HeapTuple *rows,
|
||||||
@ -131,16 +51,10 @@ static double random_fract(void);
|
|||||||
static double init_selection_state(int n);
|
static double init_selection_state(int n);
|
||||||
static double select_next_random_record(double t, int n, double *stateptr);
|
static double select_next_random_record(double t, int n, double *stateptr);
|
||||||
static int compare_rows(const void *a, const void *b);
|
static int compare_rows(const void *a, const void *b);
|
||||||
static int compare_scalars(const void *a, const void *b);
|
|
||||||
static int compare_mcvs(const void *a, const void *b);
|
|
||||||
static void compute_minimal_stats(VacAttrStats *stats,
|
|
||||||
TupleDesc tupDesc, double totalrows,
|
|
||||||
HeapTuple *rows, int numrows);
|
|
||||||
static void compute_scalar_stats(VacAttrStats *stats,
|
|
||||||
TupleDesc tupDesc, double totalrows,
|
|
||||||
HeapTuple *rows, int numrows);
|
|
||||||
static void update_attstats(Oid relid, int natts, VacAttrStats **vacattrstats);
|
static void update_attstats(Oid relid, int natts, VacAttrStats **vacattrstats);
|
||||||
|
|
||||||
|
static bool std_typanalyze(VacAttrStats *stats);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* analyze_rel() -- analyze one relation
|
* analyze_rel() -- analyze one relation
|
||||||
@ -345,19 +259,12 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt)
|
|||||||
old_context = MemoryContextSwitchTo(col_context);
|
old_context = MemoryContextSwitchTo(col_context);
|
||||||
for (i = 0; i < attr_cnt; i++)
|
for (i = 0; i < attr_cnt; i++)
|
||||||
{
|
{
|
||||||
switch (vacattrstats[i]->algcode)
|
(*vacattrstats[i]->compute_stats) (vacattrstats[i],
|
||||||
{
|
vacattrstats[i]->tupattnum,
|
||||||
case ALG_MINIMAL:
|
onerel->rd_att,
|
||||||
compute_minimal_stats(vacattrstats[i],
|
totalrows,
|
||||||
onerel->rd_att, totalrows,
|
rows,
|
||||||
rows, numrows);
|
numrows);
|
||||||
break;
|
|
||||||
case ALG_SCALAR:
|
|
||||||
compute_scalar_stats(vacattrstats[i],
|
|
||||||
onerel->rd_att, totalrows,
|
|
||||||
rows, numrows);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
MemoryContextResetAndDeleteChildren(col_context);
|
MemoryContextResetAndDeleteChildren(col_context);
|
||||||
}
|
}
|
||||||
MemoryContextSwitchTo(old_context);
|
MemoryContextSwitchTo(old_context);
|
||||||
@ -390,14 +297,11 @@ static VacAttrStats *
|
|||||||
examine_attribute(Relation onerel, int attnum)
|
examine_attribute(Relation onerel, int attnum)
|
||||||
{
|
{
|
||||||
Form_pg_attribute attr = onerel->rd_att->attrs[attnum - 1];
|
Form_pg_attribute attr = onerel->rd_att->attrs[attnum - 1];
|
||||||
Operator func_operator;
|
|
||||||
HeapTuple typtuple;
|
HeapTuple typtuple;
|
||||||
Oid eqopr = InvalidOid;
|
|
||||||
Oid eqfunc = InvalidOid;
|
|
||||||
Oid ltopr = InvalidOid;
|
|
||||||
VacAttrStats *stats;
|
VacAttrStats *stats;
|
||||||
|
bool ok;
|
||||||
|
|
||||||
/* Don't analyze dropped columns */
|
/* Never analyze dropped columns */
|
||||||
if (attr->attisdropped)
|
if (attr->attisdropped)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -405,23 +309,10 @@ examine_attribute(Relation onerel, int attnum)
|
|||||||
if (attr->attstattarget == 0)
|
if (attr->attstattarget == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* If column has no "=" operator, we can't do much of anything */
|
|
||||||
func_operator = equality_oper(attr->atttypid, true);
|
|
||||||
if (func_operator != NULL)
|
|
||||||
{
|
|
||||||
eqopr = oprid(func_operator);
|
|
||||||
eqfunc = oprfuncid(func_operator);
|
|
||||||
ReleaseSysCache(func_operator);
|
|
||||||
}
|
|
||||||
if (!OidIsValid(eqfunc))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we have "=" then we're at least able to do the minimal
|
* Create the VacAttrStats struct.
|
||||||
* algorithm, so start filling in a VacAttrStats struct.
|
|
||||||
*/
|
*/
|
||||||
stats = (VacAttrStats *) palloc0(sizeof(VacAttrStats));
|
stats = (VacAttrStats *) palloc0(sizeof(VacAttrStats));
|
||||||
stats->attnum = attnum;
|
|
||||||
stats->attr = (Form_pg_attribute) palloc(ATTRIBUTE_TUPLE_SIZE);
|
stats->attr = (Form_pg_attribute) palloc(ATTRIBUTE_TUPLE_SIZE);
|
||||||
memcpy(stats->attr, attr, ATTRIBUTE_TUPLE_SIZE);
|
memcpy(stats->attr, attr, ATTRIBUTE_TUPLE_SIZE);
|
||||||
typtuple = SearchSysCache(TYPEOID,
|
typtuple = SearchSysCache(TYPEOID,
|
||||||
@ -432,57 +323,25 @@ examine_attribute(Relation onerel, int attnum)
|
|||||||
stats->attrtype = (Form_pg_type) palloc(sizeof(FormData_pg_type));
|
stats->attrtype = (Form_pg_type) palloc(sizeof(FormData_pg_type));
|
||||||
memcpy(stats->attrtype, GETSTRUCT(typtuple), sizeof(FormData_pg_type));
|
memcpy(stats->attrtype, GETSTRUCT(typtuple), sizeof(FormData_pg_type));
|
||||||
ReleaseSysCache(typtuple);
|
ReleaseSysCache(typtuple);
|
||||||
stats->eqopr = eqopr;
|
stats->anl_context = anl_context;
|
||||||
stats->eqfunc = eqfunc;
|
stats->tupattnum = attnum;
|
||||||
|
|
||||||
/* If the attstattarget column is negative, use the default value */
|
|
||||||
if (stats->attr->attstattarget < 0)
|
|
||||||
stats->attr->attstattarget = default_statistics_target;
|
|
||||||
|
|
||||||
/* Is there a "<" operator with suitable semantics? */
|
|
||||||
func_operator = ordering_oper(attr->atttypid, true);
|
|
||||||
if (func_operator != NULL)
|
|
||||||
{
|
|
||||||
ltopr = oprid(func_operator);
|
|
||||||
ReleaseSysCache(func_operator);
|
|
||||||
}
|
|
||||||
stats->ltopr = ltopr;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Determine the algorithm to use (this will get more complicated
|
* Call the type-specific typanalyze function. If none is specified,
|
||||||
* later)
|
* use std_typanalyze().
|
||||||
*/
|
*/
|
||||||
if (OidIsValid(ltopr))
|
if (OidIsValid(stats->attrtype->typanalyze))
|
||||||
{
|
ok = DatumGetBool(OidFunctionCall1(stats->attrtype->typanalyze,
|
||||||
/* Seems to be a scalar datatype */
|
PointerGetDatum(stats)));
|
||||||
stats->algcode = ALG_SCALAR;
|
|
||||||
/*--------------------
|
|
||||||
* The following choice of minrows is based on the paper
|
|
||||||
* "Random sampling for histogram construction: how much is enough?"
|
|
||||||
* by Surajit Chaudhuri, Rajeev Motwani and Vivek Narasayya, in
|
|
||||||
* Proceedings of ACM SIGMOD International Conference on Management
|
|
||||||
* of Data, 1998, Pages 436-447. Their Corollary 1 to Theorem 5
|
|
||||||
* says that for table size n, histogram size k, maximum relative
|
|
||||||
* error in bin size f, and error probability gamma, the minimum
|
|
||||||
* random sample size is
|
|
||||||
* r = 4 * k * ln(2*n/gamma) / f^2
|
|
||||||
* Taking f = 0.5, gamma = 0.01, n = 1 million rows, we obtain
|
|
||||||
* r = 305.82 * k
|
|
||||||
* Note that because of the log function, the dependence on n is
|
|
||||||
* quite weak; even at n = 1 billion, a 300*k sample gives <= 0.59
|
|
||||||
* bin size error with probability 0.99. So there's no real need to
|
|
||||||
* scale for n, which is a good thing because we don't necessarily
|
|
||||||
* know it at this point.
|
|
||||||
*--------------------
|
|
||||||
*/
|
|
||||||
stats->minrows = 300 * stats->attr->attstattarget;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
|
ok = std_typanalyze(stats);
|
||||||
|
|
||||||
|
if (!ok || stats->compute_stats == NULL || stats->minrows <= 0)
|
||||||
{
|
{
|
||||||
/* Can't do much but the minimal stuff */
|
pfree(stats->attrtype);
|
||||||
stats->algcode = ALG_MINIMAL;
|
pfree(stats->attr);
|
||||||
/* Might as well use the same minrows as above */
|
pfree(stats);
|
||||||
stats->minrows = 300 * stats->attr->attstattarget;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return stats;
|
return stats;
|
||||||
@ -851,6 +710,304 @@ compare_rows(const void *a, const void *b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* update_attstats() -- update attribute statistics for one relation
|
||||||
|
*
|
||||||
|
* Statistics are stored in several places: the pg_class row for the
|
||||||
|
* relation has stats about the whole relation, and there is a
|
||||||
|
* pg_statistic row for each (non-system) attribute that has ever
|
||||||
|
* been analyzed. The pg_class values are updated by VACUUM, not here.
|
||||||
|
*
|
||||||
|
* pg_statistic rows are just added or updated normally. This means
|
||||||
|
* that pg_statistic will probably contain some deleted rows at the
|
||||||
|
* completion of a vacuum cycle, unless it happens to get vacuumed last.
|
||||||
|
*
|
||||||
|
* To keep things simple, we punt for pg_statistic, and don't try
|
||||||
|
* to compute or store rows for pg_statistic itself in pg_statistic.
|
||||||
|
* This could possibly be made to work, but it's not worth the trouble.
|
||||||
|
* Note analyze_rel() has seen to it that we won't come here when
|
||||||
|
* vacuuming pg_statistic itself.
|
||||||
|
*
|
||||||
|
* Note: if two backends concurrently try to analyze the same relation,
|
||||||
|
* the second one is likely to fail here with a "tuple concurrently
|
||||||
|
* updated" error. This is slightly annoying, but no real harm is done.
|
||||||
|
* We could prevent the problem by using a stronger lock on the
|
||||||
|
* relation for ANALYZE (ie, ShareUpdateExclusiveLock instead
|
||||||
|
* of AccessShareLock); but that cure seems worse than the disease,
|
||||||
|
* especially now that ANALYZE doesn't start a new transaction
|
||||||
|
* for each relation. The lock could be held for a long time...
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
update_attstats(Oid relid, int natts, VacAttrStats **vacattrstats)
|
||||||
|
{
|
||||||
|
Relation sd;
|
||||||
|
int attno;
|
||||||
|
|
||||||
|
sd = heap_openr(StatisticRelationName, RowExclusiveLock);
|
||||||
|
|
||||||
|
for (attno = 0; attno < natts; attno++)
|
||||||
|
{
|
||||||
|
VacAttrStats *stats = vacattrstats[attno];
|
||||||
|
HeapTuple stup,
|
||||||
|
oldtup;
|
||||||
|
int i,
|
||||||
|
k,
|
||||||
|
n;
|
||||||
|
Datum values[Natts_pg_statistic];
|
||||||
|
char nulls[Natts_pg_statistic];
|
||||||
|
char replaces[Natts_pg_statistic];
|
||||||
|
|
||||||
|
/* Ignore attr if we weren't able to collect stats */
|
||||||
|
if (!stats->stats_valid)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Construct a new pg_statistic tuple
|
||||||
|
*/
|
||||||
|
for (i = 0; i < Natts_pg_statistic; ++i)
|
||||||
|
{
|
||||||
|
nulls[i] = ' ';
|
||||||
|
replaces[i] = 'r';
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
values[i++] = ObjectIdGetDatum(relid); /* starelid */
|
||||||
|
values[i++] = Int16GetDatum(stats->attr->attnum); /* staattnum */
|
||||||
|
values[i++] = Float4GetDatum(stats->stanullfrac); /* stanullfrac */
|
||||||
|
values[i++] = Int32GetDatum(stats->stawidth); /* stawidth */
|
||||||
|
values[i++] = Float4GetDatum(stats->stadistinct); /* stadistinct */
|
||||||
|
for (k = 0; k < STATISTIC_NUM_SLOTS; k++)
|
||||||
|
{
|
||||||
|
values[i++] = Int16GetDatum(stats->stakind[k]); /* stakindN */
|
||||||
|
}
|
||||||
|
for (k = 0; k < STATISTIC_NUM_SLOTS; k++)
|
||||||
|
{
|
||||||
|
values[i++] = ObjectIdGetDatum(stats->staop[k]); /* staopN */
|
||||||
|
}
|
||||||
|
for (k = 0; k < STATISTIC_NUM_SLOTS; k++)
|
||||||
|
{
|
||||||
|
int nnum = stats->numnumbers[k];
|
||||||
|
|
||||||
|
if (nnum > 0)
|
||||||
|
{
|
||||||
|
Datum *numdatums = (Datum *) palloc(nnum * sizeof(Datum));
|
||||||
|
ArrayType *arry;
|
||||||
|
|
||||||
|
for (n = 0; n < nnum; n++)
|
||||||
|
numdatums[n] = Float4GetDatum(stats->stanumbers[k][n]);
|
||||||
|
/* XXX knows more than it should about type float4: */
|
||||||
|
arry = construct_array(numdatums, nnum,
|
||||||
|
FLOAT4OID,
|
||||||
|
sizeof(float4), false, 'i');
|
||||||
|
values[i++] = PointerGetDatum(arry); /* stanumbersN */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nulls[i] = 'n';
|
||||||
|
values[i++] = (Datum) 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (k = 0; k < STATISTIC_NUM_SLOTS; k++)
|
||||||
|
{
|
||||||
|
if (stats->numvalues[k] > 0)
|
||||||
|
{
|
||||||
|
ArrayType *arry;
|
||||||
|
|
||||||
|
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
|
||||||
|
{
|
||||||
|
nulls[i] = 'n';
|
||||||
|
values[i++] = (Datum) 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Is there already a pg_statistic tuple for this attribute? */
|
||||||
|
oldtup = SearchSysCache(STATRELATT,
|
||||||
|
ObjectIdGetDatum(relid),
|
||||||
|
Int16GetDatum(stats->attr->attnum),
|
||||||
|
0, 0);
|
||||||
|
|
||||||
|
if (HeapTupleIsValid(oldtup))
|
||||||
|
{
|
||||||
|
/* Yes, replace it */
|
||||||
|
stup = heap_modifytuple(oldtup,
|
||||||
|
sd,
|
||||||
|
values,
|
||||||
|
nulls,
|
||||||
|
replaces);
|
||||||
|
ReleaseSysCache(oldtup);
|
||||||
|
simple_heap_update(sd, &stup->t_self, stup);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* No, insert new tuple */
|
||||||
|
stup = heap_formtuple(sd->rd_att, values, nulls);
|
||||||
|
simple_heap_insert(sd, stup);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* update indexes too */
|
||||||
|
CatalogUpdateIndexes(sd, stup);
|
||||||
|
|
||||||
|
heap_freetuple(stup);
|
||||||
|
}
|
||||||
|
|
||||||
|
heap_close(sd, RowExclusiveLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*==========================================================================
|
||||||
|
*
|
||||||
|
* Code below this point represents the "standard" type-specific statistics
|
||||||
|
* analysis algorithms. This code can be replaced on a per-data-type basis
|
||||||
|
* by setting a nonzero value in pg_type.typanalyze.
|
||||||
|
*
|
||||||
|
*==========================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* To avoid consuming too much memory during analysis and/or too much space
|
||||||
|
* in the resulting pg_statistic rows, we ignore varlena datums that are wider
|
||||||
|
* than WIDTH_THRESHOLD (after detoasting!). This is legitimate for MCV
|
||||||
|
* and distinct-value calculations since a wide value is unlikely to be
|
||||||
|
* duplicated at all, much less be a most-common value. For the same reason,
|
||||||
|
* ignoring wide values will not affect our estimates of histogram bin
|
||||||
|
* boundaries very much.
|
||||||
|
*/
|
||||||
|
#define WIDTH_THRESHOLD 1024
|
||||||
|
|
||||||
|
#define swapInt(a,b) do {int _tmp; _tmp=a; a=b; b=_tmp;} while(0)
|
||||||
|
#define swapDatum(a,b) do {Datum _tmp; _tmp=a; a=b; b=_tmp;} while(0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extra information used by the default analysis routines
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
Oid eqopr; /* '=' operator for datatype, if any */
|
||||||
|
Oid eqfunc; /* and associated function */
|
||||||
|
Oid ltopr; /* '<' operator for datatype, if any */
|
||||||
|
} StdAnalyzeData;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
Datum value; /* a data value */
|
||||||
|
int tupno; /* position index for tuple it came from */
|
||||||
|
} ScalarItem;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int count; /* # of duplicates */
|
||||||
|
int first; /* values[] index of first occurrence */
|
||||||
|
} ScalarMCVItem;
|
||||||
|
|
||||||
|
|
||||||
|
/* context information for compare_scalars() */
|
||||||
|
static FmgrInfo *datumCmpFn;
|
||||||
|
static SortFunctionKind datumCmpFnKind;
|
||||||
|
static int *datumCmpTupnoLink;
|
||||||
|
|
||||||
|
|
||||||
|
static void compute_minimal_stats(VacAttrStats *stats, int attnum,
|
||||||
|
TupleDesc tupDesc, double totalrows,
|
||||||
|
HeapTuple *rows, int numrows);
|
||||||
|
static void compute_scalar_stats(VacAttrStats *stats, int attnum,
|
||||||
|
TupleDesc tupDesc, double totalrows,
|
||||||
|
HeapTuple *rows, int numrows);
|
||||||
|
static int compare_scalars(const void *a, const void *b);
|
||||||
|
static int compare_mcvs(const void *a, const void *b);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* std_typanalyze -- the default type-specific typanalyze function
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
std_typanalyze(VacAttrStats *stats)
|
||||||
|
{
|
||||||
|
Form_pg_attribute attr = stats->attr;
|
||||||
|
Operator func_operator;
|
||||||
|
Oid eqopr = InvalidOid;
|
||||||
|
Oid eqfunc = InvalidOid;
|
||||||
|
Oid ltopr = InvalidOid;
|
||||||
|
StdAnalyzeData *mystats;
|
||||||
|
|
||||||
|
/* If the attstattarget column is negative, use the default value */
|
||||||
|
/* NB: it is okay to scribble on stats->attr since it's a copy */
|
||||||
|
if (attr->attstattarget < 0)
|
||||||
|
attr->attstattarget = default_statistics_target;
|
||||||
|
|
||||||
|
/* If column has no "=" operator, we can't do much of anything */
|
||||||
|
func_operator = equality_oper(attr->atttypid, true);
|
||||||
|
if (func_operator != NULL)
|
||||||
|
{
|
||||||
|
eqopr = oprid(func_operator);
|
||||||
|
eqfunc = oprfuncid(func_operator);
|
||||||
|
ReleaseSysCache(func_operator);
|
||||||
|
}
|
||||||
|
if (!OidIsValid(eqfunc))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* Is there a "<" operator with suitable semantics? */
|
||||||
|
func_operator = ordering_oper(attr->atttypid, true);
|
||||||
|
if (func_operator != NULL)
|
||||||
|
{
|
||||||
|
ltopr = oprid(func_operator);
|
||||||
|
ReleaseSysCache(func_operator);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Save the operator info for compute_stats routines */
|
||||||
|
mystats = (StdAnalyzeData *) palloc(sizeof(StdAnalyzeData));
|
||||||
|
mystats->eqopr = eqopr;
|
||||||
|
mystats->eqfunc = eqfunc;
|
||||||
|
mystats->ltopr = ltopr;
|
||||||
|
stats->extra_data = mystats;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Determine which standard statistics algorithm to use
|
||||||
|
*/
|
||||||
|
if (OidIsValid(ltopr))
|
||||||
|
{
|
||||||
|
/* Seems to be a scalar datatype */
|
||||||
|
stats->compute_stats = compute_scalar_stats;
|
||||||
|
/*--------------------
|
||||||
|
* The following choice of minrows is based on the paper
|
||||||
|
* "Random sampling for histogram construction: how much is enough?"
|
||||||
|
* by Surajit Chaudhuri, Rajeev Motwani and Vivek Narasayya, in
|
||||||
|
* Proceedings of ACM SIGMOD International Conference on Management
|
||||||
|
* of Data, 1998, Pages 436-447. Their Corollary 1 to Theorem 5
|
||||||
|
* says that for table size n, histogram size k, maximum relative
|
||||||
|
* error in bin size f, and error probability gamma, the minimum
|
||||||
|
* random sample size is
|
||||||
|
* r = 4 * k * ln(2*n/gamma) / f^2
|
||||||
|
* Taking f = 0.5, gamma = 0.01, n = 1 million rows, we obtain
|
||||||
|
* r = 305.82 * k
|
||||||
|
* Note that because of the log function, the dependence on n is
|
||||||
|
* quite weak; even at n = 1 billion, a 300*k sample gives <= 0.59
|
||||||
|
* bin size error with probability 0.99. So there's no real need to
|
||||||
|
* scale for n, which is a good thing because we don't necessarily
|
||||||
|
* know it at this point.
|
||||||
|
*--------------------
|
||||||
|
*/
|
||||||
|
stats->minrows = 300 * attr->attstattarget;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Can't do much but the minimal stuff */
|
||||||
|
stats->compute_stats = compute_minimal_stats;
|
||||||
|
/* Might as well use the same minrows as above */
|
||||||
|
stats->minrows = 300 * attr->attstattarget;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* compute_minimal_stats() -- compute minimal column statistics
|
* compute_minimal_stats() -- compute minimal column statistics
|
||||||
*
|
*
|
||||||
@ -867,7 +1024,7 @@ compare_rows(const void *a, const void *b)
|
|||||||
* depend mainly on the length of the list we are willing to keep.
|
* depend mainly on the length of the list we are willing to keep.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
compute_minimal_stats(VacAttrStats *stats,
|
compute_minimal_stats(VacAttrStats *stats, int attnum,
|
||||||
TupleDesc tupDesc, double totalrows,
|
TupleDesc tupDesc, double totalrows,
|
||||||
HeapTuple *rows, int numrows)
|
HeapTuple *rows, int numrows)
|
||||||
{
|
{
|
||||||
@ -890,6 +1047,7 @@ compute_minimal_stats(VacAttrStats *stats,
|
|||||||
int track_cnt,
|
int track_cnt,
|
||||||
track_max;
|
track_max;
|
||||||
int num_mcv = stats->attr->attstattarget;
|
int num_mcv = stats->attr->attstattarget;
|
||||||
|
StdAnalyzeData *mystats = (StdAnalyzeData *) stats->extra_data;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We track up to 2*n values for an n-element MCV list; but at least
|
* We track up to 2*n values for an n-element MCV list; but at least
|
||||||
@ -901,7 +1059,7 @@ compute_minimal_stats(VacAttrStats *stats,
|
|||||||
track = (TrackItem *) palloc(track_max * sizeof(TrackItem));
|
track = (TrackItem *) palloc(track_max * sizeof(TrackItem));
|
||||||
track_cnt = 0;
|
track_cnt = 0;
|
||||||
|
|
||||||
fmgr_info(stats->eqfunc, &f_cmpeq);
|
fmgr_info(mystats->eqfunc, &f_cmpeq);
|
||||||
|
|
||||||
for (i = 0; i < numrows; i++)
|
for (i = 0; i < numrows; i++)
|
||||||
{
|
{
|
||||||
@ -914,7 +1072,7 @@ compute_minimal_stats(VacAttrStats *stats,
|
|||||||
|
|
||||||
vacuum_delay_point();
|
vacuum_delay_point();
|
||||||
|
|
||||||
value = heap_getattr(tuple, stats->attnum, tupDesc, &isnull);
|
value = heap_getattr(tuple, attnum, tupDesc, &isnull);
|
||||||
|
|
||||||
/* Check for null/nonnull */
|
/* Check for null/nonnull */
|
||||||
if (isnull)
|
if (isnull)
|
||||||
@ -1137,7 +1295,7 @@ compute_minimal_stats(VacAttrStats *stats,
|
|||||||
float4 *mcv_freqs;
|
float4 *mcv_freqs;
|
||||||
|
|
||||||
/* Must copy the target values into anl_context */
|
/* Must copy the target values into anl_context */
|
||||||
old_context = MemoryContextSwitchTo(anl_context);
|
old_context = MemoryContextSwitchTo(stats->anl_context);
|
||||||
mcv_values = (Datum *) palloc(num_mcv * sizeof(Datum));
|
mcv_values = (Datum *) palloc(num_mcv * sizeof(Datum));
|
||||||
mcv_freqs = (float4 *) palloc(num_mcv * sizeof(float4));
|
mcv_freqs = (float4 *) palloc(num_mcv * sizeof(float4));
|
||||||
for (i = 0; i < num_mcv; i++)
|
for (i = 0; i < num_mcv; i++)
|
||||||
@ -1150,7 +1308,7 @@ compute_minimal_stats(VacAttrStats *stats,
|
|||||||
MemoryContextSwitchTo(old_context);
|
MemoryContextSwitchTo(old_context);
|
||||||
|
|
||||||
stats->stakind[0] = STATISTIC_KIND_MCV;
|
stats->stakind[0] = STATISTIC_KIND_MCV;
|
||||||
stats->staop[0] = stats->eqopr;
|
stats->staop[0] = mystats->eqopr;
|
||||||
stats->stanumbers[0] = mcv_freqs;
|
stats->stanumbers[0] = mcv_freqs;
|
||||||
stats->numnumbers[0] = num_mcv;
|
stats->numnumbers[0] = num_mcv;
|
||||||
stats->stavalues[0] = mcv_values;
|
stats->stavalues[0] = mcv_values;
|
||||||
@ -1175,7 +1333,7 @@ compute_minimal_stats(VacAttrStats *stats,
|
|||||||
* data values into order.
|
* data values into order.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
compute_scalar_stats(VacAttrStats *stats,
|
compute_scalar_stats(VacAttrStats *stats, int attnum,
|
||||||
TupleDesc tupDesc, double totalrows,
|
TupleDesc tupDesc, double totalrows,
|
||||||
HeapTuple *rows, int numrows)
|
HeapTuple *rows, int numrows)
|
||||||
{
|
{
|
||||||
@ -1199,12 +1357,13 @@ compute_scalar_stats(VacAttrStats *stats,
|
|||||||
int track_cnt = 0;
|
int track_cnt = 0;
|
||||||
int num_mcv = stats->attr->attstattarget;
|
int num_mcv = stats->attr->attstattarget;
|
||||||
int num_bins = stats->attr->attstattarget;
|
int num_bins = stats->attr->attstattarget;
|
||||||
|
StdAnalyzeData *mystats = (StdAnalyzeData *) stats->extra_data;
|
||||||
|
|
||||||
values = (ScalarItem *) palloc(numrows * sizeof(ScalarItem));
|
values = (ScalarItem *) palloc(numrows * sizeof(ScalarItem));
|
||||||
tupnoLink = (int *) palloc(numrows * sizeof(int));
|
tupnoLink = (int *) palloc(numrows * sizeof(int));
|
||||||
track = (ScalarMCVItem *) palloc(num_mcv * sizeof(ScalarMCVItem));
|
track = (ScalarMCVItem *) palloc(num_mcv * sizeof(ScalarMCVItem));
|
||||||
|
|
||||||
SelectSortFunction(stats->ltopr, &cmpFn, &cmpFnKind);
|
SelectSortFunction(mystats->ltopr, &cmpFn, &cmpFnKind);
|
||||||
fmgr_info(cmpFn, &f_cmpfn);
|
fmgr_info(cmpFn, &f_cmpfn);
|
||||||
|
|
||||||
/* Initial scan to find sortable values */
|
/* Initial scan to find sortable values */
|
||||||
@ -1216,7 +1375,7 @@ compute_scalar_stats(VacAttrStats *stats,
|
|||||||
|
|
||||||
vacuum_delay_point();
|
vacuum_delay_point();
|
||||||
|
|
||||||
value = heap_getattr(tuple, stats->attnum, tupDesc, &isnull);
|
value = heap_getattr(tuple, attnum, tupDesc, &isnull);
|
||||||
|
|
||||||
/* Check for null/nonnull */
|
/* Check for null/nonnull */
|
||||||
if (isnull)
|
if (isnull)
|
||||||
@ -1469,7 +1628,7 @@ compute_scalar_stats(VacAttrStats *stats,
|
|||||||
float4 *mcv_freqs;
|
float4 *mcv_freqs;
|
||||||
|
|
||||||
/* Must copy the target values into anl_context */
|
/* Must copy the target values into anl_context */
|
||||||
old_context = MemoryContextSwitchTo(anl_context);
|
old_context = MemoryContextSwitchTo(stats->anl_context);
|
||||||
mcv_values = (Datum *) palloc(num_mcv * sizeof(Datum));
|
mcv_values = (Datum *) palloc(num_mcv * sizeof(Datum));
|
||||||
mcv_freqs = (float4 *) palloc(num_mcv * sizeof(float4));
|
mcv_freqs = (float4 *) palloc(num_mcv * sizeof(float4));
|
||||||
for (i = 0; i < num_mcv; i++)
|
for (i = 0; i < num_mcv; i++)
|
||||||
@ -1482,7 +1641,7 @@ compute_scalar_stats(VacAttrStats *stats,
|
|||||||
MemoryContextSwitchTo(old_context);
|
MemoryContextSwitchTo(old_context);
|
||||||
|
|
||||||
stats->stakind[slot_idx] = STATISTIC_KIND_MCV;
|
stats->stakind[slot_idx] = STATISTIC_KIND_MCV;
|
||||||
stats->staop[slot_idx] = stats->eqopr;
|
stats->staop[slot_idx] = mystats->eqopr;
|
||||||
stats->stanumbers[slot_idx] = mcv_freqs;
|
stats->stanumbers[slot_idx] = mcv_freqs;
|
||||||
stats->numnumbers[slot_idx] = num_mcv;
|
stats->numnumbers[slot_idx] = num_mcv;
|
||||||
stats->stavalues[slot_idx] = mcv_values;
|
stats->stavalues[slot_idx] = mcv_values;
|
||||||
@ -1555,7 +1714,7 @@ compute_scalar_stats(VacAttrStats *stats,
|
|||||||
Assert(nvals >= num_hist);
|
Assert(nvals >= num_hist);
|
||||||
|
|
||||||
/* Must copy the target values into anl_context */
|
/* Must copy the target values into anl_context */
|
||||||
old_context = MemoryContextSwitchTo(anl_context);
|
old_context = MemoryContextSwitchTo(stats->anl_context);
|
||||||
hist_values = (Datum *) palloc(num_hist * sizeof(Datum));
|
hist_values = (Datum *) palloc(num_hist * sizeof(Datum));
|
||||||
for (i = 0; i < num_hist; i++)
|
for (i = 0; i < num_hist; i++)
|
||||||
{
|
{
|
||||||
@ -1569,7 +1728,7 @@ compute_scalar_stats(VacAttrStats *stats,
|
|||||||
MemoryContextSwitchTo(old_context);
|
MemoryContextSwitchTo(old_context);
|
||||||
|
|
||||||
stats->stakind[slot_idx] = STATISTIC_KIND_HISTOGRAM;
|
stats->stakind[slot_idx] = STATISTIC_KIND_HISTOGRAM;
|
||||||
stats->staop[slot_idx] = stats->ltopr;
|
stats->staop[slot_idx] = mystats->ltopr;
|
||||||
stats->stavalues[slot_idx] = hist_values;
|
stats->stavalues[slot_idx] = hist_values;
|
||||||
stats->numvalues[slot_idx] = num_hist;
|
stats->numvalues[slot_idx] = num_hist;
|
||||||
slot_idx++;
|
slot_idx++;
|
||||||
@ -1584,7 +1743,7 @@ compute_scalar_stats(VacAttrStats *stats,
|
|||||||
corr_x2sum;
|
corr_x2sum;
|
||||||
|
|
||||||
/* Must copy the target values into anl_context */
|
/* Must copy the target values into anl_context */
|
||||||
old_context = MemoryContextSwitchTo(anl_context);
|
old_context = MemoryContextSwitchTo(stats->anl_context);
|
||||||
corrs = (float4 *) palloc(sizeof(float4));
|
corrs = (float4 *) palloc(sizeof(float4));
|
||||||
MemoryContextSwitchTo(old_context);
|
MemoryContextSwitchTo(old_context);
|
||||||
|
|
||||||
@ -1607,7 +1766,7 @@ compute_scalar_stats(VacAttrStats *stats,
|
|||||||
(values_cnt * corr_x2sum - corr_xsum * corr_xsum);
|
(values_cnt * corr_x2sum - corr_xsum * corr_xsum);
|
||||||
|
|
||||||
stats->stakind[slot_idx] = STATISTIC_KIND_CORRELATION;
|
stats->stakind[slot_idx] = STATISTIC_KIND_CORRELATION;
|
||||||
stats->staop[slot_idx] = stats->ltopr;
|
stats->staop[slot_idx] = mystats->ltopr;
|
||||||
stats->stanumbers[slot_idx] = corrs;
|
stats->stanumbers[slot_idx] = corrs;
|
||||||
stats->numnumbers[slot_idx] = 1;
|
stats->numnumbers[slot_idx] = 1;
|
||||||
slot_idx++;
|
slot_idx++;
|
||||||
@ -1665,155 +1824,3 @@ compare_mcvs(const void *a, const void *b)
|
|||||||
|
|
||||||
return da - db;
|
return da - db;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* update_attstats() -- update attribute statistics for one relation
|
|
||||||
*
|
|
||||||
* Statistics are stored in several places: the pg_class row for the
|
|
||||||
* relation has stats about the whole relation, and there is a
|
|
||||||
* pg_statistic row for each (non-system) attribute that has ever
|
|
||||||
* been analyzed. The pg_class values are updated by VACUUM, not here.
|
|
||||||
*
|
|
||||||
* pg_statistic rows are just added or updated normally. This means
|
|
||||||
* that pg_statistic will probably contain some deleted rows at the
|
|
||||||
* completion of a vacuum cycle, unless it happens to get vacuumed last.
|
|
||||||
*
|
|
||||||
* To keep things simple, we punt for pg_statistic, and don't try
|
|
||||||
* to compute or store rows for pg_statistic itself in pg_statistic.
|
|
||||||
* This could possibly be made to work, but it's not worth the trouble.
|
|
||||||
* Note analyze_rel() has seen to it that we won't come here when
|
|
||||||
* vacuuming pg_statistic itself.
|
|
||||||
*
|
|
||||||
* Note: if two backends concurrently try to analyze the same relation,
|
|
||||||
* the second one is likely to fail here with a "tuple concurrently
|
|
||||||
* updated" error. This is slightly annoying, but no real harm is done.
|
|
||||||
* We could prevent the problem by using a stronger lock on the
|
|
||||||
* relation for ANALYZE (ie, ShareUpdateExclusiveLock instead
|
|
||||||
* of AccessShareLock); but that cure seems worse than the disease,
|
|
||||||
* especially now that ANALYZE doesn't start a new transaction
|
|
||||||
* for each relation. The lock could be held for a long time...
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
update_attstats(Oid relid, int natts, VacAttrStats **vacattrstats)
|
|
||||||
{
|
|
||||||
Relation sd;
|
|
||||||
int attno;
|
|
||||||
|
|
||||||
sd = heap_openr(StatisticRelationName, RowExclusiveLock);
|
|
||||||
|
|
||||||
for (attno = 0; attno < natts; attno++)
|
|
||||||
{
|
|
||||||
VacAttrStats *stats = vacattrstats[attno];
|
|
||||||
HeapTuple stup,
|
|
||||||
oldtup;
|
|
||||||
int i,
|
|
||||||
k,
|
|
||||||
n;
|
|
||||||
Datum values[Natts_pg_statistic];
|
|
||||||
char nulls[Natts_pg_statistic];
|
|
||||||
char replaces[Natts_pg_statistic];
|
|
||||||
|
|
||||||
/* Ignore attr if we weren't able to collect stats */
|
|
||||||
if (!stats->stats_valid)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Construct a new pg_statistic tuple
|
|
||||||
*/
|
|
||||||
for (i = 0; i < Natts_pg_statistic; ++i)
|
|
||||||
{
|
|
||||||
nulls[i] = ' ';
|
|
||||||
replaces[i] = 'r';
|
|
||||||
}
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
values[i++] = ObjectIdGetDatum(relid); /* starelid */
|
|
||||||
values[i++] = Int16GetDatum(stats->attnum); /* staattnum */
|
|
||||||
values[i++] = Float4GetDatum(stats->stanullfrac); /* stanullfrac */
|
|
||||||
values[i++] = Int32GetDatum(stats->stawidth); /* stawidth */
|
|
||||||
values[i++] = Float4GetDatum(stats->stadistinct); /* stadistinct */
|
|
||||||
for (k = 0; k < STATISTIC_NUM_SLOTS; k++)
|
|
||||||
{
|
|
||||||
values[i++] = Int16GetDatum(stats->stakind[k]); /* stakindN */
|
|
||||||
}
|
|
||||||
for (k = 0; k < STATISTIC_NUM_SLOTS; k++)
|
|
||||||
{
|
|
||||||
values[i++] = ObjectIdGetDatum(stats->staop[k]); /* staopN */
|
|
||||||
}
|
|
||||||
for (k = 0; k < STATISTIC_NUM_SLOTS; k++)
|
|
||||||
{
|
|
||||||
int nnum = stats->numnumbers[k];
|
|
||||||
|
|
||||||
if (nnum > 0)
|
|
||||||
{
|
|
||||||
Datum *numdatums = (Datum *) palloc(nnum * sizeof(Datum));
|
|
||||||
ArrayType *arry;
|
|
||||||
|
|
||||||
for (n = 0; n < nnum; n++)
|
|
||||||
numdatums[n] = Float4GetDatum(stats->stanumbers[k][n]);
|
|
||||||
/* XXX knows more than it should about type float4: */
|
|
||||||
arry = construct_array(numdatums, nnum,
|
|
||||||
FLOAT4OID,
|
|
||||||
sizeof(float4), false, 'i');
|
|
||||||
values[i++] = PointerGetDatum(arry); /* stanumbersN */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
nulls[i] = 'n';
|
|
||||||
values[i++] = (Datum) 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (k = 0; k < STATISTIC_NUM_SLOTS; k++)
|
|
||||||
{
|
|
||||||
if (stats->numvalues[k] > 0)
|
|
||||||
{
|
|
||||||
ArrayType *arry;
|
|
||||||
|
|
||||||
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
|
|
||||||
{
|
|
||||||
nulls[i] = 'n';
|
|
||||||
values[i++] = (Datum) 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Is there already a pg_statistic tuple for this attribute? */
|
|
||||||
oldtup = SearchSysCache(STATRELATT,
|
|
||||||
ObjectIdGetDatum(relid),
|
|
||||||
Int16GetDatum(stats->attnum),
|
|
||||||
0, 0);
|
|
||||||
|
|
||||||
if (HeapTupleIsValid(oldtup))
|
|
||||||
{
|
|
||||||
/* Yes, replace it */
|
|
||||||
stup = heap_modifytuple(oldtup,
|
|
||||||
sd,
|
|
||||||
values,
|
|
||||||
nulls,
|
|
||||||
replaces);
|
|
||||||
ReleaseSysCache(oldtup);
|
|
||||||
simple_heap_update(sd, &stup->t_self, stup);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* No, insert new tuple */
|
|
||||||
stup = heap_formtuple(sd->rd_att, values, nulls);
|
|
||||||
simple_heap_insert(sd, stup);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* update indexes too */
|
|
||||||
CatalogUpdateIndexes(sd, stup);
|
|
||||||
|
|
||||||
heap_freetuple(stup);
|
|
||||||
}
|
|
||||||
|
|
||||||
heap_close(sd, RowExclusiveLock);
|
|
||||||
}
|
|
||||||
|
@ -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);
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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 @@
|
|||||||
* 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)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* 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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
/* 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 @@
|
|||||||
* 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 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* yyyymmddN */
|
/* yyyymmddN */
|
||||||
#define CATALOG_VERSION_NO 200402021
|
#define CATALOG_VERSION_NO 200402121
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -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;
|
|||||||
{ 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));
|
|||||||
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 @@
|
|||||||
* 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;
|
|||||||
* ----------------
|
* ----------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
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 @@
|
|||||||
* 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;
|
|||||||
/*
|
/*
|
||||||
* 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.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -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_type.h,v 1.148 2003/11/29 22:40:58 pgsql Exp $
|
* $PostgreSQL: pgsql/src/include/catalog/pg_type.h,v 1.149 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
|
||||||
@ -104,6 +104,11 @@ CATALOG(pg_type) BOOTSTRAP
|
|||||||
regproc typreceive; /* binary format (optional) */
|
regproc typreceive; /* binary format (optional) */
|
||||||
regproc typsend;
|
regproc typsend;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Custom ANALYZE procedure for the datatype (0 selects the default).
|
||||||
|
*/
|
||||||
|
regproc typanalyze;
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
* typalign is the alignment required when storing a value of this
|
* typalign is the alignment required when storing a value of this
|
||||||
* type. It applies to storage on disk as well as most
|
* type. It applies to storage on disk as well as most
|
||||||
@ -200,7 +205,7 @@ typedef FormData_pg_type *Form_pg_type;
|
|||||||
* compiler constants for pg_type
|
* compiler constants for pg_type
|
||||||
* ----------------
|
* ----------------
|
||||||
*/
|
*/
|
||||||
#define Natts_pg_type 22
|
#define Natts_pg_type 23
|
||||||
#define Anum_pg_type_typname 1
|
#define Anum_pg_type_typname 1
|
||||||
#define Anum_pg_type_typnamespace 2
|
#define Anum_pg_type_typnamespace 2
|
||||||
#define Anum_pg_type_typowner 3
|
#define Anum_pg_type_typowner 3
|
||||||
@ -215,14 +220,15 @@ typedef FormData_pg_type *Form_pg_type;
|
|||||||
#define Anum_pg_type_typoutput 12
|
#define Anum_pg_type_typoutput 12
|
||||||
#define Anum_pg_type_typreceive 13
|
#define Anum_pg_type_typreceive 13
|
||||||
#define Anum_pg_type_typsend 14
|
#define Anum_pg_type_typsend 14
|
||||||
#define Anum_pg_type_typalign 15
|
#define Anum_pg_type_typanalyze 15
|
||||||
#define Anum_pg_type_typstorage 16
|
#define Anum_pg_type_typalign 16
|
||||||
#define Anum_pg_type_typnotnull 17
|
#define Anum_pg_type_typstorage 17
|
||||||
#define Anum_pg_type_typbasetype 18
|
#define Anum_pg_type_typnotnull 18
|
||||||
#define Anum_pg_type_typtypmod 19
|
#define Anum_pg_type_typbasetype 19
|
||||||
#define Anum_pg_type_typndims 20
|
#define Anum_pg_type_typtypmod 20
|
||||||
#define Anum_pg_type_typdefaultbin 21
|
#define Anum_pg_type_typndims 21
|
||||||
#define Anum_pg_type_typdefault 22
|
#define Anum_pg_type_typdefaultbin 22
|
||||||
|
#define Anum_pg_type_typdefault 23
|
||||||
|
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
@ -238,82 +244,82 @@ typedef FormData_pg_type *Form_pg_type;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* OIDS 1 - 99 */
|
/* OIDS 1 - 99 */
|
||||||
DATA(insert OID = 16 ( bool PGNSP PGUID 1 t b t \054 0 0 boolin boolout boolrecv boolsend c p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 16 ( bool PGNSP PGUID 1 t b t \054 0 0 boolin boolout boolrecv boolsend - c p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("boolean, 'true'/'false'");
|
DESCR("boolean, 'true'/'false'");
|
||||||
#define BOOLOID 16
|
#define BOOLOID 16
|
||||||
|
|
||||||
DATA(insert OID = 17 ( bytea PGNSP PGUID -1 f b t \054 0 0 byteain byteaout bytearecv byteasend i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 17 ( bytea PGNSP PGUID -1 f b t \054 0 0 byteain byteaout bytearecv byteasend - i x f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("variable-length string, binary values escaped");
|
DESCR("variable-length string, binary values escaped");
|
||||||
#define BYTEAOID 17
|
#define BYTEAOID 17
|
||||||
|
|
||||||
DATA(insert OID = 18 ( char PGNSP PGUID 1 t b t \054 0 0 charin charout charrecv charsend c p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 18 ( char PGNSP PGUID 1 t b t \054 0 0 charin charout charrecv charsend - c p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("single character");
|
DESCR("single character");
|
||||||
#define CHAROID 18
|
#define CHAROID 18
|
||||||
|
|
||||||
DATA(insert OID = 19 ( name PGNSP PGUID NAMEDATALEN f b t \054 0 18 namein nameout namerecv namesend i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 19 ( name PGNSP PGUID NAMEDATALEN f b t \054 0 18 namein nameout namerecv namesend - i p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("63-character type for storing system identifiers");
|
DESCR("63-character type for storing system identifiers");
|
||||||
#define NAMEOID 19
|
#define NAMEOID 19
|
||||||
|
|
||||||
DATA(insert OID = 20 ( int8 PGNSP PGUID 8 f b t \054 0 0 int8in int8out int8recv int8send d p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 20 ( int8 PGNSP PGUID 8 f b t \054 0 0 int8in int8out int8recv int8send - d p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("~18 digit integer, 8-byte storage");
|
DESCR("~18 digit integer, 8-byte storage");
|
||||||
#define INT8OID 20
|
#define INT8OID 20
|
||||||
|
|
||||||
DATA(insert OID = 21 ( int2 PGNSP PGUID 2 t b t \054 0 0 int2in int2out int2recv int2send s p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 21 ( int2 PGNSP PGUID 2 t b t \054 0 0 int2in int2out int2recv int2send - s p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("-32 thousand to 32 thousand, 2-byte storage");
|
DESCR("-32 thousand to 32 thousand, 2-byte storage");
|
||||||
#define INT2OID 21
|
#define INT2OID 21
|
||||||
|
|
||||||
DATA(insert OID = 22 ( int2vector PGNSP PGUID INDEX_MAX_KEYS*2 f b t \054 0 21 int2vectorin int2vectorout int2vectorrecv int2vectorsend i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 22 ( int2vector PGNSP PGUID INDEX_MAX_KEYS*2 f b t \054 0 21 int2vectorin int2vectorout int2vectorrecv int2vectorsend - i p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("array of INDEX_MAX_KEYS int2 integers, used in system tables");
|
DESCR("array of INDEX_MAX_KEYS int2 integers, used in system tables");
|
||||||
#define INT2VECTOROID 22
|
#define INT2VECTOROID 22
|
||||||
|
|
||||||
DATA(insert OID = 23 ( int4 PGNSP PGUID 4 t b t \054 0 0 int4in int4out int4recv int4send i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 23 ( int4 PGNSP PGUID 4 t b t \054 0 0 int4in int4out int4recv int4send - i p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("-2 billion to 2 billion integer, 4-byte storage");
|
DESCR("-2 billion to 2 billion integer, 4-byte storage");
|
||||||
#define INT4OID 23
|
#define INT4OID 23
|
||||||
|
|
||||||
DATA(insert OID = 24 ( regproc PGNSP PGUID 4 t b t \054 0 0 regprocin regprocout regprocrecv regprocsend i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 24 ( regproc PGNSP PGUID 4 t b t \054 0 0 regprocin regprocout regprocrecv regprocsend - i p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("registered procedure");
|
DESCR("registered procedure");
|
||||||
#define REGPROCOID 24
|
#define REGPROCOID 24
|
||||||
|
|
||||||
DATA(insert OID = 25 ( text PGNSP PGUID -1 f b t \054 0 0 textin textout textrecv textsend i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 25 ( text PGNSP PGUID -1 f b t \054 0 0 textin textout textrecv textsend - i x f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("variable-length string, no limit specified");
|
DESCR("variable-length string, no limit specified");
|
||||||
#define TEXTOID 25
|
#define TEXTOID 25
|
||||||
|
|
||||||
DATA(insert OID = 26 ( oid PGNSP PGUID 4 t b t \054 0 0 oidin oidout oidrecv oidsend i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 26 ( oid PGNSP PGUID 4 t b t \054 0 0 oidin oidout oidrecv oidsend - i p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("object identifier(oid), maximum 4 billion");
|
DESCR("object identifier(oid), maximum 4 billion");
|
||||||
#define OIDOID 26
|
#define OIDOID 26
|
||||||
|
|
||||||
DATA(insert OID = 27 ( tid PGNSP PGUID 6 f b t \054 0 0 tidin tidout tidrecv tidsend i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 27 ( tid PGNSP PGUID 6 f b t \054 0 0 tidin tidout tidrecv tidsend - i p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("(Block, offset), physical location of tuple");
|
DESCR("(Block, offset), physical location of tuple");
|
||||||
#define TIDOID 27
|
#define TIDOID 27
|
||||||
|
|
||||||
DATA(insert OID = 28 ( xid PGNSP PGUID 4 t b t \054 0 0 xidin xidout xidrecv xidsend i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 28 ( xid PGNSP PGUID 4 t b t \054 0 0 xidin xidout xidrecv xidsend - i p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("transaction id");
|
DESCR("transaction id");
|
||||||
#define XIDOID 28
|
#define XIDOID 28
|
||||||
|
|
||||||
DATA(insert OID = 29 ( cid PGNSP PGUID 4 t b t \054 0 0 cidin cidout cidrecv cidsend i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 29 ( cid PGNSP PGUID 4 t b t \054 0 0 cidin cidout cidrecv cidsend - i p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("command identifier type, sequence in transaction id");
|
DESCR("command identifier type, sequence in transaction id");
|
||||||
#define CIDOID 29
|
#define CIDOID 29
|
||||||
|
|
||||||
DATA(insert OID = 30 ( oidvector PGNSP PGUID INDEX_MAX_KEYS*4 f b t \054 0 26 oidvectorin oidvectorout oidvectorrecv oidvectorsend i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 30 ( oidvector PGNSP PGUID INDEX_MAX_KEYS*4 f b t \054 0 26 oidvectorin oidvectorout oidvectorrecv oidvectorsend - i p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("array of INDEX_MAX_KEYS oids, used in system tables");
|
DESCR("array of INDEX_MAX_KEYS oids, used in system tables");
|
||||||
#define OIDVECTOROID 30
|
#define OIDVECTOROID 30
|
||||||
|
|
||||||
DATA(insert OID = 32 ( SET PGNSP PGUID -1 f b t \054 0 0 unknownin unknownout - - i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 32 ( SET PGNSP PGUID -1 f b t \054 0 0 unknownin unknownout - - - i p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("set of tuples");
|
DESCR("set of tuples");
|
||||||
|
|
||||||
DATA(insert OID = 71 ( pg_type PGNSP PGUID 4 t c t \054 1247 0 record_in record_out record_recv record_send i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 71 ( pg_type PGNSP PGUID 4 t c t \054 1247 0 record_in record_out record_recv record_send - i p f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 75 ( pg_attribute PGNSP PGUID 4 t c t \054 1249 0 record_in record_out record_recv record_send i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 75 ( pg_attribute PGNSP PGUID 4 t c t \054 1249 0 record_in record_out record_recv record_send - i p f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 81 ( pg_proc PGNSP PGUID 4 t c t \054 1255 0 record_in record_out record_recv record_send i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 81 ( pg_proc PGNSP PGUID 4 t c t \054 1255 0 record_in record_out record_recv record_send - i p f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 83 ( pg_class PGNSP PGUID 4 t c t \054 1259 0 record_in record_out record_recv record_send i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 83 ( pg_class PGNSP PGUID 4 t c t \054 1259 0 record_in record_out record_recv record_send - i p f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 86 ( pg_shadow PGNSP PGUID 4 t c t \054 1260 0 record_in record_out record_recv record_send i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 86 ( pg_shadow PGNSP PGUID 4 t c t \054 1260 0 record_in record_out record_recv record_send - i p f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 87 ( pg_group PGNSP PGUID 4 t c t \054 1261 0 record_in record_out record_recv record_send i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 87 ( pg_group PGNSP PGUID 4 t c t \054 1261 0 record_in record_out record_recv record_send - i p f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 88 ( pg_database PGNSP PGUID 4 t c t \054 1262 0 record_in record_out record_recv record_send i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 88 ( pg_database PGNSP PGUID 4 t c t \054 1262 0 record_in record_out record_recv record_send - i p f 0 -1 0 _null_ _null_ ));
|
||||||
|
|
||||||
/* OIDS 100 - 199 */
|
/* OIDS 100 - 199 */
|
||||||
|
|
||||||
/* OIDS 200 - 299 */
|
/* OIDS 200 - 299 */
|
||||||
|
|
||||||
DATA(insert OID = 210 ( smgr PGNSP PGUID 2 t b t \054 0 0 smgrin smgrout - - s p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 210 ( smgr PGNSP PGUID 2 t b t \054 0 0 smgrin smgrout - - - s p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("storage manager");
|
DESCR("storage manager");
|
||||||
|
|
||||||
/* OIDS 300 - 399 */
|
/* OIDS 300 - 399 */
|
||||||
@ -323,192 +329,192 @@ DESCR("storage manager");
|
|||||||
/* OIDS 500 - 599 */
|
/* OIDS 500 - 599 */
|
||||||
|
|
||||||
/* OIDS 600 - 699 */
|
/* OIDS 600 - 699 */
|
||||||
DATA(insert OID = 600 ( point PGNSP PGUID 16 f b t \054 0 701 point_in point_out point_recv point_send d p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 600 ( point PGNSP PGUID 16 f b t \054 0 701 point_in point_out point_recv point_send - d p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("geometric point '(x, y)'");
|
DESCR("geometric point '(x, y)'");
|
||||||
#define POINTOID 600
|
#define POINTOID 600
|
||||||
DATA(insert OID = 601 ( lseg PGNSP PGUID 32 f b t \054 0 600 lseg_in lseg_out lseg_recv lseg_send d p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 601 ( lseg PGNSP PGUID 32 f b t \054 0 600 lseg_in lseg_out lseg_recv lseg_send - d p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("geometric line segment '(pt1,pt2)'");
|
DESCR("geometric line segment '(pt1,pt2)'");
|
||||||
#define LSEGOID 601
|
#define LSEGOID 601
|
||||||
DATA(insert OID = 602 ( path PGNSP PGUID -1 f b t \054 0 0 path_in path_out path_recv path_send d x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 602 ( path PGNSP PGUID -1 f b t \054 0 0 path_in path_out path_recv path_send - d x f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("geometric path '(pt1,...)'");
|
DESCR("geometric path '(pt1,...)'");
|
||||||
#define PATHOID 602
|
#define PATHOID 602
|
||||||
DATA(insert OID = 603 ( box PGNSP PGUID 32 f b t \073 0 600 box_in box_out box_recv box_send d p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 603 ( box PGNSP PGUID 32 f b t \073 0 600 box_in box_out box_recv box_send - d p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("geometric box '(lower left,upper right)'");
|
DESCR("geometric box '(lower left,upper right)'");
|
||||||
#define BOXOID 603
|
#define BOXOID 603
|
||||||
DATA(insert OID = 604 ( polygon PGNSP PGUID -1 f b t \054 0 0 poly_in poly_out poly_recv poly_send d x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 604 ( polygon PGNSP PGUID -1 f b t \054 0 0 poly_in poly_out poly_recv poly_send - d x f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("geometric polygon '(pt1,...)'");
|
DESCR("geometric polygon '(pt1,...)'");
|
||||||
#define POLYGONOID 604
|
#define POLYGONOID 604
|
||||||
|
|
||||||
DATA(insert OID = 628 ( line PGNSP PGUID 32 f b t \054 0 701 line_in line_out line_recv line_send d p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 628 ( line PGNSP PGUID 32 f b t \054 0 701 line_in line_out line_recv line_send - d p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("geometric line (not implemented)'");
|
DESCR("geometric line (not implemented)'");
|
||||||
#define LINEOID 628
|
#define LINEOID 628
|
||||||
DATA(insert OID = 629 ( _line PGNSP PGUID -1 f b t \054 0 628 array_in array_out array_recv array_send d x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 629 ( _line PGNSP PGUID -1 f b t \054 0 628 array_in array_out array_recv array_send - d x f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("");
|
DESCR("");
|
||||||
|
|
||||||
/* OIDS 700 - 799 */
|
/* OIDS 700 - 799 */
|
||||||
|
|
||||||
DATA(insert OID = 700 ( float4 PGNSP PGUID 4 f b t \054 0 0 float4in float4out float4recv float4send i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 700 ( float4 PGNSP PGUID 4 f b t \054 0 0 float4in float4out float4recv float4send - i p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("single-precision floating point number, 4-byte storage");
|
DESCR("single-precision floating point number, 4-byte storage");
|
||||||
#define FLOAT4OID 700
|
#define FLOAT4OID 700
|
||||||
DATA(insert OID = 701 ( float8 PGNSP PGUID 8 f b t \054 0 0 float8in float8out float8recv float8send d p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 701 ( float8 PGNSP PGUID 8 f b t \054 0 0 float8in float8out float8recv float8send - d p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("double-precision floating point number, 8-byte storage");
|
DESCR("double-precision floating point number, 8-byte storage");
|
||||||
#define FLOAT8OID 701
|
#define FLOAT8OID 701
|
||||||
DATA(insert OID = 702 ( abstime PGNSP PGUID 4 t b t \054 0 0 abstimein abstimeout abstimerecv abstimesend i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 702 ( abstime PGNSP PGUID 4 t b t \054 0 0 abstimein abstimeout abstimerecv abstimesend - i p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("absolute, limited-range date and time (Unix system time)");
|
DESCR("absolute, limited-range date and time (Unix system time)");
|
||||||
#define ABSTIMEOID 702
|
#define ABSTIMEOID 702
|
||||||
DATA(insert OID = 703 ( reltime PGNSP PGUID 4 t b t \054 0 0 reltimein reltimeout reltimerecv reltimesend i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 703 ( reltime PGNSP PGUID 4 t b t \054 0 0 reltimein reltimeout reltimerecv reltimesend - i p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("relative, limited-range time interval (Unix delta time)");
|
DESCR("relative, limited-range time interval (Unix delta time)");
|
||||||
#define RELTIMEOID 703
|
#define RELTIMEOID 703
|
||||||
DATA(insert OID = 704 ( tinterval PGNSP PGUID 12 f b t \054 0 0 tintervalin tintervalout tintervalrecv tintervalsend i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 704 ( tinterval PGNSP PGUID 12 f b t \054 0 0 tintervalin tintervalout tintervalrecv tintervalsend - i p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("(abstime,abstime), time interval");
|
DESCR("(abstime,abstime), time interval");
|
||||||
#define TINTERVALOID 704
|
#define TINTERVALOID 704
|
||||||
DATA(insert OID = 705 ( unknown PGNSP PGUID -1 f b t \054 0 0 unknownin unknownout unknownrecv unknownsend i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 705 ( unknown PGNSP PGUID -1 f b t \054 0 0 unknownin unknownout unknownrecv unknownsend - i p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("");
|
DESCR("");
|
||||||
#define UNKNOWNOID 705
|
#define UNKNOWNOID 705
|
||||||
|
|
||||||
DATA(insert OID = 718 ( circle PGNSP PGUID 24 f b t \054 0 0 circle_in circle_out circle_recv circle_send d p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 718 ( circle PGNSP PGUID 24 f b t \054 0 0 circle_in circle_out circle_recv circle_send - d p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("geometric circle '(center,radius)'");
|
DESCR("geometric circle '(center,radius)'");
|
||||||
#define CIRCLEOID 718
|
#define CIRCLEOID 718
|
||||||
DATA(insert OID = 719 ( _circle PGNSP PGUID -1 f b t \054 0 718 array_in array_out array_recv array_send d x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 719 ( _circle PGNSP PGUID -1 f b t \054 0 718 array_in array_out array_recv array_send - d x f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 790 ( money PGNSP PGUID 4 f b t \054 0 0 cash_in cash_out cash_recv cash_send i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 790 ( money PGNSP PGUID 4 f b t \054 0 0 cash_in cash_out cash_recv cash_send - i p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("monetary amounts, $d,ddd.cc");
|
DESCR("monetary amounts, $d,ddd.cc");
|
||||||
#define CASHOID 790
|
#define CASHOID 790
|
||||||
DATA(insert OID = 791 ( _money PGNSP PGUID -1 f b t \054 0 790 array_in array_out array_recv array_send i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 791 ( _money PGNSP PGUID -1 f b t \054 0 790 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
|
||||||
|
|
||||||
/* OIDS 800 - 899 */
|
/* OIDS 800 - 899 */
|
||||||
DATA(insert OID = 829 ( macaddr PGNSP PGUID 6 f b t \054 0 0 macaddr_in macaddr_out macaddr_recv macaddr_send i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 829 ( macaddr PGNSP PGUID 6 f b t \054 0 0 macaddr_in macaddr_out macaddr_recv macaddr_send - i p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("XX:XX:XX:XX:XX:XX, MAC address");
|
DESCR("XX:XX:XX:XX:XX:XX, MAC address");
|
||||||
#define MACADDROID 829
|
#define MACADDROID 829
|
||||||
DATA(insert OID = 869 ( inet PGNSP PGUID -1 f b t \054 0 0 inet_in inet_out inet_recv inet_send i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 869 ( inet PGNSP PGUID -1 f b t \054 0 0 inet_in inet_out inet_recv inet_send - i p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("IP address/netmask, host address, netmask optional");
|
DESCR("IP address/netmask, host address, netmask optional");
|
||||||
#define INETOID 869
|
#define INETOID 869
|
||||||
DATA(insert OID = 650 ( cidr PGNSP PGUID -1 f b t \054 0 0 cidr_in cidr_out cidr_recv cidr_send i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 650 ( cidr PGNSP PGUID -1 f b t \054 0 0 cidr_in cidr_out cidr_recv cidr_send - i p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("network IP address/netmask, network address");
|
DESCR("network IP address/netmask, network address");
|
||||||
#define CIDROID 650
|
#define CIDROID 650
|
||||||
|
|
||||||
/* OIDS 900 - 999 */
|
/* OIDS 900 - 999 */
|
||||||
|
|
||||||
/* OIDS 1000 - 1099 */
|
/* OIDS 1000 - 1099 */
|
||||||
DATA(insert OID = 1000 ( _bool PGNSP PGUID -1 f b t \054 0 16 array_in array_out array_recv array_send i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1000 ( _bool PGNSP PGUID -1 f b t \054 0 16 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 1001 ( _bytea PGNSP PGUID -1 f b t \054 0 17 array_in array_out array_recv array_send i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1001 ( _bytea PGNSP PGUID -1 f b t \054 0 17 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 1002 ( _char PGNSP PGUID -1 f b t \054 0 18 array_in array_out array_recv array_send i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1002 ( _char PGNSP PGUID -1 f b t \054 0 18 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 1003 ( _name PGNSP PGUID -1 f b t \054 0 19 array_in array_out array_recv array_send i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1003 ( _name PGNSP PGUID -1 f b t \054 0 19 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 1005 ( _int2 PGNSP PGUID -1 f b t \054 0 21 array_in array_out array_recv array_send i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1005 ( _int2 PGNSP PGUID -1 f b t \054 0 21 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 1006 ( _int2vector PGNSP PGUID -1 f b t \054 0 22 array_in array_out array_recv array_send i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1006 ( _int2vector PGNSP PGUID -1 f b t \054 0 22 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 1007 ( _int4 PGNSP PGUID -1 f b t \054 0 23 array_in array_out array_recv array_send i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1007 ( _int4 PGNSP PGUID -1 f b t \054 0 23 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 1008 ( _regproc PGNSP PGUID -1 f b t \054 0 24 array_in array_out array_recv array_send i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1008 ( _regproc PGNSP PGUID -1 f b t \054 0 24 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 1009 ( _text PGNSP PGUID -1 f b t \054 0 25 array_in array_out array_recv array_send i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1009 ( _text PGNSP PGUID -1 f b t \054 0 25 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 1028 ( _oid PGNSP PGUID -1 f b t \054 0 26 array_in array_out array_recv array_send i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1028 ( _oid PGNSP PGUID -1 f b t \054 0 26 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 1010 ( _tid PGNSP PGUID -1 f b t \054 0 27 array_in array_out array_recv array_send i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1010 ( _tid PGNSP PGUID -1 f b t \054 0 27 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 1011 ( _xid PGNSP PGUID -1 f b t \054 0 28 array_in array_out array_recv array_send i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1011 ( _xid PGNSP PGUID -1 f b t \054 0 28 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 1012 ( _cid PGNSP PGUID -1 f b t \054 0 29 array_in array_out array_recv array_send i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1012 ( _cid PGNSP PGUID -1 f b t \054 0 29 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 1013 ( _oidvector PGNSP PGUID -1 f b t \054 0 30 array_in array_out array_recv array_send i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1013 ( _oidvector PGNSP PGUID -1 f b t \054 0 30 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 1014 ( _bpchar PGNSP PGUID -1 f b t \054 0 1042 array_in array_out array_recv array_send i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1014 ( _bpchar PGNSP PGUID -1 f b t \054 0 1042 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 1015 ( _varchar PGNSP PGUID -1 f b t \054 0 1043 array_in array_out array_recv array_send i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1015 ( _varchar PGNSP PGUID -1 f b t \054 0 1043 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 1016 ( _int8 PGNSP PGUID -1 f b t \054 0 20 array_in array_out array_recv array_send d x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1016 ( _int8 PGNSP PGUID -1 f b t \054 0 20 array_in array_out array_recv array_send - d x f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 1017 ( _point PGNSP PGUID -1 f b t \054 0 600 array_in array_out array_recv array_send d x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1017 ( _point PGNSP PGUID -1 f b t \054 0 600 array_in array_out array_recv array_send - d x f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 1018 ( _lseg PGNSP PGUID -1 f b t \054 0 601 array_in array_out array_recv array_send d x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1018 ( _lseg PGNSP PGUID -1 f b t \054 0 601 array_in array_out array_recv array_send - d x f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 1019 ( _path PGNSP PGUID -1 f b t \054 0 602 array_in array_out array_recv array_send d x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1019 ( _path PGNSP PGUID -1 f b t \054 0 602 array_in array_out array_recv array_send - d x f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 1020 ( _box PGNSP PGUID -1 f b t \073 0 603 array_in array_out array_recv array_send d x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1020 ( _box PGNSP PGUID -1 f b t \073 0 603 array_in array_out array_recv array_send - d x f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 1021 ( _float4 PGNSP PGUID -1 f b t \054 0 700 array_in array_out array_recv array_send i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1021 ( _float4 PGNSP PGUID -1 f b t \054 0 700 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 1022 ( _float8 PGNSP PGUID -1 f b t \054 0 701 array_in array_out array_recv array_send d x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1022 ( _float8 PGNSP PGUID -1 f b t \054 0 701 array_in array_out array_recv array_send - d x f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 1023 ( _abstime PGNSP PGUID -1 f b t \054 0 702 array_in array_out array_recv array_send i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1023 ( _abstime PGNSP PGUID -1 f b t \054 0 702 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 1024 ( _reltime PGNSP PGUID -1 f b t \054 0 703 array_in array_out array_recv array_send i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1024 ( _reltime PGNSP PGUID -1 f b t \054 0 703 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 1025 ( _tinterval PGNSP PGUID -1 f b t \054 0 704 array_in array_out array_recv array_send i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1025 ( _tinterval PGNSP PGUID -1 f b t \054 0 704 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 1027 ( _polygon PGNSP PGUID -1 f b t \054 0 604 array_in array_out array_recv array_send d x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1027 ( _polygon PGNSP PGUID -1 f b t \054 0 604 array_in array_out array_recv array_send - d x f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 1033 ( aclitem PGNSP PGUID 12 f b t \054 0 0 aclitemin aclitemout - - i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1033 ( aclitem PGNSP PGUID 12 f b t \054 0 0 aclitemin aclitemout - - - i p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("access control list");
|
DESCR("access control list");
|
||||||
#define ACLITEMOID 1033
|
#define ACLITEMOID 1033
|
||||||
DATA(insert OID = 1034 ( _aclitem PGNSP PGUID -1 f b t \054 0 1033 array_in array_out array_recv array_send i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1034 ( _aclitem PGNSP PGUID -1 f b t \054 0 1033 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 1040 ( _macaddr PGNSP PGUID -1 f b t \054 0 829 array_in array_out array_recv array_send i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1040 ( _macaddr PGNSP PGUID -1 f b t \054 0 829 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 1041 ( _inet PGNSP PGUID -1 f b t \054 0 869 array_in array_out array_recv array_send i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1041 ( _inet PGNSP PGUID -1 f b t \054 0 869 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 651 ( _cidr PGNSP PGUID -1 f b t \054 0 650 array_in array_out array_recv array_send i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 651 ( _cidr PGNSP PGUID -1 f b t \054 0 650 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 1042 ( bpchar PGNSP PGUID -1 f b t \054 0 0 bpcharin bpcharout bpcharrecv bpcharsend i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1042 ( bpchar PGNSP PGUID -1 f b t \054 0 0 bpcharin bpcharout bpcharrecv bpcharsend - i x f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("char(length), blank-padded string, fixed storage length");
|
DESCR("char(length), blank-padded string, fixed storage length");
|
||||||
#define BPCHAROID 1042
|
#define BPCHAROID 1042
|
||||||
DATA(insert OID = 1043 ( varchar PGNSP PGUID -1 f b t \054 0 0 varcharin varcharout varcharrecv varcharsend i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1043 ( varchar PGNSP PGUID -1 f b t \054 0 0 varcharin varcharout varcharrecv varcharsend - i x f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("varchar(length), non-blank-padded string, variable storage length");
|
DESCR("varchar(length), non-blank-padded string, variable storage length");
|
||||||
#define VARCHAROID 1043
|
#define VARCHAROID 1043
|
||||||
|
|
||||||
DATA(insert OID = 1082 ( date PGNSP PGUID 4 t b t \054 0 0 date_in date_out date_recv date_send i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1082 ( date PGNSP PGUID 4 t b t \054 0 0 date_in date_out date_recv date_send - i p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("ANSI SQL date");
|
DESCR("ANSI SQL date");
|
||||||
#define DATEOID 1082
|
#define DATEOID 1082
|
||||||
DATA(insert OID = 1083 ( time PGNSP PGUID 8 f b t \054 0 0 time_in time_out time_recv time_send d p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1083 ( time PGNSP PGUID 8 f b t \054 0 0 time_in time_out time_recv time_send - d p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("hh:mm:ss, ANSI SQL time");
|
DESCR("hh:mm:ss, ANSI SQL time");
|
||||||
#define TIMEOID 1083
|
#define TIMEOID 1083
|
||||||
|
|
||||||
/* OIDS 1100 - 1199 */
|
/* OIDS 1100 - 1199 */
|
||||||
DATA(insert OID = 1114 ( timestamp PGNSP PGUID 8 f b t \054 0 0 timestamp_in timestamp_out timestamp_recv timestamp_send d p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1114 ( timestamp PGNSP PGUID 8 f b t \054 0 0 timestamp_in timestamp_out timestamp_recv timestamp_send - d p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("date and time");
|
DESCR("date and time");
|
||||||
#define TIMESTAMPOID 1114
|
#define TIMESTAMPOID 1114
|
||||||
DATA(insert OID = 1115 ( _timestamp PGNSP PGUID -1 f b t \054 0 1114 array_in array_out array_recv array_send d x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1115 ( _timestamp PGNSP PGUID -1 f b t \054 0 1114 array_in array_out array_recv array_send - d x f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 1182 ( _date PGNSP PGUID -1 f b t \054 0 1082 array_in array_out array_recv array_send i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1182 ( _date PGNSP PGUID -1 f b t \054 0 1082 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 1183 ( _time PGNSP PGUID -1 f b t \054 0 1083 array_in array_out array_recv array_send d x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1183 ( _time PGNSP PGUID -1 f b t \054 0 1083 array_in array_out array_recv array_send - d x f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 1184 ( timestamptz PGNSP PGUID 8 f b t \054 0 0 timestamptz_in timestamptz_out timestamptz_recv timestamptz_send d p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1184 ( timestamptz PGNSP PGUID 8 f b t \054 0 0 timestamptz_in timestamptz_out timestamptz_recv timestamptz_send - d p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("date and time with time zone");
|
DESCR("date and time with time zone");
|
||||||
#define TIMESTAMPTZOID 1184
|
#define TIMESTAMPTZOID 1184
|
||||||
DATA(insert OID = 1185 ( _timestamptz PGNSP PGUID -1 f b t \054 0 1184 array_in array_out array_recv array_send d x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1185 ( _timestamptz PGNSP PGUID -1 f b t \054 0 1184 array_in array_out array_recv array_send - d x f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 1186 ( interval PGNSP PGUID 12 f b t \054 0 0 interval_in interval_out interval_recv interval_send d p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1186 ( interval PGNSP PGUID 12 f b t \054 0 0 interval_in interval_out interval_recv interval_send - d p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("@ <number> <units>, time interval");
|
DESCR("@ <number> <units>, time interval");
|
||||||
#define INTERVALOID 1186
|
#define INTERVALOID 1186
|
||||||
DATA(insert OID = 1187 ( _interval PGNSP PGUID -1 f b t \054 0 1186 array_in array_out array_recv array_send d x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1187 ( _interval PGNSP PGUID -1 f b t \054 0 1186 array_in array_out array_recv array_send - d x f 0 -1 0 _null_ _null_ ));
|
||||||
|
|
||||||
/* OIDS 1200 - 1299 */
|
/* OIDS 1200 - 1299 */
|
||||||
DATA(insert OID = 1231 ( _numeric PGNSP PGUID -1 f b t \054 0 1700 array_in array_out array_recv array_send i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1231 ( _numeric PGNSP PGUID -1 f b t \054 0 1700 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 1266 ( timetz PGNSP PGUID 12 f b t \054 0 0 timetz_in timetz_out timetz_recv timetz_send d p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1266 ( timetz PGNSP PGUID 12 f b t \054 0 0 timetz_in timetz_out timetz_recv timetz_send - d p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("hh:mm:ss, ANSI SQL time");
|
DESCR("hh:mm:ss, ANSI SQL time");
|
||||||
#define TIMETZOID 1266
|
#define TIMETZOID 1266
|
||||||
DATA(insert OID = 1270 ( _timetz PGNSP PGUID -1 f b t \054 0 1266 array_in array_out array_recv array_send d x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1270 ( _timetz PGNSP PGUID -1 f b t \054 0 1266 array_in array_out array_recv array_send - d x f 0 -1 0 _null_ _null_ ));
|
||||||
|
|
||||||
/* OIDS 1500 - 1599 */
|
/* OIDS 1500 - 1599 */
|
||||||
DATA(insert OID = 1560 ( bit PGNSP PGUID -1 f b t \054 0 0 bit_in bit_out bit_recv bit_send i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1560 ( bit PGNSP PGUID -1 f b t \054 0 0 bit_in bit_out bit_recv bit_send - i x f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("fixed-length bit string");
|
DESCR("fixed-length bit string");
|
||||||
#define BITOID 1560
|
#define BITOID 1560
|
||||||
DATA(insert OID = 1561 ( _bit PGNSP PGUID -1 f b t \054 0 1560 array_in array_out array_recv array_send i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1561 ( _bit PGNSP PGUID -1 f b t \054 0 1560 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 1562 ( varbit PGNSP PGUID -1 f b t \054 0 0 varbit_in varbit_out varbit_recv varbit_send i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1562 ( varbit PGNSP PGUID -1 f b t \054 0 0 varbit_in varbit_out varbit_recv varbit_send - i x f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("variable-length bit string");
|
DESCR("variable-length bit string");
|
||||||
#define VARBITOID 1562
|
#define VARBITOID 1562
|
||||||
DATA(insert OID = 1563 ( _varbit PGNSP PGUID -1 f b t \054 0 1562 array_in array_out array_recv array_send i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1563 ( _varbit PGNSP PGUID -1 f b t \054 0 1562 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
|
||||||
|
|
||||||
/* OIDS 1600 - 1699 */
|
/* OIDS 1600 - 1699 */
|
||||||
|
|
||||||
/* OIDS 1700 - 1799 */
|
/* OIDS 1700 - 1799 */
|
||||||
DATA(insert OID = 1700 ( numeric PGNSP PGUID -1 f b t \054 0 0 numeric_in numeric_out numeric_recv numeric_send i m f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1700 ( numeric PGNSP PGUID -1 f b t \054 0 0 numeric_in numeric_out numeric_recv numeric_send - i m f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("numeric(precision, decimal), arbitrary precision number");
|
DESCR("numeric(precision, decimal), arbitrary precision number");
|
||||||
#define NUMERICOID 1700
|
#define NUMERICOID 1700
|
||||||
|
|
||||||
DATA(insert OID = 1790 ( refcursor PGNSP PGUID -1 f b t \054 0 0 textin textout textrecv textsend i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 1790 ( refcursor PGNSP PGUID -1 f b t \054 0 0 textin textout textrecv textsend - i x f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("reference cursor (portal name)");
|
DESCR("reference cursor (portal name)");
|
||||||
#define REFCURSOROID 1790
|
#define REFCURSOROID 1790
|
||||||
|
|
||||||
/* OIDS 2200 - 2299 */
|
/* OIDS 2200 - 2299 */
|
||||||
DATA(insert OID = 2201 ( _refcursor PGNSP PGUID -1 f b t \054 0 1790 array_in array_out array_recv array_send i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 2201 ( _refcursor PGNSP PGUID -1 f b t \054 0 1790 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
|
||||||
|
|
||||||
DATA(insert OID = 2202 ( regprocedure PGNSP PGUID 4 t b t \054 0 0 regprocedurein regprocedureout regprocedurerecv regproceduresend i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 2202 ( regprocedure PGNSP PGUID 4 t b t \054 0 0 regprocedurein regprocedureout regprocedurerecv regproceduresend - i p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("registered procedure (with args)");
|
DESCR("registered procedure (with args)");
|
||||||
#define REGPROCEDUREOID 2202
|
#define REGPROCEDUREOID 2202
|
||||||
|
|
||||||
DATA(insert OID = 2203 ( regoper PGNSP PGUID 4 t b t \054 0 0 regoperin regoperout regoperrecv regopersend i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 2203 ( regoper PGNSP PGUID 4 t b t \054 0 0 regoperin regoperout regoperrecv regopersend - i p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("registered operator");
|
DESCR("registered operator");
|
||||||
#define REGOPEROID 2203
|
#define REGOPEROID 2203
|
||||||
|
|
||||||
DATA(insert OID = 2204 ( regoperator PGNSP PGUID 4 t b t \054 0 0 regoperatorin regoperatorout regoperatorrecv regoperatorsend i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 2204 ( regoperator PGNSP PGUID 4 t b t \054 0 0 regoperatorin regoperatorout regoperatorrecv regoperatorsend - i p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("registered operator (with args)");
|
DESCR("registered operator (with args)");
|
||||||
#define REGOPERATOROID 2204
|
#define REGOPERATOROID 2204
|
||||||
|
|
||||||
DATA(insert OID = 2205 ( regclass PGNSP PGUID 4 t b t \054 0 0 regclassin regclassout regclassrecv regclasssend i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 2205 ( regclass PGNSP PGUID 4 t b t \054 0 0 regclassin regclassout regclassrecv regclasssend - i p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("registered class");
|
DESCR("registered class");
|
||||||
#define REGCLASSOID 2205
|
#define REGCLASSOID 2205
|
||||||
|
|
||||||
DATA(insert OID = 2206 ( regtype PGNSP PGUID 4 t b t \054 0 0 regtypein regtypeout regtyperecv regtypesend i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 2206 ( regtype PGNSP PGUID 4 t b t \054 0 0 regtypein regtypeout regtyperecv regtypesend - i p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("registered type");
|
DESCR("registered type");
|
||||||
#define REGTYPEOID 2206
|
#define REGTYPEOID 2206
|
||||||
|
|
||||||
DATA(insert OID = 2207 ( _regprocedure PGNSP PGUID -1 f b t \054 0 2202 array_in array_out array_recv array_send i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 2207 ( _regprocedure PGNSP PGUID -1 f b t \054 0 2202 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 2208 ( _regoper PGNSP PGUID -1 f b t \054 0 2203 array_in array_out array_recv array_send i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 2208 ( _regoper PGNSP PGUID -1 f b t \054 0 2203 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 2209 ( _regoperator PGNSP PGUID -1 f b t \054 0 2204 array_in array_out array_recv array_send i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 2209 ( _regoperator PGNSP PGUID -1 f b t \054 0 2204 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 2210 ( _regclass PGNSP PGUID -1 f b t \054 0 2205 array_in array_out array_recv array_send i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 2210 ( _regclass PGNSP PGUID -1 f b t \054 0 2205 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
|
||||||
DATA(insert OID = 2211 ( _regtype PGNSP PGUID -1 f b t \054 0 2206 array_in array_out array_recv array_send i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 2211 ( _regtype PGNSP PGUID -1 f b t \054 0 2206 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* pseudo-types
|
* pseudo-types
|
||||||
@ -519,25 +525,25 @@ DATA(insert OID = 2211 ( _regtype PGNSP PGUID -1 f b t \054 0 2206 array_in a
|
|||||||
* argument and result types (if supported by the function's implementation
|
* argument and result types (if supported by the function's implementation
|
||||||
* language).
|
* language).
|
||||||
*/
|
*/
|
||||||
DATA(insert OID = 2249 ( record PGNSP PGUID 4 t p t \054 0 0 record_in record_out record_recv record_send i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 2249 ( record PGNSP PGUID 4 t p t \054 0 0 record_in record_out record_recv record_send - i p f 0 -1 0 _null_ _null_ ));
|
||||||
#define RECORDOID 2249
|
#define RECORDOID 2249
|
||||||
DATA(insert OID = 2275 ( cstring PGNSP PGUID -2 f p t \054 0 0 cstring_in cstring_out cstring_recv cstring_send c p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 2275 ( cstring PGNSP PGUID -2 f p t \054 0 0 cstring_in cstring_out cstring_recv cstring_send - c p f 0 -1 0 _null_ _null_ ));
|
||||||
#define CSTRINGOID 2275
|
#define CSTRINGOID 2275
|
||||||
DATA(insert OID = 2276 ( any PGNSP PGUID 4 t p t \054 0 0 any_in any_out - - i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 2276 ( any PGNSP PGUID 4 t p t \054 0 0 any_in any_out - - - i p f 0 -1 0 _null_ _null_ ));
|
||||||
#define ANYOID 2276
|
#define ANYOID 2276
|
||||||
DATA(insert OID = 2277 ( anyarray PGNSP PGUID -1 f p t \054 0 0 anyarray_in anyarray_out anyarray_recv anyarray_send i x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 2277 ( anyarray PGNSP PGUID -1 f p t \054 0 0 anyarray_in anyarray_out anyarray_recv anyarray_send - i x f 0 -1 0 _null_ _null_ ));
|
||||||
#define ANYARRAYOID 2277
|
#define ANYARRAYOID 2277
|
||||||
DATA(insert OID = 2278 ( void PGNSP PGUID 4 t p t \054 0 0 void_in void_out - - i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 2278 ( void PGNSP PGUID 4 t p t \054 0 0 void_in void_out - - - i p f 0 -1 0 _null_ _null_ ));
|
||||||
#define VOIDOID 2278
|
#define VOIDOID 2278
|
||||||
DATA(insert OID = 2279 ( trigger PGNSP PGUID 4 t p t \054 0 0 trigger_in trigger_out - - i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 2279 ( trigger PGNSP PGUID 4 t p t \054 0 0 trigger_in trigger_out - - - i p f 0 -1 0 _null_ _null_ ));
|
||||||
#define TRIGGEROID 2279
|
#define TRIGGEROID 2279
|
||||||
DATA(insert OID = 2280 ( language_handler PGNSP PGUID 4 t p t \054 0 0 language_handler_in language_handler_out - - i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 2280 ( language_handler PGNSP PGUID 4 t p t \054 0 0 language_handler_in language_handler_out - - - i p f 0 -1 0 _null_ _null_ ));
|
||||||
#define LANGUAGE_HANDLEROID 2280
|
#define LANGUAGE_HANDLEROID 2280
|
||||||
DATA(insert OID = 2281 ( internal PGNSP PGUID 4 t p t \054 0 0 internal_in internal_out - - i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 2281 ( internal PGNSP PGUID 4 t p t \054 0 0 internal_in internal_out - - - i p f 0 -1 0 _null_ _null_ ));
|
||||||
#define INTERNALOID 2281
|
#define INTERNALOID 2281
|
||||||
DATA(insert OID = 2282 ( opaque PGNSP PGUID 4 t p t \054 0 0 opaque_in opaque_out - - i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 2282 ( opaque PGNSP PGUID 4 t p t \054 0 0 opaque_in opaque_out - - - i p f 0 -1 0 _null_ _null_ ));
|
||||||
#define OPAQUEOID 2282
|
#define OPAQUEOID 2282
|
||||||
DATA(insert OID = 2283 ( anyelement PGNSP PGUID 4 t p t \054 0 0 anyelement_in anyelement_out - - i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 2283 ( anyelement PGNSP PGUID 4 t p t \054 0 0 anyelement_in anyelement_out - - - i p f 0 -1 0 _null_ _null_ ));
|
||||||
#define ANYELEMENTOID 2283
|
#define ANYELEMENTOID 2283
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -557,6 +563,7 @@ extern Oid 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,
|
const char *defaultTypeValue,
|
||||||
@ -576,6 +583,7 @@ extern void 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,
|
||||||
|
@ -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 @@
|
|||||||
#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
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user