org.apache.drill.exec.dotdrill.View Maven / Gradle / Ivy
/**
* 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.dotdrill;
import java.util.List;
import org.apache.calcite.avatica.util.TimeUnit;
import org.apache.calcite.sql.SqlIntervalQualifier;
import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.calcite.sql.type.SqlTypeFamily;
import org.apache.drill.exec.planner.StarColumnHelper;
import org.apache.drill.exec.planner.types.RelDataTypeDrillImpl;
import org.apache.drill.exec.planner.types.RelDataTypeHolder;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.rel.type.RelDataTypeField;
import org.apache.calcite.sql.type.SqlTypeName;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeName;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
@JsonTypeName("view")
public class View {
private final String name;
private String sql;
private List fields;
/* Current schema when view is created (not the schema to which view belongs to) */
private List workspaceSchemaPath;
@JsonInclude(Include.NON_NULL)
public static class FieldType {
private final String name;
private final SqlTypeName type;
private final Integer precision;
private final Integer scale;
private SqlIntervalQualifier intervalQualifier;
private final Boolean isNullable;
@JsonCreator
public FieldType(
@JsonProperty("name") String name,
@JsonProperty("type") SqlTypeName type,
@JsonProperty("precision") Integer precision,
@JsonProperty("scale") Integer scale,
@JsonProperty("startUnit") TimeUnit startUnit,
@JsonProperty("endUnit") TimeUnit endUnit,
@JsonProperty("fractionalSecondPrecision") Integer fractionalSecondPrecision,
@JsonProperty("isNullable") Boolean isNullable) {
this.name = name;
this.type = type;
this.precision = precision;
this.scale = scale;
this.intervalQualifier =
null == startUnit
? null
: new SqlIntervalQualifier(
startUnit, precision, endUnit, fractionalSecondPrecision, SqlParserPos.ZERO );
// Property "isNullable" is not part of the initial view definition and
// was added in DRILL-2342. If the default value is null, consider it as
// "true". It is safe to default to "nullable" than "required" type.
this.isNullable = isNullable == null ? true : isNullable;
}
public FieldType(String name, RelDataType dataType) {
this.name = name;
this.type = dataType.getSqlTypeName();
Integer p = null;
Integer s = null;
Integer fractionalSecondPrecision = null;
switch (dataType.getSqlTypeName()) {
case CHAR:
case BINARY:
case VARBINARY:
case VARCHAR:
p = dataType.getPrecision();
break;
case DECIMAL:
p = dataType.getPrecision();
s = dataType.getScale();
break;
case INTERVAL_YEAR_MONTH:
case INTERVAL_DAY_TIME:
p = dataType.getIntervalQualifier().getStartPrecisionPreservingDefault();
default:
break;
}
this.precision = p;
this.scale = s;
this.intervalQualifier = dataType.getIntervalQualifier();
this.isNullable = dataType.isNullable();
}
/**
* Gets the name of this field.
*/
public String getName() {
return name;
}
/**
* Gets the data type of this field.
* (Data type only; not full datatype descriptor.)
*/
public SqlTypeName getType() {
return type;
}
/**
* Gets the precision of the data type descriptor of this field.
* The precision is the precision for a numeric type, the length for a
* string type, or the start unit precision for an interval type.
* */
public Integer getPrecision() {
return precision;
}
/**
* Gets the numeric scale of the data type descriptor of this field,
* for numeric types.
*/
public Integer getScale() {
return scale;
}
/**
* Gets the interval type qualifier of the interval data type descriptor of
* this field (iff interval type). */
@JsonIgnore
public SqlIntervalQualifier getIntervalQualifier() {
return intervalQualifier;
}
/**
* Gets the time range start unit of the type qualifier of the interval data
* type descriptor of this field (iff interval type).
*/
public TimeUnit getStartUnit() {
return null == intervalQualifier ? null : intervalQualifier.getStartUnit();
}
/**
* Gets the time range end unit of the type qualifier of the interval data
* type descriptor of this field (iff interval type).
*/
public TimeUnit getEndUnit() {
return null == intervalQualifier ? null : intervalQualifier.getEndUnit();
}
/**
* Gets the fractional second precision of the type qualifier of the interval
* data type descriptor of this field (iff interval type).
* Gets the interval type descriptor's fractional second precision
* (iff interval type).
*/
public Integer getFractionalSecondPrecision() {
return null == intervalQualifier ? null : intervalQualifier.getFractionalSecondPrecisionPreservingDefault();
}
/**
* Gets the nullability of the data type desription of this field.
*/
public Boolean getIsNullable() {
return isNullable;
}
}
public View(String name, String sql, RelDataType rowType, List workspaceSchemaPath) {
this.name = name;
this.sql = sql;
fields = Lists.newArrayList();
for (RelDataTypeField f : rowType.getFieldList()) {
fields.add(new FieldType(f.getName(), f.getType()));
}
this.workspaceSchemaPath =
workspaceSchemaPath == null ? ImmutableList.of() : ImmutableList.copyOf(workspaceSchemaPath);
}
@JsonCreator
public View(@JsonProperty("name") String name,
@JsonProperty("sql") String sql,
@JsonProperty("fields") List fields,
@JsonProperty("workspaceSchemaPath") List workspaceSchemaPath){
this.name = name;
this.sql = sql;
this.fields = fields;
this.workspaceSchemaPath =
workspaceSchemaPath == null ? ImmutableList.of() : ImmutableList.copyOf(workspaceSchemaPath);
}
public RelDataType getRowType(RelDataTypeFactory factory) {
// if there are no fields defined, this is a dynamic view.
if (isDynamic()) {
return new RelDataTypeDrillImpl(new RelDataTypeHolder(), factory);
}
List types = Lists.newArrayList();
List names = Lists.newArrayList();
for (FieldType field : fields) {
names.add(field.getName());
RelDataType type;
if ( SqlTypeFamily.INTERVAL_YEAR_MONTH == field.getType().getFamily()
|| SqlTypeFamily.INTERVAL_DAY_TIME == field.getType().getFamily() ) {
type = factory.createSqlIntervalType( field.getIntervalQualifier() );
} else if (field.getPrecision() == null && field.getScale() == null) {
type = factory.createSqlType(field.getType());
} else if (field.getPrecision() != null && field.getScale() == null) {
type = factory.createSqlType(field.getType(), field.getPrecision());
} else {
type = factory.createSqlType(field.getType(), field.getPrecision(), field.getScale());
}
if (field.getIsNullable()) {
types.add(factory.createTypeWithNullability(type, true));
} else {
types.add(type);
}
}
return factory.createStructType(types, names);
}
@JsonIgnore
public boolean isDynamic(){
return fields.isEmpty();
}
@JsonIgnore
public boolean hasStar() {
for (FieldType field : fields) {
if (StarColumnHelper.isNonPrefixedStarColumn(field.getName())) {
return true;
}
}
return false;
}
public String getSql() {
return sql;
}
public void setSql(String sql) {
this.sql = sql;
}
public String getName() {
return name;
}
public List getFields() {
return fields;
}
public List getWorkspaceSchemaPath() {
return workspaceSchemaPath;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy