/*
 * Copyright 2004-2019 H2 Group. Multiple-Licensed under the MPL 2.0,
 * and the EPL 1.0 (http://h2database.com/html/license.html).
 * Initial Developer: H2 Group
 */
package org.h2.value;

import java.sql.PreparedStatement;
import java.sql.SQLException;

import org.h2.engine.SysProperties;
import org.h2.util.MathUtils;
import org.h2.util.StringUtils;

Implementation of the VARCHAR data type. It is also the base class for other ValueString* classes.
/** * Implementation of the VARCHAR data type. * It is also the base class for other ValueString* classes. */
public class ValueString extends Value {
Empty string. Should not be used in places where empty string can be treated as NULL depending on database mode.
/** * Empty string. Should not be used in places where empty string can be * treated as {@code NULL} depending on database mode. */
public static final ValueString EMPTY = new ValueString("");
The string data.
/** * The string data. */
protected final String value; private TypeInfo type; protected ValueString(String value) { this.value = value; } @Override public StringBuilder getSQL(StringBuilder builder) { return StringUtils.quoteStringSQL(builder, value); } @Override public boolean equals(Object other) { return other instanceof ValueString && value.equals(((ValueString) other).value); } @Override public int compareTypeSafe(Value o, CompareMode mode) { return mode.compareString(value, ((ValueString) o).value, false); } @Override public String getString() { return value; } @Override public Object getObject() { return value; } @Override public void set(PreparedStatement prep, int parameterIndex) throws SQLException { prep.setString(parameterIndex, value); } @Override public int getMemory() { /* * Java 11 with -XX:-UseCompressedOops * Empty string: 88 bytes * 1 to 4 UTF-16 chars: 96 bytes */ return value.length() * 2 + 94; } @Override public Value convertPrecision(long precision, boolean force) { if (precision == 0 || value.length() <= precision) { return this; } int p = MathUtils.convertLongToInt(precision); return getNew(value.substring(0, p)); } @Override public int hashCode() { // TODO hash performance: could build a quicker hash // by hashing the size and a few characters return value.hashCode(); // proposed code: // private int hash = 0; // // public int hashCode() { // int h = hash; // if (h == 0) { // String s = value; // int l = s.length(); // if (l > 0) { // if (l < 16) // h = s.hashCode(); // else { // h = l; // for (int i = 1; i <= l; i <<= 1) // h = 31 * // (31 * h + s.charAt(i - 1)) + // s.charAt(l - i); // } // hash = h; // } // } // return h; // } } @Override public final TypeInfo getType() { TypeInfo type = this.type; if (type == null) { int length = value.length(); this.type = type = new TypeInfo(getValueType(), length, 0, length, null); } return type; } @Override public int getValueType() { return STRING; }
Get or create a string value for the given string.
Params:
  • s – the string
Returns:the value
/** * Get or create a string value for the given string. * * @param s the string * @return the value */
public static Value get(String s) { return get(s, false); }
Get or create a string value for the given string.
Params:
  • s – the string
  • treatEmptyStringsAsNull – whether or not to treat empty strings as NULL
Returns:the value
/** * Get or create a string value for the given string. * * @param s the string * @param treatEmptyStringsAsNull whether or not to treat empty strings as * NULL * @return the value */
public static Value get(String s, boolean treatEmptyStringsAsNull) { if (s.isEmpty()) { return treatEmptyStringsAsNull ? ValueNull.INSTANCE : EMPTY; } ValueString obj = new ValueString(StringUtils.cache(s)); if (s.length() > SysProperties.OBJECT_CACHE_MAX_PER_ELEMENT_SIZE) { return obj; } return Value.cache(obj); // this saves memory, but is really slow // return new ValueString(s.intern()); }
Create a new String value of the current class. This method is meant to be overridden by subclasses.
Params:
  • s – the string
Returns:the value
/** * Create a new String value of the current class. * This method is meant to be overridden by subclasses. * * @param s the string * @return the value */
protected Value getNew(String s) { return ValueString.get(s); } }