View Javadoc
1   /*
2    * Copyright 2021 TiKV Project Authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   *
16   */
17  
18  package org.tikv.common.meta;
19  
20  import static java.util.Objects.requireNonNull;
21  
22  import com.fasterxml.jackson.annotation.JsonCreator;
23  import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
24  import com.fasterxml.jackson.annotation.JsonProperty;
25  import com.google.common.collect.ImmutableList;
26  import com.pingcap.tidb.tipb.TableInfo;
27  import java.io.Serializable;
28  import java.util.HashMap;
29  import java.util.List;
30  import java.util.Map;
31  import java.util.stream.Collectors;
32  import org.tikv.common.exception.TiClientInternalException;
33  import org.tikv.common.meta.TiColumnInfo.InternalTypeHolder;
34  import org.tikv.common.types.DataType;
35  import org.tikv.common.types.DataTypeFactory;
36  
37  @JsonIgnoreProperties(ignoreUnknown = true)
38  public class TiTableInfo implements Serializable {
39    private final long id;
40    private final String name;
41    private final String charset;
42    private final String collate;
43    private final List<org.tikv.common.meta.TiColumnInfo> columns;
44    private final Map<String, org.tikv.common.meta.TiColumnInfo> columnsMap;
45    private final List<org.tikv.common.meta.TiIndexInfo> indices;
46    private final boolean pkIsHandle;
47    private final String comment;
48    private final long autoIncId;
49    private final long maxColumnId;
50    private final long maxIndexId;
51    private final long oldSchemaId;
52    private final long rowSize; // estimated row size
53    private final org.tikv.common.meta.TiPartitionInfo partitionInfo;
54    private final org.tikv.common.meta.TiColumnInfo primaryKeyColumn;
55    private final TiViewInfo viewInfo;
56    private final TiFlashReplicaInfo tiflashReplicaInfo;
57    private final long version;
58    private final long updateTimestamp;
59    private final long maxShardRowIDBits;
60    private final org.tikv.common.meta.TiSequenceInfo sequenceInfo;
61  
62    @JsonCreator
63    @JsonIgnoreProperties(ignoreUnknown = true)
64    public TiTableInfo(
65        @JsonProperty("id") long id,
66        @JsonProperty("name") org.tikv.common.meta.CIStr name,
67        @JsonProperty("charset") String charset,
68        @JsonProperty("collate") String collate,
69        @JsonProperty("pk_is_handle") boolean pkIsHandle,
70        @JsonProperty("cols") List<org.tikv.common.meta.TiColumnInfo> columns,
71        @JsonProperty("index_info") List<org.tikv.common.meta.TiIndexInfo> indices,
72        @JsonProperty("comment") String comment,
73        @JsonProperty("auto_inc_id") long autoIncId,
74        @JsonProperty("max_col_id") long maxColumnId,
75        @JsonProperty("max_idx_id") long maxIndexId,
76        @JsonProperty("old_schema_id") long oldSchemaId,
77        @JsonProperty("partition") org.tikv.common.meta.TiPartitionInfo partitionInfo,
78        @JsonProperty("view") TiViewInfo viewInfo,
79        @JsonProperty("tiflash_replica") TiFlashReplicaInfo tiFlashReplicaInfo,
80        @JsonProperty("version") long version,
81        @JsonProperty("update_timestamp") long updateTimestamp,
82        @JsonProperty("max_shard_row_id_bits") long maxShardRowIDBits,
83        @JsonProperty("sequence") org.tikv.common.meta.TiSequenceInfo sequenceInfo) {
84      this.id = id;
85      this.name = name.getL();
86      this.charset = charset;
87      this.collate = collate;
88      if (sequenceInfo == null) {
89        this.columns = ImmutableList.copyOf(requireNonNull(columns, "columns is null"));
90        this.columnsMap = new HashMap<>();
91        for (org.tikv.common.meta.TiColumnInfo col : this.columns) {
92          this.columnsMap.put(col.getName(), col);
93        }
94        this.rowSize = columns.stream().mapToLong(org.tikv.common.meta.TiColumnInfo::getSize).sum();
95      } else {
96        this.columns = null;
97        this.columnsMap = null;
98        // 9 is the rowSize for type bigint
99        this.rowSize = 9;
100     }
101     // TODO: Use more precise predication according to types
102     this.pkIsHandle = pkIsHandle;
103     this.indices = indices != null ? ImmutableList.copyOf(indices) : ImmutableList.of();
104     if (this.columns != null) {
105       this.indices.forEach(x -> x.calculateIndexSize(columns));
106     }
107     this.comment = comment;
108     this.autoIncId = autoIncId;
109     this.maxColumnId = maxColumnId;
110     this.maxIndexId = maxIndexId;
111     this.oldSchemaId = oldSchemaId;
112     this.partitionInfo = partitionInfo;
113     this.viewInfo = viewInfo;
114     this.tiflashReplicaInfo = tiFlashReplicaInfo;
115     this.version = version;
116     this.updateTimestamp = updateTimestamp;
117     this.maxShardRowIDBits = maxShardRowIDBits;
118     this.sequenceInfo = sequenceInfo;
119 
120     org.tikv.common.meta.TiColumnInfo primaryKey = null;
121     if (sequenceInfo == null) {
122       for (org.tikv.common.meta.TiColumnInfo col : this.columns) {
123         if (col.isPrimaryKey()) {
124           primaryKey = col;
125           break;
126         }
127       }
128     }
129     primaryKeyColumn = primaryKey;
130   }
131 
132   public boolean isView() {
133     return this.viewInfo != null;
134   }
135 
136   public boolean isSequence() {
137     return this.sequenceInfo != null;
138   }
139 
140   // auto increment column must be a primary key column
141   public boolean hasAutoIncrementColumn() {
142     if (primaryKeyColumn != null) {
143       return primaryKeyColumn.isAutoIncrement();
144     }
145     return false;
146   }
147 
148   // auto increment column must be a primary key column
149   public org.tikv.common.meta.TiColumnInfo getAutoIncrementColInfo() {
150     if (hasAutoIncrementColumn()) {
151       return primaryKeyColumn;
152     }
153     return null;
154   }
155 
156   public boolean isAutoIncColUnsigned() {
157     org.tikv.common.meta.TiColumnInfo col = getAutoIncrementColInfo();
158     if (col == null) return false;
159     return col.getType().isUnsigned();
160   }
161 
162   public long getMaxShardRowIDBits() {
163     return this.maxShardRowIDBits;
164   }
165 
166   public long getId() {
167     return id;
168   }
169 
170   public String getName() {
171     return name;
172   }
173 
174   public String getCharset() {
175     return charset;
176   }
177 
178   public String getCollate() {
179     return collate;
180   }
181 
182   public List<org.tikv.common.meta.TiColumnInfo> getColumns() {
183     return columns;
184   }
185 
186   public long getEstimatedRowSizeInByte() {
187     return rowSize;
188   }
189 
190   public org.tikv.common.meta.TiColumnInfo getColumn(String name) {
191     return this.columnsMap.get(name.toLowerCase());
192   }
193 
194   public org.tikv.common.meta.TiColumnInfo getColumn(int offset) {
195     if (offset < 0 || offset >= columns.size()) {
196       throw new TiClientInternalException(String.format("Column offset %d out of bound", offset));
197     }
198     return columns.get(offset);
199   }
200 
201   public boolean isPkHandle() {
202     return pkIsHandle;
203   }
204 
205   public List<org.tikv.common.meta.TiIndexInfo> getIndices() {
206     return indices;
207   }
208 
209   public String getComment() {
210     return comment;
211   }
212 
213   private long getAutoIncId() {
214     return autoIncId;
215   }
216 
217   private long getMaxColumnId() {
218     return maxColumnId;
219   }
220 
221   private long getMaxIndexId() {
222     return maxIndexId;
223   }
224 
225   private long getOldSchemaId() {
226     return oldSchemaId;
227   }
228 
229   public org.tikv.common.meta.TiPartitionInfo getPartitionInfo() {
230     return partitionInfo;
231   }
232 
233   public TiFlashReplicaInfo getTiflashReplicaInfo() {
234     return tiflashReplicaInfo;
235   }
236 
237   TableInfo toProto() {
238     return TableInfo.newBuilder()
239         .setTableId(getId())
240         .addAllColumns(
241             getColumns().stream().map(col -> col.toProto(this)).collect(Collectors.toList()))
242         .build();
243   }
244 
245   public boolean hasPrimaryKey() {
246     return primaryKeyColumn != null;
247   }
248 
249   // Only Integer Column will be a PK column
250   // and there exists only one PK column
251   public org.tikv.common.meta.TiColumnInfo getPKIsHandleColumn() {
252     if (isPkHandle()) {
253       for (org.tikv.common.meta.TiColumnInfo col : getColumns()) {
254         if (col.isPrimaryKey()) {
255           return col;
256         }
257       }
258     }
259     return null;
260   }
261 
262   private org.tikv.common.meta.TiColumnInfo copyColumn(org.tikv.common.meta.TiColumnInfo col) {
263     DataType type = col.getType();
264     InternalTypeHolder typeHolder = type.toTypeHolder();
265     typeHolder.setFlag(type.getFlag() & (~DataType.PriKeyFlag));
266     DataType newType = DataTypeFactory.of(typeHolder);
267     return new org.tikv.common.meta.TiColumnInfo(
268             col.getId(),
269             col.getName(),
270             col.getOffset(),
271             newType,
272             col.getSchemaState(),
273             col.getOriginDefaultValue(),
274             col.getDefaultValue(),
275             col.getDefaultValueBit(),
276             col.getComment(),
277             col.getVersion(),
278             col.getGeneratedExprString())
279         .copyWithoutPrimaryKey();
280   }
281 
282   public TiTableInfo copyTableWithRowId() {
283     if (!isPkHandle()) {
284       ImmutableList.Builder<org.tikv.common.meta.TiColumnInfo> newColumns = ImmutableList.builder();
285       for (org.tikv.common.meta.TiColumnInfo col : getColumns()) {
286         newColumns.add(copyColumn(col));
287       }
288       newColumns.add(org.tikv.common.meta.TiColumnInfo.getRowIdColumn(getColumns().size()));
289       return new TiTableInfo(
290           getId(),
291           org.tikv.common.meta.CIStr.newCIStr(getName()),
292           getCharset(),
293           getCollate(),
294           true,
295           newColumns.build(),
296           getIndices(),
297           getComment(),
298           getAutoIncId(),
299           getMaxColumnId(),
300           getMaxIndexId(),
301           getOldSchemaId(),
302           partitionInfo,
303           null,
304           getTiflashReplicaInfo(),
305           version,
306           updateTimestamp,
307           maxShardRowIDBits,
308           null);
309     } else {
310       return this;
311     }
312   }
313 
314   @Override
315   public String toString() {
316     return toProto().toString();
317   }
318 
319   public boolean isPartitionEnabled() {
320     if (partitionInfo == null) return false;
321     return partitionInfo.isEnable();
322   }
323 
324   public boolean hasGeneratedColumn() {
325     for (org.tikv.common.meta.TiColumnInfo col : getColumns()) {
326       if (col.isGeneratedColumn()) {
327         return true;
328       }
329     }
330     return false;
331   }
332 
333   public long getVersion() {
334     return version;
335   }
336 
337   public long getUpdateTimestamp() {
338     return updateTimestamp;
339   }
340 }