(Context<?> ctx)
| 137 | } |
| 138 | |
| 139 | @Override |
| 140 | public final void accept(Context<?> ctx) { |
| 141 | |
| 142 | // [#3511] These dialects need to emulate the IS DISTINCT FROM predicate, |
| 143 | // optimally using INTERSECT... |
| 144 | // [#7222] [#7224] Make sure the columns are aliased |
| 145 | // [#10178] Special treatment for DISTINCT with subqueries |
| 146 | if (EMULATE_DISTINCT.contains(ctx.dialect()) || rhsSelect != null && EMULATE_DISTINCT_SELECT.contains(ctx.dialect())) { |
| 147 | Select<Record> intersect = select(lhs.fields()).intersect(rhsSelect != null ? rhsSelect : select(rhsRow.fields())); |
| 148 | ctx.visit(not ? exists(intersect) : notExists(intersect)); |
| 149 | } |
| 150 | |
| 151 | // [#17057] When INTERSECT isn't available, just use UNION with OFFSET |
| 152 | else if (EMULATE_WITH_UNION.contains(ctx.dialect())) { |
| 153 | Select<Record> union = select(lhs.fields()).union(rhsSelect != null ? rhsSelect : select(rhsRow.fields())).offset(one()); |
| 154 | ctx.visit(not ? notExists(union) : exists(union)); |
| 155 | } |
| 156 | |
| 157 | // MySQL knows the <=> operator |
| 158 | else if (SUPPORT_DISTINCT_WITH_ARROW.contains(ctx.dialect())) { |
| 159 | if (!not) |
| 160 | ctx.visit(K_NOT).sql('('); |
| 161 | |
| 162 | ctx.visit(lhs).sql(" <=> "); |
| 163 | |
| 164 | if (rhsRow != null) |
| 165 | ctx.visit(rhsRow); |
| 166 | else |
| 167 | visitSubquery(ctx, rhsSelect, PREDICAND); |
| 168 | |
| 169 | if (!not) |
| 170 | ctx.sql(')'); |
| 171 | } |
| 172 | |
| 173 | else if (EMULATE_WITH_ARRAYS.contains(ctx.dialect())) { |
| 174 | ctx.visit( |
| 175 | function(N_arrayUniq, INTEGER, |
| 176 | array( |
| 177 | lhs, |
| 178 | rhsRow != null ? rhsRow : CustomField.of(NQ_SELECT, SQLDataType.RECORD, c -> visitSubquery(c, rhsSelect, PREDICAND)) |
| 179 | ) |
| 180 | ).eq(inline(not ? 1 : 2)) |
| 181 | ); |
| 182 | } |
| 183 | |
| 184 | // SQLite knows the IS / IS NOT predicate |
| 185 | else if (SQLITE == ctx.family()) { |
| 186 | ctx.visit(lhs).sql(' ').visit(K_IS).sql(' '); |
| 187 | |
| 188 | if (!not) |
| 189 | ctx.visit(K_NOT).sql(' '); |
| 190 | |
| 191 | if (rhsRow != null) |
| 192 | ctx.visit(rhsRow); |
| 193 | else |
| 194 | visitSubquery(ctx, rhsSelect, PREDICAND); |
| 195 | } |
| 196 |
nothing calls this directly
no test coverage detected