blob: 803390e9901cf9865d77f23d05f547ff0136aa14 [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.presto;
import java.lang.reflect.*;
import java.util.Map;
import org.apache.carbondata.hive.CarbonHiveSerDe;
import org.apache.carbondata.hive.MapredCarbonInputFormat;
import org.apache.carbondata.hive.MapredCarbonOutputFormat;
import com.google.inject.Module;
import io.airlift.units.DataSize;
import io.prestosql.plugin.hive.HiveConnectorFactory;
import io.prestosql.plugin.hive.HiveStorageFormat;
import io.prestosql.spi.connector.Connector;
import io.prestosql.spi.connector.ConnectorContext;
import sun.misc.Unsafe;
import static io.airlift.units.DataSize.Unit.MEGABYTE;
/**
* Build Carbondata Connector
* It will be called by CarbondataPlugin
*/
public class CarbondataConnectorFactory extends HiveConnectorFactory {
static {
try {
setCarbonEnum();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public CarbondataConnectorFactory(String connectorName) {
this(connectorName, EmptyModule.class);
}
public CarbondataConnectorFactory(String connectorName, Class<? extends Module> module) {
super(connectorName, module);
}
@Override
public Connector create(
String catalogName,
Map<String, String> config,
ConnectorContext context) {
return InternalCarbonDataConnectorFactory
.createConnector(catalogName, config, context, new EmptyModule());
}
/**
* Set the Carbon format enum to HiveStorageFormat, its a hack but for time being it is best
* choice to avoid lot of code change.
*
* @throws Exception
*/
private static void setCarbonEnum() throws Exception {
for (HiveStorageFormat format : HiveStorageFormat.values()) {
if ("CARBON".equals(format.name()) || "ORG.APACHE.CARBONDATA.FORMAT".equals(format.name())
|| "CARBONDATA".equals(format.name())) {
return;
}
}
addHiveStorageFormatsForCarbondata("CARBON");
addHiveStorageFormatsForCarbondata("ORG.APACHE.CARBONDATA.FORMAT");
addHiveStorageFormatsForCarbondata("CARBONDATA");
}
private static void addHiveStorageFormatsForCarbondata(String storedAs) throws Exception {
Constructor<?> constructor = Unsafe.class.getDeclaredConstructors()[0];
constructor.setAccessible(true);
Unsafe unsafe = (Unsafe) constructor.newInstance();
HiveStorageFormat enumValue =
(HiveStorageFormat) unsafe.allocateInstance(HiveStorageFormat.class);
Field nameField = Enum.class.getDeclaredField("name");
makeAccessible(nameField);
nameField.set(enumValue, storedAs);
Field ordinalField = Enum.class.getDeclaredField("ordinal");
makeAccessible(ordinalField);
ordinalField.setInt(enumValue, HiveStorageFormat.values().length);
Field serdeField = HiveStorageFormat.class.getDeclaredField("serde");
makeAccessible(serdeField);
serdeField.set(enumValue, CarbonHiveSerDe.class.getName());
Field inputFormatField = HiveStorageFormat.class.getDeclaredField("inputFormat");
makeAccessible(inputFormatField);
inputFormatField.set(enumValue, MapredCarbonInputFormat.class.getName());
Field outputFormatField = HiveStorageFormat.class.getDeclaredField("outputFormat");
makeAccessible(outputFormatField);
outputFormatField.set(enumValue, MapredCarbonOutputFormat.class.getName());
Field estimatedWriterSystemMemoryUsageField =
HiveStorageFormat.class.getDeclaredField("estimatedWriterSystemMemoryUsage");
makeAccessible(estimatedWriterSystemMemoryUsageField);
estimatedWriterSystemMemoryUsageField.set(enumValue, new DataSize((long) 256, MEGABYTE));
Field values = HiveStorageFormat.class.getDeclaredField("$VALUES");
makeAccessible(values);
HiveStorageFormat[] hiveStorageFormats =
new HiveStorageFormat[HiveStorageFormat.values().length + 1];
HiveStorageFormat[] src = (HiveStorageFormat[]) values.get(null);
System.arraycopy(src, 0, hiveStorageFormats, 0, src.length);
hiveStorageFormats[src.length] = enumValue;
values.set(null, hiveStorageFormats);
}
private static void makeAccessible(Field field) throws Exception {
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
}
}