blob: c128271e633ec6060c65177fd34439f273affa38 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.carbondata.core.metadata.schema.table;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import org.apache.carbondata.common.exceptions.sql.MalformedIndexCommandException;
import org.apache.carbondata.core.metadata.schema.index.IndexProperty;
import static org.apache.carbondata.core.constants.CarbonCommonConstants.INDEX_COLUMNS;
import com.google.gson.annotations.SerializedName;
import org.apache.commons.lang.StringUtils;
/**
* It is the new schema of index and it has less fields compare to {{@link IndexSchema}}
*/
public class IndexSchema implements Serializable, Writable {
private static final long serialVersionUID = -8394577999061329687L;
protected String indexName;
/**
* Cg and Fg Index: provider name is class name of implementation class of IndexFactory
*/
// the old version the field name for providerName was className, so to de-serialization
// old schema provided the old field name in the alternate filed using annotation
@SerializedName(value = "providerName", alternate = "className")
protected String providerName;
/**
* For MV, this is the identifier of the MV table.
* For Index, this is the identifier of the main table.
*/
protected RelationIdentifier relationIdentifier;
/**
* Properties provided by user
*/
protected Map<String, String> properties;
/**
* child table schema
*/
protected TableSchema childSchema;
public IndexSchema(String indexName, String providerName) {
this.indexName = indexName;
this.providerName = providerName;
}
public IndexSchema() {
}
public String getIndexName() {
return indexName;
}
public void setIndexName(String indexName) {
this.indexName = indexName;
}
public String getProviderName() {
return providerName;
}
public RelationIdentifier getRelationIdentifier() {
return relationIdentifier;
}
public void setRelationIdentifier(RelationIdentifier relationIdentifier) {
this.relationIdentifier = relationIdentifier;
}
public Map<String, String> getProperties() {
return properties;
}
public void setProperties(Map<String, String> properties) {
this.properties = properties;
}
/**
* Return true if this is an Index
* @return
*/
public boolean isIndex() {
return true;
}
/**
* Return true if this index is lazy (created with DEFERRED REBUILD syntax)
*/
public boolean isLazy() {
String deferredRebuild = getProperties().get(IndexProperty.DEFERRED_REBUILD);
return deferredRebuild != null && deferredRebuild.equalsIgnoreCase("true");
}
@Override
public void write(DataOutput out) throws IOException {
out.writeUTF(indexName);
out.writeUTF(providerName);
boolean isRelationIdentifierExists = null != relationIdentifier;
out.writeBoolean(isRelationIdentifierExists);
if (isRelationIdentifierExists) {
this.relationIdentifier.write(out);
}
boolean isChildSchemaExists = null != this.childSchema;
out.writeBoolean(isChildSchemaExists);
if (isChildSchemaExists) {
this.childSchema.write(out);
}
if (properties == null) {
out.writeShort(0);
} else {
out.writeShort(properties.size());
for (Map.Entry<String, String> entry : properties.entrySet()) {
out.writeUTF(entry.getKey());
out.writeUTF(entry.getValue());
}
}
}
@Override
public void readFields(DataInput in) throws IOException {
this.indexName = in.readUTF();
this.providerName = in.readUTF();
boolean isRelationIdentifierExists = in.readBoolean();
if (isRelationIdentifierExists) {
this.relationIdentifier = new RelationIdentifier(null, null, null);
this.relationIdentifier.readFields(in);
}
boolean isChildSchemaExists = in.readBoolean();
if (isChildSchemaExists) {
this.childSchema = new TableSchema();
this.childSchema.readFields(in);
}
int mapSize = in.readShort();
this.properties = new HashMap<>(mapSize);
for (int i = 0; i < mapSize; i++) {
String key = in.readUTF();
String value = in.readUTF();
this.properties.put(key, value);
}
}
/**
* Return the list of column name
*/
public String[] getIndexColumns()
throws MalformedIndexCommandException {
String columns = getProperties().get(INDEX_COLUMNS);
if (columns == null) {
columns = getProperties().get(INDEX_COLUMNS.toLowerCase());
}
if (columns == null) {
throw new MalformedIndexCommandException(INDEX_COLUMNS + " INDEXPROPERTY is required");
} else if (StringUtils.isBlank(columns)) {
throw new MalformedIndexCommandException(INDEX_COLUMNS + " INDEXPROPERTY is blank");
} else {
return columns.split(",", -1);
}
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
IndexSchema that = (IndexSchema) o;
return Objects.equals(indexName, that.indexName);
}
@Override
public int hashCode() {
return Objects.hash(indexName);
}
}