aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/network.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2018-03-03 20:31:35 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2018-03-03 20:31:35 -0500
commit58d9acc18d38899ebc30812b4984778c7069f42c (patch)
tree1e3f000b42be70214165ef2b5b22bd51968ed9af /src/backend/utils/adt/network.c
parent7726147f5368e04d0b7c1ab1849a6be47391ff24 (diff)
downloadpostgresql-58d9acc18d38899ebc30812b4984778c7069f42c.tar.gz
postgresql-58d9acc18d38899ebc30812b4984778c7069f42c.zip
Fix assorted issues in convert_to_scalar().
If convert_to_scalar is passed a pair of datatypes it can't cope with, its former behavior was just to elog(ERROR). While this is OK so far as the core code is concerned, there's extension code that would like to use scalarltsel/scalargtsel/etc as selectivity estimators for operators that work on non-core datatypes, and this behavior is a show-stopper for that use-case. If we simply allow convert_to_scalar to return FALSE instead of outright failing, then the main logic of scalarltsel/scalargtsel will work fine for any operator that behaves like a scalar inequality comparison. The lack of conversion capability will mean that we can't estimate to better than histogram-bin-width precision, since the code will effectively assume that the comparison constant falls at the middle of its bin. But that's still a lot better than nothing. (Someday we should provide a way for extension code to supply a custom version of convert_to_scalar, but today is not that day.) While poking at this issue, we noted that the existing code for handling type bytea in convert_to_scalar is several bricks shy of a load. It assumes without checking that if the comparison value is type bytea, the bounds values are too; in the worst case this could lead to a crash. It also fails to detoast the input values, so that the comparison result is complete garbage if any input is toasted out-of-line, compressed, or even just short-header. I'm not sure how often such cases actually occur --- the bounds values, at least, are probably safe since they are elements of an array and hence can't be toasted. But that doesn't make this code OK. Back-patch to all supported branches, partly because author requested that, but mostly because of the bytea bugs. The change in API for the exposed routine convert_network_to_scalar() is theoretically a back-patch hazard, but it seems pretty unlikely that any third-party code is calling that function directly. Tomas Vondra, with some adjustments by me Discussion: https://postgr.es/m/b68441b6-d18f-13ab-b43b-9a72188a4e02@2ndquadrant.com
Diffstat (limited to 'src/backend/utils/adt/network.c')
-rw-r--r--src/backend/utils/adt/network.c13
1 files changed, 5 insertions, 8 deletions
diff --git a/src/backend/utils/adt/network.c b/src/backend/utils/adt/network.c
index aac76217173..350b1a63d21 100644
--- a/src/backend/utils/adt/network.c
+++ b/src/backend/utils/adt/network.c
@@ -902,9 +902,12 @@ inet_merge(PG_FUNCTION_ARGS)
* Convert a value of a network datatype to an approximate scalar value.
* This is used for estimating selectivities of inequality operators
* involving network types.
+ *
+ * On failure (e.g., unsupported typid), set *failure to true;
+ * otherwise, that variable is not changed.
*/
double
-convert_network_to_scalar(Datum value, Oid typid)
+convert_network_to_scalar(Datum value, Oid typid, bool *failure)
{
switch (typid)
{
@@ -931,8 +934,6 @@ convert_network_to_scalar(Datum value, Oid typid)
res += ip_addr(ip)[i];
}
return res;
-
- break;
}
case MACADDROID:
{
@@ -956,11 +957,7 @@ convert_network_to_scalar(Datum value, Oid typid)
}
}
- /*
- * Can't get here unless someone tries to use scalarineqsel() on an
- * operator with one network and one non-network operand.
- */
- elog(ERROR, "unsupported type: %u", typid);
+ *failure = true;
return 0;
}