google-cloud-spanner 3.41.0__tar.gz → 3.43.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. {google-cloud-spanner-3.41.0/google_cloud_spanner.egg-info → google-cloud-spanner-3.43.0}/PKG-INFO +2 -1
  2. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_database_v1/gapic_version.py +1 -1
  3. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_database_v1/types/spanner_database_admin.py +57 -0
  4. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_instance_v1/gapic_version.py +1 -1
  5. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_dbapi/_helpers.py +2 -2
  6. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_dbapi/batch_dml_executor.py +12 -13
  7. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_dbapi/checksum.py +3 -3
  8. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_dbapi/client_side_statement_executor.py +4 -0
  9. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_dbapi/client_side_statement_parser.py +24 -10
  10. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_dbapi/connection.py +123 -125
  11. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_dbapi/cursor.py +181 -129
  12. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_dbapi/parse_utils.py +3 -3
  13. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_dbapi/parsed_statement.py +7 -3
  14. google-cloud-spanner-3.43.0/google/cloud/spanner_dbapi/transaction_helper.py +292 -0
  15. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/__init__.py +2 -0
  16. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/batch.py +9 -1
  17. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/database.py +129 -17
  18. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/gapic_version.py +1 -1
  19. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/instance.py +31 -12
  20. google-cloud-spanner-3.43.0/google/cloud/spanner_v1/merged_result_set.py +133 -0
  21. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/session.py +4 -0
  22. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/snapshot.py +0 -4
  23. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/table.py +55 -13
  24. google-cloud-spanner-3.43.0/google/cloud/spanner_v1/testing/database_test.py +112 -0
  25. google-cloud-spanner-3.43.0/google/cloud/spanner_v1/testing/interceptors.py +65 -0
  26. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/transaction.py +26 -7
  27. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/types/spanner.py +14 -0
  28. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/types/type.py +22 -0
  29. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0/google_cloud_spanner.egg-info}/PKG-INFO +2 -1
  30. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google_cloud_spanner.egg-info/SOURCES.txt +5 -0
  31. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google_cloud_spanner.egg-info/requires.txt +1 -0
  32. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/setup.py +1 -0
  33. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/system/test_database_api.py +40 -0
  34. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/system/test_dbapi.py +348 -39
  35. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/system/test_session_api.py +66 -2
  36. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/system/test_table_api.py +1 -1
  37. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/gapic/spanner_admin_database_v1/test_database_admin.py +6 -0
  38. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/spanner_dbapi/test_connection.py +105 -375
  39. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/spanner_dbapi/test_cursor.py +227 -260
  40. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/spanner_dbapi/test_parse_utils.py +28 -0
  41. google-cloud-spanner-3.43.0/tests/unit/spanner_dbapi/test_transaction_helper.py +621 -0
  42. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/test_batch.py +45 -9
  43. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/test_database.py +12 -5
  44. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/test_snapshot.py +0 -22
  45. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/test_spanner.py +14 -0
  46. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/test_table.py +13 -6
  47. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/test_transaction.py +53 -30
  48. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/LICENSE +0 -0
  49. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/MANIFEST.in +0 -0
  50. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/README.rst +0 -0
  51. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner.py +0 -0
  52. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_database_v1/__init__.py +0 -0
  53. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_database_v1/gapic_metadata.json +0 -0
  54. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_database_v1/py.typed +0 -0
  55. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_database_v1/services/__init__.py +0 -0
  56. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_database_v1/services/database_admin/__init__.py +0 -0
  57. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_database_v1/services/database_admin/async_client.py +0 -0
  58. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_database_v1/services/database_admin/client.py +0 -0
  59. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_database_v1/services/database_admin/pagers.py +0 -0
  60. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_database_v1/services/database_admin/transports/__init__.py +0 -0
  61. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_database_v1/services/database_admin/transports/base.py +0 -0
  62. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_database_v1/services/database_admin/transports/grpc.py +0 -0
  63. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_database_v1/services/database_admin/transports/grpc_asyncio.py +0 -0
  64. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_database_v1/services/database_admin/transports/rest.py +0 -0
  65. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_database_v1/types/__init__.py +0 -0
  66. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_database_v1/types/backup.py +0 -0
  67. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_database_v1/types/common.py +0 -0
  68. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_instance_v1/__init__.py +0 -0
  69. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_instance_v1/gapic_metadata.json +0 -0
  70. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_instance_v1/py.typed +0 -0
  71. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_instance_v1/services/__init__.py +0 -0
  72. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_instance_v1/services/instance_admin/__init__.py +0 -0
  73. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_instance_v1/services/instance_admin/async_client.py +0 -0
  74. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_instance_v1/services/instance_admin/client.py +0 -0
  75. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_instance_v1/services/instance_admin/pagers.py +0 -0
  76. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_instance_v1/services/instance_admin/transports/__init__.py +0 -0
  77. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_instance_v1/services/instance_admin/transports/base.py +0 -0
  78. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_instance_v1/services/instance_admin/transports/grpc.py +0 -0
  79. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_instance_v1/services/instance_admin/transports/grpc_asyncio.py +0 -0
  80. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_instance_v1/services/instance_admin/transports/rest.py +0 -0
  81. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_instance_v1/types/__init__.py +0 -0
  82. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_instance_v1/types/common.py +0 -0
  83. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_instance_v1/types/spanner_instance_admin.py +0 -0
  84. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_dbapi/__init__.py +0 -0
  85. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_dbapi/exceptions.py +0 -0
  86. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_dbapi/parser.py +0 -0
  87. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_dbapi/partition_helper.py +0 -0
  88. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_dbapi/types.py +0 -0
  89. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_dbapi/utils.py +0 -0
  90. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_dbapi/version.py +0 -0
  91. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/_helpers.py +0 -0
  92. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/_opentelemetry_tracing.py +0 -0
  93. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/backup.py +0 -0
  94. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/client.py +0 -0
  95. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/data_types.py +0 -0
  96. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/gapic_metadata.json +0 -0
  97. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/keyset.py +0 -0
  98. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/param_types.py +0 -0
  99. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/pool.py +0 -0
  100. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/py.typed +0 -0
  101. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/services/__init__.py +0 -0
  102. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/services/spanner/__init__.py +0 -0
  103. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/services/spanner/async_client.py +0 -0
  104. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/services/spanner/client.py +0 -0
  105. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/services/spanner/pagers.py +0 -0
  106. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/services/spanner/transports/__init__.py +0 -0
  107. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/services/spanner/transports/base.py +0 -0
  108. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/services/spanner/transports/grpc.py +0 -0
  109. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/services/spanner/transports/grpc_asyncio.py +0 -0
  110. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/services/spanner/transports/rest.py +0 -0
  111. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/streamed.py +0 -0
  112. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/types/__init__.py +0 -0
  113. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/types/commit_response.py +0 -0
  114. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/types/keys.py +0 -0
  115. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/types/mutation.py +0 -0
  116. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/types/query_plan.py +0 -0
  117. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/types/result_set.py +0 -0
  118. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/types/transaction.py +0 -0
  119. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google_cloud_spanner.egg-info/dependency_links.txt +0 -0
  120. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google_cloud_spanner.egg-info/not-zip-safe +0 -0
  121. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google_cloud_spanner.egg-info/top_level.txt +0 -0
  122. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/setup.cfg +0 -0
  123. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/__init__.py +0 -0
  124. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/_fixtures.py +0 -0
  125. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/_helpers.py +0 -0
  126. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/system/__init__.py +0 -0
  127. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/system/_helpers.py +0 -0
  128. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/system/_sample_data.py +0 -0
  129. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/system/conftest.py +0 -0
  130. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/system/test_backup_api.py +0 -0
  131. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/system/test_instance_api.py +0 -0
  132. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/system/test_streaming_chunking.py +0 -0
  133. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/system/utils/__init__.py +0 -0
  134. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/system/utils/clear_streaming.py +0 -0
  135. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/system/utils/populate_streaming.py +0 -0
  136. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/system/utils/scrub_instances.py +0 -0
  137. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/system/utils/streaming_utils.py +0 -0
  138. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/__init__.py +0 -0
  139. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/gapic/__init__.py +0 -0
  140. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/gapic/spanner_admin_database_v1/__init__.py +0 -0
  141. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/gapic/spanner_admin_instance_v1/__init__.py +0 -0
  142. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/gapic/spanner_admin_instance_v1/test_instance_admin.py +0 -0
  143. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/gapic/spanner_v1/__init__.py +0 -0
  144. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/gapic/spanner_v1/test_spanner.py +0 -0
  145. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/spanner_dbapi/__init__.py +0 -0
  146. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/spanner_dbapi/test__helpers.py +0 -0
  147. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/spanner_dbapi/test_batch_dml_executor.py +0 -0
  148. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/spanner_dbapi/test_checksum.py +0 -0
  149. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/spanner_dbapi/test_connect.py +0 -0
  150. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/spanner_dbapi/test_globals.py +0 -0
  151. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/spanner_dbapi/test_parser.py +0 -0
  152. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/spanner_dbapi/test_types.py +0 -0
  153. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/spanner_dbapi/test_utils.py +0 -0
  154. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/streaming-read-acceptance-test.json +0 -0
  155. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/test__helpers.py +0 -0
  156. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/test__opentelemetry_tracing.py +0 -0
  157. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/test_backup.py +0 -0
  158. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/test_client.py +0 -0
  159. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/test_instance.py +0 -0
  160. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/test_keyset.py +0 -0
  161. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/test_packaging.py +0 -0
  162. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/test_param_types.py +0 -0
  163. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/test_pool.py +0 -0
  164. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/test_session.py +0 -0
  165. {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/test_streamed.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: google-cloud-spanner
3
- Version: 3.41.0
3
+ Version: 3.43.0
4
4
  Summary: Google Cloud Spanner API client library
5
5
  Home-page: https://github.com/googleapis/python-spanner
6
6
  Author: Google LLC
@@ -30,6 +30,7 @@ Requires-Dist: sqlparse>=0.4.4
30
30
  Requires-Dist: proto-plus<2.0.0dev,>=1.22.2; python_version >= "3.11"
31
31
  Requires-Dist: protobuf!=3.20.0,!=3.20.1,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<5.0.0dev,>=3.19.5
32
32
  Requires-Dist: deprecated>=1.2.14
33
+ Requires-Dist: grpc-interceptor>=0.15.4
33
34
  Provides-Extra: tracing
34
35
  Requires-Dist: opentelemetry-api>=1.1.0; extra == "tracing"
35
36
  Requires-Dist: opentelemetry-sdk>=1.1.0; extra == "tracing"
@@ -13,4 +13,4 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
  #
16
- __version__ = "3.41.0" # {x-release-please-version}
16
+ __version__ = "3.43.0" # {x-release-please-version}
@@ -355,6 +355,26 @@ class CreateDatabaseRequest(proto.Message):
355
355
  database_dialect (google.cloud.spanner_admin_database_v1.types.DatabaseDialect):
356
356
  Optional. The dialect of the Cloud Spanner
357
357
  Database.
358
+ proto_descriptors (bytes):
359
+ Optional. Proto descriptors used by CREATE/ALTER PROTO
360
+ BUNDLE statements in 'extra_statements' above. Contains a
361
+ protobuf-serialized
362
+ `google.protobuf.FileDescriptorSet <https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/descriptor.proto>`__.
363
+ To generate it,
364
+ `install <https://grpc.io/docs/protoc-installation/>`__ and
365
+ run ``protoc`` with --include_imports and
366
+ --descriptor_set_out. For example, to generate for
367
+ moon/shot/app.proto, run
368
+
369
+ ::
370
+
371
+ $protoc --proto_path=/app_path --proto_path=/lib_path \
372
+ --include_imports \
373
+ --descriptor_set_out=descriptors.data \
374
+ moon/shot/app.proto
375
+
376
+ For more details, see protobuffer `self
377
+ description <https://developers.google.com/protocol-buffers/docs/techniques#self-description>`__.
358
378
  """
359
379
 
360
380
  parent: str = proto.Field(
@@ -379,6 +399,10 @@ class CreateDatabaseRequest(proto.Message):
379
399
  number=5,
380
400
  enum=common.DatabaseDialect,
381
401
  )
402
+ proto_descriptors: bytes = proto.Field(
403
+ proto.BYTES,
404
+ number=6,
405
+ )
382
406
 
383
407
 
384
408
  class CreateDatabaseMetadata(proto.Message):
@@ -521,6 +545,25 @@ class UpdateDatabaseDdlRequest(proto.Message):
521
545
  underscore. If the named operation already exists,
522
546
  [UpdateDatabaseDdl][google.spanner.admin.database.v1.DatabaseAdmin.UpdateDatabaseDdl]
523
547
  returns ``ALREADY_EXISTS``.
548
+ proto_descriptors (bytes):
549
+ Optional. Proto descriptors used by CREATE/ALTER PROTO
550
+ BUNDLE statements. Contains a protobuf-serialized
551
+ `google.protobuf.FileDescriptorSet <https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/descriptor.proto>`__.
552
+ To generate it,
553
+ `install <https://grpc.io/docs/protoc-installation/>`__ and
554
+ run ``protoc`` with --include_imports and
555
+ --descriptor_set_out. For example, to generate for
556
+ moon/shot/app.proto, run
557
+
558
+ ::
559
+
560
+ $protoc --proto_path=/app_path --proto_path=/lib_path \
561
+ --include_imports \
562
+ --descriptor_set_out=descriptors.data \
563
+ moon/shot/app.proto
564
+
565
+ For more details, see protobuffer `self
566
+ description <https://developers.google.com/protocol-buffers/docs/techniques#self-description>`__.
524
567
  """
525
568
 
526
569
  database: str = proto.Field(
@@ -535,6 +578,10 @@ class UpdateDatabaseDdlRequest(proto.Message):
535
578
  proto.STRING,
536
579
  number=3,
537
580
  )
581
+ proto_descriptors: bytes = proto.Field(
582
+ proto.BYTES,
583
+ number=4,
584
+ )
538
585
 
539
586
 
540
587
  class DdlStatementActionInfo(proto.Message):
@@ -682,12 +729,22 @@ class GetDatabaseDdlResponse(proto.Message):
682
729
  A list of formatted DDL statements defining
683
730
  the schema of the database specified in the
684
731
  request.
732
+ proto_descriptors (bytes):
733
+ Proto descriptors stored in the database. Contains a
734
+ protobuf-serialized
735
+ `google.protobuf.FileDescriptorSet <https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/descriptor.proto>`__.
736
+ For more details, see protobuffer `self
737
+ description <https://developers.google.com/protocol-buffers/docs/techniques#self-description>`__.
685
738
  """
686
739
 
687
740
  statements: MutableSequence[str] = proto.RepeatedField(
688
741
  proto.STRING,
689
742
  number=1,
690
743
  )
744
+ proto_descriptors: bytes = proto.Field(
745
+ proto.BYTES,
746
+ number=2,
747
+ )
691
748
 
692
749
 
693
750
  class ListDatabaseOperationsRequest(proto.Message):
@@ -13,4 +13,4 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
  #
16
- __version__ = "3.41.0" # {x-release-please-version}
16
+ __version__ = "3.43.0" # {x-release-please-version}
@@ -18,13 +18,13 @@ from google.cloud.spanner_v1 import param_types
18
18
  SQL_LIST_TABLES = """
19
19
  SELECT table_name
20
20
  FROM information_schema.tables
21
- WHERE table_catalog = '' AND table_schema = ''
21
+ WHERE table_catalog = '' AND table_schema = @table_schema
22
22
  """
23
23
 
24
24
  SQL_GET_TABLE_COLUMN_SCHEMA = """
25
25
  SELECT COLUMN_NAME, IS_NULLABLE, SPANNER_TYPE
26
26
  FROM INFORMATION_SCHEMA.COLUMNS
27
- WHERE TABLE_SCHEMA = '' AND TABLE_NAME = @table_name
27
+ WHERE TABLE_SCHEMA = @table_schema AND TABLE_NAME = @table_name
28
28
  """
29
29
 
30
30
  # This table maps spanner_types to Spanner's data type sizes as per
@@ -16,7 +16,6 @@ from __future__ import annotations
16
16
 
17
17
  from enum import Enum
18
18
  from typing import TYPE_CHECKING, List
19
- from google.cloud.spanner_dbapi.checksum import ResultsChecksum
20
19
  from google.cloud.spanner_dbapi.parsed_statement import (
21
20
  ParsedStatement,
22
21
  StatementType,
@@ -80,8 +79,10 @@ def run_batch_dml(cursor: "Cursor", statements: List[Statement]):
80
79
  """
81
80
  from google.cloud.spanner_dbapi import OperationalError
82
81
 
83
- connection = cursor.connection
84
82
  many_result_set = StreamedManyResultSets()
83
+ if not statements:
84
+ return many_result_set
85
+ connection = cursor.connection
85
86
  statements_tuple = []
86
87
  for statement in statements:
87
88
  statements_tuple.append(statement.get_tuple())
@@ -90,28 +91,26 @@ def run_batch_dml(cursor: "Cursor", statements: List[Statement]):
90
91
  many_result_set.add_iter(res)
91
92
  cursor._row_count = sum([max(val, 0) for val in res])
92
93
  else:
93
- retried = False
94
94
  while True:
95
95
  try:
96
96
  transaction = connection.transaction_checkout()
97
97
  status, res = transaction.batch_update(statements_tuple)
98
- many_result_set.add_iter(res)
99
- res_checksum = ResultsChecksum()
100
- res_checksum.consume_result(res)
101
- res_checksum.consume_result(status.code)
102
- if not retried:
103
- connection._statements.append((statements, res_checksum))
104
- cursor._row_count = sum([max(val, 0) for val in res])
105
-
106
98
  if status.code == ABORTED:
107
99
  connection._transaction = None
108
100
  raise Aborted(status.message)
109
101
  elif status.code != OK:
110
102
  raise OperationalError(status.message)
103
+
104
+ cursor._batch_dml_rows_count = res
105
+ many_result_set.add_iter(res)
106
+ cursor._row_count = sum([max(val, 0) for val in res])
111
107
  return many_result_set
112
108
  except Aborted:
113
- connection.retry_transaction()
114
- retried = True
109
+ # We are raising it so it could be handled in transaction_helper.py and is retried
110
+ if cursor._in_retry_mode:
111
+ raise
112
+ else:
113
+ connection._transaction_helper.retry_transaction()
115
114
 
116
115
 
117
116
  def _do_batch_update(transaction, statements):
@@ -62,6 +62,8 @@ class ResultsChecksum:
62
62
 
63
63
 
64
64
  def _compare_checksums(original, retried):
65
+ from google.cloud.spanner_dbapi.transaction_helper import RETRY_ABORTED_ERROR
66
+
65
67
  """Compare the given checksums.
66
68
 
67
69
  Raise an error if the given checksums are not equal.
@@ -75,6 +77,4 @@ def _compare_checksums(original, retried):
75
77
  :raises: :exc:`google.cloud.spanner_dbapi.exceptions.RetryAborted` in case if checksums are not equal.
76
78
  """
77
79
  if retried != original:
78
- raise RetryAborted(
79
- "The transaction was aborted and could not be retried due to a concurrent modification."
80
- )
80
+ raise RetryAborted(RETRY_ABORTED_ERROR)
@@ -103,6 +103,10 @@ def execute(cursor: "Cursor", parsed_statement: ParsedStatement):
103
103
  return connection.run_partition(
104
104
  parsed_statement.client_side_statement_params[0]
105
105
  )
106
+ if statement_type == ClientSideStatementType.RUN_PARTITIONED_QUERY:
107
+ return connection.run_partitioned_query(parsed_statement)
108
+ if statement_type == ClientSideStatementType.SET_AUTOCOMMIT_DML_MODE:
109
+ return connection._set_autocommit_dml_mode(parsed_statement)
106
110
 
107
111
 
108
112
  def _get_streamed_result_set(column_name, type_code, column_values):
@@ -35,6 +35,12 @@ RE_RUN_BATCH = re.compile(r"^\s*(RUN)\s+(BATCH)", re.IGNORECASE)
35
35
  RE_ABORT_BATCH = re.compile(r"^\s*(ABORT)\s+(BATCH)", re.IGNORECASE)
36
36
  RE_PARTITION_QUERY = re.compile(r"^\s*(PARTITION)\s+(.+)", re.IGNORECASE)
37
37
  RE_RUN_PARTITION = re.compile(r"^\s*(RUN)\s+(PARTITION)\s+(.+)", re.IGNORECASE)
38
+ RE_RUN_PARTITIONED_QUERY = re.compile(
39
+ r"^\s*(RUN)\s+(PARTITIONED)\s+(QUERY)\s+(.+)", re.IGNORECASE
40
+ )
41
+ RE_SET_AUTOCOMMIT_DML_MODE = re.compile(
42
+ r"^\s*(SET)\s+(AUTOCOMMIT_DML_MODE)\s+(=)\s+(.+)", re.IGNORECASE
43
+ )
38
44
 
39
45
 
40
46
  def parse_stmt(query):
@@ -53,28 +59,36 @@ def parse_stmt(query):
53
59
  client_side_statement_params = []
54
60
  if RE_COMMIT.match(query):
55
61
  client_side_statement_type = ClientSideStatementType.COMMIT
56
- if RE_BEGIN.match(query):
57
- client_side_statement_type = ClientSideStatementType.BEGIN
58
- if RE_ROLLBACK.match(query):
62
+ elif RE_ROLLBACK.match(query):
59
63
  client_side_statement_type = ClientSideStatementType.ROLLBACK
60
- if RE_SHOW_COMMIT_TIMESTAMP.match(query):
64
+ elif RE_SHOW_COMMIT_TIMESTAMP.match(query):
61
65
  client_side_statement_type = ClientSideStatementType.SHOW_COMMIT_TIMESTAMP
62
- if RE_SHOW_READ_TIMESTAMP.match(query):
66
+ elif RE_SHOW_READ_TIMESTAMP.match(query):
63
67
  client_side_statement_type = ClientSideStatementType.SHOW_READ_TIMESTAMP
64
- if RE_START_BATCH_DML.match(query):
68
+ elif RE_START_BATCH_DML.match(query):
65
69
  client_side_statement_type = ClientSideStatementType.START_BATCH_DML
66
- if RE_RUN_BATCH.match(query):
70
+ elif RE_BEGIN.match(query):
71
+ client_side_statement_type = ClientSideStatementType.BEGIN
72
+ elif RE_RUN_BATCH.match(query):
67
73
  client_side_statement_type = ClientSideStatementType.RUN_BATCH
68
- if RE_ABORT_BATCH.match(query):
74
+ elif RE_ABORT_BATCH.match(query):
69
75
  client_side_statement_type = ClientSideStatementType.ABORT_BATCH
70
- if RE_PARTITION_QUERY.match(query):
76
+ elif RE_RUN_PARTITIONED_QUERY.match(query):
77
+ match = re.search(RE_RUN_PARTITIONED_QUERY, query)
78
+ client_side_statement_params.append(match.group(4))
79
+ client_side_statement_type = ClientSideStatementType.RUN_PARTITIONED_QUERY
80
+ elif RE_PARTITION_QUERY.match(query):
71
81
  match = re.search(RE_PARTITION_QUERY, query)
72
82
  client_side_statement_params.append(match.group(2))
73
83
  client_side_statement_type = ClientSideStatementType.PARTITION_QUERY
74
- if RE_RUN_PARTITION.match(query):
84
+ elif RE_RUN_PARTITION.match(query):
75
85
  match = re.search(RE_RUN_PARTITION, query)
76
86
  client_side_statement_params.append(match.group(3))
77
87
  client_side_statement_type = ClientSideStatementType.RUN_PARTITION
88
+ elif RE_SET_AUTOCOMMIT_DML_MODE.match(query):
89
+ match = re.search(RE_SET_AUTOCOMMIT_DML_MODE, query)
90
+ client_side_statement_params.append(match.group(4))
91
+ client_side_statement_type = ClientSideStatementType.SET_AUTOCOMMIT_DML_MODE
78
92
  if client_side_statement_type is not None:
79
93
  return ParsedStatement(
80
94
  StatementType.CLIENT_SIDE,
@@ -13,7 +13,6 @@
13
13
  # limitations under the License.
14
14
 
15
15
  """DB-API Connection for the Google Cloud Spanner."""
16
- import time
17
16
  import warnings
18
17
 
19
18
  from google.api_core.exceptions import Aborted
@@ -23,19 +22,17 @@ from google.cloud.spanner_dbapi import partition_helper
23
22
  from google.cloud.spanner_dbapi.batch_dml_executor import BatchMode, BatchDmlExecutor
24
23
  from google.cloud.spanner_dbapi.parse_utils import _get_statement_type
25
24
  from google.cloud.spanner_dbapi.parsed_statement import (
26
- ParsedStatement,
27
- Statement,
28
25
  StatementType,
26
+ AutocommitDmlMode,
29
27
  )
30
28
  from google.cloud.spanner_dbapi.partition_helper import PartitionId
29
+ from google.cloud.spanner_dbapi.parsed_statement import ParsedStatement, Statement
30
+ from google.cloud.spanner_dbapi.transaction_helper import TransactionRetryHelper
31
+ from google.cloud.spanner_dbapi.cursor import Cursor
31
32
  from google.cloud.spanner_v1 import RequestOptions
32
- from google.cloud.spanner_v1.session import _get_retry_delay
33
33
  from google.cloud.spanner_v1.snapshot import Snapshot
34
34
  from deprecated import deprecated
35
35
 
36
- from google.cloud.spanner_dbapi.checksum import _compare_checksums
37
- from google.cloud.spanner_dbapi.checksum import ResultsChecksum
38
- from google.cloud.spanner_dbapi.cursor import Cursor
39
36
  from google.cloud.spanner_dbapi.exceptions import (
40
37
  InterfaceError,
41
38
  OperationalError,
@@ -44,13 +41,10 @@ from google.cloud.spanner_dbapi.exceptions import (
44
41
  from google.cloud.spanner_dbapi.version import DEFAULT_USER_AGENT
45
42
  from google.cloud.spanner_dbapi.version import PY_VERSION
46
43
 
47
- from google.rpc.code_pb2 import ABORTED
48
-
49
44
 
50
45
  CLIENT_TRANSACTION_NOT_STARTED_WARNING = (
51
46
  "This method is non-operational as a transaction has not been started."
52
47
  )
53
- MAX_INTERNAL_RETRIES = 50
54
48
 
55
49
 
56
50
  def check_not_closed(function):
@@ -106,9 +100,6 @@ class Connection:
106
100
  self._transaction = None
107
101
  self._session = None
108
102
  self._snapshot = None
109
- # SQL statements, which were executed
110
- # within the current transaction
111
- self._statements = []
112
103
 
113
104
  self.is_closed = False
114
105
  self._autocommit = False
@@ -125,6 +116,27 @@ class Connection:
125
116
  self._spanner_transaction_started = False
126
117
  self._batch_mode = BatchMode.NONE
127
118
  self._batch_dml_executor: BatchDmlExecutor = None
119
+ self._transaction_helper = TransactionRetryHelper(self)
120
+ self._autocommit_dml_mode: AutocommitDmlMode = AutocommitDmlMode.TRANSACTIONAL
121
+
122
+ @property
123
+ def spanner_client(self):
124
+ """Client for interacting with Cloud Spanner API. This property exposes
125
+ the spanner client so that underlying methods can be accessed.
126
+ """
127
+ return self._instance._client
128
+
129
+ @property
130
+ def current_schema(self):
131
+ """schema name for this connection.
132
+
133
+ :rtype: str
134
+ :returns: the current default schema of this connection. Currently, this
135
+ is always "" for GoogleSQL and "public" for PostgreSQL databases.
136
+ """
137
+ if self.database is None:
138
+ raise ValueError("database property not set on the connection")
139
+ return self.database.default_schema_name
128
140
 
129
141
  @property
130
142
  def autocommit(self):
@@ -157,6 +169,23 @@ class Connection:
157
169
  """
158
170
  return self._database
159
171
 
172
+ @property
173
+ def autocommit_dml_mode(self):
174
+ """Modes for executing DML statements in autocommit mode for this connection.
175
+
176
+ The DML autocommit modes are:
177
+ 1) TRANSACTIONAL - DML statements are executed as single read-write transaction.
178
+ After successful execution, the DML statement is guaranteed to have been applied
179
+ exactly once to the database.
180
+
181
+ 2) PARTITIONED_NON_ATOMIC - DML statements are executed as partitioned DML transactions.
182
+ If an error occurs during the execution of the DML statement, it is possible that the
183
+ statement has been applied to some but not all of the rows specified in the statement.
184
+
185
+ :rtype: :class:`~google.cloud.spanner_dbapi.parsed_statement.AutocommitDmlMode`
186
+ """
187
+ return self._autocommit_dml_mode
188
+
160
189
  @property
161
190
  @deprecated(
162
191
  reason="This method is deprecated. Use _spanner_transaction_started field"
@@ -282,82 +311,13 @@ class Connection:
282
311
 
283
312
  The session will be returned into the sessions pool.
284
313
  """
314
+ if self._session is None:
315
+ return
285
316
  if self.database is None:
286
317
  raise ValueError("Database needs to be passed for this operation")
287
- if self._session is not None:
288
- self.database._pool.put(self._session)
318
+ self.database._pool.put(self._session)
289
319
  self._session = None
290
320
 
291
- def retry_transaction(self):
292
- """Retry the aborted transaction.
293
-
294
- All the statements executed in the original transaction
295
- will be re-executed in new one. Results checksums of the
296
- original statements and the retried ones will be compared.
297
-
298
- :raises: :class:`google.cloud.spanner_dbapi.exceptions.RetryAborted`
299
- If results checksum of the retried statement is
300
- not equal to the checksum of the original one.
301
- """
302
- attempt = 0
303
- while True:
304
- self._spanner_transaction_started = False
305
- attempt += 1
306
- if attempt > MAX_INTERNAL_RETRIES:
307
- raise
308
-
309
- try:
310
- self._rerun_previous_statements()
311
- break
312
- except Aborted as exc:
313
- delay = _get_retry_delay(exc.errors[0], attempt)
314
- if delay:
315
- time.sleep(delay)
316
-
317
- def _rerun_previous_statements(self):
318
- """
319
- Helper to run all the remembered statements
320
- from the last transaction.
321
- """
322
- for statement in self._statements:
323
- if isinstance(statement, list):
324
- statements, checksum = statement
325
-
326
- transaction = self.transaction_checkout()
327
- statements_tuple = []
328
- for single_statement in statements:
329
- statements_tuple.append(single_statement.get_tuple())
330
- status, res = transaction.batch_update(statements_tuple)
331
-
332
- if status.code == ABORTED:
333
- raise Aborted(status.details)
334
-
335
- retried_checksum = ResultsChecksum()
336
- retried_checksum.consume_result(res)
337
- retried_checksum.consume_result(status.code)
338
-
339
- _compare_checksums(checksum, retried_checksum)
340
- else:
341
- res_iter, retried_checksum = self.run_statement(statement, retried=True)
342
- # executing all the completed statements
343
- if statement != self._statements[-1]:
344
- for res in res_iter:
345
- retried_checksum.consume_result(res)
346
-
347
- _compare_checksums(statement.checksum, retried_checksum)
348
- # executing the failed statement
349
- else:
350
- # streaming up to the failed result or
351
- # to the end of the streaming iterator
352
- while len(retried_checksum) < len(statement.checksum):
353
- try:
354
- res = next(iter(res_iter))
355
- retried_checksum.consume_result(res)
356
- except StopIteration:
357
- break
358
-
359
- _compare_checksums(statement.checksum, retried_checksum)
360
-
361
321
  def transaction_checkout(self):
362
322
  """Get a Cloud Spanner transaction.
363
323
 
@@ -433,12 +393,10 @@ class Connection:
433
393
 
434
394
  def commit(self):
435
395
  """Commits any pending transaction to the database.
436
-
437
396
  This is a no-op if there is no active client transaction.
438
397
  """
439
398
  if self.database is None:
440
399
  raise ValueError("Database needs to be passed for this operation")
441
-
442
400
  if not self._client_transaction_started:
443
401
  warnings.warn(
444
402
  CLIENT_TRANSACTION_NOT_STARTED_WARNING, UserWarning, stacklevel=2
@@ -450,17 +408,13 @@ class Connection:
450
408
  if self._spanner_transaction_started and not self._read_only:
451
409
  self._transaction.commit()
452
410
  except Aborted:
453
- self.retry_transaction()
411
+ self._transaction_helper.retry_transaction()
454
412
  self.commit()
455
413
  finally:
456
- self._release_session()
457
- self._statements = []
458
- self._transaction_begin_marked = False
459
- self._spanner_transaction_started = False
414
+ self._reset_post_commit_or_rollback()
460
415
 
461
416
  def rollback(self):
462
417
  """Rolls back any pending transaction.
463
-
464
418
  This is a no-op if there is no active client transaction.
465
419
  """
466
420
  if not self._client_transaction_started:
@@ -468,15 +422,17 @@ class Connection:
468
422
  CLIENT_TRANSACTION_NOT_STARTED_WARNING, UserWarning, stacklevel=2
469
423
  )
470
424
  return
471
-
472
425
  try:
473
426
  if self._spanner_transaction_started and not self._read_only:
474
427
  self._transaction.rollback()
475
428
  finally:
476
- self._release_session()
477
- self._statements = []
478
- self._transaction_begin_marked = False
479
- self._spanner_transaction_started = False
429
+ self._reset_post_commit_or_rollback()
430
+
431
+ def _reset_post_commit_or_rollback(self):
432
+ self._release_session()
433
+ self._transaction_helper.reset()
434
+ self._transaction_begin_marked = False
435
+ self._spanner_transaction_started = False
480
436
 
481
437
  @check_not_closed
482
438
  def cursor(self):
@@ -493,7 +449,7 @@ class Connection:
493
449
 
494
450
  return self.database.update_ddl(ddl_statements).result()
495
451
 
496
- def run_statement(self, statement: Statement, retried=False):
452
+ def run_statement(self, statement: Statement):
497
453
  """Run single SQL statement in begun transaction.
498
454
 
499
455
  This method is never used in autocommit mode. In
@@ -513,17 +469,11 @@ class Connection:
513
469
  checksum of this statement results.
514
470
  """
515
471
  transaction = self.transaction_checkout()
516
- if not retried:
517
- self._statements.append(statement)
518
-
519
- return (
520
- transaction.execute_sql(
521
- statement.sql,
522
- statement.params,
523
- param_types=statement.param_types,
524
- request_options=self.request_options,
525
- ),
526
- ResultsChecksum() if retried else statement.checksum,
472
+ return transaction.execute_sql(
473
+ statement.sql,
474
+ statement.params,
475
+ param_types=statement.param_types,
476
+ request_options=self.request_options,
527
477
  )
528
478
 
529
479
  @check_not_closed
@@ -600,15 +550,7 @@ class Connection:
600
550
  ):
601
551
  statement = parsed_statement.statement
602
552
  partitioned_query = parsed_statement.client_side_statement_params[0]
603
- if _get_statement_type(Statement(partitioned_query)) is not StatementType.QUERY:
604
- raise ProgrammingError(
605
- "Only queries can be partitioned. Invalid statement: " + statement.sql
606
- )
607
- if self.read_only is not True and self._client_transaction_started is True:
608
- raise ProgrammingError(
609
- "Partitioned query not supported as the connection is not in "
610
- "read only mode or ReadWrite transaction started"
611
- )
553
+ self._partitioned_query_validation(partitioned_query, statement)
612
554
 
613
555
  batch_snapshot = self._database.batch_snapshot()
614
556
  partition_ids = []
@@ -620,17 +562,18 @@ class Connection:
620
562
  query_options=query_options,
621
563
  )
622
564
  )
565
+
566
+ batch_transaction_id = batch_snapshot.get_batch_transaction_id()
623
567
  for partition in partitions:
624
- batch_transaction_id = batch_snapshot.get_batch_transaction_id()
625
568
  partition_ids.append(
626
569
  partition_helper.encode_to_string(batch_transaction_id, partition)
627
570
  )
628
571
  return partition_ids
629
572
 
630
573
  @check_not_closed
631
- def run_partition(self, batch_transaction_id):
574
+ def run_partition(self, encoded_partition_id):
632
575
  partition_id: PartitionId = partition_helper.decode_from_string(
633
- batch_transaction_id
576
+ encoded_partition_id
634
577
  )
635
578
  batch_transaction_id = partition_id.batch_transaction_id
636
579
  batch_snapshot = self._database.batch_snapshot(
@@ -640,6 +583,60 @@ class Connection:
640
583
  )
641
584
  return batch_snapshot.process(partition_id.partition_result)
642
585
 
586
+ @check_not_closed
587
+ def run_partitioned_query(
588
+ self,
589
+ parsed_statement: ParsedStatement,
590
+ ):
591
+ statement = parsed_statement.statement
592
+ partitioned_query = parsed_statement.client_side_statement_params[0]
593
+ self._partitioned_query_validation(partitioned_query, statement)
594
+ batch_snapshot = self._database.batch_snapshot()
595
+ return batch_snapshot.run_partitioned_query(
596
+ partitioned_query, statement.params, statement.param_types
597
+ )
598
+
599
+ @check_not_closed
600
+ def _set_autocommit_dml_mode(
601
+ self,
602
+ parsed_statement: ParsedStatement,
603
+ ):
604
+ autocommit_dml_mode_str = parsed_statement.client_side_statement_params[0]
605
+ autocommit_dml_mode = AutocommitDmlMode[autocommit_dml_mode_str.upper()]
606
+ self.set_autocommit_dml_mode(autocommit_dml_mode)
607
+
608
+ def set_autocommit_dml_mode(
609
+ self,
610
+ autocommit_dml_mode,
611
+ ):
612
+ """
613
+ Sets the mode for executing DML statements in autocommit mode for this connection.
614
+ This mode is only used when the connection is in autocommit mode, and may only
615
+ be set while the transaction is in autocommit mode and not in a temporary transaction.
616
+ """
617
+
618
+ if self._client_transaction_started is True:
619
+ raise ProgrammingError(
620
+ "Cannot set autocommit DML mode while not in autocommit mode or while a transaction is active."
621
+ )
622
+ if self.read_only is True:
623
+ raise ProgrammingError(
624
+ "Cannot set autocommit DML mode for a read-only connection."
625
+ )
626
+ if self._batch_mode is not BatchMode.NONE:
627
+ raise ProgrammingError("Cannot set autocommit DML mode while in a batch.")
628
+ self._autocommit_dml_mode = autocommit_dml_mode
629
+
630
+ def _partitioned_query_validation(self, partitioned_query, statement):
631
+ if _get_statement_type(Statement(partitioned_query)) is not StatementType.QUERY:
632
+ raise ProgrammingError(
633
+ "Only queries can be partitioned. Invalid statement: " + statement.sql
634
+ )
635
+ if self.read_only is not True and self._client_transaction_started is True:
636
+ raise ProgrammingError(
637
+ "Partitioned query is not supported, because the connection is in a read/write transaction."
638
+ )
639
+
643
640
  def __enter__(self):
644
641
  return self
645
642
 
@@ -729,9 +726,10 @@ def connect(
729
726
  raise ValueError("project in url does not match client object project")
730
727
 
731
728
  instance = client.instance(instance_id)
732
- conn = Connection(
733
- instance, instance.database(database_id, pool=pool) if database_id else None
734
- )
729
+ database = None
730
+ if database_id:
731
+ database = instance.database(database_id, pool=pool)
732
+ conn = Connection(instance, database)
735
733
  if pool is not None:
736
734
  conn._own_pool = False
737
735