Using Drupal 7.9 with PostgreSQL 9.
When I try to create a new node OR even when I try to edit an existing node as the site super user I'm getting this error:

PDOException: SQLSTATE[42803]: Grouping error: 7 ERROR: column "u.name" must appear in the GROUP BY clause or be used in an aggregate function LINE 1: ...function, load_args, is_new) SELECT u.uid AS uid, u.name AS ... ^: INSERT INTO subscriptions_queue (uid, name, language, module, field, value, author_uid, send_interval, digest, suspended, last_sent, load_function, load_args, is_new) SELECT u.uid AS uid, u.name AS name, u.language AS language, s.module AS module, s.field AS field, s.value AS value, s.author_uid AS author_uid, s.send_interval AS send_interval, su.digest AS digest, su.suspended AS suspended, COALESCE(sls.last_sent, 0) AS last_sent, 'subscriptions_content_load_node' AS load_function, '575' AS load_args, 1 AS is_new FROM subscriptions s INNER JOIN subscriptions_user su ON s.recipient_uid = su.uid INNER JOIN users u ON su.uid = u.uid LEFT OUTER JOIN subscriptions_last_sent sls ON su.uid = sls.uid AND s.send_interval = sls.send_interval INNER JOIN taxonomy_index tn ON s.value = CAST(tn.tid AS VARCHAR) WHERE (s.module = :db_condition_placeholder_0) AND (s.field = :db_condition_placeholder_1) AND (s.author_uid IN (:db_condition_placeholder_2, :db_condition_placeholder_3)) AND (tn.nid = :db_condition_placeholder_4) GROUP BY u.uid, tn.nid; Array ( ) in subscriptions_queue() (line 438 of /sites/all/modules/contrib/subscriptions/subscriptions.module).

I have also seen this same error with the notification module if that helps with anything.

Comments

salvis’s picture

Please try the following:

Locate the line

          ->groupBy('u.uid');

in subscriptions.module and replace it with

          ->groupBy('u.uid', 'u.name', 'u.language');

Does that help?

I have also seen this same error with the notification module if that helps with anything.

Hehehe, what does that tell you about their porting effort? I'm sure my fix will appear in their module soon...

americkson’s picture

You know I actually tried the code below to see what would happen just before I posted the ticket. (which I believe would be the same thing you suggested, but if I'm wrong please let me know.) :

->groupBy('u.uid')->groupBy('u.name')->groupBy('u.language');

PDOException: SQLSTATE[42803]: Grouping error: 7 ERROR: column "s.module" must appear in the GROUP BY clause or be used in an aggregate function LINE 1: ...function, .....

The error was basically the same thing just indicating the 's' table starting with the 's.module' column (see below). So I thought it might be a little deeper than that.

Unfortunately I cannot test your suggestion at this moment because I can't connect to my database which only works internally at the office. I will see if I can load up an old database dump to it try out.

I really appreciate the quick response!!!

salvis’s picture

Hmm, actually, your syntax is the correct one and mine isn't...

I have to research this...

salvis’s picture

It seems that we have two choices: either we ->groupBy() on each and every fields, or we replace the ->groupBy('u.uid') with

->distinct()

There are warnings about distinct() possibly being inefficient, but I'm not convinced that a long string of groupBy()'s would be better...

Will pgsql accept distinct()?

americkson’s picture

Ok I have tried both options. No Luck. The groupBy() on each field gave me something new however...

  • First I went with the ->groupBy() on each field:
    line# 406 in subscriptions.module
->groupBy('u.uid')->groupBy('u.name')->groupBy('u.language')->groupBy('s.module')->groupBy('s.field')
->groupBy('s.value')->groupBy('s.author_uid')->groupBy('s.send_interval')->groupBy('su.digest')
->groupBy('su.suspended')->groupBy('sls.last_sent');

Returns this error:
PDOException: SQLSTATE[55000]: Object not in prerequisite state: 7 ERROR: currval of sequence "subscriptions_queue_sqid_seq" is not yet defined in this session: INSERT INTO subscriptions_queue (uid, name, language, module, field, value, author_uid, send_interval, digest, suspended, last_sent, load_function, load_args, is_new) SELECT u.uid AS uid, u.name AS name, u.language AS language, s.module AS module, s.field AS field, s.value AS value, s.author_uid AS author_uid, s.send_interval AS send_interval, su.digest AS digest, su.suspended AS suspended, COALESCE(sls.last_sent, 0) AS last_sent, 'subscriptions_content_load_node' AS load_function, '584' AS load_args, 1 AS is_new FROM subscriptions s INNER JOIN subscriptions_user su ON s.recipient_uid = su.uid INNER JOIN users u ON su.uid = u.uid LEFT OUTER JOIN subscriptions_last_sent sls ON su.uid = sls.uid AND s.send_interval = sls.send_interval INNER JOIN taxonomy_index tn ON s.value = CAST(tn.tid AS VARCHAR) WHERE (s.module = :db_condition_placeholder_0) AND (s.field = :db_condition_placeholder_1) AND (s.author_uid IN (:db_condition_placeholder_2, :db_condition_placeholder_3)) AND (tn.nid = :db_condition_placeholder_4) GROUP BY u.uid, u.name, u.language, s.module, s.field, s.value, s.author_uid, s.send_interval, su.digest, suspended, sls.last_sent, tn.nid; Array ( ) in subscriptions_queue() (line 438 of /sites/all/modules/contrib/subscriptions/subscriptions.module).

  • Next I went with distinct():
    line# 406 in subscriptions.module
->distinct();

Returns this error:
PDOException: SQLSTATE[42803]: Grouping error: 7 ERROR: column "u.uid" must appear in the GROUP BY clause or be used in an aggregate function LINE 1: ...load_function, load_args, is_new) SELECT DISTINCT u.uid AS u... ^: INSERT INTO subscriptions_queue (uid, name, language, module, field, value, author_uid, send_interval, digest, suspended, last_sent, load_function, load_args, is_new) SELECT DISTINCT u.uid AS uid, u.name AS name, u.language AS language, s.module AS module, s.field AS field, s.value AS value, s.author_uid AS author_uid, s.send_interval AS send_interval, su.digest AS digest, su.suspended AS suspended, COALESCE(sls.last_sent, 0) AS last_sent, 'subscriptions_content_load_node' AS load_function, '585' AS load_args, 1 AS is_new FROM subscriptions s INNER JOIN subscriptions_user su ON s.recipient_uid = su.uid INNER JOIN users u ON su.uid = u.uid LEFT OUTER JOIN subscriptions_last_sent sls ON su.uid = sls.uid AND s.send_interval = sls.send_interval INNER JOIN taxonomy_index tn ON s.value = CAST(tn.tid AS VARCHAR) WHERE (s.module = :db_condition_placeholder_0) AND (s.field = :db_condition_placeholder_1) AND (s.author_uid IN (:db_condition_placeholder_2, :db_condition_placeholder_3)) AND (tn.nid = :db_condition_placeholder_4) GROUP BY tn.nid; Array ( ) in subscriptions_queue() (line 438 of /sites/all/modules/contrib/subscriptions/subscriptions.module).

  • Then I tried to pass in the u.uid in distinct():
    line# 406 in subscriptions.module

Then I tried to pass in the u.uid in distinct():
line# 406 in subscriptions.module

->distinct('u.uid');

Returns this error (basically the same as above):
PDOException: SQLSTATE[42803]: Grouping error: 7 ERROR: column "u.uid" must appear in the GROUP BY clause or be used in an aggregate function LINE 1: ...load_function, load_args, is_new) SELECT DISTINCT u.uid AS u... ^: INSERT INTO subscriptions_queue (uid, name, language, module, field, value, author_uid, send_interval, digest, suspended, last_sent, load_function, load_args, is_new) SELECT DISTINCT u.uid AS uid, u.name AS name, u.language AS language, s.module AS module, s.field AS field, s.value AS value, s.author_uid AS author_uid, s.send_interval AS send_interval, su.digest AS digest, su.suspended AS suspended, COALESCE(sls.last_sent, 0) AS last_sent, 'subscriptions_content_load_node' AS load_function, '586' AS load_args, 1 AS is_new FROM subscriptions s INNER JOIN subscriptions_user su ON s.recipient_uid = su.uid INNER JOIN users u ON su.uid = u.uid LEFT OUTER JOIN subscriptions_last_sent sls ON su.uid = sls.uid AND s.send_interval = sls.send_interval INNER JOIN taxonomy_index tn ON s.value = CAST(tn.tid AS VARCHAR) WHERE (s.module = :db_condition_placeholder_0) AND (s.field = :db_condition_placeholder_1) AND (s.author_uid IN (:db_condition_placeholder_2, :db_condition_placeholder_3)) AND (tn.nid = :db_condition_placeholder_4) GROUP BY tn.nid; Array ( ) in subscriptions_queue() (line 438 of /sites/all/modules/contrib/subscriptions/subscriptions.module).

salvis’s picture

Thank you for the tests.

1. In the first one you're missing last_sent, load_function, load_args, and is_new. In general, specifying aliases is probably the better approach — groupBy('sls.last_sent') is wrong. Also, I'm seeing no GROUP BY clause in the error message at all, which is strange.

2. If you add the ->distinct(), then you must remove the ->groupBy('tn.nid').

3. AFAICS this produces exactly the same SQL statement.

americkson’s picture

  1. For the 1st test. I actually left off the 'sls.last_sent' the first time but then the error was the exact same as before but it was looking for the 'sls.last_sent' column.

    PDOException: SQLSTATE[42803]: Grouping error: 7 ERROR: column "sls.last_sent" must appear in the GROUP BY clause or be used in an aggregate function LINE 1: ...function, .....

    So I added ->groupBy('sls.last_sent') to the code then I received the new error. So I figured that I would post that for you. I will try do another b adding the others you suggest as well and see what happens. It might take me a little bit. I need to get it running locally on my machine since I'm not at the office.

  2. for #2. I did completely replace the ->groupBy() with ->distinct(). However I see a little further down there is this:
    if (!empty($query['groupby'])) {
              $select
                ->groupBy($query['groupby']);
            }
    

    Do I need to replace that as well?

salvis’s picture

1. The 'sls.last_sent' is inside a function. It's the result that we need to group by. Using the alias (the name after the 'AS') will always be correct.

2. On the last line but one of your message we see
:db_condition_placeholder_4) GROUP BY tn.nid; Array ( ) in subscriptions_queue() (line 438 of /sites/all/modules/contrib

It's that GROUP BY that we need to get rid of, wherever it comes from. I'd be a bit surprised if it came from ->groupBy($query['groupby']), but for the sake of the test remove the entire if, if that's what it takes.

americkson’s picture

Hello -

Sorry about the delay in responses. I was out of town for a long weekend.

I have updated the groupBy() to what you suggested and I also removed the other IF statement mentioned above:

->groupBy('u.uid')->groupBy('u.name')->groupBy('u.language')        ->groupBy('s.module')->groupBy('s.field')->groupBy('s.value')->groupBy('s.author_uid')->groupBy('s.send_interval')
->groupBy('su.digest')->groupBy('su.suspended')
->groupBy('last_sent')->groupBy('load_function')->groupBy('load_args')->groupBy('is_new');

Here is the error I get:
PDOException: SQLSTATE[55000]: Object not in prerequisite state: 7 ERROR: currval of sequence "subscriptions_queue_sqid_seq" is not yet defined in this session: INSERT INTO subscriptions_queue (uid, name, language, module, field, value, author_uid, send_interval, digest, suspended, last_sent, load_function, load_args, is_new) SELECT u.uid AS uid, u.name AS name, u.language AS language, s.module AS module, s.field AS field, s.value AS value, s.author_uid AS author_uid, s.send_interval AS send_interval, su.digest AS digest, su.suspended AS suspended, COALESCE(sls.last_sent, 0) AS last_sent, 'subscriptions_content_load_node' AS load_function, '588' AS load_args, 1 AS is_new FROM subscriptions s INNER JOIN subscriptions_user su ON s.recipient_uid = su.uid INNER JOIN users u ON su.uid = u.uid LEFT OUTER JOIN subscriptions_last_sent sls ON su.uid = sls.uid AND s.send_interval = sls.send_interval INNER JOIN taxonomy_index tn ON s.value = CAST(tn.tid AS VARCHAR) WHERE (s.module = :db_condition_placeholder_0) AND (s.field = :db_condition_placeholder_1) AND (s.author_uid IN (:db_condition_placeholder_2, :db_condition_placeholder_3)) AND (tn.nid = :db_condition_placeholder_4) GROUP BY u.uid, u.name, u.language, s.module, s.field, s.value, s.author_uid, s.send_interval, su.digest, su.suspended, last_sent, load_function, load_args, is_new; Array ( ) in subscriptions_queue() (line 442 of /sites/all/modules/contrib/subscriptions/subscriptions.module).

anilkhadka’s picture

When I try to edit existing node after installing subscriptions 7.x-1.0-alpha6, it gave me same error as in first post.When I changed subscriptions.module file by adding group by of all field as mentioned above, it gave me another error exactly same as just mentioned above. I tried by using developer version and alpha5 version but I am getting same error. Is there any solution ?

salvis’s picture

Hmm, you're both concentrating on #1. #1 is more of an academic exercise. We may be able to pull it off, but I think it would be very inefficient, even more so than distinct(). Have you looked into really getting rid of the "GROUP BY" in the message?

With "Object not in prerequisite state: 7 ERROR: currval of sequence "subscriptions_queue_sqid_seq" is not yet defined in this session" we're going into uncharted territory...

anilkhadka’s picture

When I disabled the Subscription module in my working server then there is no error. However, When I installed same subscription module in my localhost , it worked fine. I don't think it is solely the problem of "Group by" error because it is now showing different error after using other field in group by.Actually,I have no knowledge of this type of error.Is there any clue or idea to get rid of this error so that I can use Subscription module ? It would be great help for me.

salvis’s picture

This is a PostgreSQL-only issue. If you're running MySQL on localhost, then it'll work fine. But PostgreSQL is obstinate...

salvis’s picture

Title: PDOexception error when creating or saving nodes - PostgreSQL » PostgreSQL: PDOexception error when creating or saving nodes
Version: 7.x-1.0-alpha6 » 7.x-1.0-beta1
Status: Active » Postponed (maintainer needs more info)

Anyone tried to get rid of the "GROUP BY" as mentioned in #8 and #11?

americkson’s picture

I'm still working on it. At the moment I'm trying to get the SQL to actually put something in the subscriptions_queue table. What I have found out is that it seems to have an issue with the taxonomy_index table not having matching values in the 'value' column. Here is the SQL statement I have been running/working with:

I have a couple items commented out (--) once I do that on those lines I get results. Once I have the taxonomy references uncommitted I get no results.

--INSERT INTO subscriptions_queue 
SELECT 
	u.uid AS uid, 
	u.name AS name, 
	u.language AS language, 
	s.module AS module, 
	s.field AS field, 
	s.value AS value, 
	s.author_uid AS author_uid, 
	s.send_interval AS send_interval, 
	su.digest AS digest,
	'628' AS load_args,
	'subscriptions_content_load_node' AS load_function,
	1 AS is_new,
	COALESCE(sls.last_sent, 0) AS last_sent, 
	su.suspended AS suspended
FROM subscriptions s 
	INNER JOIN subscriptions_user su ON s.recipient_uid = su.uid 
	INNER JOIN users u ON su.uid = u.uid 
	LEFT OUTER JOIN subscriptions_last_sent sls ON su.uid = sls.uid AND s.send_interval = sls.send_interval 
	--INNER JOIN taxonomy_index tn ON s.value = CAST(tn.tid AS VARCHAR) 
WHERE (s.module = 'node') 
	AND (s.field = 'tid') 
	AND (s.author_uid IN (1, -1)) 
	--AND (tn.nid = 629) 
GROUP BY 
	u.uid, u.name, u.language, s.module, s.field, s.value, s.author_uid, s.send_interval, su.digest, su.suspended, last_sent--, tn.nid
americkson’s picture

Well it's now working. 2 things.

  • The following code needs to replace the ->groupBy(u.uid); . We were on the right track:
    ->groupBy('u.uid')->groupBy('u.name')->groupBy('u.language')
    ->groupBy('s.module')->groupBy('s.field')->groupBy('s.value')->groupBy('s.author_uid')->groupBy('s.send_interval')
    ->groupBy('su.digest')->groupBy('su.suspended')
    ->groupBy('last_sent');
    
  • The other part that was that in order for the content to publish there needed to be a user already subscribed to content. So for the function subscriptions_queue(array $event) { function maybe there should be some check to see if there is subscribers, if not skip the $insert->execute();

I think the later part is why I though there was an issue with the taxonomy stuff that I mentioned in the post above.

salvis’s picture

Status: Postponed (maintainer needs more info) » Active

Ouch, that looks really nasty. And I could imagine that it's quite inefficient, too. Is there really no way to make it work with distinct()?

in order for the content to publish there needed to be a user already subscribed to content.

I don't understand what you mean by "for the content to publish". What happens (or not) if the content does not publish?

Do you mean PostgreSQL generates an error if the SELECT inside the INSERT does not return any rows? That would mean we have to do the same SELECT twice...

salvis’s picture

Status: Active » Postponed (maintainer needs more info)

Still waiting for an answer here...

salvis’s picture

seattlehimay’s picture

After playing with this a bit, I feel like I can answer your questions posed in #17.

I believe americkson is saying that the error in #9 is thrown upon new node creation because the sid is null until a user is subscribed to content. There is a old but similar core issue here: http://drupal.org/node/445214

Now as for getting rid of the groupBy's, I believe you must actually use "DISTINCT ON" in postgres if you wish to construct the query without the groupby's. But that, of course, cases mysql issues.

(Sorry I'm not more useful in actually solving these!!)

salvis’s picture

Thank you for looking into this!

the sid is null until a user is subscribed to content

The {subscriptions}.sid? Where does that enter into the picture?

The issue that you linked seems to say that there would be a problem, if we passed something for {subscriptions_queue}.sqid, but we don't.

Do you get the "Object not in prerequisite state: 7 ERROR: currval of sequence 'subscriptions_queue_sqid_seq' is not yet defined in this session" error, too? I don't know how to overcome this.

If there are no subscribers, then the sub-select should not return any rows, and thus nothing should be inserted. It's not unthinkable that pgsql hates that, but doing the query twice (once to find out whether we have subscriptions, and again to actually create the queue entries) is not nice nor efficient.

I don't know what to do here... This is supposed to be efficient, because the INSERT SELECT is done entirely in the database, but if we can't get this to work for pgsql, then I guess we'll have to special case pgsql and loop in PHP... I have no idea how this will scale to lots of subscribers, but I'm sure that doing 5000 separate INSERTs takes longer than the corresponding INSERT SELECT.

 

Re DISTINCT:
According to #5 distinct() produces "SELECT DISTINCT u.uid AS uid, u.name AS name, ...". I don't think we can convince DBTNG to produce DISTINCT ON. I guess we'll go with lotsa groupBy() for pgsql...

seattlehimay’s picture

Does #33 here help? http://drupal.org/node/761976#comment-3357570
As a possible solution, call nextval to initialize currval?

Admittedly, I'm stabbing in the dark and over my head. I should stop now ;)

salvis’s picture

No, not really. All this is happening inside InsertQuery_pgsql::execute. If nothing was inserted, then there can't be any currval.

But here's an idea: try replacing

        $insert = db_insert('subscriptions_queue')

with

        $insert = db_insert('subscriptions_queue', array('return' => Database::RETURN_NULL))

From what you write I'm still not 100% sure whether you can reproduce that problem, but if you can, this might help...

salvis’s picture

Reminder: this will need to be backported to D6: #1405990: PostgreSQL: error with group by when adding/saving a node.

seattlehimay’s picture

Indeed, the error was reproducible on my site.

But the code in #23 along with the groupby code in #16 has fixed the problem. Thanks much.

salvis’s picture

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

I've committed this to the -dev version (give it up to 12h to be repackaged).

Please check it out and let us know if it works.

salvis’s picture

Version: 7.x-1.0-beta1 » 6.x-1.x-dev
Status: Needs review » Patch (to be ported)

@seattlehimay: Have you tried the D7 -dev version?

seattlehimay’s picture

Yes, sorry. It is installed, and no errors so far. I haven't extensively tested yet, but I also haven't seen any sign of the named bug. Thanks much!!

salvis’s picture

Status: Patch (to be ported) » Fixed

Thanks.

I've committed an equivalent fix to 6.x-1.x-dev.

Status: Fixed » Closed (fixed)

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