Feature Proposal: Native Set and Map Support in format()
See PR #27 for an example implementation
Problem
Currently, when a Set or Map is passed as a parameter to format(), it is coerced via the default object-to-string conversion, producing output like:
SELECT * FROM users WHERE id IN ('[object Set]')
UPDATE t SET data = '[object Map]'
This forces every caller to manually convert these structures before calling format():
format('SELECT * FROM users WHERE id IN (?)', [Array.from(idSet)]);
format('UPDATE t SET ?', [Object.fromEntries(colMap)]);
That conversion is repetitive boilerplate and is easy to forget, leading to broken SQL at runtime.
Proposal
Treat Set and Map as natural extensions of the existing Array/Object handling for the ? placeholder:
- Set → expand like
Array
IN (?) with new Set([1, 2, 3]) → IN (1, 2, 3)
SELECT ? with new Set([42]) → SELECT 42
- Map → expand like a plain object when used in
UPDATE ... SET ?
UPDATE t SET ? with new Map([['name', 'foo'], ['count', 7]]) → UPDATE t SET \name` = 'foo', `count` = 7`
- Empty Collections: Empty
Set / Map should produce empty expansions, just like empty Array / Object do today.
- Fallback: For a
Map used in a non-SET ? position, keep the current fallback behavior ('[object Map]') to avoid breaking any code that may rely on it.
Why
- Idiomatic:
Set and Map are idiomatic in modern TypeScript/Node code.
- Order Preservation: They preserve insertion order (useful for deterministic SQL).
- Deduplication:
Set provides natural deduplication for IN (?) lists.
- Developer Experience: Removes repetitive
Array.from / Object.fromEntries calls at call sites.
Feature Proposal: Native Set and Map Support in
format()See PR #27 for an example implementation
Problem
Currently, when a
SetorMapis passed as a parameter toformat(), it is coerced via the default object-to-string conversion, producing output like:This forces every caller to manually convert these structures before calling
format():That conversion is repetitive boilerplate and is easy to forget, leading to broken SQL at runtime.
Proposal
Treat
SetandMapas natural extensions of the existingArray/Objecthandling for the?placeholder:ArrayIN (?)withnew Set([1, 2, 3])→IN (1, 2, 3)SELECT ?withnew Set([42])→SELECT 42UPDATE ... SET ?UPDATE t SET ?withnew Map([['name', 'foo'], ['count', 7]])→UPDATE t SET \name` = 'foo', `count` = 7`Set/Mapshould produce empty expansions, just like emptyArray/Objectdo today.Mapused in a non-SET?position, keep the current fallback behavior ('[object Map]') to avoid breaking any code that may rely on it.Why
SetandMapare idiomatic in modern TypeScript/Node code.Setprovides natural deduplication forIN (?)lists.Array.from/Object.fromEntriescalls at call sites.