Commit 2c199283 authored by Tom Lane's avatar Tom Lane

plpgsql can assign to subscripted variables now, e.g.

	x[42] := whatever;
The facility is pretty primitive because it doesn't do array slicing and
it has the same semantics as array update in SQL (array must already
be non-null, etc).  But it's a start.
parent 9e29b32e
......@@ -4,7 +4,7 @@
* procedural language
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/gram.y,v 1.40 2002/11/10 00:35:58 momjian Exp $
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/gram.y,v 1.41 2003/03/25 03:16:40 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
......@@ -105,7 +105,8 @@ static void check_assignable(PLpgSQL_datum *datum);
%type <nsitem> decl_aliasitem
%type <str> decl_stmts decl_stmt
%type <expr> expr_until_semi expr_until_then expr_until_loop
%type <expr> expr_until_semi expr_until_rightbracket
%type <expr> expr_until_then expr_until_loop
%type <expr> opt_exitcond
%type <ival> assign_var cursor_variable
......@@ -822,6 +823,21 @@ assign_var : T_VARIABLE
check_assignable(yylval.variable);
$$ = yylval.variable->dno;
}
| assign_var '[' expr_until_rightbracket
{
PLpgSQL_arrayelem *new;
new = malloc(sizeof(PLpgSQL_arrayelem));
memset(new, 0, sizeof(PLpgSQL_arrayelem));
new->dtype = PLPGSQL_DTYPE_ARRAYELEM;
new->subscript = $3;
new->arrayparentno = $1;
plpgsql_adddatum((PLpgSQL_datum *)new);
$$ = new->dno;
}
;
stmt_if : K_IF lno expr_until_then proc_sect stmt_else K_END K_IF ';'
......@@ -1491,6 +1507,10 @@ expr_until_semi :
{ $$ = plpgsql_read_expression(';', ";"); }
;
expr_until_rightbracket :
{ $$ = plpgsql_read_expression(']', "]"); }
;
expr_until_then :
{ $$ = plpgsql_read_expression(K_THEN, "THEN"); }
;
......@@ -1577,16 +1597,16 @@ read_sql_construct(int until,
for (;;)
{
tok = yylex();
if (tok == '(')
if (tok == until && parenlevel == 0)
break;
if (tok == '(' || tok == '[')
parenlevel++;
else if (tok == ')')
else if (tok == ')' || tok == ']')
{
parenlevel--;
if (parenlevel < 0)
elog(ERROR, "mismatched parentheses");
}
else if (parenlevel == 0 && tok == until)
break;
/*
* End of function definition is an error, and we don't expect to
* hit a semicolon either (unless it's the until symbol, in which
......@@ -1988,6 +2008,9 @@ check_assignable(PLpgSQL_datum *datum)
case PLPGSQL_DTYPE_RECFIELD:
/* always assignable? */
break;
case PLPGSQL_DTYPE_ARRAYELEM:
/* always assignable? */
break;
case PLPGSQL_DTYPE_TRIGARG:
yyerror("cannot assign to tg_argv");
break;
......
This diff is collapsed.
......@@ -3,7 +3,7 @@
* procedural language
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_funcs.c,v 1.24 2003/03/25 00:34:23 tgl Exp $
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_funcs.c,v 1.25 2003/03/25 03:16:41 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
......@@ -1023,6 +1023,12 @@ plpgsql_dumptree(PLpgSQL_function * func)
((PLpgSQL_recfield *) d)->fieldname,
((PLpgSQL_recfield *) d)->recparentno);
break;
case PLPGSQL_DTYPE_ARRAYELEM:
printf("ARRAYELEM of VAR %d subscript ",
((PLpgSQL_arrayelem *) d)->arrayparentno);
dump_expr(((PLpgSQL_arrayelem *) d)->subscript);
printf("\n");
break;
case PLPGSQL_DTYPE_TRIGARG:
printf("TRIGARG ");
dump_expr(((PLpgSQL_trigarg *) d)->argnum);
......
......@@ -3,7 +3,7 @@
* procedural language
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.32 2003/03/25 00:34:24 tgl Exp $
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.33 2003/03/25 03:16:41 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
......@@ -72,6 +72,7 @@ enum
PLPGSQL_DTYPE_ROW,
PLPGSQL_DTYPE_REC,
PLPGSQL_DTYPE_RECFIELD,
PLPGSQL_DTYPE_ARRAYELEM,
PLPGSQL_DTYPE_EXPR,
PLPGSQL_DTYPE_TRIGARG
};
......@@ -154,7 +155,8 @@ typedef struct
/*
* PLpgSQL_datum is the common supertype for PLpgSQL_expr, PLpgSQL_var,
* PLpgSQL_row, PLpgSQL_rec, PLpgSQL_recfield, PLpgSQL_trigarg
* PLpgSQL_row, PLpgSQL_rec, PLpgSQL_recfield, PLpgSQL_arrayelem, and
* PLpgSQL_trigarg
*/
typedef struct
{ /* Generic datum array item */
......@@ -231,10 +233,19 @@ typedef struct
int dtype;
int rfno;
char *fieldname;
int recparentno; /* recno of parent record */
int recparentno; /* dno of parent record */
} PLpgSQL_recfield;
typedef struct
{ /* Element of array variable */
int dtype;
int dno;
PLpgSQL_expr *subscript;
int arrayparentno; /* dno of parent array variable */
} PLpgSQL_arrayelem;
typedef struct
{ /* Positional argument to trigger */
int dtype;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment