3232from google .cloud .spanner_dbapi .exceptions import OperationalError
3333from google .cloud .spanner_dbapi .exceptions import ProgrammingError
3434
35- from google .cloud .spanner_dbapi import _helpers
35+ from google .cloud .spanner_dbapi import _helpers , client_side_statement_executor
3636from google .cloud .spanner_dbapi ._helpers import ColumnInfo
3737from google .cloud .spanner_dbapi ._helpers import CODE_TO_DISPLAY_SIZE
3838
3939from google .cloud .spanner_dbapi import parse_utils
4040from google .cloud .spanner_dbapi .parse_utils import get_param_types
4141from google .cloud .spanner_dbapi .parse_utils import sql_pyformat_args_to_spanner
42+ from google .cloud .spanner_dbapi .parsed_statement import StatementType
4243from google .cloud .spanner_dbapi .utils import PeekIterator
4344from google .cloud .spanner_dbapi .utils import StreamedManyResultSets
4445
@@ -210,7 +211,10 @@ def _batch_DDLs(self, sql):
210211 for ddl in sqlparse .split (sql ):
211212 if ddl :
212213 ddl = ddl .rstrip (";" )
213- if parse_utils .classify_stmt (ddl ) != parse_utils .STMT_DDL :
214+ if (
215+ parse_utils .classify_statement (ddl ).statement_type
216+ != StatementType .DDL
217+ ):
214218 raise ValueError ("Only DDL statements may be batched." )
215219
216220 statements .append (ddl )
@@ -239,8 +243,12 @@ def execute(self, sql, args=None):
239243 self ._handle_DQL (sql , args or None )
240244 return
241245
242- class_ = parse_utils .classify_stmt (sql )
243- if class_ == parse_utils .STMT_DDL :
246+ parsed_statement = parse_utils .classify_statement (sql )
247+ if parsed_statement .statement_type == StatementType .CLIENT_SIDE :
248+ return client_side_statement_executor .execute (
249+ self .connection , parsed_statement
250+ )
251+ if parsed_statement .statement_type == StatementType .DDL :
244252 self ._batch_DDLs (sql )
245253 if self .connection .autocommit :
246254 self .connection .run_prior_DDL_statements ()
@@ -251,7 +259,7 @@ def execute(self, sql, args=None):
251259 # self._run_prior_DDL_statements()
252260 self .connection .run_prior_DDL_statements ()
253261
254- if class_ == parse_utils . STMT_UPDATING :
262+ if parsed_statement . statement_type == StatementType . UPDATE :
255263 sql = parse_utils .ensure_where_clause (sql )
256264
257265 sql , args = sql_pyformat_args_to_spanner (sql , args or None )
@@ -276,7 +284,7 @@ def execute(self, sql, args=None):
276284 self .connection .retry_transaction ()
277285 return
278286
279- if class_ == parse_utils . STMT_NON_UPDATING :
287+ if parsed_statement . statement_type == StatementType . QUERY :
280288 self ._handle_DQL (sql , args or None )
281289 else :
282290 self .connection .database .run_in_transaction (
@@ -309,19 +317,29 @@ def executemany(self, operation, seq_of_params):
309317 self ._result_set = None
310318 self ._row_count = _UNSET_COUNT
311319
312- class_ = parse_utils .classify_stmt (operation )
313- if class_ == parse_utils . STMT_DDL :
320+ parsed_statement = parse_utils .classify_statement (operation )
321+ if parsed_statement . statement_type == StatementType . DDL :
314322 raise ProgrammingError (
315323 "Executing DDL statements with executemany() method is not allowed."
316324 )
317325
326+ if parsed_statement .statement_type == StatementType .CLIENT_SIDE :
327+ raise ProgrammingError (
328+ "Executing the following operation: "
329+ + operation
330+ + ", with executemany() method is not allowed."
331+ )
332+
318333 # For every operation, we've got to ensure that any prior DDL
319334 # statements were run.
320335 self .connection .run_prior_DDL_statements ()
321336
322337 many_result_set = StreamedManyResultSets ()
323338
324- if class_ in (parse_utils .STMT_INSERT , parse_utils .STMT_UPDATING ):
339+ if parsed_statement .statement_type in (
340+ StatementType .INSERT ,
341+ StatementType .UPDATE ,
342+ ):
325343 statements = []
326344
327345 for params in seq_of_params :
0 commit comments