Author: shawkins
Date: 2012-08-16 13:46:48 -0400 (Thu, 16 Aug 2012)
New Revision: 4335
Modified:
trunk/api/src/main/java/org/teiid/metadata/ProcedureParameter.java
trunk/build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html
trunk/engine/src/main/java/org/teiid/query/resolver/command/ExecResolver.java
trunk/engine/src/main/java/org/teiid/query/resolver/util/ResolverUtil.java
trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj
trunk/engine/src/test/java/org/teiid/query/resolver/TestProcedureResolving.java
Log:
TEIID-2150 modifying procedure resolving and making sure that the parser doesn't
change default nullability.
Modified: trunk/api/src/main/java/org/teiid/metadata/ProcedureParameter.java
===================================================================
--- trunk/api/src/main/java/org/teiid/metadata/ProcedureParameter.java 2012-08-16 15:35:25
UTC (rev 4334)
+++ trunk/api/src/main/java/org/teiid/metadata/ProcedureParameter.java 2012-08-16 17:46:48
UTC (rev 4335)
@@ -49,10 +49,12 @@
return type;
}
+ @Deprecated
public void setOptional(boolean optional) {
this.optional = optional;
}
+ @Deprecated
public boolean isOptional() {
return optional;
}
Modified: trunk/build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html
===================================================================
--- trunk/build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html 2012-08-16 15:35:25 UTC
(rev 4334)
+++ trunk/build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html 2012-08-16 17:46:48 UTC
(rev 4335)
@@ -26,6 +26,10 @@
</UL>
<H2><A NAME="Highlights"></A>Highlights</H2>
+<ul>
+ <li>TEIID-2150 <b>Positional procedure defaults</b> - a procedure now
may be called positionally with just the leading input parameters as long as all trailing
parameters are out or defaultable.
+</ul>
+
<h2><a name="Compatibility">Compatibility
Issues</a></h2>
<ul>
<li>Support for named parameter syntax using param=value has been deprecated,
since it is ambiguous with a comparison predicate boolean value expression.
param<b>=></b>value should be used instead.
Modified: trunk/engine/src/main/java/org/teiid/query/resolver/command/ExecResolver.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/resolver/command/ExecResolver.java 2012-08-16
15:35:25 UTC (rev 4334)
+++
trunk/engine/src/main/java/org/teiid/query/resolver/command/ExecResolver.java 2012-08-16
17:46:48 UTC (rev 4335)
@@ -140,15 +140,32 @@
List<SPParameter> metadataParams = storedProcedureInfo.getParameters();
List<SPParameter> clonedMetadataParams = new
ArrayList<SPParameter>(metadataParams.size());
int inputParams = 0;
+ int optionalParams = 0;
int outParams = 0;
boolean hasReturnValue = false;
+ boolean optional = false;
for (SPParameter metadataParameter : metadataParams) {
if( (metadataParameter.getParameterType()==ParameterInfo.IN) ||
(metadataParameter.getParameterType()==ParameterInfo.INOUT)){
-
- inputParams++;
+ if (ResolverUtil.hasDefault(metadataParameter.getMetadataID(), metadata)) {
+ optional = true;
+ optionalParams++;
+ } else {
+ inputParams++;
+ if (optional) {
+ optional = false;
+ inputParams += optionalParams;
+ optionalParams = 0;
+ }
+ }
} else if (metadataParameter.getParameterType() == ParameterInfo.OUT) {
outParams++;
+ /*
+ * TODO: it would consistent to do the following, but it is a breaking
change for procedures that have intermixed out params with in.
+ * we may need to revisit this later
+ */
+ //optional = true;
+ //optionalParams++;
} else if (metadataParameter.getParameterType() ==
ParameterInfo.RETURN_VALUE) {
hasReturnValue = true;
}
@@ -174,6 +191,7 @@
if (param.getParameterType() == SPParameter.RETURN_VALUE) {
Expression expr = postionalExpressions.remove(exprIndex++);
param.setExpression(expr);
+ break;
}
}
}
@@ -196,6 +214,10 @@
continue;
}
Expression expr = postionalExpressions.remove(exprIndex++);
+ if (expr == null) {
+ expr = ResolverUtil.getDefault(param.getParameterSymbol(), metadata);
+ param.setUsingDefault(true);
+ }
param.setExpression(expr);
}
}
Modified: trunk/engine/src/main/java/org/teiid/query/resolver/util/ResolverUtil.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/resolver/util/ResolverUtil.java 2012-08-16
15:35:25 UTC (rev 4334)
+++ trunk/engine/src/main/java/org/teiid/query/resolver/util/ResolverUtil.java 2012-08-16
17:46:48 UTC (rev 4335)
@@ -428,6 +428,12 @@
return getProperlyTypedConstant(defaultValue, type);
}
+
+ public static boolean hasDefault(Object mid, QueryMetadataInterface metadata) throws
QueryMetadataException, TeiidComponentException {
+ Object defaultValue = metadata.getDefaultValue(mid);
+
+ return defaultValue != null || metadata.elementSupports(mid,
SupportConstants.Element.NULL);
+ }
/**
* Construct a Constant with proper type, given the String default
Modified: trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj
===================================================================
--- trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj 2012-08-16 15:35:25
UTC (rev 4334)
+++ trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj 2012-08-16 17:46:48
UTC (rev 4335)
@@ -846,6 +846,7 @@
String element = null;
ParsedDataType type = null;
boolean autoIncrement = false;
+ //TODO: once we support udts, then this will need to inherit the nullability from the
type
boolean notNull = false;
}
{
@@ -4503,7 +4504,7 @@
ProcedureParameter.Type ppType = ProcedureParameter.Type.In;
ProcedureParameter param = null;
String defaultValue = null;
- Boolean notNull = null;
+ boolean notNull = false;
}
{
[((<IN> {ppType = ProcedureParameter.Type.In ;})
@@ -4524,7 +4525,7 @@
try {
param = factory.addProcedureParameter(validateElementName(name), type.type, ppType,
proc);
setTypeInfo(type, param);
- if (notNull != null) {
+ if (notNull) {
param.setNullType(Column.NullType.No_Nulls);
}
} catch (TranslatorException e){
@@ -4775,7 +4776,7 @@
String element = null;
ParsedDataType type = null;
boolean autoIncrement = false;
- boolean notNull = false;
+ Boolean notNull = false;
String defalt = null;
Column column = null;
List<String> columnName = new ArrayList<String>();
@@ -4799,7 +4800,7 @@
}
}
)
- [<NOT> <NULL> { notNull = true; }]
+ [<NOT> <NULL> { column.setNullType(Column.NullType.No_Nulls); }]
([(<UNIQUE> { unique = true; })
|((word = <INDEX> | word = <AUTO_INCREMENT>)
{ if (word.image.equalsIgnoreCase("INDEX")) index = true;
@@ -4834,7 +4835,6 @@
}
column.setAutoIncremented(autoIncrement);
- column.setNullType(notNull?Column.NullType.No_Nulls:Column.NullType.Nullable);
}
}
Modified: trunk/engine/src/test/java/org/teiid/query/resolver/TestProcedureResolving.java
===================================================================
---
trunk/engine/src/test/java/org/teiid/query/resolver/TestProcedureResolving.java 2012-08-16
15:35:25 UTC (rev 4334)
+++
trunk/engine/src/test/java/org/teiid/query/resolver/TestProcedureResolving.java 2012-08-16
17:46:48 UTC (rev 4335)
@@ -24,35 +24,45 @@
import static org.junit.Assert.*;
+import java.util.Arrays;
import java.util.Map;
import org.junit.Test;
+import org.teiid.adminapi.impl.VDBMetaData;
import org.teiid.api.exception.query.QueryMetadataException;
import org.teiid.api.exception.query.QueryParserException;
import org.teiid.api.exception.query.QueryResolverException;
import org.teiid.core.TeiidComponentException;
import org.teiid.core.types.DataTypeManager;
+import org.teiid.metadata.MetadataStore;
import org.teiid.metadata.Table;
+import org.teiid.query.metadata.CompositeMetadataStore;
+import org.teiid.query.metadata.MetadataValidator;
import org.teiid.query.metadata.QueryMetadataInterface;
import org.teiid.query.metadata.TempMetadataAdapter;
import org.teiid.query.metadata.TempMetadataID;
+import org.teiid.query.metadata.TestMetadataValidator;
+import org.teiid.query.metadata.TransformationMetadata;
import org.teiid.query.parser.QueryParser;
import org.teiid.query.sql.ProcedureReservedWords;
import org.teiid.query.sql.lang.Command;
import org.teiid.query.sql.lang.Insert;
import org.teiid.query.sql.lang.ProcedureContainer;
+import org.teiid.query.sql.lang.StoredProcedure;
import org.teiid.query.sql.proc.AssignmentStatement;
import org.teiid.query.sql.proc.Block;
import org.teiid.query.sql.proc.CommandStatement;
import org.teiid.query.sql.proc.CreateProcedureCommand;
import org.teiid.query.sql.proc.LoopStatement;
import org.teiid.query.sql.proc.TriggerAction;
+import org.teiid.query.sql.symbol.Constant;
import org.teiid.query.sql.symbol.ElementSymbol;
import org.teiid.query.sql.symbol.Expression;
import org.teiid.query.sql.visitor.CommandCollectorVisitor;
import org.teiid.query.sql.visitor.ElementCollectorVisitor;
import org.teiid.query.unittest.RealMetadataFactory;
+@SuppressWarnings("nls")
public class TestProcedureResolving {
private void helpFailUpdateProcedure(String procedure, String userUpdateStr,
Table.TriggerEvent procedureType) {
@@ -1013,4 +1023,27 @@
helpResolve("EXEC example1.pm1.vsp29()",
RealMetadataFactory.example1Cached()); //$NON-NLS-1$
}
+ @Test public void testOptionalParams() throws Exception {
+ VDBMetaData vdb = new VDBMetaData();
+ MetadataStore store = new MetadataStore();
+ String ddl = "create foreign procedure proc (x integer, y string);\n";
+ TestMetadataValidator.buildModel("x", true, vdb, store, ddl);
+ TransformationMetadata tm = new TransformationMetadata(vdb, new
CompositeMetadataStore(Arrays.asList(store)), null,
RealMetadataFactory.SFM.getSystemFunctions(), null);
+ vdb.addAttchment(TransformationMetadata.class, tm);
+ vdb.addAttchment(QueryMetadataInterface.class, tm);
+ new MetadataValidator().validate(vdb, store);
+
+ String sql = "call proc (1)"; //$NON-NLS-1$
+
+ StoredProcedure sp = (StoredProcedure) TestResolver.helpResolve(sql, tm);
+
+ assertEquals(new Constant(null, DataTypeManager.DefaultDataClasses.STRING),
sp.getParameter(2).getExpression());
+
+ sql = "call proc (1, 'a')"; //$NON-NLS-1$
+
+ sp = (StoredProcedure) TestResolver.helpResolve(sql, tm);
+
+ assertEquals(new Constant("a",
DataTypeManager.DefaultDataClasses.STRING), sp.getParameter(2).getExpression());
+ }
+
}