Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitbe06f13

Browse files
committed
Rewrite aqo_cardinality_error in C.
One more step towards true relocatability.
1 parent60dc4e6 commitbe06f13

File tree

2 files changed

+95
-38
lines changed

2 files changed

+95
-38
lines changed

‎aqo--1.4--1.5.sql‎

Lines changed: 2 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -167,44 +167,8 @@ COMMENT ON FUNCTION aqo_cleanup() IS
167167
--
168168
CREATE OR REPLACEFUNCTIONaqo_cardinality_error(controlledboolean)
169169
RETURNS TABLE(numbigint, idbigint, fshashbigint, error float, nexecsbigint)
170-
AS $$
171-
BEGIN
172-
IF (controlled) THEN
173-
RETURN QUERY
174-
SELECT
175-
row_number() OVER (ORDER BY (cerror, query_id, fs_hash)DESC)AS nn,
176-
query_id, fs_hash, cerror, execs
177-
FROM (
178-
SELECT
179-
aq.queryidAS query_id,
180-
aq.fsAS fs_hash,
181-
cardinality_error_with_aqo[array_length(cardinality_error_with_aqo,1)]AS cerror,
182-
executions_with_aqoAS execs
183-
FROM aqo_queries aqJOIN aqo_query_stat aqs
184-
ONaq.queryid=aqs.queryid
185-
WHERE TRUE= ANY (SELECT unnest(cardinality_error_with_aqo)IS NOT NULL)
186-
)AS q1
187-
ORDER BY nnASC;
188-
ELSE
189-
RETURN QUERY
190-
SELECT
191-
row_number() OVER (ORDER BY (cerror, query_id, fs_hash)DESC)AS nn,
192-
query_id, fs_hash, cerror, execs
193-
FROM (
194-
SELECT
195-
aq.queryidAS query_id,
196-
aq.fsAS fs_hash,
197-
(SELECTAVG(t)FROM unnest(cardinality_error_without_aqo) t)AS cerror,
198-
executions_without_aqoAS execs
199-
FROM aqo_queries aqJOIN aqo_query_stat aqs
200-
ONaq.queryid=aqs.queryid
201-
WHERE TRUE= ANY (SELECT unnest(cardinality_error_without_aqo)IS NOT NULL)
202-
)AS q1
203-
ORDER BY (nn)ASC;
204-
END IF;
205-
END;
206-
$$ LANGUAGE plpgsql;
207-
170+
AS'MODULE_PATHNAME','aqo_cardinality_error'
171+
LANGUAGE C STRICT VOLATILE;
208172
COMMENT ON FUNCTION aqo_cardinality_error(boolean) IS
209173
'Get cardinality error of queries the last time they were executed. Order queries according to an error value.';
210174

‎storage.c‎

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ PG_FUNCTION_INFO_V1(aqo_queries_update);
102102
PG_FUNCTION_INFO_V1(aqo_reset);
103103
PG_FUNCTION_INFO_V1(aqo_cleanup);
104104
PG_FUNCTION_INFO_V1(aqo_drop_class);
105+
PG_FUNCTION_INFO_V1(aqo_cardinality_error);
105106

106107

107108
bool
@@ -2203,3 +2204,95 @@ aqo_drop_class(PG_FUNCTION_ARGS)
22032204

22042205
PG_RETURN_INT32(cnt);
22052206
}
2207+
2208+
typedefenum {
2209+
AQE_NN=0,AQE_QUERYID,AQE_FS,AQE_CERROR,AQE_NEXECS,AQE_TOTAL_NCOLS
2210+
}ce_output_order;
2211+
2212+
/*
2213+
* Show cardinality error gathered on last execution.
2214+
* Skip entries with empty stat slots. XXX: is it possible?
2215+
*/
2216+
Datum
2217+
aqo_cardinality_error(PG_FUNCTION_ARGS)
2218+
{
2219+
boolcontrolled=PG_GETARG_BOOL(0);
2220+
ReturnSetInfo*rsinfo= (ReturnSetInfo*)fcinfo->resultinfo;
2221+
TupleDesctupDesc;
2222+
MemoryContextper_query_ctx;
2223+
MemoryContextoldcontext;
2224+
Tuplestorestate*tupstore;
2225+
Datumvalues[AQE_TOTAL_NCOLS];
2226+
boolnulls[AQE_TOTAL_NCOLS];
2227+
HASH_SEQ_STATUShash_seq;
2228+
QueriesEntry*qentry;
2229+
StatEntry*sentry;
2230+
intcounter=0;
2231+
2232+
/* check to see if caller supports us returning a tuplestore */
2233+
if (rsinfo==NULL|| !IsA(rsinfo,ReturnSetInfo))
2234+
ereport(ERROR,
2235+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2236+
errmsg("set-valued function called in context that cannot accept a set")));
2237+
if (!(rsinfo->allowedModes&SFRM_Materialize))
2238+
ereport(ERROR,
2239+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2240+
errmsg("materialize mode required, but it is not allowed in this context")));
2241+
2242+
/* Switch into long-lived context to construct returned data structures */
2243+
per_query_ctx=rsinfo->econtext->ecxt_per_query_memory;
2244+
oldcontext=MemoryContextSwitchTo(per_query_ctx);
2245+
2246+
/* Build a tuple descriptor for our result type */
2247+
if (get_call_result_type(fcinfo,NULL,&tupDesc)!=TYPEFUNC_COMPOSITE)
2248+
elog(ERROR,"return type must be a row type");
2249+
Assert(tupDesc->natts==AQE_TOTAL_NCOLS);
2250+
2251+
tupstore=tuplestore_begin_heap(true, false,work_mem);
2252+
rsinfo->returnMode=SFRM_Materialize;
2253+
rsinfo->setResult=tupstore;
2254+
rsinfo->setDesc=tupDesc;
2255+
2256+
MemoryContextSwitchTo(oldcontext);
2257+
2258+
LWLockAcquire(&aqo_state->queries_lock,LW_SHARED);
2259+
LWLockAcquire(&aqo_state->stat_lock,LW_SHARED);
2260+
2261+
hash_seq_init(&hash_seq,queries_htab);
2262+
while ((qentry=hash_seq_search(&hash_seq))!=NULL)
2263+
{
2264+
boolfound;
2265+
double*ce;
2266+
int64nexecs;
2267+
intnvals;
2268+
2269+
memset(nulls,0,AQE_TOTAL_NCOLS*sizeof(nulls[0]));
2270+
2271+
sentry= (StatEntry*)hash_search(stat_htab,&qentry->queryid,
2272+
HASH_FIND,&found);
2273+
if (!found)
2274+
/* Statistics not found by some reason. Just go further */
2275+
continue;
2276+
2277+
nvals=controlled ?sentry->cur_stat_slot_aqo :sentry->cur_stat_slot;
2278+
if (nvals==0)
2279+
/* No one stat slot filled */
2280+
continue;
2281+
2282+
nexecs=controlled ?sentry->execs_with_aqo :sentry->execs_without_aqo;
2283+
ce=controlled ?sentry->est_error_aqo :sentry->est_error;
2284+
2285+
values[AQE_NN]=Int32GetDatum(counter++);
2286+
values[AQE_QUERYID]=Int64GetDatum(qentry->queryid);
2287+
values[AQE_FS]=Int64GetDatum(qentry->fs);
2288+
values[AQE_NEXECS]=Int64GetDatum(nexecs);
2289+
values[AQE_CERROR]=Float8GetDatum(ce[nvals-1]);
2290+
tuplestore_putvalues(tupstore,tupDesc,values,nulls);
2291+
}
2292+
2293+
LWLockRelease(&aqo_state->stat_lock);
2294+
LWLockRelease(&aqo_state->queries_lock);
2295+
2296+
tuplestore_donestoring(tupstore);
2297+
return (Datum)0;
2298+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp