5353 SQLServerPaginationSupport ,
5454 SQLServerMergeSupport ,
5555 SQLServerPartitionSupport ,
56+ SQLServerOutputSupport ,
57+ SQLServerTableHintSupport ,
58+ SQLServerTryCastSupport ,
59+ SQLServerIdentitySupport ,
60+ SQLServerIndexedViewSupport ,
5661)
5762from rhosocial .activerecord .backend .dialect .mixins import (
5863 CollationMixin ,
96101from rhosocial .activerecord .backend .dialect .exceptions import UnsupportedFeatureError
97102from .collation import validate_sqlserver_collation_name
98103from .alter_table_modifier import SQLServerAlterColumnModifierMixin
104+ from .mixins .sequence import SQLServerSequenceMixin
105+ from .mixins .protocol_support import SQLServerProtocolSupportMixin
99106# SQLServerPartitionMixin is registered lazily in _register_partition_formatters()
100107
101108if TYPE_CHECKING :
@@ -169,6 +176,8 @@ class SQLServerDialect(
169176 DQLMixin ,
170177 DMLMixin ,
171178 SQLServerAlterColumnModifierMixin , # Before DDLColumnMixin to override format_*_action
179+ SQLServerProtocolSupportMixin , # SQL Server protocol contract implementations
180+ SQLServerSequenceMixin , # NEXT VALUE FOR formatter (2012+)
172181 DDLColumnMixin ,
173182 DDLTypeMixin ,
174183 # Feature mixins
@@ -203,12 +212,14 @@ class SQLServerDialect(
203212 CTESupport ,
204213 FilterClauseSupport ,
205214 WindowFunctionSupport ,
215+ SQLServerJSONSupport , # Before JSONSupport (subclass must precede its base)
206216 JSONSupport ,
207217 ReturningSupport ,
208218 AdvancedGroupingSupport ,
209219 ArraySupport ,
210220 ExplainSupport ,
211221 GraphSupport ,
222+ SQLServerLockingSupport , # Before LockingSupport
212223 LockingSupport ,
213224 MergeSupport ,
214225 OrderedSetAggregationSupport ,
@@ -224,15 +235,25 @@ class SQLServerDialect(
224235 SchemaSupport ,
225236 IndexSupport ,
226237 SequenceSupport ,
238+ SQLServerTableSupport , # Before TableSupport
227239 TableSupport ,
228240 ConstraintSupport ,
229241 IntrospectionSupport ,
230242 TransactionControlSupport ,
231243 SQLFunctionSupport ,
232- # SQL Server-specific protocols (removed from MRO to avoid diamond inheritance)
233- # SQLServerTableSupport, SQLServerLockingSupport, SQLServerJSONSupport,
234- # SQLServerTemporalTableSupport, SQLServerSequenceSupport,
235- # SQLServerFullTextSearchSupport, SQLServerPaginationSupport, SQLServerMergeSupport,
244+ # SQL Server-specific protocols (marker classes for isinstance() checks;
245+ # implementations live in SQLServerProtocolSupportMixin / SQLServerSequenceMixin)
246+ SQLServerOutputSupport ,
247+ SQLServerPaginationSupport ,
248+ SQLServerFullTextSearchSupport ,
249+ SQLServerTryCastSupport ,
250+ SQLServerTableHintSupport ,
251+ SQLServerTemporalTableSupport ,
252+ SQLServerMergeSupport ,
253+ SQLServerSequenceSupport ,
254+ SQLServerIdentitySupport ,
255+ SQLServerIndexedViewSupport ,
256+ SQLServerPartitionSupport , # Before PartitionSupport
236257 PartitionSupport ,
237258):
238259 """
@@ -1434,12 +1455,20 @@ def format_merge_statement(self, expr: "MergeExpression") -> Tuple[str, tuple]:
14341455 on_sql , on_params = expr .on_condition .to_sql ()
14351456 all_params .extend (on_params )
14361457
1458+ dialect_options = getattr (expr , "dialect_options" , {}) or {}
1459+ output_columns = dialect_options .get ("output" )
1460+ output_action = dialect_options .get ("output_action" , False )
1461+ holdlock = dialect_options .get ("holdlock" , False )
1462+
14371463 parts = [
14381464 f"MERGE INTO { target_sql } " ,
14391465 f"USING { source_sql } " ,
14401466 f"ON { on_sql } " ,
14411467 ]
14421468
1469+ if holdlock and self .supports_merge_holdlock ():
1470+ parts [0 ] = f"MERGE INTO { target_sql } WITH (HOLDLOCK)"
1471+
14431472 for action in expr .when_matched :
14441473 action_parts = []
14451474 if action .condition :
@@ -1484,6 +1513,14 @@ def format_merge_statement(self, expr: "MergeExpression") -> Tuple[str, tuple]:
14841513 action_parts .append ("THEN INSERT DEFAULT VALUES" )
14851514 parts .append (" " .join (action_parts ))
14861515
1516+ if output_columns and self .supports_merge_output ():
1517+ action_type = "$action" if output_action else None
1518+ output_sql , output_params = self .format_merge_output_clause (
1519+ list (output_columns ), action_type = action_type
1520+ )
1521+ parts .append (output_sql )
1522+ all_params .extend (output_params )
1523+
14871524 return " " .join (parts ), tuple (all_params )
14881525
14891526 def format_set_transaction (self , expr : "SetTransactionExpression" ) -> Tuple [str , tuple ]:
0 commit comments