in src/main/java/com/amazon/redshift/jdbc/RedshiftArray.java [423:540]
private synchronized void buildArrayList() throws SQLException {
if (arrayList != null) {
return;
}
arrayList = new RsArrayList();
char delim = connection.getTypeInfo().getArrayDelimiter(oid);
if (fieldString != null) {
char[] chars = fieldString.toCharArray();
StringBuilder buffer = null;
boolean insideString = false;
boolean wasInsideString = false; // needed for checking if NULL
// value occurred
List<RsArrayList> dims = new ArrayList<RsArrayList>(); // array dimension arrays
RsArrayList curArray = arrayList; // currently processed array
// Starting with 8.0 non-standard (beginning index
// isn't 1) bounds the dimensions are returned in the
// data formatted like so "[0:3]={0,1,2,3,4}".
// Older versions simply do not return the bounds.
//
// Right now we ignore these bounds, but we could
// consider allowing these index values to be used
// even though the JDBC spec says 1 is the first
// index. I'm not sure what a client would like
// to see, so we just retain the old behavior.
int startOffset = 0;
{
if (chars[0] == '[') {
while (chars[startOffset] != '=') {
startOffset++;
}
startOffset++; // skip =
}
}
for (int i = startOffset; i < chars.length; i++) {
// escape character that we need to skip
if (chars[i] == '\\') {
i++;
} else if (!insideString && chars[i] == '{') {
// subarray start
if (dims.isEmpty()) {
dims.add(arrayList);
} else {
RsArrayList a = new RsArrayList();
RsArrayList p = dims.get(dims.size() - 1);
p.add(a);
dims.add(a);
}
curArray = dims.get(dims.size() - 1);
// number of dimensions
{
for (int t = i + 1; t < chars.length; t++) {
if (Character.isWhitespace(chars[t])) {
continue;
} else if (chars[t] == '{') {
curArray.dimensionsCount++;
} else {
break;
}
}
}
buffer = new StringBuilder();
continue;
} else if (chars[i] == '"') {
// quoted element
insideString = !insideString;
wasInsideString = true;
continue;
} else if (!insideString && Character.isWhitespace(chars[i])) {
// white space
continue;
} else if ((!insideString && (chars[i] == delim || chars[i] == '}'))
|| i == chars.length - 1) {
// array end or element end
// when character that is a part of array element
if (chars[i] != '"' && chars[i] != '}' && chars[i] != delim && buffer != null) {
buffer.append(chars[i]);
}
String b = buffer == null ? null : buffer.toString();
// add element to current array
if (b != null && (!b.isEmpty() || wasInsideString)) {
curArray.add(!wasInsideString && b.equals("NULL") ? null : b);
}
wasInsideString = false;
buffer = new StringBuilder();
// when end of an array
if (chars[i] == '}') {
dims.remove(dims.size() - 1);
// when multi-dimension
if (!dims.isEmpty()) {
curArray = dims.get(dims.size() - 1);
}
buffer = null;
}
continue;
}
if (buffer != null) {
buffer.append(chars[i]);
}
}
}
}