@@ -146,7 +146,7 @@ module PEP249 {
146146 * Note: while `execute` method on a connection is not part of PEP249, if it is used, we
147147 * recognize it as an alias for constructing a cursor and calling `execute` on it.
148148 *
149- * See https://www .python.org/dev/peps/ pep-0249/#id15 .
149+ * See https://peps .python.org/pep-0249/#execute .
150150 */
151151 private DataFlow:: TypeTrackingNode execute ( DataFlow:: TypeTracker t ) {
152152 t .startInAttr ( "execute" ) and
@@ -161,14 +161,44 @@ module PEP249 {
161161 * Note: while `execute` method on a connection is not part of PEP249, if it is used, we
162162 * recognize it as an alias for constructing a cursor and calling `execute` on it.
163163 *
164- * See https://www .python.org/dev/peps/ pep-0249/#id15 .
164+ * See https://peps .python.org/pep-0249/#execute .
165165 */
166166 DataFlow:: Node execute ( ) { execute ( DataFlow:: TypeTracker:: end ( ) ) .flowsTo ( result ) }
167167
168- /** A call to the `execute` method on a cursor (or on a connection). */
168+ /**
169+ * A call to the `execute` method on a cursor or a connection.
170+ *
171+ * See https://peps.python.org/pep-0249/#execute
172+ *
173+ * Note: While `execute` method on a connection is not part of PEP249, if it is used, we
174+ * recognize it as an alias for constructing a cursor and calling `execute` on it.
175+ */
169176 private class ExecuteCall extends SqlExecution:: Range , DataFlow:: CallCfgNode {
170177 ExecuteCall ( ) { this .getFunction ( ) = execute ( ) }
171178
172179 override DataFlow:: Node getSql ( ) { result in [ this .getArg ( 0 ) , this .getArgByName ( "sql" ) ] }
173180 }
181+
182+ private DataFlow:: TypeTrackingNode executemany ( DataFlow:: TypeTracker t ) {
183+ t .startInAttr ( "executemany" ) and
184+ result in [ Cursor:: instance ( ) , Connection:: instance ( ) ]
185+ or
186+ exists ( DataFlow:: TypeTracker t2 | result = executemany ( t2 ) .track ( t2 , t ) )
187+ }
188+
189+ private DataFlow:: Node executemany ( ) { executemany ( DataFlow:: TypeTracker:: end ( ) ) .flowsTo ( result ) }
190+
191+ /**
192+ * A call to the `executemany` method on a cursor or a connection.
193+ *
194+ * See https://peps.python.org/pep-0249/#executemany
195+ *
196+ * Note: While `executemany` method on a connection is not part of PEP249, if it is used, we
197+ * recognize it as an alias for constructing a cursor and calling `executemany` on it.
198+ */
199+ private class ExecutemanyCall extends SqlExecution:: Range , DataFlow:: CallCfgNode {
200+ ExecutemanyCall ( ) { this .getFunction ( ) = executemany ( ) }
201+
202+ override DataFlow:: Node getSql ( ) { result in [ this .getArg ( 0 ) , this .getArgByName ( "sql" ) ] }
203+ }
174204}
0 commit comments