diff --git a/wcs/sql.py b/wcs/sql.py index 5ba8d68e4..75397daaa 100644 --- a/wcs/sql.py +++ b/wcs/sql.py @@ -979,21 +979,37 @@ def do_formdef_indexes(formdef, created, conn, cur, concurrently=False): existing_indexes = set() if not created: cur.execute( - '''SELECT indexname - FROM pg_indexes - WHERE schemaname = 'public' - AND tablename IN (%s, %s)''', + '''SELECT pci.relname, array_length(pi.indkey, 1) + FROM pg_index pi + JOIN pg_class pci on pci.oid = pi.indexrelid + JOIN pg_class pct on pct.oid = pi.indrelid + WHERE pci.relnamespace = 'public'::regnamespace + AND pct.relname in (%s, %s)''', (table_name, evolutions_table_name), ) - existing_indexes = {x[0] for x in cur.fetchall()} + existing_indexes = {x[0]: x[1] for x in cur.fetchall()} create_index = 'CREATE INDEX' if concurrently: create_index = 'CREATE INDEX CONCURRENTLY' - if evolutions_table_name + '_fid' not in existing_indexes: + fid_idx = evolutions_table_name + '_fid' + + if fid_idx in existing_indexes and existing_indexes[fid_idx] != 2: + # The index was previously (< #67757) on formdata_id only, so + # search for it with only one key and recreate it if needed. + if concurrently: + cur.execute('DROP INDEX CONCURRENTLY %s' % fid_idx) + else: + cur.execute('DROP INDEX %s' % fid_idx) cur.execute( - '''%s %s_fid ON %s (formdata_id)''' % (create_index, evolutions_table_name, evolutions_table_name) + '''%s %s_fid ON %s (formdata_id, id)''' + % (create_index, evolutions_table_name, evolutions_table_name) + ) + elif fid_idx not in existing_indexes: + cur.execute( + '''%s %s_fid ON %s (formdata_id, id)''' + % (create_index, evolutions_table_name, evolutions_table_name) ) for attr in ('receipt_time', 'anonymised', 'user_id', 'status'):