Reference Guide > Custom Procedure Examples > Example 5: Expression Evaluator
 
Example 5: Expression Evaluator
This custom procedure evaluates simple expressions.
package proc;
 
import com.compositesw.extension.*;
import java.sql.SQLException;
import java.sql.Types;
 
/**
* Custom procedure to evaluate simple expressions:
*
* ARG1 | ARG2
* ARG1 if it is neither null nor 0, otherwise ARG2
*
* ARG1 & ARG2
* ARG1 if neither argument is null or 0, otherwise 0
*
* ARG1 < ARG2
* ARG1 is less than ARG2
*
* ARG1 <= ARG2
* ARG1 is less than or equal to ARG2
*
* ARG1 = ARG2
* ARG1 is equal to ARG2
*
* ARG1 != ARG2
* ARG1 is unequal to ARG2
*
* ARG1 >= ARG2
* ARG1 is greater than or equal to ARG2
*
* ARG1 > ARG2
* ARG1 is greater than ARG2
*
* ARG1 + ARG2
* arithmetic sum of ARG1 and ARG2
*
* ARG1 - ARG2
* arithmetic difference of ARG1 and ARG2
*
* ARG1 * ARG2
* arithmetic product of ARG1 and ARG2
*
* ARG1 / ARG2
* arithmetic quotient of ARG1 divided by ARG2
*
* ARG1 % ARG2
* arithmetic remainder of ARG1 divided by ARG2
*/
 
public class ExpressionEvaluator
 
implements CustomProcedure
{
private ExecutionEnvironment qenv;
private int result;
public ExpressionEvaluator() { }
/**
* This is called once just after constructing the class. The
* environment contains methods used to interact with the server.
*/
 
public void initialize(ExecutionEnvironment qenv)
throws SQLException
{
this.qenv = qenv;
}
 
/**
* Called during introspection to get the description of the input
* and output parameters. Should not return null.
*/
 
public ParameterInfo[] getParameterInfo() {
return new ParameterInfo[] {
new ParameterInfo("arg1", Types.INTEGER, DIRECTION_IN),
new ParameterInfo("operator", Types.VARCHAR, DIRECTION_IN),
new ParameterInfo("arg2", Types.INTEGER, DIRECTION_IN),
new ParameterInfo("result", Types.INTEGER, DIRECTION_OUT),
};
}
 
/**
* Called to invoke the stored procedure. Will only be called a
* single time per instance. Can throw CustomProcedureException or
* SQLException if there is an error during invoke.
*/
 
public void invoke(Object[] inputValues)
throws CustomProcedureException, SQLException
{
int arg1 =
(inputValues[0] != null ? ((Integer)inputValues[0]).intValue() : 0);
String op = (String)inputValues[1];
int arg2 =
(inputValues[2] != null ? ((Integer)inputValues[2]).intValue() : 0);
if (op.equals("|"))
result = (arg1 != 0) ? arg1 : arg2;
else if (op.equals("&"))
result = (arg1 != 0 && arg2 != 0) ? arg1 : 0;
else if (op.equals("<"))
result = (arg1 < arg2) ? 1 : 0;
else if (op.equals("<="))
result = (arg1 <= arg2) ? 1 : 0;
else if (op.equals("="))
result = (arg1 == arg2) ? 1 : 0;
else if (op.equals("!="))
result = (arg1 != arg2) ? 1 : 0;
else if (op.equals(">="))
result = (arg1 >= arg2) ? 1 : 0;
else if (op.equals(">"))
result = (arg1 > arg2) ? 1 : 0;
else if (op.equals("+"))
result = arg1 + arg2;
else if (op.equals("-"))
result = arg1 - arg2;
else if (op.equals("*"))
result = arg1 * arg2;
else if (op.equals("/"))
result = arg1 / arg2;
else if (op.equals("%"))
result = arg1 % arg2;
else
throw new CustomProcedureException("Unknown operator: " + op);
}
 
/**
* Called to retrieve the number of rows that were inserted,
* updated, or deleted during the execution of the procedure. A
* return value of -1 indicates that the number of affected rows is
* unknown. Can throw CustomProcedureException or SQLException if
* there is an error when getting the number of affected rows.
*/
 
public int getNumAffectedRows() {
return 0;
}
 
/**
* Called to retrieve the output values. The returned objects
* should obey the Java to SQL typing conventions as defined in the
* table above. Output cursors can be returned as either
* CustomCursor or java.sql.ResultSet. Can throw
* CustomProcedureException or SQLException if there is an error
* when getting the output values. Should not return null.
*/
 
public Object[] getOutputValues() {
return new Object[] { new Integer(result) };
}
 
/**
* Called when the procedure reference is no longer needed. Close
* can be called without retrieving any of the output values (such
* as cursors) or even invoking, so this needs to do any remaining
* cleanup. Close can be called concurrently with any other call
* such as "invoke" or "getOutputValues". In this case, any pending
* methods should immediately throw a CustomProcedureException.
*/
 
public void close()
throws SQLException
{ }
 
//
// Introspection methods
//
/**
* Called during introspection to get the short name of the stored
* procedure. This name can be overridden during configuration.
* Should not return null.
*/
 
public String getName() {
return "expr";
}
/**
* Called during introspection to get the description of the stored
* procedure. Should not return null.
*/
 
public String getDescription() {
return "Custom procedure to evaluate simple expressions";
}
 
//
// Transaction methods
//
 
/**
* Returns true if the custom procedure uses transactions. If this
* method returns false then commit and rollback will not be called.
*/
 
public boolean canCommit() {
return false;
}
 
/**
* Commit any open transactions.
*/
 
public void commit()
throws SQLException
{ }
 
/**
* Rollback any open transactions.
*/
 
public void rollback()
throws SQLException
{ }
 
/**
* Returns true if the transaction can be compensated.
*/
 
public boolean canCompensate() {
return false;
}
 
/**
* Compensate any committed transactions (if supported).
*/
 
public void compensate(ExecutionEnvironment qenv)
throws SQLException
{ }
}