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,
3535CandidateList * candidates ,
3636char rightleft );
3737static 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
3941Oid
4042any_ordering_op (Oid restype )
@@ -224,11 +226,11 @@ oper_select_candidate(int nargs,
224226
225227if (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+ }
232234return (ncandidates == 1 ) ?candidates -> args :NULL ;
233235}
234236
@@ -279,11 +281,11 @@ oper_select_candidate(int nargs,
279281
280282if (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+ }
287289return (ncandidates == 1 ) ?candidates -> args :NULL ;
288290}
289291
@@ -368,8 +370,7 @@ oper_select_candidate(int nargs,
368370current_candidate != NULL ;
369371current_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{
374375ncandidates ++ ;
375376last_candidate = current_candidate ;
@@ -559,6 +560,7 @@ right_oper(char *op, Oid arg)
559560int ncandidates ;
560561Oid * targetOid ;
561562
563+ /* Try for exact match */
562564tup = SearchSysCacheTuple (OPERNAME ,
563565PointerGetDatum (op ),
564566ObjectIdGetDatum (arg ),
@@ -567,44 +569,35 @@ right_oper(char *op, Oid arg)
567569
568570if (!HeapTupleIsValid (tup ))
569571{
572+ /* Try for inexact matches */
570573ncandidates = unary_oper_get_candidates (op ,arg ,& candidates ,'r' );
571574if (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}
576578else if (ncandidates == 1 )
577579{
578580tup = SearchSysCacheTuple (OPERNAME ,
579581PointerGetDatum (op ),
580- ObjectIdGetDatum (candidates -> args [0 ]),
582+ ObjectIdGetDatum (candidates -> args [0 ]),
581583ObjectIdGetDatum (InvalidOid ),
582584CharGetDatum ('r' ));
583- Assert (HeapTupleIsValid (tup ));
584585}
585586else
586587{
587588targetOid = oper_select_candidate (1 ,& arg ,candidates );
588-
589589if (targetOid != NULL )
590- {
591590tup = SearchSysCacheTuple (OPERNAME ,
592591PointerGetDatum (op ),
592+ ObjectIdGetDatum (targetOid [0 ]),
593593ObjectIdGetDatum (InvalidOid ),
594- ObjectIdGetDatum (* targetOid ),
595594CharGetDatum ('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+
608601return (Operator )tup ;
609602}/* right_oper() */
610603
@@ -619,6 +612,7 @@ left_oper(char *op, Oid arg)
619612int ncandidates ;
620613Oid * targetOid ;
621614
615+ /* Try for exact match */
622616tup = SearchSysCacheTuple (OPERNAME ,
623617PointerGetDatum (op ),
624618ObjectIdGetDatum (InvalidOid ),
@@ -627,43 +621,35 @@ left_oper(char *op, Oid arg)
627621
628622if (!HeapTupleIsValid (tup ))
629623{
624+ /* Try for inexact matches */
630625ncandidates = unary_oper_get_candidates (op ,arg ,& candidates ,'l' );
631626if (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}
636630else if (ncandidates == 1 )
637631{
638632tup = SearchSysCacheTuple (OPERNAME ,
639633PointerGetDatum (op ),
640634ObjectIdGetDatum (InvalidOid ),
641- ObjectIdGetDatum (candidates -> args [0 ]),
635+ ObjectIdGetDatum (candidates -> args [0 ]),
642636CharGetDatum ('l' ));
643- Assert (HeapTupleIsValid (tup ));
644637}
645638else
646639{
647640targetOid = oper_select_candidate (1 ,& arg ,candidates );
648641if (targetOid != NULL )
649- {
650642tup = SearchSysCacheTuple (OPERNAME ,
651643PointerGetDatum (op ),
652644ObjectIdGetDatum (InvalidOid ),
653- ObjectIdGetDatum (* targetOid ),
645+ ObjectIdGetDatum (targetOid [ 0 ] ),
654646CharGetDatum ('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+
667653return (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" ,
699685op ,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+ }