end $$;
NOTICE: execute = 10
NOTICE: r.strict = 1
+-- Test handling of a reserved keyword as a record field name.
+do $$ declare r record;
+begin
+ select 1 as x, 2 as foreach into r;
+ raise notice 'r.x = %', r.x;
+ raise notice 'r.foreach = %', r.foreach; -- fails
+end $$;
+NOTICE: r.x = 1
+ERROR: field name "foreach" is a reserved key word
+LINE 1: r.foreach
+ ^
+HINT: Use double quotes to quote it.
+QUERY: r.foreach
+CONTEXT: PL/pgSQL function inline_code_block line 5 at RAISE
+do $$ declare r record;
+begin
+ select 1 as x, 2 as foreach into r;
+ raise notice 'r.x = %', r.x;
+ raise notice 'r."foreach" = %', r."foreach"; -- ok
+end $$;
+NOTICE: r.x = 1
+NOTICE: r."foreach" = 2
}
/*
- * We should not get here, because a RECFIELD datum should
- * have been built at parse time for every possible qualified
- * reference to fields of this record. But if we do, handle
- * it like field-not-found: throw error or return NULL.
+ * Ideally we'd never get here, because a RECFIELD datum
+ * should have been built at parse time for every qualified
+ * reference to a field of this record that appears in the
+ * source text. However, plpgsql_yylex will not build such a
+ * datum unless the field name lexes as token type IDENT.
+ * Hence, if the would-be field name is a PL/pgSQL reserved
+ * word, we lose. Assume that that's what happened and tell
+ * the user to quote it, unless the caller prefers we just
+ * return NULL.
*/
if (error_if_no_field)
ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_COLUMN),
- errmsg("record \"%s\" has no field \"%s\"",
- (nnames_field == 1) ? name1 : name2,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("field name \"%s\" is a reserved key word",
colname),
+ errhint("Use double quotes to quote it."),
parser_errposition(pstate, cref->location)));
}
break;
select 1 as strict into r;
raise notice 'r.strict = %', r.strict;
end $$;
+
+-- Test handling of a reserved keyword as a record field name.
+
+do $$ declare r record;
+begin
+ select 1 as x, 2 as foreach into r;
+ raise notice 'r.x = %', r.x;
+ raise notice 'r.foreach = %', r.foreach; -- fails
+end $$;
+
+do $$ declare r record;
+begin
+ select 1 as x, 2 as foreach into r;
+ raise notice 'r.x = %', r.x;
+ raise notice 'r."foreach" = %', r."foreach"; -- ok
+end $$;