Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
I set up Drupal from CVS yesterday, using PostgreSQL 8.0 as database.
viewing pages as anonymous user often generates the following warning:
warning: pg_query(): Query failed: ERROR: column "sessions.timestamp" must appear in the GROUP BY clause or be used in an aggregate function in /www/htdocs/includes/database.pgsql.inc on line 45.
always followed by:
user error:
query: SELECT COUNT(DISTINCT(uid)) AS count FROM sessions WHERE timestamp >= 1113122734 AND uid != 0 GROUP BY uid ORDER BY timestamp DESC in /www/htdocs/includes/database.pgsql.inc on line 62.
Comment | File | Size | Author |
---|---|---|---|
#5 | drupal-head-throttle-20255.diff | 856 bytes | Cvbge |
Comments
Comment #1
(not verified) CreditAttribution: commentedokay, after some time playing around in drupal, I could near the problem down a bit:
the message appeared about every 10th time... and my auto-throttle-probability was set to 10%. Setting the probability to 50%, and the mentioned warnings came with that percentage.
so the error seems to be in the throttle module.
anyway, looking through the support issues, similar warnings ("xyz must appear in the GROUP BY") happen in several places when pgsql is used. Maybe the problem could be solved somewhere general instead of in each module, or there should be at least a note regarding this on the module developers handbook ( http://drupal.org/node/1395 ), as I assume this is some MySQL-specific notation.
Comment #2
rkerr CreditAttribution: rkerr commentedAt my work, we ran into the same problem when doing a migration from Oracle to Postgres.
The problem, I think, is that Postgres orders its results after the select statement not before
so that it's impossible for it to order the results on a column you didn't select.
I'm told we mostly ended up rewriting the queries to avoid this problem but given the information
below, there might be a way around it without changing the queries too much.
Here are a couple of links potentially relating to this same error:
http://archives.postgresql.org/pgsql-general/2004-02/msg01199.php
http://www.postgresql.org/docs/7.4/static/queries-select-lists.html#QUERIES-DISTINCT
Comment #3
adrian CreditAttribution: adrian commentedWe always change the queries. From the link you posted :
The DISTINCT ON clause is not part of the SQL standard and is sometimes considered bad style because of the potentially indeterminate nature of its results. With judicious use of GROUP BY and subqueries in FROM the construct can be avoided, but it is often the most convenient alternative.
Adding the fields in the GROUP BY is the only way to have the sql work for both mysql and postgres.
I'm gonna make a patch for this now.
Comment #4
Uwe Hermann CreditAttribution: Uwe Hermann commentedAdrian, any updates on this?
Comment #5
Cvbge CreditAttribution: Cvbge commentedAttached patch should fix the error.
I've removed the ORDER BY (sorting does not have any impact on COUNT) and GROUP BY (we already have DISTINCT).
Please test.
Comment #6
Cvbge CreditAttribution: Cvbge commentedI believe there's a problem with throttling by registered users. The code from throttle.module:
<?php
if ($max_guests = variable_get('throttle_anonymous', 0)) {
$guests = db_result(db_query('SELECT COUNT(sid) AS count FROM {sessions} WHERE timestamp >= %d AND uid = 0', time() - $
time_period));
}
else {
$guests = 0;
}
if ($max_users = variable_get('throttle_user', 0)) {
$users = db_result(db_query('SELECT COUNT(DISTINCT(uid)) AS count FROM {sessions} WHERE timestamp >= %d AND uid != 0 GR
OUP BY uid ORDER BY timestamp DESC', time() - $time_period));
}
else {
$users = 0;
}
The second query is incorrect. Morbus run following commands for me:
SELECT COUNT(DISTINCT(uid)) AS count FROM sessions WHERE timestamp >= 0 AND uid != 0 GROUP BY uid ORDER BY timestamp DESC
Result: 9 rows of '1'
SELECT COUNT(DISTINCT(uid)) AS count FROM sessions WHERE timestamp >= 0 AND uid != 0 GROUP BY uid
Result: 9 rows of '1'
SELECT COUNT(DISTINCT(uid)) AS count FROM sessions WHERE timestamp >= 0 AND uid != 0
Result: 1 row of '9'
First two queries are incorrect. They group rows (with 1 column - uid) by uid first - this generates 9 groups with the same uid. Then DISTINCT leaves only one row in each row with the uid. Then COUNT() counts rows in each group, which gives 9 groups of count==1.
The 3rd query is correct. It counts the number of different uids meeting the criteria. It's equivalent to the query for the anonymous users.
Comment #7
Cvbge CreditAttribution: Cvbge commentedCurrently throttling by registered users does not work. I've explained it nicely and project.module or drupal have eaten my explanation without any warning. The attached post fixes postgres' GROUP BY problem and also fixes throttling problem.
Comment #8
Cvbge CreditAttribution: Cvbge commentedThere. I've even tested the patch and it works. +1 ;)
Comment #9
Jeremy CreditAttribution: Jeremy commentedAgreed, the GROUP BY and ORDER BY are both unnecessary. Please commit.
Comment #10
Dries CreditAttribution: Dries commentedCommitted to HEAD. Thanks.
Comment #11
Dries CreditAttribution: Dries commentedErr.
Comment #12
(not verified) CreditAttribution: commentedComment #13
(not verified) CreditAttribution: commentedComment #14
(not verified) CreditAttribution: commented