datatypedescriptor.java
来自「derby database source code.good for you.」· Java 代码 · 共 1,094 行 · 第 1/2 页
JAVA
1,094 行
* by the maximum width for the (var)char. The maximumWidth * becomes the new precision + 3. This is because * the (var)char could contain any decimal value from XXXXXX * to 0.XXXXX. (In other words, we don't know which side of the * decimal point the characters will be on.) */ if (lowerTypeId.isStringTypeId()) { if (higherTypeId.isBitTypeId() && ! (higherTypeId.isLongConcatableTypeId())) { if (lowerTypeId.isLongConcatableTypeId()) { if (maximumWidth > (Integer.MAX_VALUE / 16)) maximumWidth = Integer.MAX_VALUE; else maximumWidth *= 16; } else { int charMaxWidth; int fromWidth = lowerType.getMaximumWidth(); if (fromWidth > (Integer.MAX_VALUE / 16)) charMaxWidth = Integer.MAX_VALUE; else charMaxWidth = 16 * fromWidth; maximumWidth = (maximumWidth >= charMaxWidth) ? maximumWidth : charMaxWidth; } } } /* * If we are doing an implicit (var)char->decimal conversion * then the resulting decimal's precision could be as high as * 2 * the maximum width (precisely 2mw-1) for the (var)char * and the scale could be as high as the maximum width * (precisely mw-1) for the (var)char. * The maximumWidth becomes the new precision + 3. This is * because the (var)char could contain any decimal value from * XXXXXX to 0.XXXXX. (In other words, we don't know which * side of the decimal point the characters will be on.) * * We don't follow this algorithm for long varchar because the * maximum length of a long varchar is maxint, and we don't * want to allocate a huge decimal value. So in this case, * the precision, scale, and maximum width all come from * the decimal type. */ if (lowerTypeId.isStringTypeId() && ! (lowerTypeId.isLongConcatableTypeId()) && higherTypeId.isDecimalTypeId() ) { int charMaxWidth = lowerType.getMaximumWidth(); int charPrecision; /* ** Be careful not to overflow when calculating the ** precision. Remember that we will be adding ** three to the precision to get the maximum width. */ if (charMaxWidth > (Integer.MAX_VALUE - 3) / 2) charPrecision = Integer.MAX_VALUE - 3; else charPrecision = charMaxWidth * 2; if (precision < charPrecision) precision = charPrecision; if (scale < charMaxWidth) scale = charMaxWidth; maximumWidth = precision + 3; } } } else { /* At least 1 type is not a system built-in type */ ClassInspector cu = cf.getClassInspector(); TypeId thisCompType = (TypeId) thisType; TypeId otherCompType = (TypeId) otherType; if (cu.assignableTo(thisCompType.getCorrespondingJavaTypeName(), otherCompType.getCorrespondingJavaTypeName())) { higherType = otherDTS; } else { if (SanityManager.DEBUG) SanityManager.ASSERT( cu.assignableTo(otherCompType.getCorrespondingJavaTypeName(), thisCompType.getCorrespondingJavaTypeName()), otherCompType.getCorrespondingJavaTypeName() + " expected to be assignable to " + thisCompType.getCorrespondingJavaTypeName()); higherType = this; } precision = higherType.getPrecision(); scale = higherType.getScale(); } higherType = new DataTypeDescriptor(higherType, precision, scale, nullable, maximumWidth); return higherType; } /** * Check whether or not the 2 types (DataTypeDescriptor) have the same type * and length. * This is useful for UNION when trying to decide whether a NormalizeResultSet * is required. * * @param otherDTS DataTypeDescriptor to compare with. * * @return boolean Whether or not the 2 DTSs have the same type and length. */ public boolean isExactTypeAndLengthMatch(DataTypeDescriptor otherDTS) { /* Do both sides have the same length? */ if (getMaximumWidth() != otherDTS.getMaximumWidth()) { return false; } if (getScale() != otherDTS.getScale()) { return false; } if (getPrecision() != otherDTS.getPrecision()) { return false; } TypeId thisType = getTypeId(); TypeId otherType = otherDTS.getTypeId(); /* Do both sides have the same type? */ if ( ! thisType.equals(otherType)) { return false; } return true; } /** * @see TypeDescriptor#getMaximumWidth */ public int getMaximumWidth() { return typeDescriptor.getMaximumWidth(); } /** * @see TypeDescriptor#getMaximumWidthInBytes */ public int getMaximumWidthInBytes() { return typeDescriptor.getMaximumWidthInBytes(); } /** * Gets the TypeId for the datatype. * * @return The TypeId for the datatype. */ public TypeId getTypeId() { return typeId; } /** Get a Null for this type. */ public DataValueDescriptor getNull() { return typeId.getNull(); } /** * Gets the name of this datatype. * * * @return the name of this datatype */ public String getTypeName() { return typeId.getSQLTypeName(); } /** * Get the jdbc type id for this type. JDBC type can be * found in java.sql.Types. * * @return a jdbc type, e.g. java.sql.Types.DECIMAL * * @see Types */ public int getJDBCTypeId() { return typeId.getJDBCTypeId(); } /** * Returns the number of decimal digits for the datatype, if applicable. * * @return The number of decimal digits for the datatype. Returns * zero for non-numeric datatypes. */ public int getPrecision() { return typeDescriptor.getPrecision(); } /** * Returns the number of digits to the right of the decimal for * the datatype, if applicable. * * @return The number of digits to the right of the decimal for * the datatype. Returns zero for non-numeric datatypes. */ public int getScale() { return typeDescriptor.getScale(); } /** * Returns TRUE if the datatype can contain NULL, FALSE if not. * JDBC supports a return value meaning "nullability unknown" - * I assume we will never have columns where the nullability is unknown. * * @return TRUE if the datatype can contain NULL, FALSE if not. */ public boolean isNullable() { return typeDescriptor.isNullable(); } /** * Set the nullability of the datatype described by this descriptor * * @param nullable TRUE means set nullability to TRUE, FALSE * means set it to FALSE * * @return Nothing */ public void setNullability(boolean nullable) { typeDescriptor.setNullability(nullable); } /** Compare if two TypeDescriptors are exactly the same @param typeDescriptor the typeDescriptor to compare to. */ public boolean equals(Object aTypeDescriptor) { return typeDescriptor.equals(aTypeDescriptor); } /** * Converts this data type descriptor (including length/precision) * to a string. E.g. * * VARCHAR(30) * * or * * java.util.Hashtable * * @return String version of datatype, suitable for running through * the Parser. */ public String getSQLstring() { return typeId.toParsableString( this ); } /** * Get the simplified type descriptor that is intended to be stored * in the system tables. */ public TypeDescriptorImpl getCatalogType() { return typeDescriptor; } /** * Get the estimated memory usage for this type descriptor. */ public double estimatedMemoryUsage() { switch (typeId.getTypeFormatId()) { case StoredFormatIds.LONGVARBIT_TYPE_ID: /* Who knows? Let's just use some big number */ return 10000.0; case StoredFormatIds.BIT_TYPE_ID: return (double) ( ( ((float) getMaximumWidth()) / 8.0) + 0.5); case StoredFormatIds.BOOLEAN_TYPE_ID: return 4.0; case StoredFormatIds.CHAR_TYPE_ID: case StoredFormatIds.VARCHAR_TYPE_ID: case StoredFormatIds.NATIONAL_CHAR_TYPE_ID: case StoredFormatIds.NATIONAL_VARCHAR_TYPE_ID: return (double) (2.0 * getMaximumWidth()); case StoredFormatIds.LONGVARCHAR_TYPE_ID: case StoredFormatIds.NATIONAL_LONGVARCHAR_TYPE_ID: /* Who knows? Let's just use some big number */ return 10000.0; case StoredFormatIds.DECIMAL_TYPE_ID: /* ** 0.415 converts from number decimal digits to number of 8-bit digits. ** Add 1.0 for the sign byte, and 0.5 to force it to round up. */ return (double) ( (getPrecision() * 0.415) + 1.5 ); case StoredFormatIds.DOUBLE_TYPE_ID: return 8.0; case StoredFormatIds.INT_TYPE_ID: return 4.0; case StoredFormatIds.LONGINT_TYPE_ID: return 8.0; case StoredFormatIds.REAL_TYPE_ID: return 4.0; case StoredFormatIds.SMALLINT_TYPE_ID: return 2.0; case StoredFormatIds.TINYINT_TYPE_ID: return 1.0; case StoredFormatIds.REF_TYPE_ID: /* I think 12 is the right number */ return 12.0; case StoredFormatIds.USERDEFINED_TYPE_ID_V3: if (typeId.userType()) { /* Who knows? Let's just use some medium-sized number */ return 256.0; } case StoredFormatIds.DATE_TYPE_ID: case StoredFormatIds.TIME_TYPE_ID: case StoredFormatIds.TIMESTAMP_TYPE_ID: return 12.0; default: return 0.0; } } /** * Compare JdbcTypeIds to determine if they represent equivalent * SQL types. For example Types.NUMERIC and Types.DECIMAL are * equivalent * * @param existingType JDBC type id of Cloudscape data type * @param jdbcTypeIdB JDBC type id passed in from application. * * @return boolean true if types are equivalent, false if not */ public static boolean isJDBCTypeEquivalent(int existingType, int jdbcTypeId) { // Any type matches itself. if (existingType == jdbcTypeId) return true; // To a numeric type if (DataTypeDescriptor.isNumericType(existingType)) { if (DataTypeDescriptor.isNumericType(jdbcTypeId)) return true; if (DataTypeDescriptor.isCharacterType(jdbcTypeId)) return true; return false; } // To character type. if (DataTypeDescriptor.isCharacterType(existingType)) { if (DataTypeDescriptor.isCharacterType(jdbcTypeId)) return true; if (DataTypeDescriptor.isNumericType(jdbcTypeId)) return true; switch (jdbcTypeId) { case Types.DATE: case Types.TIME: case Types.TIMESTAMP: return true; default: break; } return false; } // To binary type if (DataTypeDescriptor.isBinaryType(existingType)) { if (DataTypeDescriptor.isBinaryType(jdbcTypeId)) return true; return false; } // To DATE, TIME if (existingType == Types.DATE || existingType == Types.TIME) { if (DataTypeDescriptor.isCharacterType(jdbcTypeId)) return true; if (jdbcTypeId == Types.TIMESTAMP) return true; return false; } // To TIMESTAMP if (existingType == Types.TIMESTAMP) { if (DataTypeDescriptor.isCharacterType(jdbcTypeId)) return true; if (jdbcTypeId == Types.DATE) return true; return false; } // To CLOB if (existingType == Types.CLOB && DataTypeDescriptor.isCharacterType(jdbcTypeId)) return true; return false; } public static boolean isNumericType(int jdbcType) { switch (jdbcType) { case Types.BIT: case org.apache.derby.iapi.reference.JDBC30Translation.SQL_TYPES_BOOLEAN: case Types.TINYINT: case Types.SMALLINT: case Types.INTEGER: case Types.BIGINT: case Types.REAL: case Types.FLOAT: case Types.DOUBLE: case Types.DECIMAL: case Types.NUMERIC: return true; default: return false; } } private static boolean isCharacterType(int jdbcType) { switch (jdbcType) { case Types.CHAR: case Types.VARCHAR: case Types.LONGVARCHAR: return true; default: return false; } } private static boolean isBinaryType(int jdbcType) { switch (jdbcType) { case Types.BINARY: case Types.VARBINARY: case Types.LONGVARBINARY: return true; default: return false; } } public String toString() { return typeDescriptor.toString(); } // Formatable methods /** * Read this object from a stream of stored objects. * * @param in read this. * * @exception IOException thrown on error * @exception ClassNotFoundException thrown on error */ public void readExternal( ObjectInput in ) throws IOException, ClassNotFoundException { /* NOTE: We only write out the generic type id. * typeId will be reset to be the generic type id * when we get read back in since the generic * one is all that is needed at execution time. */ typeId = (TypeId) in.readObject(); typeDescriptor = (TypeDescriptorImpl) in.readObject(); } /** * Write this object to a stream of stored objects. * * @param out write bytes here. * * @exception IOException thrown on error */ public void writeExternal( ObjectOutput out ) throws IOException { out.writeObject( typeId ); out.writeObject( typeDescriptor ); } /** * Get the formatID which corresponds to this class. * * @return the formatID of this class */ public int getTypeFormatId() { return StoredFormatIds.DATA_TYPE_SERVICES_IMPL_V01_ID; }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?