このドキュメントでは、Spanner Graph の使用時に発生する可能性のあるエラーについて説明します。エラーの例と推奨の対応方法も記載しています。
このトラブルシューティング ガイドを参照したうえでなおサポートが必要な場合は、サポートの利用をご覧ください。
スキーマエラー
スキーマの結果は、Spanner Graph を設定してクエリを実行するで使用したデータセットに基づいています。
要素キーは一意である必要がある
エラー メッセージ
Neither the primary keys nor any unique index defined on the property graph
element source table `Person` provides the uniqueness guarantee for graph
element `Person` belonging to the graph `FinGraph`. You want to redefine the
element key columns (`name`) based on the source table's primary keys, or
create a unique index on the element's key columns.
エラーの例
CREATE OR REPLACE PROPERTY GRAPH FinGraph
NODE TABLES (
Person KEY (name)
);
推奨の対応方法
要素キー列に一意のインデックスを作成し、ソーステーブルの主キーに基づいて要素キー列を再定義します。
CREATE OR REPLACE PROPERTY GRAPH FinGraph
NODE TABLES (
Person KEY (id)
);
または、要素キー列に一意のインデックスを作成します。
CREATE UNIQUE INDEX PersonNameIndex ON Person(name);
CREATE OR REPLACE PROPERTY GRAPH FinGraph
NODE TABLES (
Person KEY (name)
);
要素定義の名前は一意である必要がある
エラー メッセージ
Account is defined more than once; use a unique name.
エラーの例
CREATE OR REPLACE PROPERTY GRAPH FinGraph
NODE TABLES (
Account,
Person
)
EDGE TABLES (
Account
SOURCE KEY(owner_id) REFERENCES Person
DESTINATION KEY(account_id) REFERENCES Account
);
推奨の対応方法
エッジ定義に一意の名前を使用します。
CREATE OR REPLACE PROPERTY GRAPH FinGraph
NODE TABLES (
Account,
Person
)
EDGE TABLES (
Account AS Owns
SOURCE KEY(owner_id) REFERENCES Person
DESTINATION KEY(account_id) REFERENCES Account
);
ラベル定義はプロパティで一貫している必要がある
エラー メッセージ
The label Entity is defined with different property declarations. There is one
instance of this label defined with properties of [id]. Another instance is
defined with properties of [name].
エラーの例
CREATE OR REPLACE PROPERTY GRAPH FinGraph
NODE TABLES (
Person LABEL Entity PROPERTIES (name),
Account LABEL Entity PROPERTIES (id)
);
推奨の対応方法
同じラベルで同じプロパティ名のセットを使用する必要があります。
CREATE OR REPLACE PROPERTY GRAPH FinGraph
NODE TABLES (
Person LABEL Entity PROPERTIES (id, name),
Account LABEL Entity PROPERTIES (id, name)
);
プロパティ宣言はプロパティ型で一貫している必要がある
エラー メッセージ
The property declaration of name has type conflicts. There is an existing
declaration of type INT64. There is a conflicting one of type STRING.
エラーの例
CREATE OR REPLACE PROPERTY GRAPH FinGraph
NODE TABLES (
Person PROPERTIES (name),
Account PROPERTIES (id AS name)
);
推奨の対応方法
CREATE OR REPLACE PROPERTY GRAPH FinGraph
NODE TABLES (
Person PROPERTIES (name),
Account PROPERTIES (CAST(id AS STRING) AS name)
);
プロパティの定義がサブクエリではない
エラー メッセージ
Property value expression of count cannot contain a subquery.
エラーの例
CREATE OR REPLACE PROPERTY GRAPH FinGraph
NODE TABLES (
Person PROPERTIES ((SELECT COUNT(*) FROM Person) AS count)
);
推奨の対応方法
なし。この条件は許可されません。
プロパティの定義は同じ要素定義内で一貫している必要がある
エラー メッセージ
Property location has more than one definition in the element table Person
エラーの例
CREATE OR REPLACE PROPERTY GRAPH FinGraph
NODE TABLES (
Person
LABEL Person PROPERTIES (country AS location)
LABEL Entity PROPERTIES (city AS location)
);
推奨の対応方法
同じプロパティ定義を使用します。
CREATE OR REPLACE PROPERTY GRAPH FinGraph
NODE TABLES (
Person
LABEL Person PROPERTIES (country AS location)
LABEL Entity PROPERTIES (country AS location)
);
または、別のプロパティ名を割り当てます。
CREATE OR REPLACE PROPERTY GRAPH FinGraph
NODE TABLES (
Person
LABEL Person PROPERTIES (country AS location)
LABEL Entity PROPERTIES (city AS city)
);
クエリエラー
クエリ結果は、Spanner Graph の設定とクエリで使用するデータセットに基づいています。
グラフ要素をクエリ結果として返すことはできない
エラー メッセージ
Returning expressions of type GRAPH_ELEMENT is not allowed
エラーの例
GRAPH FinGraph
MATCH (n:Account)
RETURN n;
推奨の対応方法
GRAPH FinGraph
MATCH (n:Account)
RETURN TO_JSON(n) AS n;
プロパティの指定を WHERE 句で使用できない
エラー メッセージ
WHERE clause cannot be used together with property specification
エラーの例
GRAPH FinGraph
MATCH (n:Account {id: 1} WHERE n.is_blocked)
RETURN n.id;
推奨の対応方法
以下にある推奨の対応方法のいずれかを実施してください。
GRAPH FinGraph
MATCH (n:Account {id: 1})
WHERE n.is_blocked
RETURN n.id;
GRAPH FinGraph
MATCH (n:Account WHERE n.id = 1 AND n.is_blocked )
RETURN n.id;
GRAPH FinGraph
MATCH (n:Account {id: 1, is_blocked: TRUE})
RETURN n.id;
前のステートメントで定義された変数への参照が許可されない
エラー メッセージ
Name 'account_id', defined in the previous statement, can only be referenced in
the outermost WHERE clause of MATCH
説明
MATCH パターン内では、前のステートメントで定義された変数への参照は許可されません。グラフクエリでは、前のステートメントで定義された名前は、MATCH の最も外側の WHERE 句でのみ使用できます。
エラーの例
GRAPH FinGraph
LET account_id = 1
MATCH (n:Account {id: account_id})
RETURN n.id;
推奨の対応方法
GRAPH FinGraph
LET account_id = 1
MATCH (n:Account)
WHERE n.id = account_id
RETURN n.id;
相関グラフ変数の再定義は許可されない
エラー メッセージ
The name account is already defined; redefining graph element variables in a
subquery is not allowed. To refer to the same graph element, use a different
name and add an explicit filter that checks for equality.
説明
グラフクエリでは、内部グラフのサブクエリでグラフ要素名を再定義することはできません。このシナリオは、外側のスコープと同じグラフ要素を参照している、または外側のスコープ名をシャドウする新しいグラフ要素にバインドされていると解釈される可能性があります。再定義は許可されません。
エラーの例
GRAPH FinGraph
MATCH (account:Account)
RETURN account.id AS account_id, VALUE {
MATCH (account:Account)-[transfer:Transfers]->(:Account)
RETURN SUM(transfer.amount) AS total_transfer
} AS total_transfer;
推奨の対応方法
GRAPH FinGraph
MATCH (account:Account)
RETURN account.id AS account_id, VALUE {
MATCH (a:Account)-[transfer:Transfers]->(:Account)
WHERE a = account
RETURN SUM(transfer.amount) AS total_transfer
} AS total_transfer;
クエリのセマンティクスに関する問題
クエリ結果は、Spanner Graph の設定とクエリで使用するデータセットに基づいています。
WHERE と FILTER が異なると、出力結果も異なります
説明
FILTER はステートメントです。一方、WHERE は句で、MATCH ステートメントや OPTIONAL
MATCH ステートメントの一部として使われます。
最初の例では、WHERE 句は OPTIONAL MATCH ステートメントで指定されたパターンに追加の制約を加えます。これは、照合が完了した後にフィルタするという意味ではありません。
2 番目の例では、FILTER ステートメントは、照合が完了した後に絞り込むためのフィルタです。
問題の例
次の例では、WHERE と FILTER が異なるため、出力結果が異なります。
例 1
GRAPH FinGraph
MATCH (n:Account {id: 7})
OPTIONAL MATCH (m:Account)
WHERE FALSE
RETURN n.id AS n_id, m.id AS m_id;
| n_id | m_id |
|---|---|
| 7 | null |
例 2
GRAPH FinGraph
MATCH (n:Account {id: 7})
OPTIONAL MATCH (m:Account)
FILTER FALSE
RETURN n.id AS n_id, m.id AS m_id;
空の結果。
異なる変数がステートメント間で引き継がれると、出力も異なってくる
説明
グラフクエリ言語では、同じ変数が複数回宣言されても、それはすべて同じグラフ要素を指します。
例 1 では、id が 7 であり 16 でもあるような Account ノードは存在しません。その結果、空の結果が返されます。
例 2 では、n は前のステートメントから返っていません(id のみが返されています)。そのため、2 番目の MATCH では、id が 16 の Account ノードが探されます。
問題の例
次の例では、ステートメント間で異なる変数が受け渡されているため、出力結果が異なります。
例 1
GRAPH FinGraph
MATCH (n:Account {id: 7})
RETURN n
NEXT
MATCH (n:Account {id: 16})
RETURN n.id AS n_id;
空の結果。
例 2
GRAPH FinGraph
MATCH (n:Account {id: 7})
RETURN n.id AS id
NEXT
MATCH (n:Account {id: 16})
RETURN n.id AS n_id;
| n_id |
|---|
| 16 |
LIMIT 以外のステートメントが続く場合、ORDER BY が無視される
説明
グラフクエリ言語では、次のいずれかに該当する場合を除き、ORDER BY ステートメントは無視されます。
ORDER BYが最後のステートメントである。ORDER BYの直後にLIMITが続く。
例 1 では、LIMIT が ORDER BY の直後に続かず、最後の LIMIT は分離されています。そのため、ORDER BY はエンジンで無視されます。
例 2 では、ORDER BY の直後に LIMIT があるため、ORDER BY が適用されます。
問題の例
次の例では、出力結果が異なります。これは、例 1 で ORDER BY が LIMIT と一緒に使われていないため無視されるからです。
例 1
GRAPH FinGraph
MATCH (n:Account)
ORDER BY n.id DESC
RETURN n.id
LIMIT 3;
| n_id |
|---|
| 7 |
例 2
GRAPH FinGraph
MATCH (n:Account)
ORDER BY n.id DESC
LIMIT 3
RETURN n.id;
| n_id |
|---|
| 20 |
エッジパターンが異なると出力結果も異なる
説明
エラーの例で使用されているデータセットでは、ANY 方向のエッジパターンがグラフ内の各 Transfers エッジに対して 2 回ずつ照合されます。
例 1 では、Account(id=x) から Account(id=y) への Transfers エッジは、次のように 2 回照合できます。
- n=
Account(id=x)、m=Account(id=y) - n=
Account(id=y)、m=Account(id=x)
例 2 では、n=Account(id=x) かつ m=Account(id=y) となる、1 つだけの一致が存在します。
結果として、例 1 のクエリは 10 を返し、例 2 のクエリは 5 を返します。
問題の例
次の例では、異なるエッジパターンが使用されているため、出力結果が異なります。
例 1
GRAPH FinGraph
MATCH (n:Account)-[:Transfers]-(m:Account)
RETURN COUNT(*) AS num_transfer_edges;
| num_transfer_edges |
|---|
| 10 |
例 2
GRAPH FinGraph
MATCH (n:Account)-[:Transfers]->(m:Account)
RETURN COUNT(*) AS num_transfer_edges;
| num_transfer_edges |
|---|
| 5 |
ミューテーション エラー
ミューテーションの結果は、Spanner Graph を設定してクエリを実行するで使用したデータセットに基づいています。
ソースノードが存在しないため外部キー制約に違反する
エラー メッセージ
Parent row for row [...] in table AccountTransferAccount is missing. Row cannot
be written.
説明
AccountTransferAccount エッジテーブルは INTERLEAVED INTO PARENT Account node テーブルです。Transfer エッジを作成するには、親の Account ノードがすでに存在している必要があります。
エラーの例
INSERT INTO AccountTransferAccount (id, to_id, create_time, amount)
VALUES (100, 1, PENDING_COMMIT_TIMESTAMP(), 200);
推奨の対応方法
まず先頭の Account ノードを作成し、次に Transfer エッジを作成します。
宛先ノードが存在しないため外部キー制約に違反する
エラー メッセージ
Foreign key constraint FK_TransferTo is violated on table
AccountTransferAccount. Cannot find referenced values in Account(id)
説明
AccountTransferAccount テーブルは、FK_TransferTo という ForeignKey を通じて Accounttable を参照しています。Transfer エッジを作成するには、参照される Account ノード(後ろ側のノード)がすでに存在している必要があります。
エラーの例
INSERT INTO AccountTransferAccount (id, to_id, create_time, amount)
VALUES (1, 100, PENDING_COMMIT_TIMESTAMP(), 200);
推奨の対応方法
最初に末尾の Account ノードを作成し、次に Transfer エッジを作成します。
孤立した出力方向のエッジが親子関係に違反している
エラー メッセージ
Integrity constraint violation during DELETE/REPLACE. Found child row [...] in
table AccountTransferAccount
説明
AccountTransferAccount エッジテーブルは INTERLEAVED INTO PARENT Account ノードテーブルであり、削除する Account ノードには出力方向のエッジがまだ接続されています。
エラーの例
DELETE FROM Account WHERE id = 1;
推奨の対応方法
まず、出力方向の Transfer エッジをすべて削除してから、Account ノードを削除します。または、INTERLEAVE に ON DELETE CASCADE を定義し、Spanner でエッジを自動的に削除します。
孤立した入力方向のエッジが親子関係に違反している
エラー メッセージ
Foreign key constraint violation when deleting or updating referenced row(s):
referencing row(s) found in table AccountTransferAccount
説明
AccountTransferAccount エッジ テーブルは ForeignKey を介して Account ノードテーブルを参照し、削除される Account ノードには引き続き入力方向のエッジが接続されています。
エラーの例
DELETE FROM Account WHERE id = 1;
推奨の対応方法
まず、入力方向の Transfer エッジをすべて削除してから、Account ノードを削除します。または、ForeignKey に ON DELETE CASCADE を定義し、Spanner でエッジを自動的に削除します。