Home>Administration>Reports>Recent log messages
Drupal\Core\Database\DatabaseExceptionWrapper: SQLSTATE[42883]: Undefined function: 7 ERROR: function unix_timestamp(timestamp with time zone) does not exist LINE 1: SELECT (relevancy * pow(2, -(UNIX_TIMESTAMP(NOW()) - timesta... ^ HINT: No function matches the given name and argument types. You might need to add explicit type casts.: SELECT (relevancy * pow(2, -(UNIX_TIMESTAMP(NOW()) - timestamp)/86400.00)) AS cutoff FROM {redirect_404} r404 ORDER BY cutoff DESC NULLS LAST LIMIT 1 OFFSET 10000; Array ( ) in Drupal\redirect_404\SqlRedirectNotFoundStorage->purgeOldRequests() (line 114 of /var/www/mysite/web/modules/contrib/redirect/modules/redirect_404/src/SqlRedirectNotFoundStorage.php).
Comments
Comment #2
thiago.maia@gmail.com commentedFunction UNIX_TIMESTAMP does not exist in PostgreSQL, only with MySQL. Do check this link.
Quick fix until a proper patch is released is to edit /var/www/mysite/web/modules/contrib/redirect/modules/redirect_404/src/SqlRedirectNotFoundStorage.php and replace 3 occurrences of "UNIX_TIMESTAMP(NOW())" with "EXTRACT(EPOCH FROM NOW())".
Comment #3
berdirThanks. I think we just need to move the generation of the current timestamp to PHP and pass that in as an argument.
Comment #4
tduong commentedDone as @Berdir suggested at comment #3.
Comment #5
tduong commentedReplaced IFNULL() with COALESCE()
Comment #6
berdirI still don't really understand why we needed to introduce all that complexity, a simply query to delete the records that were not updated for the longest would have been *so* much simpler.
Now have to debug fun things like this. Apparently $cut_off is *really* small: 2.98101277755881e-59.
And apparently sqlite doesn't support comparing values with such a high precision and just deletes everything. Switched to fetching the actual relevancy and deleting based on that. That passes but of course makes the whole thing pointless as we are then basically back to just deleting everything that is higher than a certain relevancy ad we don't need the whole calculation anymore :p
I also like how the test sets the row limit to 5 but asserts that we have 6 records ;)
halp?
Comment #7
berdirDiscussed this a while back, we agreed on using log() to sort on the count. Then we still get a sort based on usage, but it's a lot less complicated than this.
Comment #8
tduong commentedTried to improve the delete query using log() as discussed (supported by MySQL and PostgreSQL). Still need to define the condition on timestamp for the SQLite database driver case and fix the tests. Will continue tomorrow.
Comment #10
tduong commentedImproved purgeOldRequests() and fixed the test, now it passes locally.
I didn't use log() anymore because I get incorrect values, i.e. "count => sort_condition result":
1 -> 0,
5 -> 0,
12 -> 1,
300 -> 1,
315 -> 1,
1557 -> 1.
In the test I've used this count example and the timestamp as @Berdir and I have discussed yesterday.
Comment #11
berdirboth before and after is way too complicated.
The discussion was length XOR log. not both.
You can simplify this to $count_log = 'log(10, count)'. Nothing else. No driver logic (yet).
Why groupBy()? We don't want to group, just orderBy('count_log')->orderBy('timestamp')
Comment #12
tduong commentedOk, discussed and checked with @Berdir, now purgeOldRequests() should have the expected implementation. Fixed the test for the SQLite case as well.
Comment #13
berdirWe need an update function to remove this column for existing sites.
This service only exists in 8.3, we can't add that yet.
yes, stick to REQUEST_TIME for now.
Why Determine => Settle, I actually like the old verb more I think.
make an explicit check for mysql and postgresql. no idea if other databases support this. And add a comment that sqlite does not support log() functions, so we only consider the timestamp.
and less visits (on a logarithmic scale) ...
no need for ..., just .
is this left-over? I don't think we need this?
I would suggest to to two test runs with the same data. Once keep 3 records, once keep 4 or 5, with different asserts.
instead of documenting this and calculting yourself, you could simply use strtotime('-1 week'), then you get a timestamp and it is self-documenting.
Comment #14
tduong commentedDone as suggested above.
Comment #15
slashrsm commentedA nitpik:
We don't need to specifically delete the entries. It should be automatically done when we drop the field.
Comment #16
tduong commentedThank you :)
removed the unnecessary lines in the hook_update() function.
Comment #17
berdirLooks pretty ok now, below are some notes to me for some cleanup before commit.
restructure comments a bit here.
also here, it is technically and OR, but in human-speak, we're not doing an OR but an AND really (delete records matching condition A and delete records matching B).
check if we can avoid duplicated code.
Comment #18
berdirComment #20
berdirCommitted.
Comment #21
berdirArgh, forgot to actually run the sqlite tests, which didn't pass. This fixes them and does a bit more cleanup.
Comment #23
berdirCommitted.