| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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 org.apache.openjpa.jdbc.sql; |
| |
| import org.apache.openjpa.jdbc.kernel.exps.FilterValue; |
| |
| /** |
| * Base dictionary for the IBM DB2 family of databases. |
| */ |
| public abstract class AbstractDB2Dictionary |
| extends DBDictionary { |
| |
| public int varcharCastLength = 1000; |
| |
| public AbstractDB2Dictionary() { |
| numericTypeName = "DOUBLE"; |
| bitTypeName = "SMALLINT"; |
| smallintTypeName = "SMALLINT"; |
| tinyintTypeName = "SMALLINT"; |
| longVarbinaryTypeName = "BLOB"; |
| varbinaryTypeName = "BLOB"; |
| |
| // DB2-based databases have restrictions on having uncast parameters |
| // in string functions |
| stringLengthFunction = "LENGTH({0})"; |
| concatenateFunction = "(CAST({0} AS VARCHAR(" + varcharCastLength |
| + ")) || CAST({1} AS VARCHAR(" + varcharCastLength + ")))"; |
| |
| trimLeadingFunction = "LTRIM({0})"; |
| trimTrailingFunction = "RTRIM({0})"; |
| trimBothFunction = "LTRIM(RTRIM({0}))"; |
| |
| // in DB2, "for update" seems to be ignored with isolation |
| // levels below REPEATABLE_READ... force isolation to behave like RR |
| forUpdateClause = "FOR UPDATE WITH RR"; |
| |
| supportsLockingWithDistinctClause = false; |
| supportsLockingWithMultipleTables = false; |
| supportsLockingWithOrderClause = false; |
| supportsLockingWithOuterJoin = false; |
| supportsLockingWithInnerJoin = false; |
| supportsLockingWithSelectRange = true; |
| supportsCaseConversionForLob = true; |
| |
| requiresAutoCommitForMetaData = true; |
| requiresAliasForSubselect = true; |
| |
| supportsAutoAssign = true; |
| autoAssignClause = "GENERATED BY DEFAULT AS IDENTITY"; |
| lastGeneratedKeyQuery = "VALUES(IDENTITY_VAL_LOCAL())"; |
| |
| // DB2 doesn't understand "X CROSS JOIN Y", but it does understand |
| // the equivalent "X JOIN Y ON 1 = 1" |
| crossJoinClause = "JOIN"; |
| requiresConditionForCrossJoin = true; |
| } |
| |
| @Override |
| public void indexOf(SQLBuffer buf, FilterValue str, FilterValue find, |
| FilterValue start) { |
| buf.append("LOCATE(CAST(("); |
| find.appendTo(buf); |
| buf.append(") AS VARCHAR(").append(Integer.toString(varcharCastLength)) |
| .append(")), CAST(("); |
| str.appendTo(buf); |
| buf.append(") AS VARCHAR(").append(Integer.toString(varcharCastLength)) |
| .append("))"); |
| if (start != null) { |
| buf.append(", CAST(("); |
| start.appendTo(buf); |
| buf.append(") AS INTEGER)"); |
| } |
| buf.append(")"); |
| } |
| |
| @Override |
| public void substring(SQLBuffer buf, FilterValue str, FilterValue start, |
| FilterValue length) { |
| buf.append("SUBSTR(CAST(("); |
| str.appendTo(buf); |
| buf.append(") AS VARCHAR(").append(Integer.toString(varcharCastLength)) |
| .append(")), "); |
| if (start.getValue() instanceof Number) { |
| buf.append(Long.toString(toLong(start))); |
| } else { |
| buf.append("CAST(("); |
| start.appendTo(buf); |
| buf.append(") AS INTEGER)"); |
| } |
| if (length != null) { |
| buf.append(", "); |
| if (length.getValue() instanceof Number) { |
| buf.append(Long.toString(toLong(length))); |
| } else { |
| buf.append("CAST(("); |
| length.appendTo(buf); |
| buf.append(") AS INTEGER)"); |
| } |
| } |
| buf.append(")"); |
| } |
| } |