Remove user-selectable ANALYZE option for range types.

It's not clear that a per-datatype typanalyze function would be any more
useful than a generic typanalyze for ranges.  What *is* clear is that
letting unprivileged users select typanalyze functions is a crash risk or
worse.  So remove the option from CREATE TYPE AS RANGE, and instead put in
a generic typanalyze function for ranges.  The generic function does
nothing as yet, but hopefully we'll improve that before 9.2 release.
This commit is contained in:
Tom Lane 2011-11-23 00:03:22 -05:00
parent df73584431
commit 74c1723fc8
8 changed files with 36 additions and 40 deletions

View File

@ -33,7 +33,6 @@ CREATE TYPE <replaceable class="parameter">name</replaceable> AS RANGE (
[ , COLLATION = <replaceable class="parameter">collation</replaceable> ]
[ , CANONICAL = <replaceable class="parameter">canonical_function</replaceable> ]
[ , SUBTYPE_DIFF = <replaceable class="parameter">subtype_diff_function</replaceable> ]
[ , ANALYZE = <replaceable class="parameter">analyze_function</replaceable> ]
)
CREATE TYPE <replaceable class="parameter">name</replaceable> (
@ -167,12 +166,6 @@ CREATE TYPE <replaceable class="parameter">name</replaceable>
that is, its result should be positive whenever its first argument is
greater than its second according to the sort ordering.
</para>
<para>
The optional <replaceable class="parameter">analyze</replaceable>
function performs type-specific statistics collection for columns of the
range type. This is defined the same as for base types; see below.
</para>
</refsect2>
<refsect2>

View File

@ -1225,12 +1225,10 @@ DefineRange(CreateRangeStmt *stmt)
List *rangeCollationName = NIL;
List *rangeCanonicalName = NIL;
List *rangeSubtypeDiffName = NIL;
List *rangeAnalyzeName = NIL;
Oid rangeSubOpclass;
Oid rangeCollation;
regproc rangeCanonical;
regproc rangeSubtypeDiff;
regproc rangeAnalyze;
int16 subtyplen;
bool subtypbyval;
char subtypalign;
@ -1326,14 +1324,6 @@ DefineRange(CreateRangeStmt *stmt)
errmsg("conflicting or redundant options")));
rangeSubtypeDiffName = defGetQualifiedName(defel);
}
else if (pg_strcasecmp(defel->defname, "analyze") == 0)
{
if (rangeAnalyzeName != NIL)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("conflicting or redundant options")));
rangeAnalyzeName = defGetQualifiedName(defel);
}
else
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
@ -1386,12 +1376,6 @@ DefineRange(CreateRangeStmt *stmt)
else
rangeSubtypeDiff = InvalidOid;
if (rangeAnalyzeName != NIL)
rangeAnalyze = findTypeAnalyzeFunction(rangeAnalyzeName,
typoid);
else
rangeAnalyze = InvalidOid;
get_typlenbyvalalign(rangeSubtype,
&subtyplen, &subtypbyval, &subtypalign);
@ -1420,7 +1404,7 @@ DefineRange(CreateRangeStmt *stmt)
F_RANGE_SEND, /* send procedure */
InvalidOid, /* typmodin procedure - none */
InvalidOid, /* typmodout procedure - none */
rangeAnalyze, /* analyze procedure */
F_RANGE_TYPANALYZE, /* analyze procedure */
InvalidOid, /* element type ID - none */
false, /* this is not an array type */
rangeArrayOid, /* array type we are about to create */

View File

@ -1135,6 +1135,23 @@ hash_range(PG_FUNCTION_ARGS)
PG_RETURN_INT32(result);
}
/* ANALYZE support */
/* typanalyze function for range datatypes */
Datum
range_typanalyze(PG_FUNCTION_ARGS)
{
/*
* For the moment, just punt and don't analyze range columns. If we
* get close to release without having a better answer, we could
* consider letting std_typanalyze do what it can ... but those stats
* are probably next door to useless for most activity with range
* columns, so it's not clear it's worth gathering them.
*/
PG_RETURN_BOOL(false);
}
/*
*----------------------------------------------------------
* CANONICAL FUNCTIONS

View File

@ -7482,11 +7482,11 @@ dumpRangeType(Archive *fout, TypeInfo *tyinfo)
"opc.opcdefault, "
"CASE WHEN rngcollation = st.typcollation THEN 0 "
" ELSE rngcollation END AS collation, "
"rngcanonical, rngsubdiff, t.typanalyze "
"FROM pg_catalog.pg_type t, pg_catalog.pg_type st, "
" pg_catalog.pg_opclass opc, pg_catalog.pg_range r "
"WHERE t.oid = rngtypid AND st.oid = rngsubtype AND "
" opc.oid = rngsubopc AND rngtypid = '%u'",
"rngcanonical, rngsubdiff "
"FROM pg_catalog.pg_range r, pg_catalog.pg_type st, "
" pg_catalog.pg_opclass opc "
"WHERE st.oid = rngsubtype AND opc.oid = rngsubopc AND "
"rngtypid = '%u'",
tyinfo->dobj.catId.oid);
res = PQexec(g_conn, query->data);
@ -7552,10 +7552,6 @@ dumpRangeType(Archive *fout, TypeInfo *tyinfo)
if (strcmp(procname, "-") != 0)
appendPQExpBuffer(q, ",\n subtype_diff = %s", procname);
procname = PQgetvalue(res, 0, PQfnumber(res, "typanalyze"));
if (strcmp(procname, "-") != 0)
appendPQExpBuffer(q, ",\n analyze = %s", procname);
appendPQExpBuffer(q, "\n);\n");
appendPQExpBuffer(labelq, "TYPE %s", fmtId(tyinfo->dobj.name));

View File

@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 201111222
#define CATALOG_VERSION_NO 201111231
#endif

View File

@ -4413,6 +4413,9 @@ DATA(insert OID = 3881 ( range_gist_same PGNSP PGUID 12 1 0 0 0 f f f t f i 3
DESCR("GiST support");
DATA(insert OID = 3902 ( hash_range PGNSP PGUID 12 1 0 0 0 f f f t f i 1 0 23 "3831" _null_ _null_ _null_ _null_ hash_range _null_ _null_ _null_ ));
DESCR("hash a range");
DATA(insert OID = 3916 ( range_typanalyze PGNSP PGUID 12 1 0 0 0 f f f t f s 1 0 16 "2281" _null_ _null_ _null_ _null_ range_typanalyze _null_ _null_ _null_ ));
DESCR("range typanalyze");
DATA(insert OID = 3914 ( int4range_canonical PGNSP PGUID 12 1 0 0 0 f f f t f i 1 0 3904 "3904" _null_ _null_ _null_ _null_ int4range_canonical _null_ _null_ _null_ ));
DESCR("convert an int4 range to canonical form");
DATA(insert OID = 3928 ( int8range_canonical PGNSP PGUID 12 1 0 0 0 f f f t f i 1 0 3926 "3926" _null_ _null_ _null_ _null_ int8range_canonical _null_ _null_ _null_ ));

View File

@ -593,23 +593,23 @@ DESCR("txid snapshot");
DATA(insert OID = 2949 ( _txid_snapshot PGNSP PGUID -1 f b A f t \054 0 2970 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 0 _null_ _null_ ));
/* range types */
DATA(insert OID = 3904 ( int4range PGNSP PGUID -1 f r R f t \054 0 0 3905 range_in range_out range_recv range_send - - - i x f 0 -1 0 0 _null_ _null_ ));
DATA(insert OID = 3904 ( int4range PGNSP PGUID -1 f r R f t \054 0 0 3905 range_in range_out range_recv range_send - - range_typanalyze i x f 0 -1 0 0 _null_ _null_ ));
DESCR("range of integers");
#define INT4RANGEOID 3904
DATA(insert OID = 3905 ( _int4range PGNSP PGUID -1 f b A f t \054 0 3904 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ ));
DATA(insert OID = 3906 ( numrange PGNSP PGUID -1 f r R f t \054 0 0 3907 range_in range_out range_recv range_send - - - i x f 0 -1 0 0 _null_ _null_ ));
DATA(insert OID = 3906 ( numrange PGNSP PGUID -1 f r R f t \054 0 0 3907 range_in range_out range_recv range_send - - range_typanalyze i x f 0 -1 0 0 _null_ _null_ ));
DESCR("range of numerics");
DATA(insert OID = 3907 ( _numrange PGNSP PGUID -1 f b A f t \054 0 3906 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ ));
DATA(insert OID = 3908 ( tsrange PGNSP PGUID -1 f r R f t \054 0 0 3909 range_in range_out range_recv range_send - - - d x f 0 -1 0 0 _null_ _null_ ));
DATA(insert OID = 3908 ( tsrange PGNSP PGUID -1 f r R f t \054 0 0 3909 range_in range_out range_recv range_send - - range_typanalyze d x f 0 -1 0 0 _null_ _null_ ));
DESCR("range of timestamps without time zone");
DATA(insert OID = 3909 ( _tsrange PGNSP PGUID -1 f b A f t \054 0 3908 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 0 _null_ _null_ ));
DATA(insert OID = 3910 ( tstzrange PGNSP PGUID -1 f r R f t \054 0 0 3911 range_in range_out range_recv range_send - - - d x f 0 -1 0 0 _null_ _null_ ));
DATA(insert OID = 3910 ( tstzrange PGNSP PGUID -1 f r R f t \054 0 0 3911 range_in range_out range_recv range_send - - range_typanalyze d x f 0 -1 0 0 _null_ _null_ ));
DESCR("range of timestamps with time zone");
DATA(insert OID = 3911 ( _tstzrange PGNSP PGUID -1 f b A f t \054 0 3910 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 0 _null_ _null_ ));
DATA(insert OID = 3912 ( daterange PGNSP PGUID -1 f r R f t \054 0 0 3913 range_in range_out range_recv range_send - - - i x f 0 -1 0 0 _null_ _null_ ));
DATA(insert OID = 3912 ( daterange PGNSP PGUID -1 f r R f t \054 0 0 3913 range_in range_out range_recv range_send - - range_typanalyze i x f 0 -1 0 0 _null_ _null_ ));
DESCR("range of dates");
DATA(insert OID = 3913 ( _daterange PGNSP PGUID -1 f b A f t \054 0 3912 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ ));
DATA(insert OID = 3926 ( int8range PGNSP PGUID -1 f r R f t \054 0 0 3927 range_in range_out range_recv range_send - - - d x f 0 -1 0 0 _null_ _null_ ));
DATA(insert OID = 3926 ( int8range PGNSP PGUID -1 f r R f t \054 0 0 3927 range_in range_out range_recv range_send - - range_typanalyze d x f 0 -1 0 0 _null_ _null_ ));
DESCR("range of bigints");
DATA(insert OID = 3927 ( _int8range PGNSP PGUID -1 f b A f t \054 0 3926 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 0 _null_ _null_ ));

View File

@ -127,6 +127,9 @@ extern Datum range_gt(PG_FUNCTION_ARGS);
/* Hash support */
extern Datum hash_range(PG_FUNCTION_ARGS);
/* ANALYZE support */
extern Datum range_typanalyze(PG_FUNCTION_ARGS);
/* Canonical functions */
extern Datum int4range_canonical(PG_FUNCTION_ARGS);
extern Datum int8range_canonical(PG_FUNCTION_ARGS);