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: support float32 type #2894

Merged
merged 28 commits into from
Feb 28, 2024
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
1d64140
feat: float32 changes with unit and integration tests
arawind Dec 1, 2023
5a7fdc2
Merge branch 'main' into float32-v2
arawind Feb 15, 2024
1358bbb
Undo the changes to GceTestEnvConfig
arawind Feb 16, 2024
74b01e5
Update formatting and clirr
arawind Feb 16, 2024
6789155
Update the hashCode logic to account for NaN equality
arawind Feb 16, 2024
f1dbc8f
Prevent FLOAT32 integration tests from running on emulator and produc…
arawind Feb 19, 2024
5b493fa
Add a kokoro presubmit workflow to run on cloud-devel.
arawind Feb 20, 2024
80f80a9
Prevent FLOAT32 schema from being added if the env is not cloud-devel
arawind Feb 20, 2024
924ef75
Merge branch 'main' into float32-v2
arawind Feb 20, 2024
253c5f1
Merge branch 'main' into float32-v2
arawind Feb 22, 2024
fac44f0
Revert "Add a kokoro presubmit workflow to run on cloud-devel."
arawind Feb 22, 2024
391f735
Merge branch 'main' into float32-v2
arawind Feb 22, 2024
3e63abd
Fix integration tests for FLOAT32
arawind Feb 23, 2024
b64e627
Update float32UntypedParameters test to work with PG dialect too
arawind Feb 23, 2024
e18fd3f
Remove FLOAT32 changes in CreateMusicTables.sql as the type isn't ful…
arawind Feb 23, 2024
202b10c
🦉 Updates from OwlBot post-processor
gcf-owl-bot[bot] Feb 23, 2024
34a10e2
Merge branch 'float32-v2' of github.com:arawind/java-spanner into flo…
arawind Feb 23, 2024
fda3987
Split the parameters test in ITQueryTest into supported + currently-u…
arawind Feb 23, 2024
dbd12a9
Merge branch 'main' into float32-v2
arawind Feb 23, 2024
646e6eb
Minor changes in comments
arawind Feb 23, 2024
2988656
Split the Mutation.isNaN method to make it more readable
arawind Feb 23, 2024
738916c
Merge branch 'main' into float32-v2
arawind Feb 23, 2024
187182b
test: added some additional tests
olavloite Feb 23, 2024
7543083
Merge branch 'main' into float32-v2
arawind Feb 25, 2024
1057826
Update to resolve comments on PR#2894.
arawind Feb 25, 2024
dedf17e
Merge branch 'main' into float32-v2
arawind Feb 28, 2024
2dfe0df
Un-ignore the skipped FLOAT32 tests as the backend fixes have been de…
arawind Feb 28, 2024
8f6e21f
Un-ignore the float32 tests in ITQueryTest
arawind Feb 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
61 changes: 59 additions & 2 deletions google-cloud-spanner/clirr-ignored-differences.xml
Expand Up @@ -506,6 +506,63 @@
<method>com.google.cloud.spanner.connection.StatementResult execute(com.google.cloud.spanner.Statement, java.util.Set)</method>
</difference>

<!-- FLOAT32 -->
<difference>
<differenceType>7013</differenceType>
<className>com/google/cloud/spanner/AbstractStructReader</className>
<method>float[] getFloatArrayInternal(int)</method>
</difference>
<difference>
<differenceType>7013</differenceType>
<className>com/google/cloud/spanner/AbstractStructReader</className>
<method>float getFloatInternal(int)</method>
</difference>
<difference>
<differenceType>7013</differenceType>
<className>com/google/cloud/spanner/AbstractStructReader</className>
<method>java.util.List getFloatListInternal(int)</method>
</difference>
<difference>
<differenceType>7012</differenceType>
<className>com/google/cloud/spanner/StructReader</className>
<method>float getFloat(int)</method>
</difference>
<difference>
<differenceType>7012</differenceType>
<className>com/google/cloud/spanner/StructReader</className>
<method>float getFloat(java.lang.String)</method>
</difference>
<difference>
<differenceType>7012</differenceType>
<className>com/google/cloud/spanner/StructReader</className>
<method>float[] getFloatArray(int)</method>
</difference>
<difference>
<differenceType>7012</differenceType>
<className>com/google/cloud/spanner/StructReader</className>
<method>float[] getFloatArray(java.lang.String)</method>
</difference>
<difference>
<differenceType>7012</differenceType>
<className>com/google/cloud/spanner/StructReader</className>
<method>java.util.List getFloatList(int)</method>
</difference>
<difference>
<differenceType>7012</differenceType>
<className>com/google/cloud/spanner/StructReader</className>
<method>java.util.List getFloatList(java.lang.String)</method>
</difference>
<difference>
<differenceType>7013</differenceType>
<className>com/google/cloud/spanner/Value</className>
<method>float getFloat32()</method>
</difference>
<difference>
<differenceType>7013</differenceType>
<className>com/google/cloud/spanner/Value</className>
<method>java.util.List getFloat32Array()</method>
</difference>

<!-- (Internal change, use stream timeout) -->
<difference>
<differenceType>7012</differenceType>
Expand Down Expand Up @@ -569,7 +626,7 @@
<method>void setSpan(io.opencensus.trace.Span)</method>
<to>void setSpan(com.google.cloud.spanner.ISpan)</to>
</difference>

<!-- Added DirectedReadOptions -->
<difference>
<differenceType>7012</differenceType>
Expand All @@ -580,5 +637,5 @@
<differenceType>7012</differenceType>
<className>com/google/cloud/spanner/connection/Connection</className>
<method>void setDirectedRead(com.google.spanner.v1.DirectedReadOptions)</method>
</difference>
</difference>
</differences>
Expand Up @@ -173,16 +173,44 @@ static double valueProtoToFloat64(com.google.protobuf.Value proto) {
return proto.getNumberValue();
}

static float valueProtoToFloat32(com.google.protobuf.Value proto) {
if (proto.getKindCase() == KindCase.STRING_VALUE) {
switch (proto.getStringValue()) {
case "-Infinity":
return Float.NEGATIVE_INFINITY;
case "Infinity":
return Float.POSITIVE_INFINITY;
case "NaN":
return Float.NaN;
default:
// Fall-through to handling below to produce an error.
}
}
if (proto.getKindCase() != KindCase.NUMBER_VALUE) {
throw newSpannerException(
ErrorCode.INTERNAL,
"Invalid value for column type "
+ Type.float32()
+ " expected NUMBER_VALUE or STRING_VALUE with value one of"
+ " \"Infinity\", \"-Infinity\", or \"NaN\" but was "
+ proto.getKindCase()
+ (proto.getKindCase() == KindCase.STRING_VALUE
? " with value \"" + proto.getStringValue() + "\""
: ""));
}
return (float) proto.getNumberValue();
}

static NullPointerException throwNotNull(int columnIndex) {
throw new NullPointerException(
"Cannot call array getter for column " + columnIndex + " with null elements");
}

/**
* Memory-optimized base class for {@code ARRAY<INT64>} and {@code ARRAY<FLOAT64>} types. Both of
* these involve conversions from the type yielded by JSON parsing, which are {@code String} and
* {@code BigDecimal} respectively. Rather than construct new wrapper objects for each array
* element, we use primitive arrays and a {@code BitSet} to track nulls.
* Memory-optimized base class for {@code ARRAY<INT64>}, {@code ARRAY<FLOAT32>} and {@code
* ARRAY<FLOAT64>} types. All of these involve conversions from the type yielded by JSON parsing,
* which are {@code String} and {@code BigDecimal} respectively. Rather than construct new wrapper
* objects for each array element, we use primitive arrays and a {@code BitSet} to track nulls.
*/
abstract static class PrimitiveArray<T, A> extends AbstractList<T> {
private final A data;
Expand Down Expand Up @@ -264,6 +292,31 @@ Long get(long[] array, int i) {
}
}

static class Float32Array extends PrimitiveArray<Float, float[]> {
Float32Array(ListValue protoList) {
super(protoList);
}

Float32Array(float[] data, BitSet nulls) {
super(data, nulls, data.length);
}

@Override
float[] newArray(int size) {
return new float[size];
}

@Override
void setProto(float[] array, int i, com.google.protobuf.Value protoValue) {
array[i] = valueProtoToFloat32(protoValue);
}

@Override
Float get(float[] array, int i) {
return array[i];
}
}

static class Float64Array extends PrimitiveArray<Double, double[]> {
Float64Array(ListValue protoList) {
super(protoList);
Expand Down Expand Up @@ -306,6 +359,11 @@ protected long getLongInternal(int columnIndex) {
return currRow().getLongInternal(columnIndex);
}

@Override
protected float getFloatInternal(int columnIndex) {
return currRow().getFloatInternal(columnIndex);
}

@Override
protected double getDoubleInternal(int columnIndex) {
return currRow().getDoubleInternal(columnIndex);
Expand Down Expand Up @@ -382,6 +440,16 @@ protected List<Long> getLongListInternal(int columnIndex) {
return currRow().getLongListInternal(columnIndex);
}

@Override
protected float[] getFloatArrayInternal(int columnIndex) {
return currRow().getFloatArrayInternal(columnIndex);
}

@Override
protected List<Float> getFloatListInternal(int columnIndex) {
return currRow().getFloatListInternal(columnIndex);
}

@Override
protected double[] getDoubleArrayInternal(int columnIndex) {
return currRow().getDoubleArrayInternal(columnIndex);
Expand Down
Expand Up @@ -43,6 +43,8 @@ public abstract class AbstractStructReader implements StructReader {

protected abstract long getLongInternal(int columnIndex);

protected abstract float getFloatInternal(int columnIndex);
arawind marked this conversation as resolved.
Show resolved Hide resolved

protected abstract double getDoubleInternal(int columnIndex);

protected abstract BigDecimal getBigDecimalInternal(int columnIndex);
Expand Down Expand Up @@ -94,6 +96,10 @@ protected Value getValueInternal(int columnIndex) {

protected abstract List<Long> getLongListInternal(int columnIndex);

protected abstract float[] getFloatArrayInternal(int columnIndex);

protected abstract List<Float> getFloatListInternal(int columnIndex);

protected abstract double[] getDoubleArrayInternal(int columnIndex);

protected abstract List<Double> getDoubleListInternal(int columnIndex);
Expand Down Expand Up @@ -164,6 +170,19 @@ public long getLong(String columnName) {
return getLongInternal(columnIndex);
}

@Override
public float getFloat(int columnIndex) {
checkNonNullOfType(columnIndex, Type.float32(), columnIndex);
return getFloatInternal(columnIndex);
}

@Override
public float getFloat(String columnName) {
int columnIndex = getColumnIndex(columnName);
checkNonNullOfType(columnIndex, Type.float32(), columnName);
return getFloatInternal(columnIndex);
}

@Override
public double getDouble(int columnIndex) {
checkNonNullOfType(columnIndex, Type.float64(), columnIndex);
Expand Down Expand Up @@ -368,6 +387,32 @@ public List<Long> getLongList(String columnName) {
return getLongListInternal(columnIndex);
}

@Override
public float[] getFloatArray(int columnIndex) {
checkNonNullOfType(columnIndex, Type.array(Type.float32()), columnIndex);
return getFloatArrayInternal(columnIndex);
}

@Override
public float[] getFloatArray(String columnName) {
int columnIndex = getColumnIndex(columnName);
checkNonNullOfType(columnIndex, Type.array(Type.float32()), columnName);
return getFloatArrayInternal(columnIndex);
}

@Override
public List<Float> getFloatList(int columnIndex) {
checkNonNullOfType(columnIndex, Type.array(Type.float32()), columnIndex);
return getFloatListInternal(columnIndex);
}

@Override
public List<Float> getFloatList(String columnName) {
int columnIndex = getColumnIndex(columnName);
checkNonNullOfType(columnIndex, Type.array(Type.float32()), columnName);
return getFloatListInternal(columnIndex);
}

@Override
public double[] getDoubleArray(int columnIndex) {
checkNonNullOfType(columnIndex, Type.array(Type.float64()), columnIndex);
Expand Down
Expand Up @@ -125,6 +125,18 @@ public long getLong(String columnName) {
return delegate.get().getLong(columnName);
}

@Override
public float getFloat(int columnIndex) {
checkValidState();
return delegate.get().getFloat(columnIndex);
}

@Override
public float getFloat(String columnName) {
checkValidState();
return delegate.get().getFloat(columnName);
}

@Override
public double getDouble(int columnIndex) {
checkValidState();
Expand Down Expand Up @@ -267,6 +279,30 @@ public List<Long> getLongList(String columnName) {
return delegate.get().getLongList(columnName);
}

@Override
public float[] getFloatArray(int columnIndex) {
checkValidState();
return delegate.get().getFloatArray(columnIndex);
}

@Override
public float[] getFloatArray(String columnName) {
checkValidState();
return delegate.get().getFloatArray(columnName);
}

@Override
public List<Float> getFloatList(int columnIndex) {
checkValidState();
return delegate.get().getFloatList(columnIndex);
}

@Override
public List<Float> getFloatList(String columnName) {
checkValidState();
return delegate.get().getFloatList(columnName);
}

@Override
public double[] getDoubleArray(int columnIndex) {
checkValidState();
Expand Down