Problem/Motivation

While exploring #1425794: SQLite exception "primary key must be unique" when sequences table erroneously contains more than one row, chx and I almost "fixed" the implemenation of "greatest" in SQLite driver, because the code is misleading.

Here, instead is a patch (was #9 in the other issue, but turned out to be unrelated) that simplifies the function and adds a comment to make its desired behavior clear. This behavior is that we mimic the way that the greatest function in MySQL works. If the function is called with less then two parameters a exception is called. With two or more parameters and with one or more of those parameters being NULL will return the value NULL.

The problem is that PostgreSQL works a little bit different. And there is no way we can change this. Calling greatest with one parameter just returns the parameter. With two or more parameters will only return NULL if ALL the parameters are NULL.

Steps to reproduce

Proposed resolution

Change sqlFunctionGreatest() to not fail when an argument in NULL. And mimic MySQL as explained above.

Remaining tasks

Review
Commit

User interface changes

API changes

Data model changes

Release notes snippet

Comments

lotyrin’s picture

StatusFileSize
new798 bytes

Hmm, patch got lost.

lotyrin’s picture

Status: Active » Needs review
halstead’s picture

Status: Needs review » Reviewed & tested by the community

Testing shows this to be functionally equivalent and it is much easier to read.

I would prefer a standard if over the ternary if to make it even more readable but either way works.
I'm marking rtbc but will happily review again if you change it.

catch’s picture

Status: Reviewed & tested by the community » Needs review

I'd prefer the if as well - wouldn't this be enough?

<?php
if (!in_array(NULL, $args, TRUE)) {
return max($args);
}
}

lotyrin’s picture

Assigned: Unassigned » lotyrin
Status: Needs review » Needs work

Yep. I agree. Patch is what someone in the other thread came up with, I'll reroll with an if.

lotyrin’s picture

StatusFileSize
new1.13 KB

Here's the if version.

lotyrin’s picture

Status: Needs work » Needs review
alan d.’s picture

Status: Needs review » Needs work

Don't you mean NULL rather than $null?

lotyrin’s picture

Status: Needs work » Needs review
StatusFileSize
new1.13 KB

Yep...

donquixote’s picture

Component: sqlite database » ajax system
Issue summary: View changes

What about GREATEST() with no arguments? Should this return NULL or should it break?

donquixote’s picture

#10:

mysql> SELECT GREATEST();
ERROR 1582 (42000): Incorrect parameter count in the call to native function 'GREATEST'
mysql> SELECT GREATEST(1);
ERROR 1582 (42000): Incorrect parameter count in the call to native function 'GREATEST'

So, in MySQL at least it requires two arguments.
But should we try to replicate this in PHP?

What we should not do is silently fail. Either we return NULL or we throw an exception.

EDIT:
Oracle docs suggest that only one argument is required:
http://docs.oracle.com/html/A95915_01/sqfunc.htm#i1005813

donquixote’s picture

Other question: How reliable is max() for strings or datetime?
For my taste we should postpone this question to a follow-up, where we can also add tests:
#2262425: Does PHP max() correctly replicate SQL GREATEST() for non-numeric values?

Another thing to do here and now: Add a nice docblock.

donquixote’s picture

Category: Task » Bug report

Btw, the existing implementation is not just misleading but wrong and buggy, as it can lead to count(UNDEFINED).
Maybe previous PHP versions were silent about this, but it is definitely wrong.
I am changing this to a bug report.

(Originally i came from here: #2259947: Minor bug fixes in database system)

jhedstrom’s picture

This patch still applies. Are there any db-driver-specific tests? Could this be tested? I don't think the testbot currently runs on sqlite, but it eventually will (hopefully) run on all supported db drivers.

amateescu’s picture

Title: SQLite Greatest implementation is misleading. » SQLite Greatest implementation is misleading
Component: ajax system » sqlite db driver

Moving to the right component.

daffie’s picture

Status: Needs review » Reviewed & tested by the community

The patch looks good to me.

The documentation from MySQL states tht there be a minimum of two parameters for the GREATEST function. It also states that if one parameter is NULL that the function will return NULL. This patch does both.

The patch still applies, so for me it is RTBC

alexpott’s picture

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

It would be nice to have some tests for this.

daffie’s picture

Issue tags: +PostgreSQL

With new tests for this we have to watch out for any problems with a PostgreSQL database.

daffie’s picture

Issue summary: View changes
Status: Needs work » Needs review
StatusFileSize
new3.24 KB

Tests added.

daffie’s picture

Issue tags: -Needs tests
StatusFileSize
new3.06 KB
new1.21 KB

Minor change to the added tests.

lotyrin’s picture

Assigned: lotyrin » Unassigned

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

daffie’s picture

Version: 8.1.x-dev » 8.2.x-dev
StatusFileSize
new3.07 KB

Rerolled the patch from comment #22, because ConnectionTest has been moved.

Status: Needs review » Needs work

The last submitted patch, 25: 1814762-25.patch, failed testing.

The last submitted patch, 25: 1814762-25.patch, failed testing.

daffie’s picture

Status: Needs work » Needs review

After some strange problems with the testbot it is now happy. So back to needs review.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.0-beta1 was released on August 3, 2016, which means new developments and disruptive changes should now be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

berdir’s picture

The NULL is interesting, I actually tried a quick fix in #2810325: Undefined variable $args in sqlFunctionGreatest() and got another exception as a result of that.

This happened for me in a kernel test that saved a user, so it tried to write to the sequence table.

daffie’s picture

Title: SQLite Greatest implementation is misleading » SQLite Greatest implementation is wrong for parameters with the value NULL

Changing the title at @Berdirs request.

berdir’s picture

Yes, tried with this patch applied now and this is the error that I get now:

General error: 20 datatype mismatch: UPDATE {sequences} SET value = GREATEST(value, :existing_id) + 1

So I guess it wants to do NULL + 1. Still not sure why one of the values is NULL in my case.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

smustgrave’s picture

Status: Needs review » Postponed (maintainer needs more info)

Patch or MR doesn't apply anymore
The last patch or MR doesn't apply to the target branch, please reroll the code so that it can be reviewed by the automated testbot.

Would like to know if still valid bug though after 6 years

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

quietone’s picture

Issue summary: View changes
Status: Postponed (maintainer needs more info) » Needs review
StatusFileSize
new7.63 KB
new4.25 KB
new5.68 KB

I started triage on #1425794: SQLite exception "primary key must be unique" when sequences table erroneously contains more than one row and found my way to this issue. The problematic code is still in sqlFunctionGreatest().

I decided to update the patch and add tests.

The last submitted patch, 47: 1814762-47-fail.patch, failed testing. View results

quietone’s picture

StatusFileSize
new502 bytes
new6.17 KB

Let's try this. Still having trouble with PHPStan locally so I can't test this.

smustgrave’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: +Needs Review Queue Initiative

IS seems to match the proposed patch
#48 has a fail patch to show the tests are covering the change
All green across the different databases.

Think this is good.

needs-review-queue-bot’s picture

Status: Reviewed & tested by the community » Needs work
StatusFileSize
new85 bytes

The Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".

This does not mean that the patch needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.