From 9b21a18cee705fa972e5b8f8ab106145015bafe7 Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Fri, 2 Oct 1998 16:23:07 +0000 Subject: [PATCH] the following little patch adds array references to query parameters. With it applied a function like CREATE FUNCTION getname(oid8, int4) RETURNS name AS 'SELECT typname FROM pg_type WHERE oid = $1[$2]' LANGUAGE 'sql'; is possible. Mainly I need this to enable array references in expressions for PL/pgSQL. Complete regression test ran O.K. Jan --- src/backend/parser/gram.y | 5 +++-- src/backend/parser/parse_expr.c | 36 +++++++++++++++++++++++++++++++-- src/include/nodes/parsenodes.h | 3 ++- 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 4d3ccc03d1..05366b6cbf 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.33 1998/09/30 05:47:56 thomas Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.34 1998/10/02 16:23:04 momjian Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -4598,10 +4598,11 @@ AexprConst: Iconst } ; -ParamNo: PARAM +ParamNo: PARAM opt_indirection { $$ = makeNode(ParamNo); $$->number = $1; + $$->indirection = $2; } ; diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c index 6bb923afce..0c2a40a190 100644 --- a/src/backend/parser/parse_expr.c +++ b/src/backend/parser/parse_expr.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.35 1998/10/01 22:51:20 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.36 1998/10/02 16:23:05 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -122,7 +122,39 @@ transformExpr(ParseState *pstate, Node *expr, int precedence) param->paramtype = (Oid) toid; param->param_tlist = (List *) NULL; - result = (Node *) param; + if (pno->indirection != NIL) + { + List *idx = pno->indirection; + + while (idx != NIL) + { + A_Indices *ai = (A_Indices *) lfirst(idx); + Node *lexpr = NULL, + *uexpr; + + uexpr = transformExpr(pstate, ai->uidx, precedence); /* must exists */ + if (exprType(uexpr) != INT4OID) + elog(ERROR, "array index expressions must be int4's"); + if (ai->lidx != NULL) + { + lexpr = transformExpr(pstate, ai->lidx, precedence); + if (exprType(lexpr) != INT4OID) + elog(ERROR, "array index expressions must be int4's"); + } + ai->lidx = lexpr; + ai->uidx = uexpr; + + /* + * note we reuse the list of indices, make sure we + * don't free them! Otherwise, make a new list + * here + */ + idx = lnext(idx); + } + result = (Node *) make_array_ref((Node *)param, pno->indirection); + } + else + result = (Node *) param; break; } case T_A_Expr: diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 26bdc420dd..0608c3101f 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -6,7 +6,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: parsenodes.h,v 1.59 1998/09/01 04:36:43 momjian Exp $ + * $Id: parsenodes.h,v 1.60 1998/10/02 16:23:07 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -667,6 +667,7 @@ typedef struct ParamNo NodeTag type; int number; /* the number of the parameter */ TypeName *typename; /* the typecast */ + List *indirection; /* array references */ } ParamNo; /*