/*
* #!
* Ontopia Engine
* #-
* Copyright (C) 2001 - 2013 The Ontopia Project
* #-
* 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 net.ontopia.persistence.query.sql;
import java.util.List;
import java.util.Map;
/**
* INTERNAL: Oracle SQL statement generator.
*/
public class OracleSQLGenerator extends GenericSQLGenerator {
OracleSQLGenerator(Map properties) {
super(properties);
}
public SQLStatementIF createSQLStatement(SQLQuery query) {
// NOTE: the following does not work, since ROWNUM > 1 always fails
// // Use ROWNUM expression when query has limit/offset
// SQLExpressionIF filter = query.getFilter();
// int limit = query.getLimit();
// int offset = query.getOffset();
//
// if (limit > 0 && offset > 0) {
// SQLVerbatimExpression ve_offset = new SQLVerbatimExpression("ROWNUM > " + offset);
// SQLVerbatimExpression ve_limit = new SQLVerbatimExpression("ROWNUM <= " + (offset + limit));
// query.setFilter(new SQLAnd(filter, ve_offset, ve_limit));
// } else if (limit > 0) {
// SQLVerbatimExpression ve_limit = new SQLVerbatimExpression("ROWNUM <= " + limit);
// query.setFilter(new SQLAnd(filter, ve_limit));
// } else if (offset > 0) {
// SQLVerbatimExpression ve_offset = new SQLVerbatimExpression("ROWNUM > " + offset);
// query.setFilter(new SQLAnd(filter, ve_offset));
// }
return super.createSQLStatement(query);
}
protected String createStatement(SQLExpressionIF filter, List selects, boolean distinct, int offset, int limit,
List orderby, boolean issetquery, BuildInfo info) {
String sql = super.createStatement(filter, selects, distinct, offset, limit, orderby, issetquery, info);
// LIMIT x OFFSET y clause
if (limit > 0 && offset > 0) {
StringBuilder sb = new StringBuilder("select * from ( select a.*, rownum rnum from (");
sb.append(sql);
sb.append(") a where rownum <= ").append(offset+limit); // max
sb.append(") where rnum >= ").append(offset+1); // min
return sb.toString();
} else if (limit > 0) {
StringBuilder sb = new StringBuilder("select a.* from (");
sb.append(sql);
sb.append(") a where rownum <= ").append(limit); // max
return sb.toString();
} else if (offset > 0) {
StringBuilder sb = new StringBuilder("select * from ( select a.*, rownum rnum from (");
sb.append(sql);
sb.append(") a ) where rnum >= ").append(offset+1); // min
return sb.toString();
} else {
return sql;
}
}
protected void fromSQLLeftOuterJoin(SQLJoin join, BuildInfo info) {
// Do nothing, since it is being specified in the where clause
}
protected void fromSQLRightOuterJoin(SQLJoin join, BuildInfo info) {
// Do nothing, since it is being specified in the where clause
}
protected void whereSQLLeftOuterJoin(SQLJoin join, StringBuilder sql, BuildInfo info) {
whereSQLLeftOuterJoin_ORACLE(join, sql, info);
}
protected void whereSQLRightOuterJoin(SQLJoin join, StringBuilder sql, BuildInfo info) {
whereSQLRightOuterJoin_ORACLE(join, sql, info);
}
protected String getSetOperator(int operator) {
if (operator == SQLSetOperation.EXCEPT)
return "minus";
if (operator == SQLSetOperation.EXCEPT_ALL)
return "minus all";
else
return super.getSetOperator(operator);
}
protected StringBuilder createOffsetLimitClause(int offset, int limit, BuildInfo info) {
// no-op, since oracle uses ROWNUM for this. see elsewhere.
return null;
}
public boolean supportsLimitOffset() {
return true;
}
protected void whereSQLFalse(SQLFalse expr, StringBuilder sql, BuildInfo info) {
sql.append("1 = 2");
}
}