Search in sources :

Example 1 with SqlTypeParser

use of io.confluent.ksql.schema.ksql.SqlTypeParser in project ksql by confluentinc.

the class SchemaParser method parse.

public TableElements parse(final String schema) {
    if (schema.trim().isEmpty()) {
        return TableElements.of();
    }
    final SqlBaseLexer lexer = new SqlBaseLexer(new CaseInsensitiveStream(CharStreams.fromString("(" + schema + ")")));
    final CommonTokenStream tokStream = new CommonTokenStream(lexer);
    final SqlBaseParser parser = new SqlBaseParser(tokStream);
    final BaseErrorListener errorListener = new BaseErrorListener() {

        @Override
        public void syntaxError(final Recognizer<?, ?> recognizer, final Object offendingSymbol, final int line, final int charPositionInLine, final String msg, final RecognitionException e) {
            throw new KsqlException(String.format("Error parsing schema \"%s\" at %d:%d: %s", schema, line, charPositionInLine, msg), e);
        }
    };
    lexer.removeErrorListeners();
    lexer.addErrorListener(errorListener);
    parser.removeErrorListeners();
    parser.addErrorListener(errorListener);
    final SqlTypeParser typeParser = SqlTypeParser.create(typeRegistry);
    final List<TableElement> elements = parser.tableElements().tableElement().stream().map(ctx -> new TableElement(getLocation(ctx), ColumnName.of(ParserUtil.getIdentifierText(ctx.identifier())), typeParser.getType(ctx.type()), ParserUtil.getColumnConstraints(ctx.columnConstraints()))).collect(Collectors.toList());
    return TableElements.of(elements);
}
Also used : Recognizer(org.antlr.v4.runtime.Recognizer) ColumnName(io.confluent.ksql.name.ColumnName) ParserUtil.getLocation(io.confluent.ksql.util.ParserUtil.getLocation) CommonTokenStream(org.antlr.v4.runtime.CommonTokenStream) TypeRegistry(io.confluent.ksql.metastore.TypeRegistry) Collectors(java.util.stream.Collectors) TableElement(io.confluent.ksql.parser.tree.TableElement) BaseErrorListener(org.antlr.v4.runtime.BaseErrorListener) List(java.util.List) CharStreams(org.antlr.v4.runtime.CharStreams) RecognitionException(org.antlr.v4.runtime.RecognitionException) Objects.requireNonNull(java.util.Objects.requireNonNull) TableElements(io.confluent.ksql.parser.tree.TableElements) SqlTypeParser(io.confluent.ksql.schema.ksql.SqlTypeParser) KsqlException(io.confluent.ksql.util.KsqlException) ParserUtil(io.confluent.ksql.util.ParserUtil) CommonTokenStream(org.antlr.v4.runtime.CommonTokenStream) BaseErrorListener(org.antlr.v4.runtime.BaseErrorListener) KsqlException(io.confluent.ksql.util.KsqlException) TableElement(io.confluent.ksql.parser.tree.TableElement) Recognizer(org.antlr.v4.runtime.Recognizer) SqlTypeParser(io.confluent.ksql.schema.ksql.SqlTypeParser) RecognitionException(org.antlr.v4.runtime.RecognitionException)

Example 2 with SqlTypeParser

use of io.confluent.ksql.schema.ksql.SqlTypeParser in project ksql by confluentinc.

the class UdtfLoaderTest method shouldNotLoadUdtfWithWrongReturnValue.

@Test
public void shouldNotLoadUdtfWithWrongReturnValue() {
    // Given:
    final MutableFunctionRegistry functionRegistry = new InternalFunctionRegistry();
    final SqlTypeParser typeParser = create(EMPTY);
    final UdtfLoader udtfLoader = new UdtfLoader(functionRegistry, empty(), typeParser, true);
    // When:
    final Exception e = assertThrows(KsqlException.class, () -> udtfLoader.loadUdtfFromClass(UdtfBadReturnValue.class, INTERNAL_PATH));
    // Then:
    assertThat(e.getMessage(), containsString("UDTF functions must return a List. Class io.confluent.ksql" + ".function.UdtfLoaderTest$UdtfBadReturnValue Method badReturn"));
}
Also used : SqlTypeParser(io.confluent.ksql.schema.ksql.SqlTypeParser) KsqlException(io.confluent.ksql.util.KsqlException) Test(org.junit.Test)

Example 3 with SqlTypeParser

use of io.confluent.ksql.schema.ksql.SqlTypeParser in project ksql by confluentinc.

the class UdtfLoaderTest method shouldNotLoadUdtfWithBigDecimalReturnAndNoSchemaProvider.

@Test
public void shouldNotLoadUdtfWithBigDecimalReturnAndNoSchemaProvider() {
    // Given:
    final MutableFunctionRegistry functionRegistry = new InternalFunctionRegistry();
    final SqlTypeParser typeParser = create(EMPTY);
    final UdtfLoader udtfLoader = new UdtfLoader(functionRegistry, empty(), typeParser, true);
    // When:
    final Exception e = assertThrows(KsqlException.class, () -> udtfLoader.loadUdtfFromClass(BigDecimalNoSchemaProvider.class, INTERNAL_PATH));
    // Then:
    assertThat(e.getMessage(), containsString("Cannot load UDF bigDecimalNoSchemaProvider. DECIMAL return type is not supported without an explicit schema"));
}
Also used : SqlTypeParser(io.confluent.ksql.schema.ksql.SqlTypeParser) KsqlException(io.confluent.ksql.util.KsqlException) Test(org.junit.Test)

Example 4 with SqlTypeParser

use of io.confluent.ksql.schema.ksql.SqlTypeParser in project ksql by confluentinc.

the class UdtfLoaderTest method shouldNotLoadUdtfWithRawListReturn.

@Test
public void shouldNotLoadUdtfWithRawListReturn() {
    // Given:
    final MutableFunctionRegistry functionRegistry = new InternalFunctionRegistry();
    final SqlTypeParser typeParser = create(EMPTY);
    final UdtfLoader udtfLoader = new UdtfLoader(functionRegistry, empty(), typeParser, true);
    // When:
    final Exception e = assertThrows(KsqlException.class, () -> udtfLoader.loadUdtfFromClass(RawListReturn.class, INTERNAL_PATH));
    // Then:
    assertThat(e.getMessage(), containsString("UDTF functions must return a parameterized List. Class io.confluent.ksql.function.UdtfLoaderTest$RawListReturn Method badReturn"));
}
Also used : SqlTypeParser(io.confluent.ksql.schema.ksql.SqlTypeParser) KsqlException(io.confluent.ksql.util.KsqlException) Test(org.junit.Test)

Example 5 with SqlTypeParser

use of io.confluent.ksql.schema.ksql.SqlTypeParser in project ksql by confluentinc.

the class FunctionLoaderUtils method handleUdfReturnSchema.

// CHECKSTYLE_RULES.OFF: CyclomaticComplexity
static SchemaProvider handleUdfReturnSchema(final Class theClass, final ParamType javaReturnSchema, final String annotationSchema, final SqlTypeParser parser, final String schemaProviderFunctionName, final String functionName, final boolean isVariadic) {
    // CHECKSTYLE_RULES.ON: CyclomaticComplexity
    final Function<List<SqlArgument>, SqlType> schemaProvider;
    if (!Udf.NO_SCHEMA_PROVIDER.equals(schemaProviderFunctionName)) {
        schemaProvider = handleUdfSchemaProviderAnnotation(schemaProviderFunctionName, theClass, functionName);
    } else if (!Udf.NO_SCHEMA.equals(annotationSchema)) {
        final SqlType sqlType = parser.parse(annotationSchema).getSqlType();
        schemaProvider = args -> sqlType;
    } else if (!GenericsUtil.hasGenerics(javaReturnSchema)) {
        // it is important to do this eagerly and not in the lambda so that
        // we can fail early (when loading the UDF) instead of when the user
        // attempts to use the UDF
        final SqlType sqlType = fromJavaType(javaReturnSchema, functionName);
        schemaProvider = args -> sqlType;
    } else {
        schemaProvider = null;
    }
    return (parameters, arguments) -> {
        if (schemaProvider != null) {
            final SqlType returnType = schemaProvider.apply(arguments);
            if (!(ParamTypes.areCompatible(SqlArgument.of(returnType), javaReturnSchema, false))) {
                throw new KsqlException(String.format("Return type %s of UDF %s does not match the declared " + "return type %s.", returnType, functionName.toUpperCase(), SchemaConverters.functionToSqlConverter().toSqlType(javaReturnSchema)));
            }
            return returnType;
        }
        final Map<GenericType, SqlType> genericMapping = new HashMap<>();
        for (int i = 0; i < Math.min(parameters.size(), arguments.size()); i++) {
            final ParamType schema = parameters.get(i);
            if (schema instanceof LambdaType) {
                if (isVariadic && i == parameters.size() - 1) {
                    throw new KsqlException(String.format("Lambda function %s cannot be variadic.", arguments.get(i).toString()));
                }
                genericMapping.putAll(GenericsUtil.reserveGenerics(schema, arguments.get(i)));
            } else {
                // we resolve any variadic as if it were an array so that the type
                // structure matches the input type
                final SqlType instance = isVariadic && i == parameters.size() - 1 ? SqlTypes.array(arguments.get(i).getSqlTypeOrThrow()) : arguments.get(i).getSqlTypeOrThrow();
                genericMapping.putAll(GenericsUtil.reserveGenerics(schema, SqlArgument.of(instance)));
            }
        }
        return GenericsUtil.applyResolved(javaReturnSchema, genericMapping);
    };
}
Also used : IntStream(java.util.stream.IntStream) Arrays(java.util.Arrays) UdfParameter(io.confluent.ksql.function.udf.UdfParameter) ParamType(io.confluent.ksql.function.types.ParamType) HashMap(java.util.HashMap) Function(java.util.function.Function) UdfUtil(io.confluent.ksql.execution.function.UdfUtil) Parameter(java.lang.reflect.Parameter) Map(java.util.Map) SqlTypeParser(io.confluent.ksql.schema.ksql.SqlTypeParser) SchemaConverters(io.confluent.ksql.schema.ksql.SchemaConverters) SqlType(io.confluent.ksql.schema.ksql.types.SqlType) Method(java.lang.reflect.Method) Udf(io.confluent.ksql.function.udf.Udf) SqlArgument(io.confluent.ksql.schema.ksql.SqlArgument) ParamTypes(io.confluent.ksql.function.types.ParamTypes) Collectors(java.util.stream.Collectors) InvocationTargetException(java.lang.reflect.InvocationTargetException) LambdaType(io.confluent.ksql.function.types.LambdaType) List(java.util.List) Type(java.lang.reflect.Type) UdfSchemaProvider(io.confluent.ksql.function.udf.UdfSchemaProvider) KsqlException(io.confluent.ksql.util.KsqlException) Optional(java.util.Optional) VisibleForTesting(com.google.common.annotations.VisibleForTesting) SqlTypes(io.confluent.ksql.schema.ksql.types.SqlTypes) GenericType(io.confluent.ksql.function.types.GenericType) LambdaType(io.confluent.ksql.function.types.LambdaType) List(java.util.List) SqlType(io.confluent.ksql.schema.ksql.types.SqlType) KsqlException(io.confluent.ksql.util.KsqlException) HashMap(java.util.HashMap) Map(java.util.Map) ParamType(io.confluent.ksql.function.types.ParamType)

Aggregations

SqlTypeParser (io.confluent.ksql.schema.ksql.SqlTypeParser)6 KsqlException (io.confluent.ksql.util.KsqlException)5 Test (org.junit.Test)3 List (java.util.List)2 Collectors (java.util.stream.Collectors)2 VisibleForTesting (com.google.common.annotations.VisibleForTesting)1 UdfUtil (io.confluent.ksql.execution.function.UdfUtil)1 InternalFunctionRegistry (io.confluent.ksql.function.InternalFunctionRegistry)1 UdfLoader (io.confluent.ksql.function.UdfLoader)1 UdtfLoader (io.confluent.ksql.function.UdtfLoader)1 GenericType (io.confluent.ksql.function.types.GenericType)1 LambdaType (io.confluent.ksql.function.types.LambdaType)1 ParamType (io.confluent.ksql.function.types.ParamType)1 ParamTypes (io.confluent.ksql.function.types.ParamTypes)1 Udf (io.confluent.ksql.function.udf.Udf)1 UdfParameter (io.confluent.ksql.function.udf.UdfParameter)1 UdfSchemaProvider (io.confluent.ksql.function.udf.UdfSchemaProvider)1 MetaStoreImpl (io.confluent.ksql.metastore.MetaStoreImpl)1 TypeRegistry (io.confluent.ksql.metastore.TypeRegistry)1 MetricCollectors (io.confluent.ksql.metrics.MetricCollectors)1