public DatalogProgram constructDatalogProgram() { DatalogProgram datalog = dfac.getDatalogProgram(); LinkedList<String> errorMessage = new LinkedList<String>(); for (OBDAMappingAxiom axiom : mappingList) { try { // Obtain the target and source query from each mapping axiom in // the model. CQIE targetQuery = (CQIE) axiom.getTargetQuery(); // Get the parsed sql, since it is already parsed by the mapping // parser // consider also MetaMappingExpander // VisitedQuery queryParsed = ...; OBDASQLQuery sourceQuery = (OBDASQLQuery) axiom.getSourceQuery(); // Construct the SQL query tree from the source query VisitedQuery queryParsed = translator.constructParser(sourceQuery.toString()); // Create a lookup table for variable swapping LookupTable lookupTable = createLookupTable(queryParsed); // We can get easily the table from the SQL ArrayList<RelationJSQL> tableList = queryParsed.getTableSet(); // Construct the body from the source query ArrayList<Function> atoms = new ArrayList<Function>(); for (RelationJSQL table : tableList) { // Construct the URI from the table name String tableName = table.getGivenName(); String predicateName = tableName; // Construct the predicate using the table name int arity = dbMetaData.getDefinition(tableName).countAttribute(); Predicate predicate = dfac.getPredicate(predicateName, arity); // Swap the column name with a new variable from the lookup // table List<Term> terms = new ArrayList<Term>(); for (int i = 1; i <= arity; i++) { String columnName = dbMetaData.getFullQualifiedAttributeName(tableName, table.getAlias(), i); String termName = lookupTable.lookup(columnName); if (termName == null) { throw new RuntimeException( "Column '" + columnName + "'was not found in the lookup table: "); } Term term = dfac.getVariable(termName); terms.add(term); } // Create an atom for a particular table Function atom = dfac.getFunction(predicate, terms); atoms.add(atom); } // For the join conditions WE STILL NEED TO CONSIDER NOT EQUI // JOIN ArrayList<Expression> joinConditions = queryParsed.getJoinCondition(); for (Expression predicate : joinConditions) { Function atom = getFunction(predicate, lookupTable); atoms.add(atom); } // For the selection "where" clause conditions SelectionJSQL selection = queryParsed.getSelection(); if (selection != null) { // Stack for filter function Stack<Function> filterFunctionStack = new Stack<Function>(); Expression conditions = selection.getRawConditions(); Function filterFunction = getFunction(conditions, lookupTable); filterFunctionStack.push(filterFunction); // The filter function stack must have 1 element left if (filterFunctionStack.size() == 1) { Function filterFunct = filterFunctionStack.pop(); Function atom = dfac.getFunction(filterFunct.getFunctionSymbol(), filterFunct.getTerms()); atoms.add(atom); } else { throwInvalidFilterExpressionException(filterFunctionStack); } } // Construct the head from the target query. List<Function> atomList = targetQuery.getBody(); // for (Function atom : atomList) { Iterator<Function> atomListIter = atomList.iterator(); while (atomListIter.hasNext()) { Function atom = atomListIter.next(); List<Term> terms = atom.getTerms(); List<Term> newterms = new LinkedList<Term>(); for (Term term : terms) { newterms.add(updateTerm(term, lookupTable)); } Function newhead = dfac.getFunction(atom.getPredicate(), newterms); CQIE rule = dfac.getCQIE(newhead, atoms); datalog.appendRule(rule); } } catch (Exception e) { errorMessage.add( "Error in mapping with id: " + axiom.getId() + " \n Description: " + e.getMessage() + " \nMapping: [" + axiom.toString() + "]"); } } if (errorMessage.size() > 0) { StringBuilder errors = new StringBuilder(); for (String error : errorMessage) { errors.append(error + "\n"); } final String msg = "There was an error analyzing the following mappings. Please correct the issue(s) to continue.\n" + errors.toString(); RuntimeException r = new RuntimeException(msg); throw r; } return datalog; }
private LookupTable createLookupTable(VisitedQuery queryParsed) throws JSQLParserException { LookupTable lookupTable = new LookupTable(); // Collect all the possible column names from tables. ArrayList<RelationJSQL> tableList = queryParsed.getTableSet(); // Collect all known column aliases HashMap<String, String> aliasMap = queryParsed.getAliasMap(); int offset = 0; // the index offset for (RelationJSQL table : tableList) { String tableName = table.getTableName(); String tableGivenName = table.getGivenName(); DataDefinition def = dbMetaData.getDefinition(tableGivenName); if (def == null) { def = dbMetaData.getDefinition(tableName); if (def == null) { throw new RuntimeException("Definition not found for table '" + tableGivenName + "'."); } } int size = def.countAttribute(); for (int i = 1; i <= size; i++) { // assigned index number int index = i + offset; // simple attribute name String columnName = dbMetaData.getAttributeName(tableGivenName, i); lookupTable.add(columnName, index); String lowercaseColumn = columnName.toLowerCase(); if (aliasMap.containsKey(lowercaseColumn)) { // register the alias name, if any lookupTable.add(aliasMap.get(lowercaseColumn), columnName); } // attribute name with table name prefix String tableColumnName = tableName + "." + columnName; lookupTable.add(tableColumnName, index); // attribute name with table name prefix String tablecolumnname = tableColumnName.toLowerCase(); if (aliasMap.containsKey(tablecolumnname)) { // register the alias name, if any lookupTable.add(aliasMap.get(tablecolumnname), tableColumnName); } // attribute name with table given name prefix String givenTableColumnName = tableGivenName + "." + columnName; lookupTable.add(givenTableColumnName, tableColumnName); String giventablecolumnname = givenTableColumnName.toLowerCase(); if (aliasMap.containsKey(giventablecolumnname)) { // register the alias name, if any lookupTable.add(aliasMap.get(giventablecolumnname), tableColumnName); } // full qualified attribute name String qualifiedColumnName = dbMetaData.getFullQualifiedAttributeName(tableGivenName, i); lookupTable.add(qualifiedColumnName, tableColumnName); String qualifiedcolumnname = qualifiedColumnName.toLowerCase(); if (aliasMap.containsKey(qualifiedcolumnname)) { // register the alias name, if any lookupTable.add(aliasMap.get(qualifiedcolumnname), tableColumnName); } // full qualified attribute name using table alias String tableAlias = table.getAlias(); if (tableAlias != null) { String qualifiedColumnAlias = dbMetaData.getFullQualifiedAttributeName(tableGivenName, tableAlias, i); lookupTable.add(qualifiedColumnAlias, index); String aliasColumnName = tableAlias.toLowerCase() + "." + lowercaseColumn; if (aliasMap.containsKey(aliasColumnName)) { // register the alias name, if any lookupTable.add(aliasMap.get(aliasColumnName), qualifiedColumnAlias); } } // check if we do not have subselect with alias name assigned for (SelectJSQL subSelect : queryParsed.getSubSelectSet()) { String subSelectAlias = subSelect.getAlias(); if (subSelectAlias != null) { String aliasColumnName = subSelectAlias.toLowerCase() + "." + lowercaseColumn; lookupTable.add(aliasColumnName, index); if (aliasMap.containsKey(aliasColumnName)) { // register the alias name, if any lookupTable.add(aliasMap.get(aliasColumnName), aliasColumnName); } } } } offset += size; } return lookupTable; }