nodejs / nodejs/node

sqlite: remove the null prototype from result rows

Offen
#65,799 4 Kommentare 1 Reaktion 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Vorherrschende Sprache
JavaScript
Sterne
122k
Forks
37.3k
Ø Merge
4 T. 2 Std.
Gemergte PRs (30 T.)
283

Beschreibung

Current behavior

Rows returned by get(), all() and iterate() are created with a null prototype. The V8 API that does this produces dictionary-mode objects, and V8 will not cache a prototype transition on a dictionary map, so every row also gets its own freshly allocated hidden class. Rows from the same statement therefore share no shape: they are slow to build, and every property access on them in user code is megamorphic.

Proposal

Drop the null prototype and build rows with v8::DictionaryTemplate, cached per statement. Rows become ordinary objects, and every row of a statement shares one hidden class.

Pros

  • all() is 10–37% faster depending on the query; reading the rows afterwards is far cheaper still.
  • Consistent with run(), which already returns an ordinary object, and with better-sqlite3.

Cons

  • Semver-major.
  • Rows can no longer be indexed by untrusted keys without Object.hasOwn()row.toString and row.constructor start resolving through Object.prototype.
  • User code comparing rows against { __proto__: null, ... } breaks.

Prototype pollution is not a concern either way: rows are built by defining own properties directly, so a __proto__ column is an own property and never reaches Object.prototype.

I have benchmarks and a working implementation if there is interest.

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginne damit, die Implementierungen von get(), all(), iterate() und die bestehende Verarbeitung der run()-Ergebnisse zu lokalisieren, und lies anschließend nach, wie die V8 API und v8::DictionaryTemplate verwendet werden. Überprüfe die im Issue erwähnten vorgeschlagenen Benchmarks und die funktionierende Implementierung. Als abgeschlossen gilt die Bewertung des Verhaltens gewöhnlicher Objekte, der gemeinsamen Zeilenstruktur, der Performance und der Kompatibilitätsbedenken im Zusammenhang mit semver-major.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
javascript, sqlite
Bereich
backend, databases
Issue-Typ
Feature
Schwierigkeit
5/5
Geschätzter Aufwand
Über eine Woche
Aktivitätsstatus
Aktiv
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
35/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.