diff options
Diffstat (limited to 'src/backend/parser/parse_oper.c')
-rw-r--r-- | src/backend/parser/parse_oper.c | 111 |
1 files changed, 60 insertions, 51 deletions
diff --git a/src/backend/parser/parse_oper.c b/src/backend/parser/parse_oper.c index 2bd65b2e126..e483372e852 100644 --- a/src/backend/parser/parse_oper.c +++ b/src/backend/parser/parse_oper.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/parser/parse_oper.c,v 1.85 2006/03/05 15:58:34 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/parser/parse_oper.c,v 1.86 2006/03/14 22:48:21 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -37,8 +37,9 @@ static FuncDetailCode oper_select_candidate(int nargs, Oid *operOid); static const char *op_signature_string(List *op, char oprkind, Oid arg1, Oid arg2); -static void op_error(List *op, char oprkind, Oid arg1, Oid arg2, - FuncDetailCode fdresult); +static void op_error(ParseState *pstate, List *op, char oprkind, + Oid arg1, Oid arg2, + FuncDetailCode fdresult, int location); static Expr *make_op_expr(ParseState *pstate, Operator op, Node *ltree, Node *rtree, Oid ltypeId, Oid rtypeId); @@ -56,10 +57,12 @@ static Expr *make_op_expr(ParseState *pstate, Operator op, * namespace search path. * * If the operator is not found, we return InvalidOid if noError is true, - * else raise an error. + * else raise an error. pstate and location are used only to report the + * error position; pass NULL/-1 if not available. */ Oid -LookupOperName(List *opername, Oid oprleft, Oid oprright, bool noError) +LookupOperName(ParseState *pstate, List *opername, Oid oprleft, Oid oprright, + bool noError, int location) { FuncCandidateList clist; char oprkind; @@ -86,7 +89,8 @@ LookupOperName(List *opername, Oid oprleft, Oid oprright, bool noError) (errcode(ERRCODE_UNDEFINED_FUNCTION), errmsg("operator does not exist: %s", op_signature_string(opername, oprkind, - oprleft, oprright)))); + oprleft, oprright)), + parser_errposition(pstate, location))); return InvalidOid; } @@ -99,8 +103,9 @@ LookupOperName(List *opername, Oid oprleft, Oid oprright, bool noError) * Pass oprleft = NULL for a prefix op, oprright = NULL for a postfix op. */ Oid -LookupOperNameTypeNames(List *opername, TypeName *oprleft, - TypeName *oprright, bool noError) +LookupOperNameTypeNames(ParseState *pstate, List *opername, + TypeName *oprleft, TypeName *oprright, + bool noError, int location) { Oid leftoid, rightoid; @@ -108,27 +113,15 @@ LookupOperNameTypeNames(List *opername, TypeName *oprleft, if (oprleft == NULL) leftoid = InvalidOid; else - { - leftoid = LookupTypeName(oprleft); - if (!OidIsValid(leftoid)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("type %s does not exist", - TypeNameToString(oprleft)))); - } + leftoid = typenameTypeId(pstate, oprleft); + if (oprright == NULL) rightoid = InvalidOid; else - { - rightoid = LookupTypeName(oprright); - if (!OidIsValid(rightoid)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("type %s does not exist", - TypeNameToString(oprright)))); - } + rightoid = typenameTypeId(pstate, oprright); - return LookupOperName(opername, leftoid, rightoid, noError); + return LookupOperName(pstate, opername, leftoid, rightoid, + noError, location); } /* @@ -500,13 +493,15 @@ oper_select_candidate(int nargs, * you need an exact- or binary-compatible match; see compatible_oper. * * If no matching operator found, return NULL if noError is true, - * raise an error if it is false. + * raise an error if it is false. pstate and location are used only to report + * the error position; pass NULL/-1 if not available. * * NOTE: on success, the returned object is a syscache entry. The caller * must ReleaseSysCache() the entry when done with it. */ Operator -oper(List *opname, Oid ltypeId, Oid rtypeId, bool noError) +oper(ParseState *pstate, List *opname, Oid ltypeId, Oid rtypeId, + bool noError, int location) { FuncCandidateList clist; Oid inputOids[2]; @@ -549,7 +544,7 @@ oper(List *opname, Oid ltypeId, Oid rtypeId, bool noError) } if (!HeapTupleIsValid(tup) && !noError) - op_error(opname, 'b', ltypeId, rtypeId, fdresult); + op_error(pstate, opname, 'b', ltypeId, rtypeId, fdresult, location); return (Operator) tup; } @@ -562,13 +557,14 @@ oper(List *opname, Oid ltypeId, Oid rtypeId, bool noError) * are accepted). Otherwise, the semantics are the same. */ Operator -compatible_oper(List *op, Oid arg1, Oid arg2, bool noError) +compatible_oper(ParseState *pstate, List *op, Oid arg1, Oid arg2, + bool noError, int location) { Operator optup; Form_pg_operator opform; /* oper() will find the best available match */ - optup = oper(op, arg1, arg2, noError); + optup = oper(pstate, op, arg1, arg2, noError, location); if (optup == (Operator) NULL) return (Operator) NULL; /* must be noError case */ @@ -585,7 +581,8 @@ compatible_oper(List *op, Oid arg1, Oid arg2, bool noError) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_FUNCTION), errmsg("operator requires run-time type coercion: %s", - op_signature_string(op, 'b', arg1, arg2)))); + op_signature_string(op, 'b', arg1, arg2)), + parser_errposition(pstate, location))); return (Operator) NULL; } @@ -602,7 +599,7 @@ compatible_oper_opid(List *op, Oid arg1, Oid arg2, bool noError) Operator optup; Oid result; - optup = compatible_oper(op, arg1, arg2, noError); + optup = compatible_oper(NULL, op, arg1, arg2, noError, -1); if (optup != NULL) { result = oprid(optup); @@ -621,13 +618,14 @@ compatible_oper_opid(List *op, Oid arg1, Oid arg2, bool noError) * you need an exact- or binary-compatible match. * * If no matching operator found, return NULL if noError is true, - * raise an error if it is false. + * raise an error if it is false. pstate and location are used only to report + * the error position; pass NULL/-1 if not available. * * NOTE: on success, the returned object is a syscache entry. The caller * must ReleaseSysCache() the entry when done with it. */ Operator -right_oper(List *op, Oid arg, bool noError) +right_oper(ParseState *pstate, List *op, Oid arg, bool noError, int location) { FuncCandidateList clist; Oid operOid = InvalidOid; @@ -669,7 +667,7 @@ right_oper(List *op, Oid arg, bool noError) } if (!HeapTupleIsValid(tup) && !noError) - op_error(op, 'r', arg, InvalidOid, fdresult); + op_error(pstate, op, 'r', arg, InvalidOid, fdresult, location); return (Operator) tup; } @@ -683,13 +681,14 @@ right_oper(List *op, Oid arg, bool noError) * you need an exact- or binary-compatible match. * * If no matching operator found, return NULL if noError is true, - * raise an error if it is false. + * raise an error if it is false. pstate and location are used only to report + * the error position; pass NULL/-1 if not available. * * NOTE: on success, the returned object is a syscache entry. The caller * must ReleaseSysCache() the entry when done with it. */ Operator -left_oper(List *op, Oid arg, bool noError) +left_oper(ParseState *pstate, List *op, Oid arg, bool noError, int location) { FuncCandidateList clist; Oid operOid = InvalidOid; @@ -736,7 +735,7 @@ left_oper(List *op, Oid arg, bool noError) } if (!HeapTupleIsValid(tup) && !noError) - op_error(op, 'l', InvalidOid, arg, fdresult); + op_error(pstate, op, 'l', InvalidOid, arg, fdresult, location); return (Operator) tup; } @@ -771,7 +770,9 @@ op_signature_string(List *op, char oprkind, Oid arg1, Oid arg2) * op_error - utility routine to complain about an unresolvable operator */ static void -op_error(List *op, char oprkind, Oid arg1, Oid arg2, FuncDetailCode fdresult) +op_error(ParseState *pstate, List *op, char oprkind, + Oid arg1, Oid arg2, + FuncDetailCode fdresult, int location) { if (fdresult == FUNCDETAIL_MULTIPLE) ereport(ERROR, @@ -779,14 +780,16 @@ op_error(List *op, char oprkind, Oid arg1, Oid arg2, FuncDetailCode fdresult) errmsg("operator is not unique: %s", op_signature_string(op, oprkind, arg1, arg2)), errhint("Could not choose a best candidate operator. " - "You may need to add explicit type casts."))); + "You may need to add explicit type casts."), + parser_errposition(pstate, location))); else ereport(ERROR, (errcode(ERRCODE_UNDEFINED_FUNCTION), errmsg("operator does not exist: %s", op_signature_string(op, oprkind, arg1, arg2)), errhint("No operator matches the given name and argument type(s). " - "You may need to add explicit type casts."))); + "You may need to add explicit type casts."), + parser_errposition(pstate, location))); } /* @@ -800,7 +803,8 @@ op_error(List *op, char oprkind, Oid arg1, Oid arg2, FuncDetailCode fdresult) * processing is wanted. */ Expr * -make_op(ParseState *pstate, List *opname, Node *ltree, Node *rtree) +make_op(ParseState *pstate, List *opname, Node *ltree, Node *rtree, + int location) { Oid ltypeId, rtypeId; @@ -813,21 +817,21 @@ make_op(ParseState *pstate, List *opname, Node *ltree, Node *rtree) /* right operator */ ltypeId = exprType(ltree); rtypeId = InvalidOid; - tup = right_oper(opname, ltypeId, false); + tup = right_oper(pstate, opname, ltypeId, false, location); } else if (ltree == NULL) { /* left operator */ rtypeId = exprType(rtree); ltypeId = InvalidOid; - tup = left_oper(opname, rtypeId, false); + tup = left_oper(pstate, opname, rtypeId, false, location); } else { /* otherwise, binary operator */ ltypeId = exprType(ltree); rtypeId = exprType(rtree); - tup = oper(opname, ltypeId, rtypeId, false); + tup = oper(pstate, opname, ltypeId, rtypeId, false, location); } /* Do typecasting and build the expression tree */ @@ -845,7 +849,8 @@ make_op(ParseState *pstate, List *opname, Node *ltree, Node *rtree) Expr * make_scalar_array_op(ParseState *pstate, List *opname, bool useOr, - Node *ltree, Node *rtree) + Node *ltree, Node *rtree, + int location) { Oid ltypeId, rtypeId, @@ -875,11 +880,12 @@ make_scalar_array_op(ParseState *pstate, List *opname, if (!OidIsValid(rtypeId)) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("op ANY/ALL (array) requires array on right side"))); + errmsg("op ANY/ALL (array) requires array on right side"), + parser_errposition(pstate, location))); } /* Now resolve the operator */ - tup = oper(opname, ltypeId, rtypeId, false); + tup = oper(pstate, opname, ltypeId, rtypeId, false, location); opform = (Form_pg_operator) GETSTRUCT(tup); args = list_make2(ltree, rtree); @@ -904,11 +910,13 @@ make_scalar_array_op(ParseState *pstate, List *opname, if (rettype != BOOLOID) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("op ANY/ALL (array) requires operator to yield boolean"))); + errmsg("op ANY/ALL (array) requires operator to yield boolean"), + parser_errposition(pstate, location))); if (get_func_retset(opform->oprcode)) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("op ANY/ALL (array) requires operator not to return a set"))); + errmsg("op ANY/ALL (array) requires operator not to return a set"), + parser_errposition(pstate, location))); /* * Now switch back to the array type on the right, arranging for any @@ -919,7 +927,8 @@ make_scalar_array_op(ParseState *pstate, List *opname, ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("could not find array type for data type %s", - format_type_be(declared_arg_types[1])))); + format_type_be(declared_arg_types[1])), + parser_errposition(pstate, location))); actual_arg_types[1] = atypeId; declared_arg_types[1] = res_atypeId; |