/** * Imperfect estimate of row size given a PTable TODO: keep row count in stats table and use total * size / row count instead * * @param table * @return estimate of size in bytes of a row */ public static long estimateRowSize(PTable table) { int keyLength = estimateKeyLength(table); long rowSize = 0; for (PColumn column : table.getColumns()) { if (!SchemaUtil.isPKColumn(column)) { PDataType type = column.getDataType(); Integer maxLength = column.getMaxLength(); int valueLength = !type.isFixedWidth() ? VAR_KV_LENGTH_ESTIMATE : maxLength == null ? type.getByteSize() : maxLength; rowSize += KeyValue.getKeyValueDataStructureSize( keyLength, column.getFamilyName().getBytes().length, column.getName().getBytes().length, valueLength); } } // Empty key value rowSize += KeyValue.getKeyValueDataStructureSize( keyLength, getEmptyColumnFamily(table).length, QueryConstants.EMPTY_COLUMN_BYTES.length, 0); return rowSize; }
// TODO: cache? public static LiteralExpression newConstant( Object value, PDataType type, Integer maxLength, Integer scale, SortOrder sortOrder, Determinism determinism, boolean rowKeyOrderOptimizable) throws SQLException { if (value == null) { return (type == null) ? getNullLiteralExpression(determinism) : getTypedNullLiteralExpression(type, determinism); } else if (value instanceof Boolean) { return getBooleanLiteralExpression((Boolean) value, determinism); } PDataType actualType = PDataType.fromLiteral(value); // For array we should check individual element in it? // It would be costly though!!!!! // UpsertStatement can try to cast varchar to date type but PVarchar can't CoercibleTo Date or // Timestamp // otherwise TO_NUMBER like functions will fail if (!actualType.isCoercibleTo(type, value) && (!actualType.equals(PVarchar.INSTANCE) || !(type.equals(PDate.INSTANCE) || type.equals(PTimestamp.INSTANCE) || type.equals(PTime.INSTANCE)))) { throw TypeMismatchException.newException(type, actualType, value.toString()); } value = type.toObject(value, actualType); byte[] b = type.isArrayType() ? ((PArrayDataType) type) .toBytes( value, PArrayDataType.arrayBaseType(type), sortOrder, rowKeyOrderOptimizable) : type.toBytes(value, sortOrder); if (type == PVarchar.INSTANCE || type == PChar.INSTANCE) { if (type == PChar.INSTANCE && maxLength != null && b.length < maxLength) { if (rowKeyOrderOptimizable) { b = type.pad(b, maxLength, sortOrder); } else { b = StringUtil.padChar(b, maxLength); } } else if (value != null) { maxLength = ((String) value).length(); } } else if (type.isArrayType()) { maxLength = ((PhoenixArray) value).getMaxLength(); } if (b.length == 0) { return getTypedNullLiteralExpression(type, determinism); } if (maxLength == null) { maxLength = type == null || !type.isFixedWidth() ? null : type.getMaxLength(value); } return new LiteralExpression(value, type, b, maxLength, scale, sortOrder, determinism); }
private LiteralExpression( Object value, PDataType type, byte[] byteValue, Determinism determinism) { this( value, type, byteValue, type == null || !type.isFixedWidth() ? null : type.getMaxLength(value), null, SortOrder.getDefault(), determinism); }
public static PName padTenantIdIfNecessary( RowKeySchema schema, boolean isSalted, PName tenantId) { int pkPos = isSalted ? 1 : 0; String tenantIdStr = tenantId.getString(); Field field = schema.getField(pkPos); PDataType dataType = field.getDataType(); boolean isFixedWidth = dataType.isFixedWidth(); Integer maxLength = field.getMaxLength(); if (isFixedWidth && maxLength != null) { if (tenantIdStr.length() < maxLength) { tenantIdStr = (String) dataType.pad(tenantIdStr, maxLength); return PNameFactory.newName(tenantIdStr); } } return tenantId; }
/** * Estimate the max key length in bytes of the PK for a given table * * @param table the table * @return the max PK length */ public static int estimateKeyLength(PTable table) { int maxKeyLength = 0; // Calculate the max length of a key (each part must currently be of a fixed width) int i = 0; List<PColumn> columns = table.getPKColumns(); while (i < columns.size()) { PColumn keyColumn = columns.get(i++); PDataType type = keyColumn.getDataType(); Integer maxLength = keyColumn.getMaxLength(); maxKeyLength += !type.isFixedWidth() ? VAR_LENGTH_ESTIMATE : maxLength == null ? type.getByteSize() : maxLength; } return maxKeyLength; }