Skip to content

Commit 8661505

Browse files
committed
Fix maximum number of bound parameters for MySQL
Also deprecate unnecessary Options getters and setters.
1 parent 38eea35 commit 8661505

8 files changed

Lines changed: 49 additions & 39 deletions

File tree

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,17 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## [6.3.1] - 2024-10-13
8+
### Changed
9+
- Improved `makeBinaryParam()` implementation for SQL Server.
10+
11+
### Fixed
12+
- Maximum number of MySQL bound parameters.
13+
14+
### Deprecated
15+
- Unnecessary `Options` getters and setters.
16+
17+
718
## [6.3.0] - 2024-10-05
819
### Changed
920
- Use `mysqli_stmt::get_result()` instead of `bind_result()` internally
@@ -327,6 +338,7 @@ insert a single row.
327338
- Initial release
328339

329340

341+
[6.3.1]: https://github.com/theodorejb/peachy-sql/compare/v6.3.0...v6.3.1
330342
[6.3.0]: https://github.com/theodorejb/peachy-sql/compare/v6.2.0...v6.3.0
331343
[6.2.0]: https://github.com/theodorejb/peachy-sql/compare/v6.1.0...v6.2.0
332344
[6.1.0]: https://github.com/theodorejb/peachy-sql/compare/v6.0.3...v6.1.0

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ and SQL Server, and runs on PHP 7.4+.
1515
## Usage
1616

1717
Start by instantiating the `Mysql` or `SqlServer` class with a database connection,
18-
which should be an existing [mysqli object](http://www.php.net/manual/en/mysqli.construct.php)
19-
or [SQLSRV connection resource](http://www.php.net/manual/en/function.sqlsrv-connect.php):
18+
which should be an existing [mysqli object](https://www.php.net/manual/en/mysqli.construct.php)
19+
or [SQLSRV connection resource](https://www.php.net/manual/en/function.sqlsrv-connect.php):
2020

2121
```php
2222
$peachySql = new PeachySQL\Mysql($mysqlConn);
@@ -207,7 +207,7 @@ $ids = $result->ids; // e.g. [64, 66, 68]
207207

208208
Note: SQL Server allows a maximum of 1,000 rows to be inserted at a time, and limits
209209
individual queries to 2,099 or fewer bound parameters. MySQL supports a maximum of
210-
65,536 bound parameters per query. These limits can be easily reached when attempting
210+
65,535 bound parameters per query. These limits can be easily reached when attempting
211211
to bulk-insert hundreds or thousands of rows at a time. To avoid these limits, the
212212
`insertRows()` method automatically splits large queries into batches to efficiently
213213
handle any number of rows (`queryCount` contains the number of required batches).

lib/BaseOptions.php

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,17 @@
99
*/
1010
abstract class BaseOptions
1111
{
12-
protected int $maxBoundParams = 0;
13-
protected int $maxInsertRows = 0;
12+
/**
13+
* The maximum number of parameters which can be bound in a single query.
14+
* If greater than zero, PeachySQL will batch insert queries to avoid the limit.
15+
*/
16+
public int $maxBoundParams = 0;
17+
18+
/**
19+
* The maximum number of rows which can be inserted via a single query.
20+
* If greater than zero, PeachySQL will batch insert queries to avoid the limit.
21+
*/
22+
public int $maxInsertRows = 0;
1423

1524
/**
1625
* Escapes a table or column name, and validates that it isn't blank
@@ -33,6 +42,8 @@ public function escapeIdentifier(string $identifier): string
3342
/**
3443
* Specify the maximum number of parameters which can be bound in a single query.
3544
* If greater than zero, PeachySQL will batch insert queries to avoid the limit.
45+
* @deprecated Use public property instead
46+
* @api
3647
*/
3748
public function setMaxBoundParams(int $maxParams): void
3849
{
@@ -43,6 +54,10 @@ public function setMaxBoundParams(int $maxParams): void
4354
$this->maxBoundParams = $maxParams;
4455
}
4556

57+
/**
58+
* @deprecated Use public property instead
59+
* @api
60+
*/
4661
public function getMaxBoundParams(): int
4762
{
4863
return $this->maxBoundParams;
@@ -51,6 +66,8 @@ public function getMaxBoundParams(): int
5166
/**
5267
* Specify the maximum number of rows which can be inserted via a single query.
5368
* If greater than zero, PeachySQL will batch insert queries to remove the limit.
69+
* @deprecated Use public property instead
70+
* @api
5471
*/
5572
public function setMaxInsertRows(int $maxRows): void
5673
{
@@ -61,6 +78,10 @@ public function setMaxInsertRows(int $maxRows): void
6178
$this->maxInsertRows = $maxRows;
6279
}
6380

81+
/**
82+
* @deprecated Use public property instead
83+
* @api
84+
*/
6485
public function getMaxInsertRows(): int
6586
{
6687
return $this->maxInsertRows;

lib/Mysql/Options.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
*/
1212
class Options extends BaseOptions
1313
{
14-
protected int $maxBoundParams = 65536; // 2^16
14+
// https://stackoverflow.com/questions/6581573/what-are-the-max-number-of-allowable-parameters-per-database-provider-type
15+
public int $maxBoundParams = 65_535; // 2 ** 16 - 1;
1516

1617
// use backticks to delimit identifiers since not everyone uses ANSI mode
1718
public function escapeIdentifier(string $identifier): string

lib/PeachySql.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
*/
1717
abstract class PeachySql
1818
{
19-
protected BaseOptions $options;
19+
/** @readonly */
20+
public BaseOptions $options;
2021

2122
/** Begins a transaction */
2223
abstract public function begin(): void;
@@ -50,6 +51,8 @@ abstract protected function insertBatch(string $table, array $colVals, int $iden
5051

5152
/**
5253
* Returns the current PeachySQL options
54+
* @deprecated Use public readonly property instead
55+
* @api
5356
*/
5457
public function getOptions(): BaseOptions
5558
{
@@ -84,7 +87,7 @@ public function insertRow(string $table, array $colVals): InsertResult
8487
public function insertRows(string $table, array $colVals, int $identityIncrement = 1): BulkInsertResult
8588
{
8689
// check whether the query needs to be split into multiple batches
87-
$batches = Insert::batchRows($colVals, $this->options->getMaxBoundParams(), $this->options->getMaxInsertRows());
90+
$batches = Insert::batchRows($colVals, $this->options->maxBoundParams, $this->options->maxInsertRows);
8891
$ids = [];
8992
$affected = 0;
9093

lib/QueryableSelector.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class QueryableSelector extends Selector
1212

1313
public function __construct(SqlParams $query, PeachySql $peachySql)
1414
{
15-
parent::__construct($query, $peachySql->getOptions());
15+
parent::__construct($query, $peachySql->options);
1616
$this->peachySql = $peachySql;
1717
}
1818

lib/SqlServer/Options.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
*/
1212
class Options extends BaseOptions
1313
{
14-
protected int $maxBoundParams = 2099;
15-
protected int $maxInsertRows = 1000;
14+
// https://learn.microsoft.com/en-us/sql/sql-server/maximum-capacity-specifications-for-sql-server
15+
public int $maxBoundParams = 2100 - 1;
16+
public int $maxInsertRows = 1000;
1617
}

test/Mysql/OptionsTest.php

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,34 +12,6 @@
1212
*/
1313
class OptionsTest extends TestCase
1414
{
15-
public function testMaxBoundParams(): void
16-
{
17-
$options = new Options();
18-
$options->setMaxBoundParams(2000);
19-
$this->assertSame(2000, $options->getMaxBoundParams());
20-
21-
try {
22-
$options->setMaxBoundParams(-1); // should throw exception
23-
$this->fail('setMaxBoundParams failed to throw expected exception');
24-
} catch (\InvalidArgumentException $e) {
25-
$this->assertSame('The maximum number of bound parameters must be greater than or equal to zero', $e->getMessage());
26-
}
27-
}
28-
29-
public function testMaxInsertRows(): void
30-
{
31-
$options = new Options();
32-
$options->setMaxInsertRows(1000);
33-
$this->assertSame(1000, $options->getMaxInsertRows());
34-
35-
try {
36-
$options->setMaxInsertRows(-1); // should throw exception
37-
$this->fail('setMaxInsertRows failed to throw expected exception');
38-
} catch (\InvalidArgumentException $e) {
39-
$this->assertSame('The maximum number of insert rows must be greater than or equal to zero', $e->getMessage());
40-
}
41-
}
42-
4315
public function testEscapeIdentifier(): void
4416
{
4517
$options = new Options();

0 commit comments

Comments
 (0)