1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.tikv.common.expression;
19
20 import com.google.common.collect.ImmutableList;
21 import com.google.common.primitives.UnsignedLong;
22 import java.math.BigDecimal;
23 import java.sql.Date;
24 import java.sql.Timestamp;
25 import java.util.List;
26 import java.util.Objects;
27 import org.joda.time.DateTime;
28 import org.tikv.common.exception.TiExpressionException;
29 import org.tikv.common.types.*;
30
31
32
33
34 public class Constant extends Expression {
35 private final Object value;
36 private final BigDecimal UNSIGNED_LONG_MAX =
37 new BigDecimal(UnsignedLong.fromLongBits(-1).toString());
38
39 public Constant(Object value, DataType type) {
40 this.value = value;
41 this.dataType = (type == null && value != null) ? getDefaultType(value) : type;
42 this.resolved = true;
43 }
44
45 public static Constant create(Object value, DataType type) {
46 return new Constant(value, type);
47 }
48
49 @Deprecated
50 public static Constant create(Object value) {
51 return new Constant(value, null);
52 }
53
54 protected static boolean isIntegerType(Object value) {
55 return value instanceof Long
56 || value instanceof Integer
57 || value instanceof Short
58 || value instanceof Byte;
59 }
60
61 private static DataType getDefaultType(Object value) {
62 if (value == null) {
63 throw new TiExpressionException("NULL constant has no type");
64 } else if (isIntegerType(value)) {
65 return IntegerType.BIGINT;
66 } else if (value instanceof String) {
67 return StringType.VARCHAR;
68 } else if (value instanceof Float) {
69 return RealType.FLOAT;
70 } else if (value instanceof Double) {
71 return RealType.DOUBLE;
72 } else if (value instanceof BigDecimal) {
73 int prec = ((BigDecimal) value).precision();
74 int frac = ((BigDecimal) value).scale();
75 return new DecimalType(prec, frac);
76 } else if (value instanceof DateTime) {
77 return DateTimeType.DATETIME;
78 } else if (value instanceof Date) {
79 return DateType.DATE;
80 } else if (value instanceof Timestamp) {
81 return TimestampType.TIMESTAMP;
82 } else if (value instanceof byte[]) {
83 return BytesType.TEXT;
84 } else {
85 throw new TiExpressionException(
86 "Constant type not supported:" + value.getClass().getSimpleName());
87 }
88 }
89
90 public void setType(DataType type) {
91 this.dataType = type;
92 }
93
94 public Object getValue() {
95 return value;
96 }
97
98 @Override
99 public String toString() {
100 if (value == null) {
101 return "null";
102 }
103 if (value instanceof String) {
104 return String.format("\"%s\"", value);
105 }
106 return value.toString();
107 }
108
109 @Override
110 public boolean equals(Object other) {
111 if (other instanceof Constant) {
112 return Objects.equals(value, ((Constant) other).value);
113 }
114 return false;
115 }
116
117 @Override
118 public int hashCode() {
119 return Objects.hashCode(value);
120 }
121
122 @Override
123 public List<Expression> getChildren() {
124 return ImmutableList.of();
125 }
126
127 @Override
128 public <R, C> R accept(Visitor<R, C> visitor, C context) {
129 return visitor.visit(this, context);
130 }
131
132 public boolean isOverflowed() {
133 if (this.dataType instanceof IntegerType) {
134 if (((IntegerType) this.dataType).isUnsignedLong()) {
135 return ((BigDecimal) value).min(UNSIGNED_LONG_MAX).signum() > 0
136 || ((BigDecimal) value).signum() < 0;
137 }
138 }
139 return false;
140 }
141 }