https://cloud.google.com/spanner/docs/reference/standard-sql/graph-patterns#quantified_paths
quantified_path_primary is not referenced by other rules.
GoogleSQL data definition language https://cloud.google.com/spanner/docs/reference/standard-sql/data-definition-language
This DDL reference is incomplete because it doesn't mention the Fully Qualified Name (FQN) for named schemas. Since named schemas are already Generally Available (GA), they should be fully integrated into the DDL reference.
Refs: https://cloud.google.com/spanner/docs/schema-and-data-model#named-schemas
https://cloud.google.com/spanner/docs/reference/standard-sql/dml-syntax#modify_multiple_fields
It is not valid query for example schema of this page. Albums should be AlbumInfo.
-(n:Person {id: 10 + n.age})-[e:Knows {since: 2023 + e.id}]
+(n:Person {id: 10 + n.age})-[e:Knows {since: 2023 + e.id}]->
https://cloud.google.com/spanner/docs/reference/standard-sql/graph-patterns#quantified_paths
This MATCH statement is example of semantic error, but there are syntax errors.
-MATCH ((p:Person)-[k:Knows]->(f:Person)){1, 3}->[x.Knows]->((p:Person)-[z:Knows]-(d:Person)){2}
+MATCH ((p:Person)-[k:Knows]->(f:Person)){1, 3}-[x:Knows]->((p:Person)-[z:Knows]-(d:Person)){2}
In the documentation, there's a table presented as a comment. The comment is not closed correctly. The closing comment delimiter */
is missing, and instead, we see /*
at the end of the table. It should be corrected to */ to properly close the multi-line comment block.
I think this problem is appeared in other documents. Please consider to fix them.
https://cloud.google.com/spanner/docs/reference/standard-sql/graph-gql-functions#edges
GRAPH FinGraph
MATCH p=(src:Account)-[t1:Transfers]->(mid:Account)-[t2:Transfers]->(dst:Account)
LET es = EDGES(p)
RETURN
LABELS(es[0]) AS labels,
es[0].to_id AS to_account;
/*----------------------------*
| labels | to_account |
+----------------------------+
| ["Transfers"] | 7 |
| ["Transfers"] | 7 |
| ["Transfers"] | 16 |
| ["Transfers"] | 16 |
| ["Transfers"] | 16 |
| ["Transfers"] | 20 |
| ["Transfers"] | 20 |
*----------------------------/*
https://cloud.google.com/spanner/docs/use-select-for-update#comparison
It is a invalid query because subquery is not parenthesized. IMO, it is better to match example schema.
SELECT s.SingerId, s.FirstName, s.LastName FROM Singers AS s
JOIN
(SELECT SingerId FROM Albums WHERE MarketingBudget > 100000 FOR UPDATE) AS a
ON a.SingerId = s.SingerId
https://cloud.google.com/spanner/docs/reference/standard-sql/graph-gql-functions#is_acyclic
I believe there might be an issue in the descriptions of the IS_ACYCLIC
and IS_TRAIL
functions.
Acyclic and trail means no repeating, but it seems the boolean return values are inverted for both.
Returns
TRUE
if a repetition is found, otherwise returnsFALSE
.
It should be:
Returns TRUE
if a repetition isn't found, otherwise returns FALSE
.
It seems that this document has a same issue. https://cloud.google.com/spanner/docs/graph/work-with-paths#is-acyclic
ALTER VECTOR INDEX Singer_vector_index ON Singers
DROP STORED COLUMN genre;
I believe this example is not valid DDL statement because ON Singers
is not permitted in this position.
ALTER VECTOR INDEX Singer_vector_index
DROP STORED COLUMN genre;
should be correct.
https://cloud.google.com/spanner/docs/reference/standard-sql/data-definition-language#alter_table
https://cloud.google.com/spanner/docs/generated-column/how-to#modify-generated-column
ALTER COLUMN data_type
seems to support AS (expr)
, but it is not reflected into this syntax reference.
The following documents discuss commit timestamp optimization without any reference to tiered storage:
On the other hand, the following documents discuss it specifically in the context of tiered storage:
ALLOW_TIMESTAMP_PREDICATE_PUSHDOWN
This technique improves the efficiency of queries that use timestamps and data with an age-based tiered storage policy.
Optimize queries with timestamp predicate pushdown
Timestamp predicate pushdown is a query optimization technique used in Spanner to improve the efficiency of queries that use timestamps and data with an age-based tiered storage policy.
Are these not closely related concepts? It seems that:
- Optimization for tiered storage is a special case of the former.
ALLOW_TIMESTAMP_PREDICATE_PUSHDOWN
is effective in both scenarios.
The Timestamp Condition
metadata has been observed in the Scan operator within query execution plans related to the optimizations mentioned above. However, this is not documented in the Query execution operators documentation.
spanner> EXPLAIN ANALYZE
@{ALLOW_TIMESTAMP_PREDICATE_PUSHDOWN=TRUE}
SELECT * FROM Performances
WHERE LastUpdateTime > TIMESTAMP "2025-05-09T23:19:51.114485+09:00";
+----+----------------------------------------------------------------------------------+------+---------+----------+
| ID | Query_Execution_Plan <execution_method> (metadata, ...) | Rows | Scanned | Filtered |
+----+----------------------------------------------------------------------------------+------+---------+----------+
| 0 | Distributed Union on Performances <Row> (split_ranges_aligned: false) | 2 | | |
| 1 | +- Local Distributed Union <Row> | 2 | | |
| 2 | +- Serialize Result <Row> | 2 | | |
| *3 | +- Filter Scan <Row> (seekable_key_size: 0) | | | |
| *4 | +- Table Scan on Performances <Row> (Full scan, scan_method: Automatic) | 2 | 4 | 2 |
+----+----------------------------------------------------------------------------------+------+---------+----------+
Predicates(identified by ID):
3: Residual Condition: ($LastUpdateTime > timestamp (2025-05-09 07:19:51.114485-07:00))
4: Timestamp Condition: ($LastUpdateTime >= IF((timestamp (2025-05-09 07:19:51.114485-07:00) < timestamp (0-12-31 16:07:02-07:52)), timestamp (0-12-31 16:07:02-07:52), TIMESTAMP_ADD(timestamp (2025-05-09 07:19:51.114485-07:00), 1, NANOSECOND)))
(It's my understanding that the documentation for the Scan operator is outdated, as it also lacks a description of Seek Condition
, for example.)
Nowhere in the documentation for Named Schemas or any descriptions related to FORCE_INDEX
is there an explanation of how to specify an index within a named schema using FORCE_INDEX
. This should be documented.
- https://cloud.google.com/spanner/docs/named-schemas
- https://cloud.google.com/spanner/docs/sql-best-practices#secondary-indexes
- https://cloud.google.com/spanner/docs/reference/standard-sql/query-syntax#table_hints
- https://cloud.google.com/spanner/docs/secondary-indexes#index-directive
spanner> SELECT * FROM sch1.Singers@{FORCE_INDEX=indexOnSingers}
WHERE FirstName = "John";
ERROR: spanner: code="InvalidArgument", desc: The table sch1.Singers does not have an index called indexOnSingers
spanner> SELECT * FROM sch1.Singers@{FORCE_INDEX=sch1.indexOnSingers}
WHERE FirstName = "John";
ERROR: spanner: code="InvalidArgument", desc: Unrecognized name: sch1 [at 1:41]
SELECT * FROM sch1.Singers@{FORCE_INDEX=sch1.indexOnSingers}
^
To infer the correct syntax, one needs to consult the lexical structure documentation and understand the transformation rules for hints in the Resolved AST. This is not self-evident.
https://cloud.google.com/spanner/docs/reference/standard-sql/lexical#hints
In the resolved AST, identifier hints are represented as string literals, so
@{hint="abc"}
is the same as@{hint=abc}
.
SELECT * FROM sch1.Singers@{FORCE_INDEX="sch1.indexOnSingers"}
WHERE FirstName = "John";
This is not the only instance; information regarding named schemas is not fully integrated into the Spanner GoogleSQL documentation. It would be beneficial for this to be improved.