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 @@ ...@@ -4,7 +4,7 @@
* procedural language * procedural language
* *
* IDENTIFICATION * 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. * This software is copyrighted by Jan Wieck - Hamburg.
* *
...@@ -105,7 +105,8 @@ static void check_assignable(PLpgSQL_datum *datum); ...@@ -105,7 +105,8 @@ static void check_assignable(PLpgSQL_datum *datum);
%type <nsitem> decl_aliasitem %type <nsitem> decl_aliasitem
%type <str> decl_stmts decl_stmt %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 <expr> opt_exitcond
%type <ival> assign_var cursor_variable %type <ival> assign_var cursor_variable
...@@ -822,6 +823,21 @@ assign_var : T_VARIABLE ...@@ -822,6 +823,21 @@ assign_var : T_VARIABLE
check_assignable(yylval.variable); check_assignable(yylval.variable);
$$ = yylval.variable->dno; $$ = 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 ';' stmt_if : K_IF lno expr_until_then proc_sect stmt_else K_END K_IF ';'
...@@ -1491,6 +1507,10 @@ expr_until_semi : ...@@ -1491,6 +1507,10 @@ expr_until_semi :
{ $$ = plpgsql_read_expression(';', ";"); } { $$ = plpgsql_read_expression(';', ";"); }
; ;
expr_until_rightbracket :
{ $$ = plpgsql_read_expression(']', "]"); }
;
expr_until_then : expr_until_then :
{ $$ = plpgsql_read_expression(K_THEN, "THEN"); } { $$ = plpgsql_read_expression(K_THEN, "THEN"); }
; ;
...@@ -1577,16 +1597,16 @@ read_sql_construct(int until, ...@@ -1577,16 +1597,16 @@ read_sql_construct(int until,
for (;;) for (;;)
{ {
tok = yylex(); tok = yylex();
if (tok == '(') if (tok == until && parenlevel == 0)
break;
if (tok == '(' || tok == '[')
parenlevel++; parenlevel++;
else if (tok == ')') else if (tok == ')' || tok == ']')
{ {
parenlevel--; parenlevel--;
if (parenlevel < 0) if (parenlevel < 0)
elog(ERROR, "mismatched parentheses"); elog(ERROR, "mismatched parentheses");
} }
else if (parenlevel == 0 && tok == until)
break;
/* /*
* End of function definition is an error, and we don't expect to * 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 * hit a semicolon either (unless it's the until symbol, in which
...@@ -1988,6 +2008,9 @@ check_assignable(PLpgSQL_datum *datum) ...@@ -1988,6 +2008,9 @@ check_assignable(PLpgSQL_datum *datum)
case PLPGSQL_DTYPE_RECFIELD: case PLPGSQL_DTYPE_RECFIELD:
/* always assignable? */ /* always assignable? */
break; break;
case PLPGSQL_DTYPE_ARRAYELEM:
/* always assignable? */
break;
case PLPGSQL_DTYPE_TRIGARG: case PLPGSQL_DTYPE_TRIGARG:
yyerror("cannot assign to tg_argv"); yyerror("cannot assign to tg_argv");
break; break;
......
This diff is collapsed.
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* procedural language * procedural language
* *
* IDENTIFICATION * 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. * This software is copyrighted by Jan Wieck - Hamburg.
* *
...@@ -1023,6 +1023,12 @@ plpgsql_dumptree(PLpgSQL_function * func) ...@@ -1023,6 +1023,12 @@ plpgsql_dumptree(PLpgSQL_function * func)
((PLpgSQL_recfield *) d)->fieldname, ((PLpgSQL_recfield *) d)->fieldname,
((PLpgSQL_recfield *) d)->recparentno); ((PLpgSQL_recfield *) d)->recparentno);
break; 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: case PLPGSQL_DTYPE_TRIGARG:
printf("TRIGARG "); printf("TRIGARG ");
dump_expr(((PLpgSQL_trigarg *) d)->argnum); dump_expr(((PLpgSQL_trigarg *) d)->argnum);
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* procedural language * procedural language
* *
* IDENTIFICATION * 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. * This software is copyrighted by Jan Wieck - Hamburg.
* *
...@@ -72,6 +72,7 @@ enum ...@@ -72,6 +72,7 @@ enum
PLPGSQL_DTYPE_ROW, PLPGSQL_DTYPE_ROW,
PLPGSQL_DTYPE_REC, PLPGSQL_DTYPE_REC,
PLPGSQL_DTYPE_RECFIELD, PLPGSQL_DTYPE_RECFIELD,
PLPGSQL_DTYPE_ARRAYELEM,
PLPGSQL_DTYPE_EXPR, PLPGSQL_DTYPE_EXPR,
PLPGSQL_DTYPE_TRIGARG PLPGSQL_DTYPE_TRIGARG
}; };
...@@ -154,7 +155,8 @@ typedef struct ...@@ -154,7 +155,8 @@ typedef struct
/* /*
* PLpgSQL_datum is the common supertype for PLpgSQL_expr, PLpgSQL_var, * 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 typedef struct
{ /* Generic datum array item */ { /* Generic datum array item */
...@@ -231,10 +233,19 @@ typedef struct ...@@ -231,10 +233,19 @@ typedef struct
int dtype; int dtype;
int rfno; int rfno;
char *fieldname; char *fieldname;
int recparentno; /* recno of parent record */ int recparentno; /* dno of parent record */
} PLpgSQL_recfield; } 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 typedef struct
{ /* Positional argument to trigger */ { /* Positional argument to trigger */
int dtype; 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