HHH-3712 - Reorganize the Sybase dialect class hierarchy, add SybaseASE15Dialect, and mark SybaseDialect as deprecated

git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@15934 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Gail Badner 2009-02-11 05:34:52 +00:00
parent a1263d35b3
commit 638b43f04b
18 changed files with 466 additions and 276 deletions

View File

@ -0,0 +1,263 @@
//$Id: $
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Middleware LLC.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program 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.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*
*/
package org.hibernate.dialect;
import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Map;
import java.util.Iterator;
import org.hibernate.Hibernate;
import org.hibernate.LockMode;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.function.CharIndexFunction;
import org.hibernate.dialect.function.NoArgSQLFunction;
import org.hibernate.dialect.function.SQLFunctionTemplate;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.dialect.function.VarArgsSQLFunction;
/**
* An abstract base class for Sybase and MS SQL Server dialects.
* @author Gavin King
*/
/* package-private */
abstract class AbstractTransactSQLDialect extends Dialect {
public AbstractTransactSQLDialect() {
super();
registerColumnType( Types.BIT, "tinyint" ); //Sybase BIT type does not support null values
registerColumnType( Types.BIGINT, "numeric(19,0)" );
registerColumnType( Types.SMALLINT, "smallint" );
registerColumnType( Types.TINYINT, "tinyint" );
registerColumnType( Types.INTEGER, "int" );
registerColumnType( Types.CHAR, "char(1)" );
registerColumnType( Types.VARCHAR, "varchar($l)" );
registerColumnType( Types.FLOAT, "float" );
registerColumnType( Types.DOUBLE, "double precision" );
registerColumnType( Types.DATE, "datetime" );
registerColumnType( Types.TIME, "datetime" );
registerColumnType( Types.TIMESTAMP, "datetime" );
registerColumnType( Types.VARBINARY, "varbinary($l)" );
registerColumnType( Types.NUMERIC, "numeric($p,$s)" );
registerColumnType( Types.BLOB, "image" );
registerColumnType( Types.CLOB, "text" );
registerFunction( "ascii", new StandardSQLFunction("ascii", Hibernate.INTEGER) );
registerFunction( "char", new StandardSQLFunction("char", Hibernate.CHARACTER) );
registerFunction( "len", new StandardSQLFunction("len", Hibernate.LONG) );
registerFunction( "lower", new StandardSQLFunction("lower") );
registerFunction( "upper", new StandardSQLFunction("upper") );
registerFunction( "str", new StandardSQLFunction("str", Hibernate.STRING) );
registerFunction( "ltrim", new StandardSQLFunction("ltrim") );
registerFunction( "rtrim", new StandardSQLFunction("rtrim") );
registerFunction( "reverse", new StandardSQLFunction("reverse") );
registerFunction( "space", new StandardSQLFunction("space", Hibernate.STRING) );
registerFunction( "user", new NoArgSQLFunction("user", Hibernate.STRING) );
registerFunction( "current_timestamp", new NoArgSQLFunction("getdate", Hibernate.TIMESTAMP) );
registerFunction( "current_time", new NoArgSQLFunction("getdate", Hibernate.TIME) );
registerFunction( "current_date", new NoArgSQLFunction("getdate", Hibernate.DATE) );
registerFunction( "getdate", new NoArgSQLFunction("getdate", Hibernate.TIMESTAMP) );
registerFunction( "getutcdate", new NoArgSQLFunction("getutcdate", Hibernate.TIMESTAMP) );
registerFunction( "day", new StandardSQLFunction("day", Hibernate.INTEGER) );
registerFunction( "month", new StandardSQLFunction("month", Hibernate.INTEGER) );
registerFunction( "year", new StandardSQLFunction("year", Hibernate.INTEGER) );
registerFunction( "datename", new StandardSQLFunction("datename", Hibernate.STRING) );
registerFunction( "abs", new StandardSQLFunction("abs") );
registerFunction( "sign", new StandardSQLFunction("sign", Hibernate.INTEGER) );
registerFunction( "acos", new StandardSQLFunction("acos", Hibernate.DOUBLE) );
registerFunction( "asin", new StandardSQLFunction("asin", Hibernate.DOUBLE) );
registerFunction( "atan", new StandardSQLFunction("atan", Hibernate.DOUBLE) );
registerFunction( "cos", new StandardSQLFunction("cos", Hibernate.DOUBLE) );
registerFunction( "cot", new StandardSQLFunction("cot", Hibernate.DOUBLE) );
registerFunction( "exp", new StandardSQLFunction("exp", Hibernate.DOUBLE) );
registerFunction( "log", new StandardSQLFunction( "log", Hibernate.DOUBLE) );
registerFunction( "log10", new StandardSQLFunction("log10", Hibernate.DOUBLE) );
registerFunction( "sin", new StandardSQLFunction("sin", Hibernate.DOUBLE) );
registerFunction( "sqrt", new StandardSQLFunction("sqrt", Hibernate.DOUBLE) );
registerFunction( "tan", new StandardSQLFunction("tan", Hibernate.DOUBLE) );
registerFunction( "pi", new NoArgSQLFunction("pi", Hibernate.DOUBLE) );
registerFunction( "square", new StandardSQLFunction("square") );
registerFunction( "rand", new StandardSQLFunction("rand", Hibernate.FLOAT) );
registerFunction("radians", new StandardSQLFunction("radians", Hibernate.DOUBLE) );
registerFunction("degrees", new StandardSQLFunction("degrees", Hibernate.DOUBLE) );
registerFunction( "round", new StandardSQLFunction("round") );
registerFunction( "ceiling", new StandardSQLFunction("ceiling") );
registerFunction( "floor", new StandardSQLFunction("floor") );
registerFunction( "isnull", new StandardSQLFunction("isnull") );
registerFunction( "concat", new VarArgsSQLFunction( Hibernate.STRING, "(","+",")" ) );
registerFunction( "length", new StandardSQLFunction( "len", Hibernate.INTEGER ) );
registerFunction( "trim", new SQLFunctionTemplate( Hibernate.STRING, "ltrim(rtrim(?1))") );
registerFunction( "locate", new CharIndexFunction() );
getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, NO_BATCH);
}
public String getAddColumnString() {
return "add";
}
public String getNullColumnString() {
return " null";
}
public boolean qualifyIndexName() {
return false;
}
public String getForUpdateString() {
return "";
}
public boolean supportsIdentityColumns() {
return true;
}
public String getIdentitySelectString() {
return "select @@identity";
}
public String getIdentityColumnString() {
return "identity not null"; //starts with 1, implicitly
}
public boolean supportsInsertSelectIdentity() {
return true;
}
public String appendIdentitySelectToInsert(String insertSQL) {
return insertSQL + "\nselect @@identity";
}
public String appendLockHint(LockMode mode, String tableName) {
if ( mode.greaterThan( LockMode.READ ) ) {
return tableName + " holdlock";
}
else {
return tableName;
}
}
public String applyLocksToSql(String sql, Map aliasedLockModes, Map keyColumnNames) {
Iterator itr = aliasedLockModes.entrySet().iterator();
StringBuffer buffer = new StringBuffer( sql );
int correction = 0;
while ( itr.hasNext() ) {
final Map.Entry entry = ( Map.Entry ) itr.next();
final LockMode lockMode = ( LockMode ) entry.getValue();
if ( lockMode.greaterThan( LockMode.READ ) ) {
final String alias = ( String ) entry.getKey();
int start = -1, end = -1;
if ( sql.endsWith( " " + alias ) ) {
start = ( sql.length() - alias.length() ) + correction;
end = start + alias.length();
}
else {
int position = sql.indexOf( " " + alias + " " );
if ( position <= -1 ) {
position = sql.indexOf( " " + alias + "," );
}
if ( position > -1 ) {
start = position + correction + 1;
end = start + alias.length();
}
}
if ( start > -1 ) {
final String lockHint = appendLockHint( lockMode, alias );
buffer.replace( start, end, lockHint );
correction += ( lockHint.length() - alias.length() );
}
}
}
return buffer.toString();
}
public int registerResultSetOutParameter(CallableStatement statement, int col) throws SQLException {
return col; // sql server just returns automatically
}
public ResultSet getResultSet(CallableStatement ps) throws SQLException {
boolean isResultSet = ps.execute();
// This assumes you will want to ignore any update counts
while ( !isResultSet && ps.getUpdateCount() != -1 ) {
isResultSet = ps.getMoreResults();
}
// You may still have other ResultSets or update counts left to process here
// but you can't do it now or the ResultSet you just got will be closed
return ps.getResultSet();
}
public boolean supportsCurrentTimestampSelection() {
return true;
}
public boolean isCurrentTimestampSelectStringCallable() {
return false;
}
public String getCurrentTimestampSelectString() {
return "select getdate()";
}
public boolean supportsTemporaryTables() {
return true;
}
public String generateTemporaryTableName(String baseTableName) {
return "#" + baseTableName;
}
public boolean dropTemporaryTableAfterUse() {
return true; // sql-server, at least needed this dropped after use; strange!
}
// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public boolean supportsEmptyInList() {
return false;
}
public boolean supportsExistsInSelect() {
return false;
}
public boolean doesReadCommittedCauseWritersToBlockReaders() {
return true;
}
public boolean doesRepeatableReadCauseReadersToBlockWriters() {
return true;
}
}

View File

@ -43,8 +43,12 @@ public class SQLServerDialect extends SybaseDialect {
registerColumnType( Types.VARBINARY, "image" ); registerColumnType( Types.VARBINARY, "image" );
registerColumnType( Types.VARBINARY, 8000, "varbinary($l)" ); registerColumnType( Types.VARBINARY, 8000, "varbinary($l)" );
registerFunction( "second", new SQLFunctionTemplate( Hibernate.INTEGER, "datepart(second, ?1)" ) );
registerFunction( "minute", new SQLFunctionTemplate( Hibernate.INTEGER, "datepart(minute, ?1)" ) );
registerFunction( "hour", new SQLFunctionTemplate( Hibernate.INTEGER, "datepart(hour, ?1)" ) );
registerFunction( "locate", new StandardSQLFunction( "charindex", Hibernate.INTEGER ) ); registerFunction( "locate", new StandardSQLFunction( "charindex", Hibernate.INTEGER ) );
registerFunction( "extract", new SQLFunctionTemplate( Hibernate.INTEGER, "datepart(?1, ?3)" ) );
registerFunction( "mod", new SQLFunctionTemplate( Hibernate.INTEGER, "?1 % ?2" ) ); registerFunction( "mod", new SQLFunctionTemplate( Hibernate.INTEGER, "?1 % ?2" ) );
registerFunction( "bit_length", new SQLFunctionTemplate( Hibernate.INTEGER, "datalength(?1) * 8" ) ); registerFunction( "bit_length", new SQLFunctionTemplate( Hibernate.INTEGER, "datalength(?1) * 8" ) );
@ -134,10 +138,6 @@ public class SQLServerDialect extends SybaseDialect {
return false; return false;
} }
public boolean supportsCascadeDelete() {
return true;
}
public boolean supportsCircularCascadeDeleteConstraints() { public boolean supportsCircularCascadeDeleteConstraints() {
// SQL Server (at least up through 2005) does not support defining // SQL Server (at least up through 2005) does not support defining
// cascade delete constraints which can circel back to the mutating // cascade delete constraints which can circel back to the mutating
@ -145,10 +145,6 @@ public class SQLServerDialect extends SybaseDialect {
return false; return false;
} }
public boolean supportsExpectedLobUsagePattern() {
return true;
}
public boolean supportsLobValueChangePropogation() { public boolean supportsLobValueChangePropogation() {
// note: at least my local SQL Server 2005 Express shows this not working... // note: at least my local SQL Server 2005 Express shows this not working...
return false; return false;

View File

@ -31,7 +31,7 @@ import org.hibernate.sql.Sybase11JoinFragment;
* A SQL dialect suitable for use with Sybase 11.9.2 (specifically: avoids ANSI JOIN syntax) * A SQL dialect suitable for use with Sybase 11.9.2 (specifically: avoids ANSI JOIN syntax)
* @author Colm O' Flaherty * @author Colm O' Flaherty
*/ */
public class Sybase11Dialect extends SybaseDialect { public class Sybase11Dialect extends AbstractTransactSQLDialect {
public Sybase11Dialect() { public Sybase11Dialect() {
super(); super();
} }

View File

@ -0,0 +1,67 @@
//$Id $
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Middleware LLC.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program 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.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*
*/
package org.hibernate.dialect;
import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Map;
import java.util.Iterator;
import org.hibernate.Hibernate;
import org.hibernate.LockMode;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.function.CharIndexFunction;
import org.hibernate.dialect.function.NoArgSQLFunction;
import org.hibernate.dialect.function.SQLFunctionTemplate;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.dialect.function.VarArgsSQLFunction;
/**
* An SQL dialect compatible with Sybase and MS SQL Server.
* @author Gavin King
*/
public class SybaseASE15Dialect extends AbstractTransactSQLDialect {
public SybaseASE15Dialect() {
super();
registerFunction( "second", new SQLFunctionTemplate(Hibernate.INTEGER, "datepart(second, ?1)") );
registerFunction( "minute", new SQLFunctionTemplate(Hibernate.INTEGER, "datepart(minute, ?1)") );
registerFunction( "hour", new SQLFunctionTemplate(Hibernate.INTEGER, "datepart(hour, ?1)") );
registerFunction( "extract", new SQLFunctionTemplate( Hibernate.INTEGER, "datepart(?1, ?3)" ) );
}
// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public boolean supportsCascadeDelete() {
return false;
}
public boolean supportsExpectedLobUsagePattern() {
return false;
}
}

View File

@ -30,7 +30,7 @@ package org.hibernate.dialect;
* (Tested on ASA 8.x) * (Tested on ASA 8.x)
* @author ? * @author ?
*/ */
public class SybaseAnywhereDialect extends SybaseDialect { public class SybaseAnywhereDialect extends AbstractTransactSQLDialect {
/** /**
* Sybase Anywhere syntax would require a "DEFAULT" for each column specified, * Sybase Anywhere syntax would require a "DEFAULT" for each column specified,

View File

@ -1,3 +1,4 @@
//$Id $
/* /*
* Hibernate, Relational Persistence for Idiomatic Java * Hibernate, Relational Persistence for Idiomatic Java
* *
@ -24,253 +25,16 @@
*/ */
package org.hibernate.dialect; package org.hibernate.dialect;
import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Map;
import java.util.Iterator;
import org.hibernate.Hibernate;
import org.hibernate.LockMode;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.function.CharIndexFunction;
import org.hibernate.dialect.function.NoArgSQLFunction;
import org.hibernate.dialect.function.SQLFunctionTemplate;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.dialect.function.VarArgsSQLFunction;
/** /**
* An SQL dialect compatible with Sybase and MS SQL Server. * SybaseDialect is being deprecated.
* @author Gavin King *
* AbstractTransactSQLDialect should be used as a base
* class for Sybase and MS SQL Server dialects.
*
* @author Gail Badner
* @deprecated SybaseASE15Dialect or SQLServerDialect should be
* used instead.
*/ */
public class SybaseDialect extends Dialect { public class SybaseDialect extends AbstractTransactSQLDialect {
public SybaseDialect() {
super();
registerColumnType( Types.BIT, "tinyint" ); //Sybase BIT type does not support null values
registerColumnType( Types.BIGINT, "numeric(19,0)" );
registerColumnType( Types.SMALLINT, "smallint" );
registerColumnType( Types.TINYINT, "tinyint" );
registerColumnType( Types.INTEGER, "int" );
registerColumnType( Types.CHAR, "char(1)" );
registerColumnType( Types.VARCHAR, "varchar($l)" );
registerColumnType( Types.FLOAT, "float" );
registerColumnType( Types.DOUBLE, "double precision" );
registerColumnType( Types.DATE, "datetime" );
registerColumnType( Types.TIME, "datetime" );
registerColumnType( Types.TIMESTAMP, "datetime" );
registerColumnType( Types.VARBINARY, "varbinary($l)" );
registerColumnType( Types.NUMERIC, "numeric($p,$s)" );
registerColumnType( Types.BLOB, "image" );
registerColumnType( Types.CLOB, "text" );
registerFunction( "ascii", new StandardSQLFunction("ascii", Hibernate.INTEGER) );
registerFunction( "char", new StandardSQLFunction("char", Hibernate.CHARACTER) );
registerFunction( "len", new StandardSQLFunction("len", Hibernate.LONG) );
registerFunction( "lower", new StandardSQLFunction("lower") );
registerFunction( "upper", new StandardSQLFunction("upper") );
registerFunction( "str", new StandardSQLFunction("str", Hibernate.STRING) );
registerFunction( "ltrim", new StandardSQLFunction("ltrim") );
registerFunction( "rtrim", new StandardSQLFunction("rtrim") );
registerFunction( "reverse", new StandardSQLFunction("reverse") );
registerFunction( "space", new StandardSQLFunction("space", Hibernate.STRING) );
registerFunction( "user", new NoArgSQLFunction("user", Hibernate.STRING) );
registerFunction( "current_timestamp", new NoArgSQLFunction("getdate", Hibernate.TIMESTAMP) );
registerFunction( "current_time", new NoArgSQLFunction("getdate", Hibernate.TIME) );
registerFunction( "current_date", new NoArgSQLFunction("getdate", Hibernate.DATE) );
registerFunction( "getdate", new NoArgSQLFunction("getdate", Hibernate.TIMESTAMP) );
registerFunction( "getutcdate", new NoArgSQLFunction("getutcdate", Hibernate.TIMESTAMP) );
registerFunction( "day", new StandardSQLFunction("day", Hibernate.INTEGER) );
registerFunction( "month", new StandardSQLFunction("month", Hibernate.INTEGER) );
registerFunction( "year", new StandardSQLFunction("year", Hibernate.INTEGER) );
registerFunction( "datename", new StandardSQLFunction("datename", Hibernate.STRING) );
registerFunction( "second", new SQLFunctionTemplate(Hibernate.INTEGER, "datepart(second, ?1)") );
registerFunction( "minute", new SQLFunctionTemplate(Hibernate.INTEGER, "datepart(minute, ?1)") );
registerFunction( "hour", new SQLFunctionTemplate(Hibernate.INTEGER, "datepart(hour, ?1)") );
registerFunction( "extract", new SQLFunctionTemplate( Hibernate.INTEGER, "datepart(?1, ?3)" ) );
registerFunction( "abs", new StandardSQLFunction("abs") );
registerFunction( "sign", new StandardSQLFunction("sign", Hibernate.INTEGER) );
registerFunction( "acos", new StandardSQLFunction("acos", Hibernate.DOUBLE) );
registerFunction( "asin", new StandardSQLFunction("asin", Hibernate.DOUBLE) );
registerFunction( "atan", new StandardSQLFunction("atan", Hibernate.DOUBLE) );
registerFunction( "cos", new StandardSQLFunction("cos", Hibernate.DOUBLE) );
registerFunction( "cot", new StandardSQLFunction("cot", Hibernate.DOUBLE) );
registerFunction( "exp", new StandardSQLFunction("exp", Hibernate.DOUBLE) );
registerFunction( "log", new StandardSQLFunction( "log", Hibernate.DOUBLE) );
registerFunction( "log10", new StandardSQLFunction("log10", Hibernate.DOUBLE) );
registerFunction( "sin", new StandardSQLFunction("sin", Hibernate.DOUBLE) );
registerFunction( "sqrt", new StandardSQLFunction("sqrt", Hibernate.DOUBLE) );
registerFunction( "tan", new StandardSQLFunction("tan", Hibernate.DOUBLE) );
registerFunction( "pi", new NoArgSQLFunction("pi", Hibernate.DOUBLE) );
registerFunction( "square", new StandardSQLFunction("square") );
registerFunction( "rand", new StandardSQLFunction("rand", Hibernate.FLOAT) );
registerFunction("radians", new StandardSQLFunction("radians", Hibernate.DOUBLE) );
registerFunction("degrees", new StandardSQLFunction("degrees", Hibernate.DOUBLE) );
registerFunction( "round", new StandardSQLFunction("round") );
registerFunction( "ceiling", new StandardSQLFunction("ceiling") );
registerFunction( "floor", new StandardSQLFunction("floor") );
registerFunction( "isnull", new StandardSQLFunction("isnull") );
registerFunction( "concat", new VarArgsSQLFunction( Hibernate.STRING, "(","+",")" ) );
registerFunction( "length", new StandardSQLFunction( "len", Hibernate.INTEGER ) );
registerFunction( "trim", new SQLFunctionTemplate( Hibernate.STRING, "ltrim(rtrim(?1))") );
registerFunction( "locate", new CharIndexFunction() );
registerFunction( "mod", new SQLFunctionTemplate( Hibernate.INTEGER, "?1 % ?2" ) );
registerFunction( "bit_length", new SQLFunctionTemplate( Hibernate.INTEGER, "datalength(?1) * 8" ) );
getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, NO_BATCH);
}
public String getAddColumnString() {
return "add";
}
public String getNullColumnString() {
return " null";
}
public boolean qualifyIndexName() {
return false;
}
public String getForUpdateString() {
return "";
}
public boolean supportsIdentityColumns() {
return true;
}
public String getIdentitySelectString() {
return "select @@identity";
}
public String getIdentityColumnString() {
return "identity not null"; //starts with 1, implicitly
}
public boolean supportsInsertSelectIdentity() {
return true;
}
public String appendIdentitySelectToInsert(String insertSQL) {
return insertSQL + "\nselect @@identity";
}
public String appendLockHint(LockMode mode, String tableName) {
if ( mode.greaterThan( LockMode.READ ) ) {
return tableName + " holdlock";
}
else {
return tableName;
}
}
public String applyLocksToSql(String sql, Map aliasedLockModes, Map keyColumnNames) {
Iterator itr = aliasedLockModes.entrySet().iterator();
StringBuffer buffer = new StringBuffer( sql );
int correction = 0;
while ( itr.hasNext() ) {
final Map.Entry entry = ( Map.Entry ) itr.next();
final LockMode lockMode = ( LockMode ) entry.getValue();
if ( lockMode.greaterThan( LockMode.READ ) ) {
final String alias = ( String ) entry.getKey();
int start = -1, end = -1;
if ( sql.endsWith( " " + alias ) ) {
start = ( sql.length() - alias.length() ) + correction;
end = start + alias.length();
}
else {
int position = sql.indexOf( " " + alias + " " );
if ( position <= -1 ) {
position = sql.indexOf( " " + alias + "," );
}
if ( position > -1 ) {
start = position + correction + 1;
end = start + alias.length();
}
}
if ( start > -1 ) {
final String lockHint = appendLockHint( lockMode, alias );
buffer.replace( start, end, lockHint );
correction += ( lockHint.length() - alias.length() );
}
}
}
return buffer.toString();
}
public int registerResultSetOutParameter(CallableStatement statement, int col) throws SQLException {
return col; // sql server just returns automatically
}
public ResultSet getResultSet(CallableStatement ps) throws SQLException {
boolean isResultSet = ps.execute();
// This assumes you will want to ignore any update counts
while ( !isResultSet && ps.getUpdateCount() != -1 ) {
isResultSet = ps.getMoreResults();
}
// You may still have other ResultSets or update counts left to process here
// but you can't do it now or the ResultSet you just got will be closed
return ps.getResultSet();
}
public boolean supportsCurrentTimestampSelection() {
return true;
}
public boolean isCurrentTimestampSelectStringCallable() {
return false;
}
public String getCurrentTimestampSelectString() {
return "select getdate()";
}
public boolean supportsTemporaryTables() {
return true;
}
public String generateTemporaryTableName(String baseTableName) {
return "#" + baseTableName;
}
public boolean dropTemporaryTableAfterUse() {
return true; // sql-server, at least needed this dropped after use; strange!
}
// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public boolean supportsCascadeDelete() {
return false;
}
public boolean supportsExpectedLobUsagePattern() {
return false;
}
public boolean supportsEmptyInList() {
return false;
}
public boolean supportsExistsInSelect() {
return false;
}
public boolean doesReadCommittedCauseWritersToBlockReaders() {
return true;
}
public boolean doesRepeatableReadCauseReadersToBlockWriters() {
return true;
}
} }

View File

@ -283,6 +283,25 @@
</properties> </properties>
</profile> </profile>
<profile>
<id>sybase15</id>
<dependencies>
<dependency>
<groupId>com.sybase</groupId>
<artifactId>jconnect</artifactId>
<version>6.0.5</version>
</dependency>
</dependencies>
<properties>
<db.dialect>org.hibernate.dialect.SybaseASE15Dialect</db.dialect>
<jdbc.driver>com.sybase.jdbc3.jdbc.SybDriver</jdbc.driver>
<jdbc.url>jdbc:sybase:Tds:dev77.qa.atl2.redhat.com:5000/hibernate</jdbc.url>
<jdbc.user>hibernate</jdbc.user>
<jdbc.pass>hibernate</jdbc.pass>
<jdbc.isolation />
</properties>
</profile>
<!-- The SQLServer2005 (jTDS) test envionment --> <!-- The SQLServer2005 (jTDS) test envionment -->
<profile> <profile>
<id>sqlserver-jtds</id> <id>sqlserver-jtds</id>
@ -324,4 +343,4 @@
</profile> </profile>
</profiles> </profiles>
</project> </project>

View File

@ -107,7 +107,7 @@ public class AggressiveReleaseTest extends ConnectionManagementTestCase {
// expected behavior // expected behavior
} }
// getting the first row only because Sybase throws NullPointerException // getting the first row only because SybaseASE15Dialect throws NullPointerException
// if data is not read before closing the ResultSet // if data is not read before closing the ResultSet
sr.next(); sr.next();

View File

@ -0,0 +1,56 @@
//$Id $
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Middleware LLC.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program 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.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*
*/
package org.hibernate.test.dialect.unit.lockhint;
import junit.framework.TestSuite;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.SybaseASE15Dialect;
/**
* {@inheritDoc}
*
* @author Gail Badner
*/
public class SybaseASE15LockHintsTest extends AbstractLockHintTest {
public static final Dialect DIALECT = new SybaseASE15Dialect();
public SybaseASE15LockHintsTest(String string) {
super( string );
}
protected String getLockHintUsed() {
return "holdlock";
}
protected Dialect getDialectUnderTest() {
return DIALECT;
}
public static TestSuite suite() {
return new TestSuite( SybaseASE15LockHintsTest.class );
}
}

View File

@ -5,6 +5,10 @@ import junit.framework.Test;
import org.hibernate.dialect.Dialect; import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.SybaseDialect; import org.hibernate.dialect.SybaseDialect;
import org.hibernate.dialect.Sybase11Dialect;
import org.hibernate.dialect.SybaseAnywhereDialect;
import org.hibernate.dialect.SybaseASE15Dialect;
import org.hibernate.dialect.SQLServerDialect;
import org.hibernate.junit.functional.FunctionalTestClassTestSuite; import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
/** /**
@ -25,7 +29,9 @@ public class TimestampGeneratedValuesWithCachingTest extends AbstractGeneratedPr
public boolean appliesTo(Dialect dialect) { public boolean appliesTo(Dialect dialect) {
// this test is specific to Sybase/SQLServer as it is testing support // this test is specific to Sybase/SQLServer as it is testing support
// for their TIMESTAMP datatype... // for their TIMESTAMP datatype...
return ( dialect instanceof SybaseDialect ); return ( dialect instanceof SybaseDialect || dialect instanceof Sybase11Dialect ||
dialect instanceof SybaseAnywhereDialect || dialect instanceof SybaseASE15Dialect ||
dialect instanceof SQLServerDialect);
} }
public static Test suite() { public static Test suite() {

View File

@ -31,6 +31,9 @@ import org.hibernate.dialect.Oracle9Dialect;
import org.hibernate.dialect.PostgreSQLDialect; import org.hibernate.dialect.PostgreSQLDialect;
import org.hibernate.dialect.SQLServerDialect; import org.hibernate.dialect.SQLServerDialect;
import org.hibernate.dialect.SybaseDialect; import org.hibernate.dialect.SybaseDialect;
import org.hibernate.dialect.Sybase11Dialect;
import org.hibernate.dialect.SybaseASE15Dialect;
import org.hibernate.dialect.SybaseAnywhereDialect;
import org.hibernate.dialect.Oracle8iDialect; import org.hibernate.dialect.Oracle8iDialect;
import org.hibernate.hql.ast.ASTQueryTranslatorFactory; import org.hibernate.hql.ast.ASTQueryTranslatorFactory;
import org.hibernate.junit.functional.FunctionalTestCase; import org.hibernate.junit.functional.FunctionalTestCase;
@ -1221,7 +1224,7 @@ public class ASTParserLoadingTest extends FunctionalTestCase {
if ( getDialect() instanceof DB2Dialect ) { if ( getDialect() instanceof DB2Dialect ) {
assertTrue( str.startsWith("1.234") ); assertTrue( str.startsWith("1.234") );
} }
else if ( getDialect() instanceof SybaseDialect ) { else if ( getDialect() instanceof SybaseDialect || getDialect() instanceof Sybase11Dialect || getDialect() instanceof SybaseASE15Dialect || getDialect() instanceof SybaseAnywhereDialect || getDialect() instanceof SQLServerDialect ) {
// str(val) on sybase assumes a default of 10 characters with no decimal point or decimal values // str(val) on sybase assumes a default of 10 characters with no decimal point or decimal values
// str(val) on sybase result is right-justified // str(val) on sybase result is right-justified
assertEquals( str.length(), 10 ); assertEquals( str.length(), 10 );
@ -1233,7 +1236,7 @@ public class ASTParserLoadingTest extends FunctionalTestCase {
else { else {
assertTrue( str.startsWith("123.4") ); assertTrue( str.startsWith("123.4") );
} }
if ( ! ( getDialect() instanceof SybaseDialect ) ) { if ( ! ( getDialect() instanceof SybaseDialect ) && ! ( getDialect() instanceof Sybase11Dialect ) && ! ( getDialect() instanceof SybaseASE15Dialect ) && ! ( getDialect() instanceof SybaseAnywhereDialect ) && ! ( getDialect() instanceof SQLServerDialect ) ) {
// In TransactSQL (the variant spoken by Sybase and SQLServer), the str() function // In TransactSQL (the variant spoken by Sybase and SQLServer), the str() function
// is explicitly intended for numeric values only... // is explicitly intended for numeric values only...
String dateStr1 = (String) session.createQuery("select str(current_date) from Animal").uniqueResult(); String dateStr1 = (String) session.createQuery("select str(current_date) from Animal").uniqueResult();

View File

@ -20,7 +20,11 @@ import org.hibernate.dialect.HSQLDialect;
import org.hibernate.dialect.MySQLDialect; import org.hibernate.dialect.MySQLDialect;
import org.hibernate.dialect.Oracle9Dialect; import org.hibernate.dialect.Oracle9Dialect;
import org.hibernate.dialect.PostgreSQLDialect; import org.hibernate.dialect.PostgreSQLDialect;
import org.hibernate.dialect.SQLServerDialect;
import org.hibernate.dialect.SybaseAnywhereDialect;
import org.hibernate.dialect.SybaseDialect; import org.hibernate.dialect.SybaseDialect;
import org.hibernate.dialect.Sybase11Dialect;
import org.hibernate.dialect.SybaseASE15Dialect;
import org.hibernate.dialect.Oracle8iDialect; import org.hibernate.dialect.Oracle8iDialect;
import org.hibernate.dialect.function.SQLFunction; import org.hibernate.dialect.function.SQLFunction;
import org.hibernate.engine.SessionFactoryImplementor; import org.hibernate.engine.SessionFactoryImplementor;
@ -219,11 +223,14 @@ public class HQLTest extends QueryTranslatorTestCase {
assertTranslation("from Animal a where abs(:param - a.bodyWeight) < 2.0"); assertTranslation("from Animal a where abs(:param - a.bodyWeight) < 2.0");
assertTranslation("from Animal where abs(:x - :y) < 2.0"); assertTranslation("from Animal where abs(:x - :y) < 2.0");
assertTranslation("from Animal where lower(upper(:foo)) like 'f%'"); assertTranslation("from Animal where lower(upper(:foo)) like 'f%'");
if ( ! ( getDialect() instanceof SybaseDialect ) ) { if ( ! ( getDialect() instanceof SybaseDialect ) && ! ( getDialect() instanceof Sybase11Dialect ) && ! ( getDialect() instanceof SybaseASE15Dialect ) && ! ( getDialect() instanceof SQLServerDialect ) ) {
// SybaseDialect maps the length function -> len; classic translator does not consider that *when nested* // Transact-SQL dialects (except SybaseAnywhereDialect) map the length function -> len;
// classic translator does not consider that *when nested*;
// SybaseAnywhereDialect supports the length function
assertTranslation("from Animal a where abs(abs(a.bodyWeight - 1.0 + :param) * abs(length('ffobar')-3)) = 3.0"); assertTranslation("from Animal a where abs(abs(a.bodyWeight - 1.0 + :param) * abs(length('ffobar')-3)) = 3.0");
} }
if ( !( getDialect() instanceof MySQLDialect || getDialect() instanceof SybaseDialect ) ) { if ( !( getDialect() instanceof MySQLDialect ) && ! ( getDialect() instanceof SybaseDialect ) && ! ( getDialect() instanceof Sybase11Dialect ) && !( getDialect() instanceof SybaseASE15Dialect ) && ! ( getDialect() instanceof SybaseAnywhereDialect ) && ! ( getDialect() instanceof SQLServerDialect ) ) {
assertTranslation("from Animal where lower(upper('foo') || upper(:bar)) like 'f%'"); assertTranslation("from Animal where lower(upper('foo') || upper(:bar)) like 'f%'");
} }
if ( getDialect() instanceof PostgreSQLDialect ) { if ( getDialect() instanceof PostgreSQLDialect ) {
@ -594,7 +601,8 @@ public class HQLTest extends QueryTranslatorTestCase {
} }
public void testConcatenation() { public void testConcatenation() {
if ( getDialect() instanceof MySQLDialect || getDialect() instanceof SybaseDialect ) { if ( getDialect() instanceof MySQLDialect || getDialect() instanceof SybaseDialect || getDialect() instanceof Sybase11Dialect || getDialect() instanceof SybaseASE15Dialect || getDialect() instanceof SybaseAnywhereDialect || getDialect() instanceof SQLServerDialect ) {
// SybaseASE15Dialect and SybaseAnywhereDialect support '||'
// MySQL uses concat(x, y, z) // MySQL uses concat(x, y, z)
// SQL Server replaces '||' with '+' // SQL Server replaces '||' with '+'
// //

View File

@ -46,7 +46,7 @@ public class InterfaceProxyTest extends FunctionalTestCase {
SecureDocument d2 = new SecureDocumentImpl(); SecureDocument d2 = new SecureDocumentImpl();
d2.setName("Secret"); d2.setName("Secret");
d2.setContent( Hibernate.createBlob( "wxyz wxyz".getBytes() ) ); d2.setContent( Hibernate.createBlob( "wxyz wxyz".getBytes() ) );
// Sybase only allows 7-bits in a byte to be inserted into a tinyint // SybaseASE15Dialect only allows 7-bits in a byte to be inserted into a tinyint
// column (0 <= val < 128) // column (0 <= val < 128)
d2.setPermissionBits( (byte) 127 ); d2.setPermissionBits( (byte) 127 );
d2.setOwner("gavin"); d2.setOwner("gavin");

View File

@ -58,6 +58,8 @@ import org.hibernate.dialect.PostgreSQLDialect;
import org.hibernate.dialect.SAPDBDialect; import org.hibernate.dialect.SAPDBDialect;
import org.hibernate.dialect.SQLServerDialect; import org.hibernate.dialect.SQLServerDialect;
import org.hibernate.dialect.SybaseDialect; import org.hibernate.dialect.SybaseDialect;
import org.hibernate.dialect.Sybase11Dialect;
import org.hibernate.dialect.SybaseASE15Dialect;
import org.hibernate.dialect.TimesTenDialect; import org.hibernate.dialect.TimesTenDialect;
import org.hibernate.engine.SessionFactoryImplementor; import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.junit.functional.FunctionalTestClassTestSuite; import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
@ -2136,7 +2138,8 @@ public class FooBarTest extends LegacyTestCase {
s.find("select count(*) from Baz as baz where 1 in indices(baz.fooArray)"); s.find("select count(*) from Baz as baz where 1 in indices(baz.fooArray)");
s.find("select count(*) from Bar as bar where 'abc' in elements(bar.baz.fooArray)"); s.find("select count(*) from Bar as bar where 'abc' in elements(bar.baz.fooArray)");
s.find("select count(*) from Bar as bar where 1 in indices(bar.baz.fooArray)"); s.find("select count(*) from Bar as bar where 1 in indices(bar.baz.fooArray)");
if ( !(getDialect() instanceof DB2Dialect) && !(getDialect() instanceof Oracle9Dialect) && !(getDialect() instanceof Oracle8iDialect ) && !( getDialect() instanceof SybaseDialect && !(getDialect() instanceof SQLServerDialect ) ) ) { if ( !(getDialect() instanceof DB2Dialect) && !(getDialect() instanceof Oracle9Dialect) && !(getDialect() instanceof Oracle8iDialect ) && !( getDialect() instanceof SybaseDialect ) && !( getDialect() instanceof Sybase11Dialect ) && !( getDialect() instanceof SybaseASE15Dialect )) {
// SybaseAnywhereDialect supports implicit conversions from strings to ints
s.find("select count(*) from Bar as bar, bar.component.glarch.proxyArray as g where g.id in indices(bar.baz.fooArray)"); s.find("select count(*) from Bar as bar, bar.component.glarch.proxyArray as g where g.id in indices(bar.baz.fooArray)");
s.find("select max( elements(bar.baz.fooArray) ) from Bar as bar, bar.component.glarch.proxyArray as g where g.id in indices(bar.baz.fooArray)"); s.find("select max( elements(bar.baz.fooArray) ) from Bar as bar, bar.component.glarch.proxyArray as g where g.id in indices(bar.baz.fooArray)");
} }

View File

@ -26,6 +26,9 @@ import org.hibernate.dialect.MySQLDialect;
import org.hibernate.dialect.Oracle9Dialect; import org.hibernate.dialect.Oracle9Dialect;
import org.hibernate.dialect.OracleDialect; import org.hibernate.dialect.OracleDialect;
import org.hibernate.dialect.SybaseDialect; import org.hibernate.dialect.SybaseDialect;
import org.hibernate.dialect.Sybase11Dialect;
import org.hibernate.dialect.SybaseASE15Dialect;
import org.hibernate.dialect.SybaseAnywhereDialect;
import org.hibernate.dialect.TimesTenDialect; import org.hibernate.dialect.TimesTenDialect;
import org.hibernate.dialect.SQLServerDialect; import org.hibernate.dialect.SQLServerDialect;
import org.hibernate.dialect.function.SQLFunction; import org.hibernate.dialect.function.SQLFunction;
@ -370,7 +373,7 @@ public class SQLFunctionsTest extends LegacyTestCase {
s.find("from Simple s where not( upper( s.name ) ='yada' or 1=2 or 'foo'='bar' or not('foo'='foo') or 'foo' like 'bar' )").size()==1 s.find("from Simple s where not( upper( s.name ) ='yada' or 1=2 or 'foo'='bar' or not('foo'='foo') or 'foo' like 'bar' )").size()==1
); );
} }
if ( !(getDialect() instanceof MySQLDialect) && !(getDialect() instanceof SybaseDialect) && !(getDialect() instanceof MckoiDialect) && !(getDialect() instanceof InterbaseDialect) && !(getDialect() instanceof TimesTenDialect) ) { //My SQL has a funny concatenation operator if ( !(getDialect() instanceof MySQLDialect) && !(getDialect() instanceof SybaseDialect) && !(getDialect() instanceof SQLServerDialect) && !(getDialect() instanceof MckoiDialect) && !(getDialect() instanceof InterbaseDialect) && !(getDialect() instanceof TimesTenDialect) ) { //My SQL has a funny concatenation operator
assertTrue( assertTrue(
s.find("from Simple s where lower( s.name || ' foo' ) ='simple 1 foo'").size()==1 s.find("from Simple s where lower( s.name || ' foo' ) ='simple 1 foo'").size()==1
); );
@ -500,8 +503,8 @@ public class SQLFunctionsTest extends LegacyTestCase {
//assertTrue( b.getClob() instanceof ClobImpl ); //assertTrue( b.getClob() instanceof ClobImpl );
s.flush(); s.flush();
// Sybase ASE does not support ResultSet.getBlob(String) // Sybase does not support ResultSet.getBlob(String)
if ( getDialect() instanceof SybaseDialect && ! ( getDialect() instanceof SQLServerDialect ) ) { if ( getDialect() instanceof SybaseDialect || getDialect() instanceof Sybase11Dialect || getDialect() instanceof SybaseASE15Dialect || getDialect() instanceof SybaseAnywhereDialect ) {
s.connection().rollback(); s.connection().rollback();
s.close(); s.close();
return; return;

View File

@ -6,7 +6,9 @@ import junit.framework.Test;
import org.hibernate.Session; import org.hibernate.Session;
import org.hibernate.dialect.Dialect; import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.SybaseDialect; import org.hibernate.dialect.SybaseDialect;
import org.hibernate.dialect.SQLServerDialect; import org.hibernate.dialect.Sybase11Dialect;
import org.hibernate.dialect.SybaseASE15Dialect;
import org.hibernate.dialect.SybaseAnywhereDialect;
import org.hibernate.junit.functional.FunctionalTestCase; import org.hibernate.junit.functional.FunctionalTestCase;
import org.hibernate.junit.functional.FunctionalTestClassTestSuite; import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
@ -35,8 +37,8 @@ public class SerializableTypeTest extends FunctionalTestCase {
} }
public void testNewSerializableType() { public void testNewSerializableType() {
// Sybase ASE does not support ResultSet.getBlob(String) // Sybase dialects do not support ResultSet.getBlob(String)
if ( getDialect() instanceof SybaseDialect && ! ( getDialect() instanceof SQLServerDialect ) ) { if ( getDialect() instanceof SybaseDialect || getDialect() instanceof Sybase11Dialect || getDialect() instanceof SybaseASE15Dialect || getDialect() instanceof SybaseAnywhereDialect ) {
return; return;
} }

View File

@ -46,7 +46,7 @@ public class MixedTest extends FunctionalTestCase {
SecureDocument d2 = new SecureDocument(); SecureDocument d2 = new SecureDocument();
d2.setName( "Secret" ); d2.setName( "Secret" );
d2.setContent( Hibernate.createBlob( "wxyz wxyz".getBytes() ) ); d2.setContent( Hibernate.createBlob( "wxyz wxyz".getBytes() ) );
// Sybase only allows 7-bits in a byte to be inserted into a tinyint // SybaseASE15Dialect only allows 7-bits in a byte to be inserted into a tinyint
// column (0 <= val < 128) // column (0 <= val < 128)
d2.setPermissionBits( (byte) 127 ); d2.setPermissionBits( (byte) 127 );
d2.setOwner( "gavin" ); d2.setOwner( "gavin" );
@ -96,7 +96,7 @@ public class MixedTest extends FunctionalTestCase {
assertNotNull( d2.getContent() ); assertNotNull( d2.getContent() );
assertEquals( "max", d2.getOwner() ); assertEquals( "max", d2.getOwner() );
assertEquals( "/", d2.getParent().getName() ); assertEquals( "/", d2.getParent().getName() );
// Sybase only allows 7-bits in a byte to be inserted into a tinyint // SybaseASE15Dialect only allows 7-bits in a byte to be inserted into a tinyint
// column (0 <= val < 128) // column (0 <= val < 128)
assertEquals( (byte) 127, d2.getPermissionBits() ); assertEquals( (byte) 127, d2.getPermissionBits() );
assertNotNull( d2.getCreated() ); assertNotNull( d2.getCreated() );

View File

@ -165,7 +165,7 @@ public class StatsTest extends FunctionalTestCase {
// same deal with scroll()... // same deal with scroll()...
assertEquals( "unexpected execution count", 3, continentStats.getExecutionCount() ); assertEquals( "unexpected execution count", 3, continentStats.getExecutionCount() );
assertEquals( "unexpected row count", results, continentStats.getExecutionRowCount() ); assertEquals( "unexpected row count", results, continentStats.getExecutionRowCount() );
// scroll through data because Sybase throws NullPointerException // scroll through data because SybaseASE15Dialect throws NullPointerException
// if data is not read before closing the ResultSet // if data is not read before closing the ResultSet
while ( scrollableResults.next() ) { while ( scrollableResults.next() ) {
// do nothing // do nothing