use of com.yahoo.elide.datastores.aggregation.query.ColumnProjection 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.query.ColumnProjection in project elide by yahoo.
the class ExpressionParser method parse.
/**
* Parses the column or join expression and returns the list of discovered references.
* @param source The source table where the column or join expression lives.
* @param expression The expression to parse.
* @param callingColumnArgs Arguments available with calling column.
* @return A list of discovered references.
*/
public List<Reference> parse(Queryable source, String expression, Map<String, Argument> callingColumnArgs) {
List<String> referenceNames = resolveFormulaReferences(expression);
List<Reference> results = new ArrayList<>();
Map<String, Argument> fixedArguments = new HashMap<>();
for (String referenceName : referenceNames) {
// Change `sql from='joinName' column='columnName[a1:v1][a2:v2]'` to `joinName.columnName`
if (referenceName.startsWith(SQL_HELPER_PREFIX)) {
try {
Template template = handlebars.compileInline(toFormulaReference(referenceName));
referenceName = template.apply(Collections.emptyMap());
int argsIndex = referenceName.indexOf('[');
if (argsIndex >= 0) {
fixedArguments = getArgumentMapFromString(referenceName.substring(argsIndex));
referenceName = referenceName.substring(0, argsIndex);
}
} catch (IOException e) {
throw new IllegalStateException(e.getMessage());
}
}
// ignore $$column.expr
if (referenceName.equals(COLUMN_EXPR)) {
continue;
}
if (referenceName.startsWith(COLUMN_ARGS_PREFIX)) {
results.add(ColumnArgReference.builder().argName(referenceName.substring(COLUMN_ARGS_PREFIX.length())).build());
} else if (referenceName.startsWith(TABLE_ARGS_PREFIX)) {
results.add(TableArgReference.builder().argName(referenceName.substring(TABLE_ARGS_PREFIX.length())).build());
} else if (referenceName.startsWith("$")) {
results.add(PhysicalReference.builder().source(source).name(referenceName.substring(1)).build());
} else if (referenceName.contains(".")) {
results.add(buildJoin(source, referenceName, callingColumnArgs, fixedArguments));
} else {
ColumnProjection referencedColumn = source.getColumnProjection(referenceName);
Preconditions.checkNotNull(referencedColumn, String.format("Couldn't find column: '%s' for table: '%s'", referenceName, source.getName()));
ColumnProjection newColumn = referencedColumn.withArguments(mergedArgumentMap(referencedColumn.getArguments(), callingColumnArgs, fixedArguments));
List<Reference> references = buildReferenceForColumn(source, newColumn);
results.add(LogicalReference.builder().source(source).column(newColumn).references(references).build());
}
}
return results;
}
use of com.yahoo.elide.datastores.aggregation.query.ColumnProjection in project elide by yahoo.
the class QueryPlanTranslator method addHiddenProjections.
public static Query.QueryBuilder addHiddenProjections(MetaDataStore metaDataStore, Query.QueryBuilder builder, Query query) {
Set<ColumnProjection> directReferencedColumns = Streams.concat(query.getColumnProjections().stream(), query.getFilterProjections(query.getWhereFilter(), ColumnProjection.class).stream()).collect(Collectors.toSet());
ExpressionParser parser = new ExpressionParser(metaDataStore);
Set<ColumnProjection> indirectReferenceColumns = new HashSet<>();
directReferencedColumns.forEach(column -> {
parser.parse(query.getSource(), column).stream().map(reference -> reference.accept(new ReferenceExtractor<LogicalReference>(LogicalReference.class, metaDataStore, ReferenceExtractor.Mode.SAME_QUERY))).flatMap(Set::stream).map(LogicalReference::getColumn).forEach(indirectReferenceColumns::add);
});
Streams.concat(directReferencedColumns.stream(), indirectReferenceColumns.stream()).forEach(column -> {
if (query.getColumnProjection(column.getAlias(), column.getArguments()) == null) {
builder.column(column.withProjected(false));
}
});
return builder;
}
use of com.yahoo.elide.datastores.aggregation.query.ColumnProjection in project elide by yahoo.
the class QueryTranslator method visitQuery.
@Override
public NativeQuery.NativeQueryBuilder visitQuery(Query query) {
NativeQuery.NativeQueryBuilder builder = query.getSource().accept(this);
if (query.isNested()) {
NativeQuery innerQuery = builder.build();
builder = NativeQuery.builder().fromClause(getFromClause("(" + innerQuery + ")", applyQuotes(query.getSource().getAlias()), dialect));
}
Set<String> joinExpressions = new LinkedHashSet<>();
builder.projectionClause(constructProjectionWithReference(query));
// Handles join for all type of column projects - dimensions, metrics and time dimention
joinExpressions.addAll(extractJoinExpressions(query));
Set<ColumnProjection> groupByDimensions = query.getAllDimensionProjections().stream().map(SQLColumnProjection.class::cast).filter(SQLColumnProjection::isProjected).collect(Collectors.toCollection(LinkedHashSet::new));
if (!groupByDimensions.isEmpty()) {
if (!query.getMetricProjections().isEmpty()) {
builder.groupByClause("GROUP BY " + groupByDimensions.stream().map(SQLColumnProjection.class::cast).map((column) -> column.toSQL(query, metaDataStore)).collect(Collectors.joining(", ")));
}
}
if (query.getWhereFilter() != null) {
builder.whereClause("WHERE " + translateFilterExpression(query.getWhereFilter(), path -> generatePredicatePathReference(path, query)));
joinExpressions.addAll(extractJoinExpressions(query, query.getWhereFilter()));
}
if (query.getHavingFilter() != null) {
builder.havingClause("HAVING " + translateFilterExpression(query.getHavingFilter(), (path) -> constructHavingClauseWithReference(path, query)));
joinExpressions.addAll(extractJoinExpressions(query, query.getHavingFilter()));
}
if (query.getSorting() != null) {
Map<Path, Sorting.SortOrder> sortClauses = query.getSorting().getSortingPaths();
builder.orderByClause(extractOrderBy(sortClauses, query));
joinExpressions.addAll(extractJoinExpressions(query, sortClauses));
}
Pagination pagination = query.getPagination();
if (pagination != null) {
builder.offsetLimitClause(dialect.generateOffsetLimitClause(pagination.getOffset(), pagination.getLimit()));
}
return builder.joinClause(String.join(" ", joinExpressions));
}
use of com.yahoo.elide.datastores.aggregation.query.ColumnProjection in project elide by yahoo.
the class SQLColumnProjection method nest.
@Override
default Pair<ColumnProjection, Set<ColumnProjection>> nest(Queryable source, MetaDataStore store, boolean joinInOuter) {
List<Reference> references = new ExpressionParser(store).parse(source, getExpression());
boolean requiresJoin = requiresJoin(references);
String columnId = source.isRoot() ? getName() : getAlias();
boolean inProjection = source.getColumnProjection(columnId, getArguments(), true) != null;
ColumnProjection outerProjection;
Set<ColumnProjection> innerProjections;
if (requiresJoin && joinInOuter) {
String outerProjectionExpression = toPhysicalReferences(source, store);
outerProjection = withExpression(outerProjectionExpression, inProjection);
innerProjections = extractPhysicalReferences(source, references, store);
} else {
outerProjection = withExpression("{{$" + this.getSafeAlias() + "}}", isProjected());
innerProjections = new LinkedHashSet<>(Arrays.asList(this));
}
return Pair.of(outerProjection, innerProjections);
}
Aggregations