-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix smart statement timeout update logic and aqo_stat_store
Note: due to a mix of absolute and relative time in set_timeout_if_need function, smart statement timeout feature doesn't currently work since its timeouts are set in the past. This commit changes checked precondition for smart statement timeout change to fix array indexing bug, but the feature itself remains broken. This commit also fixes arithmetic errors in aqo_stat_store in the case of fully filled arrays.
- Loading branch information
Artem Fadeev
committed
Sep 30, 2024
1 parent
294f523
commit b6bea36
Showing
5 changed files
with
254 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
-- Testing aqo_query_stat update logic | ||
-- Note: this test assumes STAT_SAMPLE_SIZE to be 20. | ||
CREATE EXTENSION IF NOT EXISTS aqo; | ||
SELECT true AS success FROM aqo_reset(); | ||
success | ||
--------- | ||
t | ||
(1 row) | ||
|
||
DROP TABLE IF EXISTS A; | ||
NOTICE: table "a" does not exist, skipping | ||
CREATE TABLE A AS SELECT x FROM generate_series(1, 20) as x; | ||
ANALYZE A; | ||
DROP TABLE IF EXISTS B; | ||
NOTICE: table "b" does not exist, skipping | ||
CREATE TABLE B AS SELECT y FROM generate_series(1, 10) as y; | ||
ANALYZE B; | ||
CREATE OR REPLACE FUNCTION round_array (double precision[]) | ||
RETURNS double precision[] | ||
LANGUAGE SQL | ||
AS $$ | ||
SELECT array_agg(round(elem::numeric, 3)) | ||
FROM unnest($1) as arr(elem); | ||
$$ | ||
SET aqo.mode = 'learn'; | ||
SET aqo.force_collect_stat = 'on'; | ||
SET aqo.min_neighbors_for_predicting = 1; | ||
-- First test: adding real records | ||
SET aqo.mode = 'disabled'; | ||
SELECT count(*) FROM A JOIN B ON (A.x > B.y) WHERE A.x > 15 AND B.y < 5; | ||
count | ||
------- | ||
20 | ||
(1 row) | ||
|
||
SELECT count(*) FROM A JOIN B ON (A.x > B.y) WHERE A.x > 16 AND B.y < 6; | ||
count | ||
------- | ||
20 | ||
(1 row) | ||
|
||
SET aqo.mode = 'learn'; | ||
SELECT aqo_enable_class(queryid) FROM aqo_queries WHERE queryid != 0; | ||
aqo_enable_class | ||
------------------ | ||
|
||
(1 row) | ||
|
||
SELECT count(*) FROM A JOIN B ON (A.x > B.y) WHERE A.x > 17 AND B.y < 7; | ||
count | ||
------- | ||
18 | ||
(1 row) | ||
|
||
SELECT count(*) FROM A JOIN B ON (A.x > B.y) WHERE A.x > 18 AND B.y < 8; | ||
count | ||
------- | ||
14 | ||
(1 row) | ||
|
||
SELECT count(*) FROM A JOIN B ON (A.x > B.y) WHERE A.x > 19 AND B.y < 9; | ||
count | ||
------- | ||
8 | ||
(1 row) | ||
|
||
-- Ignore unstable time-related columns | ||
SELECT round_array(cardinality_error_with_aqo) AS error_aqo, round_array(cardinality_error_without_aqo) AS error_no_aqo, executions_with_aqo, executions_without_aqo FROM aqo_query_stat; | ||
error_aqo | error_no_aqo | executions_with_aqo | executions_without_aqo | ||
--------------------+--------------+---------------------+------------------------ | ||
{0.22,0.362,0.398} | {0.392,0.21} | 3 | 2 | ||
(1 row) | ||
|
||
SELECT true AS success from aqo_reset(); | ||
success | ||
--------- | ||
t | ||
(1 row) | ||
|
||
-- Second test: fake data in aqo_query_stat | ||
SET aqo.mode = 'disabled'; | ||
SELECT count(*) FROM A JOIN B ON (A.x > B.y) WHERE A.x > 5 AND B.y < 100; | ||
count | ||
------- | ||
135 | ||
(1 row) | ||
|
||
SELECT aqo_query_stat_update( | ||
queryid, | ||
'{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}', '{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}', | ||
'{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}', '{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}', | ||
'{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}', '{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}', | ||
100, 50) | ||
FROM aqo_query_stat; | ||
aqo_query_stat_update | ||
----------------------- | ||
t | ||
(1 row) | ||
|
||
SELECT round_array(cardinality_error_with_aqo) AS error_aqo, round_array(cardinality_error_without_aqo) AS error_no_aqo, executions_with_aqo, executions_without_aqo FROM aqo_query_stat; | ||
error_aqo | error_no_aqo | executions_with_aqo | executions_without_aqo | ||
------------------------------------------------------+------------------------------------------------------+---------------------+------------------------ | ||
{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20} | {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20} | 100 | 50 | ||
(1 row) | ||
|
||
SELECT count(*) FROM A JOIN B ON (A.x > B.y) WHERE A.x > 10 AND B.y < 100; | ||
count | ||
------- | ||
100 | ||
(1 row) | ||
|
||
SET aqo.mode = 'learn'; | ||
SELECT aqo_enable_class(queryid) FROM aqo_queries WHERE queryid != 0; | ||
aqo_enable_class | ||
------------------ | ||
|
||
(1 row) | ||
|
||
SELECT count(*) FROM A JOIN B ON (A.x > B.y) WHERE A.x > 15 AND B.y < 5; | ||
count | ||
------- | ||
20 | ||
(1 row) | ||
|
||
SELECT count(*) FROM A JOIN B ON (A.x > B.y) WHERE A.x > 16 AND B.y < 6; | ||
count | ||
------- | ||
20 | ||
(1 row) | ||
|
||
SELECT count(*) FROM A JOIN B ON (A.x > B.y) WHERE A.x > 17 AND B.y < 7; | ||
count | ||
------- | ||
18 | ||
(1 row) | ||
|
||
SELECT count(*) FROM A JOIN B ON (A.x > B.y) WHERE A.x > 18 AND B.y < 8; | ||
count | ||
------- | ||
14 | ||
(1 row) | ||
|
||
SELECT round_array(cardinality_error_with_aqo) AS error_aqo, round_array(cardinality_error_without_aqo) AS error_no_aqo, executions_with_aqo, executions_without_aqo FROM aqo_query_stat; | ||
error_aqo | error_no_aqo | executions_with_aqo | executions_without_aqo | ||
---------------------------------------------------------------------+----------------------------------------------------------+---------------------+------------------------ | ||
{5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,0.392,0.344,0.34,0.362} | {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,0.218} | 104 | 51 | ||
(1 row) | ||
|
||
SET aqo.mode TO DEFAULT; | ||
SET aqo.force_collect_stat TO DEFAULT; | ||
SET aqo.min_neighbors_for_predicting TO DEFAULT; | ||
DROP FUNCTION round_array; | ||
DROP TABLE A; | ||
DROP TABLE B; | ||
DROP EXTENSION aqo CASCADE; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,3 +23,4 @@ test: look_a_like | |
test: feature_subspace | ||
test: eclasses | ||
test: eclasses_mchar | ||
test: aqo_query_stat |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
-- Testing aqo_query_stat update logic | ||
-- Note: this test assumes STAT_SAMPLE_SIZE to be 20. | ||
CREATE EXTENSION IF NOT EXISTS aqo; | ||
SELECT true AS success FROM aqo_reset(); | ||
|
||
DROP TABLE IF EXISTS A; | ||
CREATE TABLE A AS SELECT x FROM generate_series(1, 20) as x; | ||
ANALYZE A; | ||
|
||
DROP TABLE IF EXISTS B; | ||
CREATE TABLE B AS SELECT y FROM generate_series(1, 10) as y; | ||
ANALYZE B; | ||
|
||
CREATE OR REPLACE FUNCTION round_array (double precision[]) | ||
RETURNS double precision[] | ||
LANGUAGE SQL | ||
AS $$ | ||
SELECT array_agg(round(elem::numeric, 3)) | ||
FROM unnest($1) as arr(elem); | ||
$$ | ||
|
||
SET aqo.mode = 'learn'; | ||
SET aqo.force_collect_stat = 'on'; | ||
SET aqo.min_neighbors_for_predicting = 1; | ||
|
||
-- First test: adding real records | ||
SET aqo.mode = 'disabled'; | ||
SELECT count(*) FROM A JOIN B ON (A.x > B.y) WHERE A.x > 15 AND B.y < 5; | ||
SELECT count(*) FROM A JOIN B ON (A.x > B.y) WHERE A.x > 16 AND B.y < 6; | ||
|
||
SET aqo.mode = 'learn'; | ||
SELECT aqo_enable_class(queryid) FROM aqo_queries WHERE queryid != 0; | ||
|
||
SELECT count(*) FROM A JOIN B ON (A.x > B.y) WHERE A.x > 17 AND B.y < 7; | ||
SELECT count(*) FROM A JOIN B ON (A.x > B.y) WHERE A.x > 18 AND B.y < 8; | ||
SELECT count(*) FROM A JOIN B ON (A.x > B.y) WHERE A.x > 19 AND B.y < 9; | ||
-- Ignore unstable time-related columns | ||
SELECT round_array(cardinality_error_with_aqo) AS error_aqo, round_array(cardinality_error_without_aqo) AS error_no_aqo, executions_with_aqo, executions_without_aqo FROM aqo_query_stat; | ||
|
||
SELECT true AS success from aqo_reset(); | ||
|
||
|
||
-- Second test: fake data in aqo_query_stat | ||
SET aqo.mode = 'disabled'; | ||
SELECT count(*) FROM A JOIN B ON (A.x > B.y) WHERE A.x > 5 AND B.y < 100; | ||
SELECT aqo_query_stat_update( | ||
queryid, | ||
'{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}', '{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}', | ||
'{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}', '{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}', | ||
'{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}', '{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}', | ||
100, 50) | ||
FROM aqo_query_stat; | ||
SELECT round_array(cardinality_error_with_aqo) AS error_aqo, round_array(cardinality_error_without_aqo) AS error_no_aqo, executions_with_aqo, executions_without_aqo FROM aqo_query_stat; | ||
|
||
SELECT count(*) FROM A JOIN B ON (A.x > B.y) WHERE A.x > 10 AND B.y < 100; | ||
|
||
SET aqo.mode = 'learn'; | ||
SELECT aqo_enable_class(queryid) FROM aqo_queries WHERE queryid != 0; | ||
|
||
SELECT count(*) FROM A JOIN B ON (A.x > B.y) WHERE A.x > 15 AND B.y < 5; | ||
SELECT count(*) FROM A JOIN B ON (A.x > B.y) WHERE A.x > 16 AND B.y < 6; | ||
SELECT count(*) FROM A JOIN B ON (A.x > B.y) WHERE A.x > 17 AND B.y < 7; | ||
SELECT count(*) FROM A JOIN B ON (A.x > B.y) WHERE A.x > 18 AND B.y < 8; | ||
SELECT round_array(cardinality_error_with_aqo) AS error_aqo, round_array(cardinality_error_without_aqo) AS error_no_aqo, executions_with_aqo, executions_without_aqo FROM aqo_query_stat; | ||
|
||
|
||
SET aqo.mode TO DEFAULT; | ||
SET aqo.force_collect_stat TO DEFAULT; | ||
SET aqo.min_neighbors_for_predicting TO DEFAULT; | ||
|
||
DROP FUNCTION round_array; | ||
DROP TABLE A; | ||
DROP TABLE B; | ||
DROP EXTENSION aqo CASCADE; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters