1997-11-25 23:07:18 +01:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
Clean up two rather nasty bugs in operator selection code.
1. If there is exactly one pg_operator entry of the right name and oprkind,
oper() and related routines would return that entry whether its input type
had anything to do with the request or not. This is just premature
optimization: we shouldn't return the single candidate until after we verify
that it really is a valid candidate, ie, is at least coercion-compatible
with the given types.
2. oper() and related routines only promise a coercion-compatible result.
Unfortunately, there were quite a few callers that assumed the returned
operator is binary-compatible with the given datatype; they would proceed
to call it without making any datatype coercions. These callers include
sorting, grouping, aggregation, and VACUUM ANALYZE. In general I think
it is appropriate for these callers to require an exact or binary-compatible
match, so I've added a new routine compatible_oper() that only succeeds if
it can find an operator that doesn't require any run-time conversions.
Callers now call oper() or compatible_oper() depending on whether they are
prepared to deal with type conversion or not.
The upshot of these bugs is revealed by the following silliness in PL/Tcl's
selftest: it creates an operator @< on int4, and then tries to use it to
sort a char(N) column. The system would let it do that :-( (and evidently
has done so since 6.3 :-( :-(). The result in this case was just a silly
sort order, but the reverse combination would've provoked coredump from
trying to dereference integers. With this fix you get more reasonable
behavior:
pltcl_test=# select * from T_pkey1 order by key1, key2 using @<;
ERROR: Unable to identify an operator '@<' for types 'bpchar' and 'bpchar'
You will have to retype this query using an explicit cast
2001-02-16 04:16:58 +01:00
|
|
|
* parse_oper.h
|
2002-11-29 22:39:12 +01:00
|
|
|
* handle operator things for parser
|
1997-11-25 23:07:18 +01:00
|
|
|
*
|
|
|
|
*
|
2020-01-01 18:21:45 +01:00
|
|
|
* Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
|
2000-01-26 06:58:53 +01:00
|
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
1997-11-25 23:07:18 +01:00
|
|
|
*
|
2010-09-20 22:08:53 +02:00
|
|
|
* src/include/parser/parse_oper.h
|
1997-11-25 23:07:18 +01:00
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
#ifndef PARSE_OPER_H
|
|
|
|
#define PARSE_OPER_H
|
|
|
|
|
1999-07-15 17:21:54 +02:00
|
|
|
#include "access/htup.h"
|
2016-12-28 18:00:00 +01:00
|
|
|
#include "nodes/parsenodes.h"
|
2003-04-30 00:13:11 +02:00
|
|
|
#include "parser/parse_node.h"
|
|
|
|
|
1997-11-25 23:07:18 +01:00
|
|
|
|
|
|
|
typedef HeapTuple Operator;
|
|
|
|
|
2002-04-17 01:08:12 +02:00
|
|
|
/* Routines to look up an operator given name and exact input type(s) */
|
2019-05-22 19:04:48 +02:00
|
|
|
extern Oid LookupOperName(ParseState *pstate, List *opername,
|
|
|
|
Oid oprleft, Oid oprright,
|
|
|
|
bool noError, int location);
|
2017-05-17 22:31:56 +02:00
|
|
|
extern Oid LookupOperWithArgs(ObjectWithArgs *oper, bool noError);
|
2002-04-17 01:08:12 +02:00
|
|
|
|
Clean up two rather nasty bugs in operator selection code.
1. If there is exactly one pg_operator entry of the right name and oprkind,
oper() and related routines would return that entry whether its input type
had anything to do with the request or not. This is just premature
optimization: we shouldn't return the single candidate until after we verify
that it really is a valid candidate, ie, is at least coercion-compatible
with the given types.
2. oper() and related routines only promise a coercion-compatible result.
Unfortunately, there were quite a few callers that assumed the returned
operator is binary-compatible with the given datatype; they would proceed
to call it without making any datatype coercions. These callers include
sorting, grouping, aggregation, and VACUUM ANALYZE. In general I think
it is appropriate for these callers to require an exact or binary-compatible
match, so I've added a new routine compatible_oper() that only succeeds if
it can find an operator that doesn't require any run-time conversions.
Callers now call oper() or compatible_oper() depending on whether they are
prepared to deal with type conversion or not.
The upshot of these bugs is revealed by the following silliness in PL/Tcl's
selftest: it creates an operator @< on int4, and then tries to use it to
sort a char(N) column. The system would let it do that :-( (and evidently
has done so since 6.3 :-( :-(). The result in this case was just a silly
sort order, but the reverse combination would've provoked coredump from
trying to dereference integers. With this fix you get more reasonable
behavior:
pltcl_test=# select * from T_pkey1 order by key1, key2 using @<;
ERROR: Unable to identify an operator '@<' for types 'bpchar' and 'bpchar'
You will have to retype this query using an explicit cast
2001-02-16 04:16:58 +01:00
|
|
|
/* Routines to find operators matching a name and given input types */
|
|
|
|
/* NB: the selected operator may require coercion of the input types! */
|
2006-03-14 23:48:25 +01:00
|
|
|
extern Operator oper(ParseState *pstate, List *op, Oid arg1, Oid arg2,
|
2019-05-22 19:04:48 +02:00
|
|
|
bool noError, int location);
|
2006-03-14 23:48:25 +01:00
|
|
|
extern Operator left_oper(ParseState *pstate, List *op, Oid arg,
|
2019-05-22 19:04:48 +02:00
|
|
|
bool noError, int location);
|
1997-11-25 23:07:18 +01:00
|
|
|
|
Clean up two rather nasty bugs in operator selection code.
1. If there is exactly one pg_operator entry of the right name and oprkind,
oper() and related routines would return that entry whether its input type
had anything to do with the request or not. This is just premature
optimization: we shouldn't return the single candidate until after we verify
that it really is a valid candidate, ie, is at least coercion-compatible
with the given types.
2. oper() and related routines only promise a coercion-compatible result.
Unfortunately, there were quite a few callers that assumed the returned
operator is binary-compatible with the given datatype; they would proceed
to call it without making any datatype coercions. These callers include
sorting, grouping, aggregation, and VACUUM ANALYZE. In general I think
it is appropriate for these callers to require an exact or binary-compatible
match, so I've added a new routine compatible_oper() that only succeeds if
it can find an operator that doesn't require any run-time conversions.
Callers now call oper() or compatible_oper() depending on whether they are
prepared to deal with type conversion or not.
The upshot of these bugs is revealed by the following silliness in PL/Tcl's
selftest: it creates an operator @< on int4, and then tries to use it to
sort a char(N) column. The system would let it do that :-( (and evidently
has done so since 6.3 :-( :-(). The result in this case was just a silly
sort order, but the reverse combination would've provoked coredump from
trying to dereference integers. With this fix you get more reasonable
behavior:
pltcl_test=# select * from T_pkey1 order by key1, key2 using @<;
ERROR: Unable to identify an operator '@<' for types 'bpchar' and 'bpchar'
You will have to retype this query using an explicit cast
2001-02-16 04:16:58 +01:00
|
|
|
/* Routines to find operators that DO NOT require coercion --- ie, their */
|
|
|
|
/* input types are either exactly as given, or binary-compatible */
|
2006-03-14 23:48:25 +01:00
|
|
|
extern Operator compatible_oper(ParseState *pstate, List *op,
|
2019-05-22 19:04:48 +02:00
|
|
|
Oid arg1, Oid arg2,
|
|
|
|
bool noError, int location);
|
2001-03-22 05:01:46 +01:00
|
|
|
|
Clean up two rather nasty bugs in operator selection code.
1. If there is exactly one pg_operator entry of the right name and oprkind,
oper() and related routines would return that entry whether its input type
had anything to do with the request or not. This is just premature
optimization: we shouldn't return the single candidate until after we verify
that it really is a valid candidate, ie, is at least coercion-compatible
with the given types.
2. oper() and related routines only promise a coercion-compatible result.
Unfortunately, there were quite a few callers that assumed the returned
operator is binary-compatible with the given datatype; they would proceed
to call it without making any datatype coercions. These callers include
sorting, grouping, aggregation, and VACUUM ANALYZE. In general I think
it is appropriate for these callers to require an exact or binary-compatible
match, so I've added a new routine compatible_oper() that only succeeds if
it can find an operator that doesn't require any run-time conversions.
Callers now call oper() or compatible_oper() depending on whether they are
prepared to deal with type conversion or not.
The upshot of these bugs is revealed by the following silliness in PL/Tcl's
selftest: it creates an operator @< on int4, and then tries to use it to
sort a char(N) column. The system would let it do that :-( (and evidently
has done so since 6.3 :-( :-(). The result in this case was just a silly
sort order, but the reverse combination would've provoked coredump from
trying to dereference integers. With this fix you get more reasonable
behavior:
pltcl_test=# select * from T_pkey1 order by key1, key2 using @<;
ERROR: Unable to identify an operator '@<' for types 'bpchar' and 'bpchar'
You will have to retype this query using an explicit cast
2001-02-16 04:16:58 +01:00
|
|
|
/* currently no need for compatible_left_oper/compatible_right_oper */
|
|
|
|
|
2008-08-02 23:32:01 +02:00
|
|
|
/* Routines for identifying "<", "=", ">" operators for a type */
|
|
|
|
extern void get_sort_group_operators(Oid argtype,
|
2019-05-22 19:04:48 +02:00
|
|
|
bool needLT, bool needEQ, bool needGT,
|
|
|
|
Oid *ltOpr, Oid *eqOpr, Oid *gtOpr,
|
|
|
|
bool *isHashable);
|
2000-11-16 23:30:52 +01:00
|
|
|
|
2002-11-29 22:39:12 +01:00
|
|
|
/* Convenience routines for common calls on the above */
|
|
|
|
extern Oid compatible_oper_opid(List *op, Oid arg1, Oid arg2, bool noError);
|
Clean up two rather nasty bugs in operator selection code.
1. If there is exactly one pg_operator entry of the right name and oprkind,
oper() and related routines would return that entry whether its input type
had anything to do with the request or not. This is just premature
optimization: we shouldn't return the single candidate until after we verify
that it really is a valid candidate, ie, is at least coercion-compatible
with the given types.
2. oper() and related routines only promise a coercion-compatible result.
Unfortunately, there were quite a few callers that assumed the returned
operator is binary-compatible with the given datatype; they would proceed
to call it without making any datatype coercions. These callers include
sorting, grouping, aggregation, and VACUUM ANALYZE. In general I think
it is appropriate for these callers to require an exact or binary-compatible
match, so I've added a new routine compatible_oper() that only succeeds if
it can find an operator that doesn't require any run-time conversions.
Callers now call oper() or compatible_oper() depending on whether they are
prepared to deal with type conversion or not.
The upshot of these bugs is revealed by the following silliness in PL/Tcl's
selftest: it creates an operator @< on int4, and then tries to use it to
sort a char(N) column. The system would let it do that :-( (and evidently
has done so since 6.3 :-( :-(). The result in this case was just a silly
sort order, but the reverse combination would've provoked coredump from
trying to dereference integers. With this fix you get more reasonable
behavior:
pltcl_test=# select * from T_pkey1 order by key1, key2 using @<;
ERROR: Unable to identify an operator '@<' for types 'bpchar' and 'bpchar'
You will have to retype this query using an explicit cast
2001-02-16 04:16:58 +01:00
|
|
|
|
|
|
|
/* Extract operator OID or underlying-function OID from an Operator tuple */
|
|
|
|
extern Oid oprid(Operator op);
|
|
|
|
extern Oid oprfuncid(Operator op);
|
2001-10-28 07:26:15 +01:00
|
|
|
|
2003-04-09 01:20:04 +02:00
|
|
|
/* Build expression tree for an operator invocation */
|
2003-04-30 00:13:11 +02:00
|
|
|
extern Expr *make_op(ParseState *pstate, List *opname,
|
2019-05-22 19:04:48 +02:00
|
|
|
Node *ltree, Node *rtree, Node *last_srf, int location);
|
2003-06-29 02:33:44 +02:00
|
|
|
extern Expr *make_scalar_array_op(ParseState *pstate, List *opname,
|
2019-05-22 19:04:48 +02:00
|
|
|
bool useOr,
|
|
|
|
Node *ltree, Node *rtree, int location);
|
2003-04-09 01:20:04 +02:00
|
|
|
|
Phase 2 of pgindent updates.
Change pg_bsd_indent to follow upstream rules for placement of comments
to the right of code, and remove pgindent hack that caused comments
following #endif to not obey the general rule.
Commit e3860ffa4dd0dad0dd9eea4be9cc1412373a8c89 wasn't actually using
the published version of pg_bsd_indent, but a hacked-up version that
tried to minimize the amount of movement of comments to the right of
code. The situation of interest is where such a comment has to be
moved to the right of its default placement at column 33 because there's
code there. BSD indent has always moved right in units of tab stops
in such cases --- but in the previous incarnation, indent was working
in 8-space tab stops, while now it knows we use 4-space tabs. So the
net result is that in about half the cases, such comments are placed
one tab stop left of before. This is better all around: it leaves
more room on the line for comment text, and it means that in such
cases the comment uniformly starts at the next 4-space tab stop after
the code, rather than sometimes one and sometimes two tabs after.
Also, ensure that comments following #endif are indented the same
as comments following other preprocessor commands such as #else.
That inconsistency turns out to have been self-inflicted damage
from a poorly-thought-through post-indent "fixup" in pgindent.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:18:54 +02:00
|
|
|
#endif /* PARSE_OPER_H */
|