Re: file_fdw: Support multi-line HEADER option.

From: Shinya Kato <shinya11(dot)kato(at)gmail(dot)com>
To: Fujii Masao <masao(dot)fujii(at)gmail(dot)com>
Cc: Chao Li <li(dot)evan(dot)chao(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: file_fdw: Support multi-line HEADER option.
Date: 2026-01-20 04:16:33
Message-ID: CAOzEurSE095pGSx1dka7Qxggdc9HtreOUY7RK7PxT-ODXr+rtA@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Mon, Jan 19, 2026 at 8:22 PM Fujii Masao <masao(dot)fujii(at)gmail(dot)com> wrote:
> +CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (header
> '2.5'); -- ERROR
> +ERROR: header requires a Boolean value, a non-negative integer, or
> the string "match"
>
> This isn't caused by the patch, but I think the error message itself should
> be improved in a separate patch before adding multi-line header support
> to file_fdw. Per the Error Message Style Guide, "non-negative" should
> be avoided because it's ambiguous about whether zero is accepted.

I didn't know such a style guide, thanks. I've fixed it in the v4-0001 patch.

> - syntax requires a value to be present in all cases. To activate
> - <command>COPY</command> options typically written without a value,
> you can pass
> - the value TRUE, since all such options are Booleans.
> + syntax requires a value to be present in all cases. Use the appropriate
> + explicit value (for example <literal>TRUE</literal>,
> <literal>match</literal>,
> + or a non-negative integer line count for <literal>HEADER</literal>) to enable
> + the desired behavior.
>
> Using "non-negative" here has the same ambiguity.
>
> I'm not sure if this change is an improvement. Isn't the original wording
> almost OK? Of course, "all such options are Booleans" is not true and
> probably should be something like "all such options accpet Boolean values",
> though.

I've fixed it as suggested.

> + if (IsA(def->arg, Integer))
> + return defCheckCopyHeaderInteger(def, intVal(def->arg), is_from);
> + else
> + return defCheckCopyHeaderString(def, defGetString(def), is_from);
>
> Personally, I think it would be simpler and easier to understand to keep
> the logic in a single function defGetCopyHeaderOption(), rather than
> splitting it across three functions. Thought?
>
> For example,
> -------------------------------------
> switch (nodeTag(def->arg))
> {
> case T_Integer:
> ival = intVal(def->arg);
> break;
> default:
> {
> char *sval = defGetString(def);
>
> ...
>
> else
> {
> ErrorSaveContext escontext = {T_ErrorSaveContext};
>
> /* Check if the header is a valid integer */
> ival = pg_strtoint32_safe(sval, (Node *) &escontext);
> if (escontext.error_occurred)
> ereport(ERROR,
> (errcode(ERRCODE_SYNTAX_ERROR),
> errmsg("%s requires a Boolean value,
> a non-negative integer, "
> "or the string \"match\"",
> def->defname)));
> }
> }
> break;
> }
>
> if (ival < 0)
> ereport(ERROR,
> (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
> errmsg("a negative integer value cannot be "
> "specified for %s", def->defname)));
>
> ...
> -------------------------------------

Thank you! I was struggling with how to write it cleanly, but the code
you suggested is clear and easy to understand.

--
Best regards,
Shinya Kato
NTT OSS Center

Attachment Content-Type Size
v4-0001-Replace-non-negative-with-greater-than-or-equal-t.patch application/octet-stream 3.7 KB
v4-0002-file_fdw-Support-multi-line-HEADER-option.patch application/octet-stream 12.7 KB

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Amit Kapila 2026-01-20 04:17:18 Re: Logical Replication of sequences
Previous Message Amit Kapila 2026-01-20 03:57:30 Re: Logical Replication of sequences