@@ -99,7 +99,8 @@ static void add_dummy_return(PLpgSQL_function *function);
99
99
static Node * plpgsql_pre_column_ref (ParseState * pstate , ColumnRef * cref );
100
100
static Node * plpgsql_post_column_ref (ParseState * pstate , ColumnRef * cref , Node * var );
101
101
static Node * plpgsql_param_ref (ParseState * pstate , ParamRef * pref );
102
- static Node * resolve_column_ref (PLpgSQL_expr * expr , ColumnRef * cref );
102
+ static Node * resolve_column_ref (ParseState * pstate , PLpgSQL_expr * expr ,
103
+ ColumnRef * cref , bool error_if_no_field );
103
104
static Node * make_datum_param (PLpgSQL_expr * expr , int dno , int location );
104
105
static PLpgSQL_row * build_row_from_class (Oid classOid );
105
106
static PLpgSQL_row * build_row_from_vars (PLpgSQL_variable * * vars , int numvars );
@@ -945,7 +946,7 @@ plpgsql_pre_column_ref(ParseState *pstate, ColumnRef *cref)
945
946
PLpgSQL_expr * expr = (PLpgSQL_expr * ) pstate -> p_ref_hook_state ;
946
947
947
948
if (expr -> func -> resolve_option == PLPGSQL_RESOLVE_VARIABLE )
948
- return resolve_column_ref (expr , cref );
949
+ return resolve_column_ref (pstate , expr , cref , false );
949
950
else
950
951
return NULL ;
951
952
}
@@ -965,7 +966,17 @@ plpgsql_post_column_ref(ParseState *pstate, ColumnRef *cref, Node *var)
965
966
if (expr -> func -> resolve_option == PLPGSQL_RESOLVE_COLUMN && var != NULL )
966
967
return NULL ; /* there's a table column, prefer that */
967
968
968
- myvar = resolve_column_ref (expr , cref );
969
+ /*
970
+ * If we find a record/row variable but can't match a field name, throw
971
+ * error if there was no core resolution for the ColumnRef either. In
972
+ * that situation, the reference is inevitably going to fail, and
973
+ * complaining about the record/row variable is likely to be more
974
+ * on-point than the core parser's error message. (It's too bad we
975
+ * don't have access to transformColumnRef's internal crerr state here,
976
+ * as in case of a conflict with a table name this could still be less
977
+ * than the most helpful error message possible.)
978
+ */
979
+ myvar = resolve_column_ref (pstate , expr , cref , (var == NULL ));
969
980
970
981
if (myvar != NULL && var != NULL )
971
982
{
@@ -1010,9 +1021,13 @@ plpgsql_param_ref(ParseState *pstate, ParamRef *pref)
1010
1021
* resolve_column_ref attempt to resolve a ColumnRef as a plpgsql var
1011
1022
*
1012
1023
* Returns the translated node structure, or NULL if name not found
1024
+ *
1025
+ * error_if_no_field tells whether to throw error or quietly return NULL if
1026
+ * we are able to match a record/row name but don't find a field name match.
1013
1027
*/
1014
1028
static Node *
1015
- resolve_column_ref (PLpgSQL_expr * expr , ColumnRef * cref )
1029
+ resolve_column_ref (ParseState * pstate , PLpgSQL_expr * expr ,
1030
+ ColumnRef * cref , bool error_if_no_field )
1016
1031
{
1017
1032
PLpgSQL_execstate * estate ;
1018
1033
PLpgSQL_nsitem * nse ;
@@ -1147,9 +1162,16 @@ resolve_column_ref(PLpgSQL_expr *expr, ColumnRef *cref)
1147
1162
/*
1148
1163
* We should not get here, because a RECFIELD datum should
1149
1164
* have been built at parse time for every possible qualified
1150
- * reference to fields of this record. But if we do, fall out
1151
- * and return NULL.
1165
+ * reference to fields of this record. But if we do, handle
1166
+ * it like field-not-found: throw error or return NULL.
1152
1167
*/
1168
+ if (error_if_no_field )
1169
+ ereport (ERROR ,
1170
+ (errcode (ERRCODE_UNDEFINED_COLUMN ),
1171
+ errmsg ("record \"%s\" has no field \"%s\"" ,
1172
+ (nnames_field == 1 ) ? name1 : name2 ,
1173
+ colname ),
1174
+ parser_errposition (pstate , cref -> location )));
1153
1175
}
1154
1176
break ;
1155
1177
case PLPGSQL_NSTYPE_ROW :
@@ -1170,7 +1192,14 @@ resolve_column_ref(PLpgSQL_expr *expr, ColumnRef *cref)
1170
1192
cref -> location );
1171
1193
}
1172
1194
}
1173
- /* Not found, so return NULL */
1195
+ /* Not found, so throw error or return NULL */
1196
+ if (error_if_no_field )
1197
+ ereport (ERROR ,
1198
+ (errcode (ERRCODE_UNDEFINED_COLUMN ),
1199
+ errmsg ("record \"%s\" has no field \"%s\"" ,
1200
+ (nnames_field == 1 ) ? name1 : name2 ,
1201
+ colname ),
1202
+ parser_errposition (pstate , cref -> location )));
1174
1203
}
1175
1204
break ;
1176
1205
default :
0 commit comments