Skip to content

Commit 08a9fe8

Browse files
committed
ensure so target is not marked as constant
1 parent e23b146 commit 08a9fe8

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

src/assign.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,56 @@ plpgsql_check_row_or_rec(PLpgSQL_checkstate *cstate, PLpgSQL_row *row, PLpgSQL_r
9595
}
9696
}
9797

98+
static void
99+
exec_check_assignable(PLpgSQL_execstate *estate, int dno)
100+
{
101+
PLpgSQL_datum *datum;
102+
103+
Assert(dno >= 0 && dno < estate->ndatums);
104+
datum = estate->datums[dno];
105+
106+
#if PG_VERSION_NUM >= 110000
107+
108+
switch (datum->dtype)
109+
{
110+
case PLPGSQL_DTYPE_VAR:
111+
case PLPGSQL_DTYPE_PROMISE:
112+
case PLPGSQL_DTYPE_REC:
113+
if (((PLpgSQL_variable *) datum)->isconst)
114+
ereport(ERROR,
115+
(errcode(ERRCODE_ERROR_IN_ASSIGNMENT),
116+
errmsg("variable \"%s\" is declared CONSTANT",
117+
((PLpgSQL_variable *) datum)->refname)));
118+
break;
119+
case PLPGSQL_DTYPE_ROW:
120+
/* always assignable; member vars were checked at compile time */
121+
break;
122+
case PLPGSQL_DTYPE_RECFIELD:
123+
/* assignable if parent record is */
124+
exec_check_assignable(estate,
125+
((PLpgSQL_recfield *) datum)->recparentno);
126+
break;
127+
default:
128+
elog(ERROR, "unrecognized dtype: %d", datum->dtype);
129+
break;
130+
}
131+
132+
#else
133+
134+
elog(NOTICE, "kuku");
135+
136+
137+
if (datum->dtype == PLPGSQL_DTYPE_VAR)
138+
if (((PLpgSQL_var *) datum)->isconst)
139+
ereport(ERROR,
140+
(errcode(ERRCODE_ERROR_IN_ASSIGNMENT),
141+
errmsg("variable \"%s\" is declared CONSTANT",
142+
((PLpgSQL_var *) datum)->refname)));
143+
144+
#endif
145+
146+
}
147+
98148
/*
99149
* Verify lvalue It doesn't repeat a checks that are done. Checks a subscript
100150
* expressions, verify a validity of record's fields.
@@ -104,6 +154,7 @@ plpgsql_check_target(PLpgSQL_checkstate *cstate, int varno, Oid *expected_typoid
104154
{
105155
PLpgSQL_datum *target = cstate->estate->datums[varno];
106156

157+
exec_check_assignable(cstate->estate, varno);
107158
plpgsql_check_record_variable_usage(cstate, varno, true);
108159

109160
switch (target->dtype)

src/stmtwalk.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1215,6 +1215,8 @@ plpgsql_check_stmt(PLpgSQL_checkstate *cstate, PLpgSQL_stmt *stmt, int *closing,
12151215
plpgsql_check_expr(cstate, (PLpgSQL_expr *) lfirst(l));
12161216
}
12171217

1218+
plpgsql_check_target(cstate, stmt_open->curvar, NULL, NULL);
1219+
12181220
cstate->modif_variables = bms_add_member(cstate->modif_variables,
12191221
stmt_open->curvar);
12201222
}
@@ -1326,6 +1328,7 @@ plpgsql_check_stmt(PLpgSQL_checkstate *cstate, PLpgSQL_stmt *stmt, int *closing,
13261328
if (target != NULL)
13271329
{
13281330
check_variable(cstate, (PLpgSQL_variable *) target);
1331+
13291332
plpgsql_check_assignment_to_variable(cstate, stmt_call->expr,
13301333
(PLpgSQL_variable *) target, -1);
13311334

0 commit comments

Comments
 (0)