-
Notifications
You must be signed in to change notification settings - Fork 1k
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: allow for decimals to be used as input types for UDFs #3217
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -126,7 +126,7 @@ protected String visitBytes(final Schema schema) { | |
+ DecimalUtil.scale(schema) + ")"; | ||
} | ||
|
||
throw new KsqlException("Cannot format bytes type: " + schema); | ||
return "BYTES"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's still the case that the only bytes type we currently support is Decimals, right? I'm having trouble understanding why this change is necessary (besides the pretty error message in UdfIndexTest#shouldNotFindArbitraryBytesTypes`). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. just the pretty error message - if you can't find a UDF we shouldn't throw "Cannot format bytes type". The other BYTES type that we support is also the way we represent Generics. |
||
} | ||
|
||
private final class Converter implements SchemaWalker.Visitor<String, String> { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,11 +16,13 @@ | |
package io.confluent.ksql.function; | ||
|
||
import com.google.common.collect.ImmutableMap; | ||
import io.confluent.ksql.util.DecimalUtil; | ||
import io.confluent.ksql.util.KsqlException; | ||
import java.lang.reflect.GenericArrayType; | ||
import java.lang.reflect.ParameterizedType; | ||
import java.lang.reflect.Type; | ||
import java.lang.reflect.TypeVariable; | ||
import java.math.BigDecimal; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.function.Supplier; | ||
|
@@ -40,6 +42,10 @@ public final class UdfUtil { | |
.put(long.class, SchemaBuilder::int64) | ||
.put(Double.class, () -> SchemaBuilder.float64().optional()) | ||
.put(double.class, SchemaBuilder::float64) | ||
// from the UDF perspective, all Decimal schemas are the same (BigDecimal) in Java | ||
// so we arbitrarily choose DECIMAL(1,0). if we migrate to use a type system dedicated | ||
// for UDFs, we can update this to be a "generic decimal" | ||
.put(BigDecimal.class, () -> DecimalUtil.builder(1, 0).optional()) | ||
.build(); | ||
|
||
private UdfUtil() { | ||
|
@@ -93,7 +99,9 @@ static Schema getSchemaFromType(final Type type, final String name, final String | |
schema = GenericsUtil.generic(((TypeVariable) type).getName()); | ||
} else { | ||
schema = typeToSchema.getOrDefault(type, () -> handleParametrizedType(type)).get(); | ||
schema.name(name); | ||
if (schema.name() == null) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this change necessary? (Why would the schema already have a name at this point?) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is something that I feel like we should change in the long run, but decimals are defined by their schema name (they all have There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, my bad. I even followed the Decimal schema builder code through but somehow missed it was setting the name. Thanks for the explanations! |
||
schema.name(name); | ||
} | ||
} | ||
|
||
schema.doc(doc); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
/* | ||
* Copyright 2019 Confluent Inc. | ||
* | ||
* Licensed under the Confluent Community License (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.confluent.io/confluent-community-license | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
* WARRANTIES OF ANY KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations under the License. | ||
*/ | ||
|
||
package io.confluent.ksql.function.udf.math; | ||
|
||
import io.confluent.ksql.function.udf.Udf; | ||
import io.confluent.ksql.function.udf.UdfDescription; | ||
import io.confluent.ksql.function.udf.UdfParameter; | ||
import java.math.BigDecimal; | ||
|
||
@UdfDescription(name = "Floor", description = Floor.DESCRIPTION) | ||
public class Floor { | ||
|
||
static final String DESCRIPTION = "Returns the largest integer less than or equal to the " | ||
+ "specified numeric expression. NOTE: for backwards compatibility, this returns a DOUBLE " | ||
+ "that has a mantissa of zero."; | ||
|
||
|
||
@Udf | ||
public Double floor(@UdfParameter final Integer val) { | ||
return (val == null) ? null : Math.floor(val); | ||
} | ||
|
||
@Udf | ||
public Double floor(@UdfParameter final Long val) { | ||
return (val == null) ? null : Math.floor(val); | ||
} | ||
|
||
@Udf | ||
public Double floor(@UdfParameter final Double val) { | ||
return (val == null) ? null : Math.floor(val); | ||
} | ||
|
||
@Udf | ||
public Double floor(@UdfParameter final BigDecimal val) { | ||
return (val == null) ? null : Math.floor(val.doubleValue()); | ||
} | ||
|
||
} |
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it only the decimal type that may contain parameters in their schemas? (Trying to understand whether removing this portion of the check is safe.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
at the moment yes - it's the only one that we use that has parameters. I think in general it makes sense to defer the parameter to check to the
CUSTOM_SCHEMA_EQ
instead of checking that they are the same.