use of com.yahoo.elide.datastores.aggregation.core.JoinPath in project elide by yahoo.
the class JoinExpressionExtractor method visitJoinReference.
@Override
public Set<String> visitJoinReference(JoinReference reference) {
JoinPath joinPath = reference.getPath();
List<PathElement> pathElements = joinPath.getPathElements();
ColumnContext currentCtx = this.context;
for (int i = 0; i < pathElements.size() - 1; i++) {
PathElement pathElement = pathElements.get(i);
Type<?> joinClass = pathElement.getFieldType();
String joinFieldName = pathElement.getFieldName();
SQLJoin sqlJoin = currentCtx.getQueryable().getJoin(joinFieldName);
ColumnContext joinCtx;
String onClause;
JoinType joinType;
String fullExpression;
if (sqlJoin != null) {
joinType = sqlJoin.getJoinType();
joinCtx = (ColumnContext) currentCtx.get(joinFieldName);
if (joinType.equals(JoinType.CROSS)) {
onClause = EMPTY;
} else {
onClause = ON + currentCtx.resolve(sqlJoin.getJoinExpression());
}
} else {
joinType = JoinType.LEFT;
SQLTable table = metaDataStore.getTable(joinClass);
joinCtx = ColumnContext.builder().queryable(table).alias(appendAlias(currentCtx.getAlias(), joinFieldName)).metaDataStore(currentCtx.getMetaDataStore()).column(currentCtx.getColumn()).tableArguments(mergedArgumentMap(table.getArguments(), currentCtx.getTableArguments())).build();
onClause = ON + String.format("%s.%s = %s.%s", currentCtx.getAlias(), dictionary.getAnnotatedColumnName(pathElement.getType(), joinFieldName), joinCtx.getAlias(), dictionary.getAnnotatedColumnName(joinClass, dictionary.getIdFieldName(joinClass)));
}
SQLDialect sqlDialect = currentCtx.getQueryable().getDialect();
String joinAlias = applyQuotes(joinCtx.getAlias(), sqlDialect);
String joinKeyword = currentCtx.getQueryable().getDialect().getJoinKeyword(joinType);
String joinSource = constructTableOrSubselect(joinCtx, joinClass);
if (sqlDialect.useASBeforeTableAlias()) {
fullExpression = String.format("%s %s AS %s %s", joinKeyword, joinSource, joinAlias, onClause);
} else {
fullExpression = String.format("%s %s %s %s", joinKeyword, joinSource, joinAlias, onClause);
}
joinExpressions.add(fullExpression);
/**
* If this `for` loop runs more than once, context should be switched to join context.
*/
currentCtx = joinCtx;
}
// If reference within current join reference is of type PhysicalReference, then below visitor doesn't matter.
// If it is of type LogicalReference, then visitLogicalReference method will recreate visitor with correct
// value of ColumnProjection in context.
JoinExpressionExtractor visitor = new JoinExpressionExtractor(currentCtx);
joinExpressions.addAll(reference.getReference().accept(visitor));
return joinExpressions;
}
use of com.yahoo.elide.datastores.aggregation.core.JoinPath in project elide by yahoo.
the class HasJoinVisitorTest method testHasJoin.
@Test
void testHasJoin() {
Queryable source = mock(Queryable.class);
JoinPath path = mock(JoinPath.class);
ColumnProjection column = mock(ColumnProjection.class);
Reference reference = LogicalReference.builder().source(source).column(column).reference(PhysicalReference.builder().name("foo").source(source).build()).reference(JoinReference.builder().source(source).path(path).reference(PhysicalReference.builder().name("bar").source(source).build()).build()).build();
assertTrue(reference.accept(new HasJoinVisitor()));
}
use of com.yahoo.elide.datastores.aggregation.core.JoinPath in project elide by yahoo.
the class ExpressionParser method buildJoin.
private JoinReference buildJoin(Queryable source, String referenceName, Map<String, Argument> callingColumnArgs, Map<String, Argument> fixedArguments) {
Queryable root = source.getRoot();
Type<?> tableClass = dictionary.getEntityClass(root.getName(), root.getVersion());
JoinPath joinPath = new JoinPath(tableClass, metaDataStore, referenceName);
Path.PathElement lastElement = joinPath.lastElement().get();
Queryable joinSource = metaDataStore.getTable(lastElement.getType());
String fieldName = lastElement.getFieldName();
Reference reference;
if (fieldName.startsWith("$")) {
reference = PhysicalReference.builder().source(joinSource).name(fieldName.substring(1)).build();
} else {
ColumnProjection referencedColumn = joinSource.getColumnProjection(fieldName);
ColumnProjection newColumn = referencedColumn.withArguments(mergedArgumentMap(referencedColumn.getArguments(), callingColumnArgs, fixedArguments));
reference = LogicalReference.builder().source(joinSource).column(newColumn).references(buildReferenceForColumn(joinSource, newColumn)).build();
}
return JoinReference.builder().path(joinPath).source(source).reference(reference).build();
}
use of com.yahoo.elide.datastores.aggregation.core.JoinPath in project elide by yahoo.
the class ReferenceExtractor method visitJoinReference.
@Override
public Set<T> visitJoinReference(JoinReference reference) {
if (referenceType.equals(JoinReference.class)) {
references.add((T) reference);
}
JoinPath path = reference.getPath();
int pathLimit = (mode == Mode.SAME_QUERY) ? 1 : path.getPathElements().size() - 1;
for (int idx = 0; idx < pathLimit; idx++) {
Path.PathElement pathElement = path.getPathElements().get(idx);
String fieldName = pathElement.getFieldName();
Type<?> parentClass = pathElement.getType();
SQLTable table = metaDataStore.getTable(parentClass);
SQLJoin join = table.getJoin(fieldName);
if (visitedJoins.contains(join)) {
continue;
}
visitedJoins.add(join);
parser.parse(table, join.getJoinExpression()).stream().forEach(ref -> ref.accept(this));
}
if (mode != Mode.SAME_QUERY) {
return reference.getReference().accept(this);
}
return references;
}
Aggregations