Skip to content

Commit 29c18a3

Browse files
committed
Enhance property mechanism to support specifying multiple value types
1 parent e53f403 commit 29c18a3

File tree

2 files changed

+76
-8
lines changed

2 files changed

+76
-8
lines changed

presto-main-base/src/main/java/com/facebook/presto/metadata/AbstractPropertyManager.java

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -93,22 +93,46 @@ public final ImmutableMap.Builder<String, Object> getUserSpecifiedProperties(
9393
propertyName));
9494
}
9595

96-
Object sqlObjectValue;
96+
PropertyMetadata.AdditionalSqlTypeHandler usedSqlTypeHandler = null;
97+
Object sqlObjectValue = null;
9798
try {
9899
sqlObjectValue = evaluatePropertyValue(sqlProperty.getValue(), property.getSqlType(), session, metadata, parameters);
99100
}
100101
catch (SemanticException e) {
101-
throw new PrestoException(propertyError,
102-
format("Invalid value for %s property '%s': Cannot convert '%s' to %s",
103-
propertyType,
104-
property.getName(),
105-
sqlProperty.getValue(),
106-
property.getSqlType()), e);
102+
for (PropertyMetadata.AdditionalSqlTypeHandler additionalSqlTypeHandler : property.getAdditionalSqlTypeHandlers()) {
103+
try {
104+
sqlObjectValue = evaluatePropertyValue(sqlProperty.getValue(), additionalSqlTypeHandler.getSqlType(), session, metadata, parameters);
105+
usedSqlTypeHandler = additionalSqlTypeHandler;
106+
break;
107+
}
108+
catch (Exception ex) {
109+
// ignored
110+
}
111+
}
112+
113+
if (usedSqlTypeHandler == null) {
114+
String additionalTypesInfo = property.getAdditionalSqlTypeHandlers().stream()
115+
.map(handler -> handler.getSqlType().getDisplayName())
116+
.reduce((type, type2) -> type + ", " + type2)
117+
.map(message -> " or any of [" + message + "]")
118+
.orElse("");
119+
throw new PrestoException(propertyError,
120+
format("Invalid value for %s property '%s': Cannot convert '%s' to %s",
121+
propertyType,
122+
property.getName(),
123+
sqlProperty.getValue(),
124+
property.getSqlType()) + additionalTypesInfo, e);
125+
}
107126
}
108127

109128
Object value;
110129
try {
111-
value = property.decode(sqlObjectValue);
130+
if (usedSqlTypeHandler != null) {
131+
value = property.decode(sqlObjectValue, usedSqlTypeHandler.getDecoder());
132+
}
133+
else {
134+
value = property.decode(sqlObjectValue);
135+
}
112136
}
113137
catch (Exception e) {
114138
throw new PrestoException(propertyError,

presto-spi/src/main/java/com/facebook/presto/spi/session/PropertyMetadata.java

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
import com.facebook.airlift.units.Duration;
1818
import com.facebook.presto.common.type.Type;
1919

20+
import java.util.ArrayList;
21+
import java.util.List;
2022
import java.util.Objects;
2123
import java.util.function.Function;
2224

@@ -36,6 +38,7 @@ public final class PropertyMetadata<T>
3638
private final T defaultValue;
3739
private final Function<Object, T> decoder;
3840
private final Function<T, Object> encoder;
41+
private final List<AdditionalSqlTypeHandler> additionalSqlTypeHandlers = new ArrayList<>();
3942

4043
public PropertyMetadata(
4144
String name,
@@ -84,6 +87,11 @@ public Type getSqlType()
8487
return sqlType;
8588
}
8689

90+
public List<AdditionalSqlTypeHandler> getAdditionalSqlTypeHandlers()
91+
{
92+
return additionalSqlTypeHandlers;
93+
}
94+
8795
/**
8896
* Java type of this property.
8997
*/
@@ -116,6 +124,14 @@ public T decode(Object value)
116124
return decoder.apply(value);
117125
}
118126

127+
/**
128+
* Decodes the SQL type object value to the Java type of the property using a specified decoder.
129+
*/
130+
public T decode(Object value, Function<Object, T> decoder)
131+
{
132+
return decoder.apply(value);
133+
}
134+
119135
public Function<Object, T> getDecoder()
120136
{
121137
return decoder;
@@ -134,6 +150,12 @@ public Function<T, Object> getEncoder()
134150
return encoder;
135151
}
136152

153+
public PropertyMetadata<?> withAdditionalTypeHandler(Type additionalSupportedType, Function<Object, T> decoder)
154+
{
155+
this.additionalSqlTypeHandlers.add(new AdditionalSqlTypeHandler(additionalSupportedType, decoder));
156+
return this;
157+
}
158+
137159
public static PropertyMetadata<Boolean> booleanProperty(String name, String description, Boolean defaultValue, boolean hidden)
138160
{
139161
return new PropertyMetadata<>(
@@ -269,4 +291,26 @@ public int hashCode()
269291

270292
return result;
271293
}
294+
295+
public class AdditionalSqlTypeHandler
296+
{
297+
Type sqlType;
298+
Function<Object, T> decoder;
299+
300+
public AdditionalSqlTypeHandler(Type sqlType, Function<Object, T> decoder)
301+
{
302+
this.sqlType = sqlType;
303+
this.decoder = decoder;
304+
}
305+
306+
public Function<Object, T> getDecoder()
307+
{
308+
return decoder;
309+
}
310+
311+
public Type getSqlType()
312+
{
313+
return sqlType;
314+
}
315+
}
272316
}

0 commit comments

Comments
 (0)