@@ -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 )
0 commit comments