Re:Reject HEADER with binary and json COPY formats by option presence

Поиск
Список
Период
Сортировка
Искать

Re:Reject HEADER with binary and json COPY formats by option presence

От:
"Tingchuan Sun" <suntingchuan1996@163.com>
Дата:







At 2026-06-03 11:11:29, "Chao Li" <li.evan.chao@gmail.com> wrote: >Hi, > >While testing “file_fdw: Support multi-line HEADER option”, I noticed a small issue. > >The doc says that the HEADER option cannot be used with the “binary" or “json" format: >``` > <varlistentry id="sql-copy-params-header"> > <term><literal>HEADER</literal></term> > <listitem> > <para> > On output, if this option is set to <literal>true</literal> > (or an equivalent Boolean value), the first line of the output will > contain the column names from the table. > Integer values <literal>0</literal> and <literal>1</literal> are > accepted as Boolean values, but other integers are not allowed for > <command>COPY TO</command> commands. > </para> > <para> > On input, if this option is set to <literal>true</literal> > (or an equivalent Boolean value), the first line of the input is > discarded. If set to a non-negative integer, that number of > lines are discarded. If set to <literal>MATCH</literal>, the first line > is discarded, and it must contain column names that exactly match the > table's columns, in both number and order; otherwise, an error is raised. > The <literal>MATCH</literal> value is only valid for > <command>COPY FROM</command> commands. > </para> > <para> > This option is not allowed when using <literal>binary</literal> or <literal>json</literal> format. > </para> > </listitem> > </varlistentry> >``` > >However, when I specified "header ‘0", the command did not fail. That means the current behavior depends on the value of the “header" option, not on presence: >``` >evantest=# create foreign table ft (i int) server fs options (format 'binary', filename '/tmp/ft.bin', header '1'); >ERROR: cannot specify HEADER in BINARY mode >evantest=# create foreign table ft (i int) server fs options (format 'binary', filename '/tmp/ft.bin', header '0'); >CREATE FOREIGN TABLE >``` > >As we can see, "header 1" fails, but header 0" is silently accepted. I don't think this behavior matches what the documentation describes. > >For comparison, VACUUM has a similar option. “BUFFER_USAGE_LIMIT" is not allowed with "VACUUM FULL", and a value of 0 means disabling the buffer access strategy: >``` > <varlistentry> > <term><literal>BUFFER_USAGE_LIMIT</literal></term> > <listitem> > <para> > Specifies the > <glossterm linkend="glossary-buffer-access-strategy">Buffer Access Strategy</glossterm> > ring buffer size for <command>VACUUM</command>. This size is used to > calculate the number of shared buffers which will be reused as part of > this strategy. <literal>0</literal> disables use of a > <literal>Buffer Access Strategy</literal>. If <option>ANALYZE</option> > is also specified, the <option>BUFFER_USAGE_LIMIT</option> value is used > for both the vacuum and analyze stages. This option can't be used with > the <option>FULL</option> option except if <option>ANALYZE</option> is > also specified. When this option is not specified, > <command>VACUUM</command> uses the value from > <xref linkend="guc-vacuum-buffer-usage-limit"/>. Higher settings can > allow <command>VACUUM</command> to run more quickly, but having too > large a setting may cause too many other useful pages to be evicted from > shared buffers. The minimum value is <literal>128 kB</literal> and the > maximum value is <literal>16 GB</literal>. > </para> > </listitem> > </varlistentry> >``` > >Using BUFFER_USAGE_LIMIT 0 with FULL is still rejected: >``` >evantest=# vacuum (full, BUFFER_USAGE_LIMIT 0) t; >ERROR: BUFFER_USAGE_LIMIT cannot be specified for VACUUM FULL >``` > >So VACUUM rejects BUFFER_USAGE_LIMIT based on the presence of the option, not its value. I think we should keep the behavior consistent here, and VACUUM's behavior better matches the documentation. Otherwise, I am afraid this could encourage more inconsistencies in the future. > >The fix is straightforward. Since we already have the “header_specified" variable to indicate whether the option is present, we can check “header_specified" instead. > >I reported a similar issue for the COPY command earlier in thread [1]. If this patch is accepted, then that one may be worth considering as well. > >[1] https://www.postgresql.org/message-id/C1D2509E-E5D1-46B0-932C-B57AA7B963A1%40gmail.com > >-- >Chao Li (Evan) >HighGo Software Co., Ltd. >https://www.highgo.com/ > > >
+1 for using presence over value.

The patch looks good to me.
Regards,
Tingchuan Sun

Re: Reject HEADER with binary and json COPY formats by option presence

От:
Chao Li <li.evan.chao@gmail.com>
Дата:


> On Jun 3, 2026, at 14:55, Fujii Masao  wrote:
> 
> On Wed, Jun 3, 2026 at 2:24 PM Shinya Kato  wrote:
>> 
>> On Sun, May 31, 2026 at 10:57 AM Chao Li  wrote:
>> 
>>> While testing “file_fdw: Support multi-line HEADER option”, I noticed a small issue.
>> 
>> Thanks for reporting this!
> 
> I'm not yet convinced that this needs a code change. We already seem to have
> both styles today: some options are rejected based on their presence,
> while others are effectively judged based on whether the specified value
> actually enables the feature. I don't think we have a clear rule that
> everything should be presence-based.
> 
> Regards,
> 
> -- 
> Fujii Masao

Okay, I withdraw this patch.

Best regards,
--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/






Re: Reject HEADER with binary and json COPY formats by option presence

От:
Fujii Masao <masao.fujii@gmail.com>
Дата:
On Wed, Jun 3, 2026 at 2:24 PM Shinya Kato  wrote:
>
> On Sun, May 31, 2026 at 10:57 AM Chao Li  wrote:
>
> > While testing “file_fdw: Support multi-line HEADER option”, I noticed a small issue.
>
> Thanks for reporting this!

I'm not yet convinced that this needs a code change. We already seem to have
both styles today: some options are rejected based on their presence,
while others are effectively judged based on whether the specified value
actually enables the feature. I don't think we have a clear rule that
everything should be presence-based.

Regards,

-- 
Fujii Masao


Re: Reject HEADER with binary and json COPY formats by option presence

От:
Shinya Kato <shinya11.kato@gmail.com>
Дата:
On Sun, May 31, 2026 at 10:57 AM Chao Li  wrote:

> While testing “file_fdw: Support multi-line HEADER option”, I noticed a small issue.

Thanks for reporting this!

> The fix is straightforward. Since we already have the “header_specified" variable to indicate whether the option is present, we can check “header_specified" instead.

Overall, the patch LGTM. Could you add COPY test cases like the following:

copy t to '/tmp/test.json' (format json, header 0);
copy t to '/tmp/test.bin' (format binary, header 0);

-- 
Best regards,
Shinya Kato
NTT OSS Center


Reject HEADER with binary and json COPY formats by option presence

От:
Chao Li <li.evan.chao@gmail.com>
Дата:
Hi,

While testing “file_fdw: Support multi-line HEADER option”, I noticed a small issue.

The doc says that the HEADER option cannot be used with the “binary" or “json" format:
```
   
    HEADER
    
     
      On output, if this option is set to true
      (or an equivalent Boolean value), the first line of the output will
      contain the column names from the table.
      Integer values 0 and 1 are
      accepted as Boolean values, but other integers are not allowed for
      COPY TO commands.
     
     
      On input, if this option is set to true
      (or an equivalent Boolean value), the first line of the input is
      discarded.  If set to a non-negative integer, that number of
      lines are discarded.  If set to MATCH, the first line
      is discarded, and it must contain column names that exactly match the
      table's columns, in both number and order; otherwise, an error is raised.
      The MATCH value is only valid for
      COPY FROM commands.
     
     
      This option is not allowed when using binary or json format.
     
    
   
```

However, when I specified "header ‘0", the command did not fail. That means the current behavior depends on the value of the “header" option, not on presence:
```
evantest=# create foreign table ft (i int) server fs options (format 'binary', filename '/tmp/ft.bin',  header '1');
ERROR:  cannot specify HEADER in BINARY mode
evantest=# create foreign table ft (i int) server fs options (format 'binary', filename '/tmp/ft.bin',  header '0');
CREATE FOREIGN TABLE
```

As we can see, "header 1" fails, but header 0" is silently accepted. I don't think this behavior matches what the documentation describes.

For comparison, VACUUM has a similar option. “BUFFER_USAGE_LIMIT" is not allowed with "VACUUM FULL", and a value of 0 means disabling the buffer access strategy:
```
   
    BUFFER_USAGE_LIMIT
    
     
      Specifies the
      Buffer Access Strategy
      ring buffer size for VACUUM.  This size is used to
      calculate the number of shared buffers which will be reused as part of
      this strategy.  0 disables use of a
      Buffer Access Strategy.  If 
      is also specified, the  value is used
      for both the vacuum and analyze stages.  This option can't be used with
      the  option except if  is
      also specified.  When this option is not specified,
      VACUUM uses the value from
      .  Higher settings can
      allow VACUUM to run more quickly, but having too
      large a setting may cause too many other useful pages to be evicted from
      shared buffers.  The minimum value is 128 kB and the
      maximum value is 16 GB.
     
    
   
```

Using BUFFER_USAGE_LIMIT 0 with FULL is still rejected:
```
evantest=# vacuum (full, BUFFER_USAGE_LIMIT 0) t;
ERROR:  BUFFER_USAGE_LIMIT cannot be specified for VACUUM FULL
```

So VACUUM rejects BUFFER_USAGE_LIMIT based on the presence of the option, not its value. I think we should keep the behavior consistent here, and VACUUM's behavior better matches the documentation. Otherwise, I am afraid this could encourage more inconsistencies in the future.

The fix is straightforward. Since we already have the “header_specified" variable to indicate whether the option is present, we can check “header_specified" instead.

I reported a similar issue for the COPY command earlier in thread [1]. If this patch is accepted, then that one may be worth considering as well.

[1] https://www.postgresql.org/message-id/C1D2509E-E5D1-46B0-932C-B57AA7B963A1%40gmail.com

--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/




FAQ