Skip to content

Conversation

louwers
Copy link
Contributor

@louwers louwers commented Aug 31, 2024

Even though these types will never be retrieved from SQLite, using them in a bind is perfectly valid.

undefined will get translated to NULL, boolean to 1 (true) or 0 (false).

@sgbeal
Copy link
Collaborator

sgbeal commented Aug 31, 2024

Achtung: whether undefined counts as null depends on the API. In some of them (am on a mobile device so cannot readily verify which ones), undefined is used as a no-op to simplify certain binding cases. e.g. oo1.Stmt.bind() does not treat undefined like null.

https://sqlite.org/wasm/doc/trunk/api-oo1.md

@louwers
Copy link
Contributor Author

louwers commented Aug 31, 2024

Oops. Let me put some more thought into this.

undefined is used as a no-op to simplify certain binding cases

Well technically you can still pass if even if it is a no-op.

@louwers louwers closed this Aug 31, 2024
@louwers
Copy link
Contributor Author

louwers commented Aug 31, 2024

  // this works
  db.prepare("INSERT INTO test VALUES (?, ?, ?)").bind([2, undefined, 1]).step()
  
  // also works
  db.prepare("INSERT INTO test VALUES (?, ?, ?)").bind(1, 1).bind(2, undefined).bind(3, 3).step();

  // also seems to work
  db.prepare("INSERT INTO test VALUES (?, 2, 3)").bind(undefined).step()

From the docs:

undefined as a standalone value is a no-op: passing undefined as a value to this function will not actually bind anything and this function will skip confirmation that binding is even legal. (Those semantics simplify certain client-side uses.) Conversely, a value of undefined as an array or object property when binding an array/object (see below) is treated the same as null.

@louwers louwers reopened this Aug 31, 2024
@louwers
Copy link
Contributor Author

louwers commented Aug 31, 2024

@sgbeal I modified the pull request to not allow undefined as a stand-alone bind.

@sgbeal
Copy link
Collaborator

sgbeal commented Sep 1, 2024

  // this works
  db.prepare("INSERT INTO test VALUES (?, ?, ?)").bind([2, undefined, 1]).step()
  
  // also works
  db.prepare("INSERT INTO test VALUES (?, ?, ?)").bind(1, 1).bind(2, undefined).bind(3, 3).step();

  // also seems to work
  db.prepare("INSERT INTO test VALUES (?, 2, 3)").bind(undefined).step()

Note that the default value for unbound parameters is null, so in the above cases it will appear as if undefined translates to null, but it's not really doing so. In these cases, it's just coincidence.

@louwers
Copy link
Contributor Author

louwers commented Sep 1, 2024

@sgbeal Yes I figured!

That is why I excluded undefined in the type for binds that don't use an array or object.

@sgbeal
Copy link
Collaborator

sgbeal commented Sep 1, 2024

Historical note: the undefined==noop oddity was based on client-side experience with an earlier sqlite binding done for a different language (this particular binding being my 7th-ish). Though i currently cannot for the life of me find a concrete example where that was useful for me, it did have a genuine utility at the time it was conceived and implemented. If i can manage to remember specifically what that utility is i'll update the docs to explain it.

@tomayac
Copy link
Collaborator

tomayac commented Sep 2, 2024

So, @sgbeal, is this good to merge then? Thanks for the contribution already, @louwers!

@sgbeal
Copy link
Collaborator

sgbeal commented Sep 2, 2024

i'm a poor judge of typescript but it looks fine to my layman's eyes.

@tomayac tomayac merged commit e74c7ab into sqlite:main Sep 2, 2024
@tomayac
Copy link
Collaborator

tomayac commented Sep 2, 2024

Released: https://github.com/sqlite/sqlite-wasm/releases/tag/3.46.1-build2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants