MySQL 从使用 UDF 的子查询中截断字符串

Posted

技术标签:

【中文标题】MySQL 从使用 UDF 的子查询中截断字符串【英文标题】:MySQL cuts off string from subquery which uses UDF 【发布时间】:2014-06-30 15:19:25 【问题描述】:

我在 mysql 5.6 和 UDF 函数中有相当大的 InnoDB 表(~100k 行):

CREATE AGGREGATE FUNCTION collect RETURNS STRING SONAME 'libcollect.so';

当我查询时

SELECT collect('CASES:10,DROP:10', shipment_bucket_code, weight) FROM d_shipments;

"83.140000,2513.910000,4439.710000,1764.100000,7852.960000,98.920000,828.620000,2346.950000,1566.620000,107594.130000" 将是结果,它是正确的。

但是如果我在子查询中调用 UDF

SELECT * FROM (
    SELECT collect('CASES:10,DROP:10', shipment_bucket_code, weight) FROM d_shipments
) as sub;

结果将是"83.140000,2513.910000,4439.710000,1764.100000"。字符串被***查询截断。通过UDF调试确认。

此外,如果我在小表上使用这些查询,一切正常。使用像CONCAT("83.140000,2513.910000,4439.710000,1764.100000,7852.960000,98.9", "20000,828.620000,2346.950000,1566.620000,107594.130000")这样的内置函数时也是如此

在原因搜索过程中,我遇到了similar old non-fixed bug。 是否有任何解决方法?似乎 MySQL 的子查询字符串结果受到某些缓冲区大小的限制,因为字符串切割总是平等地发生。

UPD:目前找到的解决方法是将子查询重写为 JOIN。

UPD2:...但它并非在所有查询中都有效。很可能,错误会在相当大的表上重现。

【问题讨论】:

【参考方案1】:

所以,我找到了解决方法:显式返回值类型转换

SELECT * FROM (
    SELECT 
        CAST(collect('CASES:10,DROP:10', shipment_bucket_code, weight) AS CHAR(255))
    FROM d_shipments
) as sub;

可能,它允许为返回的字符串分配所需的内存大小。我没有查看 mysql 源代码,但有些东西提示我从 UDF 中返回的字符串(和 DECIMAL)的弱类型化存在问题。

【讨论】:

以上是关于MySQL 从使用 UDF 的子查询中截断字符串的主要内容,如果未能解决你的问题,请参考以下文章

雪花标量 UDF 返回 无法评估不支持的子查询类型

雪花不支持的子查询类型无法在 UDF 标量中评估

尝试从 UDF 执行 spark sql 查询

使用来自 PHP 的 UDF MySQL 查询

某些服务器上的 MySQL 数据截断错误

如何创建一个接受查询字符串并返回查询结果集的 UDF