use of org.finos.legend.pure.m3.coreinstance.meta.relational.metamodel.relation.NamedRelation 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.NamedRelation 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.NamedRelation 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.NamedRelation in project legend-engine by finos.
the class RelationalCompilerExtension method getExtraExecutionContextProcessors.
@Override
public List<Function2<ExecutionContext, CompileContext, org.finos.legend.pure.m3.coreinstance.meta.pure.runtime.ExecutionContext>> getExtraExecutionContextProcessors() {
return Collections.singletonList((executionContext, context) -> {
if (executionContext instanceof RelationalExecutionContext) {
RelationalExecutionContext relationalContext = (RelationalExecutionContext) executionContext;
MutableMap<Relation, org.finos.legend.pure.m3.coreinstance.meta.pure.functions.collection.List<Column>> fksByTable = Maps.mutable.empty();
ListIterate.forEach(relationalContext.importDataFlowFkCols, fks -> {
org.finos.legend.pure.m3.coreinstance.meta.relational.metamodel.Schema schema = ((org.finos.legend.pure.m3.coreinstance.meta.relational.metamodel.Database) context.pureModel.getStore(fks.table.getDb()))._schemas().detect(s -> s._name().equals(fks.table.schema));
RichIterable<? extends NamedRelation> relations = fks.table._type.equals("Table") ? schema._tables() : fks.table._type.equals("View") ? schema._views() : null;
Relation table = relations != null ? relations.detect(a -> a._name().equals(fks.table.table)) : null;
RichIterable<Column> columns = ListIterate.collect(fks.columns, col -> table != null ? table._columns().select(c -> c instanceof Column).collect(c -> (Column) c).detect(c -> c._name().equals(col)) : null).select(Objects::nonNull);
fksByTable.put(table, new Root_meta_pure_functions_collection_List_Impl("")._values(columns));
});
return new Root_meta_relational_runtime_RelationalExecutionContext_Impl("")._queryTimeOutInSeconds(relationalContext.queryTimeOutInSeconds)._enableConstraints(relationalContext.enableConstraints)._addDriverTablePkForProject(relationalContext.addDriverTablePkForProject)._insertDriverTablePkInTempTable(relationalContext.insertDriverTablePkInTempTable)._useTempTableAsDriver(relationalContext.useTempTableAsDriver)._preserveJoinOrder(relationalContext.preserveJoinOrder)._importDataFlow(relationalContext.importDataFlow)._importDataFlowAddFks(relationalContext.importDataFlowAddFks)._importDataFlowFksByTable(relationalContext.importDataFlowAddFks != null && relationalContext.importDataFlowAddFks ? new PureMap(fksByTable) : null)._importDataFlowImplementationCount(relationalContext.importDataFlowImplementationCount);
}
return null;
});
}
use of org.finos.legend.pure.m3.coreinstance.meta.relational.metamodel.relation.NamedRelation in project legend-pure by finos.
the class RelationalInstanceSetImplementationProcessor method process.
@Override
public void process(RootRelationalInstanceSetImplementation implementation, ProcessorState state, Matcher matcher, final ModelRepository repository, final Context context, final ProcessorSupport processorSupport) {
// No need to cross reference... ClassMapping is responsible for that
ModelElement cls = (ModelElement) ImportStub.withImportStubByPass(implementation._classCoreInstance(), processorSupport);
GenericType instanceGenericType = cls._classifierGenericType() == null ? (GenericType) Type.wrapGenericType(processorSupport.getClassifier(cls), processorSupport) : cls._classifierGenericType();
CoreInstance propertyReturnGenericType = org.finos.legend.pure.m3.navigation.generictype.GenericType.resolvePropertyReturnType((implementation._classifierGenericType() == null ? (GenericType) Type.wrapGenericType(processorSupport.getClassifier(implementation), processorSupport) : implementation._classifierGenericType()), implementation.getKeyByName(M3Properties._class), processorSupport);
if (!org.finos.legend.pure.m3.navigation.generictype.GenericType.subTypeOf(instanceGenericType, propertyReturnGenericType, processorSupport)) {
throw new PureCompilationException(implementation.getSourceInformation(), "Trying to map an unsupported type in Relational: Type Error: '" + org.finos.legend.pure.m3.navigation.generictype.GenericType.print(instanceGenericType, processorSupport) + "' not a subtype of '" + org.finos.legend.pure.m3.navigation.generictype.GenericType.print(propertyReturnGenericType, processorSupport) + "'");
}
RichIterable<? extends PropertyMapping> propertyMappings = implementation._propertyMappings();
MutableSet<TableAlias> tableAliases = RelationalPropertyMappingProcessor.processRelationalPropertyMappings(propertyMappings, implementation, implementation, implementation._id(), matcher, state, repository, processorSupport);
if (implementation._id().equals(implementation._superSetImplementationId())) {
throw new PureCompilationException(implementation.getSourceInformation(), "Extend mapping id cannot reference self \'" + implementation._id() + "\'");
}
TableAlias mainTableAlias;
TableAlias userDefinedMainTable = implementation._mainTableAlias();
if (userDefinedMainTable == null) {
MutableSet<RelationalOperationElement> tables = tableAliases.collect(TABLE_ALIAS_TO_RELATIONAL_OPERATION_ELEMENT_FN);
MutableSet<Database> databases = tableAliases.collectWith(TABLE_ALIAS_TO_DATABASE_FN, processorSupport);
if (implementation._superSetImplementationId() != null) {
RootRelationalInstanceSetImplementation superImplementation = getSuperMapping(implementation, processorSupport);
PostProcessor.processElement(matcher, superImplementation, state, processorSupport);
collectTableAndDatabaseFromSuperImplementation(superImplementation, implementation, tables, databases, processorSupport);
}
if (tables.size() != 1) {
throw new PureCompilationException(implementation.getSourceInformation(), "Can't find the main table for class '" + cls._name() + "'. Please specify a main table using the ~mainTable directive.");
}
if (databases.size() != 1) {
throw new PureCompilationException(implementation.getSourceInformation(), "Can't find the main table for class '" + cls._name() + "'. Inconsistent database definitions for the mapping");
}
mainTableAlias = (TableAlias) processorSupport.newAnonymousCoreInstance(null, M2RelationalPaths.TableAlias);
mainTableAlias._name(repository.newStringCoreInstance_cached("").getName());
mainTableAlias._relationalElement(tables.toList().getFirst());
mainTableAlias._databaseCoreInstance(databases.toList().getFirst());
implementation._mainTableAlias(mainTableAlias);
} else {
if (implementation._superSetImplementationId() == null) {
mainTableAlias = userDefinedMainTable;
Database database = (Database) ImportStub.withImportStubByPass(mainTableAlias._databaseCoreInstance(), processorSupport);
NamedRelation table = (NamedRelation) DatabaseProcessor.findTableForAlias(database, mainTableAlias, processorSupport);
mainTableAlias._relationalElement(table);
mainTableAlias._setMappingOwner(implementation);
} else {
throw new PureCompilationException(implementation.getSourceInformation(), "Cannot specify main table explicitly for extended mapping [" + implementation._id() + "]");
}
}
RelationalOperationElement mainTable = mainTableAlias._relationalElement();
for (JoinTreeNode joinTreeNode : RelationalPropertyMappingProcessor.collectJoinTreeNodes(propertyMappings)) {
RelationalOperationElementProcessor.processAliasForJoinTreeNode(joinTreeNode, mainTable, processorSupport);
}
RelationalMappingSpecificationProcessing.processFilterMapping(implementation, implementation, mainTable, matcher, state, repository, processorSupport);
GroupByMapping groupByMapping = RelationalMappingSpecificationProcessing.processGroupByMapping(implementation, implementation, state, matcher, repository, processorSupport).getOne();
Boolean distinct = implementation._distinct();
if (groupByMapping != null) {
implementation._primaryKey(groupByMapping._columns());
} else if (distinct) {
RichIterable<RelationalOperationElement> pks = propertyMappings.flatCollect(PROPERTY_MAPPING_TO_RELATIONAL_OPERATION_ELEMENT_FN);
RichIterable<RelationalOperationElement> pksWithDistinctColumns = pks.groupBy(TAC_TO_COLUMN).keyMultiValuePairsView().collect(Functions.<RichIterable<RelationalOperationElement>>secondOfPair()).collect(new Function<RichIterable<RelationalOperationElement>, RelationalOperationElement>() {
@Override
public RelationalOperationElement valueOf(RichIterable<RelationalOperationElement> roes) {
return roes.getFirst();
}
});
implementation._primaryKey(pksWithDistinctColumns.select(RELATIONAL_OPERATION_ELEMENT_PK_PREDICATE));
} else if (implementation._primaryKey().isEmpty()) {
Relation relation = (Relation) mainTableAlias._relationalElement();
final TableAlias finalMainTable = mainTableAlias;
DatabaseProcessor.processTable(relation, matcher, state, processorSupport);
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 = (TableAliasColumn) repository.newEphemeralAnonymousCoreInstance(null, processorSupport.package_getByUserPath(M2RelationalPaths.TableAliasColumn));
tableAliasColumn._column(column);
tableAliasColumn._alias(finalMainTable);
return tableAliasColumn;
}
});
implementation._primaryKey(primaryKey);
} else // else if (Instance.getValueForMetaPropertyToManyResolved(implementation, M2RelationalProperties.primaryKey, context, processorSupport).isEmpty())
// {
// // throw new PureCompilationException(implementation.getSourceInformation(), "Please provide a primaryKey");
// }
{
processUserDefinedPrimaryKey(implementation, implementation, matcher, state, repository, processorSupport);
}
implementation._stores(implementation._propertyMappings().collect(STORE).toSet().with(implementation._mainTableAlias()._database()).without(null));
MilestoningPropertyMappingProcessor.processMilestoningPropertyMapping(implementation, implementation, processorSupport);
}
Aggregations