Lexikalische Struktur und Syntax

Eine Cloud Spanner-SQL-Anweisung umfasst eine Reihe von Token. Tokens umfassen Kennungen, Kennungen in Anführungszeichen, Literale, Keywords, Operatoren und Sonderzeichen. Sie können Tokens durch Leerräume (z. B. Leerzeichen, Rücktaste, Tab, Zeilenvorschub) oder Kommentare trennen.

Kennungen

Kennungen sind Namen, die mit Spalten, Tabellen und anderen Datenbankobjekten verknüpft sind. Sie können ohne Anführungszeichen oder in Anführungszeichen gesetzt werden.

  • Kennungen können in Pfadausdrücken verwendet werden, die ein STRUCT zurückgeben.
  • Bei einigen Kennungen wird zwischen Groß- und Kleinschreibung unterschieden, bei anderen nicht. Weitere Informationen finden Sie unter Groß-/Kleinschreibung beachten.
  • Kennungen ohne Anführungszeichen müssen mit einem Buchstaben oder einem Unterstrich beginnen. Nachfolgende Zeichen können Buchstaben, Zahlen oder Unterstriche sein.
  • Kennungen in Anführungszeichen müssen in Graviszeichen (') eingeschlossen werden.
    • Kennungen in Anführungszeichen können beliebige Zeichen enthalten, wie Leerzeichen oder Symbole.
    • Sie dürfen aber nicht leer sein.
    • Kennungen in Anführungszeichen haben dieselben Escape-Sequenzen wie Stringliterale.
    • Ein reserviertes Keyword muss eine Kennzeichnung in Anführungszeichen sein, wenn es ein eigenständiges Keyword oder die erste Komponente eines Pfadausdrucks ist. Es kann als zweite oder spätere Komponente eines Pfadausdrucks in Anführungszeichen gesetzt werden.

Beispiele

Dies sind gültige Kennungen:

Customers5
`5Customers`
dataField
_dataField1
ADGROUP
`tableName~`
`GROUP`

Diese Pfadausdrücke enthalten gültige Kennungen:

foo.`GROUP`
foo.GROUP
foo().dataField
list[OFFSET(3)].dataField
list[ORDINAL(3)].dataField
@parameter.dataField

Dies sind ungültige Kennungen:

5Customers
_dataField!
GROUP

5Customers beginnt mit einer Zahl und nicht mit einem Buchstaben oder Unterstrich. _dataField! enthält das Sonderzeichen "!", das kein Buchstabe, keine Zahl und kein Unterstrich ist. GROUP ist ein reserviertes Keyword und kann somit nur als Kennung verwendet werden, wenn es in Graviszeichen steht.

Literale

Ein Literal stellt einen konstanten Wert eines integrierten Datentyps dar. Einige, jedoch nicht alle Datentypen können als Literale ausgedrückt werden.

String- und Byteliterale

Sowohl String- als auch Byteliterale müssen in Anführungszeichen gesetzt werden, entweder mit einfachen (') oder doppelten Anführungszeichen ("). Außerdem ist es möglich, die Literale mit Gruppen aus drei einfachen (''') oder drei doppelten (""") Anführungszeichen in dreifache Anführungszeichen zu setzen.

Literale in Anführungszeichen:

Literal Beispiele Beschreibung
String in Anführungszeichen
  • "abc"
  • "it's"
  • 'it\'s'
  • 'Title: "Boy"'
Strings in einfachen Anführungszeichen (') können doppelte Anführungszeichen (") ohne Escapezeichen enthalten und umgekehrt.
Umgekehrte Schrägstriche (\) stehen vor Escapesequenzen. Siehe Tabelle "Escapesequenzen" unten.
Strings in Anführungszeichen können keine Zeilenumbrüche enthalten, selbst wenn ihnen ein umgekehrter Schrägstrich (\) vorangestellt ist.
String in drei Anführungszeichen
  • """abc"""
  • '''it's'''
  • '''Title:"Boy"'''
  • '''two
    lines'''
  • '''why\?'''
Eingebettete Zeilenumbrüche und Anführungszeichen sind ohne Escapezeichen zulässig – siehe viertes Beispiel.
Umgekehrte Schrägstriche (\) stehen vor Escapesequenzen. Siehe Tabelle "Escapesequenzen" unten.
Ein abschließender umgekehrter Schrägstrich ohne Escapezeichen (\) am Ende einer Zeile ist nicht zulässig.
Beenden Sie den String mit drei Anführungszeichen hintereinander ohne Escapezeichen, die mit den einführenden Anführungszeichen übereinstimmen.
Rohstring
  • R"abc+"
  • r'''abc+'''
  • R"""abc+"""
  • r'f\(abc,(.*),def\)'
Literale in Anführungszeichen oder Literale in dreifachen Anführungszeichen, die über das Präfix für Rohstringliterale verfügen (r oder R) werden als Rohstrings/reguläre Ausdrucksstrings interpretiert.
Umgekehrte Schrägstriche (\) fungieren nicht als Escapezeichen. Wenn ein umgekehrter Schrägstrich gefolgt von einem anderen Zeichen innerhalb des Stringliterals auftritt, werden beide Zeichen beibehalten.
Ein Rohstring kann nicht mit einer ungeraden Zahl von umgekehrten Schrägstrichen enden.
Rohstrings werden besonders für das Erstellen regulärer Ausdrücke verwendet.

Präfixzeichen (r, R, b, B)) sind für Strings in Anführungszeichen oder dreifachen Anführungszeichen optional. Sie geben an, dass der String ein Rohstring/regulärer Ausdrucksstring oder eine Bytes-Sequenz ist. Zum Beispiel werden b'abc' und b'''abc''' beide als Bytetypen interpretiert. Bei Präfixzeichen muss die Groß-/Kleinschreibung nicht berücksichtigt werden.

Literale in Anführungszeichen mit Präfixen:

Literal Beispiel Beschreibung
Byte
  • B"abc"
  • B'''abc'''
  • b"""abc"""
Literale in Anführungszeichen oder dreifachen Anführungszeichen, die das Präfix für Byteliterale (b oder B) enthalten, werden als Byte interpretiert.
Rohbyte
  • br'abc+'
  • RB"abc+"
  • RB'''abc'''
Die Präfixe r und b können in beliebiger Reihenfolge kombiniert werden. rb'abc*' entspricht beispielsweise br'abc*'.

In der Tabelle unten werden alle gültigen Escapesequenzen zur Darstellung nicht alphanumerischer Zeichen in String- und Byteliteralen aufgeführt. Jede nicht in dieser Tabelle aufgeführte Sequenz erzeugt einen Fehler.

Escapesequenz Beschreibung
\a Akustisches Signal
\b Rückschritt
\f Seitenvorschub
\n Zeilenvorschub
\r Wagenrücklauf
\t Tabulator
\v Vertikaler Tabulator
\\ Umgekehrter Schrägstrich (\)
\? Fragezeichen (?)
\" Doppeltes Anführungszeichen (")
\' Einfaches Anführungszeichen (')
\` Gravis (`)
\ooo Oktal-Escapesequenz mit genau drei Ziffern (im Bereich 0–7). Wird in ein einzelnes Unicode-Zeichen (in Stringliteralen) oder Byte (in Byteliteralen) decodiert.
\xhh oder \Xhh Hexadezimal-Escapesequenz, mit genau zwei Hexadezimalziffern (0–9 oder A–F oder a–f). Wird in ein einzelnes Unicode-Zeichen (in Stringliteralen) oder Byte (in Byteliteralen) decodiert. Beispiele:
  • '\x41' == 'A'
  • '\x41B' ist 'AB'
  • '\x4' ist ein Fehler
\uhhhh Unicode-Escapesequenz, mit Kleinbuchstabe "u" und genau vier Hexadezimalziffern. Nur in Stringliteralen oder Kennungen gültig.
Der Bereich D800–DFFF ist nicht zulässig, da das Ersatz-Unicode-Werte sind.
\Uhhhhhhhh Unicode-Escapesequenz mit Großbuchstabe "U" und genau acht Hexadezimalziffern. Nur in Stringliteralen oder Kennungen gültig.
Der Bereich D800-DFFF ist nicht zulässig, da diese Werte Ersatz-Unicode-Werte sind. Außerdem sind Werte größer als 10FFFF nicht zulässig.

Ganzzahlliterale

Ganzzahlliterale bestehen entweder aus einer Sequenz von Dezimalziffern (0–9) oder einem Hexadezimalwert mit vorangestelltem "0x" oder "0X". Ganzzahlen können "+" oder "-" zur Darstellung von positiven bzw. negativen Werten vorangestellt werden. Beispiele:

123
0xABC
-123

Ein Ganzzahlliteral wird als INT64 interpretiert.

Gleitkommaliterale

Syntaxoptionen:

[+-]DIGITS.[DIGITS][e[+-]DIGITS]
[DIGITS].DIGITS[e[+-]DIGITS]
DIGITSe[+-]DIGITS

DIGITS stellt eine oder mehrere Dezimalzahlen (0 bis 9) dar und e stellt die Exponentenmarkierung (e oder E) dar.

Beispiele:

123.456e-67
.1E4
58.
4e2

Numerische Literale, die einen Dezimalpunkt oder eine Exponentenmarkierung enthalten, werden als "Double"-Typ betrachtet.

Das implizite Erzwingen von Gleitkommaliteralen in den "Float"-Typ ist möglich, wenn der Wert innerhalb des gültigen Gleitkommabereichs liegt.

Es gibt keine literale Darstellung von NaN oder unendlich, die folgenden Strings, bei denen die Groß-/Kleinschreibung nicht beachtet werden muss, können jedoch explizit in "float" umgewandelt werden:

  • "NaN"
  • "inf" oder "+inf"
  • "-inf"

Arrayliterale

Arrayliterale sind durch Kommas getrennte Listen von Elementen in eckigen Klammern. Das ARRAY-Keyword ist optional und ein expliziter Elementtyp "T" ist ebenfalls optional.

Beispiele:

[1, 2, 3]
['x', 'y', 'xy']
ARRAY[1, 2, 3]
ARRAY<string>['x', 'y', 'xy']
ARRAY<int64>[]

Strukturliterale

Syntax:

(elem[, elem...])

wobei elem ein Element in der Struktur ist. elem muss ein literaler Datentyp sein, kein Ausdruck oder Spaltenname.

Der Ausgabetyp ist ein anonymer Strukturtyp (Strukturen sind keine benannten Typen) mit anonymen Feldern, deren Typen mit den Typen der Eingabeausdrücke übereinstimmen.

Beispiel Ausgabetyp
(1, 2, 3) STRUCT<int64,int64,int64>
(1, 'abc') STRUCT<int64,string>

Datumsliterale

Syntax:

DATE 'YYYY-M[M]-D[D]'

Datumsliterale enthalten das Keyword DATE, gefolgt von einem Stringliteral, das dem kanonischen Datumsformat entspricht und in einfache Anführungszeichen eingeschlossen ist. Datumsliterale unterstützen einen Bereich zwischen den Jahren 1 und 9999 (einschließlich). Datumsangaben außerhalb dieses Bereichs sind ungültig.

Das folgende Datumsliteral stellt beispielsweise den 27. September 2014 dar:

DATE '2014-09-27'

Stringliterale im kanonischen Datumsformat werden außerdem implizit in den DATE-Typ umgewandelt, wenn sie an einer Stelle verwendet werden, an der ein Ausdruck vom Typ DATE erwartet wird. Beispiel: In der Abfrage

SELECT * FROM foo WHERE date_col = "2014-09-27"

wird das Stringliteral "2014-09-27" in ein Datumsliteral umgewandelt.

Zeitstempelliterale

Syntax:

TIMESTAMP 'YYYY-[M]M-[D]D [[H]H:[M]M:[S]S[.DDDDDD] [timezone]]`

Zeitstempelliterale enthalten das TIMESTAMP Keyword und ein Zeichenfolgenliteral, das dem kanonischen Zeitstempelformat entspricht, in einfachen Anführungszeichen.

Zeitstempelliterale unterstützen einen Bereich zwischen den Jahren 1 und 9999 einschließlich. Zeitstempel außerhalb dieses Bereichs sind ungültig.

Ein Zeitstempelliteral kann ein numerisches Suffix zur Angabe der Zeitzone enthalten:

TIMESTAMP '2014-09-27 12:30:00.45-08'

Wenn dieses Suffix nicht vorhanden ist, wird die Standard-Zeitzone America/Los_Angeles verwendet.

Beispiel: Der folgende Zeitstempel stellt 12:30 Uhr am 27. September 2014 in der Zeitzone America/Los_Angeles dar:

TIMESTAMP '2014-09-27 12:30:00.45'

Weitere Informationen zu Zeitzonen finden Sie im Abschnitt Zeitzone.

Stringliterale mit dem kanonischen Zeitstempelformat, einschließlich Literalen mit Zeitzonennamen, werden implizit in ein Zeitstempelliteral umgewandelt, wenn sie an einer Stelle verwendet werden, an der ein Zeitstempelausdruck erwartet wird. In der folgenden Abfrage wird beispielsweise das Stringliteral "2014-09-27 12:30:00.45 America/Los_Angeles" in ein Zeitstempelliteral umgewandelt.

SELECT * FROM foo
WHERE timestamp_col = "2014-09-27 12:30:00.45 America/Los_Angeles"

Ein Zeitstempelliteral kann diese optionalen Zeichen enthalten:

  • T oder t: Ein Flag für die Uhrzeit. Verwenden Sie es als Trennzeichen zwischen Datum und Uhrzeit.
  • Z oder z: Ein Flag für die Standardzeitzone. Dieses kann nicht mit [timezone] verwendet werden.

Wenn Sie eines dieser Zeichen verwenden, darf davor oder danach kein Leerzeichen stehen. Diese Formate sind gültig:

TIMESTAMP '2017-01-18T12:34:56.123456Z'
TIMESTAMP '2017-01-18t12:34:56.123456'
TIMESTAMP '2017-01-18 12:34:56.123456z'
TIMESTAMP '2017-01-18 12:34:56.123456Z'

Zeitzone

Da Zeitstempelliterale einem bestimmten Zeitpunkt zugeordnet werden müssen, ist eine Zeitzone zur korrekten Interpretation eines Literals erforderlich. Wenn eine Zeitzone nicht als Teil des Literals selbst angegeben wird, wird von Cloud Spanner SQL der Standardzeitzonenwert verwendet, der von der Cloud Spanner SQL-Implementierung festgelegt wird.

Cloud Spanner SQL stellt Zeitzonen mithilfe von Strings im folgenden kanonischen Format dar, das den Zeitversatz gegenüber koordinierter Weltzeit (Coordinated Universal Time, UTC) ausdrückt.

Format:

(+|-)H[H][:M[M]]

Beispiele:

'-08:00'
'-8:15'
'+3:00'
'+07:30'
'-7'

Zeitzonen können auch mit Stringzeitzonennamen aus der tz-Datenbank ausgedrückt werden. Eine weniger umfassende, aber einfachere Referenz finden Sie unter List of tz database time zones bei Wikipedia. Kanonische Zeitzonennamen haben das Format <continent/[region/]city>, wie America/Los_Angeles.

Beispiel:

TIMESTAMP '2014-09-27 12:30:00 America/Los_Angeles'
TIMESTAMP '2014-09-27 12:30:00 America/Argentina/Buenos_Aires'

Berücksichtigung der Groß-/Kleinschreibung

Bei Cloud Spanner gelten folgende Regeln für die Berücksichtigung der Groß-/Kleinschreibung:

Kategorie Wird Groß- und Kleinschreibung berücksichtigt? Hinweise
Keywords Nein  
Funktionsnamen Nein  
Tabellennamen Siehe Hinweise Bei Tabellennamen wird in der Regel die Groß-/Kleinschreibung nicht berücksichtigt. Sie kann jedoch bei der Abfrage einer Datenbank beachtet werden, in der die Groß-/Kleinschreibung in den Tabellennamen Verwendung findet.
Spaltennamen Nein  
Stringwerte Ja
Stringvergleiche Ja  
Aliasse innerhalb einer Abfrage Nein  
Abgleich regulärer Ausdrücke Siehe Hinweise Beim Abgleich regulärer Ausdrücke muss die Groß-/Kleinschreibung standardmäßig berücksichtigt werden, es sei denn, der Ausdruck selbst gibt an, dass die Groß-/Kleinschreibung nicht berücksichtigt werden soll.
LIKE-Abgleich Ja  

Reservierte Keywords

Keywords bestehen aus einer Gruppe von Token, die in der Sprache von Cloud Spanner SQL eine besondere Bedeutung haben. Sie haben folgende Eigenschaften:

  • Keywords können nur als Kennungen verwendet werden, wenn sie in Graviszeichen (`) stehen.
  • Bei Keywords muss die Groß-/Kleinschreibung nicht berücksichtigt werden.

Cloud Spanner SQL enthält die folgenden reservierten Keywords.

ALL
AND
ANY
ARRAY
AS
ASC
ASSERT_ROWS_MODIFIED
AT
BETWEEN
BY
CASE
CAST
COLLATE
CONTAINS
CREATE
CROSS
CUBE
CURRENT
DEFAULT
DEFINE
DESC
DISTINCT
ELSE
END
ENUM
ESCAPE
EXCEPT
EXCLUDE
EXISTS
EXTRACT
FALSE
FETCH
FOLLOWING
FOR
FROM
FULL
GROUP
GROUPING
GROUPS
HASH
HAVING
IF
IGNORE
IN
INNER
INTERSECT
INTERVAL
INTO
IS
JOIN
LATERAL
LEFT
LIKE
LIMIT
LOOKUP
MERGE
NATURAL
NEW
NO
NOT
NULL
NULLS
OF
ON
OR
ORDER
OUTER
OVER
PARTITION
PRECEDING
PROTO
RANGE
RECURSIVE
RESPECT
RIGHT
ROLLUP
ROWS
SELECT
SET
SOME
STRUCT
TABLESAMPLE
THEN
TO
TREAT
TRUE
UNBOUNDED
UNION
UNNEST
USING
WHEN
WHERE
WINDOW
WITH
WITHIN

Abschließende Semikola

Sie können optional ein abschließendes Semikolon (;) verwenden, wenn Sie eine Abfragestringanweisung über eine API senden.

In einer Anfrage mit mehreren Anweisungen müssen Sie die Anweisungen durch Semikola trennen, nach der letzten Anweisung ist das Semikolon im Allgemeinen jedoch optional. Bei einigen interaktiven Tools müssen Anweisungen ein abschließendes Semikolon enthalten.

Nachgestellte Kommas

Optional können Sie ein nachgestelltes Komma (,) am Ende einer Liste in einer SELECT-Anweisung verwenden.

Beispiel

SELECT name, release_date, FROM Books

Suchparameter

Sie können Suchparameter verwenden, um beliebige Ausdrücke zu ersetzen. Suchparameter können jedoch nicht verwendet werden, um Kennzeichnungen, Spaltennamen, Tabellennamen oder andere Teile der Abfrage selbst zu ersetzen. Suchparameter werden außerhalb der Abfrageanweisung definiert.

Client-APIs ermöglichen die Bindung von Parameternamen an Werte. Die Abfrage-Engine ersetzt einen begrenzten Wert für einen Parameter bei der Ausführung.

Benannte Suchparameter

Syntax:

@parameter_name

Ein benannter Suchparameter wird durch eine Kennung angegeben, der das Zeichen @ vorangestellt ist.

Beispiel:

In diesem Beispiel werden alle Zeilen zurückgegeben, in denen LastName dem Wert des benannten Suchparameters myparam entspricht.

SELECT * FROM Roster WHERE LastName = @myparam

Hinweise

@{ hint [, ...] }

hint:
  [engine_name.]hint_name = value

Der Zweck eines Hinweises besteht darin, die Ausführungsstrategie für eine Abfrage zu ändern, ohne das Ergebnis der Abfrage zu ändern. Hinweise wirken sich im Allgemeinen nicht auf die Abfragesemantik aus, können jedoch Auswirkungen auf die Leistung haben. Diese Hinweistypen sind verfügbar:

Die Hinweissyntax erfordert das Zeichen @ gefolgt von geschweiften Klammern. Sie können einen Hinweis oder eine Gruppe von Hinweisen erstellen. Mit dem optionalen Präfix engine_name. können mehrere Suchmaschinen Hinweise mit demselben hint_name definieren. Dies ist wichtig, wenn Sie verschiedene Suchmaschinenspezifische Ausführungsstrategien vorschlagen müssen oder verschiedene Suchmaschinen unterschiedliche Hinweise unterstützen.

Sie können Hinweisen Bezeichner und Literale zuweisen.

  • Kennungen sind nützlich für Hinweise, die wie Aufzählungen funktionieren sollen. Sie können eine Kennung verwenden, um die Verwendung eines Strings in Anführungszeichen zu vermeiden. In der aufgelösten AST werden Identitätshinweise als Stringliterale dargestellt, sodass @{hint="abc"} mit @{hint=abc} identisch ist. Kennungshinweise können auch für Hinweise verwendet werden, die einen Tabellennamen oder Spaltennamen als einzelne Kennung verwenden.
  • NULL-Literale sind zulässig und werden als Ganzzahlen abgeleitet.

Hinweise gelten nur für den Knoten, mit dem sie verknüpft sind, und nicht für einen größeren Bereich. Beispiel: Ein Hinweis auf ein JOIN in der Mitte der FROM-Klausel soll nur für diesen JOIN gelten und nicht für andere JOIN in der FROM-Klausel. Hinweise auf Anweisungsebene können für Hinweise verwendet werden, die die Ausführung einer gesamten Anweisung ändern, z. B. ein Gesamtspeicherbudget oder eine Frist.

Beispiele

In diesem Beispiel wird einem Hinweis ein Literal zugewiesen. Dieser Hinweis wird nur mit zwei Datenbank-Engines namens database_engine_a und database_engine_b verwendet. Der Wert für den Hinweis ist für jede Datenbank-Engine unterschiedlich.

@{ database_engine_a.file_count=23, database_engine_b.file_count=10 }

In diesem Beispiel wird einem Hinweis eine Kennung zugewiesen. Für jeden Hinweistyp gibt es eindeutige Kennungen. Am Anfang dieses Themas können Sie eine Liste mit Hinweistypen aufrufen.

@{ JOIN_METHOD=HASH_JOIN }

Kommentare

Kommentare sind Zeichensequenzen, die der Parser ignoriert. Cloud Spanner SQL unterstützt die folgenden Typen von Kommentaren.

Einzeilige Kommentare

Verwenden Sie einen einzeiligen Kommentar, wenn der Kommentar in einer eigenen Zeile angezeigt werden soll.

Beispiele

# this is a single-line comment
SELECT book FROM library;
-- this is a single-line comment
SELECT book FROM library;
/* this is a single-line comment */
SELECT book FROM library;
SELECT book FROM library
/* this is a single-line comment */
WHERE book = "Ulysses";

Inline-Kommentare

Verwenden Sie einen Inline-Kommentar, wenn der Kommentar in derselben Zeile wie eine Anleitung angezeigt werden soll. Ein Kommentar mit vorangestelltem # oder -- muss rechts von einer Anleitung stehen.

Beispiele

SELECT book FROM library; # this is an inline comment
SELECT book FROM library; -- this is an inline comment
SELECT book FROM library; /* this is an inline comment */
SELECT book FROM library /* this is an inline comment */ WHERE book = "Ulysses";

Mehrzeilige Kommentare

Verwenden Sie einen mehrzeiligen Kommentar, wenn der Kommentar mehrere Zeilen umfassen soll. Verschachtelte mehrzeilige Kommentare werden nicht unterstützt.

Beispiele

SELECT book FROM library
/*
  This is a multiline comment
  on multiple lines
*/
WHERE book = "Ulysses";
SELECT book FROM library
/* this is a multiline comment
on two lines */
WHERE book = "Ulysses";