mirror of
https://github.com/querydsl/querydsl.git
synced 2026-06-16 21:01:10 +08:00
Fix TeradataSuite issues #585
This commit is contained in:
parent
0b1a2608cc
commit
aeb740feaf
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright 2011, Mysema Ltd
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@ -23,6 +23,7 @@ import java.util.List;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.Session;
|
||||
import org.junit.After;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.MethodRule;
|
||||
@ -44,23 +45,31 @@ import com.mysema.testutil.HibernateTestRunner;
|
||||
*/
|
||||
@RunWith(HibernateTestRunner.class)
|
||||
public class HibernateBase extends AbstractJPATest {
|
||||
|
||||
|
||||
private static final QCat cat = QCat.cat;
|
||||
|
||||
|
||||
@Rule
|
||||
public static MethodRule jpaProviderRule = new JPAProviderRule();
|
||||
|
||||
|
||||
@Rule
|
||||
public static MethodRule targetRule = new TargetRule();
|
||||
|
||||
|
||||
private Session session;
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
session.flush();
|
||||
session.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HibernateQuery query() {
|
||||
return new HibernateQuery(session, getTemplates());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected HibernateQuery testQuery() {
|
||||
return new HibernateQuery(new DefaultSessionHolder(session),
|
||||
return new HibernateQuery(new DefaultSessionHolder(session),
|
||||
getTemplates(), new DefaultQueryMetadata().noValidate());
|
||||
}
|
||||
|
||||
@ -84,7 +93,7 @@ public class HibernateBase extends AbstractJPATest {
|
||||
assertNotNull(results);
|
||||
assertFalse(results.isEmpty());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void WithComment() {
|
||||
query().from(cat).setComment("my comment").list(cat);
|
||||
@ -94,7 +103,7 @@ public class HibernateBase extends AbstractJPATest {
|
||||
public void LockMode() {
|
||||
query().from(cat).setLockMode(cat, LockMode.PESSIMISTIC_WRITE).list(cat);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void FlushMode() {
|
||||
query().from(cat).setFlushMode(org.hibernate.FlushMode.AUTO).list(cat);
|
||||
@ -125,6 +134,6 @@ public class HibernateBase extends AbstractJPATest {
|
||||
}
|
||||
rows.close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -27,6 +27,7 @@ import javax.persistence.EntityManager;
|
||||
import javax.persistence.FlushModeType;
|
||||
import javax.persistence.LockModeType;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
@ -64,6 +65,12 @@ public class JPABase extends AbstractJPATest {
|
||||
|
||||
private EntityManager entityManager;
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
entityManager.flush();
|
||||
entityManager.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JPAQuery query() {
|
||||
return new JPAQuery(entityManager);
|
||||
|
||||
@ -18,6 +18,7 @@ import java.util.Map;
|
||||
import javax.persistence.ElementCollection;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.MapKeyColumn;
|
||||
import javax.persistence.Table;
|
||||
|
||||
/**
|
||||
@ -31,6 +32,7 @@ public class Show {
|
||||
long id;
|
||||
|
||||
@ElementCollection
|
||||
@MapKeyColumn(name="acts_key")
|
||||
public Map<String, String> acts;
|
||||
|
||||
public Show() {}
|
||||
|
||||
@ -0,0 +1,424 @@
|
||||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2008, 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 com.mysema.query.jpa.support;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.sql.Types;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.dialect.function.SQLFunctionTemplate;
|
||||
import org.hibernate.dialect.function.VarArgsSQLFunction;
|
||||
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtracter;
|
||||
import org.hibernate.exception.spi.ViolatedConstraintNameExtracter;
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
|
||||
/**
|
||||
* A dialect for the Teradata database created by MCR as part of the dialect
|
||||
* certification process.
|
||||
*
|
||||
* @author Jay Nance
|
||||
*/
|
||||
public class TeradataDialect extends Dialect {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public TeradataDialect() {
|
||||
super();
|
||||
// registerColumnType data types
|
||||
registerColumnType(Types.NUMERIC, "NUMERIC($p,$s)");
|
||||
registerColumnType(Types.DOUBLE, "DOUBLE PRECISION");
|
||||
registerColumnType(Types.BIGINT, "NUMERIC(18,0)");
|
||||
registerColumnType(Types.BIT, "BYTEINT");
|
||||
registerColumnType(Types.TINYINT, "BYTEINT");
|
||||
registerColumnType(Types.VARBINARY, "VARBYTE($l)");
|
||||
registerColumnType(Types.BINARY, "BYTEINT");
|
||||
registerColumnType(Types.LONGVARCHAR, "LONG VARCHAR");
|
||||
registerColumnType(Types.CHAR, "CHAR(1)");
|
||||
registerColumnType(Types.DECIMAL, "DECIMAL");
|
||||
registerColumnType(Types.INTEGER, "INTEGER");
|
||||
registerColumnType(Types.SMALLINT, "SMALLINT");
|
||||
registerColumnType(Types.FLOAT, "FLOAT");
|
||||
registerColumnType(Types.VARCHAR, "VARCHAR($l)");
|
||||
registerColumnType(Types.DATE, "DATE");
|
||||
registerColumnType(Types.TIME, "TIME");
|
||||
registerColumnType(Types.TIMESTAMP, "TIMESTAMP");
|
||||
registerColumnType(Types.BOOLEAN, "BYTEINT"); // hibernate seems to
|
||||
// ignore this type...
|
||||
registerColumnType(Types.BLOB, "BLOB");
|
||||
registerColumnType(Types.CLOB, "CLOB");
|
||||
|
||||
registerFunction("year", new SQLFunctionTemplate(StandardBasicTypes.INTEGER,
|
||||
"extract(year from ?1)"));
|
||||
registerFunction("length", new SQLFunctionTemplate(StandardBasicTypes.INTEGER,
|
||||
"character_length(?1)"));
|
||||
registerFunction("concat",
|
||||
new VarArgsSQLFunction(StandardBasicTypes.STRING, "(", "||", ")"));
|
||||
registerFunction("substring", new SQLFunctionTemplate(StandardBasicTypes.STRING,
|
||||
"substring(?1 from ?2 for ?3)"));
|
||||
registerFunction("locate", new SQLFunctionTemplate(StandardBasicTypes.STRING,
|
||||
"position(?1 in ?2)"));
|
||||
registerFunction("mod", new SQLFunctionTemplate(StandardBasicTypes.STRING, "?1 mod ?2"));
|
||||
registerFunction("str", new SQLFunctionTemplate(StandardBasicTypes.STRING,
|
||||
"cast(?1 as varchar(255))"));
|
||||
|
||||
// bit_length feels a bit broken to me. We have to cast to char in order
|
||||
// to
|
||||
// pass when a numeric value is supplied. But of course the answers
|
||||
// given will
|
||||
// be wildly different for these two datatypes. 1234.5678 will be 9
|
||||
// bytes as
|
||||
// a char string but will be 8 or 16 bytes as a true numeric.
|
||||
// Jay Nance 2006-09-22
|
||||
registerFunction("bit_length", new SQLFunctionTemplate(StandardBasicTypes.INTEGER,
|
||||
"octet_length(cast(?1 as char))*4"));
|
||||
|
||||
// The preference here would be
|
||||
// SQLFunctionTemplate( Hibernate.TIMESTAMP, "current_timestamp(?1)",
|
||||
// false)
|
||||
// but this appears not to work.
|
||||
// Jay Nance 2006-09-22
|
||||
registerFunction("current_timestamp", new SQLFunctionTemplate(StandardBasicTypes.TIMESTAMP,
|
||||
"current_timestamp"));
|
||||
registerFunction("current_time", new SQLFunctionTemplate(StandardBasicTypes.TIME,
|
||||
"current_time"));
|
||||
registerFunction("current_date", new SQLFunctionTemplate(StandardBasicTypes.DATE,
|
||||
"current_date"));
|
||||
// IBID for current_time and current_date
|
||||
|
||||
registerKeyword("account");
|
||||
registerKeyword("alias");
|
||||
registerKeyword("class");
|
||||
registerKeyword("column");
|
||||
registerKeyword("first");
|
||||
registerKeyword("map");
|
||||
registerKeyword("month");
|
||||
registerKeyword("password");
|
||||
registerKeyword("role");
|
||||
registerKeyword("summary");
|
||||
registerKeyword("title");
|
||||
registerKeyword("type");
|
||||
registerKeyword("value");
|
||||
registerKeyword("year");
|
||||
|
||||
// Tell hibernate to use getBytes instead of getBinaryStream
|
||||
getDefaultProperties().setProperty(Environment.USE_STREAMS_FOR_BINARY, "false");
|
||||
// No batch statements
|
||||
getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, NO_BATCH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this dialect support the <tt>FOR UPDATE</tt> syntax?
|
||||
*
|
||||
* @return empty string ... Teradata does not support
|
||||
* <tt>FOR UPDATE<tt> syntax
|
||||
*/
|
||||
@Override
|
||||
public String getForUpdateString() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsIdentityColumns() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsSequences() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAddColumnString() {
|
||||
return "Add";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTemporaryTables() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCreateTemporaryTableString() {
|
||||
return "create global temporary table";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCreateTemporaryTablePostfix() {
|
||||
return " on commit preserve rows";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean performTemporaryTableDDLInIsolation() {
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dropTemporaryTableAfterUse() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the database type associated with the given
|
||||
* <tt>java.sql.Types</tt> typecode.
|
||||
*
|
||||
* @param code
|
||||
* <tt>java.sql.Types</tt> typecode
|
||||
* @param length
|
||||
* the length or precision of the column
|
||||
* @param precision
|
||||
* the precision of the column
|
||||
* @param scale
|
||||
* the scale of the column
|
||||
*
|
||||
* @return the database type name
|
||||
*
|
||||
* @throws HibernateException
|
||||
*/
|
||||
public String getTypeName(int code, int length, int precision, int scale)
|
||||
throws HibernateException {
|
||||
/*
|
||||
* We might want a special case for 19,2. This is very common for money
|
||||
* types and here it is converted to 18,1
|
||||
*/
|
||||
float f = precision > 0 ? (float) scale / (float) precision : 0;
|
||||
int p = (precision > 18 ? 18 : precision);
|
||||
int s = (precision > 18 ? (int) (18.0 * f) : (scale > 18 ? 18 : scale));
|
||||
|
||||
return super.getTypeName(code, length, p, s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsCascadeDelete() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsCircularCascadeDeleteConstraints() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areStringComparisonsCaseInsensitive() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsEmptyInList() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSelectClauseNullString(int sqlType) {
|
||||
String v = "null";
|
||||
|
||||
switch (sqlType) {
|
||||
case Types.BIT:
|
||||
case Types.TINYINT:
|
||||
case Types.SMALLINT:
|
||||
case Types.INTEGER:
|
||||
case Types.BIGINT:
|
||||
case Types.FLOAT:
|
||||
case Types.REAL:
|
||||
case Types.DOUBLE:
|
||||
case Types.NUMERIC:
|
||||
case Types.DECIMAL:
|
||||
v = "cast(null as decimal)";
|
||||
break;
|
||||
case Types.CHAR:
|
||||
case Types.VARCHAR:
|
||||
case Types.LONGVARCHAR:
|
||||
v = "cast(null as varchar(255))";
|
||||
break;
|
||||
case Types.DATE:
|
||||
case Types.TIME:
|
||||
case Types.TIMESTAMP:
|
||||
v = "cast(null as timestamp)";
|
||||
break;
|
||||
case Types.BINARY:
|
||||
case Types.VARBINARY:
|
||||
case Types.LONGVARBINARY:
|
||||
case Types.NULL:
|
||||
case Types.OTHER:
|
||||
case Types.JAVA_OBJECT:
|
||||
case Types.DISTINCT:
|
||||
case Types.STRUCT:
|
||||
case Types.ARRAY:
|
||||
case Types.BLOB:
|
||||
case Types.CLOB:
|
||||
case Types.REF:
|
||||
case Types.DATALINK:
|
||||
case Types.BOOLEAN:
|
||||
break;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCreateMultisetTableString() {
|
||||
return "create multiset table ";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsLobValueChangePropogation() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doesReadCommittedCauseWritersToBlockReaders() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doesRepeatableReadCauseReadersToBlockWriters() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsBindAsCallableArgument() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
|
||||
return EXTRACTER;
|
||||
}
|
||||
|
||||
private static ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() {
|
||||
|
||||
/**
|
||||
* Extract the name of the violated constraint from the given
|
||||
* SQLException.
|
||||
*
|
||||
* @param sqle
|
||||
* The exception that was the result of the constraint
|
||||
* violation.
|
||||
* @return The extracted constraint name.
|
||||
*/
|
||||
@Override
|
||||
public String extractConstraintName(SQLException sqle) {
|
||||
String constraintName = null;
|
||||
|
||||
int errorCode = sqle.getErrorCode();
|
||||
if (errorCode == 27003) {
|
||||
constraintName = extractUsingTemplate("Unique constraint (", ") violated.",
|
||||
sqle.getMessage());
|
||||
}
|
||||
|
||||
if (constraintName != null) {
|
||||
int i = constraintName.indexOf('.');
|
||||
if (i != -1) {
|
||||
constraintName = constraintName.substring(i + 1);
|
||||
}
|
||||
}
|
||||
return constraintName;
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public boolean supportsNotNullUnique() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsExpectedLobUsagePattern() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsUnboundedLobLocatorMaterialization() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsDropPreProcess() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String performDropPreProcess(Statement stmt, String dropSql) throws SQLException {
|
||||
|
||||
String alterStr = "alter";
|
||||
String tableStr = "table";
|
||||
String dropStr = "drop";
|
||||
String constraintStr = "constraint";
|
||||
|
||||
java.util.StringTokenizer st = new java.util.StringTokenizer(dropSql);
|
||||
if (alterStr.equalsIgnoreCase(st.nextToken()) && tableStr.equalsIgnoreCase(st.nextToken())) {
|
||||
String tableName = st.nextToken();
|
||||
|
||||
if ((tableName.startsWith("\"")) && (!tableName.endsWith("\""))) {
|
||||
String next = null;
|
||||
while (true) {
|
||||
next = st.nextToken();
|
||||
tableName += " " + next;
|
||||
if (next.endsWith("\\\"")) {
|
||||
continue;
|
||||
}
|
||||
if (next.endsWith("\"")) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (dropStr.equalsIgnoreCase(st.nextToken())
|
||||
&& constraintStr.equalsIgnoreCase(st.nextToken())) {
|
||||
String constraintName = st.nextToken();
|
||||
|
||||
// Table name might have whitespace characters within name so
|
||||
// just take whatever lies between
|
||||
// "alter table " and "drop constraint"
|
||||
|
||||
int idx_start = dropSql.indexOf(tableStr, 0) + 5;
|
||||
int idx_end = dropSql.lastIndexOf(dropStr);
|
||||
tableName = dropSql.substring(idx_start, idx_end).trim();
|
||||
|
||||
if (tableName.startsWith("\"") && tableName.endsWith("\"")) {
|
||||
tableName = tableName.substring(1, tableName.length() - 1);
|
||||
}
|
||||
|
||||
String arrStr = null;
|
||||
String queryStr = "sel IndexId, ChildTable, IndexName from dbc.RI_Distinct_ChildrenV where IndexName = '"
|
||||
+ constraintName + "'";
|
||||
java.sql.ResultSet rs = stmt.executeQuery(queryStr);
|
||||
|
||||
if (rs.next()) {
|
||||
arrStr = "drop table \"" + tableName + "_" + rs.getString(1) + "\"";
|
||||
rs.close();
|
||||
return arrStr;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void performDropPostProcess(Statement stmt, String dropSql) throws SQLException {
|
||||
if (dropSql == null) {
|
||||
return;
|
||||
}
|
||||
stmt.executeUpdate(dropSql);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
package com.mysema.query.suites;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.Persistence;
|
||||
|
||||
public class Teradata {
|
||||
|
||||
public static void main(String[] args) {
|
||||
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("teradata");
|
||||
try {
|
||||
EntityManager entityManager = entityManagerFactory.createEntityManager();
|
||||
try {
|
||||
entityManager.getTransaction().begin();
|
||||
entityManager.getTransaction().commit();
|
||||
} finally {
|
||||
entityManager.close();
|
||||
}
|
||||
} finally {
|
||||
entityManagerFactory.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -277,7 +277,7 @@
|
||||
<provider>org.hibernate.ejb.HibernatePersistence</provider>
|
||||
<properties>
|
||||
<property name="hibernate.archive.autodetection" value="class" />
|
||||
<property name="hibernate.dialect" value="org.hibernate.dialect.TeradataDialect" />
|
||||
<property name="hibernate.dialect" value="com.mysema.query.jpa.support.TeradataDialect" />
|
||||
<property name="hibernate.connection.driver_class" value="com.teradata.jdbc.TeraDriver" />
|
||||
<property name="hibernate.connection.url" value="jdbc:teradata://teradata/dbc" />
|
||||
<property name="hibernate.connection.username" value="querydsl" />
|
||||
@ -285,6 +285,7 @@
|
||||
<!-- <property name="hibernate.show_sql" value="true"/> -->
|
||||
<property name="hibernate.flushMode" value="FLUSH_AUTO" />
|
||||
<property name="hibernate.hbm2ddl.auto" value="update" />
|
||||
<property name="hibernate.globally_quoted_identifiers" value="true" />
|
||||
</properties>
|
||||
</persistence-unit>
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
hibernate.dialect=org.hibernate.dialect.TeradataDialect
|
||||
hibernate.dialect=com.mysema.query.jpa.support.TeradataDialect
|
||||
hibernate.connection.driver_class=com.teradata.jdbc.TeraDriver
|
||||
hibernate.connection.url=jdbc:teradata://teradata/dbc
|
||||
hibernate.connection.username=querydsl
|
||||
@ -6,4 +6,5 @@ hibernate.connection.password=querydsl
|
||||
|
||||
#hibernate.show_sql=true
|
||||
hibernate.flushMode=FLUSH_AUTO
|
||||
hibernate.hbm2ddl.auto=update
|
||||
hibernate.hbm2ddl.auto=update
|
||||
hibernate.globally_quoted_identifiers=true
|
||||
Loading…
Reference in New Issue
Block a user