In 2.4.0, SpannerIO#read has been migrated to use batch API. The batch API provides abstractions to scale out reads from Spanner, but it requires the query to be root-partitionable. The root-partitionable queries cover majority of the use cases, however there are examples when running arbitrary query is useful. For example, reading all the table names from the information_schema.* and reading the content of those tables in the next step.