Skip to content

Commit

Permalink
Allow anonymous rows in Hive temporary tables
Browse files Browse the repository at this point in the history
  • Loading branch information
arhimondr committed Aug 30, 2019
1 parent 5d18a1c commit d591d79
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@
import static com.facebook.presto.hive.HiveType.HIVE_STRING;
import static com.facebook.presto.hive.HiveType.toHiveType;
import static com.facebook.presto.hive.HiveUtil.PRESTO_VIEW_FLAG;
import static com.facebook.presto.hive.HiveUtil.assignFieldNamesForAnonymousRowColumns;
import static com.facebook.presto.hive.HiveUtil.columnExtraInfo;
import static com.facebook.presto.hive.HiveUtil.decodeViewData;
import static com.facebook.presto.hive.HiveUtil.encodeViewData;
Expand Down Expand Up @@ -749,7 +750,12 @@ public ConnectorTableHandle createTemporaryTable(ConnectorSession session, List<
return new HiveBucketProperty(partitioning.getPartitionColumns(), partitioningHandle.getBucketCount(), ImmutableList.of());
});

List<HiveColumnHandle> columnHandles = getColumnHandles(columns, ImmutableSet.of(), typeTranslator);
List<HiveColumnHandle> columnHandles = getColumnHandles(
// Hive doesn't support anonymous rows
// Since this method doesn't create a real table, it is fine to assign dummy field names to the anonymous rows
assignFieldNamesForAnonymousRowColumns(columns, typeManager),
ImmutableSet.of(),
typeTranslator);
storageFormat.validateColumns(columnHandles);

Table table = Table.builder()
Expand Down
64 changes: 64 additions & 0 deletions presto-hive/src/main/java/com/facebook/presto/hive/HiveUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.facebook.presto.hive.metastore.Table;
import com.facebook.presto.hive.util.FooterAwareRecordReader;
import com.facebook.presto.orc.OrcReader;
import com.facebook.presto.spi.ColumnMetadata;
import com.facebook.presto.spi.ConnectorTableHandle;
import com.facebook.presto.spi.ErrorCodeSupplier;
import com.facebook.presto.spi.PrestoException;
Expand All @@ -28,8 +29,13 @@
import com.facebook.presto.spi.type.CharType;
import com.facebook.presto.spi.type.DecimalType;
import com.facebook.presto.spi.type.Decimals;
import com.facebook.presto.spi.type.NamedTypeSignature;
import com.facebook.presto.spi.type.RowFieldName;
import com.facebook.presto.spi.type.StandardTypes;
import com.facebook.presto.spi.type.Type;
import com.facebook.presto.spi.type.TypeManager;
import com.facebook.presto.spi.type.TypeSignature;
import com.facebook.presto.spi.type.TypeSignatureParameter;
import com.facebook.presto.spi.type.VarcharType;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
Expand Down Expand Up @@ -1060,4 +1066,62 @@ private static Map<String, Integer> buildPhysicalNameOrdinalMap(OrcReader reader

return physicalNameOrdinalMap.build();
}

public static List<ColumnMetadata> assignFieldNamesForAnonymousRowColumns(List<ColumnMetadata> columns, TypeManager typeManager)
{
return columns.stream()
.map(column -> new ColumnMetadata(
column.getName(),
typeManager.getType(assignFieldNamesForAnonymousRowType(column.getType().getTypeSignature())),
column.isNullable(),
column.getComment(),
column.getExtraInfo(),
column.isHidden(),
column.getProperties()))
.collect(toImmutableList());
}

private static TypeSignature assignFieldNamesForAnonymousRowType(TypeSignature typeSignature)
{
List<TypeSignatureParameter> parameters = typeSignature.getParameters();

if (typeSignature.getBase().equals(StandardTypes.ROW)) {
ImmutableList.Builder<TypeSignatureParameter> updatedParameters = ImmutableList.builder();
for (int i = 0; i < parameters.size(); i++) {
TypeSignatureParameter typeSignatureParameter = parameters.get(i);
checkArgument(typeSignatureParameter.isNamedTypeSignature(), "unexpected row type signature parameter: %s", typeSignatureParameter);
NamedTypeSignature namedTypeSignature = typeSignatureParameter.getNamedTypeSignature();
updatedParameters.add(TypeSignatureParameter.of(new NamedTypeSignature(
Optional.of(namedTypeSignature.getFieldName().orElse(new RowFieldName("_field_" + i, false))),
assignFieldNamesForAnonymousRowType(namedTypeSignature.getTypeSignature()))));
}
return new TypeSignature(StandardTypes.ROW, updatedParameters.build());
}

if (!parameters.isEmpty()) {
ImmutableList.Builder<TypeSignatureParameter> updatedParameters = ImmutableList.builder();
for (TypeSignatureParameter parameter : parameters) {
switch (parameter.getKind()) {
case LONG:
case VARIABLE:
updatedParameters.add(parameter);
continue;
case TYPE:
updatedParameters.add(TypeSignatureParameter.of(assignFieldNamesForAnonymousRowType(parameter.getTypeSignature())));
break;
case NAMED_TYPE:
NamedTypeSignature namedTypeSignature = parameter.getNamedTypeSignature();
updatedParameters.add(TypeSignatureParameter.of(new NamedTypeSignature(
namedTypeSignature.getFieldName(),
assignFieldNamesForAnonymousRowType(namedTypeSignature.getTypeSignature()))));
break;
default:
throw new IllegalArgumentException("Unexpected parameter type: " + parameter.getKind());
}
}
return new TypeSignature(typeSignature.getBase(), updatedParameters.build());
}

return typeSignature;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1338,4 +1338,17 @@ public void testQuantileDigestMergeGroupBy()
"GROUP BY partkey",
"SELECT partkey, true FROM lineitem GROUP BY partkey");
}

@Test
public void testGroupedRow()
{
assertQuery(
"SELECT count(r[1]), count(r[2]) " +
"FROM (" +
" SELECT orderkey, max_by(ROW(orderstatus, shippriority), orderstatus) AS r " +
" FROM orders " +
" GROUP BY orderkey" +
")",
"SELECT 15000, 15000");
}
}

0 comments on commit d591d79

Please sign in to comment.