Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.google.cloud.spark.spanner.binding;
Comment thread
stevelordbq marked this conversation as resolved.

public class GoogleSqlParameterRegistry extends ParameterRegistry {
@Override
public ParameterRef nextParameter() {
counter++;
final String name = "p" + String.valueOf(counter);
return new ParameterRef(name, name);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.google.cloud.spark.spanner.binding;

public class ParameterRef {
private final String bindName;
private final String sqlName;

public ParameterRef(String bindName, String sqlName) {
this.bindName = bindName;
this.sqlName = sqlName;
}

public String getBindName() {
return bindName;
}

public String getSqlName() {
return sqlName;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.google.cloud.spark.spanner.binding;

import com.google.cloud.spanner.Dialect;

public abstract class ParameterRegistry {
protected int counter = 0;

public abstract ParameterRef nextParameter();

public static ParameterRegistry create(Dialect dialect) {
switch (dialect) {
case POSTGRESQL:
return new PostgresSqlParameterRegistry();
case GOOGLE_STANDARD_SQL:
return new GoogleSqlParameterRegistry();
}
throw new IllegalArgumentException("Unsupported dialect: " + dialect);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.google.cloud.spark.spanner.binding;

public class PostgresSqlParameterRegistry extends ParameterRegistry {
@Override
public ParameterRef nextParameter() {
counter++;
final String name = String.valueOf(counter);
return new ParameterRef("p" + name, name);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package com.google.cloud.spark.spanner.binding;

import com.google.cloud.spanner.Statement;
import com.google.cloud.spanner.Type;
import com.google.cloud.spark.spanner.planning.expression.LiteralExpr;
import java.math.BigDecimal;
import org.apache.spark.sql.types.DataType;
import org.apache.spark.sql.types.DataTypes;
import org.apache.spark.sql.types.DecimalType;

public final class SpannerTypeBinder {

public static void bind(Statement.Builder builder, String parameter, LiteralExpr literal) {

Object value = literal.getValue();
DataType type = literal.getSparkType();

if (value == null) {
builder.bind(parameter).to(mapToSpannerType(type), (com.google.cloud.spanner.Struct) null);
return;
}

if (type instanceof DecimalType) {
Comment thread
stevelordbq marked this conversation as resolved.
BigDecimal bd = (BigDecimal) value;
// Spanner NUMERIC validation: precision <= 38, scale <= 9
if (bd.precision() <= 38 && bd.scale() <= 9) {
builder.bind(parameter).to(bd);
} else {
throw new IllegalArgumentException("Decimal out of Spanner NUMERIC range");
}
Comment thread
stevelordbq marked this conversation as resolved.
} else if (type.sameType(DataTypes.StringType)) {
builder.bind(parameter).to((String) value);
} else if (type.sameType(DataTypes.LongType)) {
builder.bind(parameter).to((Long) value);
} else if (type.sameType(DataTypes.BooleanType)) {
builder.bind(parameter).to((Boolean) value);
} else if (type.sameType(DataTypes.IntegerType)) {
builder.bind(parameter).to(((Integer) value).longValue());
} else if (type.sameType(DataTypes.ShortType)) {
builder.bind(parameter).to(((Short) value).longValue());
} else if (type.sameType(DataTypes.ByteType)) {
builder.bind(parameter).to(((Byte) value).longValue());
} else if (type.sameType(DataTypes.DoubleType)) {
builder.bind(parameter).to((Double) value);
} else if (type.sameType(DataTypes.FloatType)) {
builder.bind(parameter).to(((Float) value).doubleValue());
} else {
throw new UnsupportedOperationException("Unsupported type: " + type);
}
}

private static Type mapToSpannerType(DataType type) {
if (type instanceof DecimalType) {
return Type.numeric();
} else if (type.sameType(DataTypes.StringType)) {
return Type.string();
} else if (type.sameType(DataTypes.LongType) || type.sameType(DataTypes.IntegerType)) {
return Type.int64();
} else if (type.sameType(DataTypes.BooleanType)) {
return Type.bool();
} else if (type.sameType(DataTypes.DoubleType)) {
return Type.float64();
} else {
Comment thread
stevelordbq marked this conversation as resolved.
throw new UnsupportedOperationException(
"Unsupported Spark type for Spanner null mapping: " + type);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.google.cloud.spark.spanner.planning.expression;

public final class AndExpr implements BoolExpr {
private final BoolExpr left;
private final BoolExpr right;

public AndExpr(BoolExpr left, BoolExpr right) {
this.left = left;
this.right = right;
}

public BoolExpr getLeft() {
return left;
}

public BoolExpr getRight() {
return right;
}

@Override
public <T> T accept(SpannerExprVisitor<T> visitor) {
return visitor.visit(this);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package com.google.cloud.spark.spanner.planning.expression;

public interface BoolExpr extends SpannerExpr {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.google.cloud.spark.spanner.planning.expression;

import org.apache.spark.sql.types.DataType;

public final class ColumnExpr implements ValueExpr {
private final String columnName;
private final DataType sparkType;

public boolean isNullable() {
return nullable;
}

public DataType getSparkType() {
return sparkType;
}

private final boolean nullable;

public ColumnExpr(String columnName, DataType sparkType, boolean nullable) {
this.columnName = columnName;
this.sparkType = sparkType;
this.nullable = nullable;
}

public String getColumnName() {
return columnName;
}

@Override
public <T> T accept(SpannerExprVisitor<T> visitor) {
return visitor.visit(this);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.google.cloud.spark.spanner.planning.expression;

public final class ContainsExpr implements BoolExpr {
private final ColumnExpr left;
private final LiteralExpr value;

public ContainsExpr(ColumnExpr left, LiteralExpr value) {
this.left = left;
this.value = value;
}

public ColumnExpr getLeft() {
return left;
}

public LiteralExpr getValue() {
return value;
}

@Override
public <T> T accept(SpannerExprVisitor<T> visitor) {
return visitor.visit(this);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.google.cloud.spark.spanner.planning.expression;

public final class EndsWithExpr implements BoolExpr {
private final ColumnExpr left;
private final LiteralExpr suffix;

public EndsWithExpr(ColumnExpr left, LiteralExpr suffix) {
this.left = left;
this.suffix = suffix;
}

public ColumnExpr getLeft() {
return left;
}

public LiteralExpr getSuffix() {
return suffix;
}

@Override
public <T> T accept(SpannerExprVisitor<T> visitor) {
return visitor.visit(this);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.google.cloud.spark.spanner.planning.expression;

public final class EqExpr implements BoolExpr {
private final ValueExpr left;
private final ValueExpr right;

public EqExpr(ValueExpr left, ValueExpr right) {
this.left = left;
this.right = right;
}

public ValueExpr getLeft() {
return left;
}

public ValueExpr getRight() {
return right;
}

@Override
public <T> T accept(SpannerExprVisitor<T> visitor) {
return visitor.visit(this);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.google.cloud.spark.spanner.planning.expression;

public final class EqNullSafeExpr implements BoolExpr {
private final ValueExpr left;
private final ValueExpr right;

public EqNullSafeExpr(ValueExpr left, ValueExpr right) {
this.left = left;
this.right = right;
}

public ValueExpr getLeft() {
return left;
}

public ValueExpr getRight() {
return right;
}

@Override
public <T> T accept(SpannerExprVisitor<T> visitor) {
return visitor.visit(this);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.google.cloud.spark.spanner.planning.expression;

public final class GtExpr implements BoolExpr {
private final ValueExpr left;
private final ValueExpr right;

public GtExpr(ValueExpr left, ValueExpr right) {
this.left = left;
this.right = right;
}

public ValueExpr getLeft() {
return left;
}

public ValueExpr getRight() {
return right;
}

@Override
public <T> T accept(SpannerExprVisitor<T> visitor) {
return visitor.visit(this);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.google.cloud.spark.spanner.planning.expression;

public final class GteExpr implements BoolExpr {
private final ValueExpr left;
private final ValueExpr right;

public GteExpr(ValueExpr left, ValueExpr right) {
this.left = left;
this.right = right;
}

public ValueExpr getLeft() {
return left;
}

public ValueExpr getRight() {
return right;
}

@Override
public <T> T accept(SpannerExprVisitor<T> visitor) {
return visitor.visit(this);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.google.cloud.spark.spanner.planning.expression;

import java.util.List;

public final class InExpr implements BoolExpr {
private final ColumnExpr left;
private final List<LiteralExpr> values;

public InExpr(ColumnExpr left, List<LiteralExpr> values) {
this.left = left;
this.values = values;
}

public ColumnExpr getLeft() {
return left;
}

public List<LiteralExpr> getValues() {
return values;
}

@Override
public <T> T accept(SpannerExprVisitor<T> visitor) {
return visitor.visit(this);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.google.cloud.spark.spanner.planning.expression;

public final class IsNotNullExpr implements BoolExpr {
private final ValueExpr value;

public IsNotNullExpr(ValueExpr value) {
this.value = value;
}

public ValueExpr getValue() {
return value;
}

@Override
public <T> T accept(SpannerExprVisitor<T> visitor) {
return visitor.visit(this);
}
}
Loading