11from __future__ import annotations
22
33import logging
4+ import re
45import typing as t
56from functools import partial
67from sqlglot import exp
@@ -112,11 +113,8 @@ def merge(
112113 ** kwargs : t .Any ,
113114 ) -> None :
114115 # Merge isn't supported until Postgres 15
115- merge_impl = (
116- super ().merge
117- if self ._connection_pool .get ().server_version >= 150000
118- else partial (logical_merge , self )
119- )
116+ major , minor = self .get_server_version ()
117+ merge_impl = super ().merge if major >= 15 else partial (logical_merge , self )
120118 merge_impl ( # type: ignore
121119 target_table ,
122120 source_table ,
@@ -125,3 +123,23 @@ def merge(
125123 when_matched = when_matched ,
126124 merge_filter = merge_filter ,
127125 )
126+
127+ def get_server_version (self ) -> t .Tuple [int , int ]:
128+ """Return major and minor server versions of the connection"""
129+ connection = self ._connection_pool .get ()
130+ connection_module = connection .__class__ .__module__
131+ if connection_module .startswith ("pg8000" ):
132+ server_version = connection .parameter_statuses .get ("server_version" )
133+ # pg8000 server version contains version as well as packaging and distribution information
134+ # e.g. 15.13 (Debian 15.13-1.pgdg120+1)
135+ match = re .search (r"(\d+)\.(\d+)" , server_version )
136+ if match :
137+ return int (match .group (1 )), int (match .group (2 ))
138+ elif connection_module .startswith ("psycopg" ):
139+ # This handles both psycopg and psycopg2 connection objects
140+ server_version = connection .info .server_version
141+ # Since major version 10, PostgreSQL represents the server version with an integer by
142+ # multiplying the server's major version number by 10000 and adding the minor version number
143+ # See https://www.postgresql.org/docs/current/libpq-status.html#LIBPQ-PQSERVERVERSION
144+ return server_version // 10000 , server_version % 100
145+ return 0 , 0
0 commit comments