Problem/Motivation

There was an issue where duplicate rows were added to the password_policy_history table that was fixed here:

#3095980: Password history policy inserts password twice in password_policy_history table

but it did not include an update hook to remove the existing duplicates. An update hook was added to do this here:

#3266140: Create hook_update to remove duplicated entries in password_policy_history

but it doesn't work for some databases and thus people are seeing errors like below.

An attempt was made to restructure the query to support all databases but this has proved difficult so the final approach is to just delete all the history. Not ideal, but will work for all databases. All new data in the table should not contain duplicates because the above fix.

Original description:

Drupal 9.4.8
Postgresql 12.x
password policy version 3.2

password_policy 3.1 works fine, but upgrading to password_policy 3.2 fails as follows:

>  [error]  SQLSTATE[42601]: Syntax error: 7 ERROR:  syntax error at or near "t1"
> LINE 1: DELETE t1 FROM "password_policy_history" t1 INNER JOIN "pass...
>                ^: DELETE t1 FROM "password_policy_history" t1 INNER JOIN "password_policy_history" t2 WHERE t1.id < t2.id AND t1.pass_hash = t2.pass_hash AND t1.timestamp = t2.timestamp; Array
> (
> )

Steps to reproduce

Postgresql v12, upgrading versions of dependencies

Proposed resolution

1. Update the update hook to delete all data from the table.

2. For those who've already run the update hook, they can manually remove the data from the table or run the new update hook once this code has been committed and they are using the updated module.

Remaining tasks

  • Update code
  • Review and test
  • Commit

User interface changes

User will not see error when updating to new version with any database.

API changes

Data model changes

Old data will be removed but the data model is not changing.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

joseph.olstad created an issue. See original summary.

joseph.olstad’s picture

uninstalling the module and re-installing it again seems to be a workaround. losing configuration is a bit of an issue but that's all the time I have for this right now.

joseph.olstad’s picture

Issue tags: +psql
joseph.olstad’s picture

Issue summary: View changes
joseph.olstad’s picture

Status: Active » Needs work

Until this is fixed, a workaround is to lock to password_policy version 3.1 and avoid the broken hook update for password_policy_update_8304

composer require drupal/password_policy:'3.1'

this isn't fixed in 3.x-dev, tried both 3.2 and 3.x-dev, lock to 3.1 for now.

joseph.olstad’s picture

Issue summary: View changes
joseph.olstad’s picture

Issue summary: View changes
joseph.olstad’s picture

Title: Update failed, password_policy_update_8304 » postgresql Update failed, password_policy_update_8304
Michelle-Buckby’s picture

Coming across the issue with the update hook:
`password_policy_update_8304`

This is after updating from 3.0 to 4.0.0
At first with `drush updb` this update hook seems to hang , on a second attempt it fails and aborts:

```
> [error] Update failed: password_policy_update_8304
[error] Update aborted by: password_policy_update_8304
[error] Finished performing updates.
```
We cannot lock to 3.1 as suggested because we need 4.0.0 as trying to upgrade a project to D10

joseph.olstad’s picture

If my memory serves me correctly (it's been a while), a likely workaround to this issue is to uninstall the password_policy module, you may need to unwind some *.info.yml dependencies and rebuild caches to prevent other modules or custom modules from being uninstalled also. Once this module is uninstalled, install the 4.0.0+ password_policy.

You can test to see what happens by trying this drush command:

drush pmu password_policy;

If the only module that is proposed for uninstall is password_policy, this should make it easier.

Probably do this before upgrading the module.

Then in another step, upgrade the password_policy module and then install it/configure it.

Michelle-Buckby’s picture

Thank you for your reply, unfortunately trying to uninstall the module with drush seems to just hang.
This was after unwinding some of the *.info.yml to prevent dependencies from uninstalling first.

Not able to give it another go at the moment but will try again at a later date..and try to get more info.

joseph.olstad’s picture

joseph.olstad’s picture

Status: Needs work » Needs review

I haven't tested this with mysql yet, however it works with Postgresql.

amanp’s picture

I confirm that the patch in #12 works with Postgresql. Thanks

Michelle-Buckby’s picture

Thank you @joseph.olstad , just getting back here to say I've successfully updated Password Policy on two projects now, no further issues related to this.

joseph.olstad’s picture

Status: Needs review » Reviewed & tested by the community

RTBC
based on comment #14

joseph.olstad’s picture

Assigned: Unassigned » joseph.olstad
Status: Reviewed & tested by the community » Needs review

ok this is RTBC for Postgresql, however if someone with MariaDB or MySQL could please test to make sure this works in MySQL, that'd be great, with that said, I could synthesize a test to see myself , I'll write some synthetic test code to try this on mariadb/mysql and see if this is compatible.

joseph.olstad’s picture

Status: Needs review » Needs work

This patch works great with Postgresql, however it fails with MariaDB/MySQL as follows:

SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 't1 USING "password_policy_history" t2 WHERE t1.id < t2.id AND t1.pass_hash = ...' at line 1: DELETE FROM "password_policy_history" t1 USING "password_policy_history" t2 WHERE t1.id < t2.id AND t1.pass_hash = t2.pass_hash AND t1.timestamp = t2.timestamp; Array

I think this query should be rewritten.

joseph.olstad’s picture

This is a patch that is compatible with all rdbms versions and drivers. sqlite, mariadb/mysql, psql/postgresql , mssql and others.

It is a brute force fix for all.

Delete ALL the history that avoids using vendor only query syntax that are not ansi-sql compliant. Some might not like this but I'm guessing most will approve.

joseph.olstad’s picture

Status: Needs work » Needs review
joseph.olstad’s picture

Assigned: joseph.olstad » Unassigned
joseph.olstad’s picture

Title: postgresql Update failed, password_policy_update_8304 » [ansi-sql compliant updates] - postgresql/mssql/mysql/sqlite Update failed, password_policy_update_8304
joseph.olstad’s picture

Title: [ansi-sql compliant updates] - postgresql/mssql/mysql/sqlite Update failed, password_policy_update_8304 » [ansi-sql compliant updates] - postgresql/mssql/mysql/sqlite password_policy_update_8304

Kristen Pol credited D2ev.

Kristen Pol’s picture

Kristen Pol’s picture

Version: 8.x-3.x-dev » 4.0.x-dev

This should be against 4.0.x as 8.x branches are no longer supported, so changing version.

Kristen Pol’s picture

Assigned: Unassigned » Kristen Pol

Assigning to myself for review.

Kristen Pol’s picture

Kristen Pol’s picture

Issue summary: View changes

Updating the summary to provide more context.

Kristen Pol’s picture

Issue summary: View changes

Minor wording change to summary.

Kristen Pol’s picture

Assigned: Kristen Pol » Unassigned
Status: Needs review » Fixed

Thanks everyone for your work on this issue. I've merged the fix and included updated/more comments for more clarification on what happened.

Status: Fixed » Closed (fixed)

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

Kristen Pol credited achap.

Kristen Pol’s picture

Kristen Pol’s picture

This is part of the new 4.0.1 release.

joseph.olstad’s picture

Thanks @Kristen Pol, definately the right call here, every system is supported.

joseph.olstad’s picture

Thanks for the credit on this also! :)