public inbox for [email protected]help / color / mirror / Atom feed
[PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute 47+ messages / 1 participants [nested] [flat]
* [PATCH v36 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 6da0dcd61c..484dab0a1a 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -1005,6 +1005,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1061,6 +1062,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index e978b491f6..95b1b14cd3 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -830,6 +830,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, false, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index 25545029d7..0b2f9d398a 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -463,6 +464,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 485d1b06c9..9e3ebd488a 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -709,6 +709,8 @@ typedef struct RelOptInfo PlannerInfo *subroot; /* if subquery */ List *subplan_params; /* if subquery */ int rel_parallel_workers; /* wanted number of parallel workers */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.21.0 --op7mf2i72xk5yu7c Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v36-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index d73ac562eb..37b4223adb 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -998,6 +998,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1054,6 +1055,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index 02f813cebd..d27167dc76 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -829,6 +829,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index c5947fa418..eebabcfccf 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -480,6 +481,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 86405a274e..0d61f04d27 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -718,6 +718,8 @@ typedef struct RelOptInfo int rel_parallel_workers; /* wanted number of parallel workers */ uint32 amflags; /* Bitmask of optional features supported by * the table AM */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.26.2 --yh7cw345mbttadjz Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v38-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index d73ac562eb..37b4223adb 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -998,6 +998,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1054,6 +1055,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index 02f813cebd..d27167dc76 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -829,6 +829,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index c5947fa418..eebabcfccf 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -480,6 +481,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 86405a274e..0d61f04d27 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -718,6 +718,8 @@ typedef struct RelOptInfo int rel_parallel_workers; /* wanted number of parallel workers */ uint32 amflags; /* Bitmask of optional features supported by * the table AM */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.26.2 --yh7cw345mbttadjz Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v38-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v36 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 6da0dcd61c..484dab0a1a 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -1005,6 +1005,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1061,6 +1062,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index e978b491f6..95b1b14cd3 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -830,6 +830,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, false, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index 25545029d7..0b2f9d398a 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -463,6 +464,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 485d1b06c9..9e3ebd488a 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -709,6 +709,8 @@ typedef struct RelOptInfo PlannerInfo *subroot; /* if subquery */ List *subplan_params; /* if subquery */ int rel_parallel_workers; /* wanted number of parallel workers */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.21.0 --op7mf2i72xk5yu7c Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v36-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v36 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 6da0dcd61c..484dab0a1a 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -1005,6 +1005,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1061,6 +1062,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index e978b491f6..95b1b14cd3 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -830,6 +830,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, false, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index 25545029d7..0b2f9d398a 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -463,6 +464,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 485d1b06c9..9e3ebd488a 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -709,6 +709,8 @@ typedef struct RelOptInfo PlannerInfo *subroot; /* if subquery */ List *subplan_params; /* if subquery */ int rel_parallel_workers; /* wanted number of parallel workers */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.21.0 --op7mf2i72xk5yu7c Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v36-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index d73ac562eb..37b4223adb 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -998,6 +998,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1054,6 +1055,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index 02f813cebd..d27167dc76 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -829,6 +829,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index c5947fa418..eebabcfccf 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -480,6 +481,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 86405a274e..0d61f04d27 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -718,6 +718,8 @@ typedef struct RelOptInfo int rel_parallel_workers; /* wanted number of parallel workers */ uint32 amflags; /* Bitmask of optional features supported by * the table AM */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.26.2 --yh7cw345mbttadjz Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v38-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v36 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 6da0dcd61c..484dab0a1a 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -1005,6 +1005,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1061,6 +1062,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index e978b491f6..95b1b14cd3 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -830,6 +830,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, false, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index 25545029d7..0b2f9d398a 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -463,6 +464,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 485d1b06c9..9e3ebd488a 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -709,6 +709,8 @@ typedef struct RelOptInfo PlannerInfo *subroot; /* if subquery */ List *subplan_params; /* if subquery */ int rel_parallel_workers; /* wanted number of parallel workers */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.21.0 --op7mf2i72xk5yu7c Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v36-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v36 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 6da0dcd61c..484dab0a1a 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -1005,6 +1005,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1061,6 +1062,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index e978b491f6..95b1b14cd3 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -830,6 +830,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, false, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index 25545029d7..0b2f9d398a 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -463,6 +464,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 485d1b06c9..9e3ebd488a 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -709,6 +709,8 @@ typedef struct RelOptInfo PlannerInfo *subroot; /* if subquery */ List *subplan_params; /* if subquery */ int rel_parallel_workers; /* wanted number of parallel workers */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.21.0 --op7mf2i72xk5yu7c Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v36-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v36 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 6da0dcd61c..484dab0a1a 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -1005,6 +1005,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1061,6 +1062,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index e978b491f6..95b1b14cd3 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -830,6 +830,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, false, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index 25545029d7..0b2f9d398a 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -463,6 +464,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 485d1b06c9..9e3ebd488a 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -709,6 +709,8 @@ typedef struct RelOptInfo PlannerInfo *subroot; /* if subquery */ List *subplan_params; /* if subquery */ int rel_parallel_workers; /* wanted number of parallel workers */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.21.0 --op7mf2i72xk5yu7c Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v36-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v37 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index b399592ff8..754f6d64f6 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -1009,6 +1009,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1065,6 +1066,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index e978b491f6..95b1b14cd3 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -830,6 +830,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, false, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index f9d0d67aa7..bdd4876a84 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -463,6 +464,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 3dd16b9ad5..925f2eac3f 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -708,6 +708,8 @@ typedef struct RelOptInfo PlannerInfo *subroot; /* if subquery */ List *subplan_params; /* if subquery */ int rel_parallel_workers; /* wanted number of parallel workers */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.21.0 --snesplnlompos6d4 Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v37-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index d73ac562eb..37b4223adb 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -998,6 +998,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1054,6 +1055,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index 02f813cebd..d27167dc76 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -829,6 +829,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index c5947fa418..eebabcfccf 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -480,6 +481,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 86405a274e..0d61f04d27 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -718,6 +718,8 @@ typedef struct RelOptInfo int rel_parallel_workers; /* wanted number of parallel workers */ uint32 amflags; /* Bitmask of optional features supported by * the table AM */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.26.2 --yh7cw345mbttadjz Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v38-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v36 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 6da0dcd61c..484dab0a1a 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -1005,6 +1005,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1061,6 +1062,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index e978b491f6..95b1b14cd3 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -830,6 +830,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, false, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index 25545029d7..0b2f9d398a 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -463,6 +464,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 485d1b06c9..9e3ebd488a 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -709,6 +709,8 @@ typedef struct RelOptInfo PlannerInfo *subroot; /* if subquery */ List *subplan_params; /* if subquery */ int rel_parallel_workers; /* wanted number of parallel workers */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.21.0 --op7mf2i72xk5yu7c Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v36-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v36 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 6da0dcd61c..484dab0a1a 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -1005,6 +1005,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1061,6 +1062,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index e978b491f6..95b1b14cd3 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -830,6 +830,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, false, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index 25545029d7..0b2f9d398a 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -463,6 +464,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 485d1b06c9..9e3ebd488a 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -709,6 +709,8 @@ typedef struct RelOptInfo PlannerInfo *subroot; /* if subquery */ List *subplan_params; /* if subquery */ int rel_parallel_workers; /* wanted number of parallel workers */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.21.0 --op7mf2i72xk5yu7c Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v36-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index d73ac562eb..37b4223adb 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -998,6 +998,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1054,6 +1055,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index 02f813cebd..d27167dc76 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -829,6 +829,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index c5947fa418..eebabcfccf 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -480,6 +481,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 86405a274e..0d61f04d27 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -718,6 +718,8 @@ typedef struct RelOptInfo int rel_parallel_workers; /* wanted number of parallel workers */ uint32 amflags; /* Bitmask of optional features supported by * the table AM */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.26.2 --yh7cw345mbttadjz Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v38-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v36 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 6da0dcd61c..484dab0a1a 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -1005,6 +1005,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1061,6 +1062,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index e978b491f6..95b1b14cd3 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -830,6 +830,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, false, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index 25545029d7..0b2f9d398a 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -463,6 +464,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 485d1b06c9..9e3ebd488a 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -709,6 +709,8 @@ typedef struct RelOptInfo PlannerInfo *subroot; /* if subquery */ List *subplan_params; /* if subquery */ int rel_parallel_workers; /* wanted number of parallel workers */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.21.0 --op7mf2i72xk5yu7c Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v36-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index d73ac562eb..37b4223adb 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -998,6 +998,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1054,6 +1055,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index 02f813cebd..d27167dc76 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -829,6 +829,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index c5947fa418..eebabcfccf 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -480,6 +481,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 86405a274e..0d61f04d27 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -718,6 +718,8 @@ typedef struct RelOptInfo int rel_parallel_workers; /* wanted number of parallel workers */ uint32 amflags; /* Bitmask of optional features supported by * the table AM */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.26.2 --yh7cw345mbttadjz Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v38-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index d73ac562eb..37b4223adb 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -998,6 +998,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1054,6 +1055,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index 02f813cebd..d27167dc76 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -829,6 +829,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index c5947fa418..eebabcfccf 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -480,6 +481,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 86405a274e..0d61f04d27 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -718,6 +718,8 @@ typedef struct RelOptInfo int rel_parallel_workers; /* wanted number of parallel workers */ uint32 amflags; /* Bitmask of optional features supported by * the table AM */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.26.2 --yh7cw345mbttadjz Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v38-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index d73ac562eb..37b4223adb 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -998,6 +998,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1054,6 +1055,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index 02f813cebd..d27167dc76 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -829,6 +829,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index c5947fa418..eebabcfccf 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -480,6 +481,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 86405a274e..0d61f04d27 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -718,6 +718,8 @@ typedef struct RelOptInfo int rel_parallel_workers; /* wanted number of parallel workers */ uint32 amflags; /* Bitmask of optional features supported by * the table AM */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.26.2 --yh7cw345mbttadjz Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v38-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v36 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 6da0dcd61c..484dab0a1a 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -1005,6 +1005,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1061,6 +1062,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index e978b491f6..95b1b14cd3 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -830,6 +830,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, false, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index 25545029d7..0b2f9d398a 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -463,6 +464,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 485d1b06c9..9e3ebd488a 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -709,6 +709,8 @@ typedef struct RelOptInfo PlannerInfo *subroot; /* if subquery */ List *subplan_params; /* if subquery */ int rel_parallel_workers; /* wanted number of parallel workers */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.21.0 --op7mf2i72xk5yu7c Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v36-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v36 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 6da0dcd61c..484dab0a1a 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -1005,6 +1005,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1061,6 +1062,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index e978b491f6..95b1b14cd3 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -830,6 +830,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, false, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index 25545029d7..0b2f9d398a 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -463,6 +464,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 485d1b06c9..9e3ebd488a 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -709,6 +709,8 @@ typedef struct RelOptInfo PlannerInfo *subroot; /* if subquery */ List *subplan_params; /* if subquery */ int rel_parallel_workers; /* wanted number of parallel workers */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.21.0 --op7mf2i72xk5yu7c Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v36-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index d73ac562eb..37b4223adb 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -998,6 +998,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1054,6 +1055,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index 02f813cebd..d27167dc76 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -829,6 +829,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index c5947fa418..eebabcfccf 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -480,6 +481,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 86405a274e..0d61f04d27 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -718,6 +718,8 @@ typedef struct RelOptInfo int rel_parallel_workers; /* wanted number of parallel workers */ uint32 amflags; /* Bitmask of optional features supported by * the table AM */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.26.2 --yh7cw345mbttadjz Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v38-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v36 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 6da0dcd61c..484dab0a1a 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -1005,6 +1005,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1061,6 +1062,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index e978b491f6..95b1b14cd3 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -830,6 +830,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, false, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index 25545029d7..0b2f9d398a 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -463,6 +464,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 485d1b06c9..9e3ebd488a 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -709,6 +709,8 @@ typedef struct RelOptInfo PlannerInfo *subroot; /* if subquery */ List *subplan_params; /* if subquery */ int rel_parallel_workers; /* wanted number of parallel workers */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.21.0 --op7mf2i72xk5yu7c Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v36-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH 01/10] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index d73ac562eb..37b4223adb 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -998,6 +998,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1054,6 +1055,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index 02f813cebd..d27167dc76 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -829,6 +829,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index c5947fa418..eebabcfccf 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -480,6 +481,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 86405a274e..0d61f04d27 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -718,6 +718,8 @@ typedef struct RelOptInfo int rel_parallel_workers; /* wanted number of parallel workers */ uint32 amflags; /* Bitmask of optional features supported by * the table AM */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.30.2 --------------F495F6B18672582269F00FF9 Content-Type: text/x-patch; charset=UTF-8; name="0002-review-20210317.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="0002-review-20210317.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH 01/10] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index d73ac562eb..37b4223adb 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -998,6 +998,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1054,6 +1055,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index 02f813cebd..d27167dc76 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -829,6 +829,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index c5947fa418..eebabcfccf 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -480,6 +481,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 86405a274e..0d61f04d27 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -718,6 +718,8 @@ typedef struct RelOptInfo int rel_parallel_workers; /* wanted number of parallel workers */ uint32 amflags; /* Bitmask of optional features supported by * the table AM */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.30.2 --------------F495F6B18672582269F00FF9 Content-Type: text/x-patch; charset=UTF-8; name="0002-review-20210317.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="0002-review-20210317.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index d73ac562eb..37b4223adb 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -998,6 +998,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1054,6 +1055,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index 02f813cebd..d27167dc76 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -829,6 +829,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index c5947fa418..eebabcfccf 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -480,6 +481,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 86405a274e..0d61f04d27 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -718,6 +718,8 @@ typedef struct RelOptInfo int rel_parallel_workers; /* wanted number of parallel workers */ uint32 amflags; /* Bitmask of optional features supported by * the table AM */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.26.2 --yh7cw345mbttadjz Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v38-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v36 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 6da0dcd61c..484dab0a1a 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -1005,6 +1005,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1061,6 +1062,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index e978b491f6..95b1b14cd3 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -830,6 +830,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, false, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index 25545029d7..0b2f9d398a 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -463,6 +464,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 485d1b06c9..9e3ebd488a 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -709,6 +709,8 @@ typedef struct RelOptInfo PlannerInfo *subroot; /* if subquery */ List *subplan_params; /* if subquery */ int rel_parallel_workers; /* wanted number of parallel workers */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.21.0 --op7mf2i72xk5yu7c Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v36-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v35 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) --- src/backend/optimizer/plan/initsplan.c | 10 ++++++++++ src/backend/optimizer/util/plancat.c | 10 ++++++++++ src/include/nodes/pathnodes.h | 2 ++ 3 files changed, 22 insertions(+) diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index e978b491f6..95b1b14cd3 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -830,6 +830,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, false, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index 25545029d7..0b2f9d398a 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -463,6 +464,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 485d1b06c9..9e3ebd488a 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -709,6 +709,8 @@ typedef struct RelOptInfo PlannerInfo *subroot; /* if subquery */ List *subplan_params; /* if subquery */ int rel_parallel_workers; /* wanted number of parallel workers */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.21.0 --tbesu4k6dthoevcy Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v8-0002-Introuduce-RelOptInfo.uniquekeys-attribute.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v36 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 6da0dcd61c..484dab0a1a 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -1005,6 +1005,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1061,6 +1062,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index e978b491f6..95b1b14cd3 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -830,6 +830,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, false, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index 25545029d7..0b2f9d398a 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -463,6 +464,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 485d1b06c9..9e3ebd488a 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -709,6 +709,8 @@ typedef struct RelOptInfo PlannerInfo *subroot; /* if subquery */ List *subplan_params; /* if subquery */ int rel_parallel_workers; /* wanted number of parallel workers */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.21.0 --op7mf2i72xk5yu7c Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v36-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index d73ac562eb..37b4223adb 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -998,6 +998,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1054,6 +1055,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index 02f813cebd..d27167dc76 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -829,6 +829,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index c5947fa418..eebabcfccf 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -480,6 +481,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 86405a274e..0d61f04d27 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -718,6 +718,8 @@ typedef struct RelOptInfo int rel_parallel_workers; /* wanted number of parallel workers */ uint32 amflags; /* Bitmask of optional features supported by * the table AM */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.26.2 --yh7cw345mbttadjz Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v38-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index d73ac562eb..37b4223adb 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -998,6 +998,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1054,6 +1055,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index 02f813cebd..d27167dc76 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -829,6 +829,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index c5947fa418..eebabcfccf 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -480,6 +481,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 86405a274e..0d61f04d27 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -718,6 +718,8 @@ typedef struct RelOptInfo int rel_parallel_workers; /* wanted number of parallel workers */ uint32 amflags; /* Bitmask of optional features supported by * the table AM */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.26.2 --yh7cw345mbttadjz Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v38-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v36 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 6da0dcd61c..484dab0a1a 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -1005,6 +1005,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1061,6 +1062,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index e978b491f6..95b1b14cd3 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -830,6 +830,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, false, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index 25545029d7..0b2f9d398a 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -463,6 +464,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 485d1b06c9..9e3ebd488a 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -709,6 +709,8 @@ typedef struct RelOptInfo PlannerInfo *subroot; /* if subquery */ List *subplan_params; /* if subquery */ int rel_parallel_workers; /* wanted number of parallel workers */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.21.0 --op7mf2i72xk5yu7c Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v36-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index d73ac562eb..37b4223adb 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -998,6 +998,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1054,6 +1055,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index 02f813cebd..d27167dc76 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -829,6 +829,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index c5947fa418..eebabcfccf 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -480,6 +481,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 86405a274e..0d61f04d27 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -718,6 +718,8 @@ typedef struct RelOptInfo int rel_parallel_workers; /* wanted number of parallel workers */ uint32 amflags; /* Bitmask of optional features supported by * the table AM */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.26.2 --yh7cw345mbttadjz Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v38-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index d73ac562eb..37b4223adb 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -998,6 +998,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1054,6 +1055,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index 02f813cebd..d27167dc76 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -829,6 +829,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index c5947fa418..eebabcfccf 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -480,6 +481,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 86405a274e..0d61f04d27 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -718,6 +718,8 @@ typedef struct RelOptInfo int rel_parallel_workers; /* wanted number of parallel workers */ uint32 amflags; /* Bitmask of optional features supported by * the table AM */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.26.2 --yh7cw345mbttadjz Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v38-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index d73ac562eb..37b4223adb 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -998,6 +998,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1054,6 +1055,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index 02f813cebd..d27167dc76 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -829,6 +829,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index c5947fa418..eebabcfccf 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -480,6 +481,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 86405a274e..0d61f04d27 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -718,6 +718,8 @@ typedef struct RelOptInfo int rel_parallel_workers; /* wanted number of parallel workers */ uint32 amflags; /* Bitmask of optional features supported by * the table AM */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.26.2 --yh7cw345mbttadjz Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v38-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index d73ac562eb..37b4223adb 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -998,6 +998,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1054,6 +1055,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index 02f813cebd..d27167dc76 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -829,6 +829,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index c5947fa418..eebabcfccf 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -480,6 +481,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 86405a274e..0d61f04d27 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -718,6 +718,8 @@ typedef struct RelOptInfo int rel_parallel_workers; /* wanted number of parallel workers */ uint32 amflags; /* Bitmask of optional features supported by * the table AM */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.26.2 --yh7cw345mbttadjz Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v38-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index d73ac562eb..37b4223adb 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -998,6 +998,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1054,6 +1055,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index 02f813cebd..d27167dc76 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -829,6 +829,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index c5947fa418..eebabcfccf 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -480,6 +481,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 86405a274e..0d61f04d27 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -718,6 +718,8 @@ typedef struct RelOptInfo int rel_parallel_workers; /* wanted number of parallel workers */ uint32 amflags; /* Bitmask of optional features supported by * the table AM */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.26.2 --yh7cw345mbttadjz Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v38-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v36 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 6da0dcd61c..484dab0a1a 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -1005,6 +1005,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1061,6 +1062,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index e978b491f6..95b1b14cd3 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -830,6 +830,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, false, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index 25545029d7..0b2f9d398a 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -463,6 +464,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 485d1b06c9..9e3ebd488a 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -709,6 +709,8 @@ typedef struct RelOptInfo PlannerInfo *subroot; /* if subquery */ List *subplan_params; /* if subquery */ int rel_parallel_workers; /* wanted number of parallel workers */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.21.0 --op7mf2i72xk5yu7c Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v36-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v36 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 6da0dcd61c..484dab0a1a 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -1005,6 +1005,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1061,6 +1062,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index e978b491f6..95b1b14cd3 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -830,6 +830,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, false, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index 25545029d7..0b2f9d398a 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -463,6 +464,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 485d1b06c9..9e3ebd488a 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -709,6 +709,8 @@ typedef struct RelOptInfo PlannerInfo *subroot; /* if subquery */ List *subplan_params; /* if subquery */ int rel_parallel_workers; /* wanted number of parallel workers */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.21.0 --op7mf2i72xk5yu7c Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v36-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v36 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 6da0dcd61c..484dab0a1a 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -1005,6 +1005,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1061,6 +1062,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index e978b491f6..95b1b14cd3 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -830,6 +830,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, false, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index 25545029d7..0b2f9d398a 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -463,6 +464,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 485d1b06c9..9e3ebd488a 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -709,6 +709,8 @@ typedef struct RelOptInfo PlannerInfo *subroot; /* if subquery */ List *subplan_params; /* if subquery */ int rel_parallel_workers; /* wanted number of parallel workers */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.21.0 --op7mf2i72xk5yu7c Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v36-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index d73ac562eb..37b4223adb 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -998,6 +998,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1054,6 +1055,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index 02f813cebd..d27167dc76 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -829,6 +829,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index c5947fa418..eebabcfccf 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -480,6 +481,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 86405a274e..0d61f04d27 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -718,6 +718,8 @@ typedef struct RelOptInfo int rel_parallel_workers; /* wanted number of parallel workers */ uint32 amflags; /* Bitmask of optional features supported by * the table AM */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.26.2 --yh7cw345mbttadjz Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v38-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index d73ac562eb..37b4223adb 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -998,6 +998,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1054,6 +1055,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index 02f813cebd..d27167dc76 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -829,6 +829,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index c5947fa418..eebabcfccf 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -480,6 +481,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 86405a274e..0d61f04d27 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -718,6 +718,8 @@ typedef struct RelOptInfo int rel_parallel_workers; /* wanted number of parallel workers */ uint32 amflags; /* Bitmask of optional features supported by * the table AM */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.26.2 --yh7cw345mbttadjz Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v38-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index d73ac562eb..37b4223adb 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -998,6 +998,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1054,6 +1055,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index 02f813cebd..d27167dc76 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -829,6 +829,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index c5947fa418..eebabcfccf 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -480,6 +481,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 86405a274e..0d61f04d27 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -718,6 +718,8 @@ typedef struct RelOptInfo int rel_parallel_workers; /* wanted number of parallel workers */ uint32 amflags; /* Bitmask of optional features supported by * the table AM */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.26.2 --yh7cw345mbttadjz Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v38-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index d73ac562eb..37b4223adb 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -998,6 +998,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1054,6 +1055,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index 02f813cebd..d27167dc76 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -829,6 +829,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index c5947fa418..eebabcfccf 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -480,6 +481,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 86405a274e..0d61f04d27 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -718,6 +718,8 @@ typedef struct RelOptInfo int rel_parallel_workers; /* wanted number of parallel workers */ uint32 amflags; /* Bitmask of optional features supported by * the table AM */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.26.2 --yh7cw345mbttadjz Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v38-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index d73ac562eb..37b4223adb 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -998,6 +998,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1054,6 +1055,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index 02f813cebd..d27167dc76 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -829,6 +829,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index c5947fa418..eebabcfccf 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -480,6 +481,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 86405a274e..0d61f04d27 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -718,6 +718,8 @@ typedef struct RelOptInfo int rel_parallel_workers; /* wanted number of parallel workers */ uint32 amflags; /* Bitmask of optional features supported by * the table AM */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.26.2 --yh7cw345mbttadjz Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v38-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v36 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 6da0dcd61c..484dab0a1a 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -1005,6 +1005,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1061,6 +1062,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index e978b491f6..95b1b14cd3 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -830,6 +830,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, false, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index 25545029d7..0b2f9d398a 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -463,6 +464,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 485d1b06c9..9e3ebd488a 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -709,6 +709,8 @@ typedef struct RelOptInfo PlannerInfo *subroot; /* if subquery */ List *subplan_params; /* if subquery */ int rel_parallel_workers; /* wanted number of parallel workers */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.21.0 --op7mf2i72xk5yu7c Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v36-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index d73ac562eb..37b4223adb 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -998,6 +998,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1054,6 +1055,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index 02f813cebd..d27167dc76 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -829,6 +829,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index c5947fa418..eebabcfccf 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -480,6 +481,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 86405a274e..0d61f04d27 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -718,6 +718,8 @@ typedef struct RelOptInfo int rel_parallel_workers; /* wanted number of parallel workers */ uint32 amflags; /* Bitmask of optional features supported by * the table AM */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.26.2 --yh7cw345mbttadjz Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v38-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
* [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute @ 2020-05-03 14:37 一挃 <[email protected]> 0 siblings, 0 replies; 47+ messages in thread From: 一挃 @ 2020-05-03 14:37 UTC (permalink / raw) The notnullattrs is calculated from catalog and run-time query. That infomation is translated to child relation as well for partitioned table. --- src/backend/optimizer/path/allpaths.c | 31 ++++++++++++++++++++++++++ src/backend/optimizer/plan/initsplan.c | 10 +++++++++ src/backend/optimizer/util/plancat.c | 10 +++++++++ src/include/nodes/pathnodes.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index d73ac562eb..37b4223adb 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -998,6 +998,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *childrel; ListCell *parentvars; ListCell *childvars; + int i = -1; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -1054,6 +1055,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, (Node *) rel->reltarget->exprs, 1, &appinfo); + /* Copy notnullattrs. */ + while ((i = bms_next_member(rel->notnullattrs, i)) > 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + AttrNumber child_attno; + if (attno == 0) + { + /* Whole row is not null, so must be same for child */ + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + attno - FirstLowInvalidHeapAttributeNumber); + break; + } + if (attno < 0 ) + /* no need to translate system column */ + child_attno = attno; + else + { + Node * node = list_nth(appinfo->translated_vars, attno - 1); + if (!IsA(node, Var)) + /* This may happens at UNION case, like (SELECT a FROM t1 UNION SELECT a + 3 + * FROM t2) t and we know t.a is not null + */ + continue; + child_attno = castNode(Var, node)->varattno; + } + + childrel->notnullattrs = bms_add_member(childrel->notnullattrs, + child_attno - FirstLowInvalidHeapAttributeNumber); + } + /* * We have to make child entries in the EquivalenceClass data * structures as well. This is needed either if the parent diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index 02f813cebd..d27167dc76 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -829,6 +829,16 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, { Node *qual = (Node *) lfirst(l); + /* Set the not null info now */ + ListCell *lc; + List *non_nullable_vars = find_nonnullable_vars(qual); + foreach(lc, non_nullable_vars) + { + Var *var = lfirst_node(Var, lc); + RelOptInfo *rel = root->simple_rel_array[var->varno]; + rel->notnullattrs = bms_add_member(rel->notnullattrs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } distribute_qual_to_rels(root, qual, below_outer_join, JOIN_INNER, root->qual_security_level, diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index c5947fa418..eebabcfccf 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -117,6 +117,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + int i; /* * We need not lock the relation since it was already locked, either by @@ -480,6 +481,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + Assert(rel->notnullattrs == NULL); + for(i = 0; i < relation->rd_att->natts; i++) + { + FormData_pg_attribute attr = relation->rd_att->attrs[i]; + if (attr.attnotnull) + rel->notnullattrs = bms_add_member(rel->notnullattrs, + attr.attnum - FirstLowInvalidHeapAttributeNumber); + } + table_close(relation, NoLock); /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 86405a274e..0d61f04d27 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -718,6 +718,8 @@ typedef struct RelOptInfo int rel_parallel_workers; /* wanted number of parallel workers */ uint32 amflags; /* Bitmask of optional features supported by * the table AM */ + /* Not null attrs, start from -FirstLowInvalidHeapAttributeNumber */ + Bitmapset *notnullattrs; /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ -- 2.26.2 --yh7cw345mbttadjz Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v38-0002-Introduce-UniqueKey-attributes-on-RelOptInfo-str.patch" ^ permalink raw reply [nested|flat] 47+ messages in thread
end of thread, other threads:[~2020-05-03 14:37 UTC | newest] Thread overview: 47+ messages (download: mbox mbox.gz follow: Atom feed) -- links below jump to the message on this page -- 2020-05-03 14:37 [PATCH v36 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v36 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v36 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v36 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v36 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v36 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v37 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v36 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v36 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v36 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v36 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v36 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v36 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH 01/10] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH 01/10] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v36 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v35 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v36 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v36 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v36 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v36 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v36 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v36 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]> 2020-05-03 14:37 [PATCH v38 1/6] Introduce RelOptInfo->notnullattrs attribute 一挃 <[email protected]>
This inbox is served by agora; see mirroring instructions for how to clone and mirror all data and code used for this inbox