Skip to content
This repository was archived by the owner on Aug 22, 2023. It is now read-only.

PHPORM-60 Fix Query on whereDate, whereDay, whereMonth, whereYear #28

Closed
wants to merge 6 commits into from

Conversation

GromNaN
Copy link
Owner

@GromNaN GromNaN commented Aug 21, 2023

Fix PHPORM-60

Created from mongodb/laravel-mongodb#2376

So basically, current whereDate, whereDay, whereMonth and whereYear is query on different column with specific need (like whereDate you need column that has value YYYY-MM-DD etc) using basic comparison.

As we all know that isnt how whereDate works on sql, this PR will generate query using built in $dayOfMonth, $month, $year on whereDay, whereMonth, and whereYear, while whereDate basically generate range date(since mongodb doesnt have date() equivalent like on sql).

  • whereDate uses $lt & $gt comparison with UTCDateTime objects
  • whereDay uses $dayOfWeek
  • whereMonth uses $month
  • whereYear uses $year
  • whereTime uses $dateToString to format into H:M:S

@GromNaN GromNaN requested a review from alcaeus August 21, 2023 13:34
@GromNaN GromNaN marked this pull request as draft August 21, 2023 14:00
@GromNaN GromNaN marked this pull request as ready for review August 21, 2023 16:31
@GromNaN GromNaN requested a review from jmikola August 21, 2023 16:31
Birthday::create(['name' => 'Robert Doe', 'birthday' => new DateTimeImmutable('2021-05-12 10:53:14'), 'time' => '10:53:14']);
Birthday::create(['name' => 'Mark Moe', 'birthday' => new DateTimeImmutable('2021-05-12 10:53:15'), 'time' => '10:53:15']);
Birthday::create(['name' => 'Mark Moe', 'birthday' => new DateTimeImmutable('2022-05-12 10:53:16'), 'time' => '10:53:16']);
Birthday::create(['name' => 'Boo']);
Copy link
Owner Author

@GromNaN GromNaN Aug 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a document without birthday field to test the behavior.

],
],
'ne' => [
'$or' => [
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested this alternative, but got segfaults.

'ne' => ['$not' => [
    $column => [
        '$gte' => $startOfDay,
        '$lte' => $endOfDay,
    ],
]],

Copy link
Collaborator

@jmikola jmikola Aug 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

got segfaults

Segfaults in mongod (executing the query) or PHP (executing this match construct)?

I'm trying to think about how this would trigger a segfault in PHP. The only thing I can think of is that $column is referenced at multiple levels of the same return value. If so, that seems like something you might be able to isolate in a PHPT test. I'd be happy to dive into it further if so.

If this is actually a mongod segfault, I assume it'd be reproducible in the shell and would warrant a new SERVER ticket.

@@ -1084,7 +1086,7 @@ protected function compileWhereBasic(array $where): array
$operator = $operator === 'regex' ? '=' : 'not';
}

if (! isset($operator) || $operator == '=') {
if (! isset($operator) || $operator === '=' || $operator === 'eq') {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could result in a subtle behavioral change when using MongoDB\BSON\Regex objects. Quoting $eq docs:

Specifying the $eq
operator is equivalent to using the form { field: } except when the is a regular expression. See below for examples.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{ field: { eq: Regex } } is not supported ATM as it will always end to { field: Regex } for matching the regex. I don't think storing Regex in database is common enough to fix it know. PHPORM-74

@@ -1205,10 +1238,18 @@ protected function compileWhereMonth(array $where): array
{
extract($where);

$where['operator'] = $operator;
$where['value'] = $value;
$value = (int) ltrim($value, '0');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is ltrim() necessary to avoid interpreting a leading zero as octal notation? I would only expect that to apply to integer literals.

In my local testing with a PHP 8.2 REPL, the integer cast seems to ignore leading zeroes.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exactly, I blindly adopted the PR code without even testing it. Fixed.

'$expr' => [
'$'.$operator => [
[
'$month' => '$'.$column,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume $column is created by extract($where). Is there any enforcement on that? It seems hard to track given we have no typing/shape information for the $where array.

Is it possible for $column to be a field path (e.g. foo.bar), or would it only be a top-level field name?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing all this extract and replacing with array access would be more verbose but a lot more explicit.

$where['value'] = $value;

return $this->compileWhereBasic($where);
return [
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noted the original author's comment in mongodb/laravel-mongodb#2376:

whereTime isnt possible to fix rn since i cant find logic to query like time() on sql

Does this address that concern?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, fixed. There is no dedicated operator, but this was possible using $dateToString.

@GromNaN
Copy link
Owner Author

GromNaN commented Aug 22, 2023

Moved to mongodb/laravel-mongodb#2572

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants