package sqlancer;

import java.sql.SQLException;
import java.util.List;
import java.util.stream.Collectors;

import sqlancer.StateToReproduce.OracleRunReproductionState;
import sqlancer.common.oracle.CompositeTestOracle;
import sqlancer.common.oracle.TestOracle;

public abstract class ProviderAdapter<G extends GlobalState<O, ?>, O extends DBMSSpecificOptions<? extends OracleFactory<G>>>
        implements DatabaseProvider<G, O> {

    private final Class<G> globalClass;
    private final Class<O> optionClass;

    public ProviderAdapter(Class<G> globalClass, Class<O> optionClass) {
        this.globalClass = globalClass;
        this.optionClass = optionClass;
    }

    @Override
    public StateToReproduce getStateToReproduce(String databaseName) {
        return new StateToReproduce(databaseName);
    }

    @Override
    public Class<G> getGlobalStateClass() {
        return globalClass;
    }

    @Override
    public Class<O> getOptionClass() {
        return optionClass;
    }

    @Override
    public void generateAndTestDatabase(G globalState) throws SQLException {
        try {
            generateDatabase(globalState);
            globalState.getManager().incrementCreateDatabase();

            TestOracle oracle = getTestOracle(globalState);
            for (int i = 0; i < globalState.getOptions().getNrQueries(); i++) {
                try (OracleRunReproductionState localState = globalState.getState().createLocalState()) {
                    assert localState != null;
                    try {
                        oracle.check();
                        globalState.getManager().incrementSelectQueryCount();
                    } catch (IgnoreMeException e) {

                    }
                    assert localState != null;
                    localState.executedWithoutError();
                }
            }
        } finally {
            globalState.getConnection().close();
        }
    }

    protected TestOracle getTestOracle(G globalState) throws SQLException {
        List<? extends OracleFactory<G>> testOracleFactory = globalState.getDmbsSpecificOptions()
                .getTestOracleFactory();
        boolean testOracleRequiresMoreThanZeroRows = testOracleFactory.stream()
                .anyMatch(p -> p.requiresAllTablesToContainRows());
        boolean userRequiresMoreThanZeroRows = globalState.getOptions().testOnlyWithMoreThanZeroRows();
        boolean checkZeroRows = testOracleRequiresMoreThanZeroRows || userRequiresMoreThanZeroRows;
        if (checkZeroRows && globalState.getSchema().containsTableWithZeroRows(globalState)) {
            throw new IgnoreMeException();
        }
        if (testOracleFactory.size() == 1) {
            return testOracleFactory.get(0).create(globalState);
        } else {
            return new CompositeTestOracle(testOracleFactory.stream().map(o -> {
                try {
                    return o.create(globalState);
                } catch (SQLException e1) {
                    throw new AssertionError(e1);
                }
            }).collect(Collectors.toList()), globalState);
        }
    }

    public abstract void generateDatabase(G globalState) throws SQLException;

}

@@ -255,16 +255,104 @@
 tOracle;
+%0Aimport sqlancer.common.query.QueryAdapter;%0Aimport sqlancer.common.schema.AbstractTable;
 %0A%0Apublic
@@ -1221,32 +1221,77 @@
 e(globalState);%0A
+            checkViewsAreValid(globalState);%0A
             glob
@@ -2001,24 +2001,24 @@
 %7D finally %7B%0A
-
             
@@ -2067,24 +2067,481 @@
    %7D%0A    %7D%0A%0A
+    private void checkViewsAreValid(G globalState) %7B%0A        List%3C? extends AbstractTable%3C?, ?%3E%3E views = globalState.getSchema().getViews();%0A        for (AbstractTable%3C?, ?%3E view : views) %7B%0A            QueryAdapter q = new QueryAdapter(%22SELECT 1 FROM %22 + view.getName() + %22 LIMIT 1%22);%0A            try %7B%0A                q.execute(globalState);%0A            %7D catch (Throwable t) %7B%0A                throw new IgnoreMeException();%0A            %7D%0A        %7D%0A    %7D%0A%0A
     protecte

Check for invalid views in the ProviderAdapter base class