Skip to content

Commit

Permalink
Merge pull request #13 from jcflack/bug/master/contravariance
Browse files Browse the repository at this point in the history
There's always something to catch *after* the pull
  • Loading branch information
thallgren committed Mar 3, 2013
2 parents 301164c + 0c344e9 commit fbf5aeb
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
Expand Down Expand Up @@ -70,6 +71,10 @@

import static javax.tools.Diagnostic.Kind;

import org.postgresql.pljava.ResultSetHandle;
import org.postgresql.pljava.ResultSetProvider;
import org.postgresql.pljava.TriggerData;

import org.postgresql.pljava.annotation.Function;
import org.postgresql.pljava.annotation.SQLAction;
import org.postgresql.pljava.annotation.SQLActions;
Expand Down Expand Up @@ -198,11 +203,11 @@ class DDRProcessorImpl
TY_RESULTSET = typu.getDeclaredType(
elmu.getTypeElement( java.sql.ResultSet.class.getName()));
TY_RESULTSETPROVIDER = typu.getDeclaredType(
elmu.getTypeElement( "org.postgresql.pljava.ResultSetProvider"));
elmu.getTypeElement( ResultSetProvider.class.getName()));
TY_RESULTSETHANDLE = typu.getDeclaredType(
elmu.getTypeElement( "org.postgresql.pljava.ResultSetHandle"));
elmu.getTypeElement( ResultSetHandle.class.getName()));
TY_TRIGGERDATA = typu.getDeclaredType(
elmu.getTypeElement( "org.postgresql.pljava.TriggerData"));
elmu.getTypeElement( TriggerData.class.getName()));

AN_FUNCTION = elmu.getTypeElement( Function.class.getName());
AN_SQLACTION = elmu.getTypeElement( SQLAction.class.getName());
Expand Down Expand Up @@ -928,7 +933,7 @@ public void characterize()
TypeMirror tm = ptms.get( arity - 1);
if ( tm.getKind().equals( TypeKind.ERROR)
// unresolved things seem assignable to anything
|| ! typu.isAssignable( tm, TY_RESULTSET) )
|| ! typu.isSameType( tm, TY_RESULTSET) )
{
msg( Kind.ERROR, func.getParameters().get( arity - 1),
"Last parameter of complex-type-returning function " +
Expand Down Expand Up @@ -981,7 +986,7 @@ else if ( ret.getKind().equals( TypeKind.VOID) && 1 == arity )
TypeMirror tm = ptms.get( 0);
if ( ! tm.getKind().equals( TypeKind.ERROR)
// unresolved things seem assignable to anything
&& typu.isAssignable( tm, TY_TRIGGERDATA) )
&& typu.isSameType( tm, TY_TRIGGERDATA) )
{
trigger = true;
}
Expand Down Expand Up @@ -1026,7 +1031,8 @@ String nameAndParams( boolean dflts)
{
VariableElement ve = ves.next();
sb.append( "\n\t").append( ve.getSimpleName().toString());
sb.append( ' ').append( tmpr.getSQLType( tm, ve, dflts));
sb.append( ' ');
sb.append( tmpr.getSQLType( tm, ve, true, dflts));
if ( 0 < -- s )
sb.append( ',');
}
Expand Down Expand Up @@ -1114,7 +1120,7 @@ public String[] undeployStrings()
*/
class TypeMapper
{
List<Map.Entry<Class<?>, String>> mappings;
ArrayList<Map.Entry<Class<?>, String>> mappings;

TypeMapper() {
mappings = new ArrayList<Map.Entry<Class<?>, String>>();
Expand Down Expand Up @@ -1149,6 +1155,7 @@ class TypeMapper
this.addMap(BigInteger.class, "numeric");
this.addMap(BigDecimal.class, "numeric");
this.addMap(ResultSet.class, "record");
this.addMap(Object.class, "\"any\"");

this.addMap(byte[].class, "bytea");

Expand Down Expand Up @@ -1213,15 +1220,16 @@ void addMap(Class<?> k, String v)
* Return the SQL type for the Java type represented by a TypeMirror,
* from an explicit annotation if present, otherwise by applying the
* default mappings. No default-value information is included in the
* string returned.
* string returned. It is assumed that a function return is being typed
* rather than a function parameter.
*
* @param tm Represents the type whose corresponding SQL type is wanted.
* @param e Annotated element (chiefly for use as a location hint in
* diagnostic messages).
*/
String getSQLType(TypeMirror tm, Element e)
{
return getSQLType( tm, e, false);
return getSQLType( tm, e, false, false);
}


Expand All @@ -1233,10 +1241,15 @@ String getSQLType(TypeMirror tm, Element e)
* @param tm Represents the type whose corresponding SQL type is wanted.
* @param e Annotated element (chiefly for use as a location hint in
* diagnostic messages).
* @param contravariant Indicates that the element whose type is wanted
* is a function parameter and should be given the widest type that can
* be assigned to it. If false, find the narrowest type that a function
* return can be assigned to.
* @param withDefault Indicates whether any specified default value
* information should also be included in the "type" string returned.
*/
String getSQLType(TypeMirror tm, Element e, boolean withDefault)
String getSQLType(TypeMirror tm, Element e,
boolean contravariant, boolean withDefault)
{
boolean array = false;
String rslt = null;
Expand Down Expand Up @@ -1279,7 +1292,13 @@ String getSQLType(TypeMirror tm, Element e, boolean withDefault)
}
else
{
for ( Map.Entry<Class<?>, String> me : mappings )
ArrayList<Map.Entry<Class<?>, String>> ms = mappings;
if ( contravariant )
{
ms = (ArrayList<Map.Entry<Class<?>, String>>)ms.clone();
Collections.reverse( ms);
}
for ( Map.Entry<Class<?>, String> me : ms )
{
Class<?> k = me.getKey();
TypeMirror ktm;
Expand All @@ -1301,9 +1320,18 @@ String getSQLType(TypeMirror tm, Element e, boolean withDefault)
if ( null == te ) // can't find it -> not used in code?
continue; // hope it's not the one I'm looking for
ktm = te.asType();
if ( typu.isAssignable( tm, ktm) )
boolean accept;
if ( contravariant )
accept = typu.isAssignable( ktm, tm);
else
accept = typu.isAssignable( tm, ktm);
if ( accept )
{
rslt = me.getValue();
// don't compute a type of Object/"any" for
// a function return (just admit defeat instead)
if ( contravariant
|| ! Object.class.equals( me.getKey()) )
rslt = me.getValue();
break;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -800,7 +800,7 @@ private static void assertJarName(String jarName) throws SQLException
private static void deployInstall(int jarId, String jarName)
throws SQLException
{
SQLDeploymentDescriptor[] depDesc = getDeploymentDescriptor(jarId);
SQLDeploymentDescriptor[] depDesc = getDeploymentDescriptors(jarId);

String[] originalSchemaAndPath = new String[2];
boolean classpathChanged = assertInPath(jarName, originalSchemaAndPath);
Expand All @@ -813,7 +813,7 @@ private static void deployInstall(int jarId, String jarName)
private static void deployRemove(int jarId, String jarName)
throws SQLException
{
SQLDeploymentDescriptor[] depDesc = getDeploymentDescriptor(jarId);
SQLDeploymentDescriptor[] depDesc = getDeploymentDescriptors(jarId);

String[] originalSchemaAndPath = new String[2];
boolean classpathChanged = assertInPath(jarName, originalSchemaAndPath);
Expand All @@ -823,7 +823,7 @@ private static void deployRemove(int jarId, String jarName)
setClassPath(originalSchemaAndPath[0], originalSchemaAndPath[1]);
}

private static SQLDeploymentDescriptor[] getDeploymentDescriptor(int jarId)
private static SQLDeploymentDescriptor[] getDeploymentDescriptors(int jarId)
throws SQLException
{
ResultSet rs = null;
Expand Down

0 comments on commit fbf5aeb

Please sign in to comment.