Structure lexicale et syntaxe

Une instruction SQL Cloud Spanner comprend une série de jetons. Les jetons incluent les éléments suivants : identifiants, identifiants entre guillemets, littéraux, mots clés, opérateurs et caractères spéciaux. Vous pouvez séparer les jetons par un espace blanc (par exemple, une espace, un retour arrière, une tabulation, un retour à la ligne) ou des commentaires.

Identifiants

Les identifiants sont des noms associés à des colonnes, des tables et d'autres objets de base de données. Ils peuvent être entre guillemets ou sans guillemets.

  • Les identifiants peuvent être utilisés dans les expressions de chemin, qui renvoient une valeur STRUCT.
  • Certains identifiants sont sensibles à la casse et d'autres non. Pour en savoir plus, consultez la section Sensibilité à la casse.
  • Les identifiants sans guillemets doivent commencer par une lettre ou un trait de soulignement. Les autres caractères peuvent être des lettres, des chiffres ou des traits de soulignement.
  • Les identifiants entre guillemets doivent être délimités par des accents graves (`).
    • Les identifiants entre guillemets peuvent contenir n'importe quel caractère (tel que des espaces ou des symboles).
    • Ils ne peuvent cependant pas être vides.
    • Les identifiants entre guillemets ont les mêmes séquences d'échappement que les littéraux de chaîne.
    • Un mot clé réservé doit être un identifiant entre guillemets s'il s'agit d'un mot clé autonome ou du premier composant d'une expression de chemin. Lorsqu'il n'est pas le premier composant d'une expression de chemin (donc à partir du deuxième composant), il peut ne pas être entre guillemets.

Exemples

Les identifiants suivants sont valides :

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

Les expressions de chemin suivantes contiennent des identifiants valides :

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

Les identifiants suivants ne sont pas valides :

5Customers
_dataField!
GROUP

5Customers commence par un chiffre, et non par une lettre ou un trait de soulignement. _dataField! contient le caractère spécial "!" qui ne correspond pas à une lettre, un chiffre ou un trait de soulignement. GROUP est un mot clé réservé et ne peut donc être utilisé comme identifiant s'il n'est pas délimité par des accents graves.

Littéraux

Un littéral représente une valeur constante d'un type de données intégré. Certains types de données, mais pas tous, peuvent être exprimés sous forme de littéraux.

Littéraux de chaîne et d'octets

Les littéraux de chaîne et d'octets doivent être placés entre guillemets simples (') ou doubles ("), ou bien entre guillemets triples avec des groupes de trois guillemets simples (''') ou doubles (""").

Littéraux entre guillemets :

Littéral Exemples Description
Chaîne entre guillemets
  • "abc"
  • "it's"
  • 'it\'s'
  • 'Title: "Boy"'
Les chaînes entre guillemets simples (') peuvent contenir des guillemets doubles (") non échappés, et inversement.
Les barres obliques inverses (\) introduisent des séquences d'échappement. Consultez le tableau des séquences d'échappement ci-dessous.
Les chaînes entre guillemets ne peuvent pas contenir de retour à la ligne, même lorsqu'elles sont précédées d'une barre oblique inverse (\).
Chaîne entre guillemets triples
  • """abc"""
  • '''it's'''
  • '''Title:"Boy"'''
  • '''two
    lines'''
  • '''why\?'''
Les retours à la ligne et les guillemets intégrés sont autorisés sans échappement (voir le quatrième exemple).
Les barres obliques inverses (\) introduisent des séquences d'échappement. Consultez le tableau des séquences d'échappement ci-dessous.
Une barre oblique inverse (\) non échappée ne peut pas être placée à la fin d'une ligne.
Marquez la fin de la chaîne par trois guillemets non échappés consécutifs correspondant aux guillemets de début.
Chaîne brute
  • R"abc+"
  • r'''abc+'''
  • R"""abc+"""
  • r'f\(abc,(.*),def\)'
Les littéraux entre guillemets (simples, doubles ou triples) qui comportent le préfixe de littéral de chaîne brute (r ou R) sont interprétés comme des chaînes brutes ou d'expressions régulières.
Les barres obliques inverses (\) ne font pas office de caractères d'échappement. Si une barre oblique inverse suivie d'un autre caractère figure à l'intérieur du littéral de chaîne, les deux caractères sont conservés.
Une chaîne brute ne peut pas se terminer par un nombre impair de barres obliques inverses.
Les chaînes brutes sont utiles pour créer des expressions régulières.

Les caractères de préfixe (r, R, b et B)) sont facultatifs pour les chaînes entre guillemets simples, doubles ou triples. Ils indiquent que ces dernières correspondent respectivement à des chaînes brutes/d'expressions régulières ou à une séquence d'octets. Par exemple, les chaînes b'abc' et b'''abc''' sont toutes deux interprétées comme des octets. Les caractères de préfixe ne sont pas sensibles à la casse.

Littéraux entre guillemets comportant des préfixes :

Littéral Exemple Description
Bytes
  • B"abc"
  • B'''abc'''
  • b"""abc"""
Les littéraux entre guillemets (simples, doubles ou triples) qui comportent le préfixe de littéral d'octets (b ou B) sont interprétés comme des octets.
Octets bruts
  • br'abc+'
  • RB"abc+"
  • RB'''abc'''
Les préfixes r et b peuvent être combinés dans n'importe quel ordre. Par exemple, rb'abc*' correspond à br'abc*'.

Le tableau ci-dessous répertorie toutes les séquences d'échappement valides permettant de représenter des caractères non alphanumériques dans des littéraux de chaîne et d'octets. Toute séquence ne figurant pas dans ce tableau génère une erreur.

Séquence d'échappement Description
\a Caractère d'appel audible
\b Retour arrière
\f Saut de page
\n Retour à la ligne
\r Retour chariot
\t Tabulation
\v Tabulation verticale
\\ Barre oblique inverse (\)
\? Point d'interrogation (?)
\" Guillemet double (")
\' Guillemet simple (')
\` Accent grave (`)
\ooo Échappement octal, avec exactement trois chiffres (dans la plage 0 à 7). Décodage sous la forme d'un seul caractère Unicode (dans les littéraux de chaîne) ou d'un octet (dans les littéraux d'octets).
\xhh ou \Xhh Échappement hexadécimal, avec exactement deux chiffres hexadécimaux (0 à 9, A à F, ou a à f). Décodage sous la forme d'un seul caractère Unicode (dans les littéraux de chaîne) ou d'un octet (dans les littéraux d'octets). Exemples :
  • '\x41' == 'A'
  • '\x41B' correspond à 'AB'.
  • '\x4' correspond à une erreur.
\uhhhh Échappement Unicode, avec la lettre minuscule "u" et exactement quatre chiffres hexadécimaux. Valable uniquement dans les littéraux de chaîne ou les identifiants.
La plage D800 à DFFF n'est pas autorisée, car elle correspond à des valeurs Unicode de substitution.
\Uhhhhhhhh Échappement Unicode, avec la lettre majuscule "U" et exactement huit chiffres hexadécimaux. Valable uniquement dans les littéraux de chaîne ou les identifiants.
La plage D800 à DFFF n'est pas autorisée, car elle correspond à des valeurs Unicode de substitution. De plus, les valeurs supérieures à 10FFFF ne sont pas autorisées.

Littéraux entiers

Les littéraux entiers correspondent à une séquence de chiffres décimaux (0 à 9) ou à une valeur hexadécimale précédée du préfixe "0x" ou "0X". Les nombres entiers peuvent être précédés du préfixe "+" ou "-" pour représenter respectivement des valeurs positives et négatives. Exemples :

123
0xABC
-123

Un littéral entier est interprété comme un type de données INT64.

Littéraux numériques (NUMERIC)

Vous pouvez créer des littéraux numériques (NUMERIC) à l'aide du mot clé NUMERIC, suivi d'une valeur à virgule flottante entre guillemets.

Exemples :

SELECT NUMERIC '0';
SELECT NUMERIC '123456';
SELECT NUMERIC '-3.14';
SELECT NUMERIC '-0.54321';
SELECT NUMERIC '1.23456e05';
SELECT NUMERIC '-9.876e-3';

Littéraux à virgule flottante

Options de syntaxe :

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

DIGITS représente un ou plusieurs chiffres décimaux (0 à 9). e désigne le marqueur d'exposant (e ou E).

Exemples :

123.456e-67
.1E4
58.
4e2

Les littéraux numériques qui contiennent un symbole décimal ou un marqueur d'exposant sont supposés être de type "double".

La conversion implicite des littéraux à virgule flottante en type "float" est possible si la valeur est comprise dans la plage valide de valeurs à virgule flottante.

Il n'existe pas de représentation littérale de NaN ou de l'infini. Toutefois, les chaînes suivantes qui ne sont pas sensibles à la casse peuvent être explicitement converties en valeurs de type "float" :

  • "NaN"
  • "inf" ou "+inf"
  • "-inf"

Littéraux de tableau

Les littéraux de tableau correspondent à des listes d'éléments séparés par une virgule et placés entre crochets. Le mot clé ARRAY est facultatif. Un type d'élément explicite T est également facultatif.

Exemples :

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

Littéraux de structure

Syntaxe :

(elem[, elem...])

elem est un élément de la structure. elem doit correspondre à un type de données littéral, et non à une expression ou à un nom de colonne.

Le type de résultat est un type de structure anonyme (les structures n'étant pas des types nommés) comportant des champs anonymes dont les types correspondent à ceux des expressions d'entrée.

Exemple Type de sortie
(1, 2, 3) STRUCT<int64,int64,int64>
(1, 'abc') STRUCT<int64,string>

Littéraux de date

Syntaxe :

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

Les littéraux de date contiennent le mot clé DATE, suivi d'un littéral de chaîne qui est conforme au format de date canonique et délimité par des guillemets simples. Ils acceptent une plage comprise entre 1 et 9 999 (inclus). Les dates situées en dehors de cette plage ne sont pas valides.

Par exemple, le littéral de date suivant représente le 27 septembre 2014 :

DATE '2014-09-27'

Les littéraux de chaîne au format de date canonique sont également convertis implicitement en littéraux de type DATE lorsqu'ils sont utilisés là où une expression de type DATE est attendue. Prenons l'exemple de la requête suivante :

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

Le littéral de chaîne "2014-09-27" est converti implicitement en littéral de date.

Littéraux d'horodatage

Syntaxe :

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

Les littéraux d'horodatage contiennent le mot clé TIMESTAMP ainsi qu'un littéral de chaîne qui est conforme au format d'horodatage canonique et délimité par des guillemets simples.

Ils acceptent une plage comprise entre 1 et 9 999 (inclus). Les horodatages situés en dehors de cette plage ne sont pas valides.

Un littéral d'horodatage peut inclure un suffixe numérique pour indiquer le fuseau horaire :

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

Si ce suffixe est absent, le fuseau horaire par défaut (America/Los_Angeles) est utilisé.

Par exemple, l'horodatage suivant correspond au 27 septembre 2014 à 12h30 dans le fuseau horaire America/Los_Angeles :

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

Pour plus d'informations sur les fuseaux horaires, consultez la section Fuseau horaire.

Les littéraux de chaîne utilisant le format d'horodatage canonique, y compris ceux comportant des noms de fuseau horaire, sont convertis implicitement en littéraux d'horodatage lorsqu'ils sont utilisés là où une expression d'horodatage est attendue. Par exemple, dans la requête suivante, le littéral de chaîne "2014-09-27 12:30:00.45 America/Los_Angeles" est converti implicitement en littéral d'horodatage :

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

Un littéral d'horodatage peut inclure les caractères facultatifs suivants :

  • T ou t : option de temps. À utiliser comme séparateur entre la date et l'heure.
  • Z ou z : option du fuseau horaire par défaut. Vous ne pouvez pas l'utiliser avec [timezone].

Si vous utilisez l'un de ces caractères, vous ne pouvez pas insérer d'espace ni avant, ni après. Les exemples suivants sont valides :

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'

Fuseau horaire

Étant donné que les littéraux d'horodatage doivent être mappés avec un instant précis, un fuseau horaire est nécessaire pour les interpréter correctement. Si aucun fuseau horaire n'est spécifié dans le littéral lui-même, la valeur de fuseau horaire par défaut, qui est définie par l'implémentation du langage SQL de Cloud Spanner, est utilisée.

Le langage SQL de Cloud Spanner représente les fuseaux horaires par des chaînes au format canonique présenté ci-dessous, qui représente le décalage par rapport au temps universel coordonné (UTC).

Format :

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

Exemples :

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

Les fuseaux horaires peuvent également être exprimés à l'aide de noms de type chaîne figurant dans la base de données tz. Pour obtenir des informations de référence moins complètes, mais plus simples, consultez l'article Wikipedia List of tz database time zones (Liste des fuseaux horaires de la base de données tz). Les noms de fuseaux horaires canoniques utilisent le format <continent/[region/]city> (par exemple, America/Los_Angeles).

Exemple :

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

Sensibilité à la casse

Le langage SQL de Cloud Spanner respecte les règles ci-dessous concernant la sensibilité à la casse.

Catégorie Sensibilité à la casse Remarques
Mots clés Non  
Noms des fonctions Non  
Noms de table Voir les remarques Les noms de table ne sont généralement pas sensibles à la casse. La sensibilité à la casse peut toutefois s'appliquer lors de l'interrogation d'une base de données utilisant des noms de table sensibles à la casse.
Noms de colonne Non  
Valeurs de chaîne Oui
Comparaisons de chaînes Oui  
Alias utilisés dans une requête Non  
Correspondances d'expressions régulières Voir les remarques Les correspondances d'expressions régulières sont par défaut sensibles à la casse, sauf si l'expression elle-même spécifie qu'elle ne doit pas l'être.
Correspondances LIKE Oui  

Mots clés réservés

Les mots clés correspondent à un groupe de jetons qui ont une signification particulière dans le langage SQL de Cloud Spanner et présentent les caractéristiques suivantes :

  • Ils ne peuvent pas être utilisés comme identifiants, sauf s'ils sont délimités par des accents graves (`).
  • Ils ne sont pas sensibles à la casse.

Le langage SQL de Cloud Spanner utilise les mots clés réservés ci-dessous.

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

Points-virgules de fin

Vous pouvez éventuellement utiliser un point-virgule de fin (;) lorsque vous envoyez une instruction de chaîne de requête via une interface de programmation d'application (API).

Dans une requête contenant plusieurs instructions, ces dernières doivent être séparées par un point-virgule. Toutefois, celui-ci est généralement facultatif pour l'instruction finale. Certains outils interactifs requièrent que les instructions incluent un point-virgule de fin.

Virgules de fin

Vous pouvez éventuellement utiliser une virgule de fin (,) à la fin d'une liste dans une instruction SELECT.

Exemple

SELECT name, release_date, FROM Books

Paramètres de requête

Vous pouvez utiliser des paramètres de requête pour remplacer des expressions arbitraires. Toutefois, vous ne pouvez pas utiliser les paramètres de requête en remplacement d'identifiants, de noms de colonne, de noms de table ou d'autres parties d'une requête. Les paramètres de requête sont définis en dehors de l'instruction de requête.

Les API clientes permettent de lier des noms de paramètres à des valeurs. Le moteur de requête remplace un paramètre par une valeur liée au moment de l'exécution.

Paramètres de requête nommés

Syntaxe :

@parameter_name

Un paramètre de requête nommé est désigné à l'aide d'un identifiant précédé du caractère @.

Exemple :

Cet exemple renvoie toutes les lignes où LastName est égal à la valeur du paramètre de requête nommé myparam.

SELECT * FROM Roster WHERE LastName = @myparam

Astuces

@{ hint [, ...] }

hint:
  [engine_name.]hint_name = value

L'objectif d'une optimisation est de modifier la stratégie d'exécution d'une requête sans modifier le résultat de la requête. Les optimisations n'affectent généralement pas la sémantique des requêtes, mais peuvent avoir des conséquences sur les performances. Ces types d'optimisations sont disponibles :

La syntaxe d'optimisation nécessite le caractère @ suivi d'accolades. Vous pouvez créer une optimisation ou un groupe d'optimisations. Le préfixe facultatif engine_name. permet à plusieurs moteurs de définir des optimisations avec le même hint_name. Ceci est important si vous devez suggérer différentes stratégies d'exécution spécifiques au moteur ou si différents moteurs prennent en charge différentes optimisations.

Vous pouvez attribuer des identifiants et des littéraux aux optimisations.

  • Les identifiants sont utiles pour les optimisations destinées à agir comme des énumérations. Vous pouvez utiliser un identifiant pour éviter d'utiliser une chaîne entre guillemets. Dans l'AST résolue, les optimisations d'identifiants sont représentées sous forme de littéraux de chaîne. Par conséquent, @{hint="abc"} est identique à @{hint=abc}. Les optimisations d'identifiant peuvent également être utilisées pour les optimisations qui prennent un nom de tableau ou une colonne en tant qu'identifiant unique.
  • Les littéraux NULL sont autorisés et sont déduits sous forme d'entiers.

Les optimisations sont destinées à s'appliquer uniquement au nœud auquel elles sont associées, et non à un champ d'application plus large. Par exemple, une optimisation sur un JOIN au milieu de la clause FROM est destiné à s'appliquer uniquement à ce JOIN, et non aux autres JOIN de la clause FROM. Les optimisations au niveau de l'instruction peuvent être utilisées pour les optimisations qui modifient l'exécution d'une instruction complète, par exemple un budget de mémoire global ou un délai.

Exemples

Dans cet exemple, un littéral est attribué à une optimisation. Cette optimisation n'est utilisée qu'avec deux moteurs de base de données appelés database_engine_a et database_engine_b. La valeur de l'optimisation est différente pour chaque moteur de base de données.

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

Dans cet exemple, un identifiant est attribué à une optimisation. Il existe des identifiants uniques pour chaque type d'optimisation. Vous pouvez afficher la liste des types d'optimisation au début de cette rubrique.

@{ JOIN_METHOD=HASH_JOIN }

Comments

Les commentaires sont des séquences de caractères ignorées par l'analyseur. Le langage SQL de Cloud Spanner accepte les types de commentaires ci-dessous.

Commentaires sur une seule ligne

Utilisez un commentaire sur une seule ligne si vous souhaitez qu'il apparaisse seul sur une ligne.

Exemples

# 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";

Commentaires intégrés

Utilisez un commentaire intégré si vous souhaitez qu'il apparaisse sur la même ligne qu'une instruction. Un commentaire précédé de # ou -- doit apparaître à droite d'une instruction.

Exemples

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";

Commentaires multilignes

Utilisez un commentaire multiligne si vous souhaitez qu'il s'étende sur plusieurs lignes. Les commentaires multilignes imbriqués ne sont pas acceptés.

Exemples

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";