/**
   * Given the time and first element of the sample, see if there are more array elements.
   *
   * @param stamp Time stamp of the sample
   * @param dbl0 Value of the first (maybe only) array element
   * @param severity Severity of the sample
   * @return Array with given element and maybe more.
   * @throws Exception on error, including 'cancel'
   */
  private double[] readArrayElements(
      final Timestamp stamp, final double dbl0, final AlarmSeverity severity) throws Exception {
    // For performance reasons, only look for array data until we hit a scalar sample.
    if (is_an_array == false) return new double[] {dbl0};

    // See if there are more array elements
    if (sel_array_samples == null) { // Lazy initialization
      sel_array_samples =
          reader.getRDB().getConnection().prepareStatement(reader.getSQL().sample_sel_array_vals);
    }
    sel_array_samples.setInt(1, channel_id);
    sel_array_samples.setTimestamp(2, TimestampHelper.toSQLTimestamp(stamp));
    // MySQL keeps nanoseconds in designated column, not TIMESTAMP
    if (!reader.isOracle()) sel_array_samples.setInt(3, stamp.getNanoSec());

    // Assemble array of unknown size in ArrayList ....
    final ArrayList<Double> vals = new ArrayList<Double>();
    reader.addForCancellation(sel_array_samples);
    try {
      final ResultSet res = sel_array_samples.executeQuery();
      vals.add(new Double(dbl0));
      while (res.next()) vals.add(res.getDouble(1));
      res.close();
    } finally {
      reader.removeFromCancellation(sel_array_samples);
    }
    // Convert to plain double array
    final int N = vals.size();
    final double ret[] = new double[N];
    for (int i = 0; i < N; i++) ret[i] = vals.get(i).doubleValue();
    // Check if it's in fact just a scalar, and a valid one
    if (N == 1 && severity != AlarmSeverity.UNDEFINED) { // Found a perfect non-array sample:
      // Assume that the data is scalar, skip the array check from now on
      is_an_array = false;
    }
    return ret;
  }