Skip to content

Simple queries are still prepared when setting search_path #943

Open
@firatoezcan

Description

@firatoezcan

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions