Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 66fe0fc

Browse files
committed
Fix poorly worded error messages for unary operator type resolution
failures. Fix some outright bugs too, including a reference to uninitialized memory that would cause failures like this one: select -('1234567890.1234567'::text); ERROR: Unable to locate type oid 2139062143 in catalog
1 parent ed0e292 commit 66fe0fc

File tree

1 file changed

+58
-47
lines changed

1 file changed

+58
-47
lines changed

src/backend/parser/parse_oper.c

Lines changed: 58 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
/*-------------------------------------------------------------------------
22
*
3-
* parse_oper.h
3+
* parse_oper.c
44
* handle operator things for parser
55
*
66
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/parser/parse_oper.c,v 1.35 2000/01/26 05:56:42 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/parser/parse_oper.c,v 1.36 2000/02/27 02:48:15 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -35,6 +35,8 @@ static int unary_oper_get_candidates(char *op,
3535
CandidateList *candidates,
3636
char rightleft);
3737
static void op_error(char *op, Oid arg1, Oid arg2);
38+
static void unary_op_error(char *op, Oid arg, bool is_left_op);
39+
3840

3941
Oid
4042
any_ordering_op(Oid restype)
@@ -224,11 +226,11 @@ oper_select_candidate(int nargs,
224226

225227
if (ncandidates <= 1)
226228
{
227-
if (ncandidates > 0 &&
228-
(!can_coerce_type(1, &input_typeids[0], &candidates->args[0]) ||
229-
(nargs > 1 &&
230-
!can_coerce_type(1, &input_typeids[1], &candidates->args[1]))))
231-
ncandidates = 0;
229+
if (ncandidates > 0)
230+
{
231+
if (!can_coerce_type(nargs, input_typeids, candidates->args))
232+
ncandidates = 0;
233+
}
232234
return (ncandidates == 1) ? candidates->args : NULL;
233235
}
234236

@@ -279,11 +281,11 @@ oper_select_candidate(int nargs,
279281

280282
if (ncandidates <= 1)
281283
{
282-
if (ncandidates > 0 &&
283-
(!can_coerce_type(1, &input_typeids[0], &candidates->args[0]) ||
284-
(nargs > 1 &&
285-
!can_coerce_type(1, &input_typeids[1], &candidates->args[1]))))
286-
ncandidates = 0;
284+
if (ncandidates > 0)
285+
{
286+
if (!can_coerce_type(nargs, input_typeids, candidates->args))
287+
ncandidates = 0;
288+
}
287289
return (ncandidates == 1) ? candidates->args : NULL;
288290
}
289291

@@ -368,8 +370,7 @@ oper_select_candidate(int nargs,
368370
current_candidate != NULL;
369371
current_candidate = current_candidate->next)
370372
{
371-
if (can_coerce_type(1, &input_typeids[0], &current_candidate->args[0])
372-
&& can_coerce_type(1, &input_typeids[1], &current_candidate->args[1]))
373+
if (can_coerce_type(nargs, input_typeids, current_candidate->args))
373374
{
374375
ncandidates++;
375376
last_candidate = current_candidate;
@@ -559,6 +560,7 @@ right_oper(char *op, Oid arg)
559560
int ncandidates;
560561
Oid *targetOid;
561562

563+
/* Try for exact match */
562564
tup = SearchSysCacheTuple(OPERNAME,
563565
PointerGetDatum(op),
564566
ObjectIdGetDatum(arg),
@@ -567,44 +569,35 @@ right_oper(char *op, Oid arg)
567569

568570
if (!HeapTupleIsValid(tup))
569571
{
572+
/* Try for inexact matches */
570573
ncandidates = unary_oper_get_candidates(op, arg, &candidates, 'r');
571574
if (ncandidates == 0)
572575
{
573-
elog(ERROR, "Can't find right op '%s' for type %u", op, arg);
574-
return NULL;
576+
unary_op_error(op, arg, FALSE);
575577
}
576578
else if (ncandidates == 1)
577579
{
578580
tup = SearchSysCacheTuple(OPERNAME,
579581
PointerGetDatum(op),
580-
ObjectIdGetDatum(candidates->args[0]),
582+
ObjectIdGetDatum(candidates->args[0]),
581583
ObjectIdGetDatum(InvalidOid),
582584
CharGetDatum('r'));
583-
Assert(HeapTupleIsValid(tup));
584585
}
585586
else
586587
{
587588
targetOid = oper_select_candidate(1, &arg, candidates);
588-
589589
if (targetOid != NULL)
590-
{
591590
tup = SearchSysCacheTuple(OPERNAME,
592591
PointerGetDatum(op),
592+
ObjectIdGetDatum(targetOid[0]),
593593
ObjectIdGetDatum(InvalidOid),
594-
ObjectIdGetDatum(*targetOid),
595594
CharGetDatum('r'));
596-
}
597-
else
598-
tup = NULL;
599-
600-
if (!HeapTupleIsValid(tup))
601-
{
602-
elog(ERROR, "Unable to convert right operator '%s' from type '%s'",
603-
op, typeidTypeName(arg));
604-
return NULL;
605-
}
606595
}
596+
597+
if (!HeapTupleIsValid(tup))
598+
unary_op_error(op, arg, FALSE);
607599
}
600+
608601
return (Operator) tup;
609602
} /* right_oper() */
610603

@@ -619,6 +612,7 @@ left_oper(char *op, Oid arg)
619612
int ncandidates;
620613
Oid *targetOid;
621614

615+
/* Try for exact match */
622616
tup = SearchSysCacheTuple(OPERNAME,
623617
PointerGetDatum(op),
624618
ObjectIdGetDatum(InvalidOid),
@@ -627,43 +621,35 @@ left_oper(char *op, Oid arg)
627621

628622
if (!HeapTupleIsValid(tup))
629623
{
624+
/* Try for inexact matches */
630625
ncandidates = unary_oper_get_candidates(op, arg, &candidates, 'l');
631626
if (ncandidates == 0)
632627
{
633-
elog(ERROR, "Can't find left op '%s' for type %u", op, arg);
634-
return NULL;
628+
unary_op_error(op, arg, TRUE);
635629
}
636630
else if (ncandidates == 1)
637631
{
638632
tup = SearchSysCacheTuple(OPERNAME,
639633
PointerGetDatum(op),
640634
ObjectIdGetDatum(InvalidOid),
641-
ObjectIdGetDatum(candidates->args[0]),
635+
ObjectIdGetDatum(candidates->args[0]),
642636
CharGetDatum('l'));
643-
Assert(HeapTupleIsValid(tup));
644637
}
645638
else
646639
{
647640
targetOid = oper_select_candidate(1, &arg, candidates);
648641
if (targetOid != NULL)
649-
{
650642
tup = SearchSysCacheTuple(OPERNAME,
651643
PointerGetDatum(op),
652644
ObjectIdGetDatum(InvalidOid),
653-
ObjectIdGetDatum(*targetOid),
645+
ObjectIdGetDatum(targetOid[0]),
654646
CharGetDatum('l'));
655-
}
656-
else
657-
tup = NULL;
658-
659-
if (!HeapTupleIsValid(tup))
660-
{
661-
elog(ERROR, "Unable to convert left operator '%s' from type '%s'",
662-
op, typeidTypeName(arg));
663-
return NULL;
664-
}
665647
}
648+
649+
if (!HeapTupleIsValid(tup))
650+
unary_op_error(op, arg, TRUE);
666651
}
652+
667653
return (Operator) tup;
668654
} /* left_oper() */
669655

@@ -698,3 +684,28 @@ op_error(char *op, Oid arg1, Oid arg2)
698684
"\n\tYou will have to retype this query using an explicit cast",
699685
op, typeTypeName(tp1), typeTypeName(tp2));
700686
}
687+
688+
/* unary_op_error()
689+
* Give a somewhat useful error message when the operator for one type
690+
* is not found.
691+
*/
692+
static void
693+
unary_op_error(char *op, Oid arg, bool is_left_op)
694+
{
695+
Type tp1 = NULL;
696+
697+
if (typeidIsValid(arg))
698+
tp1 = typeidType(arg);
699+
else
700+
{
701+
elog(ERROR, "Argument of %s operator '%s' has an unknown type"
702+
"\n\tProbably a bad attribute name",
703+
(is_left_op ? "left" : "right"),
704+
op);
705+
}
706+
707+
elog(ERROR, "Unable to identify a %s operator '%s' for type '%s'"
708+
"\n\tYou will have to retype this query using an explicit cast",
709+
(is_left_op ? "left" : "right"),
710+
op, typeTypeName(tp1));
711+
}

0 commit comments

Comments
 (0)