diff --git a/sqlserver/changelog.d/19110.fixed b/sqlserver/changelog.d/19110.fixed new file mode 100644 index 0000000000000..5b971349edede --- /dev/null +++ b/sqlserver/changelog.d/19110.fixed @@ -0,0 +1 @@ +Use alternative schema collection query for sqlserver 2016 and older due to STRING_AGG not being supported until SQLServer 2017 diff --git a/sqlserver/datadog_checks/sqlserver/queries.py b/sqlserver/datadog_checks/sqlserver/queries.py index f479a4cd5ff3c..a8f32b36ab595 100644 --- a/sqlserver/datadog_checks/sqlserver/queries.py +++ b/sqlserver/datadog_checks/sqlserver/queries.py @@ -57,6 +57,36 @@ i.is_unique, i.is_primary_key, i.is_unique_constraint, i.is_disabled; """ +INDEX_QUERY_PRE_2017 = """ +SELECT + i.object_id AS id, + i.name, + i.type, + i.is_unique, + i.is_primary_key, + i.is_unique_constraint, + i.is_disabled, + STUFF(( + SELECT ',' + c.name + FROM sys.index_columns ic + JOIN sys.columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_id + WHERE ic.object_id = i.object_id AND ic.index_id = i.index_id + FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '') AS column_names +FROM + sys.indexes i +WHERE + i.object_id IN ({}) +GROUP BY + i.object_id, + i.name, + i.index_id, + i.type, + i.is_unique, + i.is_primary_key, + i.is_unique_constraint, + i.is_disabled; +""" + FOREIGN_KEY_QUERY = """ SELECT FK.parent_object_id AS id, @@ -74,6 +104,33 @@ FK.name, FK.parent_object_id, FK.referenced_object_id; """ +FOREIGN_KEY_QUERY_PRE_2017 = """ +SELECT + FK.parent_object_id AS id, + FK.name AS foreign_key_name, + OBJECT_NAME(FK.parent_object_id) AS referencing_table, + STUFF(( + SELECT ',' + COL_NAME(FKC.parent_object_id, FKC.parent_column_id) + FROM sys.foreign_key_columns AS FKC + WHERE FKC.constraint_object_id = FK.object_id + FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '') AS referencing_column, + OBJECT_NAME(FK.referenced_object_id) AS referenced_table, + STUFF(( + SELECT ',' + COL_NAME(FKC.referenced_object_id, FKC.referenced_column_id) + FROM sys.foreign_key_columns AS FKC + WHERE FKC.constraint_object_id = FK.object_id + FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '') AS referenced_column +FROM + sys.foreign_keys AS FK +WHERE + FK.parent_object_id IN ({}) +GROUP BY + FK.name, + FK.parent_object_id, + FK.object_id, + FK.referenced_object_id; +""" + XE_SESSION_DATADOG = "datadog" XE_SESSION_SYSTEM = "system_health" XE_SESSIONS_QUERY = f""" diff --git a/sqlserver/datadog_checks/sqlserver/schemas.py b/sqlserver/datadog_checks/sqlserver/schemas.py index b40dd59415fa8..ffe6f3adfa43d 100644 --- a/sqlserver/datadog_checks/sqlserver/schemas.py +++ b/sqlserver/datadog_checks/sqlserver/schemas.py @@ -16,6 +16,7 @@ from datadog_checks.sqlserver.const import ( DEFAULT_SCHEMAS_COLLECTION_INTERVAL, STATIC_INFO_ENGINE_EDITION, + STATIC_INFO_MAJOR_VERSION, STATIC_INFO_VERSION, SWITCH_DB_STATEMENT, ) @@ -23,7 +24,9 @@ COLUMN_QUERY, DB_QUERY, FOREIGN_KEY_QUERY, + FOREIGN_KEY_QUERY_PRE_2017, INDEX_QUERY, + INDEX_QUERY_PRE_2017, PARTITIONS_QUERY, SCHEMA_QUERY, TABLES_IN_SCHEMA_QUERY, @@ -395,7 +398,10 @@ def _populate_with_partitions_data(self, table_ids, table_id_to_table_data, curs @tracked_method(agent_check_getter=agent_check_getter) def _populate_with_index_data(self, table_ids, table_id_to_table_data, cursor): - rows = execute_query(INDEX_QUERY.format(table_ids), cursor) + index_query = INDEX_QUERY + if self._check.static_info_cache.get(STATIC_INFO_MAJOR_VERSION) <= 2016: + index_query = INDEX_QUERY_PRE_2017 + rows = execute_query(index_query.format(table_ids), cursor) for row in rows: table_id = row.pop("id", None) table_id_str = str(table_id) @@ -412,7 +418,10 @@ def _populate_with_index_data(self, table_ids, table_id_to_table_data, cursor): @tracked_method(agent_check_getter=agent_check_getter, track_result_length=True) def _populate_with_foreign_keys_data(self, table_ids, table_id_to_table_data, cursor): - rows = execute_query(FOREIGN_KEY_QUERY.format(table_ids), cursor) + foreign_key_query = FOREIGN_KEY_QUERY + if self._check.static_info_cache.get(STATIC_INFO_MAJOR_VERSION) <= 2016: + foreign_key_query = FOREIGN_KEY_QUERY_PRE_2017 + rows = execute_query(foreign_key_query.format(table_ids), cursor) for row in rows: table_id = row.pop("id", None) table_id_str = str(table_id)