Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1voLQE-001l8k-0q for pgsql-hackers@arkaria.postgresql.org; Fri, 06 Feb 2026 12:58:54 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1voLQD-003ocE-18 for pgsql-hackers@arkaria.postgresql.org; Fri, 06 Feb 2026 12:58:53 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1voLQD-003oc6-08 for pgsql-hackers@lists.postgresql.org; Fri, 06 Feb 2026 12:58:52 +0000 Received: from mail-yw1-x1131.google.com ([2607:f8b0:4864:20::1131]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1voLQA-00000001Mbu-1rs7 for pgsql-hackers@lists.postgresql.org; Fri, 06 Feb 2026 12:58:52 +0000 Received: by mail-yw1-x1131.google.com with SMTP id 00721157ae682-794ed669269so33862887b3.1 for ; Fri, 06 Feb 2026 04:58:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1770382729; x=1770987529; darn=lists.postgresql.org; h=in-reply-to:references:subject:cc:to:from:message-id:date :content-transfer-encoding:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=RlDzC+iLkS/3GySLBruzhlggI9/JNp7FXYcjfl/lMdA=; b=IHMnZ4RYVdm2zohKlFRw6qJH/KRfEaQJPhMT1Yj/BZhhkXWr6ov/bd+kdMdnq72UBk cIaC5i02Yd51ST9VOkrz6AFxoUKYsXcsIZJ8nYniFcsYvnDXsBFmL95oYF8ZpzS3aUc0 TuPWE5vcmYYgm03kSVICGqAdo1XdJp5YUpMi3HkX0UGKywuIIP6yn84fKoKCtQQTxi2v kzF0dqMOml8yWAMALggeq33SD7t/g++0VKNc4esjZWU4Q+ufDNqi35UoK0Tuzx7JI8G5 uXwcb7XX69zU+U+i5JZUl9bEo5rdAsOIuL6xXRf7xRHGh8z2xYaXEEAAvzVEWtasDEpd ojsg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770382729; x=1770987529; h=in-reply-to:references:subject:cc:to:from:message-id:date :content-transfer-encoding:mime-version:x-gm-gg:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=RlDzC+iLkS/3GySLBruzhlggI9/JNp7FXYcjfl/lMdA=; b=FFKBoWxywm0mN7QkaOD8RYwBL9w+m8dB9SnTQsLA0nlTq4cpS4DvcGu54C+Ak8hDWZ W+qtFatyVWxPt+W2AtGKJNmdmXBE9qn4gwpNXnV183qXwwkphgb/gZ7UCQqLKCgk+Jls wwLjUVGFI/tlivVsVfnjY3V1O7vt/CXMOKT+bNns71shoToc0lKXrL6wEB8ryzv87p3r WtzK/XO8NXraBpYMdOpLbUUfAUSiA4nSVxzw+F4sZHwDHkJOr2btLc0dXa9PCWKC0+Jx pu5gqLBa0moAjnoemfyu/olRJTp16axQR0qEwUzuN5zgc2PEnZLWTN1vMO60Hsb+iH0t IkpA== X-Forwarded-Encrypted: i=1; AJvYcCUYfD81/OUZOb24zhnEw/2uxXLQW/sd10KYtiWKw8oa8zH3SXySYhKWx6Om4Ebx1LesvhIxbrk2PrwWGk5l@lists.postgresql.org X-Gm-Message-State: AOJu0YwFPXxCTwN3jfdL69+pezt7/+ewDzaCCPO2Fr+9+i7gjpXCmL9Z lxDODgRP2bakIewmdoYTgbmPCFyscXS0/wXsKsqlV5Cc1NKy7xr0d5Py X-Gm-Gg: AZuq6aIhNfm6AGbnS5ny0mNRxEWsRmHhTYe6YmEGvilB3qR4IBqmpc+Yz3C1H614dkN /PUfsZRb2z5355R4vfS4yoSIfNchoQi/KoRx5u8UBoWE3BrQuutWrWzeuH4x5hX/VaDL4aROdOy KJZyO+P2Kar+jhow3zFBOon2BYQlrXtJbNfDTt9KDNlf9jeg3qrjcc+L/3Dfw0jQPse5XrQU/t1 jD6ci/RMPQeSAjvYZKChZccoinTZM/VjuIc83m6okqVUsXzE7rV3A/XSF32411e0+DALH3rfPNj DiEZ5KT/hv6Zx3dyob4BNRnh1iSbIKHKBaL4we/Z0/ANUwVvbc0rPa7b4KVezmfhpDgG6F5dZhX bS1IYXIjknt3claC9T5SeTSzYfh+1QTfenYitjfmvv/1PNuKozZW2m8Q5n+zOVqioPdv0RvKKmB xd/G4E6fMbVDY6Qk1htgg+OupcwEFzhWBNDdIOriNkYr7ezQ== X-Received: by 2002:a05:690c:22c8:b0:795:905:c00e with SMTP id 00721157ae682-79514cac20dmr57348647b3.14.1770382729007; Fri, 06 Feb 2026 04:58:49 -0800 (PST) Received: from localhost ([2804:14d:328a:a59c:4d20:d883:f7a1:b34c]) by smtp.gmail.com with ESMTPSA id 00721157ae682-7952a057011sm20165997b3.17.2026.02.06.04.58.45 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 06 Feb 2026 04:58:48 -0800 (PST) Mime-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=UTF-8 Date: Fri, 06 Feb 2026 09:58:43 -0300 Message-Id: From: "Matheus Alcantara" To: "jian he" , "Matheus Alcantara" Cc: "torikoshia" , "Masahiko Sawada" , "vignesh C" , "Jim Jones" , "Kirill Reshke" , "Fujii Masao" , "David G. Johnston" , "Yugo NAGATA" , "PostgreSQL Hackers" Subject: Re: Change COPY ... ON_ERROR ignore to ON_ERROR ignore_row X-Mailer: aerc 0.21.0 References: <901967e5-e5dc-42c6-b2bf-fb3a49d7e787@gmail.com> <4c540fe3-495c-4bbf-8dcf-2c1e2b88bc3d@gmail.com> In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Fri Feb 6, 2026 at 12:40 AM -03, jian he wrote: >> Yeah, after some more thinking it seems ok to use both options >> together. I just found a bit strange when using integer columns. >> Consider this example: >> >> cat data.csv >> 1,11 >> 2,22 >> 3, >> 4,44 >> >> postgres=3D# create table t(a int not null, b int); >> CREATE TABLE >> >> postgres=3D# copy t from >> '/Users/matheus/dev/pgdev/copy-on-error-set-null/data.csv' with >> (FORCE_NOT_NULL(b), format csv, delimiter ',', ON_ERROR set_null); >> NOTICE: 1 row was replaced with null due to data type incompatibility >> COPY 4 >> >> postgres=3D# select * from t where b is null; >> a | b >> ---+--- >> 3 | >> (1 row) >> >> We are requiring a not null value on column b but we are still >> generating rows with null values on b. >> >> The reasoning on this is that the row 3 would generate a "invalid >> input syntax for type integer" error and the ON_ERROR set_null fix >> this by inserting a NULL value. It make sense I think but I'm >> wondering if it could cause any confusion? >> > > After careful reading the FORCE_NOT_NULL, FORCE_NULL option. > It's about dealing with empty value and NULL strings. > > copy t from stdin with(FORCE_NOT_NULL (b), format csv, delimiter ','); > Enter data to be copied followed by a newline. > End with a backslash and a period on a line by itself, or an EOF signal. >>> 1, >>> \. > ERROR: invalid input syntax for type integer: "" > CONTEXT: COPY t, line 1, column b: "" > > in this case, FORCE_NOT_NULL will convert the empty value to null > string (empty double quote) > > another FORCE_NULL. > copy t from stdin with(FORCE_NULL (b), format csv, delimiter ','); > Enter data to be copied followed by a newline. > End with a backslash and a period on a line by itself, or an EOF signal. >>> 1,"" >>> \. > COPY 1 > src9=3D# table t; > a | b > ---+--- > 1 | > (1 row) > > In this case, FORCE_NULL will convert null string (empty double quote) to= NULL. > > ON_ERROR explanation, the first sentence: > """ > Specifies how to behave when encountering an error converting a > column's input value into its data type. > """ > FORCE_NULL, FORCE_NOT_NULL is a special handling of input value, ON_ERROR= is > about converting the input value to data type, so it's before ON_ERROR. > > Overall the current doc is fine, IMHO. > Yeah, after also reading more carefully it's sounds correct to me too. > The attached patch has addressed your other points. > Thanks, overall the patch looks good to me. I'm attaching a diff with just some small tweaks on documentation and error messages. Please see and check if it's make sense. I'm wondering if we should have an else if block on CopyFromTextLikeOneRow() when cstate->cur_attval is NULL to handle COPY_ON_ERROR_SET_NULL when log_verbosity is set to COPY_LOG_VERBOSITY_VERBOSE if (cstate->opts.on_error =3D=3D COPY_ON_ERROR_IGNORE) ereport(NOTICE, errmsg("skipping row due to data type incompatibility at line %= " PRIu64 " for column \"%s\": null input", cstate->cur_lineno, cstate->cur_attname)); + else if (cstate->opts.on_error =3D=3D COPY_ON_ERROR_SET_NULL) + ereport(NOTICE, + errmsg("setting to null due to data type incompatibility at l= ine %" PRIu64 " for column \"%s\": null input", + cstate->cur_lineno, + cstate->cur_attname)); -- Matheus Alcantara EDB: https://www.enterprisedb.com