* create_unique_rowid_path (GPDB) * * Create a UniquePath to deduplicate based on a RowIdExp column. This is * used as part of implementing semi-joins (such as "x IN (SELECT ...)"). * * In PostgreSQL, semi-joins are implemented with JOIN_SEMI join types, or * by first eliminating duplicates from the inner side, and then performing * normal inner join (that's JOIN_UNIQUE_OUTER and JOIN_UNIQU
| 2698 | * the real work for create_plan(). |
| 2699 | */ |
| 2700 | UniquePath * |
| 2701 | create_unique_rowid_path(PlannerInfo *root, |
| 2702 | RelOptInfo *rel, |
| 2703 | Path *subpath, |
| 2704 | Relids required_outer, |
| 2705 | int rowidexpr_id) |
| 2706 | { |
| 2707 | UniquePath *pathnode; |
| 2708 | CdbPathLocus locus; |
| 2709 | Path sort_path; /* dummy for result of cost_sort */ |
| 2710 | Path agg_path; /* dummy for result of cost_agg */ |
| 2711 | int numCols; |
| 2712 | bool all_btree; |
| 2713 | bool all_hash; |
| 2714 | double numsegments; |
| 2715 | |
| 2716 | Assert(rowidexpr_id > 0); |
| 2717 | |
| 2718 | /* |
| 2719 | * For easier merging (albeit it's going to manual), keep this function |
| 2720 | * similar to create_unique_path(). In this function, we deduplicate based |
| 2721 | * on RowIdExpr that we generate on the fly. Sorting and hashing are both |
| 2722 | * possible, but we keep these as variables to resemble |
| 2723 | * create_unique_path(). |
| 2724 | */ |
| 2725 | all_btree = true; |
| 2726 | all_hash = enable_hashagg; /* don't consider hash if not enabled */ |
| 2727 | |
| 2728 | RowIdExpr *rowidexpr = makeNode(RowIdExpr); |
| 2729 | rowidexpr->rowidexpr_id = rowidexpr_id; |
| 2730 | |
| 2731 | subpath->pathtarget = copy_pathtarget(subpath->pathtarget); |
| 2732 | add_column_to_pathtarget(subpath->pathtarget, (Expr *) rowidexpr, 0); |
| 2733 | |
| 2734 | /* Repartition first if duplicates might be on different QEs. */ |
| 2735 | if (!CdbPathLocus_IsBottleneck(subpath->locus)) |
| 2736 | { |
| 2737 | int numsegments = CdbPathLocus_NumSegments(subpath->locus); |
| 2738 | |
| 2739 | locus = cdbpathlocus_from_exprs(root, |
| 2740 | subpath->parent, |
| 2741 | list_make1(rowidexpr), |
| 2742 | list_make1_oid(cdb_default_distribution_opfamily_for_type(INT8OID)), |
| 2743 | list_make1_int(0), |
| 2744 | numsegments, |
| 2745 | subpath->parallel_workers); |
| 2746 | subpath = cdbpath_create_motion_path(root, subpath, NIL, false, locus); |
| 2747 | if (!subpath) |
| 2748 | return NULL; |
| 2749 | |
| 2750 | /* |
| 2751 | * The motion path has been created correctly, but there's a little |
| 2752 | * problem with the locus. The locus has RowIdExpr as the distribution |
| 2753 | * key, but because there are no Vars in it, the EC machinery will |
| 2754 | * consider it a pseudo-constant. We don't want that, as it would |
| 2755 | * mean that all rows were considered to live on the same segment, |
| 2756 | * which is not how this works. Therefore set the locus of the Unique |
| 2757 | * path to Strewn, which doesn't have that problem. No node above the |
no test coverage detected