字面量¶
字面量(Literal)是指在 GQL 查询中直接使用的固定值。这些值可以是数字、字符串、日期、布尔值等,直接在查询中写出,而不是引用表中的列。字面量的类型由其声明时的形式确定。例如,双引号(")用于识别字符串字面量,而数字字面量不需要引号;DATETIME用于识别日期时间字面量。
本文介绍 GQL 中支持的字面量。
数值字面量¶
数值字面量指整数、浮点数以及任意精度数。更多信息,请参见数据类型。
整数字面量¶
当数值字面量为整数时:
- 默认整数值的数据类型为
INT32,取值范围为-2147483648到2147483647。
- 当整数值超出
INT32类型的取值范围时,GQL 默认将其转成INT64类型,取值范围为-9223372036854775808到9223372036854775807。
- 当整数值超出
INT64类型的取值范围时,GQL 默认将其转成DECIMAL类型。更多信息,请参见任意精度数字面量。
例如:
(root@doc)> RETURN 2147483647 // 2147483647 是 INT32 的最大值。
+------------+
| 2147483647 |
+------------+
| 2147483647 |
+------------+
(root@doc)> RETURN 2147483648 // 2147483648 超出 INT32 的最大值,自动转成 INT64 类型。
+------------+
| 2147483648 |
+------------+
| 2147483648 |
+------------+
(root@doc)> RETURN 9223372036854775808 // 9223372036854775808 超出 INT64 的最大值,自动转成 DECIMAL 类型。
+---------------------+
| 9223372036854775808 |
+---------------------+
| 9223372036854775808 |
+---------------------+
但是,在计算表达式中,如果数值的取值范围超出其数据类型的最大值,GQL 会报错。例如当 INT32 类型的值超出其最大值时,会报错:
(root@doc)> RETURN 2147483647+1
Error: [22003]: Numeric value out of range: `2147483647 + 1`, type: `INT32`
解决方法是将 INT32 类型的值显式地转成 INT64 类型,例如:
(root@doc)> RETURN CAST(2147483647 AS INT64) + 1
+-------------------------------+
| CAST(2147483647 AS INT64) + 1 |
+-------------------------------+
| 2147483648 |
+-------------------------------+
或者
(root@doc)> RETURN 2147483647 + CAST(1 AS INT64)
+-------------------------------+
| 2147483647 + CAST(1 AS INT64) |
+-------------------------------+
| 2147483648 |
+-------------------------------+
浮点数字面量¶
若要显式指定浮点数字面量的数据类型,可在数值后面加上后缀F或f以表示FLOAT类型,或者加上后缀D或d以表示DOUBLE类型。例如:
(root@doc)> RETURN cast(666.66 AS FLOAT) = 666.66F
+---------------------------------+
| cast(666.66 AS FLOAT) = 666.66F |
+---------------------------------+
| true |
+---------------------------------+
(root@doc)> RETURN cast(666.66 AS DOUBLE) = 666.66d
+----------------------------------+
| cast(666.66 AS DOUBLE) = 666.66d |
+----------------------------------+
| true |
+----------------------------------+
任意精度数字面量¶
任意精度数字面量的数据类型为DECIMAL,精度的取值范围为1 ~ 256,小数位数取值范围为0 ~ 128。若要显式指定任意精度数字面量,可在数值后面加上后缀M或m。例如:
(root@doc)> RETURN 9223372036854775807M+1
+------------------------+
| 9223372036854775807M+1 |
+------------------------+
| 9223372036854775808 |
+------------------------+
在 GQL 中,若没有对含小数位的数值指定后缀,默认其数据类型为DECIMAL。DECIMAL类型可以隐式或显式地转化成FLOAT或DOUBLE类型。更多信息,请参见预定义数据类型之间的转换。
(root@doc)> RETURN cast(666.66 AS FLOAT) = 666.66
+--------------------------------+
| cast(666.66 AS FLOAT) = 666.66 |
+--------------------------------+
| true |
+--------------------------------+
(root@doc)> RETURN cast(666.66 AS DOUBLE) = 666.66
+---------------------------------+
| cast(666.66 AS DOUBLE) = 666.66 |
+---------------------------------+
| true |
+---------------------------------+
字符串字面量¶
字符串字面量是由双引号(")或单引号(')包裹的零个或多个字符组合而成的。字符串必须使用相同类型的引号进行包裹,即成对使用单引号或成对使用双引号。
在表达式求值等运行时场景下,字符串值受 2³²−1 字节限制。更多信息,请参见字符串类型。
单引号字符串字面量¶
RETURN 'Hello, World!'
RETURN '12345'
RETURN 'A single quoted string'
双引号字符串字面量¶
RETURN "Hello, World!"
RETURN "12345"
RETURN "A double quoted string"
嵌套引号¶
可以在单引号字符串中直接使用双引号,或在双引号字符串中直接使用单引号,而无需进行转义操作。例如:
RETURN 'He said: "Hello, World!"'
RETURN "It's a beautiful day!"
字符串拼接¶
可以通过符号||拼接多个字符串字面量,例如:
(root@doc)> RETURN 'Hello, ' || 'World!' as _str
+---------------+
| _str |
+---------------+
| Hello, World! |
+---------------+
字符转义¶
在字符字面量中,有些字符需要使用反斜杠(\)进行转义,以避免与语法冲突。这些字符包括单引号(')本身、反斜杠(\)和其他特殊字符。
以下是一些常见的转义序列:
| 转义序列 | 描述 |
|---|---|
\\ |
反斜杠 |
\' |
单引号(仅在单引号字符串中需要转义) |
\" |
双引号(仅在双引号字符串中需要转义) |
\t |
制表符 |
\b |
退格符 |
\n |
换行符 |
\r |
回车符 |
\f |
换页符 |
\uXXXX |
Unicode 字符,其中\u后面跟 4 个十六进制数字。 |
\UXXXXXXXX |
Unicode 字符,其中\U后面跟 8 个十六进制数字。 |
(root@doc)> RETURN "'\n\"\n\\"
+-------------+
| "'\n\"\n\\" |
+-------------+
| '\n\"\n\ |
+-------------+
(root@doc)> RETURN "a\tb\tc\n1\t2\t3"
+--------------------+
| "a\tb\tc\n1\t2\t3" |
+--------------------+
| a\tb\tc\n1\t2\t3 |
+--------------------+
布尔字面量¶
布尔类型的字面量有 3 个值:
TRUE:表示真。FALSE:表示假。UNKNOWN:表示未知。
NULL 字面量¶
NULL字面量表示缺少值,与空字符串、数字0或空容器不同。NULL字面量的推导类型为NULL。当NULL字面量用于具有具体类型的上下文时,系统按照该上下文处理NULL值。
RETURN NULL, typeof(NULL)
关于NULL值、NULL类型和可否为 NULL 的区别,请参见 NULL 类型。
日期和时间字面量¶
时间点字面量¶
时间点字面量是由关键字,如DATETIME或DATE等,和单引号(')或双引号(")包裹的日期和时间组合而成的。时间点字面量的声明如下:
| 类型 | 声明关键字 | 默认格式 |
|---|---|---|
| 日期 | DATE |
YYYY-MM-DD |
| 时间 | TIME |
HH:MM:SS[.SSSSSS][-1200 ~ +1400] |
| 日期时间 | DATETIME |
YYYY-MM-DDTHH:MM:SS[.SSSSSS][-1200 ~ +1400] |
- 当字面量中不包含微秒(
.SSSSSS)时,GQL 默认将其设置为000000;当字面量中包含微秒时且长度不足 6 位时,GQL 会在末尾补 0。 - 当字面量中不包含时区信息时(
-1200 ~ +1400),GQL 默认使用当前会话中设置的时区;当字面量中包含时区信息时,返回的结果会根据时区信息转换为当前会话中的时间,即 UTC 时间加上当前会话所在时区的时区偏移量。
示例:
(root@doc)> '''
RETURN DATE '2022-12-31' AS _date,
TIME '12:34:56' AS _time,
TIME '12:34:56+0900' AS _zoned_time ,
DATETIME '2022-12-31T12:34:56' AS _datetime,
DATETIME '2022-12-31T12:34:56.123+0900' AS _zoned_datetime
'''
+------------+-----------------+------------------+----------------------------+-----------------------------+
| _date | _time | _zoned_time | _datetime | _zoned_datetime |
+------------+-----------------+------------------+----------------------------+-----------------------------+
| 2022-12-31 | 12:34:56.000000 | 03:34:56.000000Z | 2022-12-31T12:34:56.000000 | 2022-12-31T03:34:56.123000Z |
+------------+-----------------+------------------+----------------------------+-----------------------------+
- 如需查看当前会话中默认的日期和时间格式,请参见 SHOW CURRENT_SESSION TIME FORMATS。
- 如需查看当前会话中的时区信息,请参见 SHOW CURRENT_SESSION。
- 如需修改当前会话中的日期和时间格式,请参见 SESSION SET。
时间段字面量¶
时间段字面量是由关键字DURATION和单引号(')或双引号(")包裹的时间段组合而成的。
DURATION字面量可以用以下两种格式表示:
-
P[nY][nM]格式:表示年和月的时间间隔。例如,P1Y2M表示 1 年 2 个月的时间间隔。P:表示时间间隔的前缀。nY:表示 n 年。nM:表示 n 月。
-
P[nD]T[nH][nM][nS]格式:表示天、小时、分钟和秒的时间间隔。例如,P3DT4H30M5S:表示 3 天 4 小时 30 分钟 5 秒的时间间隔。P:表示时间间隔的前缀。nD:表示 n 天。T:表示时间部分的前缀(如果有小时、分钟或秒)。nH:表示 n 小时。nM:表示 n 分钟。nS:表示 n 秒,可以包含小数部分。
示例:
(root@doc)> '''
RETURN DURATION 'P1Y' AS _year,
DURATION 'P2M' AS _month,
DURATION 'P1Y2M' AS _duration1,
DURATION 'P3D' AS _day,
DURATION 'PT4H30M5S' AS _duration2,
DURATION 'P3DT4H30M5S' AS _duration3,
DURATION 'P3DT4H30M5.123S' AS _duration4
'''
+-------+--------+------------+------+------------+-------------+-----------------+
| _year | _month | _duration1 | _day | _duration2 | _duration3 | _duration4 |
+-------+--------+------------+------+------------+-------------+-----------------+
| P1Y | P2M | P1Y2M | P3D | PT4H30M5S | P3DT4H30M5S | P3DT4H30M5.123S |
+-------+--------+------------+------+------------+-------------+-----------------+
时间点字面量和时间段字面量的运算¶
时间点字面量和时间段字面量之间可以进行加减运算,例如:
(root@doc)> RETURN DATETIME '2022-12-31T12:34:56' + DURATION 'P1Y2M' AS _datetime
+----------------------------+
| _datetime |
+----------------------------+
| 2024-02-29T12:34:56.000000 |
+----------------------------+
更多关于时间点字面量和时间段字面量的运算规则,请参见日期和时间值的运算。
向量字面量¶
向量字面量的声明如下:
VECTOR<dimension, coordinate_type>([coordinate1, coordinate2, ...])
或
VECTOR(coordinate1, coordinate2, ...)
dimension:向量字面量的维度数,取值范围为 1 到 2,147,483,647。若不指定,则自动根据向量字面量的坐标数推断维度数。coordinate_type:向量字面量的坐标的数据类型,必须是FLOAT。若不指定,则默认为FLOAT。coordinate1, coordinate2, ...:向量字面量的坐标的取值。若用dimension指定了维度数,则坐标的数量必须等于维度数。每个坐标的取值不可为NULL。
示例:
(root@doc)> RETURN VECTOR<3, FLOAT>([1.0, 2.0, 3.0]) AS v1, VECTOR(1, 2, 3) AS v2
向量字面量的运算¶
向量字面量之间可以进行加减运算,例如:
(root@nebula)> LET x = VECTOR<3, FLOAT>([10.1, 20.2, 30.3]), y = VECTOR<3, FLOAT>([2.2, 3.3, 4.4]), z = VECTOR<3, FLOAT>([1.2, 2.3, 3.3]) RETURN x + y -z AS w
+-----------------------+
| w |
+-----------------------+
| [11.1,21.2,31.400002] |
+-----------------------+
更多关于向量字面量的运算规则,请参见支持的算术运算。
列表字面量¶
列表字面量是由方括号([])包裹的零个或多个值组合而成的,方括号前可以有类型声明,也可以省略。列表字面量的声明如下:
type? [value1, value2, ...]
type:声明列表的关键字,为LIST或ARRAY。- 列表字面量中的值可以是任意类型的字面量,也可以是表达式的结果,但是列表中的所有值必须是同一类型。
示例:
(root@doc)> '''
RETURN [1+2, 2+3, 3+4] AS _list,
LIST [true, false, unknown] AS _list1,
ARRAY ['a', 'b', 'c'] AS _list2,
[ RECORD {a :123, b: true }, RECORD {a:456, b: false} ] AS _list3,
[ VECTOR<3, FLOAT>([1.0, 2.0, 3.0]), VECTOR<3, FLOAT>([4.0, 5.0, 6.0]) ] AS _list4
'''
+---------+-------------------+---------+----------------------------------+-------------------------------+
| _list | _list1 | _list2 | _list3 | _list4 |
+---------+-------------------+---------+----------------------------------+-------------------------------+
| [3,5,7] | [true,false,null] | [a,b,c] | [{a:123,b:true},{a:456,b:false}] | [[1.0,2.0,3.0],[4.0,5.0,6.0]] |
+---------+-------------------+---------+----------------------------------+-------------------------------+
如需拼接多个列表字面量,可以使用符号||。多个列表字面量的类型必须相同,例如:
(root@doc)> RETURN [1, 2, 3] || [4, 5, 6] AS _list
+---------------+
| _list |
+---------------+
| [1,2,3,4,5,6] |
+---------------+
关于列表字面量的更多信息,请参见列表类型。
集合字面量 ¶
集合字面量的声明如下:
SET {value, value, ...}
集合字面量中的值可以是任意类型的字面量,也可以是表达式的结果,但是集合中的所有值必须是同一类型。
集合字面量中的元素是无序的且不重复的。如果构造时包含重复值,系统会自动去重。
示例:
(root@doc)> '''
RETURN SET {} AS _set,
SET {true, false, unknown} AS _set1,
SET {"a", "b", "c"} AS _set2,
SET {RECORD {a :123, b: true }, RECORD {a:456, b: false} } AS _set3,
SET {VECTOR<3, FLOAT>([1.0, 2.0, 3.0]), VECTOR<3, FLOAT>([4.0, 5.0, 6.0]) } AS _set4
'''
+------+-------------------+---------+------------------------------------+-------------------------------+
| _set | _set1 | _set2 | _set3 | _set4 |
+------+-------------------+---------+------------------------------------+-------------------------------+
| {} | {null,false,true} | {c,b,a} | { {a:456,b:false},{a:123,b:true} } | {[4.0,5.0,6.0],[1.0,2.0,3.0]} |
+------+-------------------+---------+------------------------------------+-------------------------------+
集合字面量的运算¶
集合字面量之间可以进行并集运算,例如:
(root@doc)> RETURN set{}||set{} AS a, set{}||set{1,2,3} AS b, set{1,2,3}||set{} AS c
+----+---------+---------+
| a | b | c |
+----+---------+---------+
| {} | {1,2,3} | {1,2,3} |
+----+---------+---------+
更多信息,请参见支持的操作符。
映射字面量 ¶
映射字面量的声明如下:
MAP {key1: value1, key2: value2, ...}
- 映射字面量中的键可以是任意类型的字面量,也可以是不依赖任何变量的表达式的结果。映射中的所有键必须是唯一且同一类型的。如果在构造映射字面量时提供了重复的键,则保留第一个键及其对应的值。
- 映射字面量中的值可以是任意类型的字面量,也可以是不依赖任何变量的表达式的结果。映射中的所有值必须是同一类型。
示例:
(root@doc)> '''
RETURN MAP { 'a': 1, 'b': 2, 'c': 3 } AS _map,
MAP { 1: DATE '2022-12-31', 2: DATETIME '2022-12-31T12:34:56' } AS _map1,
MAP { true: DURATION 'P1Y2M', false: DURATION 'P3DT4H' } AS _map2,
MAP { [1,2]: VECTOR<3, FLOAT>([1.0, 2.0, 3.0]), [4,5]: VECTOR<3, FLOAT>([4.0, 5.0, 6.0]) } AS _map3,
MAP { SET{1,2}: RECORD {x: 'set', y: 'type'}, SET{3,4}: RECORD {x: 'set', y: 'literal'} } AS _map4,
MAP { MAP{'a':1}: 'map type', MAP{'b':2}: 'map literal' } AS _map5
'''
+---------------+-------------------------------------------------------------+---------------------------+-----------------------------------------------+----------------------------------------------------+-----------------------------------------+
| _map | _map1 | _map2 | _map3 | _map4 | _map5 |
+---------------+-------------------------------------------------------------+---------------------------+-----------------------------------------------+----------------------------------------------------+-----------------------------------------+
| {a:1,b:2,c:3} | {1:2022-12-31T00:00:00.000000,2:2022-12-31T12:34:56.000000} | {false:P3DT4H,true:P1Y2M} | {"[1,2]":[1.0,2.0,3.0],"[4,5]":[4.0,5.0,6.0]} | {"{2,1}":{x:set,y:type},"{4,3}":{x:set,y:literal}} | { {a:1}:"map type",{b:2}:"map literal"} |
+---------------+-------------------------------------------------------------+---------------------------+-----------------------------------------------+----------------------------------------------------+-----------------------------------------+
映射字面量的运算¶
映射字面量之间可以进行并集运算,例如:
(root@doc)> RETURN MAP{'a': 1, 'b': 2} || MAP{'b': 3, 'c': 4} || MAP { } AS _map
+---------------+
| _map |
+---------------+
| {a:1,b:2,c:4} |
+---------------+
更多信息,请参见支持的操作符。
记录字面量¶
记录字面量是由声明关键字RECORD和大括号({})包裹的零个或多个键值对组合而成的。记录字面量中的每对键与值之间由冒号(:)分隔,键值对之间由逗号(,)分隔。例如:
(root@doc)> '''
RETURN RECORD { _int:2023,
_boolean:false,
_string:"string",
_list: list[1,2,3],
_record:{_int:123},
_vector: VECTOR<3, FLOAT>([1.0, 2.0, 3.0]),
_instant: DATETIME '2023-01-01T00:00:00',
_duration: DURATION 'P1Y2M'
} AS _record
'''
+------------------------------------------------------------------------------------------------------------------------------------------------------+
| _record |
+------------------------------------------------------------------------------------------------------------------------------------------------------+
| {_boolean:false,_duration:P1Y2M,_instant:2023-01-01T00:00:00.000000,_int:2023,_list:[1,2,3],_record:{_int:123},_string:string,_vector:[1.0,2.0,3.0]} |
+------------------------------------------------------------------------------------------------------------------------------------------------------+