Repository: googleapis/python-spanner

Issue:
Spanner DB API incorrectly classifying queries beginning with brackets
`spanner_dbapi` is incorrectly classifying the following query as `STMT_UPDATING` due to the initial bracket:
```
(SELECT some_table.id, some_table.x, some_table.y 
FROM some_table 
WHERE some_table.id = 2 ORDER BY some_table.id
 LIMIT 1) UNION DISTINCT (SELECT some_table.id, some_table.x, some_table.y 
FROM some_table 
WHERE some_table.id = 3 ORDER BY some_table.id
 LIMIT 1) ORDER BY id
 LIMIT 2
 ```
 
 It looks like the SQL parsing RE expressions may need some work to handle queries which include brackets.

Discussion:

Patch:
diff --git a/google/cloud/spanner_dbapi/parse_utils.py b/google/cloud/spanner_dbapi/parse_utils.py
index 1744874..aa0e12d 100644
--- a/google/cloud/spanner_dbapi/parse_utils.py
+++ b/google/cloud/spanner_dbapi/parse_utils.py
@@ -145,7 +145,7 @@ STMT_UPDATING = "UPDATING"
 STMT_INSERT = "INSERT"
 
 # Heuristic for identifying statements that don't need to be run as updates.
-RE_NON_UPDATE = re.compile(r"^\s*(SELECT)", re.IGNORECASE)
+RE_NON_UPDATE = re.compile(r"^\W*(SELECT)", re.IGNORECASE)
 
 RE_WITH = re.compile(r"^\s*(WITH)", re.IGNORECASE)
 


Test patch:
diff --git a/tests/unit/spanner_dbapi/test_parse_utils.py b/tests/unit/spanner_dbapi/test_parse_utils.py
index 11239d7..4de4290 100644
--- a/tests/unit/spanner_dbapi/test_parse_utils.py
+++ b/tests/unit/spanner_dbapi/test_parse_utils.py
@@ -33,6 +33,7 @@ class TestParseUtils(unittest.TestCase):
         cases = (
             ("SELECT 1", STMT_NON_UPDATING),
             ("SELECT s.SongName FROM Songs AS s", STMT_NON_UPDATING),
+            ("(SELECT s.SongName FROM Songs AS s)", STMT_NON_UPDATING),
             (
                 "WITH sq AS (SELECT SchoolID FROM Roster) SELECT * from sq",
                 STMT_NON_UPDATING,