Compare commits

...

14 Commits

Author SHA1 Message Date
Jarred Sumner
750502b330 Update MySQLConnection.zig 2025-09-11 03:16:10 -07:00
Jarred Sumner
2f0307b3d6 Update MySQLConnection.zig 2025-09-11 03:15:12 -07:00
Jarred Sumner
12c36a9852 Update MySQLConnection.zig 2025-09-11 03:03:24 -07:00
Jarred Sumner
7bd828bdf9 Update MySQLConnection.zig 2025-09-11 02:57:42 -07:00
Jarred Sumner
f2498ffe19 try this 2025-09-11 02:23:11 -07:00
Jarred Sumner
e59b34a7b8 Update runner.node.mjs 2025-09-11 01:23:06 -07:00
Jarred Sumner
ae1e6ddcc2 Update MySQLConnection.zig 2025-09-11 01:16:09 -07:00
Jarred Sumner
a50183ae60 Update MySQLConnection.zig 2025-09-11 01:03:45 -07:00
Jarred Sumner
aadf38c1c6 Update MySQLConnection.zig 2025-09-11 01:03:26 -07:00
Jarred Sumner
a00c0d5232 try this 2025-09-11 00:09:35 -07:00
Jarred Sumner
b827d3d87c try this 2025-09-10 23:06:48 -07:00
Jarred Sumner
aa9c3c1a3e Update JSRef.zig 2025-09-10 21:56:52 -07:00
Jarred Sumner
bded3385c1 Try this 2025-09-10 21:35:31 -07:00
Jarred Sumner
142296257e Try clearing Strong earlier 2025-09-10 21:31:43 -07:00
14 changed files with 152 additions and 114 deletions

View File

@@ -1087,6 +1087,7 @@ async function spawnBun(execPath, { args, cwd, timeout, env, stdout, stderr }) {
BUN_JSC_randomIntegrityAuditRate: "1.0",
BUN_RUNTIME_TRANSPILER_CACHE_PATH: "0",
BUN_INSTALL_CACHE_DIR: tmpdirPath,
SHELLOPTS: isWindows ? "igncr" : undefined, // ignore "\r" on Windows
TEST_TMPDIR: tmpdirPath, // Used in Node.js tests.
...(typeof remapPort == "number"

View File

@@ -84,6 +84,8 @@ pub const Optional = struct {
const impl = strong.impl orelse return .zero;
const result = impl.get();
if (result == .zero) {
strong.impl = null;
impl.deinit();
return .zero;
}
impl.clear();

View File

@@ -1,6 +1,6 @@
import { define } from "../../codegen/class-definitions";
const types = ["PostgresSQL", "MySQL"];
const types = ["PostgresSQL", "MySQL"] as const;
const classes = [];
for (const type of types) {
classes.push(
@@ -9,7 +9,7 @@ for (const type of types) {
construct: true,
finalize: true,
configurable: false,
hasPendingActivity: true,
hasPendingActivity: type === "PostgresSQL",
klass: {
// escapeString: {
// fn: "escapeString",

View File

@@ -15,7 +15,7 @@ pub const JSRef = union(enum) {
return .{ .weak = .zero };
}
pub fn get(this: *@This()) jsc.JSValue {
pub fn get(this: *const @This()) jsc.JSValue {
return switch (this.*) {
.weak => this.weak,
.strong => this.strong.get() orelse .zero,
@@ -23,7 +23,7 @@ pub const JSRef = union(enum) {
};
}
pub fn tryGet(this: *@This()) ?jsc.JSValue {
pub fn tryGet(this: *const @This()) ?jsc.JSValue {
return switch (this.*) {
.weak => if (this.weak != .zero) this.weak else null,
.strong => this.strong.get(),
@@ -64,6 +64,21 @@ pub const JSRef = union(enum) {
}
}
pub fn downgrade(this: *@This()) void {
switch (this.*) {
.weak => {},
.strong => {
if (this.strong.trySwap()) |strong| {
bun.debugAssert(strong != .zero);
this.* = .{ .weak = strong };
}
},
.finalized => {},
}
}
pub const finalize = deinit;
pub fn deinit(this: *@This()) void {
switch (this.*) {
.weak => {

View File

@@ -441,13 +441,19 @@ extern "C" EncodedJSValue JSC__createStructure(JSC::JSGlobalObject* globalObject
if (name.isNamedColumn()) {
propertyNames.add(Identifier::fromString(vm, name.name.toWTFString()));
}
if (name.isIndexedColumn()) {
return encodedJSValue();
}
nonDuplicateCount += !name.isDuplicateColumn();
if (nonDuplicateCount == JSFinalObject::maxInlineCapacity) {
break;
}
}
Structure* structure = globalObject->structureCache().emptyObjectStructureForPrototype(globalObject, globalObject->objectPrototype(), nonDuplicateCount);
ASSERT_WITH_MESSAGE(nonDuplicateCount < JSFinalObject::maxInlineCapacity, "expected nonDuplicateCount %u to be less than maxInlineCapacity %u", nonDuplicateCount, JSFinalObject::maxInlineCapacity);
Structure* structure = Structure::create(vm, globalObject, globalObject->objectPrototype(), JSFinalObject::typeInfo(), JSFinalObject::info(), NonArray, nonDuplicateCount);
if (owner) {
vm.writeBarrier(owner, structure);
} else {

View File

@@ -21,8 +21,7 @@ poll_ref: bun.Async.KeepAlive = .{},
globalObject: *jsc.JSGlobalObject,
vm: *jsc.VirtualMachine,
pending_activity_count: std.atomic.Value(u32) = std.atomic.Value(u32).init(0),
js_value: JSValue = .js_undefined,
js_value: jsc.JSRef = .empty(),
server_version: bun.ByteList = .{},
connection_id: u32 = 0,
@@ -122,14 +121,16 @@ pub const AuthState = union(enum) {
};
};
pub fn hasPendingActivity(this: *MySQLConnection) bool {
return this.pending_activity_count.load(.acquire) > 0;
}
fn updateHasPendingActivity(this: *MySQLConnection) void {
if (this.js_value == .finalized) return;
const a: u32 = if (this.requests.readableLength() > 0) 1 else 0;
const b: u32 = if (this.status != .disconnected) 1 else 0;
this.pending_activity_count.store(a + b, .release);
const c: u32 = if (this.socket.isClosed()) 0 else 1;
if (a + b + c == 0) {
this.js_value.downgrade();
} else {
this.js_value.upgrade(this.globalObject);
}
}
fn hasDataToSend(this: *@This()) bool {
@@ -265,27 +266,34 @@ fn drainInternal(this: *@This()) void {
}
}
pub fn finalize(this: *MySQLConnection) void {
this.stopTimers();
debug("MySQLConnection finalize", .{});
this.js_value.finalize();
this.stopTimers();
// Ensure we disconnect before finalizing
if (this.status != .disconnected) {
this.disconnect();
}
this.js_value = .zero;
this.deref();
}
pub fn doRef(this: *@This(), _: *jsc.JSGlobalObject, _: *jsc.CallFrame) bun.JSError!JSValue {
this.poll_ref.ref(this.vm);
if (!this.socket.isClosed()) {
this.poll_ref.ref(this.vm);
}
this.updateHasPendingActivity();
return .js_undefined;
}
pub fn doUnref(this: *@This(), _: *jsc.JSGlobalObject, _: *jsc.CallFrame) bun.JSError!JSValue {
this.poll_ref.unref(this.vm);
this.updateHasPendingActivity();
return .js_undefined;
}
@@ -309,6 +317,7 @@ pub fn getConnected(this: *MySQLConnection, _: *jsc.JSGlobalObject) JSValue {
pub fn doClose(this: *MySQLConnection, globalObject: *jsc.JSGlobalObject, _: *jsc.CallFrame) bun.JSError!JSValue {
_ = globalObject;
this.disconnect();
this.write_buffer.clearAndFree(bun.default_allocator);
return .js_undefined;
@@ -351,8 +360,8 @@ pub fn stopTimers(this: *@This()) void {
}
}
pub fn getQueriesArray(this: *const @This()) JSValue {
return js.queriesGetCached(this.js_value) orelse .js_undefined;
pub fn getQueriesArray(this: *@This()) JSValue {
return js.queriesGetCached(this.js_value.tryGet() orelse return .js_undefined) orelse .js_undefined;
}
pub fn failFmt(this: *@This(), error_code: AnyMySQLError.Error, comptime fmt: [:0]const u8, args: anytype) void {
const message = bun.handleOom(std.fmt.allocPrint(bun.default_allocator, fmt, args));
@@ -362,77 +371,85 @@ pub fn failFmt(this: *@This(), error_code: AnyMySQLError.Error, comptime fmt: [:
this.failWithJSValue(err);
}
pub fn failWithJSValue(this: *MySQLConnection, value: JSValue) void {
this.ref();
defer this.deref();
defer this.updateHasPendingActivity();
this.stopTimers();
if (this.status == .failed) return;
this.setStatus(.failed);
this.ref();
defer this.deref();
this.setStatus(.failed);
const js_value = this.js_value.tryGet() orelse return;
const globalObject = this.globalObject;
// we defer the refAndClose so the on_close will be called first before we reject the pending requests
defer this.refAndClose(value);
const on_close = this.consumeOnCloseCallback(this.globalObject) orelse return;
const on_close = this.consumeOnCloseCallback(globalObject) orelse return;
const loop = this.vm.eventLoop();
loop.enter();
defer loop.exit();
_ = on_close.call(
this.globalObject,
this.js_value,
globalObject,
js_value,
&[_]JSValue{
value,
this.getQueriesArray(),
},
) catch |e| this.globalObject.reportActiveExceptionAsUnhandled(e);
) catch |e| globalObject.reportActiveExceptionAsUnhandled(e);
this.closeWithReason(js_value);
}
const FinalizeRequests = struct {
connection: *MySQLConnection,
task: jsc.AnyTask,
pub fn run(this: *FinalizeRequests) void {
defer {
this.connection.deref();
bun.destroy(this);
}
this.connection.cleanUpRequests(null);
}
};
pub fn fail(this: *MySQLConnection, message: []const u8, err: AnyMySQLError.Error) void {
debug("failed: {s}: {s}", .{ message, @errorName(err) });
if (this.js_value == .finalized) {
if (!this.flags.is_finalizing_requests and this.requests.readableLength() > 0) {
this.flags.is_finalizing_requests = true;
const finalize_requests = bun.new(FinalizeRequests, .{
.connection = this,
.task = undefined,
});
finalize_requests.task = jsc.AnyTask.New(FinalizeRequests, FinalizeRequests.run).init(finalize_requests);
this.vm.eventLoop().enqueueTask(jsc.Task.init(&finalize_requests.task));
}
return;
}
const instance = AnyMySQLError.mysqlErrorToJS(this.globalObject, message, err);
this.failWithJSValue(instance);
}
pub fn onClose(this: *MySQLConnection) void {
var vm = this.vm;
defer vm.drainMicrotasks();
this.poll_ref.disable();
this.setStatus(.disconnected);
this.fail("Connection closed", error.ConnectionClosed);
this.updateHasPendingActivity();
}
fn refAndClose(this: *@This(), js_reason: ?jsc.JSValue) void {
// refAndClose is always called when we wanna to disconnect or when we are closed
if (!this.socket.isClosed()) {
// event loop need to be alive to close the socket
this.poll_ref.ref(this.vm);
// will unref on socket close
this.socket.close();
}
// cleanup requests
fn closeWithReason(this: *@This(), js_reason: ?jsc.JSValue) void {
this.cleanUpRequests(js_reason);
this.socket.close();
}
pub fn disconnect(this: *@This()) void {
this.poll_ref.disable();
this.stopTimers();
if (this.status == .connected) {
this.setStatus(.disconnected);
this.poll_ref.disable();
const requests = this.requests.readableSlice(0);
this.requests.head = 0;
this.requests.count = 0;
// Fail any pending requests
for (requests) |request| {
this.finishRequest(request);
request.onError(.{
.error_code = 2013, // CR_SERVER_LOST
.error_message = .{ .temporary = "Lost connection to MySQL server" },
}, this.globalObject);
}
this.socket.close();
}
this.cleanUpRequests(null);
this.socket.close();
this.updateRef();
}
fn finishRequest(this: *@This(), item: *MySQLQuery) void {
@@ -705,6 +722,7 @@ fn SocketHandler(comptime ssl: bool) type {
return Socket{ .SocketTCP = s };
}
pub fn onOpen(this: *MySQLConnection, socket: SocketType) void {
this.socket = _socket(socket);
this.onOpen(_socket(socket));
}
@@ -715,32 +733,32 @@ fn SocketHandler(comptime ssl: bool) type {
pub const onHandshake = if (ssl) onHandshake_ else null;
pub fn onClose(this: *MySQLConnection, socket: SocketType, _: i32, _: ?*anyopaque) void {
_ = socket;
this.socket = _socket(socket);
this.onClose();
}
pub fn onEnd(this: *MySQLConnection, socket: SocketType) void {
_ = socket;
this.onClose();
this.socket = _socket(socket);
socket.close(.normal);
}
pub fn onConnectError(this: *MySQLConnection, socket: SocketType, _: i32) void {
_ = socket;
this.socket = _socket(socket);
this.onClose();
}
pub fn onTimeout(this: *MySQLConnection, socket: SocketType) void {
_ = socket;
this.socket = _socket(socket);
this.onTimeout();
}
pub fn onData(this: *MySQLConnection, socket: SocketType, data: []const u8) void {
_ = socket;
this.socket = _socket(socket);
this.onData(data);
}
pub fn onWritable(this: *MySQLConnection, socket: SocketType) void {
_ = socket;
this.socket = _socket(socket);
this.onDrain();
}
};
@@ -937,13 +955,16 @@ pub fn call(globalObject: *jsc.JSGlobalObject, callframe: *jsc.CallFrame) bun.JS
};
}
}
ptr.setStatus(.connecting);
ptr.updateHasPendingActivity();
ptr.resetConnectionTimeout();
ptr.poll_ref.ref(vm);
const js_value = ptr.toJS(globalObject);
js_value.ensureStillAlive();
ptr.js_value = js_value;
ptr.js_value.setStrong(js_value, globalObject);
ptr.setStatus(.connecting);
ptr.updateHasPendingActivity();
ptr.resetConnectionTimeout();
js.onconnectSetCached(js_value, globalObject, on_connect);
js.oncloseSetCached(js_value, globalObject, on_close);
@@ -1270,18 +1291,20 @@ fn handleHandshakeDecodePublicKey(this: *MySQLConnection, comptime Context: type
pub fn consumeOnConnectCallback(this: *const @This(), globalObject: *jsc.JSGlobalObject) ?jsc.JSValue {
debug("consumeOnConnectCallback", .{});
const on_connect = js.onconnectGetCached(this.js_value) orelse return null;
const this_value = this.js_value.tryGet() orelse return null;
const on_connect = js.onconnectGetCached(this_value) orelse return null;
debug("consumeOnConnectCallback exists", .{});
js.onconnectSetCached(this.js_value, globalObject, .zero);
js.onconnectSetCached(this_value, globalObject, .zero);
return on_connect;
}
pub fn consumeOnCloseCallback(this: *const @This(), globalObject: *jsc.JSGlobalObject) ?jsc.JSValue {
debug("consumeOnCloseCallback", .{});
const on_close = js.oncloseGetCached(this.js_value) orelse return null;
const this_value = this.js_value.tryGet() orelse return null;
const on_close = js.oncloseGetCached(this_value) orelse return null;
debug("consumeOnCloseCallback exists", .{});
js.oncloseSetCached(this.js_value, globalObject, .zero);
js.oncloseSetCached(this_value, globalObject, .zero);
return on_close;
}
@@ -1291,15 +1314,20 @@ pub fn setStatus(this: *@This(), status: ConnectionState) void {
this.status = status;
this.resetConnectionTimeout();
if (this.vm.isShuttingDown()) return;
if (this.vm.isShuttingDown()) {
this.poll_ref.disable();
return;
}
switch (status) {
.connected => {
const on_connect = this.consumeOnConnectCallback(this.globalObject) orelse return;
const js_value = this.js_value;
const js_value = this.js_value.tryGet() orelse return;
js_value.ensureStillAlive();
this.globalObject.queueMicrotask(on_connect, &[_]JSValue{ JSValue.jsNull(), js_value });
this.poll_ref.unref(this.vm);
},
.disconnected, .failed => {
this.poll_ref.disable();
},
else => {},
}
@@ -1307,11 +1335,6 @@ pub fn setStatus(this: *@This(), status: ConnectionState) void {
pub fn updateRef(this: *@This()) void {
this.updateHasPendingActivity();
if (this.pending_activity_count.raw > 0) {
this.poll_ref.ref(this.vm);
} else {
this.poll_ref.unref(this.vm);
}
}
pub fn handleAuth(this: *MySQLConnection, comptime Context: type, reader: NewReader(Context), header_length: u24) !void {
const first_byte = try reader.int(u8);
@@ -1765,7 +1788,7 @@ fn handleResultSetOK(this: *MySQLConnection, request: *MySQLQuery, statement: *M
request.onResult(
statement.result_count,
this.globalObject,
this.js_value,
this.js_value.tryGet() orelse return,
this.flags.is_ready_for_query,
last_insert_id,
affected_rows,
@@ -1871,10 +1894,10 @@ pub fn handleResultSet(this: *MySQLConnection, comptime Context: type, reader: N
.bigint = request.flags.bigint,
};
var structure: JSValue = .js_undefined;
var cached_structure: ?CachedStructure = null;
var cached_structure: ?*CachedStructure = null;
switch (request.flags.result_mode) {
.objects => {
cached_structure = statement.structure(this.js_value, this.globalObject);
cached_structure = statement.structure(this.js_value.tryGet() orelse return, this.globalObject);
structure = cached_structure.?.jsValue() orelse .js_undefined;
},
.raw, .values => {

View File

@@ -66,11 +66,7 @@ pub fn finalize(this: *@This()) void {
this.statement = null;
}
if (this.thisValue == .weak) {
// clean up if is a weak reference, if is a strong reference we need to wait until the query is done
// if we are a strong reference, here is probably a bug because GC'd should not happen
this.thisValue.weak = .zero;
}
this.thisValue.finalize();
this.deref();
}
@@ -82,7 +78,7 @@ pub fn onWriteFail(
) void {
this.status = .fail;
const thisValue = this.thisValue.get();
defer this.thisValue.deinit();
defer this.thisValue.downgrade();
const targetValue = this.getTarget(globalObject, true);
if (thisValue == .zero or targetValue == .zero) {
return;
@@ -168,7 +164,7 @@ pub fn onJSError(this: *@This(), err: jsc.JSValue, globalObject: *jsc.JSGlobalOb
defer this.deref();
this.status = .fail;
const thisValue = this.thisValue.get();
defer this.thisValue.deinit();
defer this.thisValue.downgrade();
const targetValue = this.getTarget(globalObject, true);
if (thisValue == .zero or targetValue == .zero) {
return;
@@ -227,8 +223,7 @@ pub fn onResult(this: *@This(), result_count: u64, globalObject: *jsc.JSGlobalOb
this.status = .partial_response;
}
defer if (is_last) {
allowGC(thisValue, globalObject);
this.thisValue.deinit();
this.thisValue.downgrade();
};
if (thisValue == .zero or targetValue == .zero) {
return;
@@ -324,9 +319,9 @@ pub fn call(globalThis: *jsc.JSGlobalObject, callframe: *jsc.CallFrame) bun.JSEr
return this_value;
}
pub fn setPendingValue(this: *@This(), globalObject: *jsc.JSGlobalObject, callframe: *jsc.CallFrame) bun.JSError!JSValue {
pub fn setPendingValue(_: *@This(), globalObject: *jsc.JSGlobalObject, callframe: *jsc.CallFrame) bun.JSError!JSValue {
const result = callframe.argument(0);
const thisValue = this.thisValue.tryGet() orelse return .js_undefined;
const thisValue = callframe.this();
js.pendingValueSetCached(thisValue, globalObject, result);
return .js_undefined;
}

View File

@@ -103,9 +103,9 @@ pub fn checkForDuplicateFields(this: *@This()) void {
this.fields_flags = flags;
}
pub fn structure(this: *MySQLStatement, owner: JSValue, globalObject: *jsc.JSGlobalObject) CachedStructure {
pub fn structure(this: *MySQLStatement, owner: JSValue, globalObject: *jsc.JSGlobalObject) *CachedStructure {
if (this.cached_structure.has()) {
return this.cached_structure;
return &this.cached_structure;
}
this.checkForDuplicateFields();
@@ -155,7 +155,7 @@ pub fn structure(this: *MySQLStatement, owner: JSValue, globalObject: *jsc.JSGlo
), null);
}
return this.cached_structure;
return &this.cached_structure;
}
pub const Param = struct {
type: types.FieldType,

View File

@@ -8,7 +8,7 @@ pub const Row = struct {
bigint: bool = false,
globalObject: *jsc.JSGlobalObject,
pub fn toJS(this: *Row, globalObject: *jsc.JSGlobalObject, array: JSValue, structure: JSValue, flags: SQLDataCell.Flags, result_mode: SQLQueryResultMode, cached_structure: ?CachedStructure) JSValue {
pub fn toJS(this: *Row, globalObject: *jsc.JSGlobalObject, array: JSValue, structure: JSValue, flags: SQLDataCell.Flags, result_mode: SQLQueryResultMode, cached_structure: ?*const CachedStructure) JSValue {
var names: ?[*]jsc.JSObject.ExternColumnIdentifier = null;
var names_count: u32 = 0;
if (cached_structure) |c| {

View File

@@ -902,7 +902,7 @@ pub const Putter = struct {
count: usize = 0,
globalObject: *jsc.JSGlobalObject,
pub fn toJS(this: *Putter, globalObject: *jsc.JSGlobalObject, array: JSValue, structure: JSValue, flags: SQLDataCell.Flags, result_mode: PostgresSQLQueryResultMode, cached_structure: ?PostgresCachedStructure) JSValue {
pub fn toJS(this: *Putter, globalObject: *jsc.JSGlobalObject, array: JSValue, structure: JSValue, flags: SQLDataCell.Flags, result_mode: PostgresSQLQueryResultMode, cached_structure: ?*PostgresCachedStructure) JSValue {
var names: ?[*]jsc.JSObject.ExternColumnIdentifier = null;
var names_count: u32 = 0;
if (cached_structure) |c| {

View File

@@ -1362,7 +1362,7 @@ pub fn on(this: *PostgresSQLConnection, comptime MessageType: @Type(.enum_litera
var statement = request.statement orelse return error.ExpectedStatement;
var structure: JSValue = .js_undefined;
var cached_structure: ?PostgresCachedStructure = null;
var cached_structure: ?*PostgresCachedStructure = null;
// explicit use switch without else so if new modes are added, we don't forget to check for duplicate fields
switch (request.flags.result_mode) {
.objects => {

View File

@@ -67,11 +67,7 @@ pub fn deinit(this: *@This()) void {
pub fn finalize(this: *@This()) void {
debug("PostgresSQLQuery finalize", .{});
if (this.thisValue == .weak) {
// clean up if is a weak reference, if is a strong reference we need to wait until the query is done
// if we are a strong reference, here is probably a bug because GC'd should not happen
this.thisValue.weak = .zero;
}
this.thisValue.finalize();
this.deref();
}
@@ -85,7 +81,7 @@ pub fn onWriteFail(
defer this.deref();
this.status = .fail;
const thisValue = this.thisValue.get();
defer this.thisValue.deinit();
defer this.thisValue.downgrade();
const targetValue = this.getTarget(globalObject, true);
if (thisValue == .zero or targetValue == .zero) {
return;
@@ -106,7 +102,7 @@ pub fn onJSError(this: *@This(), err: jsc.JSValue, globalObject: *jsc.JSGlobalOb
defer this.deref();
this.status = .fail;
const thisValue = this.thisValue.get();
defer this.thisValue.deinit();
defer this.thisValue.downgrade();
const targetValue = this.getTarget(globalObject, true);
if (thisValue == .zero or targetValue == .zero) {
return;
@@ -154,8 +150,7 @@ pub fn onResult(this: *@This(), command_tag_str: []const u8, globalObject: *jsc.
this.status = .partial_response;
}
defer if (is_last) {
allowGC(thisValue, globalObject);
this.thisValue.deinit();
this.thisValue.downgrade();
};
if (thisValue == .zero or targetValue == .zero) {
return;
@@ -257,9 +252,9 @@ pub fn doDone(this: *@This(), globalObject: *jsc.JSGlobalObject, _: *jsc.CallFra
this.flags.is_done = true;
return .js_undefined;
}
pub fn setPendingValue(this: *PostgresSQLQuery, globalObject: *jsc.JSGlobalObject, callframe: *jsc.CallFrame) bun.JSError!JSValue {
pub fn setPendingValue(_: *PostgresSQLQuery, globalObject: *jsc.JSGlobalObject, callframe: *jsc.CallFrame) bun.JSError!JSValue {
const result = callframe.argument(0);
const thisValue = this.thisValue.tryGet() orelse return .js_undefined;
const thisValue = callframe.this();
js.pendingValueSetCached(thisValue, globalObject, result);
return .js_undefined;
}

View File

@@ -107,9 +107,9 @@ pub fn deinit(this: *PostgresSQLStatement) void {
bun.default_allocator.destroy(this);
}
pub fn structure(this: *PostgresSQLStatement, owner: JSValue, globalObject: *jsc.JSGlobalObject) PostgresCachedStructure {
pub fn structure(this: *PostgresSQLStatement, owner: JSValue, globalObject: *jsc.JSGlobalObject) *PostgresCachedStructure {
if (this.cached_structure.has()) {
return this.cached_structure;
return &this.cached_structure;
}
this.checkForDuplicateFields();
@@ -157,7 +157,7 @@ pub fn structure(this: *PostgresSQLStatement, owner: JSValue, globalObject: *jsc
), null);
}
return this.cached_structure;
return &this.cached_structure;
}
const debug = bun.Output.scoped(.Postgres, .visible);

View File

@@ -4,4 +4,5 @@ pub const ConnectionFlags = packed struct {
use_unnamed_prepared_statements: bool = false,
waiting_to_prepare: bool = false,
has_backpressure: bool = false,
is_finalizing_requests: bool = false,
};