Skip to content

Commit

Permalink
TEIID-2317 allowing non-lob values to remain undisturbed when returned
Browse files Browse the repository at this point in the history
as object values.
  • Loading branch information
shawkins committed Dec 5, 2012
1 parent cd1eea5 commit 7f96a3f
Show file tree
Hide file tree
Showing 15 changed files with 85 additions and 136 deletions.
2 changes: 1 addition & 1 deletion api/src/main/java/org/teiid/translator/TypeFacility.java
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ public static final String getDataTypeNameFromSQLType(int sqlType) {
* @return
*/
public Object convertToRuntimeType(Object value) {
return DataTypeManager.convertToRuntimeType(value);
return DataTypeManager.convertToRuntimeType(value, true);
}

/**
Expand Down
1 change: 1 addition & 0 deletions build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ <h4>from 8.2</h4>
For backwards compatibility a the system property org.teiid.implicitMultiSourceJoin was introduced to control whether multi-source joins are effectively partitioned by source without a source_name predicate. The property defaults to true, the pre 8.3 behavior - but should be
switched to false for later versions unless the issues with implicit join planning are addressed.
</ul>
<li>TEIID-2317 byte[] char[] and java.util.Date instances returned as object values will be left in tact and not automatically converted to BinaryType, ClobType, and Timestamp respectively. The values may still be cast to those types.
<ul>

<h4>from 8.1</h4>
Expand Down
5 changes: 2 additions & 3 deletions client/src/main/java/org/teiid/jdbc/DataTypeTransformer.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@

import org.teiid.core.types.BinaryType;
import org.teiid.core.types.DataTypeManager;
import org.teiid.core.types.TransformationException;
import org.teiid.core.util.ReaderInputStream;


Expand Down Expand Up @@ -98,8 +97,8 @@ static final <T> T transform(Object value, Class<T> targetType) throws SQLExcept
}
}
try {
return targetType.cast(DataTypeManager.transformValue(DataTypeManager.convertToRuntimeType(value), getRuntimeType(targetType)));
} catch (TransformationException e) {
return targetType.cast(DataTypeManager.transformValue(DataTypeManager.convertToRuntimeType(value, true), getRuntimeType(targetType)));
} catch (Exception e) {
String valueStr = value.toString();
if (valueStr.length() > 20) {
valueStr = valueStr.substring(0, 20) + "..."; //$NON-NLS-1$
Expand Down
107 changes: 42 additions & 65 deletions common-core/src/main/java/org/teiid/core/types/DataTypeManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -308,8 +308,6 @@ private static Transform getTransformFromMaps(String srcType,

private static Set<Class<?>> DATA_TYPE_CLASSES = Collections.unmodifiableSet(dataTypeClasses.keySet());

private static Map<Class<?>, SourceTransform> sourceConverters = new HashMap<Class<?>, SourceTransform>();

// Static initializer - loads basic transforms types
static {
// Load default data types - not extensible yet
Expand All @@ -318,8 +316,6 @@ private static Transform getTransformFromMaps(String srcType,
// Load default transforms
loadBasicTransforms();

loadSourceConversions();

for (Map.Entry<String, Class<?>> entry : dataTypeNames.entrySet()) {
Class<?> arrayType = getArrayType(entry.getValue());
arrayTypes.put(entry.getValue(), arrayType);
Expand Down Expand Up @@ -398,7 +394,7 @@ public static String getDataTypeName(Class<?> typeClass) {
}
String result = dataTypeClasses.get(typeClass);
if (result == null) {
if (typeClass.isArray()) {
if (typeClass.isArray() && !typeClass.getComponentType().isPrimitive()) {
result = arrayTypeNames.get(typeClass);
if (result == null) {
return getDataTypeName(typeClass.getComponentType()) + ARRAY_SUFFIX;
Expand All @@ -424,7 +420,7 @@ public static Class<?> determineDataTypeClass(Object value) {
if (DATA_TYPE_CLASSES.contains(clazz)) {
return clazz;
}
clazz = convertToRuntimeType(value).getClass();
clazz = convertToRuntimeType(value, true).getClass();
if (DATA_TYPE_CLASSES.contains(clazz)) {
return clazz;
}
Expand Down Expand Up @@ -799,62 +795,38 @@ public boolean isExplicit() {

}

static void loadSourceConversions() {
addSourceTransform(Clob.class, new SourceTransform<Clob, ClobType>(ClobType.class) {
@Override
public ClobType transform(Clob value) {
return new ClobType(value);
}
});
addSourceTransform(char[].class, new SourceTransform<char[], ClobType>(ClobType.class) {
@Override
public ClobType transform(char[] value) {
return new ClobType(ClobImpl.createClob(value));
}
});
addSourceTransform(Blob.class, new SourceTransform<Blob, BlobType>(BlobType.class) {
@Override
public BlobType transform(Blob value) {
return new BlobType(value);
}
});
addSourceTransform(byte[].class, new SourceTransform<byte[], BinaryType>(BinaryType.class) {
@Override
public BinaryType transform(byte[] value) {
return new BinaryType(value);
}
});
addSourceTransform(SQLXML.class, new SourceTransform<SQLXML, XMLType>(XMLType.class) {
@Override
public XMLType transform(SQLXML value) {
return new XMLType(value);
}
});
addSourceTransform(Date.class, new SourceTransform<Date, Timestamp>(Timestamp.class) {
@Override
public Timestamp transform(Date value) {
return new Timestamp(value.getTime());
}
});
}

public static Object convertToRuntimeType(Object value) {
/**
* Convert the value to the probable runtime type.
* @param allConversions if false only lob conversions will be used
*/
public static Object convertToRuntimeType(Object value, boolean allConversions) {
if (value == null) {
return null;
}
Class<?> c = value.getClass();
if (DATA_TYPE_CLASSES.contains(c)) {
return value;
}
SourceTransform t = sourceConverters.get(c);
if (t != null) {
return t.transform(value);
}
for (Map.Entry<Class<?>, SourceTransform> entry : sourceConverters.entrySet()) {
if (entry.getKey().isAssignableFrom(c)) {
return entry.getValue().transform(value);
if (allConversions) {
if (c == char[].class) {
return new ClobType(ClobImpl.createClob((char[])value));
}
if (c == byte[].class) {
return new BinaryType((byte[])value);
}
if (java.util.Date.class.isAssignableFrom(c)) {
return new Timestamp(((java.util.Date)value).getTime());
}
}
if (Clob.class.isAssignableFrom(c)) {
return new ClobType((Clob)value);
}
if (Blob.class.isAssignableFrom(c)) {
return new BlobType((Blob)value);
}
if (SQLXML.class.isAssignableFrom(c)) {
return new XMLType((SQLXML)value);
}
return value; // "object type"
}

Expand All @@ -865,15 +837,24 @@ public static Class<?> getRuntimeType(Class<?> c) {
if (DATA_TYPE_CLASSES.contains(c)) {
return c;
}
SourceTransform t = sourceConverters.get(c);
if (t != null) {
return t.getTargetType();
if (c == char[].class) {
return DefaultDataClasses.CLOB;
}
for (Map.Entry<Class<?>, SourceTransform> entry : sourceConverters.entrySet()) {
if (entry.getKey().isAssignableFrom(c)) {
return entry.getValue().getTargetType();
}
if (c == byte[].class) {
return DefaultDataClasses.VARBINARY;
}
if (java.util.Date.class.isAssignableFrom(c)) {
return DefaultDataClasses.DATE;
}
if (Clob.class.isAssignableFrom(c)) {
return DefaultDataClasses.CLOB;
}
if (Blob.class.isAssignableFrom(c)) {
return DefaultDataClasses.BLOB;
}
if (SQLXML.class.isAssignableFrom(c)) {
return DefaultDataClasses.XML;
}
return DefaultDataClasses.OBJECT; // "object type"
}

Expand All @@ -887,7 +868,7 @@ public static <T> T transformValue(Object value, Class<T> targetClass)
}

@SuppressWarnings("unchecked")
public static <T> T transformValue(Object value, Class sourceType,
public static <T> T transformValue(Object value, Class<?> sourceType,
Class<T> targetClass) throws TransformationException {
if (value == null || sourceType == targetClass || DefaultDataClasses.OBJECT == targetClass) {
return (T) value;
Expand All @@ -909,10 +890,6 @@ public static boolean isNonComparable(String type) {
|| DataTypeManager.DefaultDataTypes.XML.equals(type);
}

public static <S> void addSourceTransform(Class<S> sourceClass, SourceTransform<S, ?> transform) {
sourceConverters.put(sourceClass, transform);
}

public static void setValueCacheEnabled(boolean enabled) {
valueCacheEnabled = enabled;
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ public void setReferenceStreamId(String id) {
@Override
public String toString() {
if (reference == null) {
return super.toString();
return getClass().getName() + " " + this.referenceStreamId; //$NON-NLS-1$
}
return reference.toString();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,22 @@ public Object transformDirect(Object value) throws TransformationException {
}

Transform transform = DataTypeManager.getTransform(value.getClass(), getTargetType());
boolean valid = true;
if (transform instanceof ObjectToAnyTransform) {
Object v1 = DataTypeManager.convertToRuntimeType(value, true);
if (v1 != value) {
try {
return transformDirect(v1);
} catch (TransformationException e) {
throw new TransformationException(
CorePlugin.Event.TEIID10076, e, CorePlugin.Util.gs(CorePlugin.Event.TEIID10076, getSourceType(),
targetClass, value));
}
}
valid = false;
}

if (transform == null || transform instanceof ObjectToAnyTransform) {
if (transform == null || !valid) {
Object[] params = new Object[] { getSourceType(), targetClass, value};
throw new TransformationException(CorePlugin.Event.TEIID10076, CorePlugin.Util.gs(CorePlugin.Event.TEIID10076, params));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,17 +181,17 @@ else if ( c == 'O' || c == 'N') {
}

@Test public void testRuntimeTypeConversion() throws Exception {
assertNull(DataTypeManager.convertToRuntimeType(null));
assertNull(DataTypeManager.convertToRuntimeType(null, true));

assertTrue(DataTypeManager.convertToRuntimeType(new SerialBlob(new byte[0])) instanceof BlobType);
assertTrue(DataTypeManager.convertToRuntimeType(new SerialBlob(new byte[0]), true) instanceof BlobType);

//unknown type should return as same
Object foo = new Object();
assertEquals(foo, DataTypeManager.convertToRuntimeType(foo));
assertEquals(foo, DataTypeManager.convertToRuntimeType(foo, true));

//known type should return as same
Integer bar = new Integer(1);
assertEquals(bar, DataTypeManager.convertToRuntimeType(bar));
assertEquals(bar, DataTypeManager.convertToRuntimeType(bar, true));
}

@Test public void testObjectType() {
Expand Down Expand Up @@ -230,4 +230,11 @@ public String toString() {
Object[] value = {1,2};
assertArrayEquals(value, (Object[])DataTypeManager.transformValue(value, value.getClass(), DataTypeManager.DefaultDataClasses.OBJECT));
}

@Test public void testByteArray() throws Exception {
byte[] value = {1,2};
assertArrayEquals(value, (byte[])DataTypeManager.convertToRuntimeType(value, false));
assertEquals(new BinaryType(value), DataTypeManager.convertToRuntimeType(value, true));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;

import org.junit.After;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@
import org.teiid.query.sql.lang.ProcedureContainer;
import org.teiid.query.sql.symbol.Expression;
import org.teiid.query.sql.symbol.GroupSymbol;
import org.teiid.translator.CacheDirective.Scope;
import org.teiid.translator.DataNotAvailableException;
import org.teiid.translator.TranslatorException;
import org.teiid.translator.CacheDirective.Scope;
import org.teiid.util.XMLInputStream;


Expand Down Expand Up @@ -276,7 +276,7 @@ static Object convertToRuntimeType(BufferManager bm, Object value, Class<?> desi
}
return new XMLType(new SQLXMLImpl((InputStreamFactory)value));
}
return DataTypeManager.convertToRuntimeType(value);
return DataTypeManager.convertToRuntimeType(value, desiredType != DataTypeManager.DefaultDataClasses.OBJECT);
}

public List<?> nextTuple() throws TeiidComponentException, TeiidProcessingException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ public static void resolveParameterValues(List<Reference> params,
if(value != null) {
try {
String targetTypeName = DataTypeManager.getDataTypeName(param.getType());
Expression expr = ResolverUtil.convertExpression(new Constant(value), targetTypeName, metadata);
Expression expr = ResolverUtil.convertExpression(new Constant(DataTypeManager.convertToRuntimeType(value, param.getType() != DataTypeManager.DefaultDataClasses.OBJECT)), targetTypeName, metadata);
value = Evaluator.evaluate(expr);
} catch (ExpressionEvaluationException e) {
String msg = QueryPlugin.Util.getString("QueryUtil.Error_executing_conversion_function_to_convert_value", new Integer(i + 1), value, DataTypeManager.getDataTypeName(param.getType())); //$NON-NLS-1$
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ public static Object importValue(Object result, Class<?> expectedType)
}
}
}
result = DataTypeManager.convertToRuntimeType(result);
result = DataTypeManager.convertToRuntimeType(result, expectedType != DataTypeManager.DefaultDataClasses.OBJECT);
if (expectedType.isArray() && result instanceof ArrayImpl) {
return result;
}
Expand Down
5 changes: 2 additions & 3 deletions engine/src/main/java/org/teiid/query/sql/symbol/Constant.java
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,7 @@ public int compare(Object o1, Object o2) {
* @param type Type for the constant, should never be null
*/
public Constant(Object value, Class<?> type) {
// Set value
this.value = DataTypeManager.convertToRuntimeType(value);
this.value = value;

// Check that type is valid, then set it
if(type == null) {
Expand All @@ -151,7 +150,7 @@ public Constant(Object value, Class<?> type) {
* @param value Constant value, may be null
*/
public Constant(Object value) {
this.value = DataTypeManager.convertToRuntimeType(value);
this.value = value;
if (this.value == null) {
this.type = DataTypeManager.DefaultDataClasses.NULL;
} else {
Expand Down
Loading

0 comments on commit 7f96a3f

Please sign in to comment.