Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
D
doctrine-dbal
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Tomáš Trávníček
doctrine-dbal
Commits
2a44c94b
Commit
2a44c94b
authored
Mar 06, 2011
by
Benjamin Eberlei
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
DBAL-78 - Fix SQLParserUtils List Parameter expansion to be zero based for positional parameters.
parent
e007fec5
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
43 additions
and
54 deletions
+43
-54
SQLParserUtils.php
lib/Doctrine/DBAL/SQLParserUtils.php
+16
-18
DataAccessTest.php
tests/Doctrine/Tests/DBAL/Functional/DataAccessTest.php
+2
-2
SQLParserUtilsTest.php
tests/Doctrine/Tests/DBAL/SQLParserUtilsTest.php
+25
-34
No files found.
lib/Doctrine/DBAL/SQLParserUtils.php
View file @
2a44c94b
...
@@ -35,8 +35,8 @@ class SQLParserUtils
...
@@ -35,8 +35,8 @@ class SQLParserUtils
/**
/**
* Get an array of the placeholders in an sql statements as keys and their positions in the query string.
* Get an array of the placeholders in an sql statements as keys and their positions in the query string.
*
*
* Returns an integer => integer pair
for a positional statement and a string => int[] pair for
* Returns an integer => integer pair
(indexed from zero) for a positional statement
* a named statement.
* a
nd a string => int[] pair for a
named statement.
*
*
* @param string $statement
* @param string $statement
* @param bool $isPositional
* @param bool $isPositional
...
@@ -49,7 +49,7 @@ class SQLParserUtils
...
@@ -49,7 +49,7 @@ class SQLParserUtils
return
array
();
return
array
();
}
}
$count
=
1
;
$count
=
0
;
$inLiteral
=
false
;
// a valid query never starts with quotes
$inLiteral
=
false
;
// a valid query never starts with quotes
$stmtLen
=
strlen
(
$statement
);
$stmtLen
=
strlen
(
$statement
);
$paramMap
=
array
();
$paramMap
=
array
();
...
@@ -85,22 +85,24 @@ class SQLParserUtils
...
@@ -85,22 +85,24 @@ class SQLParserUtils
*/
*/
static
public
function
expandListParameters
(
$query
,
$params
,
$types
)
static
public
function
expandListParameters
(
$query
,
$params
,
$types
)
{
{
$isPositional
=
false
;
$isPositional
=
is_int
(
key
(
$params
))
;
$arrayPositions
=
array
();
$arrayPositions
=
array
();
$bindIndex
=
-
1
;
foreach
(
$types
AS
$name
=>
$type
)
{
foreach
(
$types
AS
$name
=>
$type
)
{
++
$bindIndex
;
if
(
$type
===
Connection
::
PARAM_INT_ARRAY
||
$type
==
Connection
::
PARAM_STR_ARRAY
)
{
if
(
$type
===
Connection
::
PARAM_INT_ARRAY
||
$type
==
Connection
::
PARAM_STR_ARRAY
)
{
if
(
$isPositional
)
{
$name
=
$bindIndex
;
}
$arrayPositions
[
$name
]
=
false
;
$arrayPositions
[
$name
]
=
false
;
$isPositional
=
(
is_numeric
(
$name
));
}
}
}
}
if
(
!
$arrayPositions
)
{
if
(
!
$arrayPositions
||
count
(
$params
)
!=
count
(
$types
)
)
{
return
array
(
$query
,
$params
,
$types
);
return
array
(
$query
,
$params
,
$types
);
}
}
ksort
(
$params
);
ksort
(
$types
);
$paramPos
=
self
::
getPlaceholderPositions
(
$query
,
$isPositional
);
$paramPos
=
self
::
getPlaceholderPositions
(
$query
,
$isPositional
);
if
(
$isPositional
)
{
if
(
$isPositional
)
{
$paramOffset
=
0
;
$paramOffset
=
0
;
...
@@ -115,25 +117,21 @@ class SQLParserUtils
...
@@ -115,25 +117,21 @@ class SQLParserUtils
$len
=
count
(
$params
[
$needle
]);
$len
=
count
(
$params
[
$needle
]);
$params
=
array_merge
(
$params
=
array_merge
(
array_slice
(
$params
,
0
,
$needle
-
1
),
array_slice
(
$params
,
0
,
$needle
),
$params
[
$needle
],
$params
[
$needle
],
array_slice
(
$params
,
$needle
)
array_slice
(
$params
,
$needle
+
1
)
);
);
array_unshift
(
$params
,
-
1
);
// temporary to shift keys
unset
(
$params
[
0
]);
$types
=
array_merge
(
$types
=
array_merge
(
array_slice
(
$types
,
0
,
$needle
-
1
),
array_slice
(
$types
,
0
,
$needle
),
array_fill
(
0
,
$len
,
$types
[
$needle
]
-
Connection
::
ARRAY_PARAM_OFFSET
),
// array needles are at PDO::PARAM_* + 100
array_fill
(
0
,
$len
,
$types
[
$needle
]
-
Connection
::
ARRAY_PARAM_OFFSET
),
// array needles are at PDO::PARAM_* + 100
array_slice
(
$types
,
$needle
)
array_slice
(
$types
,
$needle
+
1
)
);
);
array_unshift
(
$types
,
-
1
);
unset
(
$types
[
0
]);
$expandStr
=
implode
(
", "
,
array_fill
(
0
,
$len
,
"?"
));
$expandStr
=
implode
(
", "
,
array_fill
(
0
,
$len
,
"?"
));
$query
=
substr
(
$query
,
0
,
$needlePos
)
.
$expandStr
.
substr
(
$query
,
$needlePos
+
1
);
$query
=
substr
(
$query
,
0
,
$needlePos
)
.
$expandStr
.
substr
(
$query
,
$needlePos
+
1
);
$paramOffset
+=
(
$len
-
1
);
$paramOffset
+=
(
$len
-
1
);
// Grows larger by number of parameters minus the replaced needle.
$queryOffset
+=
(
strlen
(
$expandStr
)
-
1
);
$queryOffset
+=
(
strlen
(
$expandStr
)
-
1
);
}
}
}
else
{
}
else
{
...
...
tests/Doctrine/Tests/DBAL/Functional/DataAccessTest.php
View file @
2a44c94b
...
@@ -231,14 +231,14 @@ class DataAccessTest extends \Doctrine\Tests\DbalFunctionalTestCase
...
@@ -231,14 +231,14 @@ class DataAccessTest extends \Doctrine\Tests\DbalFunctionalTestCase
}
}
$stmt
=
$this
->
_conn
->
executeQuery
(
'SELECT test_int FROM fetch_table WHERE test_int IN (?)'
,
$stmt
=
$this
->
_conn
->
executeQuery
(
'SELECT test_int FROM fetch_table WHERE test_int IN (?)'
,
array
(
1
=>
array
(
100
,
101
,
102
,
103
,
104
)),
array
(
1
=>
Connection
::
PARAM_INT_ARRAY
));
array
(
array
(
100
,
101
,
102
,
103
,
104
)),
array
(
Connection
::
PARAM_INT_ARRAY
));
$data
=
$stmt
->
fetchAll
(
PDO
::
FETCH_NUM
);
$data
=
$stmt
->
fetchAll
(
PDO
::
FETCH_NUM
);
$this
->
assertEquals
(
5
,
count
(
$data
));
$this
->
assertEquals
(
5
,
count
(
$data
));
$this
->
assertEquals
(
array
(
array
(
100
),
array
(
101
),
array
(
102
),
array
(
103
),
array
(
104
)),
$data
);
$this
->
assertEquals
(
array
(
array
(
100
),
array
(
101
),
array
(
102
),
array
(
103
),
array
(
104
)),
$data
);
$stmt
=
$this
->
_conn
->
executeQuery
(
'SELECT test_int FROM fetch_table WHERE test_string IN (?)'
,
$stmt
=
$this
->
_conn
->
executeQuery
(
'SELECT test_int FROM fetch_table WHERE test_string IN (?)'
,
array
(
1
=>
array
(
'foo100'
,
'foo101'
,
'foo102'
,
'foo103'
,
'foo104'
)),
array
(
1
=>
Connection
::
PARAM_STR_ARRAY
));
array
(
array
(
'foo100'
,
'foo101'
,
'foo102'
,
'foo103'
,
'foo104'
)),
array
(
Connection
::
PARAM_STR_ARRAY
));
$data
=
$stmt
->
fetchAll
(
PDO
::
FETCH_NUM
);
$data
=
$stmt
->
fetchAll
(
PDO
::
FETCH_NUM
);
$this
->
assertEquals
(
5
,
count
(
$data
));
$this
->
assertEquals
(
5
,
count
(
$data
));
...
...
tests/Doctrine/Tests/DBAL/SQLParserUtilsTest.php
View file @
2a44c94b
...
@@ -20,13 +20,13 @@ class SQLParserUtilsTest extends \Doctrine\Tests\DbalTestCase
...
@@ -20,13 +20,13 @@ class SQLParserUtilsTest extends \Doctrine\Tests\DbalTestCase
array
(
'SELECT * FROM Foo'
,
false
,
array
()),
array
(
'SELECT * FROM Foo'
,
false
,
array
()),
// Positionals
// Positionals
array
(
'SELECT ?'
,
true
,
array
(
1
=>
7
)),
array
(
'SELECT ?'
,
true
,
array
(
7
)),
array
(
'SELECT * FROM Foo WHERE bar IN (?, ?, ?)'
,
true
,
array
(
1
=>
32
,
2
=>
35
,
3
=>
38
)),
array
(
'SELECT * FROM Foo WHERE bar IN (?, ?, ?)'
,
true
,
array
(
32
,
35
,
38
)),
array
(
'SELECT ? FROM ?'
,
true
,
array
(
1
=>
7
,
2
=>
14
)),
array
(
'SELECT ? FROM ?'
,
true
,
array
(
7
,
14
)),
array
(
'SELECT "?" FROM foo'
,
true
,
array
()),
array
(
'SELECT "?" FROM foo'
,
true
,
array
()),
array
(
"SELECT '?' FROM foo"
,
true
,
array
()),
array
(
"SELECT '?' FROM foo"
,
true
,
array
()),
array
(
'SELECT "?" FROM foo WHERE bar = ?'
,
true
,
array
(
1
=>
32
)),
array
(
'SELECT "?" FROM foo WHERE bar = ?'
,
true
,
array
(
32
)),
array
(
"SELECT '?' FROM foo WHERE bar = ?"
,
true
,
array
(
1
=>
32
)),
array
(
"SELECT '?' FROM foo WHERE bar = ?"
,
true
,
array
(
32
)),
// named
// named
array
(
'SELECT :foo FROM :bar'
,
false
,
array
(
':foo'
=>
array
(
7
),
':bar'
=>
array
(
17
))),
array
(
'SELECT :foo FROM :bar'
,
false
,
array
(
':foo'
=>
array
(
7
),
':bar'
=>
array
(
17
))),
...
@@ -54,56 +54,47 @@ class SQLParserUtilsTest extends \Doctrine\Tests\DbalTestCase
...
@@ -54,56 +54,47 @@ class SQLParserUtilsTest extends \Doctrine\Tests\DbalTestCase
// Positional: Very simple with one needle
// Positional: Very simple with one needle
array
(
array
(
"SELECT * FROM Foo WHERE foo IN (?)"
,
"SELECT * FROM Foo WHERE foo IN (?)"
,
array
(
1
=>
array
(
1
,
2
,
3
)),
array
(
array
(
1
,
2
,
3
)),
array
(
1
=>
Connection
::
PARAM_INT_ARRAY
),
array
(
Connection
::
PARAM_INT_ARRAY
),
'SELECT * FROM Foo WHERE foo IN (?, ?, ?)'
,
'SELECT * FROM Foo WHERE foo IN (?, ?, ?)'
,
array
(
1
=>
1
,
2
=>
2
,
3
=>
3
),
array
(
1
,
2
,
3
),
array
(
1
=>
\PDO
::
PARAM_INT
,
2
=>
\PDO
::
PARAM_INT
,
3
=>
\PDO
::
PARAM_INT
)
array
(
\PDO
::
PARAM_INT
,
\PDO
::
PARAM_INT
,
\PDO
::
PARAM_INT
)
),
),
// Positional: One non-list before d one after list-needle
// Positional: One non-list before d one after list-needle
array
(
array
(
"SELECT * FROM Foo WHERE foo = ? AND bar IN (?)"
,
"SELECT * FROM Foo WHERE foo = ? AND bar IN (?)"
,
array
(
1
=>
"string"
,
2
=>
array
(
1
,
2
,
3
)),
array
(
"string"
,
array
(
1
,
2
,
3
)),
array
(
1
=>
\PDO
::
PARAM_STR
,
2
=>
Connection
::
PARAM_INT_ARRAY
),
array
(
\PDO
::
PARAM_STR
,
Connection
::
PARAM_INT_ARRAY
),
'SELECT * FROM Foo WHERE foo = ? AND bar IN (?, ?, ?)'
,
'SELECT * FROM Foo WHERE foo = ? AND bar IN (?, ?, ?)'
,
array
(
1
=>
"string"
,
2
=>
1
,
3
=>
2
,
4
=>
3
),
array
(
"string"
,
1
,
2
,
3
),
array
(
1
=>
\PDO
::
PARAM_STR
,
2
=>
\PDO
::
PARAM_INT
,
3
=>
\PDO
::
PARAM_INT
,
4
=>
\PDO
::
PARAM_INT
)
array
(
\PDO
::
PARAM_STR
,
\PDO
::
PARAM_INT
,
\PDO
::
PARAM_INT
,
\PDO
::
PARAM_INT
)
),
// Positional: One non-list before d one after list-needle, parameters and types reversed.
array
(
"SELECT * FROM Foo WHERE foo = ? AND bar IN (?)"
,
array
(
2
=>
array
(
1
,
2
,
3
),
1
=>
"string"
),
array
(
2
=>
Connection
::
PARAM_INT_ARRAY
,
1
=>
\PDO
::
PARAM_STR
),
'SELECT * FROM Foo WHERE foo = ? AND bar IN (?, ?, ?)'
,
array
(
1
=>
"string"
,
2
=>
1
,
3
=>
2
,
4
=>
3
),
array
(
1
=>
\PDO
::
PARAM_STR
,
2
=>
\PDO
::
PARAM_INT
,
3
=>
\PDO
::
PARAM_INT
,
4
=>
\PDO
::
PARAM_INT
)
),
),
// Positional: One non-list after list-needle
// Positional: One non-list after list-needle
array
(
array
(
"SELECT * FROM Foo WHERE bar IN (?) AND baz = ?"
,
"SELECT * FROM Foo WHERE bar IN (?) AND baz = ?"
,
array
(
1
=>
array
(
1
,
2
,
3
),
3
=>
"foo"
),
array
(
array
(
1
,
2
,
3
),
"foo"
),
array
(
1
=>
Connection
::
PARAM_INT_ARRAY
,
3
=>
\PDO
::
PARAM_STR
),
array
(
Connection
::
PARAM_INT_ARRAY
,
\PDO
::
PARAM_STR
),
'SELECT * FROM Foo WHERE bar IN (?, ?, ?) AND baz = ?'
,
'SELECT * FROM Foo WHERE bar IN (?, ?, ?) AND baz = ?'
,
array
(
1
=>
1
,
2
=>
2
,
3
=>
3
,
4
=>
"foo"
),
array
(
1
,
2
,
3
,
"foo"
),
array
(
1
=>
\PDO
::
PARAM_INT
,
2
=>
\PDO
::
PARAM_INT
,
3
=>
\PDO
::
PARAM_INT
,
4
=>
\PDO
::
PARAM_STR
)
array
(
\PDO
::
PARAM_INT
,
\PDO
::
PARAM_INT
,
\PDO
::
PARAM_INT
,
\PDO
::
PARAM_STR
)
),
),
// Positional: One non-list before and one after list-needle
// Positional: One non-list before and one after list-needle
array
(
array
(
"SELECT * FROM Foo WHERE foo = ? AND bar IN (?) AND baz = ?"
,
"SELECT * FROM Foo WHERE foo = ? AND bar IN (?) AND baz = ?"
,
array
(
1
=>
1
,
2
=>
array
(
1
,
2
,
3
),
3
=>
4
),
array
(
1
,
array
(
1
,
2
,
3
),
4
),
array
(
1
=>
\PDO
::
PARAM_INT
,
2
=>
Connection
::
PARAM_INT_ARRAY
,
3
=>
\PDO
::
PARAM_INT
),
array
(
\PDO
::
PARAM_INT
,
Connection
::
PARAM_INT_ARRAY
,
\PDO
::
PARAM_INT
),
'SELECT * FROM Foo WHERE foo = ? AND bar IN (?, ?, ?) AND baz = ?'
,
'SELECT * FROM Foo WHERE foo = ? AND bar IN (?, ?, ?) AND baz = ?'
,
array
(
1
=>
1
,
2
=>
1
,
3
=>
2
,
4
=>
3
,
5
=>
4
),
array
(
1
,
1
,
2
,
3
,
4
),
array
(
1
=>
\PDO
::
PARAM_INT
,
2
=>
\PDO
::
PARAM_INT
,
3
=>
\PDO
::
PARAM_INT
,
4
=>
\PDO
::
PARAM_INT
,
5
=>
\PDO
::
PARAM_INT
)
array
(
\PDO
::
PARAM_INT
,
\PDO
::
PARAM_INT
,
\PDO
::
PARAM_INT
,
\PDO
::
PARAM_INT
,
\PDO
::
PARAM_INT
)
),
),
// Positional: Two lists
// Positional: Two lists
array
(
array
(
"SELECT * FROM Foo WHERE foo IN (?, ?)"
,
"SELECT * FROM Foo WHERE foo IN (?, ?)"
,
array
(
1
=>
array
(
1
,
2
,
3
),
2
=>
array
(
4
,
5
)),
array
(
array
(
1
,
2
,
3
),
array
(
4
,
5
)),
array
(
1
=>
Connection
::
PARAM_INT_ARRAY
,
2
=>
Connection
::
PARAM_INT_ARRAY
),
array
(
Connection
::
PARAM_INT_ARRAY
,
Connection
::
PARAM_INT_ARRAY
),
'SELECT * FROM Foo WHERE foo IN (?, ?, ?, ?, ?)'
,
'SELECT * FROM Foo WHERE foo IN (?, ?, ?, ?, ?)'
,
array
(
1
=>
1
,
2
=>
2
,
3
=>
3
,
4
=>
4
,
5
=>
5
),
array
(
1
,
2
,
3
,
4
,
5
),
array
(
1
=>
\PDO
::
PARAM_INT
,
2
=>
\PDO
::
PARAM_INT
,
3
=>
\PDO
::
PARAM_INT
,
4
=>
\PDO
::
PARAM_INT
,
5
=>
\PDO
::
PARAM_INT
)
array
(
\PDO
::
PARAM_INT
,
\PDO
::
PARAM_INT
,
\PDO
::
PARAM_INT
,
\PDO
::
PARAM_INT
,
\PDO
::
PARAM_INT
)
),
),
);
);
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment