porsager / postgres

Postgres.js - The Fastest full featured PostgreSQL client for Node.js, Deno, Bun and CloudFlare

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Error while inserting a JSON array (if object contains the key "type")

VxRain opened this issue · comments

Hi, everyone,I encountered a strange phenomenon:
if the array object contains the key "type", an error occurs during insertion.

Reproduction Code

const postgres = require('postgres');
const sql = postgres('postgresql://xxxxxxxxxxxxxx', { max: 17 });

/**
AppPage DDL:
CREATE TABLE "public"."AppPage" (
  "id" int4 NOT NULL DEFAULT nextval('"AppPage_id_seq"'::regclass),
  "name" text COLLATE "pg_catalog"."default" NOT NULL,
  "desc" text COLLATE "pg_catalog"."default",
  "nodes" jsonb[] DEFAULT ARRAY[]::jsonb[],
  "pageSetId" int4,
  CONSTRAINT "AppPage_pkey" PRIMARY KEY ("id")
);
 */

async function main() {
  await sql`SELECT 1`;

  const title1 = 'test1';
  const desc1 = 'desc1';
  const nodes1 = [{ foo: 'bar' }];
  // ok
  await sql`INSERT INTO "AppPage" ("name", "desc", "nodes") VALUES (${title1}, ${desc1}, ${nodes1});`;

  const title2 = 'test2';
  const desc2 = 'desc2';
  const nodes2 = [{ type: 'bar' }];
  // If the object includes the type key, it will throw an error
  await sql`INSERT INTO "AppPage" ("name", "desc", "nodes") VALUES (${title2}, ${desc2}, ${nodes2});`;

  /**
  ERROR:
  ${workspace}\node_modules\.pnpm\postgres@3.4.4\node_modules\postgres\cjs\src\types.js:237
      .replace(escapeBackslash, '\\\\')
      ^

  TypeError: Cannot read properties of undefined (reading 'replace')
      at arrayEscape (${workspace}\node_modules\.pnpm\postgres@3.4.4\node_modules\postgres\cjs\src\types.js:237:6)
      at ${workspace}\node_modules\.pnpm\postgres@3.4.4\node_modules\postgres\cjs\src\types.js:264:15
      at Array.map (<anonymous>)
      at arraySerializer (${workspace}\node_modules\.pnpm\postgres@3.4.4\node_modules\postgres\cjs\src\types.js:255:19)
      at options.serializers.<computed> (${workspace}\node_modules\.pnpm\postgres@3.4.4\node_modules\postgres\cjs\src\connection.js:761:45)
      at ${workspace}\node_modules\.pnpm\postgres@3.4.4\node_modules\postgres\cjs\src\connection.js:934:36
      at Array.forEach (<anonymous>)
      at Bind (${workspace}\node_modules\.pnpm\postgres@3.4.4\node_modules\postgres\cjs\src\connection.js:928:16)
      at prepared (${workspace}\node_modules\.pnpm\postgres@3.4.4\node_modules\postgres\cjs\src\connection.js:204:7)
      at toBuffer (${workspace}\node_modules\.pnpm\postgres@3.4.4\node_modules\postgres\cjs\src\connection.js:190:15)
      at cachedError (${workspace}\node_modules\.pnpm\postgres@3.4.4\node_modules\postgres\cjs\src\query.js:170:23)
      at new Query (${workspace}\node_modules\.pnpm\postgres@3.4.4\node_modules\postgres\cjs\src\query.js:36:24)
      at sql (${workspace}\node_modules\.pnpm\postgres@3.4.4\node_modules\postgres\cjs\src\index.js:112:11)
      at main (${workspace}\postgres.js:30:12)
 */
}

main();

Env

Nodejs: v20.11.1
Postgres.js: 3.4.4
PostgreSQL: 15.3

I can replicate this but it manifests in a slightly different way. When I am trying to insert a object as JSON, the automatic string conversion fails when object contains a type field instead creating the string [Object object] vs the expected JSON string:

column "content" is of type json but expression is of type text, PostgresError, ERROR, ERROR, 42804, You will need to rewrite or cast the expression., 127, parse_target.c, 31, 10, 586, 10, /app/node_modules/postgres/src/errors.js, transformAssignedExpr, INSERT INTO logs ("id","actor_id","created_at","type","content","confirmed_at","collection_reference_id") VALUES ($1,$2,$3,$4,$5,$6,$7), 018fc991-4721-72f1-b58d-633942a9125d,user_01HRTCRHP9VX4B4TF0PN6TT3CR,1717073692449,collection.update,[object Object],1717073692721,018fb014-7b64-7a7e-89f9-941831e80310, [object Object],[object Object], 2950,25,20,25,25,20,2950

The architecture is a fully event based system were payloads are sent in a wrapper, the payloads which do not have type in the content field work fine.