Author: shawkins
Date: 2012-09-25 14:58:05 -0400 (Tue, 25 Sep 2012)
New Revision: 4471
Modified:
trunk/api/src/main/java/org/teiid/language/SQLConstants.java
trunk/build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html
trunk/client/src/main/java/org/teiid/jdbc/TeiidSQLException.java
trunk/engine/src/main/java/org/teiid/query/eval/Evaluator.java
trunk/engine/src/main/java/org/teiid/query/optimizer/ProcedurePlanner.java
trunk/engine/src/main/java/org/teiid/query/processor/proc/CreateCursorResultSetInstruction.java
trunk/engine/src/main/java/org/teiid/query/processor/proc/ErrorInstruction.java
trunk/engine/src/main/java/org/teiid/query/processor/proc/IfInstruction.java
trunk/engine/src/main/java/org/teiid/query/processor/proc/LoopInstruction.java
trunk/engine/src/main/java/org/teiid/query/processor/proc/ProcedurePlan.java
trunk/engine/src/main/java/org/teiid/query/processor/proc/Program.java
trunk/engine/src/main/java/org/teiid/query/processor/proc/ProgramInstruction.java
trunk/engine/src/main/java/org/teiid/query/processor/proc/WhileInstruction.java
trunk/engine/src/main/java/org/teiid/query/resolver/command/UpdateProcedureResolver.java
trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrPostOrderNavigator.java
trunk/engine/src/main/java/org/teiid/query/sql/proc/Block.java
trunk/engine/src/main/java/org/teiid/query/sql/proc/ExceptionExpression.java
trunk/engine/src/main/java/org/teiid/query/sql/proc/RaiseStatement.java
trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java
trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj
trunk/engine/src/main/resources/org/teiid/query/i18n.properties
trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java
trunk/engine/src/test/java/org/teiid/query/processor/proc/TestProcErrors.java
trunk/engine/src/test/java/org/teiid/query/resolver/TestProcedureResolving.java
Log:
TEIID-1386 refinement to exception handling. changed syntax slightly and added an
exception handler to a block
Modified: trunk/api/src/main/java/org/teiid/language/SQLConstants.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/SQLConstants.java 2012-09-25 18:56:07 UTC
(rev 4470)
+++ trunk/api/src/main/java/org/teiid/language/SQLConstants.java 2012-09-25 18:58:05 UTC
(rev 4471)
@@ -128,6 +128,7 @@
public static final String INDEX = "INDEX"; //$NON-NLS-1$
public static final String EXCEPTION = "EXCEPTION"; //$NON-NLS-1$
public static final String RAISE = "RAISE"; //$NON-NLS-1$
+ public static final String CHAIN = "CHAIN"; //$NON-NLS-1$
}
public interface Reserved {
Modified: trunk/build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html
===================================================================
--- trunk/build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html 2012-09-25 18:56:07 UTC
(rev 4470)
+++ trunk/build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html 2012-09-25 18:58:05 UTC
(rev 4471)
@@ -56,7 +56,6 @@
<li>TEIID-2184 to be consistent with the rest of Teiid's logic the system
functions dayName and monthName will return values from the default locale, rather than
only the English names. Use the system property org.teiid.enDateNames true to revert to
the pre-8.2 behavior.
<li>TEIID-2187 the CONSTRAINT keyword is not correctly used in table DDL. It
should be replaced with a comma from scripts to be compatible with 8.2. If desired, 8.2
now supports the CONSTRAINT keyword to provide a name for each constraint.
<li>TEIID-2181 system tables no longer contain valid OIDs. That responsibility
has moved to the pg_catalog.
- <li>TEIID-1386 assignment statements and stored procedure invocations assigning a
return value will no longer allow non-quoted non-reserved identifiers as left hand side
variables. The workaround is to use a quoted variable name if you are using a
non-reserved word as a variable name.
<li>TEIID-1386 the SQLState and errorCode reported by a TeiidSQLException will
typically be from the top level nested SQLException. If there is also a nested
TeiidException, the TeiidSQLException.teiidCode will be set to the TeiidException.getCode
value and the TeiidSQLException.errorCode will be set
to the integer suffix of the teiidCode if possible.
</ul>
Modified: trunk/client/src/main/java/org/teiid/jdbc/TeiidSQLException.java
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/TeiidSQLException.java 2012-09-25 18:56:07
UTC (rev 4470)
+++ trunk/client/src/main/java/org/teiid/jdbc/TeiidSQLException.java 2012-09-25 18:58:05
UTC (rev 4471)
@@ -102,7 +102,7 @@
if (exception instanceof SQLException) {
return new TeiidSQLException((SQLException) exception, message, true);
}
- String sqlState = SQLStates.DEFAULT;
+ String sqlState = null;
int errorCode = 0;
SQLException se = ExceptionUtil.getExceptionOfType(exception, SQLException.class);
if (se != null && se.getSQLState() != null) {
@@ -125,8 +125,13 @@
}
}
}
- exception = findRootException(exception);
- sqlState = determineSQLState(exception, sqlState);
+ if (sqlState == null) {
+ exception = findRootException(exception);
+ sqlState = determineSQLState(exception, sqlState);
+ }
+ if (sqlState == null) {
+ sqlState = SQLStates.DEFAULT;
+ }
TeiidSQLException tse = new TeiidSQLException(origException, message, sqlState,
errorCode);
tse.teiidCode = code;
return tse;
Modified: trunk/engine/src/main/java/org/teiid/query/eval/Evaluator.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/eval/Evaluator.java 2012-09-25 18:56:07 UTC
(rev 4470)
+++ trunk/engine/src/main/java/org/teiid/query/eval/Evaluator.java 2012-09-25 18:58:05 UTC
(rev 4471)
@@ -59,7 +59,6 @@
import org.teiid.core.types.basic.StringToSQLXMLTransform;
import org.teiid.core.util.EquivalenceUtil;
import org.teiid.jdbc.TeiidSQLException;
-import org.teiid.jdbc.TeiidSQLWarning;
import org.teiid.language.Like.MatchMode;
import org.teiid.query.QueryPlugin;
import org.teiid.query.function.FunctionDescriptor;
@@ -685,12 +684,7 @@
if (ee.getParent() != null) {
parent = (Exception) internalEvaluate(ee.getParent(), tuple);
}
- Exception result = null;
- if (ee.isWarning()) {
- result = new TeiidSQLWarning(msg, sqlState, errorCode!=null?errorCode:0, parent);
- } else {
- result = new TeiidSQLException(parent, msg, sqlState, errorCode!=null?errorCode:0);
- }
+ Exception result = new TeiidSQLException(parent, msg, sqlState,
errorCode!=null?errorCode:0);
result.setStackTrace(SourceWarning.EMPTY_STACK_TRACE);
return result;
}
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/ProcedurePlanner.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/ProcedurePlanner.java 2012-09-25
18:56:07 UTC (rev 4470)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/ProcedurePlanner.java 2012-09-25
18:58:05 UTC (rev 4471)
@@ -23,6 +23,7 @@
package org.teiid.query.optimizer;
import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Map;
import org.teiid.api.exception.query.QueryMetadataException;
@@ -132,7 +133,29 @@
programBlock.setLabel(block.getLabel());
// plan each statement in the block
- for (Statement statement : block.getStatements()) {
+ planStatements(parentProcCommand, block.getStatements(), metadata, debug,
idGenerator,
+ capFinder, analysisRecord, context, programBlock);
+
+ if (block.getExceptionGroup() != null) {
+ programBlock.setExceptionGroup(block.getExceptionGroup());
+ if (block.getExceptionStatements() != null) {
+ Program exceptionBlock = new Program(false);
+ planStatements(parentProcCommand, block.getExceptionStatements(),
metadata, debug, idGenerator,
+ capFinder, analysisRecord, context, exceptionBlock);
+ programBlock.setExceptionProgram(exceptionBlock);
+ }
+ }
+
+ return programBlock;
+ }
+
+ private void planStatements(CreateProcedureCommand parentProcCommand,
+ List<Statement> stmts, QueryMetadataInterface metadata, boolean debug,
+ IDGenerator idGenerator, CapabilitiesFinder capFinder,
+ AnalysisRecord analysisRecord, CommandContext context,
+ Program programBlock) throws QueryPlannerException,
+ QueryMetadataException, TeiidComponentException {
+ for (Statement statement : stmts) {
Object instruction = planStatement(parentProcCommand, statement, metadata, debug,
idGenerator, capFinder, analysisRecord, context);
if(instruction instanceof ProgramInstruction){
programBlock.addInstruction((ProgramInstruction)instruction);
@@ -144,10 +167,8 @@
}
}
}
+ }
- return programBlock;
- }
-
/**
* <p> Plan a {@link Statement} object, depending on the type of the statement
construct the appropriate
* {@link ProgramInstruction} return it to added to a {@link Program}. If the statement
references a
@@ -198,8 +219,9 @@
Expression asigExpr = res.getExpression();
error.setExpression(asigExpr);
+ error.setWarning(res.isWarning());
if(debug) {
- analysisRecord.println("\tERROR STATEMENT:\n" + statement);
//$NON-NLS-1$
+ analysisRecord.println("\tRAISE STATEMENT:\n" + statement);
//$NON-NLS-1$
}
break;
}
Modified:
trunk/engine/src/main/java/org/teiid/query/processor/proc/CreateCursorResultSetInstruction.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/processor/proc/CreateCursorResultSetInstruction.java 2012-09-25
18:56:07 UTC (rev 4470)
+++
trunk/engine/src/main/java/org/teiid/query/processor/proc/CreateCursorResultSetInstruction.java 2012-09-25
18:58:05 UTC (rev 4471)
@@ -26,7 +26,6 @@
import static org.teiid.query.analysis.AnalysisRecord.*;
-import java.util.List;
import java.util.Map;
import org.teiid.client.plan.PlanNode;
@@ -104,9 +103,4 @@
return plan;
}
- @Override
- public void getChildPlans(List<ProcessorPlan> plans) {
- plans.add(this.plan);
- }
-
}
Modified: trunk/engine/src/main/java/org/teiid/query/processor/proc/ErrorInstruction.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/processor/proc/ErrorInstruction.java 2012-09-25
18:56:07 UTC (rev 4470)
+++
trunk/engine/src/main/java/org/teiid/query/processor/proc/ErrorInstruction.java 2012-09-25
18:58:05 UTC (rev 4471)
@@ -24,14 +24,11 @@
import static org.teiid.query.analysis.AnalysisRecord.*;
-import java.sql.SQLWarning;
-
-import org.teiid.client.ProcedureErrorInstructionException;
import org.teiid.client.plan.PlanNode;
import org.teiid.core.TeiidComponentException;
import org.teiid.core.TeiidProcessingException;
+import org.teiid.jdbc.TeiidSQLException;
import org.teiid.logging.LogManager;
-import org.teiid.query.QueryPlugin;
import org.teiid.query.sql.symbol.Expression;
@@ -42,6 +39,7 @@
public class ErrorInstruction extends ProgramInstruction {
private Expression expression;
+ private boolean warning;
/**
* Constructor for DeclareInstruction.
@@ -52,6 +50,10 @@
public void setExpression(Expression expression) {
this.expression = expression;
}
+
+ public void setWarning(boolean warning) {
+ this.warning = warning;
+ }
/**
* @see org.teiid.query.processor.proc.ProgramInstruction#clone()
@@ -59,29 +61,33 @@
public ErrorInstruction clone() {
ErrorInstruction clone = new ErrorInstruction();
clone.expression = expression;
+ clone.warning = warning;
return clone;
}
public String toString() {
- return "RAISE ERROR INSTRUCTION: " + expression; //$NON-NLS-1$
+ return "RAISE " + (warning?"WARNING":"ERROR")
+" INSTRUCTION: " + expression; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
//$NON-NLS-4$
}
public PlanNode getDescriptionProperties() {
- PlanNode node = new PlanNode("RAISE ERROR"); //$NON-NLS-1$
+ PlanNode node = new PlanNode("RAISE " +
(warning?"WARNING":"ERROR")); //$NON-NLS-1$ //$NON-NLS-2$
//$NON-NLS-3$
node.addProperty(PROP_EXPRESSION, this.expression.toString());
return node;
}
@Override
public void process(ProcedurePlan env) throws TeiidComponentException,
- TeiidProcessingException {
+ TeiidProcessingException, TeiidSQLException {
Object value = env.evaluateExpression(expression);
- LogManager.logTrace(org.teiid.logging.LogConstants.CTX_DQP, "Processing
ErrorInstruction with the value :", value); //$NON-NLS-1$
- if (value instanceof SQLWarning) {
- env.getContext().addWarning((Exception)value);
- return;
- }
- throw new ProcedureErrorInstructionException(QueryPlugin.Event.TEIID30167,
(Exception) value);
+ LogManager.logTrace(org.teiid.logging.LogConstants.CTX_DQP, "Processing
RAISE with the value :", value); //$NON-NLS-1$
+ if (warning) {
+ env.getContext().addWarning((Exception)value);
+ return;
+ }
+ if (value == null) {
+ throw new TeiidProcessingException();
+ }
+ throw TeiidSQLException.create((Exception)value);
}
}
\ No newline at end of file
Modified: trunk/engine/src/main/java/org/teiid/query/processor/proc/IfInstruction.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/processor/proc/IfInstruction.java 2012-09-25
18:56:07 UTC (rev 4470)
+++
trunk/engine/src/main/java/org/teiid/query/processor/proc/IfInstruction.java 2012-09-25
18:58:05 UTC (rev 4471)
@@ -24,14 +24,11 @@
import static org.teiid.query.analysis.AnalysisRecord.*;
-import java.util.List;
-
import org.teiid.client.plan.PlanNode;
import org.teiid.common.buffer.BlockedException;
import org.teiid.core.TeiidComponentException;
import org.teiid.core.TeiidProcessingException;
import org.teiid.logging.LogManager;
-import org.teiid.query.processor.ProcessorPlan;
import org.teiid.query.sql.lang.Criteria;
@@ -118,10 +115,10 @@
* Returns a deep clone
*/
public IfInstruction clone(){
- Program cloneIf = (Program) this.ifProgram.clone();
+ Program cloneIf = this.ifProgram.clone();
Program cloneElse = null;
if(elseProgram != null) {
- cloneElse = (Program) this.elseProgram.clone();
+ cloneElse = this.elseProgram.clone();
}
IfInstruction clone = new IfInstruction(this.condition, cloneIf, cloneElse);
return clone;
@@ -141,12 +138,4 @@
return props;
}
- @Override
- public void getChildPlans(List<ProcessorPlan> plans) {
- ifProgram.getChildPlans(plans);
- if (elseProgram != null) {
- elseProgram.getChildPlans(plans);
- }
- }
-
}
Modified: trunk/engine/src/main/java/org/teiid/query/processor/proc/LoopInstruction.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/processor/proc/LoopInstruction.java 2012-09-25
18:56:07 UTC (rev 4470)
+++
trunk/engine/src/main/java/org/teiid/query/processor/proc/LoopInstruction.java 2012-09-25
18:58:05 UTC (rev 4471)
@@ -122,10 +122,4 @@
procEnv.removeResults(rsName);
}
- @Override
- public void getChildPlans(List<ProcessorPlan> plans) {
- super.getChildPlans(plans);
- this.loopProgram.getChildPlans(plans);
- }
-
}
Modified: trunk/engine/src/main/java/org/teiid/query/processor/proc/ProcedurePlan.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/processor/proc/ProcedurePlan.java 2012-09-25
18:56:07 UTC (rev 4470)
+++
trunk/engine/src/main/java/org/teiid/query/processor/proc/ProcedurePlan.java 2012-09-25
18:58:05 UTC (rev 4471)
@@ -37,6 +37,7 @@
import org.teiid.api.exception.query.QueryMetadataException;
import org.teiid.api.exception.query.QueryValidatorException;
+import org.teiid.client.ProcedureErrorInstructionException;
import org.teiid.client.plan.PlanNode;
import org.teiid.client.xa.XATransactionException;
import org.teiid.common.buffer.BlockedException;
@@ -56,6 +57,7 @@
import org.teiid.dqp.service.TransactionService;
import org.teiid.dqp.service.TransactionContext.Scope;
import org.teiid.events.EventDistributor;
+import org.teiid.jdbc.TeiidSQLException;
import org.teiid.logging.LogConstants;
import org.teiid.logging.LogManager;
import org.teiid.query.QueryPlugin;
@@ -69,11 +71,13 @@
import org.teiid.query.processor.QueryProcessor;
import org.teiid.query.processor.RegisterRequestParameter;
import org.teiid.query.processor.relational.SubqueryAwareEvaluator;
+import org.teiid.query.resolver.command.UpdateProcedureResolver;
import org.teiid.query.sql.ProcedureReservedWords;
import org.teiid.query.sql.lang.Command;
import org.teiid.query.sql.lang.Criteria;
import org.teiid.query.sql.symbol.ElementSymbol;
import org.teiid.query.sql.symbol.Expression;
+import org.teiid.query.sql.symbol.GroupSymbol;
import org.teiid.query.sql.util.VariableContext;
import org.teiid.query.tempdata.TempTableStore;
import org.teiid.query.util.CommandContext;
@@ -357,21 +361,61 @@
this.pop(true);
continue;
}
- if (inst instanceof RepeatedInstruction) {
- LogManager.logTrace(org.teiid.logging.LogConstants.CTX_DQP, "Executing
repeated instruction", inst); //$NON-NLS-1$
- RepeatedInstruction loop = (RepeatedInstruction)inst;
- if (loop.testCondition(this)) {
- LogManager.logTrace(org.teiid.logging.LogConstants.CTX_DQP,
"Passed condition, executing program " + loop.getNestedProgram());
//$NON-NLS-1$
- inst.process(this);
- this.push(loop.getNestedProgram());
- continue;
- }
- LogManager.logTrace(org.teiid.logging.LogConstants.CTX_DQP, "Exiting
repeated instruction", inst); //$NON-NLS-1$
- loop.postInstruction(this);
- } else {
- LogManager.logTrace(org.teiid.logging.LogConstants.CTX_DQP, "Executing
instruction", inst); //$NON-NLS-1$
- inst.process(this);
- }
+ try {
+ if (inst instanceof RepeatedInstruction) {
+ LogManager.logTrace(org.teiid.logging.LogConstants.CTX_DQP, "Executing
repeated instruction", inst); //$NON-NLS-1$
+ RepeatedInstruction loop = (RepeatedInstruction)inst;
+ if (loop.testCondition(this)) {
+ LogManager.logTrace(org.teiid.logging.LogConstants.CTX_DQP,
"Passed condition, executing program " + loop.getNestedProgram());
//$NON-NLS-1$
+ inst.process(this);
+ this.push(loop.getNestedProgram());
+ continue;
+ }
+ LogManager.logTrace(org.teiid.logging.LogConstants.CTX_DQP,
"Exiting repeated instruction", inst); //$NON-NLS-1$
+ loop.postInstruction(this);
+ } else {
+ LogManager.logTrace(org.teiid.logging.LogConstants.CTX_DQP, "Executing
instruction", inst); //$NON-NLS-1$
+ inst.process(this);
+ }
+ } catch (Exception e) {
+ if (e instanceof BlockedException) {
+ throw (BlockedException)e;
+ }
+ while (program.getExceptionGroup() == null) {
+ this.pop(false);
+ if (this.programs.empty()) {
+ //reached the top without a handler, so throw
+ if (e instanceof RuntimeException) {
+ throw (RuntimeException)e;
+ }
+ if (e instanceof TeiidComponentException) {
+ throw (TeiidComponentException)e;
+ }
+ if (e instanceof TeiidProcessingException) {
+ throw (TeiidProcessingException)e;
+ }
+ throw new ProcedureErrorInstructionException(QueryPlugin.Event.TEIID30167,
e);
+ }
+ program = peek();
+ }
+ //assign variables
+ if (program.getExceptionProgram() == null) {
+ this.pop(true);
+ continue;
+ }
+ Program exceptionProgram = program.getExceptionProgram();
+ exceptionProgram.setStartedTxn(program.startedTxn());
+ this.pop(null); //all the current program to go out of scope
+ this.push(exceptionProgram);
+ TeiidSQLException tse = TeiidSQLException.create(e);
+ GroupSymbol gs = new GroupSymbol(program.getExceptionGroup());
+ this.currentVarContext.setValue(exceptionSymbol(gs, 0), tse.getSQLState());
+ this.currentVarContext.setValue(exceptionSymbol(gs, 1), tse.getErrorCode());
+ this.currentVarContext.setValue(exceptionSymbol(gs, 2), tse.getTeiidCode());
+ this.currentVarContext.setValue(exceptionSymbol(gs, 3), tse);
+ this.currentVarContext.setValue(exceptionSymbol(gs, 4), tse.getCause());
+ continue;
+ }
program.incrementProgramCounter();
}
@@ -381,6 +425,12 @@
return lastTupleSource;
}
+ private ElementSymbol exceptionSymbol(GroupSymbol gs, int pos) {
+ ElementSymbol es = UpdateProcedureResolver.exceptionGroup.get(pos).clone();
+ es.setGroupSymbol(gs);
+ return es;
+ }
+
public void close()
throws TeiidComponentException {
if (!this.cursorStates.isEmpty()) {
@@ -409,7 +459,7 @@
}
public ProcessorPlan clone(){
- ProcedurePlan plan = new ProcedurePlan((Program)originalProgram.clone());
+ ProcedurePlan plan = new ProcedurePlan(originalProgram.clone());
plan.setOutputElements(this.getOutputElements());
plan.setParams(params);
plan.setOutParams(outParams);
@@ -565,13 +615,13 @@
* @throws TeiidComponentException
* @throws XATransactionException
*/
- public void pop(boolean success) throws TeiidComponentException {
+ public void pop(Boolean success) throws TeiidComponentException {
Program program = this.programs.pop();
if (this.currentVarContext.getParentContext() != null) {
this.currentVarContext = this.currentVarContext.getParentContext();
}
program.getTempTableStore().removeTempTables();
- if (program.startedTxn() && this.blockContext != null) {
+ if (success != null && program.startedTxn() && this.blockContext !=
null) {
TransactionService ts = this.getContext().getTransactionServer();
TransactionContext tc = this.blockContext;
this.blockContext = null;
Modified: trunk/engine/src/main/java/org/teiid/query/processor/proc/Program.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/proc/Program.java 2012-09-25
18:56:07 UTC (rev 4470)
+++ trunk/engine/src/main/java/org/teiid/query/processor/proc/Program.java 2012-09-25
18:58:05 UTC (rev 4471)
@@ -26,7 +26,6 @@
import java.util.List;
import org.teiid.client.plan.PlanNode;
-import org.teiid.query.processor.ProcessorPlan;
import org.teiid.query.sql.proc.Statement.Labeled;
import org.teiid.query.tempdata.TempTableStore;
import org.teiid.query.tempdata.TempTableStore.TransactionMode;
@@ -45,6 +44,8 @@
private String label;
private TempTableStore tempTables;
private boolean startedTxn;
+ private String exceptionGroup;
+ private Program exceptionProgram;
/**
* Constructor for Program.
@@ -149,7 +150,7 @@
/**
* Produces a deep clone.
*/
- public Object clone(){
+ public Program clone(){
Program program = new Program(atomic);
program.counter = this.counter;
@@ -161,12 +162,18 @@
program.programInstructions = clonedInstructions;
}
program.label = label;
+ program.exceptionGroup = this.exceptionGroup;
+ if (this.exceptionProgram != null) {
+ program.exceptionProgram = this.exceptionProgram.clone();
+ }
return program;
}
public PlanNode getDescriptionProperties() {
PlanNode props = new PlanNode("Program"); //$NON-NLS-1$
-
+ if (label != null) {
+ props.addProperty("Label", label); //$NON-NLS-1$
+ }
if(this.programInstructions != null) {
for (int i = 0; i < programInstructions.size(); i++) {
ProgramInstruction inst = programInstructions.get(i);
@@ -174,6 +181,13 @@
props.addProperty("Instruction " + i, childProps);
//$NON-NLS-1$
}
}
+
+ if (this.exceptionGroup != null) {
+ props.addProperty("EXCEPTION GROUP", this.exceptionGroup);
//$NON-NLS-1$
+ if (this.exceptionProgram != null) {
+ props.addProperty("EXCEPTION HANDLER",
this.exceptionProgram.getDescriptionProperties()); //$NON-NLS-1$
+ }
+ }
return props;
}
@@ -207,7 +221,12 @@
StringBuilder str = new StringBuilder();
programToString(str);
-
+ if (exceptionGroup != null) {
+ str.append("\nEXCEPTION
").append(exceptionGroup).append("\n"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ if (exceptionProgram != null) {
+ exceptionProgram.programToString(str);
+ }
return "PROGRAM counter " + this.counter + "\n" +
str.toString(); //$NON-NLS-1$ //$NON-NLS-2$
}
@@ -248,11 +267,21 @@
buffer.append(counterStr + line + "\n"); //$NON-NLS-1$
}
-
- void getChildPlans(List<ProcessorPlan> plans) {
- for (ProgramInstruction instruction : programInstructions) {
- instruction.getChildPlans(plans);
- }
- }
+
+ public void setExceptionGroup(String exceptionGroup) {
+ this.exceptionGroup = exceptionGroup;
+ }
+
+ public void setExceptionProgram(Program exceptionBlock) {
+ this.exceptionProgram = exceptionBlock;
+ }
+
+ public String getExceptionGroup() {
+ return exceptionGroup;
+ }
+
+ public Program getExceptionProgram() {
+ return exceptionProgram;
+ }
}
Modified:
trunk/engine/src/main/java/org/teiid/query/processor/proc/ProgramInstruction.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/processor/proc/ProgramInstruction.java 2012-09-25
18:56:07 UTC (rev 4470)
+++
trunk/engine/src/main/java/org/teiid/query/processor/proc/ProgramInstruction.java 2012-09-25
18:58:05 UTC (rev 4471)
@@ -22,12 +22,10 @@
package org.teiid.query.processor.proc;
-import java.util.List;
-
import org.teiid.client.plan.PlanNode;
import org.teiid.core.TeiidComponentException;
import org.teiid.core.TeiidProcessingException;
-import org.teiid.query.processor.ProcessorPlan;
+import org.teiid.jdbc.TeiidSQLException;
/**
@@ -50,19 +48,12 @@
* in turn manipulate the running program. A typical instruction should simply
{@link
* Program#incrementProgramCounter increment} the program counter of the current
program, but specialized
* instructions may add sub programs to the stack or not increment the counter (so
that they are executed again.)
+ * @throws TeiidSQLException
*/
public abstract void process(ProcedurePlan env)
- throws TeiidComponentException, TeiidProcessingException;
+ throws TeiidComponentException, TeiidProcessingException, TeiidSQLException;
/**
- * Finds all nested plans and returns them.
- * @return List of ProcessorPlan
- * @since 4.2
- */
- public void getChildPlans(List<ProcessorPlan> plans) {
- }
-
- /**
* Override Object.clone() to make the method public. This method
* simply calls super.clone(), deferring to the default shallow
* cloning. Some ProcessorInstruction subclasses may need to
Modified: trunk/engine/src/main/java/org/teiid/query/processor/proc/WhileInstruction.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/processor/proc/WhileInstruction.java 2012-09-25
18:56:07 UTC (rev 4470)
+++
trunk/engine/src/main/java/org/teiid/query/processor/proc/WhileInstruction.java 2012-09-25
18:58:05 UTC (rev 4471)
@@ -26,12 +26,9 @@
import static org.teiid.query.analysis.AnalysisRecord.*;
-import java.util.List;
-
import org.teiid.client.plan.PlanNode;
import org.teiid.core.TeiidComponentException;
import org.teiid.core.TeiidProcessingException;
-import org.teiid.query.processor.ProcessorPlan;
import org.teiid.query.sql.lang.Criteria;
@@ -73,7 +70,7 @@
* Returns a deep clone
*/
public WhileInstruction clone(){
- return new WhileInstruction((Program)this.whileProgram.clone(), this.condition,
this.label);
+ return new WhileInstruction(this.whileProgram.clone(), this.condition,
this.label);
}
public String toString() {
@@ -104,9 +101,4 @@
public void postInstruction(ProcedurePlan procEnv) throws TeiidComponentException {
}
- @Override
- public void getChildPlans(List<ProcessorPlan> plans) {
- whileProgram.getChildPlans(plans);
- }
-
}
Modified:
trunk/engine/src/main/java/org/teiid/query/resolver/command/UpdateProcedureResolver.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/resolver/command/UpdateProcedureResolver.java 2012-09-25
18:56:07 UTC (rev 4470)
+++
trunk/engine/src/main/java/org/teiid/query/resolver/command/UpdateProcedureResolver.java 2012-09-25
18:58:05 UTC (rev 4471)
@@ -35,6 +35,7 @@
import org.teiid.core.TeiidComponentException;
import org.teiid.core.types.DataTypeManager;
import org.teiid.language.SQLConstants;
+import org.teiid.language.SQLConstants.NonReserved;
import org.teiid.logging.LogManager;
import org.teiid.query.QueryPlugin;
import org.teiid.query.metadata.SupportConstants;
@@ -71,6 +72,21 @@
List<StatementNode> children;
}
+ public static final List<ElementSymbol> exceptionGroup;
+ static {
+ ElementSymbol es1 = new ElementSymbol("STATE"); //$NON-NLS-1$
+ es1.setType(DataTypeManager.DefaultDataClasses.STRING);
+ ElementSymbol es2 = new ElementSymbol("ERRORCODE"); //$NON-NLS-1$
+ es2.setType(DataTypeManager.DefaultDataClasses.INTEGER);
+ ElementSymbol es3 = new ElementSymbol("TEIIDCODE"); //$NON-NLS-1$
+ es3.setType(DataTypeManager.DefaultDataClasses.STRING);
+ ElementSymbol es4 = new ElementSymbol(NonReserved.EXCEPTION);
+ es4.setType(Exception.class);
+ ElementSymbol es5 = new ElementSymbol(NonReserved.CHAIN);
+ es5.setType(Exception.class);
+ exceptionGroup = Arrays.asList(es1, es2, es3, es4, es5);
+ }
+
/**
* @see
org.teiid.query.resolver.CommandResolver#resolveCommand(org.teiid.query.sql.lang.Command,
TempMetadataAdapter, boolean)
*/
@@ -145,6 +161,24 @@
for (Statement statement : block.getStatements()) {
resolveStatement(command, statement, externalGroups, variables, metadata,
sn);
}
+
+ if (block.getExceptionGroup() != null) {
+ //create a new variable and metadata context for this block so that
discovered metadata is not visible else where
+ store = metadata.getMetadataStore().clone();
+ metadata = new TempMetadataAdapter(metadata.getMetadata(), store);
+ externalGroups = new GroupContext(externalGroups, null);
+
+ //create a new variables group for this block
+ variables =
ProcedureContainerResolver.addScalarGroup(ProcedureReservedWords.VARIABLES, store,
externalGroups, new LinkedList<Expression>());
+ isValidGroup(metadata, block.getExceptionGroup());
+
+ if (block.getExceptionStatements() != null) {
+ ProcedureContainerResolver.addScalarGroup(block.getExceptionGroup(), store,
externalGroups, exceptionGroup, false);
+ for (Statement statement : block.getExceptionStatements()) {
+ resolveStatement(command, statement, externalGroups, variables,
metadata, sn);
+ }
+ }
+ }
}
private void resolveStatement(CreateProcedureCommand command, Statement statement,
GroupContext externalGroups, GroupSymbol variables, TempMetadataAdapter metadata,
StatementNode sn)
@@ -208,12 +242,7 @@
//this could be the last select statement, set the projected symbol
//on the virtual procedure command
if (subCommand.returnsResultSet() && sn != null) {
- updateDynamicAs(sn);
-
- sn.cs = cmdStmt;
- if (sn.children != null) {
- sn.children.clear();
- }
+ clearReturnableStatement(sn, cmdStmt);
}
break;
@@ -254,6 +283,9 @@
exprStmt.setExpression(ResolverUtil.convertExpression(exprStmt.getExpression(),
varTypeName, metadata));
if (statement.getType() == Statement.TYPE_ERROR) {
ResolverVisitor.checkException(exprStmt.getExpression());
+ if (!((RaiseStatement)statement).isWarning()) {
+ clearReturnableStatement(sn, null);
+ }
}
}
break;
@@ -270,15 +302,7 @@
LoopStatement loopStmt = (LoopStatement) statement;
String groupName = loopStmt.getCursorName();
- if (metadata.getMetadataStore().getTempGroupID(groupName) != null) {
- throw new QueryResolverException(QueryPlugin.Event.TEIID30124,
QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30124));
- }
-
- //check - cursor name should not start with #
- if(GroupSymbol.isTempGroupName(loopStmt.getCursorName())){
- String errorMsg =
QueryPlugin.Util.getString("ResolveVariablesVisitor.reserved_word_for_temporary_used",
loopStmt.getCursorName()); //$NON-NLS-1$
- throw new QueryResolverException(QueryPlugin.Event.TEIID30125, errorMsg);
- }
+ isValidGroup(metadata, groupName);
Command cmd = loopStmt.getCommand();
resolveEmbeddedCommand(metadata, externalGroups, cmd);
List<Expression> symbols = cmd.getProjectedSymbols();
@@ -295,6 +319,28 @@
}
}
+ private void clearReturnableStatement(StatementNode sn,
+ CommandStatement cmdStmt) {
+ updateDynamicAs(sn);
+
+ sn.cs = cmdStmt;
+ if (sn.children != null) {
+ sn.children.clear();
+ }
+ }
+
+ private void isValidGroup(TempMetadataAdapter metadata, String groupName)
+ throws QueryResolverException {
+ if (metadata.getMetadataStore().getTempGroupID(groupName) != null) {
+ throw new QueryResolverException(QueryPlugin.Event.TEIID30124,
QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30124, groupName));
+ }
+
+ //check - cursor name should not start with #
+ if(GroupSymbol.isTempGroupName(groupName)){
+ throw new QueryResolverException(QueryPlugin.Event.TEIID30125,
QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30125, groupName));
+ }
+ }
+
private void updateDynamicAs(StatementNode sn) {
if (sn.cs != null && sn.cs.getCommand().getType() == Command.TYPE_DYNAMIC) {
DynamicCommand dynamicCommand = (DynamicCommand)sn.cs.getCommand();
Modified: trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java 2012-09-25
18:56:07 UTC (rev 4470)
+++ trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java 2012-09-25
18:58:05 UTC (rev 4471)
@@ -242,20 +242,27 @@
private Block rewriteBlock(Block block)
throws TeiidComponentException, TeiidProcessingException{
List<Statement> statements = block.getStatements();
- Iterator<Statement> stmtIter = statements.iterator();
+ List<Statement> newStmts = rewriteStatements(statements);
+ block.setStatements(newStmts);
+ if (block.getExceptionStatements() != null) {
+
block.setExceptionStatements(rewriteStatements(block.getExceptionStatements()));
+ }
+ return block;
+ }
+ private List<Statement> rewriteStatements(List<Statement> statements)
+ throws TeiidComponentException, TeiidProcessingException {
+ Iterator<Statement> stmtIter = statements.iterator();
+
List<Statement> newStmts = new ArrayList<Statement>(statements.size());
// plan each statement in the block
while(stmtIter.hasNext()) {
Statement stmnt = stmtIter.next();
rewriteStatement(stmnt, newStmts);
}
+ return newStmts;
+ }
- block.setStatements(newStmts);
-
- return block;
- }
-
private void rewriteStatement(Statement statement, List<Statement> newStmts)
throws TeiidComponentException, TeiidProcessingException{
Modified:
trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrPostOrderNavigator.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrPostOrderNavigator.java 2012-09-25
18:56:07 UTC (rev 4470)
+++
trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrPostOrderNavigator.java 2012-09-25
18:58:05 UTC (rev 4471)
@@ -103,6 +103,7 @@
public void visit(Block obj) {
preVisitVisitor(obj);
visitNodes(obj.getStatements());
+ visitNodes(obj.getExceptionStatements());
postVisitVisitor(obj);
}
public void visit(BranchingStatement obj) {
Modified: trunk/engine/src/main/java/org/teiid/query/sql/proc/Block.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/proc/Block.java 2012-09-25 18:56:07 UTC
(rev 4470)
+++ trunk/engine/src/main/java/org/teiid/query/sql/proc/Block.java 2012-09-25 18:58:05 UTC
(rev 4471)
@@ -27,6 +27,7 @@
import org.teiid.core.util.EquivalenceUtil;
import org.teiid.core.util.StringUtil;
+import org.teiid.query.sql.LanguageObject;
import org.teiid.query.sql.LanguageVisitor;
import org.teiid.query.sql.ProcedureReservedWords;
import org.teiid.query.sql.lang.Command;
@@ -46,6 +47,9 @@
private List<Statement> statements;
private boolean atomic;
private String label;
+
+ private String exceptionGroup;
+ private List<Statement> exceptionStatements;
/**
* Constructor for Block.
@@ -92,11 +96,15 @@
* @param statement The <code>Statement</code> to be added to the block
*/
public void addStatement(Statement statement) {
+ addStatement(statement, false);
+ }
+
+ public void addStatement(Statement statement, boolean exception) {
if (statement instanceof AssignmentStatement) {
AssignmentStatement stmt = (AssignmentStatement)statement;
Command cmd = stmt.getCommand();
if (cmd != null) {
- statements.add(new CommandStatement(cmd));
+ internalAddStatement(new CommandStatement(cmd), exception);
stmt.setCommand(null);
stmt.setExpression(null);
if
(stmt.getVariable().getShortName().equalsIgnoreCase(ProcedureReservedWords.ROWCOUNT)
@@ -107,8 +115,19 @@
stmt.setExpression(new ElementSymbol(fullName));
}
}
- statements.add(statement);
+ internalAddStatement(statement, exception);
}
+
+ private void internalAddStatement(Statement statement, boolean exception) {
+ if (exception) {
+ if (this.exceptionStatements == null) {
+ exceptionStatements = new ArrayList<Statement>();
+ }
+ exceptionStatements.add(statement);
+ } else {
+ statements.add(statement);
+ }
+ }
// =========================================================================
// P R O C E S S I N G M E T H O D S
@@ -125,9 +144,11 @@
public Block clone() {
Block copy = new Block();
copy.setAtomic(atomic);
- for (Statement statement : statements) {
- copy.addStatement((Statement)statement.clone());
+ copy.statements = LanguageObject.Util.deepClone(statements, Statement.class);
+ if (exceptionStatements != null) {
+ copy.exceptionStatements = LanguageObject.Util.deepClone(exceptionStatements,
Statement.class);
}
+ copy.exceptionGroup = this.exceptionGroup;
copy.setLabel(label);
return copy;
}
@@ -154,7 +175,9 @@
// Compare the statements on the block
return this.atomic == other.atomic
&& StringUtil.equalsIgnoreCase(label, other.label)
- && EquivalenceUtil.areEqual(getStatements(), other.getStatements());
+ && EquivalenceUtil.areEqual(getStatements(), other.getStatements())
+ && EquivalenceUtil.areEqual(exceptionGroup, exceptionGroup)
+ && EquivalenceUtil.areEqual(exceptionStatements, exceptionStatements);
}
/**
@@ -188,5 +211,21 @@
public int getType() {
return Statement.TYPE_COMPOUND;
}
+
+ public String getExceptionGroup() {
+ return exceptionGroup;
+ }
+
+ public void setExceptionGroup(String exceptionGroup) {
+ this.exceptionGroup = exceptionGroup;
+ }
+
+ public List<Statement> getExceptionStatements() {
+ return exceptionStatements;
+ }
+
+ public void setExceptionStatements(List<Statement> exceptionStatements) {
+ this.exceptionStatements = exceptionStatements;
+ }
}// END CLASS
Modified: trunk/engine/src/main/java/org/teiid/query/sql/proc/ExceptionExpression.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/sql/proc/ExceptionExpression.java 2012-09-25
18:56:07 UTC (rev 4470)
+++
trunk/engine/src/main/java/org/teiid/query/sql/proc/ExceptionExpression.java 2012-09-25
18:58:05 UTC (rev 4471)
@@ -36,7 +36,6 @@
private Expression sqlState;
private Expression errorCode;
private Expression parent;
- private boolean warning;
@Override
public Class<?> getType() {
@@ -58,13 +57,12 @@
return EquivalenceUtil.areEqual(message, other.message)
&& EquivalenceUtil.areEqual(sqlState, other.sqlState)
&& EquivalenceUtil.areEqual(errorCode, other.errorCode)
- && EquivalenceUtil.areEqual(parent, other.parent)
- && warning == other.warning;
+ && EquivalenceUtil.areEqual(parent, other.parent);
}
@Override
public int hashCode() {
- return HashCodeUtil.hashCode(warning?0:1, message, sqlState, errorCode);
+ return HashCodeUtil.hashCode(0, message, sqlState, errorCode);
}
@Override
@@ -75,7 +73,6 @@
@Override
public ExceptionExpression clone() {
ExceptionExpression clone = new ExceptionExpression();
- clone.warning = this.warning;
if (this.message != null) {
clone.message = (Expression) this.message.clone();
}
@@ -123,23 +120,12 @@
this.parent = parent;
}
- public boolean isWarning() {
- return warning;
- }
-
- public void setWarning(boolean warning) {
- this.warning = warning;
- }
-
@Override
public void acceptVisitor(LanguageVisitor visitor) {
visitor.visit(this);
}
public String getDefaultSQLState() {
- if (isWarning()) {
- return "01000";
- }
return "50001";
}
Modified: trunk/engine/src/main/java/org/teiid/query/sql/proc/RaiseStatement.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/proc/RaiseStatement.java 2012-09-25
18:56:07 UTC (rev 4470)
+++ trunk/engine/src/main/java/org/teiid/query/sql/proc/RaiseStatement.java 2012-09-25
18:58:05 UTC (rev 4471)
@@ -35,6 +35,7 @@
public class RaiseStatement extends Statement implements ExpressionStatement {
private Expression expression;
+ private boolean warning;
public RaiseStatement() {
}
@@ -46,6 +47,11 @@
public RaiseStatement(Expression message) {
expression = message;
}
+
+ public RaiseStatement(Expression message, boolean warning) {
+ expression = message;
+ this.warning = warning;
+ }
public void acceptVisitor(LanguageVisitor visitor) {
visitor.visit(this);
@@ -65,7 +71,7 @@
@Override
public RaiseStatement clone() {
- return new RaiseStatement((Expression) this.expression.clone());
+ return new RaiseStatement((Expression) this.expression.clone(), warning);
}
@Override
@@ -84,12 +90,20 @@
RaiseStatement other = (RaiseStatement)obj;
- return other.expression.equals(this.expression);
+ return other.expression.equals(this.expression) && this.warning ==
other.warning;
}
@Override
public Class<?> getExpectedType() {
return DataTypeManager.DefaultDataClasses.OBJECT;
}
+
+ public boolean isWarning() {
+ return warning;
+ }
+
+ public void setWarning(boolean warning) {
+ this.warning = warning;
+ }
} // END CLASS
\ No newline at end of file
Modified: trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java 2012-09-25
18:56:07 UTC (rev 4470)
+++
trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java 2012-09-25
18:58:05 UTC (rev 4471)
@@ -47,6 +47,7 @@
import org.teiid.query.sql.lang.TextTable.TextColumn;
import org.teiid.query.sql.lang.XMLTable.XMLColumn;
import org.teiid.query.sql.proc.*;
+import org.teiid.query.sql.proc.BranchingStatement.BranchingMode;
import org.teiid.query.sql.proc.Statement.Labeled;
import org.teiid.query.sql.symbol.*;
import org.teiid.query.sql.symbol.AggregateSymbol.Type;
@@ -1376,7 +1377,21 @@
append(ATOMIC);
}
append("\n"); //$NON-NLS-1$
- Iterator<Statement> stmtIter = statements.iterator();
+ addStatements(statements);
+ if (obj.getExceptionGroup() != null) {
+ append(NonReserved.EXCEPTION);
+ append(SPACE);
+ outputDisplayName(obj.getExceptionGroup());
+ append("\n"); //$NON-NLS-1$
+ if (obj.getExceptionStatements() != null) {
+ addStatements(obj.getExceptionStatements());
+ }
+ }
+ append(END);
+ }
+
+ private void addStatements(List<Statement> statements) {
+ Iterator<Statement> stmtIter = statements.iterator();
while (stmtIter.hasNext()) {
// Add each statement
addTabs(1);
@@ -1384,8 +1399,7 @@
append("\n"); //$NON-NLS-1$
}
addTabs(0);
- append(END);
- }
+ }
private void addLabel(Labeled obj) {
if (obj.getLabel() != null) {
@@ -1464,17 +1478,17 @@
public void visit( RaiseStatement obj ) {
append(NonReserved.RAISE);
append(SPACE);
+ if (obj.isWarning()) {
+ append(SQLWARNING);
+ append(SPACE);
+ }
visitNode(obj.getExpression());
append(";"); //$NON-NLS-1$
}
@Override
public void visit(ExceptionExpression exceptionExpression) {
- if (exceptionExpression.isWarning()) {
- append(SQLWARNING);
- } else {
- append(SQLEXCEPTION);
- }
+ append(SQLEXCEPTION);
append(SPACE);
visitNode(exceptionExpression.getMessage());
if (exceptionExpression.getSqlState() != null) {
@@ -1490,7 +1504,7 @@
}
if (exceptionExpression.getParent() != null) {
append(SPACE);
- append(NonReserved.EXCEPTION);
+ append(NonReserved.CHAIN);
append(SPACE);
append(exceptionExpression.getParent());
}
@@ -1525,7 +1539,7 @@
append(") "); //$NON-NLS-1$
append(AS);
append(" "); //$NON-NLS-1$
- append(obj.getCursorName());
+ outputDisplayName(obj.getCursorName());
append("\n"); //$NON-NLS-1$
addTabs(0);
visitNode(obj.getBlock());
Modified: trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj
===================================================================
--- trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj 2012-09-25 18:56:07
UTC (rev 4470)
+++ trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj 2012-09-25 18:58:05
UTC (rev 4471)
@@ -457,6 +457,7 @@
| <VARIADIC: "variadic">
| <EXCEPTION: "exception">
| <RAISE: "raise">
+| <CHAIN: "chain">
}
/*
@@ -564,7 +565,7 @@
|<TO_BYTES>|<TIMESTAMPADD>|<TIMESTAMPDIFF>|<QUERYSTRING>|<NAMESPACE>|<RESULT>|<INDEX>|<ACCESSPATTERN>|<AUTO_INCREMENT>|<WELLFORMED>|<SQL_TSI_FRAC_SECOND>
|<SQL_TSI_SECOND>|<SQL_TSI_MINUTE>|<SQL_TSI_HOUR>|<SQL_TSI_DAY>|<SQL_TSI_WEEK>|<SQL_TSI_MONTH>|<SQL_TSI_QUARTER>|<SQL_TSI_YEAR>|<TEXTTABLE>|<ARRAYTABLE>
|<SELECTOR>|<SKIP_KEYWORD>|<WIDTH>|<PASSING>|<NAME>|<ENCODING>|<COLUMNS>|<DELIMITER>|<QUOTE>|<HEADER>|<NULLS>|<OBJECTTABLE>
-
|<VERSION>|<INCLUDING>|<EXCLUDING>|<XMLDECLARATION>|<VARIADIC>|<RAISE>|<EXCEPTION>)
+
|<VERSION>|<INCLUDING>|<EXCLUDING>|<XMLDECLARATION>|<VARIADIC>|<RAISE>|<EXCEPTION>|<CHAIN>)
{
return getToken(0);
}
@@ -910,12 +911,14 @@
RaiseStatement raiseStatement(ParseInfo info) :
{
Expression err = null;
+ boolean warning = false;
}
{
<RAISE>
+ [<SQLWARNING> {warning = true;}]
err = exceptionReference(info)
{
- return new RaiseStatement(err);
+ return new RaiseStatement(err, warning);
}
}
@@ -949,22 +952,20 @@
Expression sqlState = null;
Expression errCode = null;
Expression parent = null;
- boolean warning = false;
}
{
- (<SQLWARNING> {warning=true;}|<SQLEXCEPTION>)
+ <SQLEXCEPTION>
err = commonValueExpression(info)
[<SQLSTATE> sqlState = commonValueExpression(info)
[<COMMA> errCode = commonValueExpression(info)]
]
- [<EXCEPTION> parent = exceptionReference(info)]
+ [<CHAIN> parent = exceptionReference(info)]
{
ExceptionExpression ee = new ExceptionExpression();
ee.setMessage(err);
ee.setSqlState(sqlState);
ee.setErrorCode(errCode);
ee.setParent(parent);
- ee.setWarning(warning);
return ee;
}
}
@@ -1013,7 +1014,7 @@
Statement stmt = null;
}
{
- (stmt = assignStatement(info) |
+ (LOOKAHEAD(2) stmt = assignStatement(info) |
stmt = sqlStatement(info) |
stmt = errorStatement(info) |
stmt = raiseStatement(info) |
@@ -1036,15 +1037,24 @@
Statement stmt = null;
Block block = new Block();
Boolean atomic = null;
+ String eId = null;
}
{
<BEGIN> [[<NOT> {atomic = Boolean.FALSE;}] <ATOMIC> {if (atomic ==
null) {atomic = Boolean.TRUE;}}]
- (
+ (LOOKAHEAD(2)
stmt = statement(info)
{
- block.addStatement(stmt);
+ block.addStatement(stmt, false);
}
)*
+ [<EXCEPTION> eId = id() {block.setExceptionGroup(validateAlias(eId));}
+ (
+ stmt = statement(info)
+ {
+ block.addStatement(stmt, true);
+ }
+ )*
+ ]
<END>
{
if (atomic != null) {
@@ -1200,13 +1210,13 @@
Statement assignStatement(ParseInfo info) :
{
LanguageObject value = null;
- Token var = null;
+ String var = null;
ElementSymbol elementID = null;
}
{
- var = <ID>
+ var = id()
{
- elementID = new ElementSymbol(normalizeId(var.image));
+ elementID = new ElementSymbol(var);
}
[<COLON>]<EQ>
(value = assignStatementOperand(info) |
Modified: trunk/engine/src/main/resources/org/teiid/query/i18n.properties
===================================================================
--- trunk/engine/src/main/resources/org/teiid/query/i18n.properties 2012-09-25 18:56:07
UTC (rev 4470)
+++ trunk/engine/src/main/resources/org/teiid/query/i18n.properties 2012-09-25 18:58:05
UTC (rev 4471)
@@ -210,7 +210,7 @@
ERR.015.012.0062 = Elements cannot appear more than once in a SET or USING clause. The
following elements are duplicated: {0}
ERR.015.012.0063 = Multiple failures occurred during validation:
ERR.015.012.0064 = Validation succeeded
-TEIID30124=Nested Loop can not use the same cursor name as that of its parent.
+TEIID30124=Loop cursor or exception group name {0} already exists.
ERR.015.012.0067 = No scalar subqueries are allowed in the SELECT with no FROM clause.
ERR.015.012.0069 = INTO clause can not be used in XML query.
@@ -673,7 +673,7 @@
QueryResolver.invalid_xpath=Invalid xpath value: {0}
TEIID30066=The definition for {0} does not have the correct number of projected symbols.
Expected {1}, but was {2}.
QueryResolver.wrong_view_symbol_type=The definition for {0} has the wrong type for column
{1}. Expected {2}, but was {3}.
-ResolveVariablesVisitor.reserved_word_for_temporary_used=Cursor names cannot begin with
"#" as that indicates the name of a temporary table: {0}.
+TEIID30125=Cursor or exception group names cannot begin with "#" as that
indicates the name of a temporary table: {0}.
SimpleQueryResolver.materialized_table_not_used=The query against {0} did not use
materialization table {1} due to the use of OPTION NOCACHE.
SimpleQueryResolver.cache_hint_used=Loading materialized view {1} for view {0} using
cache hint {2}.
SimpleQueryResolver.procedure_cache_used=Procedure caching will be used for {0}.
Modified: trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java 2012-09-25 18:56:07
UTC (rev 4470)
+++ trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java 2012-09-25 18:58:05
UTC (rev 4471)
@@ -3021,12 +3021,11 @@
@Test public void testRaiseErrorStatement() throws Exception {
ExceptionExpression ee = new ExceptionExpression();
ee.setMessage(new Constant("Test only"));
- ee.setWarning(true);
ee.setSqlState(new Constant("100"));
ee.setParent(new ElementSymbol("e"));
- RaiseStatement errStmt = new RaiseStatement(ee);
+ RaiseStatement errStmt = new RaiseStatement(ee, true);
- helpStmtTest("RAISE SQLWARNING 'Test only' SQLSTATE '100'
EXCEPTION e;", "RAISE SQLWARNING 'Test only' SQLSTATE '100'
EXCEPTION e;", //$NON-NLS-1$ //$NON-NLS-2$
+ helpStmtTest("RAISE SQLWARNING SQLEXCEPTION 'Test only' SQLSTATE
'100' chain e;", "RAISE SQLWARNING SQLEXCEPTION 'Test only'
SQLSTATE '100' CHAIN e;", //$NON-NLS-1$ //$NON-NLS-2$
errStmt);
}
@@ -5270,5 +5269,17 @@
@Test public void testTextTableNegativeWidth() {
helpException("SELECT * from texttable(null columns x string width -1) as
x");
}
+
+ @Test public void testBlockExceptionHandling() throws ParseException {
+ CommandStatement cmdStmt = new CommandStatement(new Query(new
Select(Arrays.asList(new MultipleElementSymbol())), new From(Arrays.asList(new
UnaryFromClause(new GroupSymbol("x")))), null, null, null));
+ AssignmentStatement assigStmt = new AssignmentStatement(new
ElementSymbol("a"), new Constant(new Integer(1))); //$NON-NLS-1$
+ RaiseStatement errStmt = new RaiseStatement(new Constant("My Error"));
//$NON-NLS-1$
+ Block b = new Block();
+ b.setExceptionGroup("g");
+ b.addStatement(cmdStmt);
+ b.addStatement(assigStmt);
+ b.addStatement(errStmt, true);
+ helpStmtTest("BEGIN\nselect * from x;\na = 1;\nexception e\nERROR 'My
Error';\nEND", "BEGIN\nSELECT * FROM x;\na = 1;\nEXCEPTION e\nRAISE
SQLEXCEPTION 'My Error';\nEND", b); //$NON-NLS-1$
+ }
}
Modified: trunk/engine/src/test/java/org/teiid/query/processor/proc/TestProcErrors.java
===================================================================
---
trunk/engine/src/test/java/org/teiid/query/processor/proc/TestProcErrors.java 2012-09-25
18:56:07 UTC (rev 4470)
+++
trunk/engine/src/test/java/org/teiid/query/processor/proc/TestProcErrors.java 2012-09-25
18:58:05 UTC (rev 4471)
@@ -25,10 +25,12 @@
import static org.junit.Assert.*;
import static org.teiid.query.processor.proc.TestProcedureProcessor.*;
+import java.util.Arrays;
+import java.util.List;
+
import org.junit.Test;
import org.teiid.core.TeiidProcessingException;
import org.teiid.jdbc.TeiidSQLException;
-import org.teiid.jdbc.TeiidSQLWarning;
import org.teiid.query.metadata.TransformationMetadata;
import org.teiid.query.processor.HardcodedDataManager;
import org.teiid.query.processor.ProcessorPlan;
@@ -39,7 +41,7 @@
@Test public void testInvalidException() throws Exception {
String ddl =
- "create virtual procedure vproc (x integer) returns integer as begin declare
object e = sqlwarning 'hello'; raise e; raise sqlexception 'hello world'
sqlstate 'abc', 1 exception e; end;";
+ "create virtual procedure vproc (x integer) returns integer as begin declare
object e = sqlexception 'hello'; raise e; raise sqlexception 'hello world'
sqlstate 'abc', 1 chain e; end;";
try {
TestProcedureResolving.createMetadata(ddl);
fail();
@@ -50,7 +52,7 @@
@Test public void testExceptionAndWarning() throws Exception {
String ddl =
- "create virtual procedure vproc (x integer) returns integer as begin declare
exception e = sqlwarning 'hello'; raise e; raise sqlexception 'hello
world' sqlstate 'abc', 1 exception e; end;";
+ "create virtual procedure vproc (x integer) returns integer as begin declare
exception e = sqlexception 'hello'; raise sqlwarning e; raise sqlexception
'hello world' sqlstate 'abc', 1 chain e; end;";
TransformationMetadata tm = TestProcedureResolving.createMetadata(ddl);
String sql = "call vproc(1)"; //$NON-NLS-1$
@@ -63,7 +65,7 @@
helpTestProcess(plan, null, dataManager, tm);
fail();
} catch (TeiidProcessingException e) {
- TeiidSQLWarning tsw = (TeiidSQLWarning)
plan.getContext().getAndClearWarnings().get(0);
+ TeiidSQLException tsw = (TeiidSQLException)
plan.getContext().getAndClearWarnings().get(0);
assertEquals("hello", tsw.getMessage());
assertEquals(e.getCause().getCause(), tsw);
@@ -74,5 +76,28 @@
}
}
+
+ @Test public void testExceptionHandling() throws Exception {
+ String ddl =
+ "create virtual procedure vproc (x integer) returns integer as begin "
+
+ "raise sqlexception 'hello world' sqlstate 'abc', 1;" +
+ "exception e " +
+ "raise sqlwarning sqlexception 'caught' chain e.exception; " +
+ "\"return\" = 1;"+
+ "end;";
+ TransformationMetadata tm = TestProcedureResolving.createMetadata(ddl);
+
+ String sql = "call vproc(1)"; //$NON-NLS-1$
+
+ ProcessorPlan plan = getProcedurePlan(sql, tm);
+
+ HardcodedDataManager dataManager = new HardcodedDataManager(tm);
+
+ helpTestProcess(plan, new List[] {Arrays.asList(1)}, dataManager, tm);
+
+ TeiidSQLException tse =
(TeiidSQLException)plan.getContext().getAndClearWarnings().get(0);
+ assertEquals("caught", tse.getMessage());
+ assertEquals("hello world", tse.getCause().getMessage());
+ }
}
Modified: trunk/engine/src/test/java/org/teiid/query/resolver/TestProcedureResolving.java
===================================================================
---
trunk/engine/src/test/java/org/teiid/query/resolver/TestProcedureResolving.java 2012-09-25
18:56:07 UTC (rev 4470)
+++
trunk/engine/src/test/java/org/teiid/query/resolver/TestProcedureResolving.java 2012-09-25
18:58:05 UTC (rev 4471)
@@ -807,7 +807,7 @@
String userUpdateStr = "UPDATE vm1.g1 SET e1='x'";
//$NON-NLS-1$
helpFailUpdateProcedure(proc.toString(), userUpdateStr,
- Table.TriggerEvent.UPDATE, "TEIID30124 Nested
Loop can not use the same cursor name as that of its parent."); //$NON-NLS-1$
+ Table.TriggerEvent.UPDATE, "TEIID30124 Loop
cursor or exception group name loopCursor already exists."); //$NON-NLS-1$
}
@Test public void testTempGroupElementShouldNotBeResolable() {
@@ -978,7 +978,7 @@
//cursor starts with "#" Defect14924
@Test public void testVirtualProcedureInvalid1() throws Exception {
- helpResolveException("EXEC
pm1.vsp32()",RealMetadataFactory.example1Cached(), "TEIID30125 Cursor names
cannot begin with \"#\" as that indicates the name of a temporary table:
#mycursor."); //$NON-NLS-1$ //$NON-NLS-2$
+ helpResolveException("EXEC
pm1.vsp32()",RealMetadataFactory.example1Cached(), "TEIID30125 Cursor or
exception group names cannot begin with \"#\" as that indicates the name of a
temporary table: #mycursor."); //$NON-NLS-1$ //$NON-NLS-2$
}
@Test public void testVirtualProcedureWithOrderBy() throws Exception {
@@ -1002,7 +1002,7 @@
}
@Test public void testLoopRedefinition2() throws Exception {
- helpResolveException("EXEC pm1.vsp11()",
RealMetadataFactory.example1Cached(), "TEIID30124 Nested Loop can not use the same
cursor name as that of its parent."); //$NON-NLS-1$ //$NON-NLS-2$
+ helpResolveException("EXEC pm1.vsp11()",
RealMetadataFactory.example1Cached(), "TEIID30124 Loop cursor or exception group name
mycursor already exists."); //$NON-NLS-1$ //$NON-NLS-2$
}
@Test public void testVariableResolutionWithIntervening() throws Exception {