### What does this PR do?

Fixes #20729

### How did you verify your code works?

There is a test

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
Jarred Sumner
2025-08-22 03:41:49 -07:00
committed by GitHub
parent cca10d4530
commit 0e37dc4e78
3 changed files with 109 additions and 12 deletions

View File

@@ -272,14 +272,11 @@ declare module "bun" {
*/
ssl?: TLSOptions | boolean | undefined;
// `.path` is currently unsupported in Bun, the implementation is
// incomplete.
//
// /**
// * Unix domain socket path for connection
// * @default ""
// */
// path?: string | undefined;
/**
* Unix domain socket path for connection
* @default undefined
*/
path?: string | undefined;
/**
* Callback executed when a connection attempt completes

View File

@@ -305,7 +305,7 @@ function parseOptions(
onclose: ((client: Bun.SQL) => void) | undefined,
max: number | null | undefined,
bigint: boolean | undefined,
path: string | string[],
path: string,
adapter: Bun.SQL.__internal.Adapter;
let prepare = true;
@@ -421,9 +421,19 @@ function parseOptions(
port ||= Number(options.port || env.PGPORT || (adapter === "mysql" ? 3306 : 5432));
path ||= (options as { path?: string }).path || "";
// add /.s.PGSQL.${port} if it doesn't exist
if (path && path?.indexOf("/.s.PGSQL.") === -1 && adapter === "postgres") {
path = `${path}/.s.PGSQL.${port}`;
if (adapter === "postgres") {
// add /.s.PGSQL.${port} if the unix domain socket is listening on that path
if (path && Number.isSafeInteger(port) && path?.indexOf("/.s.PGSQL.") === -1) {
const pathWithSocket = `${path}/.s.PGSQL.${port}`;
// Only add the path if it actually exists. It would be better to just
// always respect whatever the user passes in, but that would technically
// be a breakpoint change at this point.
if (require("node:fs").existsSync(pathWithSocket)) {
path = pathWithSocket;
}
}
}
username ||=
@@ -579,6 +589,12 @@ function parseOptions(
ret.onclose = onclose;
}
if (path) {
if (require("node:fs").existsSync(path)) {
ret.path = path;
}
}
return ret;
}

View File

@@ -147,9 +147,88 @@ if (isDockerEnabled()) {
// --- Expected pg_hba.conf ---
process.env.DATABASE_URL = `postgres://bun_sql_test@localhost:${container.port}/bun_sql_test`;
const net = require("node:net");
const fs = require("node:fs");
const path = require("node:path");
const os = require("node:os");
// Create a temporary unix domain socket path
const socketPath = path.join(os.tmpdir(), `postgres_echo_${Date.now()}.sock`);
// Clean up any existing socket file
try {
fs.unlinkSync(socketPath);
} catch {}
// Create a unix domain socket server that proxies to the PostgreSQL container
const socketServer = net.createServer(clientSocket => {
console.log("PostgreSQL connection received on unix socket");
// Create connection to the actual PostgreSQL container
const containerSocket = net.createConnection({
host: login.host,
port: login.port,
});
// Handle container connection
containerSocket.on("connect", () => {
console.log("Connected to PostgreSQL container");
});
containerSocket.on("error", err => {
console.error("Container connection error:", err);
clientSocket.destroy();
});
containerSocket.on("close", () => {
console.log("Container connection closed");
clientSocket.end();
});
// Handle client socket
clientSocket.on("data", data => {
// Forward client data to container
containerSocket.write(data);
});
clientSocket.on("error", err => {
console.error("Client socket error:", err);
containerSocket.destroy();
});
clientSocket.on("close", () => {
console.log("Client connection closed");
containerSocket.end();
});
// Forward container responses back to client
containerSocket.on("data", data => {
clientSocket.write(data);
});
});
socketServer.listen(socketPath, () => {
console.log(`Unix domain socket server listening on ${socketPath}`);
});
// Clean up the socket on exit
afterAll(() => {
socketServer.close();
try {
fs.unlinkSync(socketPath);
} catch {}
});
const login: Bun.SQL.PostgresOrMySQLOptions = {
username: "bun_sql_test",
port: container.port,
path: socketPath,
};
const login_domain_socket: Bun.SQL.PostgresOrMySQLOptions = {
username: "bun_sql_test",
port: container.port,
path: socketPath,
};
const login_md5: Bun.SQL.PostgresOrMySQLOptions = {
@@ -1036,6 +1115,11 @@ if (isDockerEnabled()) {
expect((await sql`select true as x`)[0].x).toBe(true);
});
test("unix domain socket can send query", async () => {
await using sql = postgres({ ...options, ...login_domain_socket });
expect((await sql`select true as x`)[0].x).toBe(true);
});
test("Login using MD5", async () => {
await using sql = postgres({ ...options, ...login_md5 });
expect(await sql`select true as x`).toEqual([{ x: true }]);