Skip to content

Commit 68a8b71

Browse files
committed
Bugfix. Fix omissions related to shifting from 32-bit query hash to 64-bit hash
1 parent de3077a commit 68a8b71

File tree

8 files changed

+61
-63
lines changed

8 files changed

+61
-63
lines changed

aqo.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -303,11 +303,13 @@ get_aqo_schema(void)
303303
* Init userlock
304304
*/
305305
void
306-
init_lock_tag(LOCKTAG *tag, uint32 key1, uint32 key2)
306+
init_lock_tag(LOCKTAG *tag, uint64 key1, int32 key2)
307307
{
308+
uint32 key = key1 % UINT32_MAX;
309+
308310
tag->locktag_field1 = AQO_MODULE_MAGIC;
309-
tag->locktag_field2 = key1;
310-
tag->locktag_field3 = key2;
311+
tag->locktag_field2 = key;
312+
tag->locktag_field3 = (uint32) key2;
311313
tag->locktag_field4 = 0;
312314
tag->locktag_type = LOCKTAG_USERLOCK;
313315
tag->locktag_lockmethodid = USER_LOCKMETHOD;

aqo.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ int get_clause_hash(Expr *clause, int nargs, int *args_hash, int *eclass_hash);
280280

281281

282282
/* Storage interaction */
283-
extern bool find_query(uint64 qhash, Datum *search_values, bool *search_nulls);
283+
extern bool find_query(uint64 qhash, QueryContextData *ctx);
284284
extern bool update_query(uint64 qhash, uint64 fhash,
285285
bool learn_aqo, bool use_aqo, bool auto_tuning);
286286
extern bool add_query_text(uint64 query_hash, const char *query_string);
@@ -343,7 +343,7 @@ extern double *selectivity_cache_find_global_relid(int clause_hash,
343343
extern void selectivity_cache_clear(void);
344344

345345
extern Oid get_aqo_schema(void);
346-
extern void init_lock_tag(LOCKTAG *tag, uint32 key1, uint32 key2);
346+
extern void init_lock_tag(LOCKTAG *tag, uint64 key1, int32 key2);
347347
extern bool IsQueryDisabled(void);
348348

349349
extern List *cur_classes;

auto_tuning.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ is_in_infinite_loop_cq(double *elems, int nelems)
144144
* this query to false.
145145
*/
146146
void
147-
automatical_query_tuning(uint64 query_hash, QueryStat * stat)
147+
automatical_query_tuning(uint64 qhash, QueryStat * stat)
148148
{
149149
double unstability = auto_tuning_exploration;
150150
double t_aqo,
@@ -204,11 +204,11 @@ automatical_query_tuning(uint64 query_hash, QueryStat * stat)
204204
}
205205

206206
if (num_iterations <= auto_tuning_max_iterations || p_use > 0.5)
207-
update_query(query_hash,
207+
update_query(qhash,
208208
query_context.fspace_hash,
209209
query_context.learn_aqo,
210210
query_context.use_aqo,
211211
true);
212212
else
213-
update_query(query_hash, query_context.fspace_hash, false, false, false);
213+
update_query(qhash, query_context.fspace_hash, false, false, false);
214214
}

expected/plancache.out

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ BEGIN
3333
END $$ LANGUAGE 'plpgsql';
3434
-- The function shows 6 executions without an AQO support (nnex) and
3535
-- 4 executions with usage of an AQO knowledge base (nex). Planning time in the
36-
-- case of AQO support (pt) is equal to '-1', because the query plan is exracted
36+
-- case of AQO support (pt) is equal to '-1', because the query plan is extracted
3737
-- from the plan cache.
3838
SELECT * FROM f1();
3939
nnex | nex | pt

postprocessing.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ atomic_fss_learn_step(uint64 fhash, int fss_hash, int ncols,
9494
LOCKTAG tag;
9595
int nrows;
9696

97-
init_lock_tag(&tag, (uint32) fhash, fss_hash);
97+
init_lock_tag(&tag, fhash, fss_hash);
9898
LockAcquire(&tag, ExclusiveLock, false, false);
9999

100100
if (!load_fss(fhash, fss_hash, ncols, matrix, targets, &nrows, NULL))
@@ -671,10 +671,9 @@ aqo_ExecutorEnd(QueryDesc *queryDesc)
671671
cardinality_error = cardinality_sum_errors / cardinality_num_objects;
672672
else
673673
cardinality_error = -1;
674-
Assert(query_context.query_hash>=0);
674+
675675
/* Prevent concurrent updates. */
676-
init_lock_tag(&tag, (uint32) query_context.query_hash,//my code
677-
(uint32) query_context.fspace_hash);//possible here
676+
init_lock_tag(&tag, query_context.query_hash, query_context.fspace_hash);
678677
LockAcquire(&tag, ExclusiveLock, false, false);
679678

680679
if (stat != NULL)
@@ -706,7 +705,6 @@ aqo_ExecutorEnd(QueryDesc *queryDesc)
706705
&stat->executions_without_aqo);
707706

708707
/* Store all learn data into the AQO service relations. */
709-
Assert(query_context.query_hash>=0);
710708
if (!query_context.adding_query && query_context.auto_tuning)
711709
automatical_query_tuning(query_context.query_hash, stat);
712710

@@ -970,7 +968,6 @@ print_into_explain(PlannedStmt *plannedstmt, IntoClause *into,
970968
*/
971969
if (aqo_mode != AQO_MODE_DISABLED || force_collect_stat)
972970
{
973-
Assert(query_context.query_hash>=0);
974971
if (aqo_show_hash)
975972
ExplainPropertyInteger("Query hash", NULL,
976973
query_context.query_hash, es);

preprocessing.c

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,6 @@ aqo_planner(Query *parse,
136136
ParamListInfo boundParams)
137137
{
138138
bool query_is_stored = false;
139-
Datum query_params[5];
140-
bool query_nulls[5] = {false, false, false, false, false};
141139
LOCKTAG tag;
142140
MemoryContext oldCxt;
143141

@@ -187,7 +185,7 @@ aqo_planner(Query *parse,
187185
boundParams);
188186
}
189187

190-
elog(DEBUG1, "AQO will be used for query '%s', class %ld",
188+
elog(DEBUG1, "AQO will be used for query '%s', class "UINT64_FORMAT,
191189
query_string ? query_string : "null string", query_context.query_hash);
192190

193191
oldCxt = MemoryContextSwitchTo(AQOMemoryContext);
@@ -201,8 +199,7 @@ aqo_planner(Query *parse,
201199
goto ignore_query_settings;
202200
}
203201

204-
query_is_stored = find_query(query_context.query_hash, &query_params[0],
205-
&query_nulls[0]);
202+
query_is_stored = find_query(query_context.query_hash, &query_context);
206203

207204
if (!query_is_stored)
208205
{
@@ -256,16 +253,12 @@ aqo_planner(Query *parse,
256253
else /* Query class exists in a ML knowledge base. */
257254
{
258255
query_context.adding_query = false;
259-
query_context.learn_aqo = DatumGetBool(query_params[1]);
260-
query_context.use_aqo = DatumGetBool(query_params[2]);
261-
query_context.fspace_hash = DatumGetInt64(query_params[3]);
262-
query_context.auto_tuning = DatumGetBool(query_params[4]);
263-
query_context.collect_stat = query_context.auto_tuning;
256+
257+
/* Other query_context fields filled in the find_query() routine. */
264258

265259
/*
266260
* Deactivate query if no one reason exists for usage of an AQO machinery.
267261
*/
268-
Assert(query_context.query_hash>=0);
269262
if (!query_context.learn_aqo && !query_context.use_aqo &&
270263
!query_context.auto_tuning && !force_collect_stat)
271264
add_deactivated_query(query_context.query_hash);
@@ -291,7 +284,6 @@ aqo_planner(Query *parse,
291284
* In this mode we want to learn with incoming query (if it is not
292285
* suppressed manually) and collect stats.
293286
*/
294-
Assert(query_context.query_hash>=0);
295287
query_context.collect_stat = true;
296288
query_context.fspace_hash = query_context.query_hash;
297289
break;
@@ -315,15 +307,13 @@ aqo_planner(Query *parse,
315307
* find-add query and query text must be atomic operation to prevent
316308
* concurrent insertions.
317309
*/
318-
Assert(query_context.query_hash>=0);
319-
init_lock_tag(&tag, (uint32) query_context.query_hash, (uint32) 0);//my code
310+
init_lock_tag(&tag, query_context.query_hash, 0);
320311
LockAcquire(&tag, ExclusiveLock, false, false);
321312
/*
322313
* Add query into the AQO knowledge base. To process an error with
323314
* concurrent addition from another backend we will try to restart
324315
* preprocessing routine.
325316
*/
326-
Assert(query_context.query_hash>=0);
327317
update_query(query_context.query_hash, query_context.fspace_hash,
328318
query_context.learn_aqo, query_context.use_aqo,
329319
query_context.auto_tuning);
@@ -332,7 +322,6 @@ aqo_planner(Query *parse,
332322
* Add query text into the ML-knowledge base. Just for further
333323
* analysis. In the case of cached plans we could have NULL query text.
334324
*/
335-
Assert(query_context.query_hash>=0);
336325
if (query_string != NULL)
337326
add_query_text(query_context.query_hash, query_string);
338327

@@ -346,7 +335,6 @@ aqo_planner(Query *parse,
346335
* query execution statistics in any mode.
347336
*/
348337
query_context.collect_stat = true;
349-
Assert(query_context.query_hash>=0);
350338
query_context.fspace_hash = query_context.query_hash;
351339
}
352340

sql/plancache.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ END $$ LANGUAGE 'plpgsql';
3737

3838
-- The function shows 6 executions without an AQO support (nnex) and
3939
-- 4 executions with usage of an AQO knowledge base (nex). Planning time in the
40-
-- case of AQO support (pt) is equal to '-1', because the query plan is exracted
40+
-- case of AQO support (pt) is equal to '-1', because the query plan is extracted
4141
-- from the plan cache.
4242
SELECT * FROM f1();
4343

storage.c

Lines changed: 41 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -94,44 +94,53 @@ open_aqo_relation(char *heaprelnspname, char *heaprelname,
9494
*
9595
* Use dirty snapshot to see all (include in-progess) data. We want to prevent
9696
* wait in the XactLockTableWait routine.
97+
* If query is found in the knowledge base, fill the query context struct.
9798
*/
9899
bool
99-
find_query(uint64 qhash, Datum *search_values, bool *search_nulls)
100+
find_query(uint64 qhash, QueryContextData *ctx)
100101
{
101-
Relation hrel;
102-
Relation irel;
103-
HeapTuple tuple;
102+
Relation hrel;
103+
Relation irel;
104+
HeapTuple tuple;
104105
TupleTableSlot *slot;
105-
bool shouldFree;
106-
IndexScanDesc scan;
107-
ScanKeyData key;
108-
SnapshotData snap;
109-
bool find_ok = false;
106+
bool shouldFree = true;
107+
IndexScanDesc scan;
108+
ScanKeyData key;
109+
SnapshotData snap;
110+
bool find_ok = false;
111+
Datum values[5];
112+
bool nulls[5] = {false, false, false, false, false};
110113

111114
if (!open_aqo_relation("public", "aqo_queries", "aqo_queries_query_hash_idx",
112115
AccessShareLock, &hrel, &irel))
113116
return false;
114117

115118
InitDirtySnapshot(snap);
116119
scan = index_beginscan(hrel, irel, &snap, 1, 0);
117-
ScanKeyInit(&key, 1, BTEqualStrategyNumber, F_INT4EQ, Int64GetDatum(qhash));
120+
ScanKeyInit(&key, 1, BTEqualStrategyNumber, F_INT8EQ, Int64GetDatum(qhash));
118121

119122
index_rescan(scan, &key, 1, NULL, 0);
120123
slot = MakeSingleTupleTableSlot(hrel->rd_att, &TTSOpsBufferHeapTuple);
121124
find_ok = index_getnext_slot(scan, ForwardScanDirection, slot);
122125

123-
if (find_ok && search_values != NULL)
126+
if (find_ok)
124127
{
125128
tuple = ExecFetchSlotHeapTuple(slot, true, &shouldFree);
126129
Assert(shouldFree != true);
127-
heap_deform_tuple(tuple, hrel->rd_att, search_values, search_nulls);
130+
heap_deform_tuple(tuple, hrel->rd_att, values, nulls);
131+
132+
/* Fill query context data */
133+
ctx->learn_aqo = DatumGetBool(values[1]);
134+
ctx->use_aqo = DatumGetBool(values[2]);
135+
ctx->fspace_hash = DatumGetInt64(values[3]);
136+
ctx->auto_tuning = DatumGetBool(values[4]);
137+
ctx->collect_stat = query_context.auto_tuning;
128138
}
129139

130140
ExecDropSingleTupleTableSlot(slot);
131141
index_endscan(scan);
132142
index_close(irel, AccessShareLock);
133143
table_close(hrel, AccessShareLock);
134-
135144
return find_ok;
136145
}
137146

@@ -177,7 +186,7 @@ update_query(uint64 qhash, uint64 fhash,
177186
*/
178187
InitDirtySnapshot(snap);
179188
scan = index_beginscan(hrel, irel, &snap, 1, 0);
180-
ScanKeyInit(&key, 1, BTEqualStrategyNumber, F_INT4EQ, Int32GetDatum(qhash));
189+
ScanKeyInit(&key, 1, BTEqualStrategyNumber, F_INT8EQ, Int64GetDatum(qhash));
181190

182191
index_rescan(scan, &key, 1, NULL, 0);
183192
slot = MakeSingleTupleTableSlot(hrel->rd_att, &TTSOpsBufferHeapTuple);
@@ -222,7 +231,8 @@ update_query(uint64 qhash, uint64 fhash,
222231
* Ooops, somebody concurrently updated the tuple. It is possible
223232
* only in the case of changes made by third-party code.
224233
*/
225-
elog(ERROR, "AQO feature space data for signature (%ld, %ld) concurrently"
234+
elog(ERROR, "AQO feature space data for signature ("UINT64_FORMAT \
235+
", "UINT64_FORMAT") concurrently"
226236
" updated by a stranger backend.",
227237
qhash, fhash);
228238
result = false;
@@ -284,7 +294,7 @@ add_query_text(uint64 qhash, const char *query_string)
284294
*/
285295
InitDirtySnapshot(snap);
286296
scan = index_beginscan(hrel, irel, &snap, 1, 0);
287-
ScanKeyInit(&key, 1, BTEqualStrategyNumber, F_INT4EQ, Int32GetDatum(qhash));
297+
ScanKeyInit(&key, 1, BTEqualStrategyNumber, F_INT8EQ, Int64GetDatum(qhash));
288298

289299
index_rescan(scan, &key, 1, NULL, 0);
290300
slot = MakeSingleTupleTableSlot(hrel->rd_att, &TTSOpsBufferHeapTuple);
@@ -391,7 +401,7 @@ load_fss(uint64 fhash, int fss_hash,
391401
return false;
392402

393403
scan = index_beginscan(hrel, irel, SnapshotSelf, 2, 0);
394-
ScanKeyInit(&key[0], 1, BTEqualStrategyNumber, F_INT4EQ, Int32GetDatum(fhash));
404+
ScanKeyInit(&key[0], 1, BTEqualStrategyNumber, F_INT8EQ, Int64GetDatum(fhash));
395405
ScanKeyInit(&key[1], 2, BTEqualStrategyNumber, F_INT4EQ, Int32GetDatum(fss_hash));
396406
index_rescan(scan, key, 2, NULL, 0);
397407

@@ -423,9 +433,10 @@ load_fss(uint64 fhash, int fss_hash,
423433
*relids = deform_oids_vector(values[5]);
424434
}
425435
else
426-
elog(ERROR, "unexpected number of features for hash (%ld, %d):\
427-
expected %d features, obtained %d",
428-
fhash, fss_hash, ncols, DatumGetInt32(values[2]));
436+
elog(ERROR, "unexpected number of features for hash (" \
437+
UINT64_FORMAT", %d):\
438+
expected %d features, obtained %d",
439+
fhash, fss_hash, ncols, DatumGetInt32(values[2]));
429440
}
430441
else
431442
success = false;
@@ -484,7 +495,7 @@ update_fss(uint64 fhash, int fsshash, int nrows, int ncols,
484495
InitDirtySnapshot(snap);
485496
scan = index_beginscan(hrel, irel, &snap, 2, 0);
486497

487-
ScanKeyInit(&key[0], 1, BTEqualStrategyNumber, F_INT4EQ, Int32GetDatum(fhash));
498+
ScanKeyInit(&key[0], 1, BTEqualStrategyNumber, F_INT8EQ, Int64GetDatum(fhash));
488499
ScanKeyInit(&key[1], 2, BTEqualStrategyNumber, F_INT4EQ, Int32GetDatum(fsshash));
489500

490501
index_rescan(scan, key, 2, NULL, 0);
@@ -494,7 +505,7 @@ update_fss(uint64 fhash, int fsshash, int nrows, int ncols,
494505

495506
if (!find_ok)
496507
{
497-
values[0] = Int32GetDatum(fhash);
508+
values[0] = Int64GetDatum(fhash);
498509
values[1] = Int32GetDatum(fsshash);
499510
values[2] = Int32GetDatum(ncols);
500511

@@ -549,8 +560,8 @@ update_fss(uint64 fhash, int fsshash, int nrows, int ncols,
549560
* Ooops, somebody concurrently updated the tuple. It is possible
550561
* only in the case of changes made by third-party code.
551562
*/
552-
elog(ERROR, "AQO data piece (%ld %d) concurrently updated"
553-
" by a stranger backend.",
563+
elog(ERROR, "AQO data piece ("UINT64_FORMAT" %d) concurrently"
564+
" updated by a stranger backend.",
554565
fhash, fsshash);
555566
result = false;
556567
}
@@ -596,7 +607,7 @@ get_aqo_stat(uint64 qhash)
596607
return false;
597608

598609
scan = index_beginscan(hrel, irel, SnapshotSelf, 1, 0);
599-
ScanKeyInit(&key, 1, BTEqualStrategyNumber, F_INT4EQ, Int32GetDatum(qhash));
610+
ScanKeyInit(&key, 1, BTEqualStrategyNumber, F_INT8EQ, Int64GetDatum(qhash));
600611
index_rescan(scan, &key, 1, NULL, 0);
601612
slot = MakeSingleTupleTableSlot(hrel->rd_att, &TTSOpsBufferHeapTuple);
602613

@@ -667,7 +678,7 @@ update_aqo_stat(uint64 qhash, QueryStat *stat)
667678

668679
InitDirtySnapshot(snap);
669680
scan = index_beginscan(hrel, irel, &snap, 1, 0);
670-
ScanKeyInit(&key, 1, BTEqualStrategyNumber, F_INT4EQ, Int64GetDatum(qhash));
681+
ScanKeyInit(&key, 1, BTEqualStrategyNumber, F_INT8EQ, Int64GetDatum(qhash));
671682
index_rescan(scan, &key, 1, NULL, 0);
672683
slot = MakeSingleTupleTableSlot(hrel->rd_att, &TTSOpsBufferHeapTuple);
673684

@@ -713,8 +724,8 @@ update_aqo_stat(uint64 qhash, QueryStat *stat)
713724
* Ooops, somebody concurrently updated the tuple. It is possible
714725
* only in the case of changes made by third-party code.
715726
*/
716-
elog(ERROR, "AQO statistic data for query signature %ld concurrently"
717-
" updated by a stranger backend.",
727+
elog(ERROR, "AQO statistic data for query signature "UINT64_FORMAT
728+
" concurrently updated by a stranger backend.",
718729
qhash);
719730
}
720731
}
@@ -914,8 +925,8 @@ init_deactivated_queries_storage(void)
914925

915926
/* Create the hashtable proper */
916927
MemSet(&hash_ctl, 0, sizeof(hash_ctl));
917-
hash_ctl.keysize = sizeof(int);
918-
hash_ctl.entrysize = sizeof(int);
928+
hash_ctl.keysize = sizeof(uint64);
929+
hash_ctl.entrysize = sizeof(uint64);
919930
deactivated_queries = hash_create("aqo_deactivated_queries",
920931
128, /* start small and extend */
921932
&hash_ctl,

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy