code: private Optional<RDFTermType> extractTripleObjectType(IQ mappingAssertion)
              throws TripleObjectTypeInferenceException {
  
          ImmutableList<Variable> projectedVariables = mappingAssertion.getProjectionAtom().getArguments();
          Variable objectVariable = projectedVariables.get(2);
  
          ImmutableTerm constructionTerm = Optional.of(mappingAssertion.getTree().getRootNode())
                  .filter(n -> n instanceof ConstructionNode)
                  .map((n) -> (ConstructionNode) n)
                  .map(ConstructionNode::getSubstitution)
                  .flatMap(s -> Optional.ofNullable(s.get(objectVariable)))
                  .orElseThrow(() -> new TripleObjectTypeInferenceException(mappingAssertion, objectVariable,
                          "Not defined in the root node (expected for a mapping assertion)"));
  
          if (constructionTerm instanceof ImmutableFunctionalTerm) {
              ImmutableFunctionalTerm constructionFunctionalTerm = ((ImmutableFunctionalTerm) constructionTerm);
              Predicate functionSymbol = constructionFunctionalTerm.getFunctionSymbol();
              if ((functionSymbol instanceof BNodePredicate)
                      || (functionSymbol instanceof URITemplatePredicate)) {
                  return Optional.of(typeFactory.getIRITermType());
              }
              else if (functionSymbol instanceof DatatypePredicate) {
                  DatatypePredicate datatypeConstructionFunctionSymbol = (DatatypePredicate) functionSymbol;
                  return Optional.of(datatypeConstructionFunctionSymbol.getReturnedType());
              }
              else {
                  throw new TripleObjectTypeInferenceException(mappingAssertion, objectVariable,
                          "Unexpected function symbol: " + functionSymbol);
              }
          }
  
          else {
              /*
               * TODO: consider variables and constants (NB: could be relevant for SPARQL->SPARQL
                * but not much for SPARQL->SQL where RDF terms have to built)
               */
              throw new TripleObjectTypeInferenceException(mappingAssertion, objectVariable,
                      "Was expecting a functional term (constants and variables are not yet supported). \n"
                              + "Term definition: " + constructionTerm);
          }
  
      }
docs: For a mapping assertion using an RDF property (not rdf:type) the building expression of the triple object
  variable is assumed to be present in the ROOT construction node.
  
  Note that this assumption does not hold for intermediate query in general.
  
  Return nothing if the property is rdf:type (class instance assertion)
  
  TODO: refactor it!