porsager / postgres

Postgres.js - The Fastest full featured PostgreSQL client for Node.js, Deno, Bun and CloudFlare
The Unlicense
7.54k stars 273 forks source link

Simple queries are still prepared when setting search_path #943

Open firatoezcan opened 2 months ago

firatoezcan commented 2 months ago

Hey,

while building a tool for managing a multi-tenant database I've found behaviour that doesn't seem intended. It can be triggered by this minimal reproduction:

const postgres = require("postgres");

const sql = postgres(null, {
    host: "localhost",
    port: 5432,
    user: "postgres",
    password: "VUYmFyBt8FHZ4Sr3EdFcWSMc",
    database: "firatcms",
    prepare: false,
    connection: {
        // search_path: "project_aq940fcg89", // Commenting in this line breaks
    },
});

const run = async () => {
    // await sql`SET search_path TO project_aq940fcg89;`; // Commenting in this line breaks
    await sql`  CREATE TABLE IF NOT EXISTS "abc" (
        "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
        "version" int NOT NULL
    );
    ALTER TABLE "abc" DROP CONSTRAINT IF EXISTS "version_unique";
    ALTER TABLE "abc" ADD CONSTRAINT "version_unique" UNIQUE ("version");`.simple();
};

run().then(() => {
    sql.end();
});

The main issue is that I have a query with multiple statements in there and I'd expect it to be not prepared. Firstly because I set prepare: false but also because I added .simple(). In the real code, I use sql.unsafe without a second arg and I checked there that the produced query always has simple: true which is correct as it's based on whether I pass in arguments or not.

After trying it out a bit more, I've found that this issue only occurs when I have a search path set either via the connection or via SET search_path

I tried debugging it myself for an hour now but it's probably some Postgres internals that I don't understand good enough