use of org.teiid.api.exception.query.QueryValidatorException in project teiid by teiid.
the class TestProcedureProcessor method testEvaluatableLimit.
@Test
public void testEvaluatableLimit() throws Exception {
TransformationMetadata metadata = RealMetadataFactory.example1();
StringBuffer procedure = // $NON-NLS-1$
new StringBuffer("CREATE VIRTUAL PROCEDURE \n").append(// $NON-NLS-1$
"BEGIN\n").append(// $NON-NLS-1$
"SELECT e1 from pm1.g1 limit param;\n").append(// $NON-NLS-1$
"END");
addProc(metadata, "sq1", procedure.toString(), new String[] { "e1" }, new String[] { DataTypeManager.DefaultDataTypes.STRING }, new String[] { "param" }, new String[] { DataTypeManager.DefaultDataTypes.INTEGER });
FakeDataManager dataMgr = exampleDataManager(metadata);
// $NON-NLS-1$
String userUpdateStr = "EXEC pm1.sq1(1)";
ProcessorPlan plan = getProcedurePlan(userUpdateStr, metadata);
helpTestProcess(plan, new List[] { Arrays.asList(new Object[] { "First" }) }, dataMgr, // $NON-NLS-1$
metadata);
// $NON-NLS-1$
userUpdateStr = "EXEC pm1.sq1(-1)";
plan = getProcedurePlan(userUpdateStr, metadata);
try {
helpTestProcess(plan, new List[] { Arrays.asList(new Object[] { "First" }) }, dataMgr, // $NON-NLS-1$
metadata);
fail();
} catch (QueryValidatorException e) {
// shouldn't allow -1
}
}
use of org.teiid.api.exception.query.QueryValidatorException in project teiid by teiid.
the class QueryRewriter method rewriteSelectInto.
/**
* This method will alias each of the select into elements to the corresponding column name in the
* target table. This ensures that they will all be uniquely named.
*
* @param query
* @throws QueryValidatorException
*/
private Command rewriteSelectInto(Query query) throws TeiidProcessingException {
Into into = query.getInto();
try {
List<ElementSymbol> allIntoElements = Util.deepClone(ResolverUtil.resolveElementsInGroup(into.getGroup(), metadata), ElementSymbol.class);
Insert insert = new Insert(into.getGroup(), allIntoElements, Collections.emptyList());
insert.setSourceHint(query.getSourceHint());
query.setSourceHint(null);
query.setInto(null);
insert.setQueryExpression(query);
return rewriteInsert(correctDatatypes(insert));
} catch (QueryMetadataException e) {
throw new QueryValidatorException(e);
} catch (TeiidComponentException e) {
throw new QueryValidatorException(e);
}
}
use of org.teiid.api.exception.query.QueryValidatorException in project teiid by teiid.
the class QueryRewriter method simplifyMathematicalCriteria.
/**
* @param criteria
* @return CompareCriteria
*/
private CompareCriteria simplifyMathematicalCriteria(CompareCriteria criteria) throws TeiidProcessingException {
Expression leftExpr = criteria.getLeftExpression();
Expression rightExpr = criteria.getRightExpression();
// Identify all the pieces of this criteria
Function function = (Function) leftExpr;
String funcName = function.getName();
Expression[] args = function.getArgs();
Constant const1 = null;
Expression expr = null;
if (args[1] instanceof Constant) {
const1 = (Constant) args[1];
expr = args[0];
} else {
if (funcName.equals("+") || funcName.equals("*")) {
// $NON-NLS-1$ //$NON-NLS-2$
const1 = (Constant) args[0];
expr = args[1];
} else {
// If we have "5 - x = 10" or "5 / x = 10", abort!
return criteria;
}
}
int operator = criteria.getOperator();
// Determine opposite function
String oppFunc = null;
switch(funcName.charAt(0)) {
// $NON-NLS-1$
case '+':
oppFunc = "-";
break;
// $NON-NLS-1$
case '-':
oppFunc = "+";
break;
// $NON-NLS-1$
case '*':
oppFunc = "/";
break;
// $NON-NLS-1$
case '/':
oppFunc = "*";
break;
}
// Create a function of the two constants and evaluate it
Expression combinedConst = null;
FunctionLibrary funcLib = this.metadata.getFunctionLibrary();
FunctionDescriptor descriptor = funcLib.findFunction(oppFunc, new Class[] { rightExpr.getType(), const1.getType() });
if (descriptor == null) {
// See defect 9380 - this can be caused by const2 being a null Constant, for example (? + 1) < null
return criteria;
}
if (rightExpr instanceof Constant) {
Constant const2 = (Constant) rightExpr;
try {
Object result = descriptor.invokeFunction(new Object[] { const2.getValue(), const1.getValue() }, null, this.context);
combinedConst = new Constant(result, descriptor.getReturnType());
} catch (FunctionExecutionException e) {
throw new QueryValidatorException(QueryPlugin.Event.TEIID30373, e, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30373, e.getMessage()));
} catch (BlockedException e) {
throw new QueryValidatorException(QueryPlugin.Event.TEIID30373, e, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30373, e.getMessage()));
}
} else {
Function conversion = new Function(descriptor.getName(), new Expression[] { rightExpr, const1 });
conversion.setType(leftExpr.getType());
conversion.setFunctionDescriptor(descriptor);
combinedConst = conversion;
}
// Flip operator if necessary
if (!(operator == CompareCriteria.EQ || operator == CompareCriteria.NE) && (oppFunc.equals("*") || oppFunc.equals("/"))) {
// $NON-NLS-1$ //$NON-NLS-2$
Object value = const1.getValue();
if (value != null) {
Class type = const1.getType();
Comparable comparisonObject = null;
if (type.equals(DataTypeManager.DefaultDataClasses.INTEGER)) {
comparisonObject = INTEGER_ZERO;
} else if (type.equals(DataTypeManager.DefaultDataClasses.DOUBLE)) {
comparisonObject = DOUBLE_ZERO;
} else if (type.equals(DataTypeManager.DefaultDataClasses.FLOAT)) {
comparisonObject = FLOAT_ZERO;
} else if (type.equals(DataTypeManager.DefaultDataClasses.LONG)) {
comparisonObject = LONG_ZERO;
} else if (type.equals(DataTypeManager.DefaultDataClasses.BIG_INTEGER)) {
comparisonObject = BIG_INTEGER_ZERO;
} else if (type.equals(DataTypeManager.DefaultDataClasses.BIG_DECIMAL)) {
comparisonObject = BIG_DECIMAL_ZERO;
} else if (type.equals(DataTypeManager.DefaultDataClasses.SHORT)) {
comparisonObject = SHORT_ZERO;
} else if (type.equals(DataTypeManager.DefaultDataClasses.BYTE)) {
comparisonObject = BYTE_ZERO;
} else {
// Unknown type
return criteria;
}
// then need to switch operator.
if (comparisonObject.compareTo(value) > 0) {
switch(operator) {
case CompareCriteria.LE:
operator = CompareCriteria.GE;
break;
case CompareCriteria.LT:
operator = CompareCriteria.GT;
break;
case CompareCriteria.GE:
operator = CompareCriteria.LE;
break;
case CompareCriteria.GT:
operator = CompareCriteria.LT;
break;
}
}
}
}
criteria.setLeftExpression(expr);
criteria.setRightExpression(combinedConst);
criteria.setOperator(operator);
// Return new simplified criteria
return criteria;
}
use of org.teiid.api.exception.query.QueryValidatorException in project teiid by teiid.
the class ValidationVisitor method visit.
public void visit(Insert obj) {
validateGroupSupportsUpdate(obj.getGroup());
validateInsert(obj);
try {
if (obj.isUpsert()) {
Collection keys = getMetadata().getUniqueKeysInGroup(obj.getGroup().getMetadataID());
if (keys.isEmpty()) {
handleValidationError(QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31132, obj.getGroup()), obj);
} else {
Set<Object> keyCols = new LinkedHashSet<Object>(getMetadata().getElementIDsInKey(keys.iterator().next()));
for (ElementSymbol es : obj.getVariables()) {
keyCols.remove(es.getMetadataID());
}
if (!keyCols.isEmpty()) {
handleValidationError(QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31133, obj.getGroup(), obj.getVariables()), obj);
}
}
}
} catch (QueryMetadataException e1) {
handleException(e1);
} catch (TeiidComponentException e1) {
handleException(e1);
}
if (obj.getQueryExpression() != null) {
validateMultisourceInsert(obj.getGroup());
}
if (obj.getUpdateInfo() != null && obj.getUpdateInfo().isInherentInsert()) {
validateUpdate(obj, Command.TYPE_INSERT, obj.getUpdateInfo());
try {
if (obj.getUpdateInfo().findInsertUpdateMapping(obj, false) == null) {
handleValidationError(QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30376, obj.getVariables()), obj);
}
} catch (QueryValidatorException e) {
handleValidationError(e.getMessage(), obj);
}
}
}
use of org.teiid.api.exception.query.QueryValidatorException in project teiid by teiid.
the class PreparedStatementRequest method handlePreparedBatchUpdate.
/**
* There are two cases
* if
* The source supports preparedBatchUpdate -> just let the command and values pass to the source
* else
* create a batchedupdatecommand that represents the batch operation
* @param command
* @throws QueryMetadataException
* @throws TeiidComponentException
* @throws QueryResolverException
* @throws QueryPlannerException
* @throws QueryValidatorException
*/
private void handlePreparedBatchUpdate() throws QueryMetadataException, TeiidComponentException, QueryResolverException, QueryPlannerException, QueryValidatorException {
List<List<?>> paramValues = (List<List<?>>) requestMsg.getParameterValues();
if (paramValues.isEmpty()) {
throw new QueryValidatorException(QueryPlugin.Event.TEIID30555, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30555));
}
boolean supportPreparedBatchUpdate = false;
Command command = null;
if (this.processPlan instanceof RelationalPlan) {
RelationalPlan rPlan = (RelationalPlan) this.processPlan;
if (rPlan.getRootNode() instanceof AccessNode) {
AccessNode aNode = (AccessNode) rPlan.getRootNode();
String modelName = aNode.getModelName();
command = aNode.getCommand();
SourceCapabilities caps = capabilitiesFinder.findCapabilities(modelName);
supportPreparedBatchUpdate = caps.supportsCapability(SourceCapabilities.Capability.BULK_UPDATE);
if (supportPreparedBatchUpdate && // only allow the plan if the multi-valued references result in expressions that can be pushed
!CriteriaCapabilityValidatorVisitor.canPushLanguageObject(command, metadata.getModelID(modelName), metadata, capabilitiesFinder, analysisRecord, false, false, true)) {
supportPreparedBatchUpdate = false;
}
}
}
List<Command> commands = new LinkedList<Command>();
List<VariableContext> contexts = new LinkedList<VariableContext>();
List<List<Object>> multiValues = new ArrayList<List<Object>>(this.prepPlan.getReferences().size());
for (List<?> values : paramValues) {
PreparedStatementRequest.resolveParameterValues(this.prepPlan.getReferences(), values, this.context, this.metadata);
contexts.add(this.context.getVariableContext());
if (supportPreparedBatchUpdate) {
if (multiValues.isEmpty()) {
for (int i = 0; i < values.size(); i++) {
multiValues.add(new ArrayList<Object>(paramValues.size()));
}
}
for (int i = 0; i < values.size(); i++) {
List<Object> multiValue = multiValues.get(i);
Object value = this.context.getVariableContext().getGlobalValue(this.prepPlan.getReferences().get(i).getContextSymbol());
multiValue.add(value);
}
} else {
// just accumulate copies of the command/plan - clones are not necessary
if (command == null) {
command = this.prepPlan.getCommand();
}
command.setProcessorPlan(this.processPlan);
commands.add(command);
}
}
if (paramValues.size() > 1) {
this.context.setVariableContext(new VariableContext());
}
if (paramValues.size() == 1) {
// just use the existing plan, and global reference evaluation
return;
}
if (supportPreparedBatchUpdate) {
for (int i = 0; i < this.prepPlan.getReferences().size(); i++) {
Constant c = new Constant(null, this.prepPlan.getReferences().get(i).getType());
c.setMultiValued(multiValues.get(i));
this.context.getVariableContext().setGlobalValue(this.prepPlan.getReferences().get(i).getContextSymbol(), c);
}
return;
}
BatchedUpdateCommand buc = new BatchedUpdateCommand(commands);
buc.setVariableContexts(contexts);
BatchedUpdatePlanner planner = new BatchedUpdatePlanner();
this.processPlan = planner.optimize(buc, idGenerator, metadata, capabilitiesFinder, analysisRecord, context);
}
Aggregations