blob: 387c669b5e0e7c7a443c05af4d59f1f52aff83ee [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.tajo.catalog;
import com.google.common.base.Function;
import org.apache.tajo.catalog.partition.PartitionMethodDesc;
import org.apache.tajo.catalog.proto.CatalogProtos.PartitionDescProto;
import org.apache.tajo.schema.IdentifierUtil;
import org.apache.tajo.util.KeyValueSet;
import org.apache.tajo.util.StringUtils;
import java.io.File;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Map.Entry;
public class DDLBuilder {
public static String buildDDLForExternalTable(TableDesc desc) {
StringBuilder sb = new StringBuilder();
sb.append("--\n")
.append("-- Name: ").append(IdentifierUtil.denormalizeIdentifier(desc.getName())).append("; Type: TABLE;")
.append(" Storage: ").append(desc.getMeta().getDataFormat());
sb.append("\n-- Path: ").append(desc.getUri());
sb.append("\n--\n");
sb.append("CREATE EXTERNAL TABLE ").append(IdentifierUtil.denormalizeIdentifier(desc.getName()));
buildSchema(sb, desc.getSchema());
buildUsingClause(sb, desc.getMeta());
buildWithClause(sb, desc.getMeta());
if (desc.hasPartition()) {
buildPartitionClause(sb, desc);
}
buildLocationClause(sb, desc);
sb.append(";");
return sb.toString();
}
public static String buildDDLForBaseTable(TableDesc desc) {
StringBuilder sb = new StringBuilder();
sb.append("--\n")
.append("-- Name: ").append(IdentifierUtil.denormalizeIdentifier(desc.getName())).append("; Type: TABLE;")
.append(" Storage: ").append(desc.getMeta().getDataFormat());
sb.append("\n--\n");
sb.append("CREATE TABLE ").append(IdentifierUtil.denormalizeIdentifier(desc.getName()));
buildSchema(sb, desc.getSchema());
buildUsingClause(sb, desc.getMeta());
buildWithClause(sb, desc.getMeta());
if (desc.hasPartition()) {
buildPartitionClause(sb, desc);
}
sb.append(";");
return sb.toString();
}
public static String buildDDLForIndex(IndexDesc desc) {
StringBuilder sb = new StringBuilder();
sb.append("--\n")
.append("-- Name: ").append(IdentifierUtil.denormalizeIdentifier(desc.getName())).append("; Type: INDEX;")
.append(" Index Method: ").append(desc.getIndexMethod());
sb.append("\n--\n");
sb.append("CREATE INDEX ").append(IdentifierUtil.denormalizeIdentifier(desc.getName()));
sb.append(" on ").append(IdentifierUtil.denormalizeIdentifier(desc.getTableName())).append(" ( ");
for (SortSpec sortSpec : desc.getKeySortSpecs()) {
sb.append(sortSpec.getSortKey().getQualifiedName()).append(" ");
sb.append(sortSpec.isAscending() ? "asc" : "desc").append(" ");
sb.append(sortSpec.isNullsFirst() ? "null first" : "null last").append(", ");
}
sb.replace(sb.length() - 2, sb.length() - 1, " )");
sb.append(" location '").append(desc.getIndexPath()).append("';");
return sb.toString();
}
public static void buildSchema(StringBuilder sb, Schema schema) {
boolean first = true;
sb.append(" (");
for (Column column : schema.toArray()) {
if (first) {
first = false;
} else {
sb.append(", ");
}
sb.append(IdentifierUtil.denormalizeIdentifier(column.getSimpleName())).append(" ");
TypeDesc typeDesc = column.getTypeDesc();
sb.append(typeDesc);
}
sb.append(")");
}
private static void buildUsingClause(StringBuilder sb, TableMeta meta) {
sb.append(" USING " + CatalogUtil.getBackwardCompitableDataFormat(meta.getDataFormat()));
}
private static void buildWithClause(final StringBuilder sb, TableMeta meta) {
KeyValueSet options = meta.getPropertySet();
if (options != null && options.size() > 0) {
sb.append(" WITH (");
// sort table properties in an lexicographic order of the property keys.
Entry<String, String> [] entries = meta.getPropertySet().getAllKeyValus().entrySet().toArray(
new Entry[meta.getPropertySet().size()]);
Arrays.sort(entries, new Comparator<Entry<String, String>>() {
@Override
public int compare(Entry<String, String> o1, Entry<String, String> o2) {
return o1.getKey().compareTo(o2.getKey());
}
});
// Join all properties by comma (',')
sb.append(StringUtils.join(entries, ", ", new Function<Entry<String, String>, String>() {
@Override
public String apply(Entry<String, String> e) {
return "'" + e.getKey() + "'='" + e.getValue() + "'";
}
}));
sb.append(")");
}
}
private static void buildLocationClause(StringBuilder sb, TableDesc desc) {
sb.append(" LOCATION '").append(desc.getUri()).append("'");
}
private static void buildPartitionClause(StringBuilder sb, TableDesc desc) {
PartitionMethodDesc partitionDesc = desc.getPartitionMethod();
sb.append(" PARTITION BY ");
sb.append(partitionDesc.getPartitionType().name());
// columns
sb.append("(");
String prefix = "";
for (Column column : partitionDesc.getExpressionSchema().toArray()) {
sb.append(prefix).append(CatalogUtil.columnToDDLString(column));
prefix = ", ";
}
sb.append(")");
}
/**
* Build alter table add partition statement
*
* @param table TableDesc to be build
* @param partition PartitionDescProto to be build
* @return
*/
public static String buildDDLForAddPartition(TableDesc table, PartitionDescProto partition) {
StringBuilder sb = new StringBuilder();
sb.append("ALTER TABLE ").append(IdentifierUtil.denormalizeIdentifier(table.getName()))
.append(" ADD IF NOT EXISTS PARTITION (");
List<Column> colums = table.getPartitionMethod().getExpressionSchema().getAllColumns();
String[] splitPartitionName = partition.getPartitionName().split(File.separator);
for(int i = 0; i < splitPartitionName.length; i++) {
String[] partitionColumnValue = splitPartitionName[i].split("=");
if (i > 0) {
sb.append(",");
}
switch (colums.get(i).getDataType().getType()) {
case TEXT:
case TIME:
case TIMESTAMP:
case DATE:
sb.append(partitionColumnValue[0]).append("='").append(partitionColumnValue[1]).append("'");
break;
default:
sb.append(partitionColumnValue[0]).append("=").append(partitionColumnValue[1]);
break;
}
}
sb.append(") LOCATION '").append(partition.getPath()).append("';\n");
return sb.toString();
}
}