Skip to content

Commit f6f76d4

Browse files
authored
Merge pull request #1445 from microsoft/dev
5.11.0 Release
2 parents cf661d1 + 3cd248f commit f6f76d4

20 files changed

+937
-910
lines changed

CHANGELOG.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,33 @@ All notable changes to this project will be documented in this file.
33

44
The format is based on [Keep a Changelog](http://keepachangelog.com/)
55

6+
## 5.11.0 - 2023-02-28
7+
Updated PECL release packages. Here is the list of updates:
8+
9+
### Added
10+
- Support for PHP 8.2
11+
12+
### Removed
13+
- Support for PHP 7.4
14+
15+
### Limitations
16+
- No support for inout / output params when using sql_variant type
17+
- No support for inout / output params when formatting decimal values
18+
- In Linux and macOS, setlocale() only takes effect if it is invoked before the first connection. Attempting to set the locale after connecting will not work
19+
- Always Encrypted requires [MS ODBC Driver 17+](https://docs.microsoft.com/sql/connect/odbc/linux-mac/installing-the-microsoft-odbc-driver-for-sql-server)
20+
- Only Windows Certificate Store and Azure Key Vault are supported. Custom Keystores are not yet supported
21+
- Issue [#716](https://github.com/Microsoft/msphpsql/issues/716) - With Always Encrypted enabled, named parameters in subqueries are not supported
22+
- Issue [#1050](https://github.com/microsoft/msphpsql/issues/1050) - With Always Encrypted enabled, insertion requires the column list for any tables with identity columns
23+
- [Always Encrypted limitations](https://docs.microsoft.com/sql/connect/php/using-always-encrypted-php-drivers#limitations-of-the-php-drivers-when-using-always-encrypted)
24+
25+
### Known Issues
26+
- This release requires ODBC Driver 17.4.2 or above. Otherwise, a warning about failing to set an attribute may be suppressed when using an older ODBC driver.
27+
- Connection pooling on Linux or macOS is not recommended with [unixODBC](http://www.unixodbc.org/) < 2.3.7
28+
- When pooling is enabled in Linux or macOS
29+
- unixODBC <= 2.3.4 (Linux and macOS) might not return proper diagnostic information, such as error messages, warnings and informative messages
30+
- due to this unixODBC bug, fetch large data (such as xml, binary) as streams as a workaround. See the examples [here](https://github.com/Microsoft/msphpsql/wiki/Features#pooling)
31+
32+
633
## 5.11.0-beta1 - 2023-01-25
734
Updated PECL release packages. Here is the list of updates:
835

azure-pipelines.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pr:
1919
jobs:
2020
- job: macOS
2121
pool:
22-
vmImage: 'macOS-10.15'
22+
vmImage: 'macos-latest'
2323
steps:
2424
- checkout: self
2525
clean: true

media/os_development.PNG

-91 KB
Binary file not shown.

media/os_production.PNG

-107 KB
Binary file not shown.

media/php_versions.PNG

-48.3 KB
Binary file not shown.

media/sql_server.PNG

-66.8 KB
Binary file not shown.

source/pdo_sqlsrv/pdo_dbh.cpp

Lines changed: 137 additions & 137 deletions
Large diffs are not rendered by default.

source/pdo_sqlsrv/pdo_parser.cpp

Lines changed: 64 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,20 @@
22
// File: pdo_parser.cpp
33
//
44
// Contents: Implements a parser to parse the PDO DSN.
5-
//
5+
//
66
// Copyright Microsoft Corporation
77
//
88
// Microsoft Drivers 5.11 for PHP for SQL Server
99
// Copyright(c) Microsoft Corporation
1010
// All rights reserved.
1111
// MIT License
12-
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the ""Software""),
13-
// to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
12+
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the ""Software""),
13+
// to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
1414
// and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions :
1515
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
16-
// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17-
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18-
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
16+
// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
1919
// IN THE SOFTWARE.
2020
//---------------------------------------------------------------------------------------------------------------------------------
2121

@@ -34,7 +34,7 @@ conn_string_parser:: conn_string_parser( _In_ sqlsrv_context& ctx, _In_ const ch
3434
this->pos = -1;
3535
this->ctx = &ctx;
3636
this->current_key = 0;
37-
this->current_key_name = NULL;
37+
this->current_key_name = NULL;
3838
}
3939

4040
sql_string_parser:: sql_string_parser( _In_ sqlsrv_context& ctx, _In_ const char* sql_str, _In_ int len, _In_ HashTable* placeholders_ht )
@@ -55,16 +55,16 @@ inline bool string_parser::next( void )
5555

5656
return false;
5757
}
58-
58+
5959
SQLSRV_ASSERT( this->pos < len, "Unexpected cursor position in conn_string_parser::next" );
6060

61-
this->pos++;
61+
this->pos++;
6262

6363
if ( this->is_eos() ) {
64-
64+
6565
return false;
6666
}
67-
67+
6868
return true;
6969
}
7070

@@ -77,12 +77,12 @@ inline bool string_parser::is_eos( void )
7777
}
7878

7979
SQLSRV_ASSERT(this->pos < len, "Unexpected cursor position in conn_string_parser::is_eos" );
80-
80+
8181
return false;
8282
}
8383

84-
// Check for white space.
85-
inline bool string_parser::is_white_space( _In_ char c )
84+
// Check for white space.
85+
inline bool string_parser::is_white_space( _In_ char c )
8686
{
8787
if( c == ' ' || c == '\r' || c == '\n' || c == '\t' ) {
8888
return true;
@@ -94,9 +94,9 @@ inline bool string_parser::is_white_space( _In_ char c )
9494
int conn_string_parser::discard_trailing_white_spaces( _In_reads_(len) const char* str, _Inout_ int len )
9595
{
9696
const char* end = str + ( len - 1 );
97-
97+
9898
while(( this->is_white_space( *end ) ) && (len > 0) ) {
99-
99+
100100
len--;
101101
end--;
102102
}
@@ -108,16 +108,16 @@ int conn_string_parser::discard_trailing_white_spaces( _In_reads_(len) const cha
108108
bool string_parser::discard_white_spaces()
109109
{
110110
if( this->is_eos() ) {
111-
111+
112112
return false;
113113
}
114114

115115
while( this->is_white_space( this->orig_str[pos] )) {
116-
116+
117117
if( !next() )
118118
return false;
119-
}
120-
119+
}
120+
121121
return true;
122122
}
123123

@@ -128,22 +128,22 @@ void string_parser::add_key_value_pair( _In_reads_(len) const char* value, _In_
128128
ZVAL_UNDEF( &value_z );
129129

130130
if( len == 0 ) {
131-
131+
132132
ZVAL_STRINGL( &value_z, "", 0);
133133
}
134134
else {
135135

136136
ZVAL_STRINGL( &value_z, const_cast<char*>( value ), len );
137-
}
137+
}
138138

139-
core::sqlsrv_zend_hash_index_update( *ctx, this->element_ht, this->current_key, &value_z );
139+
core::sqlsrv_zend_hash_index_update( *ctx, this->element_ht, this->current_key, &value_z );
140140
}
141141

142142
// Add a key-value pair to the hashtable with int value
143143
void sql_string_parser::add_key_int_value_pair( _In_ unsigned int value ) {
144144
zval value_z;
145145
ZVAL_LONG( &value_z, value );
146-
146+
147147
core::sqlsrv_zend_hash_index_update( *ctx, this->element_ht, this->current_key, &value_z );
148148
}
149149

@@ -168,9 +168,9 @@ void conn_string_parser::validate_key( _In_reads_(key_len) const char *key, _Ino
168168
key_name = static_cast<char*>( sqlsrv_malloc( new_len + 1 ));
169169
memcpy_s( key_name, new_len + 1 ,key, new_len );
170170

171-
key_name[new_len] = '\0';
171+
key_name[new_len] = '\0';
172172

173-
THROW_PDO_ERROR( this->ctx, PDO_SQLSRV_ERROR_INVALID_DSN_KEY, static_cast<char*>( key_name ) );
173+
THROW_PDO_ERROR( this->ctx, PDO_SQLSRV_ERROR_INVALID_DSN_KEY, static_cast<char*>( key_name ), NULL );
174174
}
175175

176176
inline bool sql_string_parser::is_placeholder_char( char c )
@@ -183,25 +183,25 @@ inline bool sql_string_parser::is_placeholder_char( char c )
183183
}
184184

185185
// Primary function which parses the connection string/DSN.
186-
void conn_string_parser:: parse_conn_string( void )
186+
void conn_string_parser:: parse_conn_string( void )
187187
{
188188
States state = FirstKeyValuePair; // starting state
189189
int start_pos = -1;
190190

191191
try {
192192

193193
while( !this->is_eos() ) {
194-
194+
195195
switch( state ) {
196-
196+
197197
case FirstKeyValuePair:
198198
{
199199
// discard leading spaces
200200
if( !next() || !discard_white_spaces() ) {
201-
201+
202202
THROW_PDO_ERROR( this->ctx, PDO_SQLSRV_ERROR_INVALID_DSN_STRING ); //EOS
203203
}
204-
204+
205205
state = Key;
206206
break;
207207
}
@@ -212,15 +212,15 @@ void conn_string_parser:: parse_conn_string( void )
212212

213213
// read the key name
214214
while( this->orig_str[pos] != '=' ) {
215-
215+
216216
if( !next() ) {
217-
218-
THROW_PDO_ERROR( this->ctx, PDO_SQLSRV_ERROR_DSN_STRING_ENDED_UNEXPECTEDLY ); //EOS
219-
}
220-
}
221217

222-
this->validate_key( &( this->orig_str[start_pos] ), ( pos - start_pos ) );
223-
218+
THROW_PDO_ERROR( this->ctx, PDO_SQLSRV_ERROR_DSN_STRING_ENDED_UNEXPECTEDLY ); //EOS
219+
}
220+
}
221+
222+
this->validate_key( &( this->orig_str[start_pos] ), ( pos - start_pos ) );
223+
224224
state = Value;
225225

226226
break;
@@ -239,23 +239,23 @@ void conn_string_parser:: parse_conn_string( void )
239239
add_key_value_pair( NULL, 0 );
240240

241241
if( this->is_eos() ) {
242-
242+
243243
break; // EOS
244244
}
245245
else {
246246

247-
// this->orig_str[pos] == ';'
247+
// this->orig_str[pos] == ';'
248248
state = NextKeyValuePair;
249249
}
250250
}
251-
251+
252252
// if LCB
253253
else if( this->orig_str[pos] == '{' ) {
254-
254+
255255
start_pos = this->pos; // starting character is LCB
256256
state = ValueContent1;
257257
}
258-
258+
259259
// If NonSP-LCB-SC
260260
else {
261261

@@ -269,10 +269,10 @@ void conn_string_parser:: parse_conn_string( void )
269269
case ValueContent1:
270270
{
271271
while ( this->orig_str[pos] != '}' ) {
272-
272+
273273
if ( ! next() ) {
274274

275-
THROW_PDO_ERROR( this->ctx, PDO_SQLSRV_ERROR_RCB_MISSING_IN_DSN_VALUE, this->current_key_name );
275+
THROW_PDO_ERROR( this->ctx, PDO_SQLSRV_ERROR_RCB_MISSING_IN_DSN_VALUE, this->current_key_name, NULL );
276276
}
277277
}
278278

@@ -287,28 +287,28 @@ void conn_string_parser:: parse_conn_string( void )
287287
while( this->orig_str[pos] != ';' ) {
288288

289289
if( ! next() ) {
290-
290+
291291
break; //EOS
292292
}
293293
}
294294

295295
if( !this->is_eos() && this->orig_str[pos] == ';' ) {
296-
296+
297297
// semi-colon encountered, so go to next key-value pair
298298
state = NextKeyValuePair;
299299
}
300-
300+
301301
add_key_value_pair( &( this->orig_str[start_pos] ), this->pos - start_pos );
302-
303-
SQLSRV_ASSERT((( state == NextKeyValuePair ) || ( this->is_eos() )),
302+
303+
SQLSRV_ASSERT((( state == NextKeyValuePair ) || ( this->is_eos() )),
304304
"conn_string_parser::parse_conn_string: Invalid state encountered " );
305305

306306
break;
307307
}
308308

309309
case RCBEncountered:
310310
{
311-
311+
312312
// Read the next character after RCB.
313313
if( !next() ) {
314314

@@ -321,11 +321,11 @@ void conn_string_parser:: parse_conn_string( void )
321321

322322
// if second RCB encountered than go back to ValueContent1
323323
if( this->orig_str[pos] == '}' ) {
324-
324+
325325
if( !next() ) {
326326

327327
// EOS after a second RCB is error
328-
THROW_PDO_ERROR( this->ctx, SQLSRV_ERROR_UNESCAPED_RIGHT_BRACE_IN_DSN, this->current_key_name );
328+
THROW_PDO_ERROR( this->ctx, SQLSRV_ERROR_UNESCAPED_RIGHT_BRACE_IN_DSN, this->current_key_name, NULL );
329329
}
330330

331331
state = ValueContent1;
@@ -336,9 +336,9 @@ void conn_string_parser:: parse_conn_string( void )
336336

337337
// discard any trailing white-spaces.
338338
if( this->is_white_space( this->orig_str[pos] )) {
339-
339+
340340
if( ! this->discard_white_spaces() ) {
341-
341+
342342
//EOS
343343
add_key_value_pair( &( this->orig_str[start_pos] ), end_pos - start_pos );
344344
break;
@@ -347,32 +347,32 @@ void conn_string_parser:: parse_conn_string( void )
347347

348348
// if semi-colon than go to next key-value pair
349349
if ( this->orig_str[pos] == ';' ) {
350-
350+
351351
add_key_value_pair( &( this->orig_str[start_pos] ), end_pos - start_pos );
352352
state = NextKeyValuePair;
353353
break;
354354
}
355355

356356
// Non - (RCB, SP*, SC, EOS) character. Any other character after an RCB is an error.
357-
THROW_PDO_ERROR( this->ctx, PDO_SQLSRV_ERROR_INVALID_DSN_VALUE, this->current_key_name );
358-
break;
357+
THROW_PDO_ERROR( this->ctx, PDO_SQLSRV_ERROR_INVALID_DSN_VALUE, this->current_key_name, NULL );
358+
break;
359359
}
360360
case NextKeyValuePair:
361361
{
362-
SQLSRV_ASSERT(( this->orig_str[pos] == ';' ),
362+
SQLSRV_ASSERT(( this->orig_str[pos] == ';' ),
363363
"conn_string_parser::parse_conn_string: semi-colon was expected." );
364364

365365
// Call next() to skip the semi-colon.
366366
if( !next() || !this->discard_white_spaces() ) {
367-
367+
368368
// EOS
369369
break;
370370
}
371-
371+
372372
if( this->orig_str[pos] == ';' ) {
373-
373+
374374
// a second semi-colon is error case.
375-
THROW_PDO_ERROR( this->ctx, PDO_SQLSRV_ERROR_EXTRA_SEMI_COLON_IN_DSN_STRING, this->pos );
375+
THROW_PDO_ERROR( this->ctx, PDO_SQLSRV_ERROR_EXTRA_SEMI_COLON_IN_DSN_STRING, this->pos, NULL );
376376
}
377377

378378
else {
@@ -384,7 +384,7 @@ void conn_string_parser:: parse_conn_string( void )
384384
} //case NextKeyValuePair
385385
} // switch
386386
} //while
387-
}
387+
}
388388
catch( pdo::PDOException& ) {
389389

390390
throw;

0 commit comments

Comments
 (0)