package it.unibz.inf.ontop.generation.serializer.impl;

import com.google.inject.Inject;
import com.google.inject.Singleton;
import it.unibz.inf.ontop.generation.algebra.SelectFromWhereWithModifiers;
import it.unibz.inf.ontop.generation.serializer.SelectFromWhereSerializer;
import it.unibz.inf.ontop.dbschema.DBParameters;
import it.unibz.inf.ontop.model.term.TermFactory;

@Singleton
public class TeiidSelectFromWhereSerializer extends DefaultSelectFromWhereSerializer implements SelectFromWhereSerializer {

    @Inject
    private TeiidSelectFromWhereSerializer(TermFactory termFactory) {
        super(new DefaultSQLTermSerializer(termFactory));
    }

    @Override
    public SelectFromWhereSerializer.QuerySerialization serialize(SelectFromWhereWithModifiers selectFromWhere, DBParameters dbParameters) {
        return selectFromWhere.acceptVisitor(
                new DefaultSelectFromWhereSerializer.DefaultRelationVisitingSerializer(dbParameters.getQuotedIDFactory()) {
                    /**
                     * See https://docs.jboss.org/teiid/7.7.0.Final/reference/en-US/html/sql_clauses.html#limit_clause
                     *
                     * LIMIT [offset,] limit
                     * [OFFSET offset ROW|ROWS] [FETCH FIRST|NEXT [limit] ROW|ROWS ONLY
                     *
                     * The limit/offset expressions must be a non-negative integer or a parameter reference (?). An offset of 0 is ignored. A limit of 0 will return no rows.
                     * The terms FIRST/NEXT are interchangable as well as ROW/ROWS.
                     *
                     * LIMIT 100 returns the first 100 records(rows 1-100)
                     * LIMIT 500,100  skips 500 records and returns the next 100 records(rows 501-600)
                     * OFFSET 500 ROWS skips 500 records
                     * OFFSET 500 ROWS FETCH NEXT 100 ROWS ONLY  skips 500 records and returns the next 100 records(rows 501-600)
                     * FETCH FIRST ROW ONLY - returns only the first record
                     */

                    //  serializeLimitOffset and  serializeLimit are standard

                    @Override
                    protected String serializeOffset(long offset, boolean noSortCondition) {
                        return String.format("OFFSET %d ROWS", offset);
                    }
                });
    }
}

@@ -71,55 +71,320 @@
 gle.
-inject.Inject;%0Aimport com.google.inject.Singlet
+common.collect.ImmutableList;%0Aimport com.google.common.collect.ImmutableMap;%0Aimport com.google.inject.Inject;%0Aimport com.google.inject.Singleton;%0Aimport it.unibz.inf.ontop.dbschema.QualifiedAttributeID;%0Aimport it.unibz.inf.ontop.dbschema.RelationID;%0Aimport it.unibz.inf.ontop.generation.algebra.SQLValuesExpressi
 on;%0A
@@ -631,16 +631,153 @@
 Factory;
+%0Aimport it.unibz.inf.ontop.model.term.Variable;%0Aimport it.unibz.inf.ontop.utils.ImmutableCollectors;%0A%0Aimport java.util.stream.Collectors;
 %0A%0A@Singl
@@ -2742,16 +2742,1628 @@
        %7D
+%0A%0A                    @Override%0A                    public QuerySerialization visit(SQLValuesExpression sqlValuesExpression) %7B%0A                        // Leaf node%0A                        ImmutableMap%3CVariable, QualifiedAttributeID%3E childColumnIDs = ImmutableMap.of();%0A%0A                        String tuplesSerialized = sqlValuesExpression.getValues().stream()%0A                                .map(tuple -%3E tuple.stream()%0A                                        .map(constant -%3E sqlTermSerializer.serialize(constant, childColumnIDs))%0A                                        .collect(Collectors.joining(%22,%22, %22 (%22, %22)%22)))%0A                                .collect(Collectors.joining(%22,%22));%0A%0A                        RelationID alias = generateFreshViewAlias();%0A%0A                        String sql = %22(VALUES %22 + tuplesSerialized + %22 ) AS %22 + alias;%0A%0A                        ImmutableList%3CVariable%3E orderedVariables = sqlValuesExpression.getOrderedVariables();%0A%0A                        // Map the column names generated by VALUES in h2 to projected variables%0A                        ImmutableMap%3CVariable, QualifiedAttributeID%3E columnIDs = orderedVariables.stream()%0A                                .collect(ImmutableCollectors.toMap(%0A                                        variable -%3E variable,%0A                                        variable -%3E new QualifiedAttributeID(null, idFactory.createAttributeID(%0A                                                alias + %22.expr%22 + (orderedVariables.indexOf(variable) + 1)))));%0A%0A                        return new QuerySerializationImpl(sql, columnIDs);%0A                    %7D
 %0A       

Support different Values serialization for teiid