Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions test/global/test-load-infile.test.mts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ await describe('Load Infile', async () => {
.query<RowDataPacket[]>('SELECT @@GLOBAL.local_infile as backup');
const originalLocalInfile = savedLocalInfile[0].backup;

// @ts-expect-error: strict.ifError is an assertion function incompatible with query callback type
connection.query('SET GLOBAL local_infile = true', strict.ifError);
connection.query(
[
Expand Down
48 changes: 48 additions & 0 deletions test/integration/connection/test-bind-undefined.test.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import type { RowDataPacket } from '../../../index.js';
import { describe, it, strict } from 'poku';
import { createConnection } from '../../common.test.mjs';

await describe('Bind Undefined', async () => {
const connection = createConnection().promise();

await it('execute: should throw TypeError for undefined parameter', async () => {
await strict.rejects(
// @ts-expect-error: testing that undefined bind parameter throws TypeError
connection.execute('SELECT ? AS result', [undefined]),
{
name: 'TypeError',
message:
'Bind parameters must not contain undefined. To pass SQL NULL specify JS null',
}
);
});

await it('execute: should accept undefined as values (no bind parameters)', async () => {
const [results] = await connection.execute<RowDataPacket[]>(
'SELECT 1 AS result',
undefined
);

strict.strictEqual(results[0].result, 1);
});

await it('query: should accept undefined bind parameter as NULL', async () => {
const [results] = await connection.query<RowDataPacket[]>(
'SELECT ? AS result',
[undefined]
);

strict.strictEqual(results[0].result, null);
});

await it('query: should accept undefined as values (no bind parameters)', async () => {
const [results] = await connection.query<RowDataPacket[]>(
'SELECT 1 AS result',
undefined
);

strict.strictEqual(results[0].result, 1);
});

await connection.end();
});
30 changes: 0 additions & 30 deletions test/integration/connection/test-execute-bind-undefined.test.mts

This file was deleted.

7 changes: 4 additions & 3 deletions typings/mysql/lib/protocol/sequences/ExecutableBase.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
Query,
QueryError,
QueryOptions,
ExecuteValues,
QueryableConstructor,
} from './Query.js';

Expand All @@ -18,20 +19,20 @@ export declare function ExecutableBase<T extends QueryableConstructor>(
): Query;
execute<T extends QueryResult>(
sql: string,
values: any,
values: ExecuteValues,
callback?:
| ((err: QueryError | null, result: T, fields: FieldPacket[]) => any)
| undefined
): Query;
execute<T extends QueryResult>(
options: QueryOptions,
callback?:
| ((err: QueryError | null, result: T, fields?: FieldPacket[]) => any)
| ((err: QueryError | null, result: T, fields: FieldPacket[]) => any)
| undefined
): Query;
execute<T extends QueryResult>(
options: QueryOptions,
values: any,
values: ExecuteValues,
callback?:
| ((err: QueryError | null, result: T, fields: FieldPacket[]) => any)
| undefined
Expand Down
14 changes: 13 additions & 1 deletion typings/mysql/lib/protocol/sequences/Query.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Readable } from 'stream';
import { Timezone } from 'sql-escaper';
import { TypeCast } from '../../parsers/typeCast.js';

export type QueryValues =
export type ExecuteValues =
| string
| number
| bigint
Expand All @@ -14,6 +14,18 @@ export type QueryValues =
| Blob
| Buffer
| ({} | null)[]
| { [key: string]: ExecuteValues };

export type QueryValues =
| string
| number
| bigint
| boolean
| Date
| null
| Blob
| Buffer
| ({} | null | undefined)[]
| { [key: string]: QueryValues };

export interface QueryOptions {
Expand Down
7 changes: 4 additions & 3 deletions typings/mysql/lib/protocol/sequences/QueryableBase.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
Query,
QueryError,
QueryOptions,
QueryValues,
QueryableConstructor,
} from './Query.js';

Expand All @@ -18,20 +19,20 @@ export declare function QueryableBase<T extends QueryableConstructor>(
): Query;
query<T extends QueryResult>(
sql: string,
values: any,
values: QueryValues,
callback?:
| ((err: QueryError | null, result: T, fields: FieldPacket[]) => any)
| undefined
): Query;
query<T extends QueryResult>(
options: QueryOptions,
callback?:
| ((err: QueryError | null, result: T, fields?: FieldPacket[]) => any)
| ((err: QueryError | null, result: T, fields: FieldPacket[]) => any)
| undefined
): Query;
query<T extends QueryResult>(
options: QueryOptions,
values: any,
values: QueryValues,
callback?:
| ((err: QueryError | null, result: T, fields: FieldPacket[]) => any)
| undefined
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { FieldPacket, QueryResult } from '../../packets/index.js';
import { QueryOptions, QueryableConstructor, QueryValues } from '../Query.js';
import { QueryOptions, QueryableConstructor, ExecuteValues } from '../Query.js';

export declare function ExecutableBase<T extends QueryableConstructor>(
Base?: T
): {
new (...args: any[]): {
execute<T extends QueryResult>(
sql: string,
values?: QueryValues
values?: ExecuteValues
): Promise<[T, FieldPacket[]]>;
execute<T extends QueryResult>(
options: QueryOptions,
values?: QueryValues
values?: ExecuteValues
): Promise<[T, FieldPacket[]]>;
};
} & T;
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import { FieldPacket, QueryResult } from '../../packets/index.js';
import { QueryOptions, QueryableConstructor } from '../Query.js';
import { QueryOptions, QueryValues, QueryableConstructor } from '../Query.js';

export declare function QueryableBase<T extends QueryableConstructor>(
Base?: T
): {
new (...args: any[]): {
query<T extends QueryResult>(
sql: string,
values?: any
values?: QueryValues
): Promise<[T, FieldPacket[]]>;

query<T extends QueryResult>(
options: QueryOptions,
values?: any
values?: QueryValues
): Promise<[T, FieldPacket[]]>;
};
} & T;
Loading