/** * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. */ package com.liferay.portal.dao.orm.hibernate; import com.liferay.portal.kernel.util.StringBundler; import com.liferay.portal.kernel.util.StringPool; import com.liferay.portal.kernel.util.StringUtil; /** * @author Shepherd Ching * @author Jian Cao * @author Laszlo Csontos */ public class DB2Dialect extends org.hibernate.dialect.DB2Dialect { public DB2Dialect() { registerKeyword("for"); registerKeyword("optimize"); } @Override public String getForUpdateString() { return " for read only with rs use and keep exclusive locks"; } @Override public String getLimitString(String sql, int offset, int limit) { boolean hasOffset = false; if ((offset > 0) || forceLimitUsage()) { hasOffset = true; } StringBundler sb = null; if (hasOffset) { sb = new StringBundler(11); } else { sb = new StringBundler(5); } if (!hasOffset) { addQueryForLimitedRows(sb, sql, limit); addOptimizeForLimitedRows(sb, limit); return sb.toString(); } // Outer query sb.append("SELECT outerQuery.* FROM ("); // Inner query sb.append("SELECT innerQuery.*, ROW_NUMBER() OVER() AS rowNumber_ "); sb.append("FROM ("); addQueryForLimitedRows(sb, sql, limit); sb.append(") AS innerQuery"); // Offset sb.append(") AS outerQuery WHERE rowNumber_ > "); sb.append(offset); addOptimizeForLimitedRows(sb, limit); return sb.toString(); } @Override public boolean supportsVariableLimit() { return _SUPPORTS_VARIABLE_LIMIT; } protected void addOptimizeForLimitedRows(StringBundler sb, int limit) { sb.append(StringPool.SPACE); sb.append( StringUtil.replace( _SQL_OPTIMIZE_FOR_LIMITED_ROWS, "[$LIMIT$]", String.valueOf(limit))); } protected void addQueryForLimitedRows( StringBundler sb, String sql, int limit) { sb.append(sql); sb.append(StringPool.SPACE); sb.append( StringUtil.replace( _SQL_FETCH_FIRST_LIMITED_ROWS_ONLY, "[$LIMIT$]", String.valueOf(limit))); } private static final String _SQL_FETCH_FIRST_LIMITED_ROWS_ONLY = "FETCH FIRST [$LIMIT$] ROWS ONLY"; private static final String _SQL_OPTIMIZE_FOR_LIMITED_ROWS = "OPTIMIZE FOR [$LIMIT$] ROWS"; private static final boolean _SUPPORTS_VARIABLE_LIMIT = false; }