Skip to content

Commit 3231ac9

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 6834a18 commit 3231ac9

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
@@ -130,22 +130,22 @@ get_selectivities(PlannerInfo *root,
130130
/*
131131
* Based on the hashTupleDesc() routine
132132
*/
133-
static uint64
133+
static uint32
134134
hashTempTupleDesc(TupleDesc desc)
135135
{
136-
uint64 s;
136+
uint32 s;
137137
int i;
138138

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

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

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

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

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

220-
hashes = lappend_uint64(hashes, DatumGetInt64(hash_any_extended(
220+
hashes = lappend_int(hashes, DatumGetInt32(hash_any(
221221
(unsigned char *) relname,
222-
strlen(relname), 0)));
222+
strlen(relname))));
223223

224224
hrels = lappend_oid(hrels, entry->relid);
225225
}
@@ -569,7 +569,7 @@ AQOnodeCopy(struct ExtensibleNode *enew, const struct ExtensibleNode *eold)
569569
/* These lists couldn't contain AQO nodes. Use basic machinery */
570570
new->rels = palloc(sizeof(RelSortOut));
571571
new->rels->hrels = list_copy(old->rels->hrels);
572-
new->rels->signatures = list_copy_uint64(old->rels->signatures);
572+
new->rels->signatures = list_copy(old->rels->signatures);
573573

574574
new->clauses = copyObject(old->clauses);
575575
new->grouping_exprs = copyObject(old->grouping_exprs);
@@ -604,21 +604,24 @@ AQOnodeEqual(const struct ExtensibleNode *a, const struct ExtensibleNode *b)
604604
#define WRITE_FLOAT_FIELD(fldname,format) \
605605
appendStringInfo(str, " :" CppAsString(fldname) " " format, node->fldname)
606606

607+
/*
608+
* Serialize AQO plan node to a string.
609+
*
610+
* Right now we can't correctly serialize all fields of the node. Taking into
611+
* account that this action needed when a plan moves into parallel workers or
612+
* just during debugging, we serialize it only partially, just for debug
613+
* purposes.
614+
* Some extensions may manipulate by parts of serialized plan too.
615+
*/
607616
static void
608617
AQOnodeOut(struct StringInfoData *str, const struct ExtensibleNode *enode)
609618
{
610619
AQOPlanNode *node = (AQOPlanNode *) enode;
611620

612-
Assert(0);
613-
WRITE_BOOL_FIELD(had_path);
614-
WRITE_NODE_FIELD(rels);
615-
WRITE_NODE_FIELD(clauses);
616-
WRITE_NODE_FIELD(selectivities);
617-
WRITE_NODE_FIELD(grouping_exprs);
618-
619-
WRITE_ENUM_FIELD(jointype, JoinType);
620-
WRITE_FLOAT_FIELD(parallel_divisor, "%.5f");
621-
WRITE_BOOL_FIELD(was_parametrized);
621+
node->had_path = false;
622+
node->jointype = 0;
623+
node->parallel_divisor = 1.0;
624+
node->was_parametrized = false;
622625

623626
/* For Adaptive optimization DEBUG purposes */
624627
WRITE_INT_FIELD(fss);
@@ -655,24 +658,28 @@ AQOnodeOut(struct StringInfoData *str, const struct ExtensibleNode *enode)
655658
(void) token; /* in case not used elsewhere */ \
656659
local_node->fldname = nodeRead(NULL, 0)
657660

661+
/*
662+
* Deserialize AQO plan node from a string to internal representation.
663+
*
664+
* Should work in coherence with AQOnodeOut().
665+
*/
658666
static void
659667
AQOnodeRead(struct ExtensibleNode *enode)
660668
{
661669
AQOPlanNode *local_node = (AQOPlanNode *) enode;
662670
const char *token;
663671
int length;
664672

665-
Assert(0);
666673
READ_BOOL_FIELD(had_path);
667-
READ_NODE_FIELD(rels);
668-
READ_NODE_FIELD(clauses);
669-
READ_NODE_FIELD(selectivities);
670-
READ_NODE_FIELD(grouping_exprs);
671-
672674
READ_ENUM_FIELD(jointype, JoinType);
673675
READ_FLOAT_FIELD(parallel_divisor);
674676
READ_BOOL_FIELD(was_parametrized);
675677

678+
local_node->rels = palloc0(sizeof(RelSortOut));
679+
local_node->clauses = NIL;
680+
local_node->selectivities = NIL;
681+
local_node->grouping_exprs = NIL;
682+
676683
/* For Adaptive optimization DEBUG purposes */
677684
READ_INT_FIELD(fss);
678685
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)