Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
project
drupal
Commits
40ae780a
Commit
40ae780a
authored
Jun 30, 2015
by
Alex Pott
Browse files
Issue
#2443679
by bzrudi71, daffie, mradcliffe, alexpott: PostgreSQL: Fix taxonomy\Tests\TermTest
parent
200e1b88
Changes
6
Hide whitespace changes
Inline
Side-by-side
core/lib/Drupal/Core/Database/Driver/mysql/EntityQuery/Condition.php
0 → 100644
View file @
40ae780a
<?php
/**
* @file
* Contains Drupal\Core\Database\Driver\mysql\EntityQuery\Condition
*/
namespace
Drupal\Core\Database\Driver\mysql\EntityQuery
;
use
Drupal\Core\Database\EntityQuery\ConditionInterface
as
EntityQueryConditionInterface
;
/**
* Implements entity query conditions for SQL databases.
*/
class
Condition
implements
EntityQueryConditionInterface
{
/**
* {@inheritdoc}
*/
public
static
function
translateCondition
(
array
&
$condition
,
$case_sensitive
)
{
}
}
core/lib/Drupal/Core/Database/Driver/pgsql/EntityQuery/Condition.php
0 → 100644
View file @
40ae780a
<?php
/**
* @file
* Contains Drupal\Core\Database\Driver\pgsql\EntityQuery\Condition
*/
namespace
Drupal\Core\Database\Driver\pgsql\EntityQuery
;
use
Drupal\Core\Database\Database
;
use
Drupal\Core\Database\EntityQuery\ConditionInterface
as
EntityQueryConditionInterface
;
/**
* Implements entity query conditions for SQL databases.
*/
class
Condition
implements
EntityQueryConditionInterface
{
/**
* {@inheritdoc}
*/
public
static
function
translateCondition
(
array
&
$condition
,
$case_sensitive
)
{
$connection
=
Database
::
getConnection
();
// For PostgreSQL all the condition arguments need to have case
// lowered to support not case sensitive fields.
if
(
is_array
(
$condition
[
'value'
])
&&
$case_sensitive
===
FALSE
)
{
$condition
[
'where'
]
=
'LOWER('
.
$connection
->
escapeField
(
$condition
[
'real_field'
])
.
') '
.
$condition
[
'operator'
]
.
' ('
;
$condition
[
'where_args'
]
=
[];
$n
=
1
;
// Only use the array values in case an associative array is passed as an
// argument following similar pattern in
// \Drupal\Core\Database\Connection::expandArguments().
foreach
(
$condition
[
'value'
]
as
$value
)
{
$condition
[
'where'
]
.
=
'LOWER(:value'
.
$n
.
'),'
;
$condition
[
'where_args'
][
':value'
.
$n
]
=
$value
;
$n
++
;
}
$condition
[
'where'
]
=
trim
(
$condition
[
'where'
],
','
);
$condition
[
'where'
]
.
=
')'
;
}
}
}
core/lib/Drupal/Core/Database/Driver/sqlite/EntityQuery/Condition.php
0 → 100644
View file @
40ae780a
<?php
/**
* @file
* Contains Drupal\Core\Database\Driver\sqlite\EntityQuery\Condition
*/
namespace
Drupal\Core\Database\Driver\sqlite\EntityQuery
;
use
Drupal\Core\Database\EntityQuery\ConditionInterface
as
EntityQueryConditionInterface
;
/**
* Implements entity query conditions for SQL databases.
*/
class
Condition
implements
EntityQueryConditionInterface
{
/**
* {@inheritdoc}
*/
public
static
function
translateCondition
(
array
&
$condition
,
$case_sensitive
)
{
}
}
core/lib/Drupal/Core/Database/EntityQuery/ConditionInterface.php
0 → 100644
View file @
40ae780a
<?php
/**
* @file
* Contains \Drupal\Core\Database\EntityQuery\ConditionInterface.
*/
namespace
Drupal\Core\Database\EntityQuery
;
/**
* Provides an interface for entity query conditions for SQL databases.
*/
interface
ConditionInterface
{
/**
* Translates the string operators to SQL equivalents. This is a no-op method
* for MySQL and SQLite databases but allows override if needed, e.g. for
* PostgreSQL to support case insensitive queries.
*
* @param array $condition
* The condition array.
* @param bool|null $case_sensitive
* If the condition should be case sensitive or not, NULL if the field does
* not define it.
*
* @see \Drupal\Core\Entity\Query\Sql\Condition::$entityQueryCondition
*/
public
static
function
translateCondition
(
array
&
$condition
,
$case_sensitive
);
}
core/lib/Drupal/Core/Entity/Query/Sql/Condition.php
View file @
40ae780a
...
...
@@ -7,10 +7,11 @@
namespace
Drupal\Core\Entity\Query\Sql
;
use
Drupal\Core\Entity\Query\ConditionBase
;
use
Drupal\Core\Entity\Query\ConditionInterface
;
use
Drupal\Core\Database\Database
;
use
Drupal\Core\Database\Query\SelectInterface
;
use
Drupal\Core\Database\Query\Condition
as
SqlCondition
;
use
Drupal\Core\Entity\Query\ConditionBase
;
use
Drupal\Core\Entity\Query\ConditionInterface
;
/**
* Implements entity query conditions for SQL databases.
...
...
@@ -28,6 +29,7 @@ class Condition extends ConditionBase {
* {@inheritdoc}
*/
public
function
compile
(
$conditionContainer
)
{
// If this is not the top level condition group then the sql query is
// added to the $conditionContainer object by this function itself. The
// SQL query object is only necessary to pass to Query::addField() so it
...
...
@@ -46,8 +48,16 @@ public function compile($conditionContainer) {
else
{
$type
=
strtoupper
(
$this
->
conjunction
)
==
'OR'
||
$condition
[
'operator'
]
==
'IS NULL'
?
'LEFT'
:
'INNER'
;
$field
=
$tables
->
addField
(
$condition
[
'field'
],
$type
,
$condition
[
'langcode'
]);
$condition
[
'real_field'
]
=
$field
;
static
::
translateCondition
(
$condition
,
$sql_query
,
$tables
->
isFieldCaseSensitive
(
$condition
[
'field'
]));
$conditionContainer
->
condition
(
$field
,
$condition
[
'value'
],
$condition
[
'operator'
]);
// Add the translated conditions back to the condition container.
if
(
isset
(
$condition
[
'where'
])
&&
isset
(
$condition
[
'where_args'
]))
{
$conditionContainer
->
where
(
$condition
[
'where'
],
$condition
[
'where_args'
]);
}
else
{
$conditionContainer
->
condition
(
$field
,
$condition
[
'value'
],
$condition
[
'operator'
]);
}
}
}
}
...
...
@@ -80,10 +90,16 @@ public function notExists($field, $langcode = NULL) {
* @see \Drupal\Core\Database\Query\ConditionInterface::condition()
*/
public
static
function
translateCondition
(
&
$condition
,
SelectInterface
$sql_query
,
$case_sensitive
)
{
// There is nothing we can do for IN ().
// There is nothing to do for IN () queries except for PostgreSQL for which
// the condition arguments need to have case lowered to support not case
// sensitive fields.
if
(
is_array
(
$condition
[
'value'
]))
{
$entityQueryCondition
=
Database
::
getConnection
()
->
getDriverClass
(
'EntityQuery\\Condition'
);
$entityQueryCondition
::
translateCondition
(
$condition
,
$case_sensitive
);
return
;
}
// Ensure that the default operator is set to simplify the cases below.
if
(
empty
(
$condition
[
'operator'
]))
{
$condition
[
'operator'
]
=
'='
;
...
...
core/modules/system/src/Tests/Entity/EntityQueryTest.php
View file @
40ae780a
...
...
@@ -210,6 +210,26 @@ function testEntityQuery() {
// Unit 0 and unit 1, so bits 0 1.
$this
->
assertResult
(
3
,
7
,
11
,
15
);
// Do the same test but with IN operator.
$query
=
$this
->
factory
->
get
(
'entity_test_mulrev'
);
$group_blue
=
$query
->
andConditionGroup
()
->
condition
(
"
$figures
.color"
,
array
(
'blue'
),
'IN'
);
$group_red
=
$query
->
andConditionGroup
()
->
condition
(
"
$figures
.color"
,
array
(
'red'
),
'IN'
);
$query
->
condition
(
$group_blue
)
->
condition
(
$group_red
)
->
sort
(
'id'
)
->
execute
();
// Unit 0 and unit 1, so bits 0 1.
$this
->
assertResult
(
3
,
7
,
11
,
15
);
// An entity might have either red or blue figure.
$this
->
queryResults
=
$this
->
factory
->
get
(
'entity_test_mulrev'
)
->
condition
(
"
$figures
.color"
,
array
(
'blue'
,
'red'
),
'IN'
)
->
sort
(
'id'
)
->
execute
();
// Bit 0 or 1 is on.
$this
->
assertResult
(
1
,
2
,
3
,
5
,
6
,
7
,
9
,
10
,
11
,
13
,
14
,
15
);
$this
->
queryResults
=
$this
->
factory
->
get
(
'entity_test_mulrev'
)
->
exists
(
"
$figures
.color"
)
->
notExists
(
"
$greetings
.value"
)
...
...
@@ -613,6 +633,38 @@ public function testCaseSensitivity() {
)
->
execute
();
$this
->
assertIdentical
(
count
(
$result
),
1
,
'Case sensitive, exact match.'
);
// Check the case insensitive field, IN operator.
$result
=
\
Drupal
::
entityQuery
(
'entity_test_mulrev'
)
->
condition
(
'field_ci'
,
array
(
$fixtures
[
0
][
'lowercase'
]
.
$fixtures
[
1
][
'lowercase'
]),
'IN'
)
->
execute
();
$this
->
assertIdentical
(
count
(
$result
),
1
,
'Case insensitive, lowercase'
);
$result
=
\
Drupal
::
entityQuery
(
'entity_test_mulrev'
)
->
condition
(
'field_ci'
,
array
(
$fixtures
[
0
][
'uppercase'
]
.
$fixtures
[
1
][
'uppercase'
]),
'IN'
)
->
execute
();
$this
->
assertIdentical
(
count
(
$result
),
1
,
'Case insensitive, uppercase'
);
$result
=
\
Drupal
::
entityQuery
(
'entity_test_mulrev'
)
->
condition
(
'field_ci'
,
array
(
$fixtures
[
0
][
'uppercase'
]
.
$fixtures
[
1
][
'lowercase'
]),
'IN'
)
->
execute
();
$this
->
assertIdentical
(
count
(
$result
),
1
,
'Case insensitive, mixed'
);
// Check the case sensitive field, IN operator.
$result
=
\
Drupal
::
entityQuery
(
'entity_test_mulrev'
)
->
condition
(
'field_cs'
,
array
(
$fixtures
[
0
][
'lowercase'
]
.
$fixtures
[
1
][
'lowercase'
]),
'IN'
)
->
execute
();
$this
->
assertIdentical
(
count
(
$result
),
0
,
'Case sensitive, lowercase'
);
$result
=
\
Drupal
::
entityQuery
(
'entity_test_mulrev'
)
->
condition
(
'field_cs'
,
array
(
$fixtures
[
0
][
'uppercase'
]
.
$fixtures
[
1
][
'uppercase'
]),
'IN'
)
->
execute
();
$this
->
assertIdentical
(
count
(
$result
),
0
,
'Case sensitive, uppercase'
);
$result
=
\
Drupal
::
entityQuery
(
'entity_test_mulrev'
)
->
condition
(
'field_cs'
,
array
(
$fixtures
[
0
][
'uppercase'
]
.
$fixtures
[
1
][
'lowercase'
]),
'IN'
)
->
execute
();
$this
->
assertIdentical
(
count
(
$result
),
1
,
'Case sensitive, mixed'
);
// Check the case insensitive field, STARTS_WITH operator.
$result
=
\
Drupal
::
entityQuery
(
'entity_test_mulrev'
)
->
condition
(
'field_ci'
,
$fixtures
[
0
][
'lowercase'
],
'STARTS_WITH'
...
...
@@ -762,4 +814,20 @@ public function testForwardRevisions() {
$this
->
assertEqual
(
$result
,
[
16
=>
'14'
]);
}
/**
* Test against SQL inject of condition field. This covers a
* database driver's EntityQuery\Condition class.
*/
public
function
testInjectionInCondition
()
{
try
{
$this
->
queryResults
=
$this
->
factory
->
get
(
'entity_test_mulrev'
)
->
condition
(
'1 ; -- '
,
array
(
0
,
1
),
'IN'
)
->
sort
(
'id'
)
->
execute
();
$this
->
fail
(
'SQL Injection attempt in Entity Query condition in operator should result in an exception.'
);
}
catch
(
\
Exception
$e
)
{
$this
->
pass
(
'SQL Injection attempt in Entity Query condition in operator should result in an exception.'
);
}
}
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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