diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2003-04-08 23:20:04 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2003-04-08 23:20:04 +0000 |
commit | 730840c9b649a48604083270d48792915ca89233 (patch) | |
tree | cf3ccc25e61cdfc07061ebec63393d77b3a2f643 /src/backend/parser/parse_oper.c | |
parent | 6fb5115850be766c42177cebf672c68c7d8e3ddd (diff) | |
download | postgresql-730840c9b649a48604083270d48792915ca89233.tar.gz postgresql-730840c9b649a48604083270d48792915ca89233.zip |
First phase of work on array improvements. ARRAY[x,y,z] constructor
expressions, ARRAY(sub-SELECT) expressions, some array functions.
Polymorphic functions using ANYARRAY/ANYELEMENT argument and return
types. Some regression tests in place, documentation is lacking.
Joe Conway, with some kibitzing from Tom Lane.
Diffstat (limited to 'src/backend/parser/parse_oper.c')
-rw-r--r-- | src/backend/parser/parse_oper.c | 120 |
1 files changed, 119 insertions, 1 deletions
diff --git a/src/backend/parser/parse_oper.c b/src/backend/parser/parse_oper.c index eeb8f6aa8bb..3be29e64def 100644 --- a/src/backend/parser/parse_oper.c +++ b/src/backend/parser/parse_oper.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_oper.c,v 1.61 2002/11/29 21:39:11 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_oper.c,v 1.62 2003/04/08 23:20:02 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -22,13 +22,16 @@ #include "catalog/namespace.h" #include "catalog/pg_operator.h" #include "parser/parse_coerce.h" +#include "parser/parse_expr.h" #include "parser/parse_func.h" #include "parser/parse_oper.h" #include "parser/parse_type.h" #include "utils/builtins.h" #include "utils/fmgroids.h" +#include "utils/lsyscache.h" #include "utils/syscache.h" + static Oid binary_oper_exact(Oid arg1, Oid arg2, FuncCandidateList candidates); static Oid oper_select_candidate(int nargs, Oid *input_typeids, @@ -1008,3 +1011,118 @@ unary_op_error(List *op, Oid arg, bool is_left_op) NameListToString(op), format_type_be(arg)); } } + + +/* + * make_op() + * Operator expression construction. + * + * Transform operator expression ensuring type compatibility. + * This is where some type conversion happens. + */ +Expr * +make_op(List *opname, Node *ltree, Node *rtree) +{ + Oid ltypeId, + rtypeId; + Operator tup; + Expr *result; + + /* Select the operator */ + if (rtree == NULL) + { + /* right operator */ + ltypeId = exprType(ltree); + rtypeId = InvalidOid; + tup = right_oper(opname, ltypeId, false); + } + else if (ltree == NULL) + { + /* left operator */ + rtypeId = exprType(rtree); + ltypeId = InvalidOid; + tup = left_oper(opname, rtypeId, false); + } + else + { + /* otherwise, binary operator */ + ltypeId = exprType(ltree); + rtypeId = exprType(rtree); + tup = oper(opname, ltypeId, rtypeId, false); + } + + /* Do typecasting and build the expression tree */ + result = make_op_expr(tup, ltree, rtree, ltypeId, rtypeId); + + ReleaseSysCache(tup); + + return result; +} + + +/* + * make_op_expr() + * Build operator expression using an already-looked-up operator. + */ +Expr * +make_op_expr(Operator op, Node *ltree, Node *rtree, + Oid ltypeId, Oid rtypeId) +{ + Form_pg_operator opform = (Form_pg_operator) GETSTRUCT(op); + Oid actual_arg_types[2]; + Oid declared_arg_types[2]; + int nargs; + List *args; + Oid rettype; + OpExpr *result; + + if (rtree == NULL) + { + /* right operator */ + args = makeList1(ltree); + actual_arg_types[0] = ltypeId; + declared_arg_types[0] = opform->oprleft; + nargs = 1; + } + else if (ltree == NULL) + { + /* left operator */ + args = makeList1(rtree); + actual_arg_types[0] = rtypeId; + declared_arg_types[0] = opform->oprright; + nargs = 1; + } + else + { + /* otherwise, binary operator */ + args = makeList2(ltree, rtree); + actual_arg_types[0] = ltypeId; + actual_arg_types[1] = rtypeId; + declared_arg_types[0] = opform->oprleft; + declared_arg_types[1] = opform->oprright; + nargs = 2; + } + + /* + * enforce consistency with ANYARRAY and ANYELEMENT argument and + * return types, possibly adjusting return type or declared_arg_types + * (which will be used as the cast destination by make_fn_arguments) + */ + rettype = enforce_generic_type_consistency(actual_arg_types, + declared_arg_types, + nargs, + opform->oprresult); + + /* perform the necessary typecasting of arguments */ + make_fn_arguments(args, actual_arg_types, declared_arg_types); + + /* and build the expression node */ + result = makeNode(OpExpr); + result->opno = oprid(op); + result->opfuncid = InvalidOid; + result->opresulttype = rettype; + result->opretset = get_func_retset(opform->oprcode); + result->args = args; + + return (Expr *) result; +} |