/* * DBeaver - Universal Database Manager * Copyright (C) 2010-2017 Serge Rider (serge@jkiss.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jkiss.dbeaver.model.impl.sql; import org.jkiss.dbeaver.model.exec.DBCException; import org.jkiss.dbeaver.model.exec.DBCQueryTransformer; import org.jkiss.dbeaver.model.exec.DBCStatement; import org.jkiss.dbeaver.model.sql.SQLQuery; import org.jkiss.dbeaver.model.sql.SQLQueryType; /** * Query transformer for LIMIT */ public class QueryTransformerLimit implements DBCQueryTransformer { //private static final Pattern SELECT_PATTERN = Pattern.compile("\\s*(?:select|update|delete|insert).+", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); public static final String KEYWORD_LIMIT = "LIMIT"; private boolean supportsOffset; private Number offset; private Number length; private boolean limitSet; public QueryTransformerLimit() { this(true); } public QueryTransformerLimit(boolean supportsOffset) { this.supportsOffset = supportsOffset; } @Override public void setParameters(Object... parameters) { this.offset = (Number) parameters[0]; this.length = (Number) parameters[1]; } @Override public String transformQueryString(SQLQuery query) throws DBCException { String newQuery; boolean plainSelect = query.isPlainSelect(); if (!plainSelect && query.getType() == SQLQueryType.UNKNOWN) { // Not parsed. Try to check with simple matcher String testQuery = query.getText().toUpperCase().trim(); plainSelect = testQuery.startsWith("SELECT") && !testQuery.contains("LIMIT") && !testQuery.contains("INTO") && !testQuery.contains("UPDATE") && !testQuery.contains("PROCEDURE"); } if (!plainSelect) { // Do not use limit if it is not a select or it already has LIMIT or it is SELECT INTO statement limitSet = false; newQuery = query.getText(); } else { if (supportsOffset) { newQuery = query.getText() + "\n" + KEYWORD_LIMIT + " " + offset + ", " + length; } else { // We can limit only total row number newQuery = query.getText() + "\n" + KEYWORD_LIMIT + " " + (offset.longValue() + length.longValue()); } limitSet = supportsOffset; } return newQuery; } @Override public void transformStatement(DBCStatement statement, int parameterIndex) throws DBCException { if (!limitSet) { statement.setLimit(offset.longValue(), length.longValue()); } } }