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