Source: https://dev-docs.yueshu.com.cn/v5.3.2/database-gql-reference/fe/expressions/cast/ Documentation version: v5.3.2 # 类型转换表达式 类型转换表达式将表达式的数据类型转换为指定的目标数据类型。 ## 语法 语法图源码 cast_value_expression ```` cast_value_expression ::= 'CAST' '(' (value_expression | 'NULL') 'AS' target_data_type ')' ```` ## 参数 ### `value_expression` 要转换为目标数据类型的[值表达式](https://dev-docs.yueshu.com.cn/v5.3.2/database-gql-reference/fe/)。不同数据类型间的转换,请参见下文数据类型转换。 有关数据类型的更多信息,请参见[数据类型](https://dev-docs.yueshu.com.cn/v5.3.2/database-gql-reference/data-types/)。 ### `target_data_type` 源数据类型转换后的目标数据类型。 ## 数据类型转换 数据类型转换分为显式转换和隐式转换。 - 显式转换:使用类型转换表达式手动进行的转换。 - 隐式转换:系统自动完成的转换,可能会导致精度损失。例如,`INT64`转换为`DOUBLE`可能会导致精度损失。如果两个数据类型支持隐式转换,则显式转换也支持。更多信息,请参见下文隐式转换的发生场景。 不同数据类型的显式和隐式转换规则不同,具体如下: - 对于预定义数据类型和复合数据类型列表(`LIST`)、记录(`RECORD`),显式和隐式转换均支持。 - 对于复合数据类型路径(`PATH`)和点/边引用,仅支持隐式转换,且受限于路径中的点或边的数据类型的转换规则。更多信息,请参见下文复合数据类型之间和点/边引用之间的转换。 ### 预定义数据类型之间的转换 下表列出了预定义数据类型之间支持的转换。最左侧的列为源数据类型,最上方的行为目标数据类型。 | 源/目标 | NULL | BOOLEAN | INT8 | INT16 | INT32 | INT64 | UINT8 | UINT16 | UINT32 | UINT64 | FLOAT | DOUBLE | DECIMAL | DURATION | DATE | LOCAL TIME | ZONED TIME | LOCAL DATETIME | ZONED DATETIME | STRING | VECTOR | NULL | | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | 🚫 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | BOOLEAN | 🚫 | | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | ➡️ | 🚫 | INT8 | 🚫 | 🚫 | | ✅ | ✅ | ✅ | ➡️ | ➡️ | ➡️ | ➡️ | ✅ | ✅ | ✅ | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | ➡️ | 🚫 | INT16 | 🚫 | 🚫 | ➡️ | | ✅ | ✅ | ➡️ | ➡️ | ➡️ | ➡️ | ✅ | ✅ | ✅ | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | ➡️ | 🚫 | INT32 | 🚫 | 🚫 | ➡️ | ➡️ | | ✅ | ➡️ | ➡️ | ➡️ | ➡️ | ✅ | ✅ | ✅ | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | ➡️ | 🚫 | INT64 | 🚫 | 🚫 | ➡️ | ➡️ | ➡️ | | ➡️ | ➡️ | ➡️ | ➡️ | ✅ | ✅ | ✅ | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | ➡️ | 🚫 | UINT8 | 🚫 | 🚫 | ➡️ | ✅ | ✅ | ✅ | | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | ➡️ | 🚫 | UINT16 | 🚫 | 🚫 | ➡️ | ➡️ | ✅ | ✅ | ➡️ | | ✅ | ✅ | ✅ | ✅ | ✅ | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | ➡️ | 🚫 | UINT32 | 🚫 | 🚫 | ➡️ | ➡️ | ➡️ | ✅ | ➡️ | ➡️ | | ✅ | ✅ | ✅ | ✅ | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | ➡️ | 🚫 | UINT64 | 🚫 | 🚫 | ➡️ | ➡️ | ➡️ | ➡️ | ➡️ | ➡️ | ➡️ | | ✅ | ✅ | ✅ | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | ➡️ | 🚫 | FLOAT | 🚫 | 🚫 | ➡️ | ➡️ | ➡️ | ➡️ | ➡️ | ➡️ | ➡️ | ➡️ | | ✅ | ➡️ | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | ➡️ | 🚫 | DOUBLE | 🚫 | 🚫 | ➡️ | ➡️ | ➡️ | ➡️ | ➡️ | ➡️ | ➡️ | ➡️ | ➡️ | | ➡️ | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | ➡️ | 🚫 | DECIMAL | 🚫 | 🚫 | ➡️ | ➡️ | ➡️ | ➡️ | ➡️ | ➡️ | ➡️ | ➡️ | ✅ | ✅ | | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | ➡️ | 🚫 | DURATION | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | ➡️ | 🚫 | DATE | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | | 🚫 | 🚫 | ✅ | ✅ | ➡️ | 🚫 | LOCAL TIME | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | | ✅ | ✅ | ✅ | ➡️ | 🚫 | ZONED TIME | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | ➡️ | | ➡️ | ✅ | ➡️ | 🚫 | LOCAL DATETIME | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | ➡️ | ➡️ | ➡️ | | ✅ | ➡️ | 🚫 | ZONED DATETIME | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | ➡️ | ➡️ | ➡️ | ➡️ | | ➡️ | 🚫 | STRING | 🚫 | ➡️ | ➡️ | ➡️ | ➡️ | ➡️ | ➡️ | ➡️ | ➡️ | ➡️ | ➡️ | ➡️ | ➡️ | 🚫 | ➡️ | ➡️ | ➡️ | ➡️ | ➡️ | | 🚫 | VECTOR | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | - ➡️ 表示支持从源数据类型到目标数据类型的显式转换。 - 🚫 表示不支持从源数据类型到目标数据类型的转换。 - ✅ 表示系统支持从源数据类型到目标数据类型的隐式转换。 Note - 上表中的`STRING`类型指的是字符串类型。 - NULL 字面量可以转换为除了 DURATION 外的任何数据类型,取值仍为`NULL`。 ### 涉及地理空间类型的转换 下表列出了涉及地理空间类型之间支持的转换。 | 源/目标 | NULL | STRING | GEOGRAPHY(ANY) | GEOGRAPHY(POINT) | GEOGRAPHY(LINESTRING) | GEOGRAPHY(POLYGON) | NULL | | ✅ | ✅ | ✅ | ✅ | ✅ | STRING | 🚫 | | ➡️ | ➡️ | ➡️ | ➡️ | GEOGRAPHY(ANY) | 🚫 | ➡️ | | ➡️ | ➡️ | ➡️ | GEOGRAPHY(POINT) | 🚫 | ➡️ | ➡️ | | 🚫 | 🚫 | GEOGRAPHY(LINESTRING) | 🚫 | ➡️ | ➡️ | 🚫 | | 🚫 | GEOGRAPHY(POLYGON) | 🚫 | ➡️ | ➡️ | 🚫 | 🚫 | ### 复合数据类型之间和点/边之间的转换 - 列表:如果源列表中的元素类型可以转换为目标列表中的元素类型,则支持显式和隐式转换。 - 集合:如果源集合中的元素类型可以转换为目标集合中的元素类型,则支持显式和隐式转换。 - 映射:如果源映射中的键和值类型都可以转换为目标映射中的键和值类型,则支持显式和隐式转换。 - 记录:如果源记录和目标记录具有相同的字段名,并且源记录中的每个字段类型都可以转换为目标记录中的相应的字段类型,则支持显式和隐式转换。 - 路径:如果源路径中的每个点/边类型都可以转换为目标路径中的至少一个点/边类型,则支持隐式转换。 - 点/边:如果源点/边类型的属性名是目标点/边类型的属性名的子集,并且源点/边中的每个属性类型都可以转换为目标点/边中的相应的属性类型,则支持隐式转换。 ### 特殊值的转换 GQL 支持将字符串表示的特殊值转换为`FLOAT`(`FLOAT32`)、`DOUBLE`(`FLOAT64`)和`DECIMAL`类型。 以下表格列出支持的特殊值的字符串表示。 | 特殊值 | 支持的字符串格式(不区分大小写) | 正无穷大 | `'Inf'`, `'+Inf'`, `'Infinity'`, `'+Infinity'` | 负无穷大 | `'-Inf'`, `'-Infinity'` | 非数值 | `'NaN'` Note 字符串首尾的空格会被自动忽略。 关于特殊值转换的示例,请参见下文[将特殊值转换](https://dev-docs.yueshu.com.cn/v5.3.2/database-gql-reference/fe/expressions/cast/#cast_special_values)部分。 ### 隐式转换的发生场景 系统会在必要时尝试隐式转换。例如: - 在函数表达式中,入参类型与声明的参数类型不同时。 - 在列表表达式中,输入的数据类型不同时。 - 在条件表达式中,`then`/`else`分支的数据类型不同时。 - 在联合运算符中,同一列的输入数据类型不同时。 - 在`INSERT`或`SET`语句中,数据类型与图类型指定的属性类型不同时。 - 在`CALL`过程语句中,输入参数类型与声明的参数类型不同时。 如果需要进行隐式转换,但相应的隐式转换类型不支持,则会出现系统报错。 ## 示例 ### 将`null`转换为指定的数据类型 ```` ''' RETURN CAST (null AS INT8) AS i8, CAST (null AS INT16) AS i16, CAST (null AS INT32) AS i32, CAST (null AS INT64) AS i64, CAST (null AS UINT8) AS u8, CAST (null AS UINT16) AS u16, CAST (null AS UINT32) AS u32, CAST (null AS UINT64) AS u64, CAST (null AS FLOAT) AS f1, CAST (null AS DOUBLE) AS d2, CAST (null AS DECIMAL) AS d3, CAST (null AS BOOLEAN) AS b1, CAST (null AS STRING) AS s1, CAST (null AS LOCAL DATETIME) AS ld, CAST (null AS ZONED DATETIME) AS zd, CAST (null AS DATE) AS d1, CAST (null AS LOCAL TIME) AS lt, CAST (null AS ZONED TIME) AS zt, CAST (null AS LIST) AS e, CAST (null AS VECTOR<3, FLOAT>) AS v, CAST (null AS GEOGRAPHY(any)) AS g1, CAST (null AS GEOGRAPHY(POINT)) AS g2 ''' ```` 上述示例将`null`字面量转换为指定的数据类型。 返回: ```` +------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ | i8 | i16 | i32 | i64 | u8 | u16 | u32 | u64 | f1 | d2 | d3 | b1 | s1 | ld | zd | d1 | lt | zt | e | v | g1 | g2 | +------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ | null | null | null | null | null | null | null | null | null | null | null | null | null | null | null | null | null | null | null | null | null | null | +------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+ ```` ### 将不同数据类型转换为字符串类型 ```` ''' RETURN CAST (1 AS STRING) AS i1, CAST (2378737378237 AS STRING) AS i2, CAST (true AS STRING) AS b1, CAST (DATETIME "2012-03-04T05:06:07.0890" AS STRING) AS d1, CAST (DATE "2012-03-04" AS STRING) AS d2, CAST (TIME "05:06:07.0890" AS STRING) AS d3, CAST (zoned_time("05:06:07.0890 -0200") AS STRING) AS d4, CAST (zoned_datetime("2012-03-04T05:06:07.0890", "%Y-%m-%dT%H:%M:%S") AS STRING) AS d5, CAST (duration({seconds:4, milliseconds:5, microseconds:6}) AS STRING) AS d6 ''' ```` 上述示例将指定的数据类型转换为字符串类型。 返回: ```` +----+---------------+------+----------------------------+------------+-----------------+-----------------------+----------------------------------+-------------------+ | i1 | i2 | b1 | d1 | d2 | d3 | d4 | d5 | d6 | +----+---------------+------+----------------------------+------------+-----------------+-----------------------+----------------------------------+-------------------+ | 1 | 2378737378237 | true | 2012-03-04T05:06:07.089000 | 2012-03-04 | 05:06:07.089000 | 07:06:07.089000 +0000 | 2012-03-04T05:06:07.089000 +0000 | P0DT0H0M4.005006S | +----+---------------+------+----------------------------+------------+-----------------+-----------------------+----------------------------------+-------------------+ ```` ### 将字符串类型转换成日期和时间类型 ```` ''' RETURN CAST ("2025-01-04" AS DATE) AS d1, CAST ("23:23:23.000000" AS LOCAL TIME) AS lt, CAST ("2025-01-04T23:23:23.000000" AS LOCAL DATETIME) AS ld, CAST ("23:23:23.000000 +0800" AS ZONED TIME) AS zt, CAST ("2025-01-04T23:23:23.000000 +0800" AS ZONED DATETIME) AS zd ''' ```` Note 将字符串类型转换为日期和时间类型时,其格式必须符合当前会话的日期和时间类型格式。关于当前会话的日期和时间类型的格式,请参见 [SHOW CURRENT_SESSION TIME FORMATS](https://dev-docs.yueshu.com.cn/v5.3.2/database-gql-reference/data-admin/show/show-current-session-time-formats/)。 返回: ```` +------------+-----------------+----------------------------+------------------+-----------------------------+ | d1 | lt | ld | zt | zd | +------------+-----------------+----------------------------+------------------+-----------------------------+ | 2025-01-04 | 23:23:23.000000 | 2025-01-04T23:23:23.000000 | 15:23:23.000000Z | 2025-01-04T15:23:23.000000Z | +------------+-----------------+----------------------------+------------------+-----------------------------+ ```` ### 数值类型间的转换 ```` ''' RETURN CAST (1 AS INT8) AS i1, CAST (1.3 AS INT16) AS i2, CAST (13 AS INT32) AS i3, CAST (1.3 AS INT64) AS i4, CAST (1 AS UINT8) AS ui1, CAST (1.3 AS UINT16) AS ui2, CAST (13 AS UINT32) AS ui3, CAST (1.3 AS UINT64) AS ui4, CAST (13 AS FLOAT32) AS f1, CAST (13 AS FLOAT64) AS f2, CAST (13 AS DECIMAL) AS d1 ''' ```` 上述示例将数值类型转换为指定的数值类型。 返回: ```` +----+----+----+----+-----+-----+-----+-----+------+------+----+ | i1 | i2 | i3 | i4 | ui1 | ui2 | ui3 | ui4 | f1 | f2 | d1 | +----+----+----+----+-----+-----+-----+-----+------+------+----+ | 1 | 1 | 13 | 1 | 1 | 1 | 13 | 1 | 13.0 | 13.0 | 13 | +----+----+----+----+-----+-----+-----+-----+------+------+----+ ```` ### 将列表的元素转换指定的数据类型 ```` RETURN CAST ([1.4, 1.5] AS LIST) AS a ```` 上述示例将列表中的小数转换为整数类型。 返回: ```` +-------+ | a | +-------+ | [1,2] | +-------+ ```` ### 将记录的字段转换为指定的数据类型 ```` RETURN CAST ({p: LIST [1.4, 1.5]} AS RECORD {p LIST}) AS a ```` 上述示例将记录中的列表字段中的小数转换为整数类型。 返回: ```` +-----------+ | a | +-----------+ | {p:[1,2]} | +-----------+ ```` ### 将通用的地理空间类型转换为字符串 ```` ''' RETURN CAST(ST_GeogFromText('POINT(0 0)') AS STRING) AS a, CAST(ST_GeogFromText('LINESTRING(1 2, 2 4, 4 8, 8 16)') AS STRING) AS b, CAST(ST_GeogFromText('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))') AS STRING) AS c ''' ```` 上述示例将通用地理空间类型`GEOGRAPHY(ANY)`转换为字符串类型。 返回: ```` +------------+---------------------------------+----------------------------------------+ | a | b | c | +------------+---------------------------------+----------------------------------------+ | POINT(0 0) | LINESTRING(1 2, 2 4, 4 8, 8 16) | POLYGON((0 0, 0 10, 10 10, 10 0, 0 0)) | +------------+---------------------------------+----------------------------------------+ ```` ### 将字符串转换为地理空间类型 ```` ''' RETURN CAST('POINT(0 1)' as GEOGRAPHY(POINT)) AS a, CAST('LINESTRING(1 2, 2 4, 4 8, 8 16)' as GEOGRAPHY(LINESTRING)) AS b, CAST('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))' as GEOGRAPHY(POLYGON)) AS c, CAST('POINT(0 1)' as GEOGRAPHY(ANY)) AS d ''' ```` 上述示例将字符串类型转换为地理空间类型。 返回: ```` +----------------+-------------------------------------------------+------------------------------------------------------------+----------------+ | a | b | c | d | +----------------+-------------------------------------------------+------------------------------------------------------------+----------------+ | POINT(0.0 1.0) | LINESTRING(1.0 2.0, 2.0 4.0, 4.0 8.0, 8.0 16.0) | POLYGON((0.0 0.0, 0.0 10.0, 10.0 10.0, 10.0 0.0, 0.0 0.0)) | POINT(0.0 1.0) | +----------------+-------------------------------------------------+------------------------------------------------------------+----------------+ ```` ### 将通用地理空间类型转换为具体地理空间类型 ```` ''' RETURN CAST(ST_GeogFromText('POINT(37.7749 -12.4194)') AS GEOGRAPHY(POINT)) AS a, CAST(ST_GeogFromText('LINESTRING(30 10, 10 30, 40 40)') AS GEOGRAPHY(LINESTRING)) AS b, CAST(ST_GeogFromText('POLYGON((30 10, 40 40, 20 40, 10 20, 30 10))') AS GEOGRAPHY(POLYGON)) AS c ''' ```` 上述示例将通用地理空间类型`GEOGRAPHY(ANY)`转换为具体的地理空间类型。 返回: ```` +-------------------------+---------------------------------------------+------------------------------------------------------------------+ | a | b | c | +-------------------------+---------------------------------------------+------------------------------------------------------------------+ | POINT(37.7749 -12.4194) | LINESTRING(30.0 10.0, 10.0 30.0, 40.0 40.0) | POLYGON((30.0 10.0, 40.0 40.0, 20.0 40.0, 10.0 20.0, 30.0 10.0)) | +-------------------------+---------------------------------------------+------------------------------------------------------------------+ ```` ### 将具体地理空间类型转换为通用地理空间类型 ```` RETURN CAST(ST_Point(37.7749, -12.4194) AS GEOGRAPHY(ANY)) AS a ```` 上述示例将具体地理空间类型`GEOGRAPHY(POINT)`转换为通用地理空间类型`GEOGRAPHY(ANY)`。 返回: ```` +-------------------------+ | a | +-------------------------+ | POINT(37.7749 -12.4194) | +-------------------------+ ```` ### 将特殊值转换为`FLOAT`(`FLOAT32`)/`FLOAT64`(`DOUBLE`)/`DECIMAL`类型 []() ```` ''' RETURN CAST('Inf' AS FLOAT) AS f32_inf, CAST('-Infinity' AS FLOAT32) AS f32_ninfinity, CAST('nan' AS FLOAT64) AS f64_nan, CAST(' NaN ' AS DOUBLE) AS space_nan, CAST('+Infinity' AS DECIMAL(128, 10)) AS inf_with_scale ''' ```` 返回: ```` +---------+---------------+---------+-----------+----------------+ | f32_inf | f32_ninfinity | f64_nan | space_nan | inf_with_scale | +---------+---------------+---------+-----------+----------------+ | +Inf | -Inf | NaN | NaN | Infinity | +---------+---------------+---------+-----------+----------------+ ````