plpgsql 测试用例中的 SELECT 查询未返回数组
Array not being returned by SELECT query inside plpgsql test case
SELECT 我正在使用的查询:
SELECT ARRAY[table_name,pg_size_pretty(table_size)]
FROM (
SELECT
table_name,
pg_table_size(table_name) AS table_size,
pg_indexes_size(table_name) AS indexes_size,
pg_total_relation_size(table_name) AS total_size
FROM (
SELECT ('"' || table_schema || '"."' || table_name || '"') AS table_name
FROM information_schema.tables where table_schema not in ('pg_catalog', 'information_schema')and table_schema not like 'pg_toast%'
) AS all_tables
ORDER BY total_size DESC
) AS have ;
此 return 的输出为:
但是当我在 plpgsql 测试用例中使用相同的查询时,它 return 并不是相同的数组。
测试用例代码:
DROP FUNCTION IF EXISTS unit_tests.example2();
CREATE FUNCTION unit_tests.example2()
RETURNS test_result
AS
$$
DECLARE message test_result;
DECLARE result boolean;
DECLARE have text[][];
DECLARE want text[][];
BEGIN
want := array[['"unit_tests"."tests"','8192 bytes'],
['"unit_tests"."test_details"','16 KB'],
['"unit_tests"."dependencies"','8192 bytes'],
['"DVDRental"."dvd_genre"','8192 bytes'],
['"DVDRental"."dvd_stock"','0 bytes']];
SELECT ARRAY[table_name,pg_size_pretty(table_size)] INTO have
FROM (
SELECT
table_name,
pg_table_size(table_name) AS table_size,
pg_indexes_size(table_name) AS indexes_size,
pg_total_relation_size(table_name) AS total_size
FROM (
SELECT ('"' || table_schema || '"."' || table_name || '"') AS table_name
FROM information_schema.tables where table_schema not in ('pg_catalog', 'information_schema')and table_schema not like 'pg_toast%'
) AS all_tables
ORDER BY total_size DESC
) AS have ;
SELECT * FROM assert.is_equal(have, want) INTO message, result;
--Test failed.
IF result = false THEN
RETURN message;
END IF;
--Test passed.
SELECT assert.ok('End of test.') INTO message;
RETURN message;
END
$$
LANGUAGE plpgsql;
--BEGIN TRANSACTION;
SELECT * FROM unit_tests.begin();
--ROLLBACK TRANSACTION;
结果由代码return编辑:
INFO: Test started from : 2015-12-10 05:50:37.291
INFO: Running test unit_tests.example2() : 2015-12-10 05:50:37.291
INFO: Test failed unit_tests.example2() : ASSERT IS_EQUAL FAILED.
Have -> {"\"unit_tests\".\"tests\"","8192 bytes"}
Want -> {{"\"unit_tests\".\"tests\"","8192 bytes"},{"\"unit_tests\".\"test_details\"","16 KB"},{"\"unit_tests\".\"dependencies\"","8192 bytes"},{"\"DVDRental\".\"dvd_genre\"","8192 bytes"},{"\"DVDRental\".\"dvd_stock\"","0 bytes"}}
INFO: Test completed on : 2015-12-10 05:50:37.322 UTC.
这里 have
变量表示查询的结果 returned 并且 want
变量具有我们期望查询为 return 的值。但是正如我们所见,have
中的值并不是查询最初 returning.
中的值
这是我使用 INTO
关键字或其他与函数相关的方式的问题吗?
UPDATE 看起来只有结果集的第一个值被分配给 have 变量,也许如果我们可以迭代结果 returned 然后分配它有,那可能有用。
您不是第一个 运行 参与其中的人。目前,array_agg()
(或数组构造函数ARRAY(SELECT ...)
只接受标量值作为输入,而不是数组类型。所以你不能用它构建多维数组。
虽然修复很简单。创建自定义聚合函数:
CREATE AGGREGATE array_agg_mult (anyarray) (
SFUNC = array_cat
,STYPE = anyarray
,INITCOND = '{}'
);
简化其他一些事情后,您的函数的基本版本变为:
CREATE FUNCTION example2()
RETURNS text[] AS
$func$
SELECT array_agg_mult(ARRAY[ARRAY[tbl, pg_size_pretty(pg_table_size(tbl))]]
ORDER BY pg_total_relation_size(tbl) DESC) AS have
FROM (
SELECT format('%I.%I', table_schema, table_name) AS tbl
FROM information_schema.tables
WHERE table_schema NOT LIKE 'pg_%'
AND table_schema <> 'information_schema'
) AS all_tables
$func$ LANGUAGE sql;
相关(展望 Postgres 9.5):
- Selecting data into a Postgres array
SELECT 我正在使用的查询:
SELECT ARRAY[table_name,pg_size_pretty(table_size)]
FROM (
SELECT
table_name,
pg_table_size(table_name) AS table_size,
pg_indexes_size(table_name) AS indexes_size,
pg_total_relation_size(table_name) AS total_size
FROM (
SELECT ('"' || table_schema || '"."' || table_name || '"') AS table_name
FROM information_schema.tables where table_schema not in ('pg_catalog', 'information_schema')and table_schema not like 'pg_toast%'
) AS all_tables
ORDER BY total_size DESC
) AS have ;
此 return 的输出为:
但是当我在 plpgsql 测试用例中使用相同的查询时,它 return 并不是相同的数组。
测试用例代码:
DROP FUNCTION IF EXISTS unit_tests.example2();
CREATE FUNCTION unit_tests.example2()
RETURNS test_result
AS
$$
DECLARE message test_result;
DECLARE result boolean;
DECLARE have text[][];
DECLARE want text[][];
BEGIN
want := array[['"unit_tests"."tests"','8192 bytes'],
['"unit_tests"."test_details"','16 KB'],
['"unit_tests"."dependencies"','8192 bytes'],
['"DVDRental"."dvd_genre"','8192 bytes'],
['"DVDRental"."dvd_stock"','0 bytes']];
SELECT ARRAY[table_name,pg_size_pretty(table_size)] INTO have
FROM (
SELECT
table_name,
pg_table_size(table_name) AS table_size,
pg_indexes_size(table_name) AS indexes_size,
pg_total_relation_size(table_name) AS total_size
FROM (
SELECT ('"' || table_schema || '"."' || table_name || '"') AS table_name
FROM information_schema.tables where table_schema not in ('pg_catalog', 'information_schema')and table_schema not like 'pg_toast%'
) AS all_tables
ORDER BY total_size DESC
) AS have ;
SELECT * FROM assert.is_equal(have, want) INTO message, result;
--Test failed.
IF result = false THEN
RETURN message;
END IF;
--Test passed.
SELECT assert.ok('End of test.') INTO message;
RETURN message;
END
$$
LANGUAGE plpgsql;
--BEGIN TRANSACTION;
SELECT * FROM unit_tests.begin();
--ROLLBACK TRANSACTION;
结果由代码return编辑:
INFO: Test started from : 2015-12-10 05:50:37.291
INFO: Running test unit_tests.example2() : 2015-12-10 05:50:37.291
INFO: Test failed unit_tests.example2() : ASSERT IS_EQUAL FAILED.
Have -> {"\"unit_tests\".\"tests\"","8192 bytes"}
Want -> {{"\"unit_tests\".\"tests\"","8192 bytes"},{"\"unit_tests\".\"test_details\"","16 KB"},{"\"unit_tests\".\"dependencies\"","8192 bytes"},{"\"DVDRental\".\"dvd_genre\"","8192 bytes"},{"\"DVDRental\".\"dvd_stock\"","0 bytes"}}
INFO: Test completed on : 2015-12-10 05:50:37.322 UTC.
这里 have
变量表示查询的结果 returned 并且 want
变量具有我们期望查询为 return 的值。但是正如我们所见,have
中的值并不是查询最初 returning.
这是我使用 INTO
关键字或其他与函数相关的方式的问题吗?
UPDATE 看起来只有结果集的第一个值被分配给 have 变量,也许如果我们可以迭代结果 returned 然后分配它有,那可能有用。
您不是第一个 运行 参与其中的人。目前,array_agg()
(或数组构造函数ARRAY(SELECT ...)
只接受标量值作为输入,而不是数组类型。所以你不能用它构建多维数组。
虽然修复很简单。创建自定义聚合函数:
CREATE AGGREGATE array_agg_mult (anyarray) (
SFUNC = array_cat
,STYPE = anyarray
,INITCOND = '{}'
);
简化其他一些事情后,您的函数的基本版本变为:
CREATE FUNCTION example2()
RETURNS text[] AS
$func$
SELECT array_agg_mult(ARRAY[ARRAY[tbl, pg_size_pretty(pg_table_size(tbl))]]
ORDER BY pg_total_relation_size(tbl) DESC) AS have
FROM (
SELECT format('%I.%I', table_schema, table_name) AS tbl
FROM information_schema.tables
WHERE table_schema NOT LIKE 'pg_%'
AND table_schema <> 'information_schema'
) AS all_tables
$func$ LANGUAGE sql;
相关(展望 Postgres 9.5):
- Selecting data into a Postgres array