blob: 0c4c3d061f0c5e6663e4d8745449fa9f7886cff7 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.drill.jdbc.impl;
import java.sql.SQLException;
import org.apache.calcite.avatica.util.Cursor.Accessor;
import org.apache.drill.exec.expr.TypeHelper;
import org.apache.drill.exec.record.RecordBatchLoader;
import org.apache.drill.exec.vector.ValueVector;
import org.apache.drill.exec.vector.accessor.BoundCheckingAccessor;
import org.apache.drill.exec.vector.accessor.SqlAccessor;
import org.apache.drill.jdbc.JdbcApiSqlException;
class DrillAccessorList extends BasicList<Accessor> {
@SuppressWarnings("unused")
private static final org.slf4j.Logger logger =
org.slf4j.LoggerFactory.getLogger(DrillAccessorList.class);
/** "None" value for rowLastColumnOffset. */
// (Not -1, since -1 can result from 0 (bad 1-based index) minus 1 (offset
// from 1-based to 0-based indexing.)
private static final int NULL_LAST_COLUMN_INDEX = -2;
private AvaticaDrillSqlAccessor[] accessors = new AvaticaDrillSqlAccessor[0];
/** Zero-based offset of last column referenced in current row.
* For {@link #wasNull()}. */
private int rowLastColumnOffset = NULL_LAST_COLUMN_INDEX;
/**
* Resets last-column-referenced information for {@link #wasNull}.
* Must be called whenever row is advanced (when {@link ResultSet#next()}
* is called).
*/
void clearLastColumnIndexedInRow() {
rowLastColumnOffset = NULL_LAST_COLUMN_INDEX;
}
void generateAccessors(DrillCursor cursor, RecordBatchLoader currentBatch) {
int cnt = currentBatch.getSchema().getFieldCount();
accessors = new AvaticaDrillSqlAccessor[cnt];
for(int i =0; i < cnt; i++){
final ValueVector vector = currentBatch.getValueAccessorById(null, i).getValueVector();
final SqlAccessor acc =
new TypeConvertingSqlAccessor(
new BoundCheckingAccessor(vector, TypeHelper.getSqlAccessor(vector))
);
accessors[i] = new AvaticaDrillSqlAccessor(acc, cursor);
}
clearLastColumnIndexedInRow();
}
/**
* @param accessorOffset 0-based index of accessor array (not 1-based SQL
* column index/ordinal value)
*/
@Override
public AvaticaDrillSqlAccessor get(final int accessorOffset) {
final AvaticaDrillSqlAccessor accessor = accessors[accessorOffset];
// Update lastColumnIndexedInRow after indexing accessors to not touch
// lastColumnIndexedInRow in case of out-of-bounds exception.
rowLastColumnOffset = accessorOffset;
return accessor;
}
boolean wasNull() throws SQLException{
if (NULL_LAST_COLUMN_INDEX == rowLastColumnOffset) {
throw new JdbcApiSqlException(
"ResultSet.wasNull() called without a preceding call to a column"
+ " getter method since the last call to ResultSet.next()");
}
return accessors[rowLastColumnOffset].wasNull();
}
@Override
public int size() {
return accessors.length;
}
}