Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion odev/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@
# or merged change.
# ------------------------------------------------------------------------------

__version__ = "4.29.3"
__version__ = "4.29.4"

Check notice on line 25 in odev/_version.py

View workflow job for this annotation

GitHub Actions / version-bump

Patch Update
55 changes: 32 additions & 23 deletions odev/common/connectors/postgres.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"""PostgreSQL connector."""

import os
import sys
import textwrap
from collections.abc import Mapping, MutableMapping, Sequence
Expand Down Expand Up @@ -356,7 +355,7 @@ def create_column(self, table: str, column: str, attributes: str) -> bool:
)

def _check_collation(self):
"""Check for collation mismatch by comparing system glibc version with DB version."""
"""Check for collation mismatch using PostgreSQL's own version tracking."""
if not self.odev or self.odev.in_test_mode or self.__class__._checking_collation:
return

Expand All @@ -373,15 +372,24 @@ def _check_collation(self):
if cr.fetchone()[0] < PG_VERSION_15:
return

cr.execute("SELECT datcollversion FROM pg_database WHERE datname = current_database()")
db_version = cr.fetchone()[0]

try:
sys_version = os.confstr("CS_GNU_LIBC_VERSION").split()[-1]
except (AttributeError, ValueError):
return

if db_version and sys_version and db_version != sys_version:
# Ask PostgreSQL what it considers the current collation version
# this avoids a false positive from comparing datcollversion (locale data version)
# against the glibc library version (which is different)
cr.execute(
"""
SELECT datcollversion IS DISTINCT FROM
pg_collation_actual_version(
(SELECT oid FROM pg_collation
WHERE collname = 'default'
AND collnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'pg_catalog')
LIMIT 1)
)
FROM pg_database
WHERE datname = current_database()
"""
)
result = cr.fetchone()
if result and result[0]:
has_mismatch = True
except (psycopg2.Error, RuntimeError):
return
Expand All @@ -407,25 +415,26 @@ def _check_collation(self):

def _refresh_all_collations(self):
"""Refresh collation version for local Odev databases with mismatches."""
try:
sys_version = os.confstr("CS_GNU_LIBC_VERSION").split()[-1]
except (AttributeError, ValueError):
return

target_psql = self
if self.database != "postgres":
target_psql = PostgresConnector("postgres")
target_psql.connect()

try:
databases = target_psql.query(
f"""
SELECT datname
FROM pg_database
WHERE datistemplate = false
AND datcollversion IS NOT NULL
AND datcollversion <> {string.quote(sys_version, force_single=True)}
ORDER BY datname
"""
SELECT d.datname
FROM pg_database d
WHERE d.datistemplate = false
AND d.datcollversion IS NOT NULL
AND d.datcollversion IS DISTINCT FROM
pg_collation_actual_version(
(SELECT oid FROM pg_collation
WHERE collname = 'default'
AND collnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'pg_catalog')
LIMIT 1)
)
ORDER BY d.datname
"""
)

Expand Down
Loading