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.94.2) (envelope-from ) id 1uu6SD-002HPg-3N for pgsql-admin@arkaria.postgresql.org; Thu, 04 Sep 2025 09:40:30 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1uu6SC-00EUoB-9T for pgsql-admin@arkaria.postgresql.org; Thu, 04 Sep 2025 09:40:28 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1uu6SB-00EUo3-TN for pgsql-admin@lists.postgresql.org; Thu, 04 Sep 2025 09:40:28 +0000 Received: from mail-pl1-x632.google.com ([2607:f8b0:4864:20::632]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1uu6SA-000U2K-23 for pgsql-admin@lists.postgresql.org; Thu, 04 Sep 2025 09:40:27 +0000 Received: by mail-pl1-x632.google.com with SMTP id d9443c01a7336-24457f581aeso9201055ad.0 for ; Thu, 04 Sep 2025 02:40:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1756978825; x=1757583625; darn=lists.postgresql.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=gX7IikTL+CYyOkzFR5fL/OJaUJ0jhqWu9m833bsUrRQ=; b=ZsDvpZvc4dcR4QmgonE31ZGw0oWRDuqJ/revAflRuaejqAua563jS4sTV2JxqFnnvg R0ywIehM6E92iYX2sQ+fXGBrPIMXwgN+G6qDp3f3T8jUIiuEP0m4DdEPAV4wUTf4JP8Z +RG78InpcDXv2fu89f8VAL9xzZ+y2pHGRenABdm7aHTf4SwnMprjndmt2ksbtW09Z63A TcX4/e0x6NVwPsEpBaAnHE8+HTW4S1WW+SUkVZ/AW7RWczQApd78/vzli5FKkGFDkhFl jv3FlhYdgIvaBfVetoek0uJRnHB+yqWRrpK9tfBQt7osvFA5SXH9u+M4w5NjHaREb9tl Mafg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1756978825; x=1757583625; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=gX7IikTL+CYyOkzFR5fL/OJaUJ0jhqWu9m833bsUrRQ=; b=tlwenKw2IkdJl92F9EuF/GOaz+qkQR7ChGQuQEjNEM7UhV7Dc2rFdOGwJFNcwY8XDN hfLHdfIzUx6Tb8GUz2gdUG7h8Wubbt+EKCrRupg+qfZFSn7cZiS9xTXo7bXtJDfcI14N 2e5mFTA3C1SoGCGmHMoJgOq8B13BkotYiAVrGhWiZhwn0FpgWlM2UOXan+nMtvUZFVwF uiYsiR95BvizTRqv2cFSwREoG13hPJrmstturY5ZP9VUbmY1j9F129tjU9u5bg+zHI6s Q/HxnpADO0ZvvUUWzLHrcGURE55JcC7qfipsz6Iyx0WZ+Q3x+r7t+OSLldOChxEPiynP /rnA== X-Gm-Message-State: AOJu0YxnqamdbsygmoqLYkc7kW4ve+gz9OJalAmysgoOV5A8Rv/XtAlD BW3H0+Rxl9TKZf11N5Cd8F5YcH2btqv+sg/Ja5/KTSbUl/66LD7Jjw6ubjKpMgTa6i+JGYtresv +03/B88C3EC3KjlPpueE7HY0oNKHmYvk= X-Gm-Gg: ASbGncu4gGIUsHONf2t5HxusGVPtBW6oW50eF1CJb1dhwihvKfJuKON4naksTZvu0h9 T2t0mwEb6quWOOtJtyNE72RM/qTB6Sh3NpCs2HiaE1wT0+P9bwN3bdZEo4SZSQ5dAWlHwiyaVWw Aor7pOD25WPOhn5MUWaCazzyhNnks+5xjsvVGQjoqTxHsxZFy3o+wdQzedN503Y0gIfW86CIknX nINRxUBASmBgI+0CQ== X-Google-Smtp-Source: AGHT+IFL86XeT8Rf1hJq9euiOId6jnjCspiWBecDKm6w4u1dDcrcQFm0GeBgSnsDmsAVMNnQ2WoXgDL7JEA/NE1AmkA= X-Received: by 2002:a17:903:37c5:b0:242:9bc4:f1ca with SMTP id d9443c01a7336-24944b71133mr218889225ad.57.1756978825320; Thu, 04 Sep 2025 02:40:25 -0700 (PDT) MIME-Version: 1.0 References: <8ec53dc7d4508410124a5a6d1442840aa90a8f0c.camel@cybertec.at> In-Reply-To: <8ec53dc7d4508410124a5a6d1442840aa90a8f0c.camel@cybertec.at> From: Edwin UY Date: Thu, 4 Sep 2025 21:39:46 +1200 X-Gm-Features: Ac12FXyu9F34TSgo5PHiMfQ8ZKX9WdIWFNJ0hPh72wISOqC9Bl5_q4rNgVsCM1M Message-ID: Subject: Re: Escaping special characters - \r when doing COPY CSV To: Laurenz Albe Cc: Pgsql-admin Content-Type: multipart/alternative; boundary="000000000000c2de14063df6826c" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --000000000000c2de14063df6826c Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Thanks Laurenz, any trick up your sleeves that will work for a select * instead of having to do it for individual columns On Thu, Sep 4, 2025 at 7:29=E2=80=AFPM Laurenz Albe wrote: > On Thu, 2025-09-04 at 18:01 +1200, Edwin UY wrote: > > I don't have access to run copy as this is a RDS database so I can only > use \copy. > > I need to send the output to csv. > > One of the fields has a special character =3D \r. I can see it visually= . > > > > Running the \copy below gives me extra row/s because of the \r > > \copy ( select * from blah where blah_ref =3D '666' order by > date_created desc limit 5; ) to 'abc.csv' WITH CSV DELIMITER ',' HEADER > > > > I have tried this > > \copy ( select * from blah where blah_ref =3D '666' order by > date_created desc limit 5; ) to 'abc.csv' WITH (FORMAT CSV, HEADER, ESCA= PE > '\r'); > > > > But it gives ERROR: COPY escape must be a single one-byte character. > > > > Besides using a view for the SQL, as suggested when I do a web search, > any chance someone here knows how to do it without using a view? > > There is no problem with having the carriage return characters in the CSV > output, > but if you'd rather do without them, you could trim them: > > \copy (SELECT trim(textcol, E'\u000d'), othercol, ... FROM tab ...) TO > ... > > In order to include escape sequences into a string literal, you have to > prepend > the opening single quote with an "E" for "extended": > > E'\r' > E'\x0D' > E'\u000D' > E'\U0000000D' > > Yours, > Laurenz Albe > --000000000000c2de14063df6826c Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Thanks Laurenz, any trick up your sleeves that will work f= or a select * instead of having to do it for individual columns=C2=A0
=
On Thu, Sep 4, 2025 at 7:29=E2=80=AFPM Laurenz Albe <laurenz.albe@cybertec.at> w= rote:
On Thu, 20= 25-09-04 at 18:01 +1200, Edwin UY wrote:
> I don't have access to run copy as this is a RDS database so I can= only use \copy.
> I need to send the output to csv.
> One of the fields has a special character =3D \r. I can see it visuall= y.
>
> Running the \copy below gives me extra row/s because of the \r
> \copy ( select *=C2=A0 from blah=C2=A0 where blah_ref =3D '666'= ;=C2=A0=C2=A0 order by date_created desc=C2=A0=C2=A0limit 5; )=C2=A0to '= ;abc.csv' WITH CSV DELIMITER ',' HEADER
>
> I have tried this
> \copy ( select *=C2=A0 from blah=C2=A0 where blah_ref =3D '666'= ;=C2=A0=C2=A0 order by date_created desc=C2=A0=C2=A0limit 5; )=C2=A0to '= ;abc.csv' WITH (FORMAT CSV, HEADER, ESCAPE '\r');
>
> But it gives ERROR: =C2=A0COPY escape must be a single one-byte charac= ter.
>
> Besides using a view for the SQL, as suggested when I do a web search,= any chance someone here knows how to do it without=C2=A0using a view?

There is no problem with having the carriage return characters in the CSV o= utput,
but if you'd rather do without them, you could trim them:

=C2=A0 \copy (SELECT trim(textcol, E'\u000d'), othercol, ... FROM t= ab ...) TO ...

In order to include escape sequences into a string literal, you have to pre= pend
the opening single quote with an "E" for "extended":
=C2=A0 E'\r'
=C2=A0 E'\x0D'
=C2=A0 E'\u000D'
=C2=A0 E'\U0000000D'

Yours,
Laurenz Albe
--000000000000c2de14063df6826c--