Skip to content
Permalink
Browse files

SqlPreprocessor: fixed IN (?) with empty array

  • Loading branch information...
dg committed Feb 19, 2015
1 parent 0735e7f commit d5aa567f2b524418af7daf83f68bde9879704b3a
Showing with 5 additions and 1 deletion.
  1. +1 −1 src/Database/SqlPreprocessor.php
  2. +4 −0 tests/Database/SqlPreprocessor.phpt
@@ -205,7 +205,7 @@ private function formatValue($value, $mode = NULL)
$vx[] = $this->delimite($k) . '=' . $this->formatValue($v);
}
}
return implode(', ', $vx);
return $vx ? implode(', ', $vx) : '1=1';
} elseif ($mode === 'and' || $mode === 'or') { // (key [operator] value) AND ...
foreach ($value as $k => $v) {
@@ -46,6 +46,10 @@ test(function() use ($preprocessor) {
test(function() use ($preprocessor) { // IN
list($sql, $params) = $preprocessor->process(array('SELECT id FROM author WHERE id IN (?)', array()));
Assert::same( 'SELECT id FROM author WHERE id IN (1=1)', $sql );
Assert::same( array(), $params );
list($sql, $params) = $preprocessor->process(array('SELECT id FROM author WHERE id IN (?)', array(10, 11)));
Assert::same( 'SELECT id FROM author WHERE id IN (10, 11)', $sql );
Assert::same( array(), $params );

10 comments on commit d5aa567

@simara-esports

This comment has been minimized.

Copy link

replied Feb 26, 2015

@dg WAT?
SELECT id FROM author WHERE id IN (1=1)
Will return row where id=1
Is this behavior expected? In my opinion isn't. I would expect FALSE condition.
(Or error, it is also better than id=1. Why 1?)

@dg

This comment has been minimized.

Copy link
Member Author

replied Feb 26, 2015

It is for compatibility with v2.2 http://forum.nette.org/en/22055-nette-2-3-0-beta-for-testing#p151507

It should return no rows, isn't it?

@simara-esports

This comment has been minimized.

Copy link

replied Feb 26, 2015

Nope.
1=1 is evaluated as TRUE, TRUE is in MySQL's world 1
So this statement is equal to:
SELECT id FROM author WHERE id IN (1)

Tested in:
MariaDB 10.0.16
MySQL 5.5.41

@hrach

This comment has been minimized.

Copy link
Contributor

replied Feb 26, 2015

Just note, change to 1=0 wouldn't help, i have a app where ID is 0 - not my dessicion.

@dg

This comment has been minimized.

Copy link
Member Author

replied Feb 26, 2015

The question is, how to solve it. Probably do nothing and let it cause SQL parse error.

@simara-esports

This comment has been minimized.

Copy link

replied Feb 26, 2015

You can change it to
SELECT id FROM author WHERE id IN (NULL)

This works in MySQL, because comparation
value = NULL
is always false

@miso-belica

This comment has been minimized.

Copy link

replied Feb 26, 2015

Maybe SELECT id FROM author WHERE id IN (NULL)?

@dg

This comment has been minimized.

Copy link
Member Author

replied Feb 26, 2015

It will not work with NOT IN (NULL).

@hrach

This comment has been minimized.

Copy link
Contributor

replied Feb 26, 2015

Only correct impl is in sqlbuilder

@tomaswindsor

This comment has been minimized.

Copy link
Contributor

replied Mar 27, 2015

expr in (?) where ? is empty array can AFAIK be fully emulated with ((expr) IS NULL AND FALSE), but then there is a problem with placement of brackets, as it is non-trivial task to detect the beginning of expr (requires sql-parser). Solution in SqlBuilder is based on this, but requires some additional conventions in using of brackets from programmer in order to avoid the need to detect the beginning of expr.

Please sign in to comment.
You can’t perform that action at this time.