mirror of https://github.com/apache/openjpa.git
OPENJPA-983: FirebirdDictionary improvements
git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@763992 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
20b3559bbe
commit
62aabafc53
|
@ -18,44 +18,460 @@
|
|||
*/
|
||||
package org.apache.openjpa.jdbc.sql;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.openjpa.jdbc.kernel.exps.FilterValue;
|
||||
import org.apache.openjpa.jdbc.schema.Column;
|
||||
import org.apache.openjpa.jdbc.schema.ForeignKey;
|
||||
import org.apache.openjpa.jdbc.schema.Index;
|
||||
import org.apache.openjpa.jdbc.schema.Sequence;
|
||||
import org.apache.openjpa.jdbc.schema.Unique;
|
||||
import org.apache.openjpa.lib.util.Localizer;
|
||||
import org.apache.openjpa.util.UnsupportedException;
|
||||
|
||||
/**
|
||||
* Dictionary for Firebird.
|
||||
* Dictionary for Firebird. Supports Firebird versions 1.5, 2.0 and 2.1.
|
||||
*/
|
||||
public class FirebirdDictionary
|
||||
extends InterbaseDictionary {
|
||||
extends DBDictionary {
|
||||
|
||||
public int firebirdVersion = 0;
|
||||
public int indexedVarcharMaxSizeFB15 = 252;
|
||||
public String rangeSyntax = null;
|
||||
protected long maxRowNumberInRange = 16000000000L;
|
||||
|
||||
protected String alterSequenceSQLFB15 = "SET GENERATOR {0} TO {1}";
|
||||
protected String alterSequenceSQLFB20 =
|
||||
"ALTER SEQUENCE {0} RESTART WITH {1}";
|
||||
protected String createSequenceSQLFB15 = "CREATE GENERATOR {0}";
|
||||
protected String createSequenceSQLFB20 = "CREATE SEQUENCE {0}";
|
||||
protected String dropSequenceSQLFB15 = "DROP GENERATOR ";
|
||||
protected String nextSequenceQueryFB15 =
|
||||
"SELECT GEN_ID({0}, 1) FROM RDB$DATABASE";
|
||||
protected String nextSequenceQueryFB20 =
|
||||
"SELECT NEXT VALUE FOR {0} FROM RDB$DATABASE";
|
||||
|
||||
protected String alterSequenceSQL = alterSequenceSQLFB20;
|
||||
protected String createSequenceSQL = createSequenceSQLFB20;
|
||||
|
||||
public static final int FB_VERSION_15 = 15;
|
||||
public static final int FB_VERSION_20 = 20;
|
||||
public static final int FB_VERSION_21 = 21;
|
||||
|
||||
public static final String RANGE_SYNTAX_FIRST_SKIP = "firstskip";
|
||||
public static final String RANGE_SYNTAX_ROWS = "rows";
|
||||
|
||||
private static final Localizer _loc =
|
||||
Localizer.forPackage(FirebirdDictionary.class);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public FirebirdDictionary() {
|
||||
platform = "Firebird";
|
||||
validationSQL = "SELECT 1 FROM RDB$DATABASE";
|
||||
supportsDeferredConstraints = false;
|
||||
|
||||
// Firebird 1.5+ locking statement
|
||||
useGetStringForClobs = true;
|
||||
useSetStringForClobs = true;
|
||||
useGetBytesForBlobs = true;
|
||||
useSetBytesForBlobs = true;
|
||||
|
||||
maxTableNameLength = 31;
|
||||
maxColumnNameLength = 31;
|
||||
maxConstraintNameLength = 31;
|
||||
maxIndexNameLength = 31;
|
||||
|
||||
supportsSelectStartIndex = true;
|
||||
supportsSelectEndIndex = true;
|
||||
|
||||
supportsMultipleNontransactionalResultSets = false;
|
||||
|
||||
nextSequenceQuery = nextSequenceQueryFB20;
|
||||
sequenceSQL =
|
||||
"SELECT NULL AS SEQUENCE_SCHEMA, RDB$GENERATOR_NAME "
|
||||
+ "AS SEQUENCE_NAME FROM RDB$GENERATORS "
|
||||
+ "WHERE (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG = 0) ";
|
||||
sequenceNameSQL = "AND RDB$GENERATOR_NAME = ?";
|
||||
|
||||
// A rough sum of reserved words in Firebird 1.0 - 2.1.
|
||||
reservedWordSet.addAll(Arrays.asList(new String[] { "ACTIVE", "ADMIN",
|
||||
"AFTER", "ASCENDING", "AUTO", "AUTODDL", "BASED", "BASENAME",
|
||||
"BASE_NAME", "BEFORE", "BIGINT", "BLOB", "BLOBEDIT", "BUFFER",
|
||||
"CACHE", "CHECK_POINT_LEN", "CHECK_POINT_LENGTH", "COMPILETIME",
|
||||
"COMPUTED", "CLOSE", "CONDITIONAL", "CONTAINING", "CSTRING",
|
||||
"CURRENT_CONNECTION", "CURRENT_ROLE", "CURRENT_TRANSACTION",
|
||||
"DATABASE", "DB_KEY", "DEBUG", "DESCENDING", "DO", "ECHO", "EDIT",
|
||||
"ENTRY_POINT", "EVENT", "EXIT", "EXTERN", "FILE", "FILTER",
|
||||
"FREE_IT", "FUNCTION", "GDSCODE", "GENERATOR", "GEN_ID", "GLOBAL",
|
||||
"GOTO", "GROUP_COMMIT_WAIT", "GROUP_COMMIT_WAIT_TIME", "HELP",
|
||||
"IF", "INACTIVE", "INDEX", "INIT", "INPUT_TYPE", "ISQL",
|
||||
"LC_MESSAGES", "LC_TYPE", "LEV", "LOGFILE", "LOG_BUFFER_SIZE",
|
||||
"LOG_BUF_SIZE", "LONG", "MANUAL", "MAXIMUM", "MAXIMUM_SEGMENT",
|
||||
"MAX_SEGMENT", "MERGE", "MESSAGE", "MINUTE", "MODULE_NAME",
|
||||
"NOAUTO", "NUM_LOG_BUFS", "NUM_LOG_BUFFERS", "OUTPUT_TYPE",
|
||||
"OVERFLOW", "PAGE", "PAGELENGTH", "PAGES", "PAGE_SIZE",
|
||||
"PARAMETER", "PASSWORD", "PLAN", "POST_EVENT", "PROCEDURE",
|
||||
"PROTECTED", "QUIT", "RAW_PARTITIONS", "RDB$DB_KEY",
|
||||
"RECORD_VERSION", "RECREATE", "RELEASE", "RESERV", "RESERVING",
|
||||
"RETAIN", "RETURN", "RETURNING_VALUES", "RETURNS", "ROLE",
|
||||
"RUNTIME", "SAVEPOINT", "SEGMENT", "SHADOW", "SHARED", "SHELL",
|
||||
"SHOW", "SINGULAR", "SNAPSHOT", "SORT", "SQLWARNING", "STABILITY",
|
||||
"START", "STARTING", "STARTS", "STATEMENT", "STATIC", "STATISTICS",
|
||||
"SUB_TYPE", "SUSPEND", "TERMINATOR", "TRIGGER", "VARIABLE",
|
||||
"VERSION", "WAIT", "WEEKDAY", "WHILE" }));
|
||||
|
||||
binaryTypeName = "BLOB";
|
||||
bitTypeName = "SMALLINT";
|
||||
charTypeName = "CHAR(1)";
|
||||
clobTypeName = "BLOB SUB_TYPE 1";
|
||||
doubleTypeName = "DOUBLE PRECISION";
|
||||
floatTypeName = "DOUBLE PRECISION";
|
||||
longVarbinaryTypeName = "BLOB";
|
||||
longVarcharTypeName = "BLOB SUB_TYPE 1";
|
||||
realTypeName = "FLOAT";
|
||||
smallintTypeName = "SMALLINT";
|
||||
tinyintTypeName = "SMALLINT";
|
||||
varbinaryTypeName = "BLOB";
|
||||
|
||||
supportsLockingWithDistinctClause = false;
|
||||
supportsLockingWithMultipleTables = false;
|
||||
supportsLockingWithOuterJoin = false;
|
||||
supportsLockingWithInnerJoin = false;
|
||||
forUpdateClause = "FOR UPDATE WITH LOCK";
|
||||
supportsQueryTimeout = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine Firebird version and configure itself accordingly.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void connectedConfiguration(Connection conn) throws SQLException {
|
||||
super.connectedConfiguration(conn);
|
||||
firebirdVersion = determineFirebirdVersion(conn);
|
||||
determineRangeSyntax();
|
||||
|
||||
if (firebirdVersion == FB_VERSION_21)
|
||||
selectWordSet.add("WITH");
|
||||
if (!(firebirdVersion == FB_VERSION_21)) {
|
||||
crossJoinClause = "JOIN";
|
||||
requiresConditionForCrossJoin = true;
|
||||
}
|
||||
if (firebirdVersion == FB_VERSION_15) {
|
||||
stringLengthFunction = "STRLEN({0})";
|
||||
trimLeadingFunction = "LTRIM({0})";
|
||||
trimTrailingFunction = "RTRIM({0})";
|
||||
trimBothFunction = "LTRIM(RTRIM({0}))";
|
||||
alterSequenceSQL = alterSequenceSQLFB15;
|
||||
createSequenceSQL = createSequenceSQLFB15;
|
||||
nextSequenceQuery = nextSequenceQueryFB15;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Use either <code>FIRST <p> SKIP <q></code> or
|
||||
* <code>ROWS <m> TO <n></code> syntax. If <code>ROWS</code>
|
||||
* variant is used and <code>end</code> equals {@link Long#MAX_VALUE}, a
|
||||
* constant is used as <code><n></code> value.
|
||||
*/
|
||||
@Override
|
||||
protected void appendSelectRange(SQLBuffer buf, long start, long end,
|
||||
boolean subselect) {
|
||||
if (RANGE_SYNTAX_FIRST_SKIP.equals(rangeSyntax)) {
|
||||
if (end != Long.MAX_VALUE)
|
||||
buf.append(" FIRST ").appendValue(end - start);
|
||||
if (start != 0)
|
||||
buf.append(" SKIP ").appendValue(start);
|
||||
return;
|
||||
}
|
||||
|
||||
buf.append(" ROWS ");
|
||||
if (start == 0) {
|
||||
buf.appendValue(end);
|
||||
return;
|
||||
}
|
||||
|
||||
buf.appendValue(start + 1).append(" TO ");
|
||||
if (end == Long.MAX_VALUE)
|
||||
buf.appendValue(maxRowNumberInRange);
|
||||
else
|
||||
buf.appendValue(end);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine Firebird version either by using JDBC 3 methods or, if they
|
||||
* are not available, by parsing the value returned by
|
||||
* {@linkplain DatabaseMetaData#getDatabaseProductVersion()}. User can
|
||||
* override Firebird version.
|
||||
*/
|
||||
protected int determineFirebirdVersion(Connection con)
|
||||
throws SQLException {
|
||||
// Let user override firebirdVersion.
|
||||
if (firebirdVersion != 0)
|
||||
return firebirdVersion;
|
||||
|
||||
DatabaseMetaData metaData = con.getMetaData();
|
||||
int maj = 0;
|
||||
int min = 0;
|
||||
if (isJDBC3) {
|
||||
maj = metaData.getDatabaseMajorVersion();
|
||||
min = metaData.getDatabaseMinorVersion();
|
||||
} else {
|
||||
try {
|
||||
// The product version looks like
|
||||
// "LI-V2.1.1.17910 Firebird 2.1,LI-V2.1.1.17910 Firebird
|
||||
// 2.1/tcp (hostname)/P10" or
|
||||
// "WI-V1.5.5.4926 Firebird 1.52WI-V1.5.5.4926 Firebird 1.5/tcp
|
||||
// (hostname)/P10"
|
||||
String productVersion = metaData.getDatabaseProductVersion();
|
||||
Pattern p = Pattern.compile(".*-V(\\d)\\.(\\d)\\..*",
|
||||
Pattern.CASE_INSENSITIVE);
|
||||
Matcher m = p.matcher(productVersion);
|
||||
m.matches();
|
||||
String majString = m.group(1);
|
||||
String minString = m.group(2);
|
||||
maj = Integer.parseInt(majString);
|
||||
min = Integer.parseInt(minString);
|
||||
} catch (Exception e) {
|
||||
// We don't understand the version format.
|
||||
if (log.isWarnEnabled())
|
||||
log.warn(e.toString(), e);
|
||||
}
|
||||
}
|
||||
if (maj < 2)
|
||||
return FB_VERSION_15;
|
||||
if (maj == 2 && min == 0)
|
||||
return FB_VERSION_20;
|
||||
return FB_VERSION_21;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine range syntax to be used depending on Firebird version.
|
||||
* User can override range syntax.
|
||||
*/
|
||||
protected void determineRangeSyntax() {
|
||||
// Let user override rangeSyntax.
|
||||
if (rangeSyntax == null)
|
||||
rangeSyntax =
|
||||
(firebirdVersion == FB_VERSION_15) ? RANGE_SYNTAX_FIRST_SKIP
|
||||
: RANGE_SYNTAX_ROWS;
|
||||
|
||||
if (RANGE_SYNTAX_FIRST_SKIP.equals(rangeSyntax))
|
||||
rangePosition = RANGE_PRE_DISTINCT;
|
||||
else
|
||||
rangePosition = RANGE_POST_SELECT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return <code><value> AS <type></code>.
|
||||
*/
|
||||
@Override
|
||||
public String getPlaceholderValueString(Column col) {
|
||||
return super.getPlaceholderValueString(col)
|
||||
+ " AS " + getTypeName(col);
|
||||
return super.getPlaceholderValueString(col) + " AS "
|
||||
+ getTypeName(col);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return <code>%</code> if <code>tableName</code> is <code>null</code>,
|
||||
* otherwise delegate to super implementation.
|
||||
*/
|
||||
@Override
|
||||
protected String getTableNameForMetadata(String tableName) {
|
||||
return (tableName == null) ? "%" : super
|
||||
.getTableNameForMetadata(tableName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return <code>%</code> if <code>columnName</code> is <code>null</code>,
|
||||
* otherwise delegate to super implementation.
|
||||
*/
|
||||
@Override
|
||||
protected String getColumnNameForMetadata(String columnName) {
|
||||
return (columnName == null) ? "%" : super
|
||||
.getColumnNameForMetadata(columnName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return
|
||||
* <code>ALTER TABLE <table name> DROP <col name></code>.
|
||||
*/
|
||||
@Override
|
||||
public String[] getDropColumnSQL(Column column) {
|
||||
return new String[] { "ALTER TABLE "
|
||||
+ getFullName(column.getTable(), false) + " DROP " + column };
|
||||
}
|
||||
|
||||
/**
|
||||
* Return either
|
||||
* <code>CREATE SEQUENCE <sequence name></code> or
|
||||
* <code>CREATE GENERATOR <sequence name></code>.
|
||||
* If initial value of sequence is set, return also
|
||||
* an appropriate <code>ALTER</code> statement.
|
||||
*/
|
||||
@Override
|
||||
public String[] getCreateSequenceSQL(Sequence seq) {
|
||||
String seqName =
|
||||
checkNameLength(getFullName(seq), maxTableNameLength,
|
||||
"long-seq-name");
|
||||
String createSeq =
|
||||
MessageFormat.format(createSequenceSQL, new Object[] { seqName });
|
||||
if (seq.getInitialValue() == 0)
|
||||
return new String[] { createSeq };
|
||||
|
||||
// Use String.valueOf to get rid of possible number formatting.
|
||||
String alterSeq =
|
||||
MessageFormat.format(alterSequenceSQL, new Object[] { seqName,
|
||||
String.valueOf(seq.getInitialValue()) });
|
||||
return new String[] { createSeq, alterSeq };
|
||||
}
|
||||
|
||||
/**
|
||||
* Return Firebird-specific statement to select the list of sequences.
|
||||
*/
|
||||
@Override
|
||||
protected String getSequencesSQL(String schemaName, String sequenceName) {
|
||||
StringBuilder buf = new StringBuilder(sequenceSQL);
|
||||
if (sequenceName != null)
|
||||
buf.append(sequenceNameSQL);
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Call super implementation and trim sequence name. This is because of
|
||||
* trailing spaces problem: <code>RDB$GENERATORS.RDB$GENERATOR_NAME</code>
|
||||
* is <code>CHAR(31)</code> and using <code>RTRIM</code> UDF function on
|
||||
* Firebird 1.5 surprisingly returns a string right-padded with spaces up
|
||||
* to the length of 255.
|
||||
*/
|
||||
@Override
|
||||
protected Sequence newSequence(ResultSet sequenceMeta) throws SQLException {
|
||||
Sequence seq = super.newSequence(sequenceMeta);
|
||||
seq.setName(seq.getName().trim());
|
||||
return seq;
|
||||
}
|
||||
|
||||
/**
|
||||
* On Firebird 1.5 return
|
||||
* <code>DROP GENERATOR <sequence name></code>.
|
||||
* On Firebird 2.0 and later delegate to the super implementation.
|
||||
*/
|
||||
@Override
|
||||
public String[] getDropSequenceSQL(Sequence seq) {
|
||||
if (firebirdVersion == FB_VERSION_15)
|
||||
return new String[] { dropSequenceSQLFB15 + getFullName(seq) };
|
||||
return super.getDropSequenceSQL(seq);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throw {@link UnsupportedException}. Firebird in version earlier than 2.1
|
||||
* has no suitable function. Firebird 2.1 has the <code>POSITION</code>
|
||||
* function but using it here results in errors like "data type unknown" or
|
||||
* "expression evaluation not supported".
|
||||
*/
|
||||
@Override
|
||||
public void indexOf(SQLBuffer buf, FilterValue str, FilterValue find,
|
||||
FilterValue start) {
|
||||
throw new UnsupportedException(_loc.get("function-not-supported",
|
||||
getClass(), "LOCATE"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Use
|
||||
* <code>SUBSTRING(<col name> FROM <m> FOR <n>)</code>.
|
||||
* Parameters are inlined because neither parameter binding nor expressions
|
||||
* are accepted by Firebird here. As a result, an
|
||||
* {@link UnsupportedException} is thrown when something else than a
|
||||
* constant is used in <code>start</code> or <code>end</code>.
|
||||
*/
|
||||
@Override
|
||||
public void substring(SQLBuffer buf, FilterValue str, FilterValue start,
|
||||
FilterValue end) {
|
||||
// SUBSTRING in Firebird is of the form:
|
||||
// SELECT SUBSTRING(SOME_COLUMN FROM 1 FOR 5)
|
||||
buf.append("SUBSTRING(");
|
||||
buf.append(substringFunctionName).append("(");
|
||||
str.appendTo(buf);
|
||||
buf.append(" FROM ");
|
||||
start.appendTo(buf);
|
||||
buf.append(" + 1");
|
||||
if (start.getValue() instanceof Number) {
|
||||
long startLong = toLong(start);
|
||||
buf.append(Long.toString(startLong + 1));
|
||||
} else {
|
||||
throw new UnsupportedException(_loc.get("function-not-supported",
|
||||
getClass(), substringFunctionName + " with non-constants"));
|
||||
}
|
||||
if (end != null) {
|
||||
buf.append(" FOR ");
|
||||
end.appendTo(buf);
|
||||
buf.append(" - (");
|
||||
start.appendTo(buf);
|
||||
buf.append(")");
|
||||
if (start.getValue() instanceof Number
|
||||
&& end.getValue() instanceof Number) {
|
||||
long startLong = toLong(start);
|
||||
long endLong = toLong(end);
|
||||
buf.append(Long.toString(endLong - startLong));
|
||||
} else {
|
||||
throw new UnsupportedException(_loc.get(
|
||||
"function-not-supported", getClass(), substringFunctionName
|
||||
+ " with non-constants"));
|
||||
}
|
||||
}
|
||||
buf.append(")");
|
||||
}
|
||||
|
||||
/**
|
||||
* On Firebird 1.5 reduce the size of indexed <code>VARCHAR</code> column
|
||||
* to 252 or a value specified by user. 252 is the maximum Firebird 1.5 can
|
||||
* handle for one-column indexes. On Firebird 2.0 and later delegate to the
|
||||
* super implementation.
|
||||
*/
|
||||
@Override
|
||||
protected String appendSize(Column col, String typeName) {
|
||||
if (firebirdVersion != FB_VERSION_15)
|
||||
return super.appendSize(col, typeName);
|
||||
|
||||
if (col.getType() == Types.VARCHAR
|
||||
&& col.getSize() > indexedVarcharMaxSizeFB15
|
||||
&& col.getTable() != null) {
|
||||
|
||||
if (col.isPrimaryKey()) {
|
||||
col.setSize(indexedVarcharMaxSizeFB15);
|
||||
return super.appendSize(col, typeName);
|
||||
}
|
||||
Index[] indexes = col.getTable().getIndexes();
|
||||
for (Index index : indexes) {
|
||||
if (index.containsColumn(col)) {
|
||||
col.setSize(indexedVarcharMaxSizeFB15);
|
||||
return super.appendSize(col, typeName);
|
||||
}
|
||||
}
|
||||
Unique[] uniques = col.getTable().getUniques();
|
||||
for (Unique unique : uniques) {
|
||||
if (unique.containsColumn(col)) {
|
||||
col.setSize(indexedVarcharMaxSizeFB15);
|
||||
return super.appendSize(col, typeName);
|
||||
}
|
||||
}
|
||||
ForeignKey[] foreignKeys = col.getTable().getForeignKeys();
|
||||
for (ForeignKey foreignKey : foreignKeys) {
|
||||
if (foreignKey.containsColumn(col)) {
|
||||
col.setSize(indexedVarcharMaxSizeFB15);
|
||||
return super.appendSize(col, typeName);
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.appendSize(col, typeName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use error code as SQL state returned by Firebird is ambiguous.
|
||||
*/
|
||||
@Override
|
||||
protected Boolean matchErrorState(int subtype, Set<String> errorStates,
|
||||
SQLException ex) {
|
||||
int errorCode = ex.getErrorCode();
|
||||
return errorStates.contains(String.valueOf(errorCode)) ? Boolean.FALSE
|
||||
: null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -137,9 +137,9 @@
|
|||
</dictionary>
|
||||
|
||||
<dictionary class="org.apache.openjpa.jdbc.sql.FirebirdDictionary">
|
||||
<lock></lock>
|
||||
<lock>335544336</lock>
|
||||
<referential-integrity></referential-integrity>
|
||||
<object-exists></object-exists>
|
||||
<object-exists>335544665</object-exists>
|
||||
<object-not-found></object-not-found>
|
||||
<optimistic></optimistic>
|
||||
<query></query>
|
||||
|
|
|
@ -3148,6 +3148,86 @@ overridden. It is used only when the schema is generated using the
|
|||
in alphabetical order -->
|
||||
</itemizedlist>
|
||||
</section>
|
||||
<section id="ref_guide_dbsetup_dbsupport_firebird">
|
||||
<title>
|
||||
FirebirdDictionary Properties
|
||||
</title>
|
||||
<indexterm zone="ref_guide_dbsetup_dbsupport_firebird">
|
||||
<primary>
|
||||
Firebird
|
||||
</primary>
|
||||
<seealso>
|
||||
DBDictionary
|
||||
</seealso>
|
||||
</indexterm>
|
||||
<para>
|
||||
The <literal>firebird</literal> dictionary understands the following additional
|
||||
properties:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem id="FirebirdDictionary.FirebirdVersion">
|
||||
<para>
|
||||
<indexterm>
|
||||
<primary>
|
||||
Firebird
|
||||
</primary>
|
||||
<secondary>
|
||||
FirebirdVersion
|
||||
</secondary>
|
||||
</indexterm>
|
||||
<literal>FirebirdVersion</literal>: The database version OpenJPA connects to.
|
||||
This property affects the SQL statements executed by OpenJPA.
|
||||
Available values are: 15, 20 and 21
|
||||
- they indicate Firebird versions 1.5, 2.0 and 2.1 respectively.
|
||||
If not set, the value will be auto-detected.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem id="FirebirdDictionary.IndexedVarcharMaxSizeFB15">
|
||||
<para>
|
||||
<indexterm>
|
||||
<primary>
|
||||
Firebird
|
||||
</primary>
|
||||
<secondary>
|
||||
IndexedVarcharMaxSizeFB15
|
||||
</secondary>
|
||||
</indexterm>
|
||||
<literal>IndexedVarcharMaxSizeFB15</literal>: Firebird 1.5 imposes
|
||||
tight limits on index size. In particular, an indexed
|
||||
<literal>VARCHAR</literal> column size cannot exceed 252.
|
||||
When <link linkend="ref_guide_mapping_mappingtool">schema is created</link>,
|
||||
OpenJPA will use this property to reduce the size
|
||||
of indexed <literal>VARCHAR</literal> columns.
|
||||
Defaults to 252 but you might want to decrease this value if multi-column
|
||||
indexes are used. If the Firebird version is 2.0 or later or
|
||||
schema creation is not used, this property does not matter.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem id="FirebirdDictionary.RangeSyntax">
|
||||
<para>
|
||||
<indexterm>
|
||||
<primary>
|
||||
Firebird
|
||||
</primary>
|
||||
<secondary>
|
||||
RangeSyntax
|
||||
</secondary>
|
||||
</indexterm>
|
||||
<literal>RangeSyntax</literal>: Firebird 2.0 and later support two
|
||||
ways of handling queries that select a range of data:
|
||||
<literal>"FIRST <p> SKIP <q>"</literal> and
|
||||
<literal>"ROWS <m> TO <n>"</literal>. Earlier versions support only
|
||||
<literal>"FIRST <p> SKIP <q>"</literal> syntax.
|
||||
This property determines the syntax to be used.
|
||||
Available values are:
|
||||
<literal>"firstskip"</literal> and <literal>"rows"</literal>.
|
||||
Defaults to using <literal>"ROWS <m> TO <n>"</literal> if the
|
||||
Firebird version is 2.0 or later, and
|
||||
<literal>"FIRST <p> SKIP <q>"</literal> otherwise.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
<section id="ref_guide_dbsetup_dbsupport_mysql">
|
||||
<title>
|
||||
MySQLDictionary Properties
|
||||
|
|
|
@ -126,13 +126,13 @@ by OpenJPA.
|
|||
Firebird
|
||||
</entry>
|
||||
<entry colname="dbversion">
|
||||
1.5
|
||||
1.5, 2.0, 2.1
|
||||
</entry>
|
||||
<entry colname="drivname">
|
||||
JayBird JCA/JDBC driver
|
||||
</entry>
|
||||
<entry colname="drivversion">
|
||||
1.0.1
|
||||
2.1.6
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
|
@ -553,7 +553,7 @@ will fail unless the <literal>SimulateLocking</literal> property is set for the
|
|||
</title>
|
||||
<programlisting>
|
||||
openjpa.ConnectionDriverName: org.firebirdsql.jdbc.FBDriver
|
||||
openjpa.ConnectionURL: jdbc:firebirdsql://SERVER_NAME:SERVER_PORT/DB_PATH
|
||||
openjpa.ConnectionURL: jdbc:firebirdsql:SERVER_NAME/3050:DB_PATH_OR_ALIAS
|
||||
</programlisting>
|
||||
</example>
|
||||
<section id="dbsupport_firebird_issues">
|
||||
|
@ -568,8 +568,13 @@ Firebird does not support auto-increment columns.
|
|||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Firebird does not support the <literal>LOWER</literal>, <literal>SUBSTRING
|
||||
</literal>, or <literal>INSTR</literal> SQL functions.
|
||||
In order to use many of JPQL functions with Firebird 1.5, Interbase UDFs
|
||||
have to be available in the database.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>LOCATE</literal> JPQL function is not supported.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
|
Loading…
Reference in New Issue