From c4e388751ed7eb85a8755547ce50e5fae260106e Mon Sep 17 00:00:00 2001 From: shawkins Date: Wed, 14 Aug 2013 10:50:11 -0400 Subject: [PATCH] TEIID-247 ensuring proper resolving with vararg procedures/functions --- .../teiid/query/function/FunctionLibrary.java | 2 +- .../query/resolver/util/ResolverVisitor.java | 4 ++- .../query/resolver/TestFunctionResolving.java | 21 +++++++++++++++- .../resolver/TestProcedureResolving.java | 25 +++++++++++++++++++ 4 files changed, 49 insertions(+), 3 deletions(-) diff --git a/engine/src/main/java/org/teiid/query/function/FunctionLibrary.java b/engine/src/main/java/org/teiid/query/function/FunctionLibrary.java index 1dc0c55889..327e66824c 100644 --- a/engine/src/main/java/org/teiid/query/function/FunctionLibrary.java +++ b/engine/src/main/java/org/teiid/query/function/FunctionLibrary.java @@ -345,7 +345,7 @@ private FunctionDescriptor[] getConverts(FunctionMethod method, Class[] types public boolean isVarArgArrayParam(FunctionMethod method, Class[] types, int i, Class targetType) { return i == types.length - 1 && method.isVarArgs() && i == method.getInputParameterCount() - 1 - && types[i].getComponentType() == targetType; + && types[i].isArray() && targetType.isAssignableFrom(types[i].getComponentType()); } private Transform getConvertFunctionDescriptor(Class sourceType, Class targetType) throws InvalidFunctionException { diff --git a/engine/src/main/java/org/teiid/query/resolver/util/ResolverVisitor.java b/engine/src/main/java/org/teiid/query/resolver/util/ResolverVisitor.java index 25d561f5ad..66b6d4b7d5 100644 --- a/engine/src/main/java/org/teiid/query/resolver/util/ResolverVisitor.java +++ b/engine/src/main/java/org/teiid/query/resolver/util/ResolverVisitor.java @@ -315,7 +315,9 @@ public void visit(Array array) { for (int i = 0; i < array.getExpressions().size(); i++) { Expression expr = array.getExpressions().get(i); setDesiredType(expr, array.getComponentType(), array); - array.getExpressions().set(i, ResolverUtil.convertExpression(expr, type, metadata)); + if (array.getComponentType() != DefaultDataClasses.OBJECT) { + array.getExpressions().set(i, ResolverUtil.convertExpression(expr, type, metadata)); + } } } else { Class type = null; diff --git a/engine/src/test/java/org/teiid/query/resolver/TestFunctionResolving.java b/engine/src/test/java/org/teiid/query/resolver/TestFunctionResolving.java index 89a55be7fa..b1b2a7054d 100644 --- a/engine/src/test/java/org/teiid/query/resolver/TestFunctionResolving.java +++ b/engine/src/test/java/org/teiid/query/resolver/TestFunctionResolving.java @@ -29,6 +29,8 @@ import org.teiid.api.exception.query.QueryResolverException; import org.teiid.core.TeiidComponentException; import org.teiid.core.types.DataTypeManager; +import org.teiid.query.eval.Evaluator; +import org.teiid.query.metadata.TransformationMetadata; import org.teiid.query.parser.QueryParser; import org.teiid.query.resolver.util.ResolverVisitor; import org.teiid.query.sql.symbol.Constant; @@ -39,7 +41,7 @@ import org.teiid.query.sql.symbol.XMLSerialize; import org.teiid.query.unittest.RealMetadataFactory; - +@SuppressWarnings("nls") public class TestFunctionResolving { @Test public void testResolveBadConvert() throws Exception { @@ -167,4 +169,21 @@ public static Expression getExpression(String sql) throws QueryParserException, getExpression(sql); } + public static String vararg(Object... vals) { + return String.valueOf(vals.length); + } + + @Test public void testVarArgsFunction() throws Exception { + String ddl = "create foreign function func (VARIADIC z object) returns string options (JAVA_CLASS '"+this.getClass().getName()+"', JAVA_METHOD 'vararg');\n"; + TransformationMetadata tm = RealMetadataFactory.fromDDL(ddl, "x", "y"); + + String sql = "func(('a', 'b'))"; + + Function func = (Function) QueryParser.getQueryParser().parseExpression(sql); + ResolverVisitor.resolveLanguageObject(func, tm); + assertEquals(1, func.getArgs().length); + + assertEquals("2", Evaluator.evaluate(func)); + } + } diff --git a/engine/src/test/java/org/teiid/query/resolver/TestProcedureResolving.java b/engine/src/test/java/org/teiid/query/resolver/TestProcedureResolving.java index 4b151110e1..f474c8e204 100644 --- a/engine/src/test/java/org/teiid/query/resolver/TestProcedureResolving.java +++ b/engine/src/test/java/org/teiid/query/resolver/TestProcedureResolving.java @@ -1095,6 +1095,13 @@ public static TransformationMetadata createMetadata(String ddl) throws Exception LanguageBridgeFactory lbf = new LanguageBridgeFactory(tm); Call call = (Call)lbf.translate(sp); assertEquals("EXEC proc(1)", call.toString()); + + sql = "call proc (1, (2, 3))"; //$NON-NLS-1$ + sp = (StoredProcedure) TestResolver.helpResolve(sql, tm); + assertEquals("EXEC proc(1, (2, 3))", sp.toString()); + assertEquals(new Constant(1), sp.getParameter(1).getExpression()); + assertEquals(new Array(DataTypeManager.DefaultDataClasses.INTEGER, Arrays.asList((Expression)new Constant(2), new Constant(3))), sp.getParameter(2).getExpression()); + assertEquals(SPParameter.RESULT_SET, sp.getParameter(3).getParameterType()); } @Test public void testVarArgs1() throws Exception { @@ -1114,4 +1121,22 @@ public static TransformationMetadata createMetadata(String ddl) throws Exception assertEquals(0, call.getArguments().size()); } + @Test public void testVarArgs2() throws Exception { + String ddl = "create foreign procedure proc (VARIADIC z object) returns (x string);\n"; + TransformationMetadata tm = createMetadata(ddl); + + String sql = "call proc ()"; //$NON-NLS-1$ + StoredProcedure sp = (StoredProcedure) TestResolver.helpResolve(sql, tm); + assertEquals("EXEC proc()", sp.toString()); + assertEquals(new Array(DataTypeManager.DefaultDataClasses.OBJECT, new ArrayList(0)), sp.getParameter(1).getExpression()); + + sql = "call proc (1, (2, 3))"; //$NON-NLS-1$ + sp = (StoredProcedure) TestResolver.helpResolve(sql, tm); + assertEquals("EXEC proc(1, (2, 3))", sp.toString()); + ArrayList expressions = new ArrayList(); + expressions.add(new Constant(1)); + expressions.add(new Array(DataTypeManager.DefaultDataClasses.INTEGER, Arrays.asList((Expression)new Constant(2), new Constant(3)))); + assertEquals(new Array(DataTypeManager.DefaultDataClasses.OBJECT, expressions), sp.getParameter(1).getExpression()); + } + }