This issue is part of #2454513: [meta] Make Drupal 8 work with SQLite.

Drupal\views\Tests\Handler\FilterStringTest is currently failing on SQLite.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

amateescu’s picture

Status: Needs review » Active

Haven't been able to figure out this one yet.

amateescu’s picture

Status: Active » Needs review
FileSize
1.68 KB

Here we go, the PHP_INT_MAX limit was quite fun to figure out with @dawehner.

Test run before:

Test summary
------------

Drupal\views\Tests\Handler\FilterStringTest                  166 passes   4 fails                 52 messages

Test run duration: 25 sec

Test run after:

Test summary
------------

Drupal\views\Tests\Handler\FilterStringTest                  170 passes                           52 messages

Test run duration: 24 sec

The other test that was affected by this is_numeric() addition (Drupal\search\Tests\SearchNumbersTest) also passes with this patch:

Test summary
------------

Drupal\search\Tests\SearchNumbersTest                        155 passes                           60 messages

Test run duration: 11 sec
dawehner’s picture

+++ b/core/lib/Drupal/Core/Database/Driver/sqlite/Statement.php
@@ -39,7 +39,10 @@ protected function getStatement($query, &$args = array()) {
+          if (is_float($value) || is_int($value) || (is_numeric($value) && $value < PHP_INT_MAX)) {

@@ -58,7 +61,10 @@ protected function getStatement($query, &$args = array()) {
+          if (is_float($value) || is_int($value) || (is_numeric($value) && $value < PHP_INT_MAX)) {

Nitpick: I think it should be possible cast $value == PHP_INT_MAX as well :P

amateescu’s picture

FileSize
1.68 KB
948 bytes

There we go, thanks for reviewing :)

amateescu’s picture

FileSize
1.68 KB
948 bytes

@amateescu--

The last submitted patch, 4: 2475247-4.patch, failed testing.

dawehner’s picture

For easier future fixes we might should have a custom unit test, what do you think? In case you think it would be not worth to test that nontrivial code,
or use the implicit test coverage we already have, set it please to RTBC.

amateescu’s picture

I'm not sure about a unit test but we can definitely have a nice integration test for this.

With the test-only path applied:

Test summary
------------

Drupal\system\Tests\Database\QueryTest                        15 passes   1 fails                            

Test run duration: 1 sec

With the full patch applied:

Test summary
------------

Drupal\system\Tests\Database\QueryTest                        16 passes                                      

Test run duration: 1 sec
dawehner’s picture

Status: Needs review » Reviewed & tested by the community

Perfect, thank you!

webchick’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs tests

Looks like we're missing a test case here for a ridiculously huge number-in-a-string? That's what this patch is intended to fix, yeah?

amateescu’s picture

Nope, the patch is intended to fix numeric arguments expressed as strings (i.e. '3' instead of 3). If we want to add an assertion for a number higher that PHP_INT_MAX that would just test that that specific number does not work as an argument :)

webchick’s picture

Status: Needs work » Fixed
Issue tags: -Needs tests

Ok, got it. It's the is_numeric() that's important here, not the PHP_INT_MAX. https://api.drupal.org/api/drupal/core!modules!search!src!Tests!SearchNu... contains various test cases, including:

    'over fifty characters' => '666666666666666666666666666666666666666666666666666666666666',

(hence this bug report :)) ...so we are good.

Committed and pushed to 8.0.x. Thanks!

  • webchick committed d141c5a on 8.0.x
    Issue #2475247 by amateescu, dawehner: SQLite: Fix views\Tests\Handler\...

Status: Fixed » Needs work

The last submitted patch, 8: 2475247-8-test-only.patch, failed testing.

Status: Needs work » Needs review

isntall queued 8: 2475247-8-test-only.patch for re-testing.

Status: Needs review » Needs work

The last submitted patch, 8: 2475247-8-test-only.patch, failed testing.

webchick’s picture

Status: Needs work » Fixed

Down, testbot

amateescu’s picture

Status: Fixed » Needs review
FileSize
4.89 KB

Unfortunately, this patch broke Drupal\comment\Tests\CommentPagerTest, which means the conclusion of my discussion with @dawehner last week was not correct, we can not (and most probably should not) treat numeric string arguments as integers.

Specifically, the is_numeric() check added in the patch also matches '01.00' and the argument substitution below turns it into 1. That breaks the comment threading algorithm which relies on the value '01.00' to be treated as a string.

After some digging, I found the root of the problem in Views, where _views_query_tag_alter_condition() does a str_replace() on all condition values, and because str_replace() always returns a string even if it doesn't do any actual replacement, our integer values are lost / converted.

This patch reverts the one from #8 and fixes the underlying bug :)

All the test that could be affected are passing now:

Test summary
------------

Drupal\search\Tests\SearchNumbersTest              155 passes       60 messages
Drupal\views\Tests\Handler\FilterStringTest        170 passes       52 messages                                                                                                                     
Drupal\comment\Tests\CommentPagerTest              323 passes       80 messages                                                                                                                     

Test run duration: 2 min 57 sec
amateescu’s picture

Status: Needs review » Needs work

Hold on, I'm running the entire views test group locally and Drupal\views\Tests\Handler\HandlerTest seems to fail with the patch applied.

amateescu’s picture

Status: Needs work » Needs review

Nope, false alarm, I just ran it again and it passes. It probably failed because I also started a test run at the same time in the UI for a different test.

dawehner’s picture

Status: Needs review » Reviewed & tested by the community

Looks fine for me, yeah this all is pretty tricky.

+++ b/core/modules/views/views.module
@@ -745,7 +745,18 @@ function _views_query_tag_alter_condition(AlterableInterface $query, &$condition
-        $condition['value'] = str_replace(array_keys($substitutions), array_values($substitutions), $condition['value']);
+        // We can not use a simple str_replace() here because it always returns
+        // a string and we have to keep the type of the condition value intact.
+        if (is_array($condition['value'])) {
+          foreach ($condition['value'] as &$value) {
+            if (is_string($value)) {
+              $value = str_replace(array_keys($substitutions), array_values($substitutions), $value);
+            }
+          }
+        }
+        elseif (is_string($condition['value'])) {
+          $condition['value'] = str_replace(array_keys($substitutions), array_values($substitutions), $condition['value']);
+        }
       }
     }
   }

I'm curious whether we should make a follow up to the database system to add such functionality (placeholder support), as I could imagine its much easier to be implemented internally than put on top of it, externally.

alexpott’s picture

Status: Reviewed & tested by the community » Needs review
+++ b/core/modules/views/views.module
@@ -745,7 +745,18 @@ function _views_query_tag_alter_condition(AlterableInterface $query, &$condition
-        $condition['value'] = str_replace(array_keys($substitutions), array_values($substitutions), $condition['value']);
+        // We can not use a simple str_replace() here because it always returns
+        // a string and we have to keep the type of the condition value intact.
+        if (is_array($condition['value'])) {
+          foreach ($condition['value'] as &$value) {
+            if (is_string($value)) {
+              $value = str_replace(array_keys($substitutions), array_values($substitutions), $value);
+            }
+          }
+        }
+        elseif (is_string($condition['value'])) {
+          $condition['value'] = str_replace(array_keys($substitutions), array_values($substitutions), $condition['value']);
+        }

And there is no use case for using substitutions on non string values?

amateescu’s picture

And there is no use case for using substitutions on non string values?

I don't think so. Substitutions have to be special strings like ***SOME_STUFF*** but I'll let @dawehner confirm that :)

dawehner’s picture

Well yeah, in case you already have the number you achieved what you need to know.

dawehner’s picture

Status: Needs review » Reviewed & tested by the community
alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Thanks for having a think about it @dawehner and @amateescu. Committed 19a7f81 and pushed to 8.0.x. Thanks!

  • alexpott committed 19a7f81 on 8.0.x
    Issue #2475247 by amateescu, dawehner: SQLite: Fix views\Tests\Handler\...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.