Skip to content

Commit

Permalink
DRILL-4120: Allow implicit columns for Avro storage format
Browse files Browse the repository at this point in the history
  • Loading branch information
vvysotskyi authored and Ben-Zvi committed Mar 7, 2018
1 parent dfe47ce commit 4652b0b
Show file tree
Hide file tree
Showing 19 changed files with 471 additions and 77 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/**
/*
* 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
Expand All @@ -21,6 +21,7 @@

import org.apache.drill.exec.planner.logical.DrillTable;
import org.apache.drill.exec.planner.logical.DynamicDrillTable;
import org.apache.drill.exec.store.SchemaConfig;
import org.apache.drill.exec.store.dfs.DrillFileSystem;
import org.apache.drill.exec.store.dfs.FileSelection;
import org.apache.drill.exec.store.dfs.FileSystemPlugin;
Expand All @@ -45,13 +46,13 @@ public boolean supportDirectoryReads() {

public DrillTable isReadable(DrillFileSystem fs,
FileSelection selection, FileSystemPlugin fsPlugin,
String storageEngineName, String userName) throws IOException {
String storageEngineName, SchemaConfig schemaConfig) throws IOException {
FileStatus status = selection.getFirstPath(fs);
if (!isFileReadable(fs, status)) {
return null;
}

return new DynamicDrillTable(fsPlugin, storageEngineName, userName,
return new DynamicDrillTable(fsPlugin, storageEngineName, schemaConfig.getUserName(),
new FormatSelection(getFormatPlugin().getConfig(), selection));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import com.mapr.fs.tables.TableProperties;
import org.apache.drill.exec.planner.logical.DrillTable;
import org.apache.drill.exec.planner.logical.DynamicDrillTable;
import org.apache.drill.exec.store.SchemaConfig;
import org.apache.drill.exec.store.dfs.DrillFileSystem;
import org.apache.drill.exec.store.dfs.FileSelection;
import org.apache.drill.exec.store.dfs.FileSystemPlugin;
Expand Down Expand Up @@ -52,7 +53,7 @@ protected boolean isSupportedTable(MapRFileStatus status) throws IOException {
@Override
public DrillTable isReadable(DrillFileSystem fs,
FileSelection selection, FileSystemPlugin fsPlugin,
String storageEngineName, String userName) throws IOException {
String storageEngineName, SchemaConfig schemaConfig) throws IOException {

if (isFileReadable(fs, selection.getFirstPath(fs))) {
List<String> files = selection.getFiles();
Expand All @@ -61,7 +62,7 @@ public DrillTable isReadable(DrillFileSystem fs,
TableProperties props = getFormatPlugin().getMaprFS().getTableProperties(new Path(tableName));

if (props.getAttr().getJson()) {
return new DynamicDrillTable(fsPlugin, storageEngineName, userName,
return new DynamicDrillTable(fsPlugin, storageEngineName, schemaConfig.getUserName(),
new FormatSelection(getFormatPlugin().getConfig(), selection));
} else {
FormatSelection formatSelection = new FormatSelection(getFormatPlugin().getConfig(), selection);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* 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.drill.exec.planner.logical;

import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.drill.exec.planner.types.ExtendableRelDataTypeHolder;
import org.apache.drill.exec.planner.types.RelDataTypeDrillImpl;

/**
* RelDataType for non-dynamic table structure which
* may be extended by adding partitions or implicit columns.
*/
public class ExtendableRelDataType extends RelDataTypeDrillImpl {

public ExtendableRelDataType(ExtendableRelDataTypeHolder holder, RelDataTypeFactory typeFactory) {
super(holder, typeFactory);
}

@Override
protected void generateTypeString(StringBuilder sb, boolean withDetail) {
sb.append("(ExtendableRelDataType").append(getFieldNames()).append(")");
}

@Override
public boolean isDynamicStruct() {
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

Expand Down Expand Up @@ -83,6 +84,7 @@
import org.apache.drill.exec.rpc.user.UserSession;

import com.google.common.base.Joiner;
import org.apache.drill.exec.store.ColumnExplorer;

/**
* Class responsible for managing parsing, validation and toRel conversion for sql statements.
Expand Down Expand Up @@ -277,6 +279,32 @@ public String deriveAlias(
return SqlValidatorUtil.getAlias(node, ordinal);
}

/**
* Checks that specified expression is not implicit column and
* adds it to a select list, ensuring that its alias does not
* clash with any existing expressions on the list.
* <p>
* This method may be used when {@link RelDataType#isDynamicStruct}
* method returns false. Each column from table row type except
* the implicit is added into specified list, aliases and fieldList.
* In the opposite case when {@link RelDataType#isDynamicStruct}
* returns true, only dynamic star is added into specified
* list, aliases and fieldList.
*/
@Override
protected void addToSelectList(
List<SqlNode> list,
Set<String> aliases,
List<Map.Entry<String, RelDataType>> fieldList,
SqlNode exp,
SqlValidatorScope scope,
final boolean includeSystemVars) {
if (!ColumnExplorer.initImplicitFileColumns(session.getOptions())
.containsKey(SqlValidatorUtil.getAlias(exp, -1))) {
super.addToSelectList(list, aliases, fieldList, exp, scope, includeSystemVars);
}
}

private void changeNamesIfTableIsTemporary(SqlIdentifier tempNode) {
List<String> temporaryTableNames = ((SqlConverter.DrillCalciteCatalogReader) getCatalogReader()).getTemporaryNames(tempNode.names);
if (temporaryTableNames != null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* 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.drill.exec.planner.types;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.rel.type.RelDataTypeField;

import java.util.List;

/**
* Base class-holder for the list of {@link RelDataTypeField}s.
*/
public abstract class AbstractRelDataTypeHolder {
protected final List<RelDataTypeField> fields;
protected RelDataTypeFactory typeFactory;

public AbstractRelDataTypeHolder(List<RelDataTypeField> fields) {
this.fields = Lists.newArrayList(fields);
}

/**
* Returns RelDataTypeField field with specified name.
*/
public abstract RelDataTypeField getField(RelDataTypeFactory typeFactory, String fieldName);

/**
* Returns list with all RelDataTypeField fields in this holder.
*/
public List<RelDataTypeField> getFieldList(RelDataTypeFactory typeFactory) {
return ImmutableList.copyOf(fields);
}

/**
* Returns count of RelDataTypeField fields in this holder.
*/
public int getFieldCount() {
return fields.size();
}

/**
* Returns list with names of RelDataTypeField fields.
*/
public List<String> getFieldNames() {
List<String> fieldNames = Lists.newArrayList();
for(RelDataTypeField f : fields) {
fieldNames.add(f.getName());
}

return fieldNames;
}

public void setRelDataTypeFactory(RelDataTypeFactory typeFactory) {
this.typeFactory = typeFactory;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* 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.drill.exec.planner.types;

import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.rel.type.RelDataTypeField;
import org.apache.calcite.rel.type.RelDataTypeFieldImpl;
import org.apache.calcite.sql.type.SqlTypeName;

import java.util.List;

/**
* Holder for list of RelDataTypeField which may be expanded by implicit columns.
*/
public class ExtendableRelDataTypeHolder extends AbstractRelDataTypeHolder {
private final List<String> implicitColumnNames;

public ExtendableRelDataTypeHolder(List<RelDataTypeField> fields, List<String> implicitColumnNames) {
super(fields);
this.implicitColumnNames = implicitColumnNames;
}

/**
* Returns RelDataTypeField field with specified name.
* If field is implicit and absent in the fields list, it will be added.
*
* @param typeFactory RelDataTypeFactory which will be used
* for the creation of RelDataType for new fields.
* @param fieldName name of the field.
* @return RelDataTypeField field
*/
public RelDataTypeField getField(RelDataTypeFactory typeFactory, String fieldName) {

/* First check if this field name exists in our field list */
for (RelDataTypeField f : fields) {
if (fieldName.equalsIgnoreCase(f.getName())) {
return f;
}
}
RelDataTypeField newField = null;

if (isImplicitField(fieldName)) {
// This implicit field does not exist in our field list, add it
newField = new RelDataTypeFieldImpl(
fieldName,
fields.size(),
typeFactory.createTypeWithNullability(
typeFactory.createSqlType(SqlTypeName.VARCHAR), true));
fields.add(newField);
}
return newField;
}

/**
* Checks that specified field is implicit.
*
* @param fieldName name of the field which should be checked
* @return {@code true} if specified filed is implicit
*/
private boolean isImplicitField(String fieldName) {
for (String implicitColumn : implicitColumnNames) {
if (implicitColumn.equalsIgnoreCase(fieldName)) {
return true;
}
}
return false;
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/**
/*
* 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
Expand Down Expand Up @@ -37,9 +37,9 @@
public class RelDataTypeDrillImpl extends DynamicRecordType {

private final RelDataTypeFactory typeFactory;
private final RelDataTypeHolder holder;
private final AbstractRelDataTypeHolder holder;

public RelDataTypeDrillImpl(RelDataTypeHolder holder, RelDataTypeFactory typeFactory) {
public RelDataTypeDrillImpl(AbstractRelDataTypeHolder holder, RelDataTypeFactory typeFactory) {
this.typeFactory = typeFactory;
this.holder = holder;
this.holder.setRelDataTypeFactory(typeFactory);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,20 @@

import java.util.List;

import com.google.common.collect.Lists;
import org.apache.calcite.rel.type.DynamicRecordType;
import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.rel.type.RelDataTypeField;
import org.apache.calcite.rel.type.RelDataTypeFieldImpl;
import org.apache.calcite.sql.type.SqlTypeName;

import com.google.common.collect.Lists;
import org.apache.drill.common.expression.SchemaPath;

public class RelDataTypeHolder {
static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(RelDataTypeHolder.class);
public class RelDataTypeHolder extends AbstractRelDataTypeHolder {

private final List<RelDataTypeField> fields = Lists.newArrayList();

private RelDataTypeFactory typeFactory;
public RelDataTypeHolder() {
super(Lists.<RelDataTypeField>newArrayList());
}

public List<RelDataTypeField> getFieldList(RelDataTypeFactory typeFactory) {
addStarIfEmpty(typeFactory);
Expand Down Expand Up @@ -75,32 +74,4 @@ public RelDataTypeField getField(RelDataTypeFactory typeFactory, String fieldNam

return newField;
}

public List<String> getFieldNames() {
List<String> fieldNames = Lists.newArrayList();
for(RelDataTypeField f : fields){
fieldNames.add(f.getName());
};

return fieldNames;
}

public void setRelDataTypeFactory(RelDataTypeFactory typeFactory) {
this.typeFactory = typeFactory;
}

@Override
public int hashCode() {
return System.identityHashCode(this);
}

@Override
public boolean equals(Object obj) {
return (this == obj);
}

private List<RelDataTypeField> getFieldList() {
return getFieldList(this.typeFactory);
}

}
Loading

0 comments on commit 4652b0b

Please sign in to comment.