| 1002 | } |
| 1003 | |
| 1004 | static Node * |
| 1005 | transformAExprDistinct(ParseState *pstate, A_Expr *a) |
| 1006 | { |
| 1007 | Node *lexpr = a->lexpr; |
| 1008 | Node *rexpr = a->rexpr; |
| 1009 | Node *result; |
| 1010 | |
| 1011 | /* |
| 1012 | * If either input is an undecorated NULL literal, transform to a NullTest |
| 1013 | * on the other input. That's simpler to process than a full DistinctExpr, |
| 1014 | * and it avoids needing to require that the datatype have an = operator. |
| 1015 | */ |
| 1016 | if (exprIsNullConstant(rexpr)) |
| 1017 | return make_nulltest_from_distinct(pstate, a, lexpr); |
| 1018 | if (exprIsNullConstant(lexpr)) |
| 1019 | return make_nulltest_from_distinct(pstate, a, rexpr); |
| 1020 | |
| 1021 | lexpr = transformExprRecurse(pstate, lexpr); |
| 1022 | rexpr = transformExprRecurse(pstate, rexpr); |
| 1023 | |
| 1024 | if (lexpr && IsA(lexpr, RowExpr) && |
| 1025 | rexpr && IsA(rexpr, RowExpr)) |
| 1026 | { |
| 1027 | /* ROW() op ROW() is handled specially */ |
| 1028 | result = make_row_distinct_op(pstate, a->name, |
| 1029 | (RowExpr *) lexpr, |
| 1030 | (RowExpr *) rexpr, |
| 1031 | a->location); |
| 1032 | } |
| 1033 | else |
| 1034 | { |
| 1035 | /* Ordinary scalar operator */ |
| 1036 | result = (Node *) make_distinct_op(pstate, |
| 1037 | a->name, |
| 1038 | lexpr, |
| 1039 | rexpr, |
| 1040 | a->location); |
| 1041 | } |
| 1042 | |
| 1043 | /* |
| 1044 | * If it's NOT DISTINCT, we first build a DistinctExpr and then stick a |
| 1045 | * NOT on top. |
| 1046 | */ |
| 1047 | if (a->kind == AEXPR_NOT_DISTINCT) |
| 1048 | result = (Node *) makeBoolExpr(NOT_EXPR, |
| 1049 | list_make1(result), |
| 1050 | a->location); |
| 1051 | |
| 1052 | return result; |
| 1053 | } |
| 1054 | |
| 1055 | static Node * |
| 1056 | transformAExprNullIf(ParseState *pstate, A_Expr *a) |
no test coverage detected