Skip to content

Commit ee5014d

Browse files
jasonmp85claude
andauthored
Parameterize explain statement queries in postgres integration (DataDog#23392)
* Parameterize explain statement queries in postgres integration Replace dollar-quoting string interpolation with psycopg bound parameters when calling the explain function, improving robustness of query handling. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Add changelog entry for postgres explain statement fix Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 4ceafe7 commit ee5014d

3 files changed

Lines changed: 8 additions & 10 deletions

File tree

postgres/changelog.d/23392.fixed

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix explain statement query construction when statement text contains dollar-quote delimiters.

postgres/datadog_checks/postgres/explain_parameterized_queries.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
EXECUTE_PREPARED_STATEMENT_QUERY = 'EXECUTE dd_{prepared_statement}{parameters}'
2626

27-
EXPLAIN_QUERY = 'SELECT {explain_function}($stmt${statement}$stmt$)'
27+
EXPLAIN_QUERY = 'SELECT {explain_function}(%s)'
2828

2929

3030
def agent_check_getter(self):
@@ -157,10 +157,8 @@ def _explain_prepared_statement(self, conn, statement, obfuscated_statement, que
157157
prepared_statement_query = self._generate_prepared_statement_query(conn, query_signature)
158158
return self._execute_query_and_fetch_rows(
159159
conn,
160-
EXPLAIN_QUERY.format(
161-
explain_function=self._explain_function,
162-
statement=prepared_statement_query,
163-
),
160+
EXPLAIN_QUERY.format(explain_function=self._explain_function),
161+
(prepared_statement_query,),
164162
)
165163
except Exception as e:
166164
logged_statement = obfuscated_statement
@@ -189,9 +187,9 @@ def _execute_query(self, conn, query):
189187
logger.debug('Executing query=[%s]', query)
190188
cursor.execute(query, ignore_query_metric=True)
191189

192-
def _execute_query_and_fetch_rows(self, conn, query):
190+
def _execute_query_and_fetch_rows(self, conn, query, params=None):
193191
with conn.cursor() as cursor:
194-
cursor.execute(query, ignore_query_metric=True)
192+
cursor.execute(query, params, ignore_query_metric=True)
195193
return cursor.fetchall()
196194

197195
def _is_parameterized_query(self, statement: str) -> bool:

postgres/datadog_checks/postgres/statement_samples.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -725,9 +725,8 @@ def _run_explain(self, dbname, statement, obfuscated_statement):
725725
"Running query on dbname=%s: %s(%s)", dbname, self._explain_function, obfuscated_statement
726726
)
727727
cursor.execute(
728-
"""SELECT {explain_function}($stmt${statement}$stmt$)""".format(
729-
explain_function=self._explain_function, statement=statement
730-
),
728+
"SELECT {}(%s)".format(self._explain_function),
729+
(statement,),
731730
ignore_query_metric=True,
732731
)
733732
result = cursor.fetchone()

0 commit comments

Comments
 (0)