* MJExamineQuals * * This deconstructs the list of mergejoinable expressions, which is given * to us by the planner in the form of a list of "leftexpr = rightexpr" * expression trees in the order matching the sort columns of the inputs. * We build an array of MergeJoinClause structs containing the information * we will need at runtime. Each struct essentially tells us how to compare * the
| 187 | * predicate is (BoolExpr_NOT (DistinctExpr_= leftexpr rightexpr)). |
| 188 | */ |
| 189 | static MergeJoinClause |
| 190 | MJExamineQuals(List *mergeclauses, |
| 191 | Oid *mergefamilies, |
| 192 | Oid *mergecollations, |
| 193 | int *mergestrategies, |
| 194 | bool *mergenullsfirst, |
| 195 | PlanState *parent) |
| 196 | { |
| 197 | MergeJoinClause clauses; |
| 198 | int nClauses = list_length(mergeclauses); |
| 199 | int iClause; |
| 200 | ListCell *cl; |
| 201 | |
| 202 | clauses = (MergeJoinClause) palloc0(nClauses * sizeof(MergeJoinClauseData)); |
| 203 | |
| 204 | iClause = 0; |
| 205 | foreach(cl, mergeclauses) |
| 206 | { |
| 207 | OpExpr *qual = (OpExpr *) lfirst(cl); |
| 208 | MergeJoinClause clause = &clauses[iClause]; |
| 209 | Oid opfamily = mergefamilies[iClause]; |
| 210 | Oid collation = mergecollations[iClause]; |
| 211 | StrategyNumber opstrategy = mergestrategies[iClause]; |
| 212 | bool nulls_first = mergenullsfirst[iClause]; |
| 213 | int op_strategy; |
| 214 | Oid op_lefttype; |
| 215 | Oid op_righttype; |
| 216 | Oid sortfunc; |
| 217 | |
| 218 | if (!IsA(qual, OpExpr)) |
| 219 | { |
| 220 | BoolExpr *bx = (BoolExpr*)qual; |
| 221 | bool ok = false; |
| 222 | |
| 223 | if ( IsA(bx, BoolExpr) && bx->boolop == NOT_EXPR && list_length(bx->args) == 1 ) |
| 224 | { |
| 225 | DistinctExpr *dx = (DistinctExpr*)linitial(bx->args); |
| 226 | |
| 227 | if ( IsA(dx, DistinctExpr) ) |
| 228 | { |
| 229 | clause->notdistinct = true; |
| 230 | qual = (OpExpr *)dx; |
| 231 | ok = true; |
| 232 | } |
| 233 | } |
| 234 | if (!ok) |
| 235 | elog(ERROR, "mergejoin clause is not an OpExpr"); |
| 236 | } |
| 237 | |
| 238 | /* |
| 239 | * Prepare the input expressions for execution. |
| 240 | */ |
| 241 | clause->lexpr = ExecInitExpr((Expr *) linitial(qual->args), parent); |
| 242 | clause->rexpr = ExecInitExpr((Expr *) lsecond(qual->args), parent); |
| 243 | |
| 244 | /* Set up sort support data */ |
| 245 | clause->ssup.ssup_cxt = CurrentMemoryContext; |
| 246 | clause->ssup.ssup_collation = collation; |
no test coverage detected