View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.extended;
19  
20  import com.google.common.base.Preconditions;
21  import lombok.Getter;
22  import lombok.RequiredArgsConstructor;
23  import org.apache.shardingsphere.db.protocol.binary.BinaryColumnType;
24  import org.apache.shardingsphere.db.protocol.postgresql.exception.PostgreSQLProtocolException;
25  import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.extended.bind.protocol.text.PostgreSQLTextValueParser;
26  import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.extended.bind.protocol.text.impl.PostgreSQLBitValueParser;
27  import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.extended.bind.protocol.text.impl.PostgreSQLBoolValueParser;
28  import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.extended.bind.protocol.text.impl.PostgreSQLDateValueParser;
29  import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.extended.bind.protocol.text.impl.PostgreSQLDoubleValueParser;
30  import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.extended.bind.protocol.text.impl.PostgreSQLFloatValueParser;
31  import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.extended.bind.protocol.text.impl.PostgreSQLIntValueParser;
32  import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.extended.bind.protocol.text.impl.PostgreSQLJsonValueParser;
33  import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.extended.bind.protocol.text.impl.PostgreSQLLongValueParser;
34  import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.extended.bind.protocol.text.impl.PostgreSQLNumericValueParser;
35  import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.extended.bind.protocol.text.impl.PostgreSQLTextArrayValueParser;
36  import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.extended.bind.protocol.text.impl.PostgreSQLTimeValueParser;
37  import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.extended.bind.protocol.text.impl.PostgreSQLTimestampValueParser;
38  import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.extended.bind.protocol.text.impl.PostgreSQLUnspecifiedValueParser;
39  import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.extended.bind.protocol.text.impl.PostgreSQLVarcharArrayValueParser;
40  import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.extended.bind.protocol.text.impl.PostgreSQLVarcharValueParser;
41  
42  import java.sql.Types;
43  import java.util.HashMap;
44  import java.util.Map;
45  
46  /**
47   * Column type for PostgreSQL.
48   */
49  @RequiredArgsConstructor
50  @Getter
51  public enum PostgreSQLColumnType implements BinaryColumnType {
52      
53      UNSPECIFIED(0, new PostgreSQLUnspecifiedValueParser()),
54      
55      INT2(21, new PostgreSQLIntValueParser()),
56      
57      INT2_ARRAY(1005, new PostgreSQLVarcharValueParser()),
58      
59      INT4(23, new PostgreSQLIntValueParser()),
60      
61      INT4_ARRAY(1007, new PostgreSQLVarcharValueParser()),
62      
63      INT8(20, new PostgreSQLLongValueParser()),
64      
65      INT8_ARRAY(1016, new PostgreSQLVarcharValueParser()),
66      
67      TEXT(25, new PostgreSQLVarcharValueParser()),
68      
69      TEXT_ARRAY(1009, new PostgreSQLTextArrayValueParser()),
70      
71      NUMERIC(1700, new PostgreSQLNumericValueParser()),
72      
73      NUMERIC_ARRAY(1231, new PostgreSQLVarcharValueParser()),
74      
75      FLOAT4(700, new PostgreSQLFloatValueParser()),
76      
77      FLOAT4_ARRAY(1021, new PostgreSQLVarcharValueParser()),
78      
79      FLOAT8(701, new PostgreSQLDoubleValueParser()),
80      
81      FLOAT8_ARRAY(1022, new PostgreSQLVarcharValueParser()),
82      
83      BOOL(16, new PostgreSQLBoolValueParser()),
84      
85      BOOL_ARRAY(1000, new PostgreSQLVarcharValueParser()),
86      
87      DATE(1082, new PostgreSQLDateValueParser()),
88      
89      DATE_ARRAY(1182, new PostgreSQLVarcharValueParser()),
90      
91      TIME(1083, new PostgreSQLTimeValueParser()),
92      
93      TIME_ARRAY(1183, new PostgreSQLVarcharValueParser()),
94      
95      TIMETZ(1266, new PostgreSQLTimeValueParser()),
96      
97      TIMETZ_ARRAY(1270, new PostgreSQLVarcharValueParser()),
98      
99      TIMESTAMP(1114, new PostgreSQLTimestampValueParser()),
100     
101     TIMESTAMP_ARRAY(1115, new PostgreSQLVarcharValueParser()),
102     
103     TIMESTAMPTZ(1184, new PostgreSQLTimestampValueParser()),
104     
105     TIMESTAMPTZ_ARRAY(1185, new PostgreSQLVarcharValueParser()),
106     
107     BYTEA(17, new PostgreSQLVarcharValueParser()),
108     
109     BYTEA_ARRAY(1001, new PostgreSQLVarcharValueParser()),
110     
111     VARCHAR(1043, new PostgreSQLVarcharValueParser()),
112     
113     VARCHAR_ARRAY(1015, new PostgreSQLVarcharArrayValueParser()),
114     
115     OID(26, new PostgreSQLVarcharValueParser()),
116     
117     OID_ARRAY(1028, new PostgreSQLVarcharValueParser()),
118     
119     BPCHAR(1042, new PostgreSQLVarcharValueParser()),
120     
121     BPCHAR_ARRAY(1014, new PostgreSQLVarcharValueParser()),
122     
123     MONEY(790, new PostgreSQLVarcharValueParser()),
124     
125     MONEY_ARRAY(791, new PostgreSQLVarcharValueParser()),
126     
127     NAME(19, new PostgreSQLVarcharValueParser()),
128     
129     NAME_ARRAY(1003, new PostgreSQLVarcharValueParser()),
130     
131     BIT(1560, new PostgreSQLBitValueParser()),
132     
133     BIT_ARRAY(1561, new PostgreSQLVarcharValueParser()),
134     
135     VOID(2278, new PostgreSQLVarcharValueParser()),
136     
137     INTERVAL(1186, new PostgreSQLVarcharValueParser()),
138     
139     INTERVAL_ARRAY(1187, new PostgreSQLVarcharValueParser()),
140     
141     CHAR(18, new PostgreSQLVarcharValueParser()),
142     
143     CHAR_ARRAY(1002, new PostgreSQLVarcharValueParser()),
144     
145     VARBIT(1562, new PostgreSQLVarcharValueParser()),
146     
147     VARBIT_ARRAY(1563, new PostgreSQLVarcharValueParser()),
148     
149     UUID(2950, new PostgreSQLVarcharValueParser()),
150     
151     UUID_ARRAY(2951, new PostgreSQLVarcharValueParser()),
152     
153     XML(142, new PostgreSQLVarcharValueParser()),
154     
155     XML_ARRAY(143, new PostgreSQLVarcharValueParser()),
156     
157     POINT(600, new PostgreSQLVarcharValueParser()),
158     
159     POINT_ARRAY(1017, new PostgreSQLVarcharValueParser()),
160     
161     BOX(603, new PostgreSQLVarcharValueParser()),
162     
163     JSONB_ARRAY(3807, new PostgreSQLVarcharValueParser()),
164     
165     JSON(114, new PostgreSQLJsonValueParser()),
166     
167     JSON_ARRAY(199, new PostgreSQLVarcharValueParser()),
168     
169     REF_CURSOR(1790, new PostgreSQLVarcharValueParser()),
170     
171     REF_CURSOR_ARRAY(2201, new PostgreSQLVarcharValueParser());
172     
173     private static final Map<Integer, PostgreSQLColumnType> JDBC_TYPE_AND_COLUMN_TYPE_MAP = new HashMap<>(values().length, 1F);
174     
175     private final int value;
176     
177     private final PostgreSQLTextValueParser<?> textValueParser;
178     
179     static {
180         JDBC_TYPE_AND_COLUMN_TYPE_MAP.put(Types.TINYINT, INT2);
181         JDBC_TYPE_AND_COLUMN_TYPE_MAP.put(Types.SMALLINT, INT2);
182         JDBC_TYPE_AND_COLUMN_TYPE_MAP.put(Types.INTEGER, INT4);
183         JDBC_TYPE_AND_COLUMN_TYPE_MAP.put(Types.BIGINT, INT8);
184         JDBC_TYPE_AND_COLUMN_TYPE_MAP.put(Types.NUMERIC, NUMERIC);
185         JDBC_TYPE_AND_COLUMN_TYPE_MAP.put(Types.DECIMAL, NUMERIC);
186         JDBC_TYPE_AND_COLUMN_TYPE_MAP.put(Types.REAL, FLOAT4);
187         JDBC_TYPE_AND_COLUMN_TYPE_MAP.put(Types.DOUBLE, FLOAT8);
188         JDBC_TYPE_AND_COLUMN_TYPE_MAP.put(Types.CHAR, CHAR);
189         JDBC_TYPE_AND_COLUMN_TYPE_MAP.put(Types.VARCHAR, VARCHAR);
190         JDBC_TYPE_AND_COLUMN_TYPE_MAP.put(Types.BINARY, BYTEA);
191         JDBC_TYPE_AND_COLUMN_TYPE_MAP.put(Types.BIT, BIT);
192         JDBC_TYPE_AND_COLUMN_TYPE_MAP.put(Types.DATE, DATE);
193         JDBC_TYPE_AND_COLUMN_TYPE_MAP.put(Types.TIME, TIME);
194         JDBC_TYPE_AND_COLUMN_TYPE_MAP.put(Types.TIMESTAMP, TIMESTAMP);
195         JDBC_TYPE_AND_COLUMN_TYPE_MAP.put(Types.OTHER, JSON);
196         JDBC_TYPE_AND_COLUMN_TYPE_MAP.put(Types.SQLXML, XML);
197         JDBC_TYPE_AND_COLUMN_TYPE_MAP.put(Types.BOOLEAN, BOOL);
198         // TODO Temporary solution for https://github.com/apache/shardingsphere/issues/22522
199         JDBC_TYPE_AND_COLUMN_TYPE_MAP.put(Types.STRUCT, VARCHAR);
200         JDBC_TYPE_AND_COLUMN_TYPE_MAP.put(Types.ARRAY, TEXT_ARRAY);
201     }
202     
203     /**
204      * Value of JDBC type.
205      *
206      * @param jdbcType JDBC type
207      * @return PostgreSQL column type enum
208      */
209     public static PostgreSQLColumnType valueOfJDBCType(final int jdbcType) {
210         Preconditions.checkArgument(JDBC_TYPE_AND_COLUMN_TYPE_MAP.containsKey(jdbcType), "Can not find JDBC type `%s` in PostgreSQL column type", jdbcType);
211         return JDBC_TYPE_AND_COLUMN_TYPE_MAP.get(jdbcType);
212     }
213     
214     /**
215      * Value of JDBC type.
216      *
217      * @param jdbcType JDBC type
218      * @param columnTypeName column type name
219      * @return PostgreSQL column type enum
220      */
221     public static PostgreSQLColumnType valueOfJDBCType(final int jdbcType, final String columnTypeName) {
222         if (isBit(jdbcType, columnTypeName)) {
223             return BIT;
224         }
225         if (isBool(jdbcType, columnTypeName)) {
226             return BOOL;
227         }
228         if (isUUID(jdbcType, columnTypeName)) {
229             return UUID;
230         }
231         return valueOfJDBCType(jdbcType);
232     }
233     
234     /**
235      * Check if pg PostgreSQL type.
236      *
237      * @param jdbcType JDBC type
238      * @param columnTypeName column type name
239      * @return whether is PostgreSQL bit
240      */
241     public static boolean isBit(final int jdbcType, final String columnTypeName) {
242         return Types.BIT == jdbcType && "bit".equalsIgnoreCase(columnTypeName);
243     }
244     
245     /**
246      * Check if PostgreSQL bit type.
247      *
248      * @param jdbcType JDBC type
249      * @param columnTypeName column type name
250      * @return whether is PostgreSQL bit
251      */
252     public static boolean isBool(final int jdbcType, final String columnTypeName) {
253         return Types.BIT == jdbcType && "bool".equalsIgnoreCase(columnTypeName);
254     }
255     
256     /**
257      * Check if PostgreSQL is UUID type.
258      *
259      * @param jdbcType JDBC type
260      * @param columnTypeName column type name
261      * @return whether it is PostgreSQL UUID
262      */
263     public static boolean isUUID(final int jdbcType, final String columnTypeName) {
264         return Types.OTHER == jdbcType && "uuid".equalsIgnoreCase(columnTypeName);
265     }
266     
267     /**
268      * Value of.
269      *
270      * @param value value
271      * @return PostgreSQL column type
272      * @throws PostgreSQLProtocolException PostgreSQL protocol exception
273      */
274     public static PostgreSQLColumnType valueOf(final int value) {
275         for (PostgreSQLColumnType each : values()) {
276             if (value == each.value) {
277                 return each;
278             }
279         }
280         throw new PostgreSQLProtocolException("Can not find value `%s` in PostgreSQL column type.", value);
281     }
282 }