Skip to content

Commit ee54713

Browse files
authored
Merge pull request #634 from m-dzianishchyts/CAY-2891-negate-null
CAY-2891 Handle `-null` expression
2 parents 33f8132 + 2423eb5 commit ee54713

File tree

3 files changed

+49
-2
lines changed

3 files changed

+49
-2
lines changed

cayenne/src/main/java/org/apache/cayenne/access/translator/select/QualifierTranslator.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,11 @@ private Node expressionNodeToSqlNode(Expression node, Expression parentNode) {
214214
case GREATER_THAN_EQUAL_TO:
215215
return new OpExpressionNode(expToStr(node.getType()));
216216
case NEGATIVE:
217+
// If operand is a scalar null, produce NULL directly (no unary minus)
218+
if (node.getOperandCount() > 0 && node.getOperand(0) == null) {
219+
expressionsToSkip.add(node);
220+
return new ValueNode(null, false, null, false);
221+
}
217222
// we need to add minus sign as a prefix, not a separator
218223
return new FunctionNode(expToStr(node.getType()), null, false);
219224
case TRUE:

cayenne/src/test/java/org/apache/cayenne/access/translator/select/QualifierTranslatorTest.java

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.junit.Test;
3535

3636
import java.util.Arrays;
37+
import java.util.Collections;
3738
import java.util.List;
3839

3940
import static org.hamcrest.CoreMatchers.instanceOf;
@@ -158,6 +159,39 @@ public void translateBetween() {
158159
}
159160
}
160161

162+
@Test
163+
public void translateNegate_NullScalar() {
164+
Node node = translate("-(null)");
165+
assertThat(node, instanceOf(ValueNode.class));
166+
assertNull(((ValueNode) node).getValue());
167+
168+
SQLGenerationVisitor visitor = new SQLGenerationVisitor(new StringBuilderAppendable());
169+
node.visit(visitor);
170+
assertEquals(" NULL", visitor.getSQLString());
171+
}
172+
173+
@Test
174+
public void translateNegate_NumberScalar() {
175+
Node node = translate("-1");
176+
assertThat(node, instanceOf(FunctionNode.class));
177+
178+
SQLGenerationVisitor visitor = new SQLGenerationVisitor(new StringBuilderAppendable());
179+
node.visit(visitor);
180+
assertEquals(" - 1", visitor.getSQLString());
181+
}
182+
183+
@Test
184+
public void translateNegate_NullParam() {
185+
Expression exp = ExpressionFactory.exp("-$v").params(Collections.singletonMap("v", null));
186+
Node node = translator.translate(exp);
187+
assertThat(node, instanceOf(ValueNode.class));
188+
assertNull(((ValueNode) node).getValue());
189+
190+
SQLGenerationVisitor visitor = new SQLGenerationVisitor(new StringBuilderAppendable());
191+
node.visit(visitor);
192+
assertEquals(" NULL", visitor.getSQLString());
193+
}
194+
161195
@Test
162196
public void translateNot() {
163197
Node not = translate("not true");
@@ -587,4 +621,4 @@ private Node translate(String s) {
587621
return translator.translate(ExpressionFactory.exp(s));
588622
}
589623

590-
}
624+
}

cayenne/src/test/java/org/apache/cayenne/exp/parser/ASTNegateTest.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,12 @@ public void testParse() {
3838
assertEquals("-1", exp.toString());
3939
}
4040

41-
}
41+
@Test
42+
public void testEvaluate_null() {
43+
ASTNegate negate = new ASTNegate();
44+
negate.setOperand(0, new ASTScalar(null));
45+
46+
Object result = negate.evaluate(null);
47+
assertNull(result);
48+
}
49+
}

0 commit comments

Comments
 (0)