use of org.finos.legend.pure.m3.coreinstance.meta.relational.metamodel.relation.Relation in project legend-pure by finos.
the class DatabaseProcessor method processTable.
static void processTable(CoreInstance table, Matcher matcher, ProcessorState processorState, ProcessorSupport processorSupport) {
MapIterable<String, Column> columnsByName = processColumnsForTableOrView(table);
if (table instanceof Table) {
MutableList<Column> primaryKey = (MutableList<Column>) ((Table) table)._primaryKey().toList();
for (int i = 0; i < primaryKey.size(); i++) {
CoreInstance key = primaryKey.get(i);
if (processorSupport.instance_instanceOf(key, M3Paths.String)) {
String columnName = key.getName();
Column column = columnsByName.get(columnName);
if (column == null) {
throw new PureCompilationException(table.getSourceInformation(), "Could not find column " + columnName + " in table " + ((NamedRelation) table)._name());
}
primaryKey.set(i, column);
}
}
((Table) table)._primaryKey(primaryKey);
}
if (table instanceof Relation) {
Relation relation = (Relation) table;
relation._setColumnsCoreInstance(relation._columns().collect(relationalOperationElement -> (Column) relationalOperationElement));
}
processTableMilestoning(table, columnsByName, matcher, processorState, processorSupport);
}
use of org.finos.legend.pure.m3.coreinstance.meta.relational.metamodel.relation.Relation in project legend-pure by finos.
the class DatabaseProcessor method processJoin.
private static void processJoin(Join join, Database defaultDb, ModelRepository repository, ProcessorSupport processorSupport) {
MutableMap<String, MutableMap<String, CoreInstance>> tableByAliasBySchema = Maps.mutable.empty();
Operation operation = join._operation();
MutableList<TableAliasColumn> selfJoinTargets = Lists.mutable.empty();
scanOperation(operation, tableByAliasBySchema, selfJoinTargets, defaultDb, repository, processorSupport, true);
Class<?> tableAliasClass = (Class<?>) processorSupport.package_getByUserPath(M2RelationalPaths.TableAlias);
MutableList<TableAlias> tableAliases = Lists.mutable.empty();
for (MutableMap<String, CoreInstance> schemaTableByAlias : tableByAliasBySchema) {
schemaTableByAlias.forEachKeyValue((alias, table) -> {
TableAlias tableAlias = (TableAlias) repository.newAnonymousCoreInstance(join.getSourceInformation(), tableAliasClass);
tableAlias._name(repository.newStringCoreInstance_cached(alias).getName());
tableAlias._relationalElement((RelationalOperationElement) table);
tableAliases.add(tableAlias);
});
}
if (tableAliases.size() > 2) {
throw new PureCompilationException(join.getSourceInformation(), "A join can only contain 2 tables. Please use Join chains (using '>') in your mapping in order to compose many of them.");
}
if (tableAliases.size() == 1) {
// Self Join
if (selfJoinTargets.isEmpty()) {
throw new PureCompilationException(join.getSourceInformation(), "The system can only find one table in the join. Please use the '{target}' notation in order to define a directed self join.");
}
TableAlias existingAlias = tableAliases.get(0);
String existingAliasName = existingAlias._name();
RelationalOperationElement existingRelationalElement = existingAlias._relationalElement();
TableAlias tableAlias = (TableAlias) repository.newAnonymousCoreInstance(existingAlias.getSourceInformation(), tableAliasClass);
tableAlias._name(repository.newStringCoreInstance_cached("t_" + existingAliasName).getName());
tableAlias._relationalElement(existingRelationalElement);
tableAliases.add(tableAlias);
join._target(tableAlias);
for (TableAliasColumn selfJoinTarget : selfJoinTargets) {
selfJoinTarget._alias(tableAlias);
String columnName = selfJoinTarget._columnName();
Column col = null;
if (existingRelationalElement instanceof Relation) {
col = (Column) ((Relation) existingRelationalElement)._columns().selectWith(COLUMN_NAME_PREDICATE, columnName).toList().getFirst();
}
if (col == null) {
throw new PureCompilationException(selfJoinTarget.getSourceInformation(), "The column '" + columnName + "' can't be found in the table '" + ((NamedRelation) existingRelationalElement)._name() + "'");
}
selfJoinTarget._column(col);
}
} else if (selfJoinTargets.notEmpty()) {
throw new PureCompilationException(join.getSourceInformation(), "A self join can only contain 1 table, found " + selfJoinTargets.size());
}
// All Joins
Pair<TableAlias, TableAlias> pair1 = newPair(tableAliasClass, tableAliasClass, repository, processorSupport);
pair1._first(tableAliases.get(0));
pair1._second(tableAliases.get(1));
Pair<TableAlias, TableAlias> pair2 = newPair(tableAliasClass, tableAliasClass, repository, processorSupport);
pair2._first(tableAliases.get(1));
pair2._second(tableAliases.get(0));
join._aliases(Lists.immutable.with(pair1, pair2));
}
use of org.finos.legend.pure.m3.coreinstance.meta.relational.metamodel.relation.Relation in project legend-pure by finos.
the class DatabaseProcessor method processColumnsForTableOrView.
public static MapIterable<String, Column> processColumnsForTableOrView(CoreInstance tableOrView) {
ListIterable<? extends RelationalOperationElement> columns = FastList.newList();
if (tableOrView instanceof Relation) {
columns = ((Relation) tableOrView)._columns().toList();
}
MutableMap<String, Column> columnsByName = UnifiedMap.newMap(columns.size());
for (RelationalOperationElement column : columns) {
if (!(column instanceof Column)) {
throw new PureCompilationException(column.getSourceInformation(), "Expected an instance of " + M2RelationalPaths.Column + ", found " + PackageableElement.getUserPathForPackageableElement(column.getClassifier()));
}
String columnName = ((Column) column)._name();
RelationalOperationElement old = columnsByName.put(columnName, (Column) column);
if (old != null) {
throw new PureCompilationException(column.getSourceInformation(), "Multiple columns named '" + columnName + "' found in " + tableOrView.getClassifier().getName().toLowerCase() + " " + ((NamedRelation) tableOrView)._name());
}
((Column) column)._owner((Relation) tableOrView);
}
return columnsByName;
}
use of org.finos.legend.pure.m3.coreinstance.meta.relational.metamodel.relation.Relation in project legend-engine by finos.
the class HelperRelationalBuilder method processRelationalPrimaryKey.
public static void processRelationalPrimaryKey(RootRelationalInstanceSetImplementation rootRelationalInstanceSetImplementation) {
if (rootRelationalInstanceSetImplementation._groupBy() != null) {
rootRelationalInstanceSetImplementation._primaryKey(rootRelationalInstanceSetImplementation._groupBy()._columns());
} else // TODO handle distinct
if (rootRelationalInstanceSetImplementation._primaryKey().isEmpty()) {
Relation relation = (Relation) rootRelationalInstanceSetImplementation._mainTableAlias()._relationalElement();
final TableAlias finalMainTable = rootRelationalInstanceSetImplementation._mainTableAlias();
RichIterable<? extends Column> columns = FastList.newList();
if (relation instanceof Table) {
columns = ((Table) relation)._primaryKey();
} else if (relation instanceof View) {
columns = ((View) relation)._primaryKey();
}
RichIterable<TableAliasColumn> primaryKey = columns.collect(new Function<Column, TableAliasColumn>() {
@Override
public TableAliasColumn valueOf(Column column) {
TableAliasColumn tableAliasColumn = new Root_meta_relational_metamodel_TableAliasColumn_Impl("");
tableAliasColumn._column(column);
tableAliasColumn._alias(finalMainTable);
return tableAliasColumn;
}
});
rootRelationalInstanceSetImplementation._primaryKey(primaryKey);
}
}
use of org.finos.legend.pure.m3.coreinstance.meta.relational.metamodel.relation.Relation in project legend-engine by finos.
the class HelperRelationalBuilder method processRelationalOperationElement.
public static RelationalOperationElement processRelationalOperationElement(org.finos.legend.engine.protocol.pure.v1.model.packageableElement.store.relational.model.operation.RelationalOperationElement operationElement, CompileContext context, MutableMap<String, org.finos.legend.pure.m3.coreinstance.meta.relational.metamodel.TableAlias> aliasMap, MutableList<org.finos.legend.pure.m3.coreinstance.meta.relational.metamodel.TableAliasColumn> selfJoinTargets) {
if (operationElement instanceof org.finos.legend.engine.protocol.pure.v1.model.packageableElement.store.relational.model.operation.TableAliasColumn) {
org.finos.legend.engine.protocol.pure.v1.model.packageableElement.store.relational.model.operation.TableAliasColumn tableAliasColumn = (org.finos.legend.engine.protocol.pure.v1.model.packageableElement.store.relational.model.operation.TableAliasColumn) operationElement;
// Self join
if (tableAliasColumn.table.table.equals(SELF_JOIN_TABLE_NAME) && tableAliasColumn.tableAlias.equals(SELF_JOIN_TABLE_NAME)) {
org.finos.legend.pure.m3.coreinstance.meta.relational.metamodel.TableAliasColumn selfJoin = new Root_meta_relational_metamodel_TableAliasColumn_Impl("")._columnName(tableAliasColumn.column);
selfJoinTargets.add(selfJoin);
return selfJoin;
}
Relation relation = getRelation((Database) context.resolveStore(tableAliasColumn.table.database, tableAliasColumn.table.sourceInformation), tableAliasColumn.table.schema, tableAliasColumn.table.table, tableAliasColumn.table.sourceInformation);
Column col = getColumn(relation, tableAliasColumn.column, tableAliasColumn.sourceInformation);
TableAlias alias = aliasMap.getIfAbsentPut(tableAliasColumn.table.schema + "." + tableAliasColumn.tableAlias, (Function0<TableAlias>) () -> new Root_meta_relational_metamodel_TableAlias_Impl("")._name(tableAliasColumn.tableAlias)._relationalElement(col._owner())._database(HelperRelationalBuilder.resolveDatabase(tableAliasColumn.table.getDb(), tableAliasColumn.table.sourceInformation, context)));
return new Root_meta_relational_metamodel_TableAliasColumn_Impl("")._columnName(col._name())._column(col)._alias(alias);
} else if (operationElement instanceof ElementWithJoins) {
ElementWithJoins elementWithJoins = (ElementWithJoins) operationElement;
RelationalOperationElementWithJoin res = new Root_meta_relational_metamodel_RelationalOperationElementWithJoin_Impl("")._joinTreeNode(buildElementWithJoinsJoinTreeNode(elementWithJoins.joins, context));
return elementWithJoins.relationalElement == null ? res : res._relationalOperationElement(processRelationalOperationElement(elementWithJoins.relationalElement, context, UnifiedMap.newMap(), selfJoinTargets));
} else if (operationElement instanceof DynaFunc) {
DynaFunc dynaFunc = (DynaFunc) operationElement;
MutableList<RelationalOperationElement> ps = ListIterate.collect(dynaFunc.parameters, relationalOperationElement -> processRelationalOperationElement(relationalOperationElement, context, aliasMap, selfJoinTargets));
return new Root_meta_relational_metamodel_DynaFunction_Impl("")._name(dynaFunc.funcName)._parameters(ps);
} else if (operationElement instanceof org.finos.legend.engine.protocol.pure.v1.model.packageableElement.store.relational.model.operation.Literal) {
org.finos.legend.engine.protocol.pure.v1.model.packageableElement.store.relational.model.operation.Literal literal = (org.finos.legend.engine.protocol.pure.v1.model.packageableElement.store.relational.model.operation.Literal) operationElement;
return new Root_meta_relational_metamodel_Literal_Impl("")._value(convertLiteral(convertLiteral(literal.value)));
} else if (operationElement instanceof org.finos.legend.engine.protocol.pure.v1.model.packageableElement.store.relational.model.operation.LiteralList) {
org.finos.legend.engine.protocol.pure.v1.model.packageableElement.store.relational.model.operation.LiteralList literalList = (org.finos.legend.engine.protocol.pure.v1.model.packageableElement.store.relational.model.operation.LiteralList) operationElement;
return new Root_meta_relational_metamodel_LiteralList_Impl("")._values(ListIterate.collect(literalList.values, l -> new Root_meta_relational_metamodel_Literal_Impl("")._value(convertLiteral(l.value))));
}
throw new UnsupportedOperationException();
}
Aggregations