use of org.apache.calcite.avatica.util.ByteString in project calcite by apache.
the class RexProgramTest method testSimplifyCastLiteral.
@Test
public void testSimplifyCastLiteral() {
final List<RexLiteral> literals = new ArrayList<>();
literals.add(rexBuilder.makeExactLiteral(BigDecimal.ONE, typeFactory.createSqlType(SqlTypeName.INTEGER)));
literals.add(rexBuilder.makeExactLiteral(BigDecimal.valueOf(2), typeFactory.createSqlType(SqlTypeName.BIGINT)));
literals.add(rexBuilder.makeExactLiteral(BigDecimal.valueOf(3), typeFactory.createSqlType(SqlTypeName.SMALLINT)));
literals.add(rexBuilder.makeExactLiteral(BigDecimal.valueOf(4), typeFactory.createSqlType(SqlTypeName.TINYINT)));
literals.add(rexBuilder.makeExactLiteral(new BigDecimal("1234"), typeFactory.createSqlType(SqlTypeName.DECIMAL, 4, 0)));
literals.add(rexBuilder.makeExactLiteral(new BigDecimal("123.45"), typeFactory.createSqlType(SqlTypeName.DECIMAL, 5, 2)));
literals.add(rexBuilder.makeApproxLiteral(new BigDecimal("3.1415"), typeFactory.createSqlType(SqlTypeName.REAL)));
literals.add(rexBuilder.makeApproxLiteral(BigDecimal.valueOf(Math.E), typeFactory.createSqlType(SqlTypeName.FLOAT)));
literals.add(rexBuilder.makeApproxLiteral(BigDecimal.valueOf(Math.PI), typeFactory.createSqlType(SqlTypeName.DOUBLE)));
literals.add(rexBuilder.makeLiteral(true));
literals.add(rexBuilder.makeLiteral(false));
literals.add(rexBuilder.makeLiteral("hello world"));
literals.add(rexBuilder.makeLiteral("1969-07-20 12:34:56"));
literals.add(rexBuilder.makeLiteral("1969-07-20"));
literals.add(rexBuilder.makeLiteral("12:34:45"));
literals.add((RexLiteral) rexBuilder.makeLiteral(new ByteString(new byte[] { 1, 2, -34, 0, -128 }), typeFactory.createSqlType(SqlTypeName.BINARY, 5), false));
literals.add(rexBuilder.makeDateLiteral(new DateString(1974, 8, 9)));
literals.add(rexBuilder.makeTimeLiteral(new TimeString(1, 23, 45), 0));
literals.add(rexBuilder.makeTimestampLiteral(new TimestampString(1974, 8, 9, 1, 23, 45), 0));
final Multimap<SqlTypeName, RexLiteral> map = LinkedHashMultimap.create();
for (RexLiteral literal : literals) {
map.put(literal.getTypeName(), literal);
}
final List<RelDataType> types = new ArrayList<>();
types.add(typeFactory.createSqlType(SqlTypeName.INTEGER));
types.add(typeFactory.createSqlType(SqlTypeName.BIGINT));
types.add(typeFactory.createSqlType(SqlTypeName.SMALLINT));
types.add(typeFactory.createSqlType(SqlTypeName.TINYINT));
types.add(typeFactory.createSqlType(SqlTypeName.REAL));
types.add(typeFactory.createSqlType(SqlTypeName.FLOAT));
types.add(typeFactory.createSqlType(SqlTypeName.DOUBLE));
types.add(typeFactory.createSqlType(SqlTypeName.BOOLEAN));
types.add(typeFactory.createSqlType(SqlTypeName.VARCHAR, 10));
types.add(typeFactory.createSqlType(SqlTypeName.CHAR, 5));
types.add(typeFactory.createSqlType(SqlTypeName.VARBINARY, 60));
types.add(typeFactory.createSqlType(SqlTypeName.BINARY, 3));
types.add(typeFactory.createSqlType(SqlTypeName.TIMESTAMP));
types.add(typeFactory.createSqlType(SqlTypeName.TIME));
types.add(typeFactory.createSqlType(SqlTypeName.DATE));
for (RelDataType fromType : types) {
for (RelDataType toType : types) {
if (SqlTypeAssignmentRules.instance(false).canCastFrom(toType.getSqlTypeName(), fromType.getSqlTypeName())) {
for (RexLiteral literal : map.get(fromType.getSqlTypeName())) {
final RexNode cast = rexBuilder.makeCast(toType, literal);
if (cast instanceof RexLiteral) {
assertThat(cast.getType(), is(toType));
// makeCast already simplified
continue;
}
final RexNode simplified = simplify.simplify(cast);
boolean expectedSimplify = literal.getTypeName() != toType.getSqlTypeName() || (literal.getTypeName() == SqlTypeName.CHAR && ((NlsString) literal.getValue()).getValue().length() > toType.getPrecision()) || (literal.getTypeName() == SqlTypeName.BINARY && ((ByteString) literal.getValue()).length() > toType.getPrecision());
boolean couldSimplify = !cast.equals(simplified);
final String reason = (expectedSimplify ? "expected to simplify, but could not: " : "simplified, but did not expect to: ") + cast + " --> " + simplified;
assertThat(reason, couldSimplify, is(expectedSimplify));
}
}
}
}
}
use of org.apache.calcite.avatica.util.ByteString in project calcite by apache.
the class SqlFunctionsTest method testByteString.
@Test
public void testByteString() {
final byte[] bytes = { (byte) 0xAB, (byte) 0xFF };
final ByteString byteString = new ByteString(bytes);
assertEquals(2, byteString.length());
assertEquals("abff", byteString.toString());
assertEquals("abff", byteString.toString(16));
assertEquals("1010101111111111", byteString.toString(2));
final ByteString emptyByteString = new ByteString(new byte[0]);
assertEquals(0, emptyByteString.length());
assertEquals("", emptyByteString.toString());
assertEquals("", emptyByteString.toString(16));
assertEquals("", emptyByteString.toString(2));
assertEquals(emptyByteString, ByteString.EMPTY);
assertEquals("ff", byteString.substring(1, 2).toString());
assertEquals("abff", byteString.substring(0, 2).toString());
assertEquals("", byteString.substring(2, 2).toString());
// Add empty string, get original string back
assertSame(byteString.concat(emptyByteString), byteString);
final ByteString byteString1 = new ByteString(new byte[] { (byte) 12 });
assertEquals("abff0c", byteString.concat(byteString1).toString());
final byte[] bytes3 = { (byte) 0xFF };
final ByteString byteString3 = new ByteString(bytes3);
assertEquals(0, byteString.indexOf(emptyByteString));
assertEquals(-1, byteString.indexOf(byteString1));
assertEquals(1, byteString.indexOf(byteString3));
assertEquals(-1, byteString3.indexOf(byteString));
thereAndBack(bytes);
thereAndBack(emptyByteString.getBytes());
thereAndBack(new byte[] { 10, 0, 29, -80 });
assertThat(ByteString.of("ab12", 16).toString(16), equalTo("ab12"));
assertThat(ByteString.of("AB0001DdeAD3", 16).toString(16), equalTo("ab0001ddead3"));
assertThat(ByteString.of("", 16), equalTo(emptyByteString));
try {
ByteString x = ByteString.of("ABg0", 16);
fail("expected error, got " + x);
} catch (IllegalArgumentException e) {
assertThat(e.getMessage(), equalTo("invalid hex character: g"));
}
try {
ByteString x = ByteString.of("ABC", 16);
fail("expected error, got " + x);
} catch (IllegalArgumentException e) {
assertThat(e.getMessage(), equalTo("hex string has odd length"));
}
final byte[] bytes4 = { 10, 0, 1, -80 };
final ByteString byteString4 = new ByteString(bytes4);
final byte[] bytes5 = { 10, 0, 1, 127 };
final ByteString byteString5 = new ByteString(bytes5);
final ByteString byteString6 = new ByteString(bytes4);
assertThat(byteString4.compareTo(byteString5) > 0, is(true));
assertThat(byteString4.compareTo(byteString6) == 0, is(true));
assertThat(byteString5.compareTo(byteString4) < 0, is(true));
}
use of org.apache.calcite.avatica.util.ByteString in project flink by apache.
the class ExpressionConverter method visit.
@Override
public RexNode visit(ValueLiteralExpression valueLiteral) {
LogicalType type = fromDataTypeToLogicalType(valueLiteral.getOutputDataType());
RexBuilder rexBuilder = relBuilder.getRexBuilder();
FlinkTypeFactory typeFactory = (FlinkTypeFactory) relBuilder.getTypeFactory();
RelDataType relDataType = typeFactory.createFieldTypeFromLogicalType(type);
if (valueLiteral.isNull()) {
return rexBuilder.makeNullLiteral(relDataType);
}
Object value = null;
switch(type.getTypeRoot()) {
case DECIMAL:
case TINYINT:
case SMALLINT:
case INTEGER:
case BIGINT:
case FLOAT:
case DOUBLE:
value = extractValue(valueLiteral, BigDecimal.class);
break;
case VARCHAR:
case CHAR:
value = extractValue(valueLiteral, String.class);
break;
case BINARY:
case VARBINARY:
value = new ByteString(extractValue(valueLiteral, byte[].class));
break;
case INTERVAL_YEAR_MONTH:
// convert to total months
value = BigDecimal.valueOf(extractValue(valueLiteral, Period.class).toTotalMonths());
break;
case INTERVAL_DAY_TIME:
// TODO planner supports only milliseconds precision
// convert to total millis
value = BigDecimal.valueOf(extractValue(valueLiteral, Duration.class).toMillis());
break;
case DATE:
value = DateString.fromDaysSinceEpoch((int) extractValue(valueLiteral, LocalDate.class).toEpochDay());
break;
case TIME_WITHOUT_TIME_ZONE:
// TODO type factory strips the precision, for literals we can be more lenient
// already
// Moreover conversion from long supports precision up to TIME(3) planner does not
// support higher
// precisions
TimeType timeType = (TimeType) type;
int precision = timeType.getPrecision();
relDataType = typeFactory.createSqlType(SqlTypeName.TIME, Math.min(precision, 3));
value = TimeString.fromMillisOfDay(extractValue(valueLiteral, LocalTime.class).get(ChronoField.MILLI_OF_DAY));
break;
case TIMESTAMP_WITHOUT_TIME_ZONE:
LocalDateTime datetime = extractValue(valueLiteral, LocalDateTime.class);
value = fromLocalDateTime(datetime);
break;
case TIMESTAMP_WITH_LOCAL_TIME_ZONE:
// normalize to UTC
Instant instant = extractValue(valueLiteral, Instant.class);
value = fromLocalDateTime(instant.atOffset(ZoneOffset.UTC).toLocalDateTime());
break;
default:
value = extractValue(valueLiteral, Object.class);
if (value instanceof TimePointUnit) {
value = commonToCalcite((TimePointUnit) value);
} else if (value instanceof TimeIntervalUnit) {
value = commonToCalcite((TimeIntervalUnit) value);
}
break;
}
return rexBuilder.makeLiteral(value, relDataType, // RexBuilder#makeCast.
true);
}
use of org.apache.calcite.avatica.util.ByteString in project beam by apache.
the class ZetaSqlCalciteTranslationUtils method toRexNode.
// Value conversion: ZetaSQL => Calcite
public static RexNode toRexNode(Value value, RexBuilder rexBuilder) {
Type type = value.getType();
if (value.isNull()) {
return rexBuilder.makeNullLiteral(toCalciteType(type, true, rexBuilder));
}
switch(type.getKind()) {
case TYPE_INT64:
return rexBuilder.makeExactLiteral(new BigDecimal(value.getInt64Value()), toCalciteType(type, false, rexBuilder));
case TYPE_DOUBLE:
// Cannot simply call makeApproxLiteral() because +inf, -inf, and NaN cannot be represented
// as BigDecimal. So we create wrapper functions here for these three cases such that we can
// later recognize it and customize its unparsing in BeamBigQuerySqlDialect.
double val = value.getDoubleValue();
String wrapperFun = null;
if (val == Double.POSITIVE_INFINITY) {
wrapperFun = BeamBigQuerySqlDialect.DOUBLE_POSITIVE_INF_WRAPPER;
} else if (val == Double.NEGATIVE_INFINITY) {
wrapperFun = BeamBigQuerySqlDialect.DOUBLE_NEGATIVE_INF_WRAPPER;
} else if (Double.isNaN(val)) {
wrapperFun = BeamBigQuerySqlDialect.DOUBLE_NAN_WRAPPER;
}
RelDataType returnType = toCalciteType(type, false, rexBuilder);
if (wrapperFun == null) {
return rexBuilder.makeApproxLiteral(new BigDecimal(val), returnType);
} else if (BeamBigQuerySqlDialect.DOUBLE_NAN_WRAPPER.equals(wrapperFun)) {
// true, which should be false.)
return rexBuilder.makeCall(SqlOperators.createZetaSqlFunction(wrapperFun, returnType.getSqlTypeName()), rexBuilder.makeApproxLiteral(BigDecimal.valueOf(Math.random()), returnType));
} else {
return rexBuilder.makeCall(SqlOperators.createZetaSqlFunction(wrapperFun, returnType.getSqlTypeName()));
}
case TYPE_BOOL:
return rexBuilder.makeLiteral(value.getBoolValue());
case TYPE_STRING:
// If not allow cast, rexBuilder() will only build a literal with CHAR type.
return rexBuilder.makeLiteral(value.getStringValue(), toCalciteType(type, false, rexBuilder), true);
case TYPE_BYTES:
return rexBuilder.makeBinaryLiteral(new ByteString(value.getBytesValue().toByteArray()));
case TYPE_NUMERIC:
// its unparsing in BeamBigQuerySqlDialect.
return rexBuilder.makeCall(SqlOperators.createZetaSqlFunction(BeamBigQuerySqlDialect.NUMERIC_LITERAL_WRAPPER, toCalciteType(type, false, rexBuilder).getSqlTypeName()), rexBuilder.makeExactLiteral(value.getNumericValue(), toCalciteType(type, false, rexBuilder)));
case TYPE_DATE:
return rexBuilder.makeDateLiteral(dateValueToDateString(value));
case TYPE_TIME:
return rexBuilder.makeTimeLiteral(timeValueToTimeString(value), rexBuilder.getTypeFactory().getTypeSystem().getMaxPrecision(SqlTypeName.TIME));
case TYPE_DATETIME:
return rexBuilder.makeTimestampWithLocalTimeZoneLiteral(datetimeValueToTimestampString(value), rexBuilder.getTypeFactory().getTypeSystem().getMaxPrecision(SqlTypeName.TIMESTAMP_WITH_LOCAL_TIME_ZONE));
case TYPE_TIMESTAMP:
return rexBuilder.makeTimestampLiteral(timestampValueToTimestampString(value), rexBuilder.getTypeFactory().getTypeSystem().getMaxPrecision(SqlTypeName.TIMESTAMP));
case TYPE_ARRAY:
return arrayValueToRexNode(value, rexBuilder);
case TYPE_STRUCT:
return structValueToRexNode(value, rexBuilder);
case // internal only, used for DateTimestampPart
TYPE_ENUM:
return enumValueToRexNode(value, rexBuilder);
default:
throw new UnsupportedOperationException("Unknown ZetaSQL type: " + type.getKind().name());
}
}
use of org.apache.calcite.avatica.util.ByteString in project calcite-avatica by apache.
the class TypedValueTest method testProtobufBytesNotSentAsBase64.
@Test
public void testProtobufBytesNotSentAsBase64() {
final byte[] bytes = "asdf".getBytes(UTF_8);
final byte[] b64Bytes = Base64.encodeBytes(bytes).getBytes(UTF_8);
TypedValue tv = TypedValue.ofLocal(Rep.BYTE_STRING, new ByteString(bytes));
// JSON encodes it as base64
assertEquals(new String(b64Bytes, UTF_8), tv.value);
// Get the protobuf variant
Common.TypedValue protoTv = tv.toProto();
Common.Rep protoRep = protoTv.getType();
assertEquals(Common.Rep.BYTE_STRING, protoRep);
// The pb variant should have the native bytes of the original value
com.google.protobuf.ByteString protoByteString = protoTv.getBytesValue();
assertNotNull(protoByteString);
assertArrayEquals(bytes, protoByteString.toByteArray());
// We should have the b64 string as a backwards compatibility feature
assertEquals(new String(b64Bytes, UTF_8), protoTv.getStringValue());
}
Aggregations