mirror of
https://github.com/zebrajr/postgres.git
synced 2025-12-07 00:20:24 +01:00
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
125 lines
4.1 KiB
C
125 lines
4.1 KiB
C
/*-------------------------------------------------------------------------
|
|
*
|
|
* builtins.h
|
|
* Declarations for operations on built-in types.
|
|
*
|
|
*
|
|
* Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
*
|
|
* src/include/utils/builtins.h
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
#ifndef BUILTINS_H
|
|
#define BUILTINS_H
|
|
|
|
#include "fmgr.h"
|
|
#include "nodes/nodes.h"
|
|
#include "utils/fmgrprotos.h"
|
|
|
|
|
|
/* bool.c */
|
|
extern bool parse_bool(const char *value, bool *result);
|
|
extern bool parse_bool_with_len(const char *value, size_t len, bool *result);
|
|
|
|
/* domains.c */
|
|
extern void domain_check(Datum value, bool isnull, Oid domainType,
|
|
void **extra, MemoryContext mcxt);
|
|
extern int errdatatype(Oid datatypeOid);
|
|
extern int errdomainconstraint(Oid datatypeOid, const char *conname);
|
|
|
|
/* encode.c */
|
|
extern unsigned hex_encode(const char *src, unsigned len, char *dst);
|
|
extern unsigned hex_decode(const char *src, unsigned len, char *dst);
|
|
|
|
/* int.c */
|
|
extern int2vector *buildint2vector(const int16 *int2s, int n);
|
|
|
|
/* name.c */
|
|
extern int namecpy(Name n1, Name n2);
|
|
extern int namestrcpy(Name name, const char *str);
|
|
extern int namestrcmp(Name name, const char *str);
|
|
|
|
/* numutils.c */
|
|
extern int32 pg_atoi(const char *s, int size, int c);
|
|
extern void pg_itoa(int16 i, char *a);
|
|
extern void pg_ltoa(int32 l, char *a);
|
|
extern void pg_lltoa(int64 ll, char *a);
|
|
extern char *pg_ltostr_zeropad(char *str, int32 value, int32 minwidth);
|
|
extern char *pg_ltostr(char *str, int32 value);
|
|
extern uint64 pg_strtouint64(const char *str, char **endptr, int base);
|
|
|
|
/* float.c */
|
|
extern PGDLLIMPORT int extra_float_digits;
|
|
|
|
extern double get_float8_infinity(void);
|
|
extern float get_float4_infinity(void);
|
|
extern double get_float8_nan(void);
|
|
extern float get_float4_nan(void);
|
|
extern int is_infinite(double val);
|
|
extern double float8in_internal(char *num, char **endptr_p,
|
|
const char *type_name, const char *orig_string);
|
|
extern char *float8out_internal(double num);
|
|
extern int float4_cmp_internal(float4 a, float4 b);
|
|
extern int float8_cmp_internal(float8 a, float8 b);
|
|
|
|
/* oid.c */
|
|
extern oidvector *buildoidvector(const Oid *oids, int n);
|
|
extern Oid oidparse(Node *node);
|
|
extern int oid_cmp(const void *p1, const void *p2);
|
|
|
|
/* regexp.c */
|
|
extern char *regexp_fixed_prefix(text *text_re, bool case_insensitive,
|
|
Oid collation, bool *exact);
|
|
|
|
/* ruleutils.c */
|
|
extern bool quote_all_identifiers;
|
|
extern const char *quote_identifier(const char *ident);
|
|
extern char *quote_qualified_identifier(const char *qualifier,
|
|
const char *ident);
|
|
|
|
/* varchar.c */
|
|
extern int bpchartruelen(char *s, int len);
|
|
|
|
/* popular functions from varlena.c */
|
|
extern text *cstring_to_text(const char *s);
|
|
extern text *cstring_to_text_with_len(const char *s, int len);
|
|
extern char *text_to_cstring(const text *t);
|
|
extern void text_to_cstring_buffer(const text *src, char *dst, size_t dst_len);
|
|
|
|
#define CStringGetTextDatum(s) PointerGetDatum(cstring_to_text(s))
|
|
#define TextDatumGetCString(d) text_to_cstring((text *) DatumGetPointer(d))
|
|
|
|
/* xid.c */
|
|
extern int xidComparator(const void *arg1, const void *arg2);
|
|
|
|
/* inet_cidr_ntop.c */
|
|
extern char *inet_cidr_ntop(int af, const void *src, int bits,
|
|
char *dst, size_t size);
|
|
|
|
/* inet_net_pton.c */
|
|
extern int inet_net_pton(int af, const char *src,
|
|
void *dst, size_t size);
|
|
|
|
/* network.c */
|
|
extern double convert_network_to_scalar(Datum value, Oid typid, bool *failure);
|
|
extern Datum network_scan_first(Datum in);
|
|
extern Datum network_scan_last(Datum in);
|
|
extern void clean_ipv6_addr(int addr_family, char *addr);
|
|
|
|
/* numeric.c */
|
|
extern Datum numeric_float8_no_overflow(PG_FUNCTION_ARGS);
|
|
|
|
/* format_type.c */
|
|
extern char *format_type_be(Oid type_oid);
|
|
extern char *format_type_be_qualified(Oid type_oid);
|
|
extern char *format_type_with_typemod(Oid type_oid, int32 typemod);
|
|
extern char *format_type_with_typemod_qualified(Oid type_oid, int32 typemod);
|
|
extern int32 type_maximum_size(Oid type_oid, int32 typemod);
|
|
|
|
/* quote.c */
|
|
extern char *quote_literal_cstr(const char *rawstr);
|
|
|
|
#endif /* BUILTINS_H */
|