|
| 1 | +import type { ResultSetHeader, RowDataPacket } from '../../../index.js'; |
| 2 | +import { describe, it, strict } from 'poku'; |
| 3 | +import { createConnection, createPool } from '../../common.test.mjs'; |
| 4 | + |
| 5 | +type DomainRow = RowDataPacket & { id: number; domain: string }; |
| 6 | +type DocRow = RowDataPacket & { id: number; foo: string; hasModified: number }; |
| 7 | + |
| 8 | +await describe('Regression #4126 — object placeholders expand in SET assignment lists', async () => { |
| 9 | + await describe('client-side formatting', async () => { |
| 10 | + const connection = createConnection(); |
| 11 | + |
| 12 | + it('should expand ?? and ? object inside SET STATEMENT ... FOR INSERT', () => { |
| 13 | + strict.equal( |
| 14 | + connection.format( |
| 15 | + 'SET STATEMENT max_statement_time=15 FOR INSERT INTO ?? SET ?', |
| 16 | + ['domains', { id: 1, domain: 'test.com' }] |
| 17 | + ), |
| 18 | + "SET STATEMENT max_statement_time=15 FOR INSERT INTO `domains` SET `id` = 1, `domain` = 'test.com'" |
| 19 | + ); |
| 20 | + }); |
| 21 | + |
| 22 | + it('should expand ? object after UTC_TIMESTAMP() in an UPDATE SET list', () => { |
| 23 | + strict.equal( |
| 24 | + connection.format( |
| 25 | + 'UPDATE docs SET modified = UTC_TIMESTAMP(), ? WHERE id = ?', |
| 26 | + [{ foo: 'bar' }, 123] |
| 27 | + ), |
| 28 | + "UPDATE docs SET modified = UTC_TIMESTAMP(), `foo` = 'bar' WHERE id = 123" |
| 29 | + ); |
| 30 | + }); |
| 31 | + |
| 32 | + connection.end(); |
| 33 | + }); |
| 34 | + |
| 35 | + await describe('end-to-end execution', async () => { |
| 36 | + const pool = createPool({ connectionLimit: 1 }).promise(); |
| 37 | + |
| 38 | + await it('should insert via object-form query with ??, ? object and timeout', async () => { |
| 39 | + await pool.query( |
| 40 | + 'CREATE TEMPORARY TABLE domains (id INT PRIMARY KEY, domain VARCHAR(255))' |
| 41 | + ); |
| 42 | + |
| 43 | + const [result] = await pool.query<ResultSetHeader>({ |
| 44 | + sql: 'INSERT INTO ?? SET ?', |
| 45 | + values: ['domains', { id: 1, domain: 'test.com' }], |
| 46 | + timeout: 16000, |
| 47 | + }); |
| 48 | + |
| 49 | + strict.equal(result.affectedRows, 1); |
| 50 | + |
| 51 | + const [rows] = await pool.query<DomainRow[]>( |
| 52 | + 'SELECT id, domain FROM domains' |
| 53 | + ); |
| 54 | + strict.equal(rows.length, 1); |
| 55 | + strict.equal(rows[0].id, 1); |
| 56 | + strict.equal(rows[0].domain, 'test.com'); |
| 57 | + }); |
| 58 | + |
| 59 | + await it('should update via ? object mixed with UTC_TIMESTAMP()', async () => { |
| 60 | + await pool.query( |
| 61 | + 'CREATE TEMPORARY TABLE docs (id INT PRIMARY KEY, foo VARCHAR(50), modified DATETIME)' |
| 62 | + ); |
| 63 | + await pool.query('INSERT INTO docs (id, foo) VALUES (123, ?)', ['old']); |
| 64 | + |
| 65 | + const [result] = await pool.query<ResultSetHeader>( |
| 66 | + 'UPDATE docs SET modified = UTC_TIMESTAMP(), ? WHERE id = ?', |
| 67 | + [{ foo: 'bar' }, 123] |
| 68 | + ); |
| 69 | + |
| 70 | + strict.equal(result.affectedRows, 1); |
| 71 | + |
| 72 | + const [rows] = await pool.query<DocRow[]>( |
| 73 | + 'SELECT id, foo, modified IS NOT NULL AS hasModified FROM docs' |
| 74 | + ); |
| 75 | + |
| 76 | + strict.equal(rows.length, 1); |
| 77 | + strict.equal(rows[0].foo, 'bar'); |
| 78 | + strict.equal(rows[0].hasModified, 1); |
| 79 | + }); |
| 80 | + |
| 81 | + await pool.end(); |
| 82 | + }); |
| 83 | +}); |
0 commit comments