Skip to content

drizzle: SQLiteInsertBase methods (_prepare, prepare, execute, returning, etc) return undefined when accessed via Any-typed receiver #643

Description

@proggeramlug

Summary

After v0.5.755 (cross-module ctor field-init persistence), drizzle's full insert chain still hits TypeError: Cannot read properties of undefined (reading 'run'). Bisecting reveals: (ins as any)._prepare is undefined even though _prepare is a regular method declaration on SQLiteInsertBase (line 140 of drizzle-orm/sqlite-core/query-builders/insert.js).

Repro

import { sqliteTable, integer, text } from "drizzle-orm/sqlite-core";
import Database from "better-sqlite3";
import { drizzle } from "drizzle-orm/better-sqlite3";

const sqlite = new Database(":memory:");
const db = drizzle(sqlite);
const users = sqliteTable("users", { id: integer("id").primaryKey(), name: text("name").notNull() });
sqlite.exec(`CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT NOT NULL)`);

const ins = db.insert(users).values([{ id: 1, name: "alice" }]);

console.log("ins.constructor[entityKind]:", (ins as any).constructor[Symbol.for("drizzle:entityKind")]);
//   → "SQLiteInsert" ✓

console.log("typeof ins.run:", typeof (ins as any).run);          // function ✓
console.log("typeof ins._prepare:", typeof (ins as any)._prepare); // undefined ✗ (Node: function)
console.log("typeof ins.prepare:", typeof (ins as any).prepare);   // undefined ✗
console.log("typeof ins.execute:", typeof (ins as any).execute);   // undefined ✗
console.log("typeof ins.returning:", typeof (ins as any).returning); // undefined ✗

ins.run();  // TypeError: Cannot read properties of undefined (reading 'run')
            // ins.run is `(p) => this._prepare().run(p)`; _prepare returns undefined

Pattern

The class SQLiteInsertBase mixes:

  • Arrow-function fields (run = (p) => ..., all, get, values) — VISIBLE in Perry
  • Method declarations (_prepare(), prepare(), returning(), execute(), getSQL(), etc.) — UNDEFINED in Perry

Both should work via the vtable. Perry's PIC / property dispatch only finds the arrow-function fields (instance slots), not the prototype methods.

Bisection state

  • v0.5.755 makes sess.client/dialect/logger correctly set after super()
  • Direct call also fails: (ins as any)._prepare() returns undefined (not a "method not found" throw — just undefined return)
  • Isolated repros with the same shape (extends from another module, static [entityKind], mixed methods+fields, computed-key dispatch in body) all WORK in tests/release/packages/drizzle-sqlite or in /tmp/method_dispatch/. Something specific to drizzle's actual class registration (~100+ classes with shared inheritance) breaks this.

Acceptance

tests/release/packages/drizzle-sqlite/entry.ts produces output byte-identical to expected.txt.

Refs

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions