use of org.apache.cayenne.access.sqlbuilder.sqltree.Node in project cayenne by apache.
the class TableTreeQualifierStage method perform.
@Override
public void perform(TranslatorContext context) {
context.getTableTree().visit(node -> {
Expression dbQualifier = node.getEntity().getQualifier();
if (dbQualifier != null) {
String pathToRoot = node.getAttributePath().getPath();
dbQualifier = dbQualifier.transform(input -> {
if (input instanceof ASTPath) {
String path = ((ASTPath) input).getPath();
if (!pathToRoot.isEmpty()) {
path = pathToRoot + '.' + path;
}
return new ASTDbPath(path);
}
return input;
});
Node rootQualifier = context.getQualifierNode();
Node translatedQualifier = context.getQualifierTranslator().translate(dbQualifier);
if (rootQualifier != null) {
NodeBuilder expressionNodeBuilder = exp(node(rootQualifier)).and(node(translatedQualifier));
context.setQualifierNode(expressionNodeBuilder.build());
} else {
context.setQualifierNode(translatedQualifier);
}
}
});
if (context.getQualifierNode() != null) {
context.getSelectBuilder().where(context.getQualifierNode());
}
}
use of org.apache.cayenne.access.sqlbuilder.sqltree.Node in project cayenne by apache.
the class FirebirdSQLTreeProcessor method onInNode.
@Override
protected void onInNode(Node parent, InNode child, int index) {
Node arg = child.getChild(0);
Node childNode = child.getChild(1);
if (childNode.getType() != NodeType.VALUE) {
return;
}
ValueNode valueNode = (ValueNode) childNode;
Object value = valueNode.getValue();
if (!value.getClass().isArray()) {
return;
}
List<Node> newChildren = new ArrayList<>();
// need to slice for batches of 1500 values
if (value instanceof Object[]) {
for (Object[] slice : ArrayUtil.sliceArray((Object[]) value, FIREBIRD_IN_BATCH_SIZE)) {
newChildren.add(newSliceNode(child, arg, valueNode, slice));
}
} else if (value instanceof int[]) {
for (int[] slice : ArrayUtil.sliceArray((int[]) value, FIREBIRD_IN_BATCH_SIZE)) {
newChildren.add(newSliceNode(child, arg, valueNode, slice));
}
} else if (value instanceof long[]) {
for (long[] slice : ArrayUtil.sliceArray((long[]) value, FIREBIRD_IN_BATCH_SIZE)) {
newChildren.add(newSliceNode(child, arg, valueNode, slice));
}
} else if (value instanceof float[]) {
for (float[] slice : ArrayUtil.sliceArray((float[]) value, FIREBIRD_IN_BATCH_SIZE)) {
newChildren.add(newSliceNode(child, arg, valueNode, slice));
}
} else if (value instanceof double[]) {
for (double[] slice : ArrayUtil.sliceArray((double[]) value, FIREBIRD_IN_BATCH_SIZE)) {
newChildren.add(newSliceNode(child, arg, valueNode, slice));
}
} else if (value instanceof short[]) {
for (short[] slice : ArrayUtil.sliceArray((short[]) value, FIREBIRD_IN_BATCH_SIZE)) {
newChildren.add(newSliceNode(child, arg, valueNode, slice));
}
} else if (value instanceof char[]) {
for (char[] slice : ArrayUtil.sliceArray((char[]) value, FIREBIRD_IN_BATCH_SIZE)) {
newChildren.add(newSliceNode(child, arg, valueNode, slice));
}
} else if (value instanceof boolean[]) {
for (boolean[] slice : ArrayUtil.sliceArray((boolean[]) value, FIREBIRD_IN_BATCH_SIZE)) {
newChildren.add(newSliceNode(child, arg, valueNode, slice));
}
} else if (value instanceof byte[]) {
for (byte[] slice : ArrayUtil.sliceArray((byte[]) value, FIREBIRD_IN_BATCH_SIZE)) {
newChildren.add(newSliceNode(child, arg, valueNode, slice));
}
}
ExpressionNodeBuilder exp = exp(node(newChildren.get(0)));
for (int i = 1; i < newChildren.size(); i++) {
exp = exp.or(node(newChildren.get(i)));
}
parent.replaceChild(index, exp.build());
}
use of org.apache.cayenne.access.sqlbuilder.sqltree.Node in project cayenne by apache.
the class FirebirdSQLTreeProcessor method onFunctionNode.
@Override
protected void onFunctionNode(Node parent, FunctionNode child, int index) {
switch(child.getFunctionName()) {
case "LENGTH":
replaceChild(parent, index, new FunctionNode("CHAR_LENGTH", child.getAlias()));
break;
case "LOCATE":
replaceChild(parent, index, new FunctionNode("POSITION", child.getAlias()));
break;
case "CONCAT":
replaceChild(parent, index, new OpExpressionNode("||"));
break;
case "SUBSTRING":
replaceChild(parent, index, new FirebirdSubstringFunctionNode(child.getAlias()));
break;
case "YEAR":
case "MONTH":
case "DAY":
case "DAY_OF_MONTH":
case "DAY_OF_WEEK":
case "DAY_OF_YEAR":
case "WEEK":
case "HOUR":
case "MINUTE":
case "SECOND":
Node functionReplacement = new FunctionNode("EXTRACT", child.getAlias(), true) {
@Override
public void appendChildrenSeparator(QuotingAppendable buffer, int childIdx) {
buffer.append(' ');
}
};
String partName = child.getFunctionName();
if ("DAY_OF_MONTH".equals(partName)) {
partName = "DAY";
} else if ("DAY_OF_WEEK".equals(partName)) {
partName = "WEEKDAY";
} else if ("DAY_OF_YEAR".equals(partName)) {
partName = "YEARDAY";
}
functionReplacement.addChild(new TextNode(partName + " FROM "));
replaceChild(parent, index, functionReplacement);
break;
}
}
use of org.apache.cayenne.access.sqlbuilder.sqltree.Node in project cayenne by apache.
the class JoinNodeBuilder method build.
@Override
public Node build() {
Node node = new JoinNode(joinType);
node.addChild(table.build());
node.addChild(joinExp.build());
return node;
}
use of org.apache.cayenne.access.sqlbuilder.sqltree.Node in project cayenne by apache.
the class SybaseSQLTreeProcessor method onLimitOffsetNode.
@Override
protected void onLimitOffsetNode(Node parent, LimitOffsetNode child, int index) {
// SQLServer uses "SELECT DISTINCT TOP N" or "SELECT TOP N" instead of LIMIT
// Offset will be calculated in-memory
replaceChild(parent, index, new EmptyNode(), false);
if (child.getLimit() > 0) {
int limit = child.getLimit() + child.getOffset();
// we have root actually as input for processor, but it's better to keep processor stateless
// root shouldn't be far from limit's parent (likely it will be parent itself)
Node root = getRoot(parent);
int idx = 0;
if (root.getChild(0).getType() == NodeType.DISTINCT) {
idx = 1;
}
root.addChild(idx, new TopNode(limit));
}
}
Aggregations