Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: adds getValue to ResultSet #1073

Merged
merged 11 commits into from Apr 25, 2021
13 changes: 13 additions & 0 deletions google-cloud-spanner/clirr-ignored-differences.xml
Expand Up @@ -592,4 +592,17 @@
<className>com/google/cloud/spanner/AsyncTransactionManager$CommitTimestampFuture</className>
<method>java.lang.Object get()</method>
</difference>

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clirr does not support Java 8 features, so it thinks these are breaking changes, where in fact we have provided default implementations for the added interface methods. No need for a major release here.

<!-- Adds getValue to ResultSet -->
<!-- These are not breaking changes, since we provide default interface implementation -->
<difference>
<differenceType>7012</differenceType>
<className>com/google/cloud/spanner/StructReader</className>
<method>com.google.cloud.spanner.Value getValue(int)</method>
</difference>
<difference>
<differenceType>7012</differenceType>
<className>com/google/cloud/spanner/StructReader</className>
<method>com.google.cloud.spanner.Value getValue(java.lang.String)</method>
</difference>
</differences>
Expand Up @@ -28,6 +28,7 @@
import com.google.cloud.ByteArray;
import com.google.cloud.Date;
import com.google.cloud.Timestamp;
import com.google.cloud.spanner.Type.StructField;
import com.google.cloud.spanner.spi.v1.SpannerRpc;
import com.google.cloud.spanner.v1.stub.SpannerStubSettings;
import com.google.common.annotations.VisibleForTesting;
Expand Down Expand Up @@ -679,6 +680,62 @@ protected Date getDateInternal(int columnIndex) {
return (Date) rowData.get(columnIndex);
}

@Override
protected Value getValueInternal(int columnIndex) {
final List<Type.StructField> structFields = getType().getStructFields();
final StructField structField = structFields.get(columnIndex);
final Type columnType = structField.getType();
final boolean isNull = rowData.get(columnIndex) == null;
switch (columnType.getCode()) {
case BOOL:
return Value.bool(isNull ? null : getBooleanInternal(columnIndex));
case INT64:
return Value.int64(isNull ? null : getLongInternal(columnIndex));
case NUMERIC:
return Value.numeric(isNull ? null : getBigDecimalInternal(columnIndex));
case FLOAT64:
return Value.float64(isNull ? null : getDoubleInternal(columnIndex));
case STRING:
return Value.string(isNull ? null : getStringInternal(columnIndex));
case BYTES:
return Value.bytes(isNull ? null : getBytesInternal(columnIndex));
case TIMESTAMP:
return Value.timestamp(isNull ? null : getTimestampInternal(columnIndex));
case DATE:
return Value.date(isNull ? null : getDateInternal(columnIndex));
case STRUCT:
return Value.struct(isNull ? null : getStructInternal(columnIndex));
case ARRAY:
switch (columnType.getArrayElementType().getCode()) {
case BOOL:
return Value.boolArray(isNull ? null : getBooleanListInternal(columnIndex));
case INT64:
return Value.int64Array(isNull ? null : getLongListInternal(columnIndex));
case NUMERIC:
return Value.numericArray(isNull ? null : getBigDecimalListInternal(columnIndex));
case FLOAT64:
return Value.float64Array(isNull ? null : getDoubleListInternal(columnIndex));
case STRING:
return Value.stringArray(isNull ? null : getStringListInternal(columnIndex));
case BYTES:
return Value.bytesArray(isNull ? null : getBytesListInternal(columnIndex));
case TIMESTAMP:
return Value.timestampArray(isNull ? null : getTimestampListInternal(columnIndex));
case DATE:
return Value.dateArray(isNull ? null : getDateListInternal(columnIndex));
case STRUCT:
return Value.structArray(
columnType.getArrayElementType(),
isNull ? null : getStructListInternal(columnIndex));
default:
thiagotnunes marked this conversation as resolved.
Show resolved Hide resolved
throw new IllegalArgumentException(
"Invalid array value type " + this.type.getArrayElementType());
}
default:
throw new IllegalArgumentException("Invalid value type " + this.type);
}
}

@Override
protected Struct getStructInternal(int columnIndex) {
return (Struct) rowData.get(columnIndex);
Expand Down Expand Up @@ -1280,6 +1337,11 @@ protected Date getDateInternal(int columnIndex) {
return currRow().getDateInternal(columnIndex);
}

@Override
protected Value getValueInternal(int columnIndex) {
return currRow().getValueInternal(columnIndex);
}

@Override
protected boolean[] getBooleanArrayInternal(int columnIndex) {
return currRow().getBooleanArrayInternal(columnIndex);
Expand Down
Expand Up @@ -49,6 +49,10 @@ public abstract class AbstractStructReader implements StructReader {

protected abstract Date getDateInternal(int columnIndex);

protected Value getValueInternal(int columnIndex) {
throw new UnsupportedOperationException("method should be overwritten");
}

protected abstract boolean[] getBooleanArrayInternal(int columnIndex);

protected abstract List<Boolean> getBooleanListInternal(int columnIndex);
Expand Down Expand Up @@ -197,6 +201,18 @@ public Date getDate(String columnName) {
return getDateInternal(columnIndex);
}

@Override
public Value getValue(int columnIndex) {
checkNonNull(columnIndex, columnIndex);
return getValueInternal(columnIndex);
}

@Override
public Value getValue(String columnName) {
int columnIndex = getColumnIndex(columnName);
return getValueInternal(columnIndex);
}

@Override
public boolean[] getBooleanArray(int columnIndex) {
checkNonNullOfType(columnIndex, Type.array(Type.bool()), columnIndex);
Expand Down
Expand Up @@ -333,4 +333,16 @@ public List<Struct> getStructList(String columnName) {
checkValidState();
return delegate.get().getStructList(columnName);
}

@Override
public Value getValue(int columnIndex) {
checkValidState();
return delegate.get().getValue(columnIndex);
}

@Override
public Value getValue(String columnName) {
checkValidState();
return delegate.get().getValue(columnName);
}
}
Expand Up @@ -273,6 +273,16 @@ public Date getDate(String columnName) {
return getCurrentRowAsStruct().getDate(columnName);
}

@Override
public Value getValue(int columnIndex) {
return getCurrentRowAsStruct().getValue(columnIndex);
}

@Override
public Value getValue(String columnName) {
return getCurrentRowAsStruct().getValue(columnName);
}

@Override
public boolean[] getBooleanArray(int columnIndex) {
return getCurrentRowAsStruct().getBooleanArray(columnIndex);
Expand Down
Expand Up @@ -207,6 +207,11 @@ protected Date getDateInternal(int columnIndex) {
return values.get(columnIndex).getDate();
}

@Override
protected Value getValueInternal(int columnIndex) {
return values.get(columnIndex);
}

@Override
protected Struct getStructInternal(int columnIndex) {
return values.get(columnIndex).getStruct();
Expand Down
Expand Up @@ -132,6 +132,16 @@ public interface StructReader {
/** Returns the value of a non-{@code NULL} column with type {@link Type#date()}. */
Date getDate(String columnName);

/** Returns the value of a nullable column as a {@link Value}. */
default Value getValue(int columnIndex) {
throw new UnsupportedOperationException("method should be overwritten");
}

/** Returns the value of a nullable column as a {@link Value}. */
default Value getValue(String columnName) {
throw new UnsupportedOperationException("method should be overwritten");
}

/**
* Returns the value of a non-{@code NULL} column with type {@code Type.array(Type.bool())}.
*
Expand Down
Expand Up @@ -543,7 +543,7 @@ private Value() {}
*
* @throws IllegalStateException if {@code isNull()} or the value is not of the expected type
*/
abstract List<Struct> getStructArray();
public abstract List<Struct> getStructArray();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@olavloite I made this method public. It surprising me that this was not public before, since users can SELECT ARRAY(SELECT STRUCT ...) and would not be able to get the results.


@Override
public String toString() {
Expand Down
Expand Up @@ -23,6 +23,7 @@
import com.google.cloud.spanner.SpannerException;
import com.google.cloud.spanner.Struct;
import com.google.cloud.spanner.Type;
import com.google.cloud.spanner.Value;
import com.google.common.base.Preconditions;
import com.google.spanner.v1.ResultSetStats;
import java.math.BigDecimal;
Expand Down Expand Up @@ -231,6 +232,18 @@ public Date getDate(String columnName) {
return delegate.getDate(columnName);
}

@Override
public Value getValue(int columnIndex) {
Preconditions.checkState(nextCalledByClient, MISSING_NEXT_CALL);
return delegate.getValue(columnIndex);
}

@Override
public Value getValue(String columnName) {
Preconditions.checkState(nextCalledByClient, MISSING_NEXT_CALL);
return delegate.getValue(columnName);
}

@Override
public boolean[] getBooleanArray(int columnIndex) {
Preconditions.checkState(nextCalledByClient, MISSING_NEXT_CALL);
Expand Down
Expand Up @@ -25,6 +25,7 @@
import com.google.cloud.spanner.SpannerExceptionFactory;
import com.google.cloud.spanner.Struct;
import com.google.cloud.spanner.Type;
import com.google.cloud.spanner.Value;
import com.google.common.base.Preconditions;
import com.google.spanner.v1.ResultSetStats;
import java.math.BigDecimal;
Expand Down Expand Up @@ -231,6 +232,18 @@ public Date getDate(String columnName) {
return delegate.getDate(columnName);
}

@Override
public Value getValue(int columnIndex) {
checkClosed();
return delegate.getValue(columnIndex);
}

@Override
public Value getValue(String columnName) {
checkClosed();
return delegate.getValue(columnName);
}

@Override
public boolean[] getBooleanArray(int columnIndex) {
checkClosed();
Expand Down