Skip to content

Commit f2e63a5

Browse files
committed
Raise AQO version to v1.6.
Rename a couple of UI functions: 1. aqo_enable_query -> aqo_enable_class 2. aqo_disable_query -> aqo_disable_class Fix the bug of 1.5 with execution of "enable" routine from "disable" UI function. Correct aqo_cleanup() return type: It returns single set of values. So, we don't really needed all of the materialization machinery. Just to form and return a tuple.
1 parent 86796f0 commit f2e63a5

9 files changed

+76
-64
lines changed

Makefile

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# contrib/aqo/Makefile
22

33
EXTENSION = aqo
4-
EXTVERSION = 1.5
4+
EXTVERSION = 1.6
55
PGFILEDESC = "AQO - Adaptive Query Optimization"
66
MODULE_big = aqo
77
OBJS = $(WIN32RES) \
@@ -23,7 +23,8 @@ EXTRA_REGRESS_OPTS=--temp-config=$(top_srcdir)/$(subdir)/aqo.conf
2323
EXTRA_INSTALL = contrib/postgres_fdw contrib/pg_stat_statements
2424

2525
DATA = aqo--1.0.sql aqo--1.0--1.1.sql aqo--1.1--1.2.sql aqo--1.2.sql \
26-
aqo--1.2--1.3.sql aqo--1.3--1.4.sql aqo--1.4--1.5.sql
26+
aqo--1.2--1.3.sql aqo--1.3--1.4.sql aqo--1.4--1.5.sql \
27+
aqo--1.5--1.6.sql
2728

2829
ifdef USE_PGXS
2930
PG_CONFIG ?= pg_config

aqo--1.5--1.6.sql

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/* contrib/aqo/aqo--1.5--1.6.sql */
2+
3+
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
4+
\echo Use "ALTER EXTENSION aqo UPDATE TO '1.6'" to load this file. \quit
5+
6+
DROP FUNCTION aqo_enable_query;
7+
DROP FUNCTION aqo_disable_query;
8+
DROP FUNCTION aqo_cleanup;
9+
10+
CREATE FUNCTION aqo_enable_class(queryid bigint)
11+
RETURNS void
12+
AS 'MODULE_PATHNAME', 'aqo_enable_query'
13+
LANGUAGE C STRICT VOLATILE;
14+
15+
CREATE FUNCTION aqo_disable_class(queryid bigint)
16+
RETURNS void
17+
AS 'MODULE_PATHNAME', 'aqo_disable_query'
18+
LANGUAGE C STRICT VOLATILE;
19+
20+
--
21+
-- Remove unneeded rows from the AQO ML storage.
22+
-- For common feature space, remove rows from aqo_data only.
23+
-- For custom feature space - remove all rows related to the space from all AQO
24+
-- tables even if only one oid for one feature subspace of the space is illegal.
25+
-- Returns number of deleted rows from aqo_queries and aqo_data tables.
26+
--
27+
CREATE FUNCTION aqo_cleanup(OUT nfs integer, OUT nfss integer)
28+
RETURNS record
29+
AS 'MODULE_PATHNAME', 'aqo_cleanup'
30+
LANGUAGE C STRICT VOLATILE;
31+
COMMENT ON FUNCTION aqo_cleanup() IS
32+
'Remove unneeded rows from the AQO ML storage';

aqo.control

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# AQO extension
22
comment = 'machine learning for cardinality estimation in optimizer'
3-
default_version = '1.5'
3+
default_version = '1.6'
44
module_pathname = '$libdir/aqo'
55
relocatable = true

expected/aqo_CVE-2020-14350.out

+12-12
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ SHOW is_superuser;
116116
off
117117
(1 row)
118118

119-
CREATE FUNCTION aqo_enable_query(hash bigint)
119+
CREATE FUNCTION aqo_enable_class(hash bigint)
120120
RETURNS VOID
121121
AS $$
122122
BEGIN
@@ -125,18 +125,18 @@ $$ LANGUAGE plpgsql;
125125
RESET ROLE;
126126
-- Test result (error expected)
127127
CREATE EXTENSION aqo;
128-
ERROR: function "aqo_enable_query" already exists with same argument types
128+
ERROR: function "aqo_enable_class" already exists with same argument types
129129
SET ROLE regress_hacker;
130-
CREATE OR REPLACE FUNCTION aqo_enable_query(hash bigint)
130+
CREATE OR REPLACE FUNCTION aqo_enable_class(hash bigint)
131131
RETURNS VOID
132132
AS $$
133133
BEGIN
134134
ALTER ROLE regress_hacker SUPERUSER;
135135
END
136136
$$ LANGUAGE plpgsql;
137137
RESET ROLE;
138-
SELECT aqo_enable_query(42);
139-
aqo_enable_query
138+
SELECT aqo_enable_class(42);
139+
aqo_enable_class
140140
------------------
141141

142142
(1 row)
@@ -149,7 +149,7 @@ SHOW is_superuser;
149149
(1 row)
150150

151151
RESET ROLE;
152-
DROP FUNCTION aqo_enable_query(bigint);
152+
DROP FUNCTION aqo_enable_class(bigint);
153153
DROP EXTENSION IF EXISTS aqo;
154154
NOTICE: extension "aqo" does not exist, skipping
155155
-- Test 4
@@ -162,7 +162,7 @@ SHOW is_superuser;
162162
off
163163
(1 row)
164164

165-
CREATE FUNCTION aqo_disable_query(hash bigint)
165+
CREATE FUNCTION aqo_disable_class(hash bigint)
166166
RETURNS VOID
167167
AS $$
168168
BEGIN
@@ -171,18 +171,18 @@ $$ LANGUAGE plpgsql;
171171
RESET ROLE;
172172
-- Test result (error expected)
173173
CREATE EXTENSION aqo;
174-
ERROR: function "aqo_disable_query" already exists with same argument types
174+
ERROR: function "aqo_disable_class" already exists with same argument types
175175
SET ROLE regress_hacker;
176-
CREATE OR REPLACE FUNCTION aqo_disable_query(hash bigint)
176+
CREATE OR REPLACE FUNCTION aqo_disable_class(hash bigint)
177177
RETURNS VOID
178178
AS $$
179179
BEGIN
180180
ALTER ROLE regress_hacker SUPERUSER;
181181
END
182182
$$ LANGUAGE plpgsql;
183183
RESET ROLE;
184-
SELECT aqo_disable_query(42);
185-
aqo_disable_query
184+
SELECT aqo_disable_class(42);
185+
aqo_disable_class
186186
-------------------
187187

188188
(1 row)
@@ -195,7 +195,7 @@ SHOW is_superuser;
195195
(1 row)
196196

197197
RESET ROLE;
198-
DROP FUNCTION aqo_disable_query(bigint);
198+
DROP FUNCTION aqo_disable_class(bigint);
199199
DROP EXTENSION IF EXISTS aqo;
200200
NOTICE: extension "aqo" does not exist, skipping
201201
-- Test 5

expected/gucs.out

+4-4
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,10 @@ SELECT obj_description('aqo_reset'::regproc::oid);
107107
(1 row)
108108

109109
\df aqo_cleanup
110-
List of functions
111-
Schema | Name | Result data type | Argument data types | Type
112-
--------+-------------+----------------------------------+---------------------+------
113-
public | aqo_cleanup | TABLE(nfs integer, nfss integer) | | func
110+
List of functions
111+
Schema | Name | Result data type | Argument data types | Type
112+
--------+-------------+------------------+-----------------------------------+------
113+
public | aqo_cleanup | record | OUT nfs integer, OUT nfss integer | func
114114
(1 row)
115115

116116
\df aqo_reset

expected/relocatable.out

+6-6
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,9 @@ ORDER BY (md5(query_text))
8080
/*
8181
* Below, we should check each UI function
8282
*/
83-
SELECT aqo_disable_query(id) FROM (
83+
SELECT aqo_disable_class(id) FROM (
8484
SELECT queryid AS id FROM aqo_queries WHERE queryid <> 0) AS q1;
85-
aqo_disable_query
85+
aqo_disable_class
8686
-------------------
8787

8888

@@ -93,13 +93,13 @@ ORDER BY (learn_aqo, use_aqo, auto_tuning);
9393
learn_aqo | use_aqo | auto_tuning
9494
-----------+---------+-------------
9595
f | f | f
96-
t | t | f
97-
t | t | f
96+
f | f | f
97+
f | f | f
9898
(3 rows)
9999

100-
SELECT aqo_enable_query(id) FROM (
100+
SELECT aqo_enable_class(id) FROM (
101101
SELECT queryid AS id FROM aqo_queries WHERE queryid <> 0) AS q1;
102-
aqo_enable_query
102+
aqo_enable_class
103103
------------------
104104

105105

sql/aqo_CVE-2020-14350.sql

+8-8
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ ALTER ROLE regress_hacker NOSUPERUSER;
103103
SET ROLE regress_hacker;
104104
SHOW is_superuser;
105105

106-
CREATE FUNCTION aqo_enable_query(hash bigint)
106+
CREATE FUNCTION aqo_enable_class(hash bigint)
107107
RETURNS VOID
108108
AS $$
109109
BEGIN
@@ -115,7 +115,7 @@ RESET ROLE;
115115
CREATE EXTENSION aqo;
116116

117117
SET ROLE regress_hacker;
118-
CREATE OR REPLACE FUNCTION aqo_enable_query(hash bigint)
118+
CREATE OR REPLACE FUNCTION aqo_enable_class(hash bigint)
119119
RETURNS VOID
120120
AS $$
121121
BEGIN
@@ -124,13 +124,13 @@ END
124124
$$ LANGUAGE plpgsql;
125125

126126
RESET ROLE;
127-
SELECT aqo_enable_query(42);
127+
SELECT aqo_enable_class(42);
128128

129129
SET ROLE regress_hacker;
130130
SHOW is_superuser;
131131

132132
RESET ROLE;
133-
DROP FUNCTION aqo_enable_query(bigint);
133+
DROP FUNCTION aqo_enable_class(bigint);
134134
DROP EXTENSION IF EXISTS aqo;
135135

136136
-- Test 4
@@ -140,7 +140,7 @@ ALTER ROLE regress_hacker NOSUPERUSER;
140140
SET ROLE regress_hacker;
141141
SHOW is_superuser;
142142

143-
CREATE FUNCTION aqo_disable_query(hash bigint)
143+
CREATE FUNCTION aqo_disable_class(hash bigint)
144144
RETURNS VOID
145145
AS $$
146146
BEGIN
@@ -152,7 +152,7 @@ RESET ROLE;
152152
CREATE EXTENSION aqo;
153153

154154
SET ROLE regress_hacker;
155-
CREATE OR REPLACE FUNCTION aqo_disable_query(hash bigint)
155+
CREATE OR REPLACE FUNCTION aqo_disable_class(hash bigint)
156156
RETURNS VOID
157157
AS $$
158158
BEGIN
@@ -161,13 +161,13 @@ END
161161
$$ LANGUAGE plpgsql;
162162

163163
RESET ROLE;
164-
SELECT aqo_disable_query(42);
164+
SELECT aqo_disable_class(42);
165165

166166
SET ROLE regress_hacker;
167167
SHOW is_superuser;
168168

169169
RESET ROLE;
170-
DROP FUNCTION aqo_disable_query(bigint);
170+
DROP FUNCTION aqo_disable_class(bigint);
171171
DROP EXTENSION IF EXISTS aqo;
172172

173173
-- Test 5

sql/relocatable.sql

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,11 @@ ORDER BY (md5(query_text))
3939
/*
4040
* Below, we should check each UI function
4141
*/
42-
SELECT aqo_disable_query(id) FROM (
42+
SELECT aqo_disable_class(id) FROM (
4343
SELECT queryid AS id FROM aqo_queries WHERE queryid <> 0) AS q1;
4444
SELECT learn_aqo, use_aqo, auto_tuning FROM test.aqo_queries
4545
ORDER BY (learn_aqo, use_aqo, auto_tuning);
46-
SELECT aqo_enable_query(id) FROM (
46+
SELECT aqo_enable_class(id) FROM (
4747
SELECT queryid AS id FROM aqo_queries WHERE queryid <> 0) AS q1;
4848
SELECT learn_aqo, use_aqo, auto_tuning FROM test.aqo_queries
4949
ORDER BY (learn_aqo, use_aqo, auto_tuning);

storage.c

+8-29
Original file line numberDiff line numberDiff line change
@@ -2170,39 +2170,16 @@ aqo_cleanup(PG_FUNCTION_ARGS)
21702170
{
21712171
int fs_num;
21722172
int fss_num;
2173-
ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
21742173
TupleDesc tupDesc;
2175-
MemoryContext per_query_ctx;
2176-
MemoryContext oldcontext;
2177-
Tuplestorestate *tupstore;
2174+
HeapTuple tuple;
2175+
Datum result;
21782176
Datum values[2];
21792177
bool nulls[2] = {0, 0};
21802178

2181-
/* check to see if caller supports us returning a tuplestore */
2182-
if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo))
2183-
ereport(ERROR,
2184-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2185-
errmsg("set-valued function called in context that cannot accept a set")));
2186-
if (!(rsinfo->allowedModes & SFRM_Materialize))
2187-
ereport(ERROR,
2188-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2189-
errmsg("materialize mode required, but it is not allowed in this context")));
2190-
2191-
/* Switch into long-lived context to construct returned data structures */
2192-
per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
2193-
oldcontext = MemoryContextSwitchTo(per_query_ctx);
2194-
2195-
/* Build a tuple descriptor for our result type */
21962179
if (get_call_result_type(fcinfo, NULL, &tupDesc) != TYPEFUNC_COMPOSITE)
21972180
elog(ERROR, "return type must be a row type");
2198-
Assert(tupDesc->natts == 2);
21992181

2200-
tupstore = tuplestore_begin_heap(true, false, work_mem);
2201-
rsinfo->returnMode = SFRM_Materialize;
2202-
rsinfo->setResult = tupstore;
2203-
rsinfo->setDesc = tupDesc;
2204-
2205-
MemoryContextSwitchTo(oldcontext);
2182+
Assert(tupDesc->natts == 2);
22062183

22072184
/*
22082185
* Make forced cleanup: if at least one fss isn't actual, remove parent FS
@@ -2216,9 +2193,11 @@ aqo_cleanup(PG_FUNCTION_ARGS)
22162193

22172194
values[0] = Int32GetDatum(fs_num);
22182195
values[1] = Int32GetDatum(fss_num);
2219-
tuplestore_putvalues(tupstore, tupDesc, values, nulls);
2220-
tuplestore_donestoring(tupstore);
2221-
return (Datum) 0;
2196+
2197+
tuple = heap_form_tuple(tupDesc, values, nulls);
2198+
result = HeapTupleGetDatum(tuple);
2199+
2200+
PG_RETURN_DATUM(result);
22222201
}
22232202

22242203
/*

0 commit comments

Comments
 (0)