Skip to content

Commit 690776a

Browse files
committed
Bugfix. AQO plan node must have reasonable set of serialization routines: it is used during plan transfer to parallel workers. Another options/extensions can require correct serialization too.
1 parent 40bad60 commit 690776a

File tree

5 files changed

+45
-50
lines changed

5 files changed

+45
-50
lines changed

aqo.h

-1
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,6 @@ void aqo_ExecutorEnd(QueryDesc *queryDesc);
284284
extern void automatical_query_tuning(uint64 query_hash, struct StatEntry *stat);
285285

286286
/* Utilities */
287-
extern int int64_compare(const void *a, const void *b);
288287
extern int int_cmp(const void *a, const void *b);
289288
extern int double_cmp(const void *a, const void *b);
290289
extern int *argsort(void *a, int n, size_t es,

cardinality_estimation.c

+1
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ predict_for_relation(List *clauses, List *selectivities, List *relsigns,
103103
result = OkNNr_predict(data, features);
104104
}
105105
}
106+
106107
#ifdef AQO_DEBUG_PRINT
107108
predict_debug_output(clauses, selectivities, relsigns, *fss, result);
108109
#endif

hash.c

+9-9
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ static int get_node_hash(Node *node);
3333
static int get_unsorted_unsafe_int_array_hash(int *arr, int len);
3434
static int get_unordered_int_list_hash(List *lst);
3535

36-
static int64 get_relations_hash(List *relsigns);
36+
static int get_relations_hash(List *relsigns);
3737
static int get_fss_hash(int clauses_hash, int eclasses_hash,
3838
int relidslist_hash);
3939

@@ -278,7 +278,7 @@ get_fss_for_object(List *relsigns, List *clauselist,
278278

279279
clauses_hash = get_int_array_hash(sorted_clauses, n - sh);
280280
eclasses_hash = get_int_array_hash(eclass_hash, nargs);
281-
relations_hash = (int) get_relations_hash(relsigns);
281+
relations_hash = get_relations_hash(relsigns);
282282
fss_hash = get_fss_hash(clauses_hash, eclasses_hash, relations_hash);
283283

284284
MemoryContextSwitchTo(old_ctx_m);
@@ -449,26 +449,26 @@ get_fss_hash(int clauses_hash, int eclasses_hash, int relidslist_hash)
449449
* Hash is supposed to be relations-order-insensitive.
450450
* Each element of a list must have a String type,
451451
*/
452-
static int64
452+
static int
453453
get_relations_hash(List *relsigns)
454454
{
455455
int nhashes = 0;
456-
int64 *hashes = palloc(list_length(relsigns) * sizeof(uint64));
456+
uint32 *hashes = palloc(list_length(relsigns) * sizeof(uint32));
457457
ListCell *lc;
458-
int64 result;
458+
int result;
459459

460460
foreach(lc, relsigns)
461461
{
462-
hashes[nhashes++] = *(int64 *) lfirst(lc);
462+
hashes[nhashes++] = (uint32) lfirst_int(lc);
463463
}
464464

465465
/* Sort the array to make query insensitive to input order of relations. */
466-
qsort(hashes, nhashes, sizeof(int64), int64_compare);
466+
qsort(hashes, nhashes, sizeof(uint32), int_cmp);
467467

468468
/* Make a final hash value */
469469

470-
result = DatumGetInt64(hash_any_extended((const unsigned char *) hashes,
471-
nhashes * sizeof(int64), 0));
470+
result = DatumGetInt32(hash_any((const unsigned char *) hashes,
471+
nhashes * sizeof(uint32)));
472472

473473
return result;
474474
}

path_utils.c

+35-28
Original file line numberDiff line numberDiff line change
@@ -131,22 +131,22 @@ get_selectivities(PlannerInfo *root,
131131
/*
132132
* Based on the hashTupleDesc() routine
133133
*/
134-
static uint64
134+
static uint32
135135
hashTempTupleDesc(TupleDesc desc)
136136
{
137-
uint64 s;
137+
uint32 s;
138138
int i;
139139

140140
s = hash_combine(0, hash_uint32(desc->natts));
141141

142142
for (i = 0; i < desc->natts; ++i)
143143
{
144144
const char *attname = NameStr(TupleDescAttr(desc, i)->attname);
145-
uint64 s1;
145+
uint32 s1;
146146

147-
s = hash_combine64(s, hash_uint32(TupleDescAttr(desc, i)->atttypid));
148-
s1 = hash_bytes_extended((const unsigned char *) attname, strlen(attname), 0);
149-
s = hash_combine64(s, s1);
147+
s = hash_combine(s, hash_uint32(TupleDescAttr(desc, i)->atttypid));
148+
s1 = hash_bytes((const unsigned char *) attname, strlen(attname));
149+
s = hash_combine(s, s1);
150150
}
151151
return s;
152152
}
@@ -182,8 +182,8 @@ get_list_of_relids(PlannerInfo *root, Relids relids, RelSortOut *rels)
182182

183183
if (!OidIsValid(entry->relid))
184184
{
185-
/* Invalid oid */
186-
hashes = lappend_uint64(hashes, (UINT64_MAX / 7));
185+
/* TODO: Explain this logic. */
186+
hashes = lappend_int(hashes, INT32_MAX / 3);
187187
continue;
188188
}
189189

@@ -208,7 +208,7 @@ get_list_of_relids(PlannerInfo *root, Relids relids, RelSortOut *rels)
208208
trel = relation_open(entry->relid, NoLock);
209209
tdesc = RelationGetDescr(trel);
210210
Assert(CheckRelationLockedByMe(trel, AccessShareLock, true));
211-
hashes = lappend_uint64(hashes, hashTempTupleDesc(tdesc));
211+
hashes = lappend_int(hashes, hashTempTupleDesc(tdesc));
212212
relation_close(trel, NoLock);
213213
}
214214
else
@@ -218,9 +218,9 @@ get_list_of_relids(PlannerInfo *root, Relids relids, RelSortOut *rels)
218218
get_namespace_name(get_rel_namespace(entry->relid)),
219219
relrewrite ? get_rel_name(relrewrite) : relname);
220220

221-
hashes = lappend_uint64(hashes, DatumGetInt64(hash_any_extended(
221+
hashes = lappend_int(hashes, DatumGetInt32(hash_any(
222222
(unsigned char *) relname,
223-
strlen(relname), 0)));
223+
strlen(relname))));
224224

225225
hrels = lappend_oid(hrels, entry->relid);
226226
}
@@ -575,7 +575,7 @@ AQOnodeCopy(struct ExtensibleNode *enew, const struct ExtensibleNode *eold)
575575
/* These lists couldn't contain AQO nodes. Use basic machinery */
576576
new->rels = palloc(sizeof(RelSortOut));
577577
new->rels->hrels = list_copy(old->rels->hrels);
578-
new->rels->signatures = list_copy_uint64(old->rels->signatures);
578+
new->rels->signatures = list_copy(old->rels->signatures);
579579

580580
new->clauses = copyObject(old->clauses);
581581
new->grouping_exprs = copyObject(old->grouping_exprs);
@@ -610,21 +610,24 @@ AQOnodeEqual(const struct ExtensibleNode *a, const struct ExtensibleNode *b)
610610
#define WRITE_FLOAT_FIELD(fldname,format) \
611611
appendStringInfo(str, " :" CppAsString(fldname) " " format, node->fldname)
612612

613+
/*
614+
* Serialize AQO plan node to a string.
615+
*
616+
* Right now we can't correctly serialize all fields of the node. Taking into
617+
* account that this action needed when a plan moves into parallel workers or
618+
* just during debugging, we serialize it only partially, just for debug
619+
* purposes.
620+
* Some extensions may manipulate by parts of serialized plan too.
621+
*/
613622
static void
614623
AQOnodeOut(struct StringInfoData *str, const struct ExtensibleNode *enode)
615624
{
616625
AQOPlanNode *node = (AQOPlanNode *) enode;
617626

618-
Assert(0);
619-
WRITE_BOOL_FIELD(had_path);
620-
WRITE_NODE_FIELD(rels);
621-
WRITE_NODE_FIELD(clauses);
622-
WRITE_NODE_FIELD(selectivities);
623-
WRITE_NODE_FIELD(grouping_exprs);
624-
625-
WRITE_ENUM_FIELD(jointype, JoinType);
626-
WRITE_FLOAT_FIELD(parallel_divisor, "%.5f");
627-
WRITE_BOOL_FIELD(was_parametrized);
627+
node->had_path = false;
628+
node->jointype = 0;
629+
node->parallel_divisor = 1.0;
630+
node->was_parametrized = false;
628631

629632
/* For Adaptive optimization DEBUG purposes */
630633
WRITE_INT_FIELD(fss);
@@ -661,24 +664,28 @@ AQOnodeOut(struct StringInfoData *str, const struct ExtensibleNode *enode)
661664
(void) token; /* in case not used elsewhere */ \
662665
local_node->fldname = nodeRead(NULL, 0)
663666

667+
/*
668+
* Deserialize AQO plan node from a string to internal representation.
669+
*
670+
* Should work in coherence with AQOnodeOut().
671+
*/
664672
static void
665673
AQOnodeRead(struct ExtensibleNode *enode)
666674
{
667675
AQOPlanNode *local_node = (AQOPlanNode *) enode;
668676
const char *token;
669677
int length;
670678

671-
Assert(0);
672679
READ_BOOL_FIELD(had_path);
673-
READ_NODE_FIELD(rels);
674-
READ_NODE_FIELD(clauses);
675-
READ_NODE_FIELD(selectivities);
676-
READ_NODE_FIELD(grouping_exprs);
677-
678680
READ_ENUM_FIELD(jointype, JoinType);
679681
READ_FLOAT_FIELD(parallel_divisor);
680682
READ_BOOL_FIELD(was_parametrized);
681683

684+
local_node->rels = palloc0(sizeof(RelSortOut));
685+
local_node->clauses = NIL;
686+
local_node->selectivities = NIL;
687+
local_node->grouping_exprs = NIL;
688+
682689
/* For Adaptive optimization DEBUG purposes */
683690
READ_INT_FIELD(fss);
684691
READ_FLOAT_FIELD(prediction);

utils.c

-12
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,6 @@ static int argsort_cmp(const void *a, const void *b);
2828
* qsort comparator functions
2929
*/
3030

31-
/* int64 comparator for pg_qsort. */
32-
int
33-
int64_compare(const void *va, const void *vb)
34-
{
35-
int64 a = *((const int64 *) va);
36-
int64 b = *((const int64 *) vb);
37-
38-
if (a == b)
39-
return 0;
40-
return (a > b) ? 1 : -1;
41-
}
42-
4331
/*
4432
* Function for qsorting an integer arrays
4533
*/

0 commit comments

Comments
 (0)