aboutsummaryrefslogtreecommitdiff
path: root/src/backend/nodes/copyfuncs.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2016-06-18 15:22:34 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2016-06-18 15:22:34 -0400
commit100340e2dcd05d6505082a8fe343fb2ef2fa5b2a (patch)
treeeb41564ad79ab0ab0557471ea004f58a9b26a753 /src/backend/nodes/copyfuncs.c
parent598aa194af2fb7f294ae4b029494a134a44be333 (diff)
downloadpostgresql-100340e2dcd05d6505082a8fe343fb2ef2fa5b2a.tar.gz
postgresql-100340e2dcd05d6505082a8fe343fb2ef2fa5b2a.zip
Restore foreign-key-aware estimation of join relation sizes.
This patch provides a new implementation of the logic added by commit 137805f89 and later removed by 77ba61080. It differs from the original primarily in expending much less effort per joinrel in large queries, which it accomplishes by doing most of the matching work once per query not once per joinrel. Hopefully, it's also less buggy and better commented. The never-documented enable_fkey_estimates GUC remains gone. There remains work to be done to make the selectivity estimates account for nulls in FK referencing columns; but that was true of the original patch as well. We may be able to address this point later in beta. In the meantime, any error should be in the direction of overestimating rather than underestimating joinrel sizes, which seems like the direction we want to err in. Tomas Vondra and Tom Lane Discussion: <31041.1465069446@sss.pgh.pa.us>
Diffstat (limited to 'src/backend/nodes/copyfuncs.c')
-rw-r--r--src/backend/nodes/copyfuncs.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 8548a4bb011..59add5ba794 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -27,6 +27,7 @@
#include "nodes/plannodes.h"
#include "nodes/relation.h"
#include "utils/datum.h"
+#include "utils/rel.h"
/*
@@ -4254,6 +4255,24 @@ _copyValue(const Value *from)
return newnode;
}
+
+static ForeignKeyCacheInfo *
+_copyForeignKeyCacheInfo(const ForeignKeyCacheInfo *from)
+{
+ ForeignKeyCacheInfo *newnode = makeNode(ForeignKeyCacheInfo);
+
+ COPY_SCALAR_FIELD(conrelid);
+ COPY_SCALAR_FIELD(confrelid);
+ COPY_SCALAR_FIELD(nkeys);
+ /* COPY_SCALAR_FIELD might work for these, but let's not assume that */
+ memcpy(newnode->conkey, from->conkey, sizeof(newnode->conkey));
+ memcpy(newnode->confkey, from->confkey, sizeof(newnode->confkey));
+ memcpy(newnode->conpfeqop, from->conpfeqop, sizeof(newnode->conpfeqop));
+
+ return newnode;
+}
+
+
/*
* copyObject
*
@@ -5052,6 +5071,13 @@ copyObject(const void *from)
retval = _copyRoleSpec(from);
break;
+ /*
+ * MISCELLANEOUS NODES
+ */
+ case T_ForeignKeyCacheInfo:
+ retval = _copyForeignKeyCacheInfo(from);
+ break;
+
default:
elog(ERROR, "unrecognized node type: %d", (int) nodeTag(from));
retval = 0; /* keep compiler quiet */