From 6c907c077004abfe3d88b9e16c1d75483f2218f1 Mon Sep 17 00:00:00 2001 From: Anastasiia Sergienko Date: Wed, 17 Mar 2021 13:39:05 +0100 Subject: [PATCH] * #97: Refactored functions tests. * #93: Replaced by {@code}. --- doc/changes/changelog.md | 1 + doc/changes/changes_4.4.1.md | 11 + pom.xml | 2 +- .../datatype/value/IntervalDayToSecond.java | 38 +- .../datatype/value/IntervalYearToMonth.java | 16 +- .../com/exasol/sql/ColumnsDefinition.java | 36 +- src/main/java/com/exasol/sql/ValueTable.java | 6 +- .../java/com/exasol/sql/ValueTableRow.java | 22 +- .../exasol/sql/ddl/create/CreateTable.java | 34 +- .../com/exasol/sql/ddl/drop/DropSchema.java | 2 +- .../com/exasol/sql/ddl/drop/DropTable.java | 4 +- .../dml/insert/AbstractInsertValueTable.java | 14 +- .../exasol/sql/dql/select/LimitClause.java | 2 +- .../com/exasol/sql/dql/select/Select.java | 30 +- .../exasol/sql/expression/ExpressionTerm.java | 2 +- .../expression/comparison/LikeComparison.java | 8 +- .../predicate/BetweenPredicate.java | 14 +- .../sql/expression/predicate/InPredicate.java | 16 +- .../sql/rendering/StringRendererConfig.java | 8 +- .../select/rendering/TestSelectRendering.java | 46 ++- .../function/exasol/AbstractFunctionTest.java | 15 + .../exasol/CastExasolFunctionTest.java | 19 +- .../exasol/ExasolAggregateFunctionTest.java | 24 -- .../exasol/ExasolAnalyticFunctionTest.java | 25 -- .../exasol/ExasolScalarFunctionTest.java | 361 ++++++++---------- 25 files changed, 351 insertions(+), 405 deletions(-) create mode 100644 doc/changes/changes_4.4.1.md create mode 100644 src/test/java/com/exasol/sql/expression/function/exasol/AbstractFunctionTest.java delete mode 100644 src/test/java/com/exasol/sql/expression/function/exasol/ExasolAggregateFunctionTest.java delete mode 100644 src/test/java/com/exasol/sql/expression/function/exasol/ExasolAnalyticFunctionTest.java diff --git a/doc/changes/changelog.md b/doc/changes/changelog.md index 30bb32b0..15f83007 100644 --- a/doc/changes/changelog.md +++ b/doc/changes/changelog.md @@ -1,5 +1,6 @@ # Changes +* [4.4.1](changes_4.4.1.md) * [4.4.0](changes_4.4.0.md) * [4.3.0](changes_4.3.0.md) * [4.2.0](changes_4.2.0.md) diff --git a/doc/changes/changes_4.4.1.md b/doc/changes/changes_4.4.1.md new file mode 100644 index 00000000..54ab6134 --- /dev/null +++ b/doc/changes/changes_4.4.1.md @@ -0,0 +1,11 @@ +# SQL Statement Builder 4.4.1, released 2021-??-?? + +Code Name: + +## Refactoring + +* #97: Refactored functions tests. +* #93: Replaced by {@code}. + +## Dependency Updates + diff --git a/pom.xml b/pom.xml index 812e418a..09231bfc 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.exasol sql-statement-builder - 4.4.0 + 4.4.1 Exasol SQL Statement Builder This module provides a Builder for SQL statements that helps creating the correct structure and validates variable parts of the statements. diff --git a/src/main/java/com/exasol/datatype/value/IntervalDayToSecond.java b/src/main/java/com/exasol/datatype/value/IntervalDayToSecond.java index af5d3dee..e9cb9836 100644 --- a/src/main/java/com/exasol/datatype/value/IntervalDayToSecond.java +++ b/src/main/java/com/exasol/datatype/value/IntervalDayToSecond.java @@ -6,8 +6,7 @@ import java.util.regex.Pattern; /** - * This class implements the Exasol-proprietary data type value INTERVAL DAY(x) TO SECONDS(y) - * . It supports + * This class implements the Exasol-proprietary data type value {@code INTERVAL DAY(x) TO SECONDS(y)}. It supports * conversions to and from strings and from milliseconds. * *

@@ -21,12 +20,11 @@ *

  • milliseconds (or fraction of seconds)
  • * *

    - * Since milliseconds are the highest resolution, each interval can also be expressed as a total - * number of milliseconds. - * This is also the recommended way to represent the interval values in other systems which do - * not natively support this data type. + * Since milliseconds are the highest resolution, each interval can also be expressed as a total number of milliseconds. + * This is also the recommended way to represent the interval values in other systems which do not natively support this + * data type. */ -@java.lang.SuppressWarnings("squid:S4784") //regular expression is safe here +@java.lang.SuppressWarnings("squid:S4784") // regular expression is safe here public final class IntervalDayToSecond extends AbstractInterval { private static final int SIGN_MATCHING_GROUP = 1; private static final int DAYS_MATCHING_GROUP = 2; @@ -35,10 +33,10 @@ public final class IntervalDayToSecond extends AbstractInterval { private static final int SECONDS_MATCHING_GROUP = 5; private static final int MILLIS_MATCHING_GROUP = 6; private static final Pattern INTERVAL_PATTERN = Pattern.compile("([-+])?(?:(\\d{1,9})\\s+)?" // days - + "(\\d{1,2})" // hours - + ":(\\d{1,2})" // minutes - + "(?::(\\d{1,2})" // seconds - + "(?:\\.(\\d{1,3}))?)?" // milliseconds + + "(\\d{1,2})" // hours + + ":(\\d{1,2})" // minutes + + "(?::(\\d{1,2})" // seconds + + "(?:\\.(\\d{1,3}))?)?" // milliseconds ); private IntervalDayToSecond(final long value) { @@ -52,7 +50,7 @@ private IntervalDayToSecond(final long absoluteValue, final boolean positive) { @Override public String toString() { return String.format("%s%d %d:%02d:%02d.%03d", getSign(), getDays(), getHours(), getMinutes(), getSeconds(), - getMillis()); + getMillis()); } private long getDays() { @@ -103,7 +101,7 @@ public static IntervalDayToSecond ofMillis(final long value) { * The accepted format is: *

    *

    - * [dddddddd ]hh:mm[:ss[.SSS]] + * {@code [dddddddd ]hh:mm[:ss[.SSS]]} *

    * Where *

    @@ -130,18 +128,18 @@ public static IntervalDayToSecond parse(final String text) { return createIntervalFromParsingResults(matcher); } else { throw new IllegalArgumentException( - "Text \"" + text + "\" cannot be parsed to an INTERVAL. Must match \"" + INTERVAL_PATTERN + "\""); + "Text \"" + text + "\" cannot be parsed to an INTERVAL. Must match \"" + INTERVAL_PATTERN + "\""); } } private static IntervalDayToSecond createIntervalFromParsingResults(final Matcher matcher) { final long parsedValue = MILLIS_PER_DAY * parseMatchingGroupToLong(matcher, DAYS_MATCHING_GROUP) // - + MILLIS_PER_HOUR * parseMatchingGroupToLong(matcher, HOURS_MATCHING_GROUP) // - + MILLIS_PER_MINUTE * parseMatchingGroupToLong(matcher, MINUTES_MATCHING_GROUP) - // - + MILLIS_PER_SECOND * parseMatchingGroupToLong(matcher, SECONDS_MATCHING_GROUP) - // - + parseMatchingGroupToLong(matcher, MILLIS_MATCHING_GROUP); + + MILLIS_PER_HOUR * parseMatchingGroupToLong(matcher, HOURS_MATCHING_GROUP) // + + MILLIS_PER_MINUTE * parseMatchingGroupToLong(matcher, MINUTES_MATCHING_GROUP) + // + + MILLIS_PER_SECOND * parseMatchingGroupToLong(matcher, SECONDS_MATCHING_GROUP) + // + + parseMatchingGroupToLong(matcher, MILLIS_MATCHING_GROUP); final boolean parsedPositive = !"-".equals(matcher.group(SIGN_MATCHING_GROUP)); return new IntervalDayToSecond(parsedValue, parsedPositive); } diff --git a/src/main/java/com/exasol/datatype/value/IntervalYearToMonth.java b/src/main/java/com/exasol/datatype/value/IntervalYearToMonth.java index 5ec6e9f3..4bd8f381 100644 --- a/src/main/java/com/exasol/datatype/value/IntervalYearToMonth.java +++ b/src/main/java/com/exasol/datatype/value/IntervalYearToMonth.java @@ -6,8 +6,7 @@ import java.util.regex.Pattern; /** - * This class implements the Exasol-proprietary data type value INTERVAL YEAR(x) TO MONTH(y) - * . It supports + * This class implements the Exasol-proprietary data type value {@code INTERVAL YEAR(x) TO MONTH(y)}. It supports * conversions to and from strings and from a number of months. * *

    @@ -18,12 +17,11 @@ *

  • months
  • * *

    - * Since months are the highest resolution, each interval can also be expressed as a total number - * of months. This is - * also the recommended way to represent the interval values in other systems which do not - * natively support this data type. + * Since months are the highest resolution, each interval can also be expressed as a total number of months. This is + * also the recommended way to represent the interval values in other systems which do not natively support this data + * type. */ -@java.lang.SuppressWarnings("squid:S4784") //regular expression is safe here +@java.lang.SuppressWarnings("squid:S4784") // regular expression is safe here public final class IntervalYearToMonth extends AbstractInterval { private static final int SIGN_MATCHING_GROUP = 1; private static final int YEARS_MATCHING_GROUP = 2; @@ -98,12 +96,12 @@ public static IntervalYearToMonth parse(final String text) { final Matcher matcher = INTERVAL_PATTERN.matcher(text); if (matcher.matches()) { final long parsedValue = MONTHS_PER_YEAR * parseMatchingGroupToLong(matcher, YEARS_MATCHING_GROUP) // - + parseMatchingGroupToLong(matcher, MONTHS_MATCHING_GROUP); + + parseMatchingGroupToLong(matcher, MONTHS_MATCHING_GROUP); final boolean parsedPositive = !"-".equals(matcher.group(SIGN_MATCHING_GROUP)); return new IntervalYearToMonth(parsedValue, parsedPositive); } else { throw new IllegalArgumentException( - "Text \"" + text + "\" cannot be parsed to an INTERVAL. Must match \"" + INTERVAL_PATTERN + "\""); + "Text \"" + text + "\" cannot be parsed to an INTERVAL. Must match \"" + INTERVAL_PATTERN + "\""); } } } \ No newline at end of file diff --git a/src/main/java/com/exasol/sql/ColumnsDefinition.java b/src/main/java/com/exasol/sql/ColumnsDefinition.java index 20b4a56d..838f4fd1 100644 --- a/src/main/java/com/exasol/sql/ColumnsDefinition.java +++ b/src/main/java/com/exasol/sql/ColumnsDefinition.java @@ -43,7 +43,7 @@ public static Builder builder() { /** * Add a new column to the {@link ColumnsDefinition} * - * @param name name of the column to be added + * @param name name of the column to be added * @param dataType data type of the column to be added */ public void add(final String name, final DataType dataType) { @@ -77,7 +77,7 @@ public static class Builder { * Add boolean column * * @param columnName name of the column to be added - * @return this for fluent programming + * @return {@code this} for fluent programming */ public Builder booleanColumn(final String columnName) { this.columns.add(new Column(null, columnName, new Boolean())); @@ -88,8 +88,8 @@ public Builder booleanColumn(final String columnName) { * Add char column. * * @param columnName name of the column to be added - * @param length pre-defined length for stored strings - * @return this for fluent programming + * @param length pre-defined length for stored strings + * @return {@code this} for fluent programming */ public Builder charColumn(final String columnName, final int length) { this.columns.add(new Column(null, columnName, new Char(length))); @@ -100,8 +100,8 @@ public Builder charColumn(final String columnName, final int length) { * Add varchar column. * * @param columnName name of the column to be added - * @param length pre-defined length for stored strings - * @return this for fluent programming + * @param length pre-defined length for stored strings + * @return {@code this} for fluent programming */ public Builder varcharColumn(final String columnName, final int length) { this.columns.add(new Column(null, columnName, new Varchar(length))); @@ -112,7 +112,7 @@ public Builder varcharColumn(final String columnName, final int length) { * Add date column. * * @param columnName name of the column to be added - * @return this for fluent programming + * @return {@code this} for fluent programming */ public Builder dateColumn(final String columnName) { this.columns.add(new Column(null, columnName, new Date())); @@ -123,9 +123,9 @@ public Builder dateColumn(final String columnName) { * Add decimal column. * * @param columnName name of the column to be added - * @param precision precision for numeric value - * @param scale scale for numeric value - * @return this for fluent programming + * @param precision precision for numeric value + * @param scale scale for numeric value + * @return {@code this} for fluent programming */ public Builder decimalColumn(final String columnName, final int precision, final int scale) { this.columns.add(new Column(null, columnName, new Decimal(precision, scale))); @@ -136,7 +136,7 @@ public Builder decimalColumn(final String columnName, final int precision, final * Add double precision column. * * @param columnName name of the column to be added - * @return this for fluent programming + * @return {@code this} for fluent programming */ public Builder doublePrecisionColumn(final String columnName) { this.columns.add(new Column(null, columnName, new DoublePrecision())); @@ -147,7 +147,7 @@ public Builder doublePrecisionColumn(final String columnName) { * Add timestamp column. * * @param columnName name of the column to be added - * @return this for fluent programming + * @return {@code this} for fluent programming */ public Builder timestampColumn(final String columnName) { this.columns.add(new Column(null, columnName, new Timestamp())); @@ -158,7 +158,7 @@ public Builder timestampColumn(final String columnName) { * Add timestamp with local time zone column. * * @param columnName name of the column to be added - * @return this for fluent programming + * @return {@code this} for fluent programming */ public Builder timestampWithLocalTimeZoneColumn(final String columnName) { this.columns.add(new Column(null, columnName, new TimestampWithLocalTimezone())); @@ -168,10 +168,10 @@ public Builder timestampWithLocalTimeZoneColumn(final String columnName) { /** * Add interval day to second column. * - * @param columnName name of the column to be added - * @param yearPrecision year precision value + * @param columnName name of the column to be added + * @param yearPrecision year precision value * @param millisecondPrecision millisecond precision value - * @return this for fluent programming + * @return {@code this} for fluent programming */ public Builder intervalDayToSecondColumn(final String columnName, final int yearPrecision, final int millisecondPrecision) { @@ -183,9 +183,9 @@ public Builder intervalDayToSecondColumn(final String columnName, final int year /** * Add interval year to month column. * - * @param columnName name of the column to be added + * @param columnName name of the column to be added * @param yearPrecision year precision value - * @return this for fluent programming + * @return {@code this} for fluent programming */ public Builder intervalYearToMonthColumn(final String columnName, final int yearPrecision) { this.columns.add(new Column(null, columnName, new IntervalYearToMonth(yearPrecision))); diff --git a/src/main/java/com/exasol/sql/ValueTable.java b/src/main/java/com/exasol/sql/ValueTable.java index 06347ae4..edc22806 100644 --- a/src/main/java/com/exasol/sql/ValueTable.java +++ b/src/main/java/com/exasol/sql/ValueTable.java @@ -28,7 +28,7 @@ public ValueTable(final Fragment root) { * * @param literals literals to be appended * - * @return this for fluent programming + * @return {@code this} for fluent programming */ public ValueTable appendRow(final String... literals) { this.rows.add(new ValueTableRow(this.root, literals)); @@ -40,7 +40,7 @@ public ValueTable appendRow(final String... literals) { * * @param row row to be appended * - * @return this for fluent programming + * @return {@code this} for fluent programming */ public ValueTable appendRow(final ValueTableRow row) { this.rows.add(row); @@ -179,7 +179,7 @@ public void accept(final ValueTableVisitor visitor) { /** * Set alias for the value table. * - * @param tableNameAlias table name alias + * @param tableNameAlias table name alias * @param columnNameAliases zero or more column names aliases */ public void alias(final String tableNameAlias, final String... columnNameAliases) { diff --git a/src/main/java/com/exasol/sql/ValueTableRow.java b/src/main/java/com/exasol/sql/ValueTableRow.java index e0e983f0..849999ba 100644 --- a/src/main/java/com/exasol/sql/ValueTableRow.java +++ b/src/main/java/com/exasol/sql/ValueTableRow.java @@ -1,8 +1,6 @@ package com.exasol.sql; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; +import java.util.*; import com.exasol.sql.expression.ValueExpression; import com.exasol.sql.expression.literal.*; @@ -89,7 +87,7 @@ public Builder(final Fragment root) { * Add one or more string literals to the row. * * @param values strings to be added - * @return this for fluent programming + * @return {@code this} for fluent programming */ public Builder add(final String... values) { for (final String value : values) { @@ -102,7 +100,7 @@ public Builder add(final String... values) { * Add one or more char literals to the row. * * @param values chars to be added - * @return this for fluent programming + * @return {@code this} for fluent programming */ public Builder add(final char... values) { for (final char value : values) { @@ -115,7 +113,7 @@ public Builder add(final char... values) { * Add one or more integer literals to the row. * * @param values integers to be added - * @return this for fluent programming + * @return {@code this} for fluent programming */ public Builder add(final int... values) { for (final int value : values) { @@ -128,7 +126,7 @@ public Builder add(final int... values) { * Add one or more long literals to the row. * * @param values longs to be added - * @return this for fluent programming + * @return {@code this} for fluent programming */ public Builder add(final long... values) { for (final long value : values) { @@ -141,7 +139,7 @@ public Builder add(final long... values) { * Add one or more double literals to the row. * * @param values doubles to be added - * @return this for fluent programming + * @return {@code this} for fluent programming */ public Builder add(final double... values) { for (final double value : values) { @@ -154,7 +152,7 @@ public Builder add(final double... values) { * Add one or more float literals to the row. * * @param values floats to be added - * @return this for fluent programming + * @return {@code this} for fluent programming */ public Builder add(final float... values) { for (final float value : values) { @@ -167,7 +165,7 @@ public Builder add(final float... values) { * Add one or more boolean literals to the row. * * @param values booleans to be added - * @return this for fluent programming + * @return {@code this} for fluent programming */ public Builder add(final boolean... values) { for (final boolean value : values) { @@ -179,7 +177,7 @@ public Builder add(final boolean... values) { /** * Add an {@link UnnamedPlaceholder} to the row. * - * @return this for fluent programming + * @return {@code this} for fluent programming */ public Builder addPlaceholder() { this.expressions.add(new UnnamedPlaceholder()); @@ -190,7 +188,7 @@ public Builder addPlaceholder() { * Add a list of expressions to the {@link ValueTableRow}. * * @param expressions expressions to be added - * @return this for fluent programming + * @return {@code this} for fluent programming */ public Builder add(final List expressions) { this.expressions.addAll(expressions); diff --git a/src/main/java/com/exasol/sql/ddl/create/CreateTable.java b/src/main/java/com/exasol/sql/ddl/create/CreateTable.java index 9351c5a9..b3463c10 100644 --- a/src/main/java/com/exasol/sql/ddl/create/CreateTable.java +++ b/src/main/java/com/exasol/sql/ddl/create/CreateTable.java @@ -26,7 +26,7 @@ public CreateTable(final String tableName) { * Add boolean column * * @param columnName name of the column to be added - * @return this for fluent programming + * @return {@code this} for fluent programming */ public synchronized CreateTable booleanColumn(final String columnName) { this.columnsDefinition.add(columnName, new Boolean()); @@ -37,8 +37,8 @@ public synchronized CreateTable booleanColumn(final String columnName) { * Add char column. * * @param columnName name of the column to be added - * @param length pre-defined length for stored strings - * @return this for fluent programming + * @param length pre-defined length for stored strings + * @return {@code this} for fluent programming */ public synchronized CreateTable charColumn(final String columnName, final int length) { this.columnsDefinition.add(columnName, new Char(length)); @@ -49,8 +49,8 @@ public synchronized CreateTable charColumn(final String columnName, final int le * Add varchar column. * * @param columnName name of the column to be added - * @param length pre-defined length for stored strings - * @return this for fluent programming + * @param length pre-defined length for stored strings + * @return {@code this} for fluent programming */ public synchronized CreateTable varcharColumn(final String columnName, final int length) { this.columnsDefinition.add(columnName, new Varchar(length)); @@ -61,7 +61,7 @@ public synchronized CreateTable varcharColumn(final String columnName, final int * Add date column * * @param columnName name of the column to be added - * @return this for fluent programming + * @return {@code this} for fluent programming */ public synchronized CreateTable dateColumn(final String columnName) { this.columnsDefinition.add(columnName, new Date()); @@ -72,9 +72,9 @@ public synchronized CreateTable dateColumn(final String columnName) { * Add decimal column. * * @param columnName name of the column to be added - * @param precision precision for numeric value - * @param scale scale for numeric value - * @return this for fluent programming + * @param precision precision for numeric value + * @param scale scale for numeric value + * @return {@code this} for fluent programming */ public synchronized CreateTable decimalColumn(final String columnName, final int precision, final int scale) { this.columnsDefinition.add(columnName, new Decimal(precision, scale)); @@ -85,7 +85,7 @@ public synchronized CreateTable decimalColumn(final String columnName, final int * Add double precision column * * @param columnName name of the column to be added - * @return this for fluent programming + * @return {@code this} for fluent programming */ public synchronized CreateTable doublePrecisionColumn(final String columnName) { this.columnsDefinition.add(columnName, new DoublePrecision()); @@ -96,7 +96,7 @@ public synchronized CreateTable doublePrecisionColumn(final String columnName) { * Add timestamp column * * @param columnName name of the column to be added - * @return this for fluent programming + * @return {@code this} for fluent programming */ public synchronized CreateTable timestampColumn(final String columnName) { this.columnsDefinition.add(columnName, new Timestamp()); @@ -107,7 +107,7 @@ public synchronized CreateTable timestampColumn(final String columnName) { * Add timestamp with local time zone column * * @param columnName name of the column to be added - * @return this for fluent programming + * @return {@code this} for fluent programming */ public synchronized CreateTable timestampWithLocalTimeZoneColumn(final String columnName) { this.columnsDefinition.add(columnName, new TimestampWithLocalTimezone()); @@ -117,10 +117,10 @@ public synchronized CreateTable timestampWithLocalTimeZoneColumn(final String co /** * Add interval day to second column. * - * @param columnName name of the column to be added - * @param yearPrecision year precision value + * @param columnName name of the column to be added + * @param yearPrecision year precision value * @param millisecondPrecision millisecond precision value - * @return this for fluent programming + * @return {@code this} for fluent programming */ public synchronized CreateTable intervalDayToSecondColumn(final String columnName, final int yearPrecision, final int millisecondPrecision) { @@ -131,9 +131,9 @@ public synchronized CreateTable intervalDayToSecondColumn(final String columnNam /** * Add interval year to month column. * - * @param columnName name of the column to be added + * @param columnName name of the column to be added * @param yearPrecision year precision value - * @return this for fluent programming + * @return {@code this} for fluent programming */ public synchronized CreateTable intervalYearToMonthColumn(final String columnName, final int yearPrecision) { this.columnsDefinition.add(columnName, new IntervalYearToMonth(yearPrecision)); diff --git a/src/main/java/com/exasol/sql/ddl/drop/DropSchema.java b/src/main/java/com/exasol/sql/ddl/drop/DropSchema.java index efcdb886..b1334941 100644 --- a/src/main/java/com/exasol/sql/ddl/drop/DropSchema.java +++ b/src/main/java/com/exasol/sql/ddl/drop/DropSchema.java @@ -27,7 +27,7 @@ public DropSchema(final String schemaName) { /** * Add {@code IF EXISTS} clause into a {@code DROP SCHEMA} statement. * - * @return this for fluent programming + * @return {@code this} for fluent programming */ public synchronized DropSchema ifExists() { if (!this.ifExists) { diff --git a/src/main/java/com/exasol/sql/ddl/drop/DropTable.java b/src/main/java/com/exasol/sql/ddl/drop/DropTable.java index 4a947240..08b4e0d0 100644 --- a/src/main/java/com/exasol/sql/ddl/drop/DropTable.java +++ b/src/main/java/com/exasol/sql/ddl/drop/DropTable.java @@ -24,7 +24,7 @@ public DropTable(final String tableName) { /** * Add {@code IF EXISTS} clause into a {@code DROP TABLE} statement. * - * @return this for fluent programming + * @return {@code this} for fluent programming */ public synchronized DropTable ifExists() { if (!this.ifExists) { @@ -36,7 +36,7 @@ public synchronized DropTable ifExists() { /** * Add {@code CASCADE CONSTRAINTS} clause into a {@code DROP TABLE} statement. * - * @return this for fluent programming + * @return {@code this} for fluent programming */ public DropTable cascadeConstraints() { this.cascadeConstraints = new CascadeConstraints(this); diff --git a/src/main/java/com/exasol/sql/dml/insert/AbstractInsertValueTable.java b/src/main/java/com/exasol/sql/dml/insert/AbstractInsertValueTable.java index 16675c10..b58917e3 100644 --- a/src/main/java/com/exasol/sql/dml/insert/AbstractInsertValueTable.java +++ b/src/main/java/com/exasol/sql/dml/insert/AbstractInsertValueTable.java @@ -33,7 +33,7 @@ protected synchronized void createInsertValueInstanceIfItDoesNotExist() { * Define fields into which should be inserted. * * @param names field names - * @return this for fluent programming + * @return {@code this} for fluent programming */ public synchronized T field(final String... names) { if (!hasFields()) { @@ -47,7 +47,7 @@ public synchronized T field(final String... names) { * Insert a value table. * * @param table value table to be inserted - * @return this for fluent programming + * @return {@code this} for fluent programming */ public synchronized T valueTable(final ValueTable table) { if (hasValues()) { @@ -61,7 +61,7 @@ public synchronized T valueTable(final ValueTable table) { * Insert a list of string values. * * @param values string values to be inserted - * @return this for fluent programming + * @return {@code this} for fluent programming */ // [impl->dsn~values-as-insert-source~1] public synchronized T values(final String... values) { @@ -74,7 +74,7 @@ public synchronized T values(final String... values) { * Insert a list of integer values. * * @param values integer values to be inserted - * @return this for fluent programming + * @return {@code this} for fluent programming */ // [impl->dsn~values-as-insert-source~1] public T values(final int... values) { @@ -87,7 +87,7 @@ public T values(final int... values) { * Insert a list of value expressions. * * @param expressions value expressions to be inserted - * @return this for fluent programming + * @return {@code this} for fluent programming */ // [impl->dsn~values-as-insert-source~1] public T values(final ValueExpression... expressions) { @@ -99,7 +99,7 @@ public T values(final ValueExpression... expressions) { /** * Add an unnamed value placeholder to the value list (this is useful for prepared statements). * - * @return this for fluent programming + * @return {@code this} for fluent programming */ // [impl->dsn~values-as-insert-source~1] public synchronized T valuePlaceholder() { @@ -112,7 +112,7 @@ public synchronized T valuePlaceholder() { * Add a given number unnamed value placeholder to the value list (this is useful for prepared statements). * * @param amount number of placeholders to be added - * @return this for fluent programming + * @return {@code this} for fluent programming */ // [impl->dsn~values-as-insert-source~1] public synchronized T valuePlaceholders(final int amount) { diff --git a/src/main/java/com/exasol/sql/dql/select/LimitClause.java b/src/main/java/com/exasol/sql/dql/select/LimitClause.java index 13dea688..626b3ba3 100644 --- a/src/main/java/com/exasol/sql/dql/select/LimitClause.java +++ b/src/main/java/com/exasol/sql/dql/select/LimitClause.java @@ -55,7 +55,7 @@ public int getCount() { /** * Check if the limit clause has an offset * - * @return true if the limit clause has an offset + * @return {@code true} if the limit clause has an offset */ public boolean hasOffset() { return this.offset > 0; diff --git a/src/main/java/com/exasol/sql/dql/select/Select.java b/src/main/java/com/exasol/sql/dql/select/Select.java index 5793eb39..0b074f69 100644 --- a/src/main/java/com/exasol/sql/dql/select/Select.java +++ b/src/main/java/com/exasol/sql/dql/select/Select.java @@ -30,7 +30,7 @@ public Select() { /** * Add a wildcard field for all involved fields. * - * @return this instance for fluent programming + * @return {@code this} instance for fluent programming */ public Select all() { final DerivedColumn derivedColumn = new DerivedColumn(this, ColumnReference.of("*")); @@ -42,7 +42,7 @@ public Select all() { * Add one or more named fields. * * @param names field name - * @return this instance for fluent programming + * @return {@code this} instance for fluent programming */ public Select field(final String... names) { for (final String name : names) { @@ -57,7 +57,7 @@ public Select field(final String... names) { * * @param functionName name of function * @param valueExpressions zero or more value expression - * @return this instance for fluent programming + * @return {@code this} instance for fluent programming */ public Select function(final FunctionName functionName, final ValueExpression... valueExpressions) { return function(functionName, "", valueExpressions); @@ -69,7 +69,7 @@ public Select function(final FunctionName functionName, final ValueExpression... * @param functionName name of the function * @param valueExpressions zero or more value expression * @param derivedColumnName name under which you can refer to the derived column - * @return this instance for fluent programming + * @return {@code this} instance for fluent programming */ public Select function(final FunctionName functionName, final String derivedColumnName, final ValueExpression... valueExpressions) { @@ -84,7 +84,7 @@ public Select function(final FunctionName functionName, final String derivedColu * * @param function function * @param derivedColumnName name under which you can refer to the derived column - * @return this instance for fluent programming + * @return {@code this} instance for fluent programming */ public Select function(final Function function, final String derivedColumnName) { final DerivedColumn derivedColumn = new DerivedColumn(this, function, derivedColumnName); @@ -96,7 +96,7 @@ public Select function(final Function function, final String derivedColumnName) * Add a function. * * @param function function - * @return this instance for fluent programming + * @return {@code this} instance for fluent programming */ public Select function(final Function function) { function(function, ""); @@ -109,7 +109,7 @@ public Select function(final Function function) { * @param functionName name of function * @param emitsColumnsDefinition column definitions for emits * @param valueExpressions zero or more value expressions - * @return this instance for fluent programming + * @return {@code this} instance for fluent programming */ public Select udf(final String functionName, final ColumnsDefinition emitsColumnsDefinition, @@ -129,7 +129,7 @@ private Select createUdf(final Function udf) { * * @param functionName a name of function * @param valueExpressions zero or more value expressions - * @return this instance for fluent programming + * @return {@code this} instance for fluent programming */ public Select udf(final String functionName, final ValueExpression... valueExpressions) { final Function udf = ExpressionTerm.udf(functionName, valueExpressions); @@ -141,7 +141,7 @@ public Select udf(final String functionName, final ValueExpression... valueExpre * * @deprecated please use a {@link #valueExpression(ValueExpression)} valueExpression} method instead. * @param arithmeticExpression arithmetic expression - * @return this instance for fluent programming + * @return {@code this} instance for fluent programming */ @Deprecated(since = "4.0.2") public Select arithmeticExpression(final BinaryArithmeticExpression arithmeticExpression) { @@ -154,7 +154,7 @@ public Select arithmeticExpression(final BinaryArithmeticExpression arithmeticEx * @deprecated please use a {@link #valueExpression(ValueExpression, String)} valueExpression} method instead. * @param arithmeticExpression arithmetic expression * @param derivedColumnName name under which you can refer to the derived column - * @return this instance for fluent programming + * @return {@code this} instance for fluent programming */ @Deprecated(since = "4.0.2") public Select arithmeticExpression(final BinaryArithmeticExpression arithmeticExpression, @@ -166,7 +166,7 @@ public Select arithmeticExpression(final BinaryArithmeticExpression arithmeticEx * Add a value expression. * * @param valueExpression value expression - * @return this instance for fluent programming + * @return {@code this} instance for fluent programming */ public Select valueExpression(final ValueExpression valueExpression) { final DerivedColumn derivedColumn = new DerivedColumn(this, valueExpression); @@ -179,7 +179,7 @@ public Select valueExpression(final ValueExpression valueExpression) { * * @param valueExpression value expression * @param derivedColumnName name under which you can refer to the derived column - * @return this instance for fluent programming + * @return {@code this} instance for fluent programming */ public Select valueExpression(final ValueExpression valueExpression, final String derivedColumnName) { final DerivedColumn derivedColumn = new DerivedColumn(this, valueExpression, derivedColumnName); @@ -204,7 +204,7 @@ public synchronized FromClause from() { * Create a new full outer {@link LimitClause}. * * @param count maximum number of rows to be included in query result - * @return this for fluent programming + * @return {@code this} for fluent programming * @throws IllegalStateException if a limit clause already exists */ // [impl->dsn~select-statement.out-of-order-clauses~1] @@ -222,7 +222,7 @@ public synchronized Select limit(final int count) { * * @param offset index of the first row in the query result * @param count maximum number of rows to be included in query result - * @return this for fluent programming + * @return {@code this} for fluent programming * @throws IllegalStateException if a limit clause already exists */ // [impl->dsn~select-statement.out-of-order-clauses~1] @@ -239,7 +239,7 @@ public synchronized Select limit(final int offset, final int count) { * Create a new {@link WhereClause}. * * @param expression boolean expression that defines the filter criteria - * @return this for fluent programming + * @return {@code this} for fluent programming */ // [impl->dsn~select-statement.out-of-order-clauses~1] public synchronized Select where(final BooleanExpression expression) { diff --git a/src/main/java/com/exasol/sql/expression/ExpressionTerm.java b/src/main/java/com/exasol/sql/expression/ExpressionTerm.java index fbad880e..ea22aac6 100644 --- a/src/main/java/com/exasol/sql/expression/ExpressionTerm.java +++ b/src/main/java/com/exasol/sql/expression/ExpressionTerm.java @@ -166,7 +166,7 @@ public static Function function(final FunctionName functionName) { * * @param functionName a name of function * @param valueExpressions zero or more value expressions - * @return this instance for fluent programming + * @return {@code this} instance for fluent programming */ public static Function function(final FunctionName functionName, final ValueExpression... valueExpressions) { return ExasolFunction.of(functionName, valueExpressions); diff --git a/src/main/java/com/exasol/sql/expression/comparison/LikeComparison.java b/src/main/java/com/exasol/sql/expression/comparison/LikeComparison.java index 900f2d54..0d9e7beb 100644 --- a/src/main/java/com/exasol/sql/expression/comparison/LikeComparison.java +++ b/src/main/java/com/exasol/sql/expression/comparison/LikeComparison.java @@ -77,7 +77,7 @@ public static class Builder { * Add the left operand. * * @param left left operand - * @return this for fluent programming + * @return {@code this} for fluent programming */ public Builder left(final ValueExpression left) { this.left = left; @@ -88,7 +88,7 @@ public Builder left(final ValueExpression left) { * Add the right operand. * * @param right right operand - * @return this for fluent programming + * @return {@code this} for fluent programming */ public Builder right(final ValueExpression right) { this.right = right; @@ -98,7 +98,7 @@ public Builder right(final ValueExpression right) { /** * Set for NOT LIKE expression. * - * @return this for fluent programming + * @return {@code this} for fluent programming */ public Builder not() { this.operator = LikeComparisonOperator.NOT_LIKE; @@ -109,7 +109,7 @@ public Builder not() { * Add an escape character. * * @param escape escape character - * @return this for fluent programming + * @return {@code this} for fluent programming */ public Builder escape(final char escape) { this.escape = escape; diff --git a/src/main/java/com/exasol/sql/expression/predicate/BetweenPredicate.java b/src/main/java/com/exasol/sql/expression/predicate/BetweenPredicate.java index d2da2124..9df2f03c 100644 --- a/src/main/java/com/exasol/sql/expression/predicate/BetweenPredicate.java +++ b/src/main/java/com/exasol/sql/expression/predicate/BetweenPredicate.java @@ -24,7 +24,7 @@ private BetweenPredicate(final Builder builder) { * @return left expression in the predicate */ public ValueExpression getExpression() { - return expression; + return this.expression; } /** @@ -33,7 +33,7 @@ public ValueExpression getExpression() { * @return start expression in the predicate */ public ValueExpression getStartExpression() { - return start; + return this.start; } /** @@ -42,7 +42,7 @@ public ValueExpression getStartExpression() { * @return end expression in the predicate */ public ValueExpression getEndExpression() { - return end; + return this.end; } /** @@ -86,7 +86,7 @@ private Builder() { * Adds the left expression of predicate. * * @param expression in predicate expression - * @return this for fluent programming + * @return {@code this} for fluent programming */ public Builder expression(final ValueExpression expression) { this.expression = expression; @@ -97,7 +97,7 @@ public Builder expression(final ValueExpression expression) { * Adds the start expression of predicate. * * @param start start expression in predicate - * @return this for fluent programming + * @return {@code this} for fluent programming */ public Builder start(final ValueExpression start) { this.start = start; @@ -108,7 +108,7 @@ public Builder start(final ValueExpression start) { * Adds the end expression of predicate. * * @param end end expression in predicate - * @return this for fluent programming + * @return {@code this} for fluent programming */ public Builder end(final ValueExpression end) { this.end = end; @@ -118,7 +118,7 @@ public Builder end(final ValueExpression end) { /** * Sets {@code NOT BETWEEN} predicate. * - * @return this for fluent programming + * @return {@code this} for fluent programming */ public Builder not() { this.operator = BetweenPredicateOperator.NOT_BETWEEN; diff --git a/src/main/java/com/exasol/sql/expression/predicate/InPredicate.java b/src/main/java/com/exasol/sql/expression/predicate/InPredicate.java index c6e7122b..9adc0d92 100644 --- a/src/main/java/com/exasol/sql/expression/predicate/InPredicate.java +++ b/src/main/java/com/exasol/sql/expression/predicate/InPredicate.java @@ -28,7 +28,7 @@ private InPredicate(final Builder builder) { * @return {@code true} if predicate has a sub query, otherwise return {@code false} */ public boolean hasSelectQuery() { - return selectQuery != null; + return this.selectQuery != null; } /** @@ -37,7 +37,7 @@ public boolean hasSelectQuery() { * @return expression in predicate */ public ValueExpression getExpression() { - return expression; + return this.expression; } /** @@ -46,7 +46,7 @@ public ValueExpression getExpression() { * @return value expression operands */ public List getOperands() { - return operands; + return this.operands; } /** @@ -55,7 +55,7 @@ public List getOperands() { * @return sub select query */ public Select getSelectQuery() { - return selectQuery; + return this.selectQuery; } /** @@ -99,7 +99,7 @@ private Builder() { * Adds the predicate expression. * * @param expression in predicate expression - * @return this for fluent programming + * @return {@code this} for fluent programming */ public Builder expression(final ValueExpression expression) { this.expression = expression; @@ -110,7 +110,7 @@ public Builder expression(final ValueExpression expression) { * Adds the operands. * * @param operands operands for {@code [NOT] IN} predicate - * @return this for fluent programming + * @return {@code this} for fluent programming */ public Builder operands(final ValueExpression... operands) { if (this.selectQuery != null) { @@ -124,7 +124,7 @@ public Builder operands(final ValueExpression... operands) { * Adds the sub select query. * * @param select sub select for {@code [NOT] IN} predicate - * @return this for fluent programming + * @return {@code this} for fluent programming */ public Builder selectQuery(final Select select) { if (this.operands != null) { @@ -142,7 +142,7 @@ private String getExceptionMessage() { /** * Sets {@code NOT IN} predicate. * - * @return this for fluent programming + * @return {@code this} for fluent programming */ public Builder not() { this.operator = InPredicateOperator.NOT_IN; diff --git a/src/main/java/com/exasol/sql/rendering/StringRendererConfig.java b/src/main/java/com/exasol/sql/rendering/StringRendererConfig.java index 2e776ff2..bb1eda10 100644 --- a/src/main/java/com/exasol/sql/rendering/StringRendererConfig.java +++ b/src/main/java/com/exasol/sql/rendering/StringRendererConfig.java @@ -17,7 +17,7 @@ private StringRendererConfig(final Builder builder) { /** * Get whether the statements should be produced in lower case. * - * @return true if statements are produced in lower case + * @return {@code true} if statements are produced in lower case */ public boolean useLowerCase() { return this.lowerCase; @@ -26,7 +26,7 @@ public boolean useLowerCase() { /** * Get whether identifiers should be enclosed in double quotation marks. * - * @return true if should be enclosed in quotes + * @return {@code true} if should be enclosed in quotes */ public boolean useQuotes() { return this.quote; @@ -72,7 +72,7 @@ public StringRendererConfig build() { /** * Define whether the statement should be produced in lower case * - * @param lowerCase set to true if the statement should be produced in lower case + * @param lowerCase set to {@code true} if the statement should be produced in lower case * @return this instance for fluent programming */ public Builder lowerCase(final boolean lowerCase) { @@ -83,7 +83,7 @@ public Builder lowerCase(final boolean lowerCase) { /** * Define whether schema, table and field identifiers should be enclosed in double quotation marks. * - * @param quote set to true if identifiers should be enclosed in quotes + * @param quote set to {@code true} if identifiers should be enclosed in quotes * @return this instance for fluent programming */ public Builder quoteIdentifiers(final boolean quote) { diff --git a/src/test/java/com/exasol/sql/dql/select/rendering/TestSelectRendering.java b/src/test/java/com/exasol/sql/dql/select/rendering/TestSelectRendering.java index e2c5c3d2..a7fc1d9f 100644 --- a/src/test/java/com/exasol/sql/dql/select/rendering/TestSelectRendering.java +++ b/src/test/java/com/exasol/sql/dql/select/rendering/TestSelectRendering.java @@ -3,7 +3,7 @@ import static com.exasol.hamcrest.SqlFragmentRenderResultMatcher.rendersTo; import static com.exasol.hamcrest.SqlFragmentRenderResultMatcher.rendersWithConfigTo; import static com.exasol.sql.expression.BooleanTerm.*; -import static com.exasol.sql.expression.ExpressionTerm.stringLiteral; +import static com.exasol.sql.expression.ExpressionTerm.*; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -11,11 +11,13 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import com.exasol.datatype.type.Varchar; import com.exasol.sql.StatementFactory; import com.exasol.sql.ValueTable; import com.exasol.sql.dql.select.Select; -import com.exasol.sql.expression.BooleanExpression; -import com.exasol.sql.expression.ColumnReference; +import com.exasol.sql.expression.*; +import com.exasol.sql.expression.function.exasol.*; +import com.exasol.sql.expression.literal.NullLiteral; import com.exasol.sql.rendering.StringRendererConfig; class TestSelectRendering { @@ -137,4 +139,42 @@ void testSelectWithLikePredicate() { this.select.valueExpression(like1, "res1").valueExpression(like2, "res2"); assertThat(this.select, rendersTo("SELECT 'abcd' NOT LIKE 'a_d' res1, '%bcd' LIKE '\\%%d' res2")); } + + @Test + void testSelectCastFunction() { + final Select select = StatementFactory.getInstance().select() + .function(CastExasolFunction.of(NullLiteral.nullLiteral(), new Varchar(254)), "TEST"); + assertThat(select, rendersTo("SELECT CAST(NULL AS VARCHAR(254)) TEST")); + } + + @Test + void testSelectAggregateFunctionCoalesce() { + final Select select = StatementFactory.getInstance().select() // + .function(ExasolAggregateFunction.APPROXIMATE_COUNT_DISTINCT, "COUNT_APPR", column("customer_id")); + select.from().table("orders"); + select.where(BooleanTerm.gt(column("price"), integerLiteral(1000))); + assertThat(select, + rendersTo("SELECT APPROXIMATE_COUNT_DISTINCT(customer_id) COUNT_APPR FROM orders WHERE price > 1000")); + } + + @Test + void testSelectAnalyticFunction() { + final Select select = StatementFactory.getInstance().select() // + .field("department") // + .function(ExasolAnalyticFunction.ANY, " ANY_ ", BooleanTerm.lt(column("age"), integerLiteral(30))); + select.from().table("employee_table"); + select.groupBy(column("department")); + assertThat(select, + rendersTo("SELECT department, ANY((age < 30)) ANY_ FROM employee_table GROUP BY department")); + } + + @Test + void testSelectTwoScalatFunctions() { + final Select select = StatementFactory.getInstance().select() // + .function(ExasolScalarFunction.ADD_YEARS, "AY1", stringLiteral("2000-02-29"), integerLiteral(1)) // + .function(ExasolScalarFunction.ADD_YEARS, "AY2", stringLiteral("2005-01-31 12:00:00"), + integerLiteral(-1)); + assertThat(select, + rendersTo("SELECT ADD_YEARS('2000-02-29', 1) AY1, ADD_YEARS('2005-01-31 12:00:00', -1) AY2")); + } } \ No newline at end of file diff --git a/src/test/java/com/exasol/sql/expression/function/exasol/AbstractFunctionTest.java b/src/test/java/com/exasol/sql/expression/function/exasol/AbstractFunctionTest.java new file mode 100644 index 00000000..a8ccdf92 --- /dev/null +++ b/src/test/java/com/exasol/sql/expression/function/exasol/AbstractFunctionTest.java @@ -0,0 +1,15 @@ +package com.exasol.sql.expression.function.exasol; + +import com.exasol.sql.expression.function.Function; +import com.exasol.sql.expression.function.FunctionVisitor; +import com.exasol.sql.expression.rendering.ValueExpressionRenderer; +import com.exasol.sql.rendering.StringRendererConfig; + +public abstract class AbstractFunctionTest { + protected String renderFunction(final Function cast) { + final ValueExpressionRenderer functionVisitor = new ValueExpressionRenderer( + StringRendererConfig.builder().build()); + cast.accept((FunctionVisitor) functionVisitor); + return functionVisitor.render(); + } +} \ No newline at end of file diff --git a/src/test/java/com/exasol/sql/expression/function/exasol/CastExasolFunctionTest.java b/src/test/java/com/exasol/sql/expression/function/exasol/CastExasolFunctionTest.java index bfb34bca..f2c637e4 100644 --- a/src/test/java/com/exasol/sql/expression/function/exasol/CastExasolFunctionTest.java +++ b/src/test/java/com/exasol/sql/expression/function/exasol/CastExasolFunctionTest.java @@ -1,27 +1,18 @@ package com.exasol.sql.expression.function.exasol; -import static com.exasol.hamcrest.SqlFragmentRenderResultMatcher.rendersTo; import static org.hamcrest.MatcherAssert.assertThat; +import org.hamcrest.CoreMatchers; import org.junit.jupiter.api.Test; import com.exasol.datatype.type.Varchar; -import com.exasol.sql.StatementFactory; -import com.exasol.sql.dql.select.Select; import com.exasol.sql.expression.literal.NullLiteral; -class CastExasolFunctionTest { +class CastExasolFunctionTest extends AbstractFunctionTest { @Test void testRendering() { - final Select select = StatementFactory.getInstance().select() - .function(CastExasolFunction.of(NullLiteral.nullLiteral(), new Varchar(254))); - assertThat(select, rendersTo("SELECT CAST(NULL AS VARCHAR(254))")); - } - - @Test - void testRenderingWithName() { - final Select select = StatementFactory.getInstance().select() - .function(CastExasolFunction.of(NullLiteral.nullLiteral(), new Varchar(254)), "TEST"); - assertThat(select, rendersTo("SELECT CAST(NULL AS VARCHAR(254)) TEST")); + final CastExasolFunction cast = CastExasolFunction.of(NullLiteral.nullLiteral(), new Varchar(254)); + final String render = renderFunction(cast); + assertThat(render, CoreMatchers.equalTo("CAST(NULL AS VARCHAR(254))")); } } \ No newline at end of file diff --git a/src/test/java/com/exasol/sql/expression/function/exasol/ExasolAggregateFunctionTest.java b/src/test/java/com/exasol/sql/expression/function/exasol/ExasolAggregateFunctionTest.java deleted file mode 100644 index fc478171..00000000 --- a/src/test/java/com/exasol/sql/expression/function/exasol/ExasolAggregateFunctionTest.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.exasol.sql.expression.function.exasol; - -import static com.exasol.hamcrest.SqlFragmentRenderResultMatcher.rendersTo; -import static com.exasol.sql.expression.ExpressionTerm.column; -import static com.exasol.sql.expression.ExpressionTerm.integerLiteral; -import static org.hamcrest.MatcherAssert.assertThat; - -import org.junit.jupiter.api.Test; - -import com.exasol.sql.StatementFactory; -import com.exasol.sql.dql.select.Select; -import com.exasol.sql.expression.BooleanTerm; - -class ExasolAggregateFunctionTest { - @Test - void testAggregateFunctionCoalesce() { - final Select select = StatementFactory.getInstance().select() // - .function(ExasolAggregateFunction.APPROXIMATE_COUNT_DISTINCT, "COUNT_APPR", column("customer_id")); - select.from().table("orders"); - select.where(BooleanTerm.gt(column("price"), integerLiteral(1000))); - assertThat(select, - rendersTo("SELECT APPROXIMATE_COUNT_DISTINCT(customer_id) COUNT_APPR FROM orders WHERE price > 1000")); - } -} \ No newline at end of file diff --git a/src/test/java/com/exasol/sql/expression/function/exasol/ExasolAnalyticFunctionTest.java b/src/test/java/com/exasol/sql/expression/function/exasol/ExasolAnalyticFunctionTest.java deleted file mode 100644 index 5d4fd06c..00000000 --- a/src/test/java/com/exasol/sql/expression/function/exasol/ExasolAnalyticFunctionTest.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.exasol.sql.expression.function.exasol; - -import static com.exasol.hamcrest.SqlFragmentRenderResultMatcher.rendersTo; -import static com.exasol.sql.expression.ExpressionTerm.column; -import static com.exasol.sql.expression.ExpressionTerm.integerLiteral; -import static org.hamcrest.MatcherAssert.assertThat; - -import org.junit.jupiter.api.Test; - -import com.exasol.sql.StatementFactory; -import com.exasol.sql.dql.select.Select; -import com.exasol.sql.expression.BooleanTerm; - -class ExasolAnalyticFunctionTest { - @Test - void testAggregateFunctionCoalesce() { - final Select select = StatementFactory.getInstance().select() // - .field("department") // - .function(ExasolAnalyticFunction.ANY, " ANY_ ", BooleanTerm.lt(column("age"), integerLiteral(30))); - select.from().table("employee_table"); - select.groupBy(column("department")); - assertThat(select, - rendersTo("SELECT department, ANY((age < 30)) ANY_ FROM employee_table GROUP BY department")); - } -} \ No newline at end of file diff --git a/src/test/java/com/exasol/sql/expression/function/exasol/ExasolScalarFunctionTest.java b/src/test/java/com/exasol/sql/expression/function/exasol/ExasolScalarFunctionTest.java index 69e3e268..27c91da7 100644 --- a/src/test/java/com/exasol/sql/expression/function/exasol/ExasolScalarFunctionTest.java +++ b/src/test/java/com/exasol/sql/expression/function/exasol/ExasolScalarFunctionTest.java @@ -1,294 +1,237 @@ package com.exasol.sql.expression.function.exasol; -import static com.exasol.hamcrest.SqlFragmentRenderResultMatcher.rendersTo; import static com.exasol.sql.expression.ExpressionTerm.*; +import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.MatcherAssert.assertThat; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; -import com.exasol.sql.StatementFactory; -import com.exasol.sql.dql.select.Select; +import com.exasol.sql.expression.BooleanTerm; -class ExasolScalarFunctionTest { - @ParameterizedTest - @CsvSource({ // - "ABS, ABS_COL, -123, SELECT ABS(-123) ABS_COL", // - "LN, LN_COL, 100, SELECT LN(100) LN_COL", // - "LOG10, LOG10_COL, 10000, SELECT LOG10(10000) LOG10_COL", // - "LOG2, LOG2_COL, 1024, SELECT LOG2(1024) LOG2_COL", // - "RADIANS, RADIANS, 180, SELECT RADIANS(180) RADIANS", // - "SINH, SINH_COL, 0, SELECT SINH(0) SINH_COL", // - "TANH, TANH_COL, 0, SELECT TANH(0) TANH_COL", // - "CHAR, CHAR, 88, SELECT CHAR(88) CHAR", // - "UNICODECHR, UNICODECHR, 252, SELECT UNICODECHR(252) UNICODECHR" // - }) - void testScalarFunctionWithIntegerAndColumnName(final String functionName, final String columnName, - final int integerLiteral, final String expected) { - final Select select = StatementFactory.getInstance().select() // - .function(ExasolScalarFunction.valueOf(functionName), columnName, integerLiteral(integerLiteral)); - assertThat(select, rendersTo(expected)); +class ExasolFunctionTest extends AbstractFunctionTest { + @Test + void testAggregateFunction() { + final ExasolFunction function = ExasolFunction.of(ExasolAggregateFunction.APPROXIMATE_COUNT_DISTINCT, + column("customer_id")); + assertThat(renderFunction(function), equalTo("APPROXIMATE_COUNT_DISTINCT(customer_id)")); + } + + @Test + void testAnalyticFunction() { + final ExasolFunction function = ExasolFunction.of(ExasolAnalyticFunction.ANY, + BooleanTerm.lt(column("age"), integerLiteral(30))); + assertThat(renderFunction(function), equalTo("ANY((age < 30))")); } @ParameterizedTest @CsvSource({ // - "ACOS, ACOS_COL, 0.5, SELECT ACOS(0.5) ACOS_COL", // - "CEIL, CEIL_COL, 0.234, SELECT CEIL(0.234) CEIL_COL", // - "FLOOR, FLOOR_COL, 4.567, SELECT FLOOR(4.567) FLOOR_COL" // + "ABS, -123, ABS(-123)", // + "LN, 100, LN(100)", // + "LOG10, 10000, LOG10(10000)", // + "LOG2, 1024, LOG2(1024)", // + "RADIANS, 180, RADIANS(180)", // + "SINH, 0, SINH(0)", // + "TANH, 0, TANH(0)", // + "CHAR, 88, CHAR(88)", // + "UNICODECHR, 252, UNICODECHR(252)", // + "ASIN, 1, ASIN(1)", // + "ATAN, 1, ATAN(1)", // + "COSH, 1, COSH(1)", // + "COT, 1, COT(1)", // + "EXP, 1, EXP(1)", // + "SIGN, -123, SIGN(-123)", // + "SIN, 1, SIN(1)", // + "SQRT, 2, SQRT(2)" // }) - void testScalarFunctionWithDoubleAndColumnName(final String functionName, final String columnName, - final double doubleLiteral, final String expected) { - final Select select = StatementFactory.getInstance().select() // - .function(ExasolScalarFunction.valueOf(functionName), columnName, doubleLiteral(doubleLiteral)); - assertThat(select, rendersTo(expected)); + void testScalarFunctionWithInteger(final String functionName, final int integerLiteral, final String expected) { + final ExasolFunction function = ExasolFunction.of(ExasolScalarFunction.valueOf(functionName), + integerLiteral(integerLiteral)); + assertThat(renderFunction(function), equalTo(expected)); } @ParameterizedTest @CsvSource({ // - "ASIN, 1, SELECT ASIN(1)", // - "ATAN, 1, SELECT ATAN(1)", // - "COSH, 1, SELECT COSH(1)", // - "COT, 1, SELECT COT(1)", // - "EXP, 1, SELECT EXP(1)", // - "SIGN, -123, SELECT SIGN(-123)", // - "SIN, 1, SELECT SIN(1)", // - "SQRT, 2, SELECT SQRT(2)" // + "ACOS, 0.5, ACOS(0.5)", // + "CEIL, 0.234, CEIL(0.234)", // + "FLOOR, 4.567, FLOOR(4.567)" // }) - void testScalarFunctionWithInteger(final String functionName, final int integerLiteral, final String expected) { - final Select select = StatementFactory.getInstance().select() // - .function(ExasolScalarFunction.valueOf(functionName), integerLiteral(integerLiteral)); - assertThat(select, rendersTo(expected)); + void testScalarFunctionWithDouble(final String functionName, final double doubleLiteral, final String expected) { + final ExasolFunction function = ExasolFunction.of(ExasolScalarFunction.valueOf(functionName), + doubleLiteral(doubleLiteral)); + assertThat(renderFunction(function), equalTo(expected)); } @ParameterizedTest @CsvSource(value = { // - "ATAN2; ATAN2_COL; 1; 1; SELECT ATAN2(1, 1) ATAN2_COL", // - "DIV; DIV_COL; 1; 1; SELECT DIV(1, 1) DIV_COL", // - "LOG; LOG_COL; 2; 1024; SELECT LOG(2, 1024) LOG_COL", // - "MOD; MODULO; 15; 6; SELECT MOD(15, 6) MODULO", // - "POWER; POWER; 2; 10; SELECT POWER(2, 10) POWER" // + "ATAN2; 1; 1; ATAN2(1, 1)", // + "DIV; 1; 1; DIV(1, 1)", // + "LOG; 2; 1024; LOG(2, 1024)", // + "MOD; 15; 6; MOD(15, 6)", // + "POWER; 2; 10; POWER(2, 10)", // + "RANDOM; 1; 10; RANDOM(1, 10)" // }, delimiter = ';') // This method has different delimiter because arguments contain commas. - void testScalarFunctionWithTwoIntegers(final String functionName, final String columnName, final int first, - final int second, final String expected) { - final Select select = StatementFactory.getInstance().select() // - .function(ExasolScalarFunction.valueOf(functionName), columnName, integerLiteral(first), - integerLiteral(second)); - assertThat(select, rendersTo(expected)); + void testScalarFunctionWithTwoIntegers(final String functionName, final int first, final int second, + final String expected) { + final ExasolFunction function = ExasolFunction.of(ExasolScalarFunction.valueOf(functionName), + integerLiteral(first), integerLiteral(second)); + assertThat(renderFunction(function), equalTo(expected)); } @ParameterizedTest - @CsvSource({ "COS, 3, SELECT COS((PI()/3))", // - "TAN, 4, SELECT TAN((PI()/4))" // + @CsvSource({ "COS, 3, COS((PI()/3))", // + "TAN, 4, TAN((PI()/4))" // }) void testScalarFunctionWithBinaryArithmetic(final String functionName, final int integerLiteral, final String expected) { - final Select select = StatementFactory.getInstance().select() // - .function(ExasolScalarFunction.valueOf(functionName), - divide(function(ExasolScalarFunction.PI), integerLiteral(integerLiteral))); - assertThat(select, rendersTo(expected)); - } - - @Test - void testScalarFunctionDegrees() { - final Select select = StatementFactory.getInstance().select() // - .function(ExasolScalarFunction.DEGREES, function(ExasolScalarFunction.PI)); - assertThat(select, rendersTo("SELECT DEGREES(PI())")); - } - - @Test - void testScalarFunctionPi() { - final Select select = StatementFactory.getInstance().select().function(ExasolScalarFunction.PI); - assertThat(select, rendersTo("SELECT PI()")); - } - - @Test - void testScalarFunctionRandom() { - final Select select = StatementFactory.getInstance().select() // - .function(ExasolScalarFunction.RANDOM, "RANDOM_1") // - .function(ExasolScalarFunction.RANDOM, "RANDOM_2", integerLiteral(5), integerLiteral(20)); - assertThat(select, rendersTo("SELECT RANDOM() RANDOM_1, RANDOM(5, 20) RANDOM_2")); - } - - @Test - void testScalarFunctionRound() { - final Select select = StatementFactory.getInstance().select() // - .function(ExasolScalarFunction.ROUND, "ROUND", doubleLiteral(123.456), integerLiteral(2)); - assertThat(select, rendersTo("SELECT ROUND(123.456, 2) ROUND")); - } - - @Test - void testScalarFunctionToChar() { - final Select select = StatementFactory.getInstance().select() // - .function(ExasolScalarFunction.TO_CHAR, "TO_CHAR", doubleLiteral(12345.67890), - stringLiteral("9999999.999999999")); - assertThat(select, rendersTo("SELECT TO_CHAR(12345.6789, '9999999.999999999') TO_CHAR")); - } - - @Test - void testScalarFunctionToNumber() { - final Select select = StatementFactory.getInstance().select() // - .function(ExasolScalarFunction.TO_NUMBER, "TO_NUMBER1", stringLiteral("+123")) // - .function(ExasolScalarFunction.TO_NUMBER, "TO_NUMBER2", stringLiteral("-123.45"), - stringLiteral("99999.999")); - assertThat(select, - rendersTo("SELECT TO_NUMBER('+123') TO_NUMBER1, TO_NUMBER('-123.45', '99999.999') TO_NUMBER2")); + final ExasolFunction function = ExasolFunction.of(ExasolScalarFunction.valueOf(functionName), + divide(function(ExasolScalarFunction.PI), integerLiteral(integerLiteral))); + assertThat(renderFunction(function), equalTo(expected)); } @ParameterizedTest @CsvSource({ // - "ASCII, , X, SELECT ASCII('X')", // - "BIT_LENGTH, BIT_LENGTH, äöü, SELECT BIT_LENGTH('äöü') BIT_LENGTH", // - "CHARACTER_LENGTH, C_LENGTH, aeiouäöü, SELECT CHARACTER_LENGTH('aeiouäöü') C_LENGTH", // - "COLOGNE_PHONETIC, , schmitt, SELECT COLOGNE_PHONETIC('schmitt')", - "DUMP, DUMP, 123abc, SELECT DUMP('123abc') DUMP", // - "INITCAP, INITCAP, ExAsOl is great, SELECT INITCAP('ExAsOl is great') INITCAP", // - "LCASE, LCASE, AbCdEf, SELECT LCASE('AbCdEf') LCASE", // - "LOWER, , AbCdEf, SELECT LOWER('AbCdEf')", // - "OCTET_LENGTH, OCT_LENGTH, abcd, SELECT OCTET_LENGTH('abcd') OCT_LENGTH", // - "REVERSE, REVERSE, abcde, SELECT REVERSE('abcde') REVERSE", // - "SOUNDEX, , smythe, SELECT SOUNDEX('smythe')", // - "UCASE, UCASE, AbCdEf, SELECT UCASE('AbCdEf') UCASE", // - "UNICODE, UNICODE, ä, SELECT UNICODE('ä') UNICODE", // - "UPPER, UPPER, AbCdEf, SELECT UPPER('AbCdEf') UPPER" // + "ASCII, X, ASCII('X')", // + "BIT_LENGTH, äöü, BIT_LENGTH('äöü')", // + "CHARACTER_LENGTH, aeiouäöü, CHARACTER_LENGTH('aeiouäöü')", // + "COLOGNE_PHONETIC, schmitt, COLOGNE_PHONETIC('schmitt')", // + "DUMP, 123abc, DUMP('123abc')", // + "INITCAP, ExAsOl is great, INITCAP('ExAsOl is great')", // + "LCASE, AbCdEf, LCASE('AbCdEf')", // + "LOWER, AbCdEf, LOWER('AbCdEf')", // + "OCTET_LENGTH, abcd, OCTET_LENGTH('abcd')", // + "REVERSE, abcde, REVERSE('abcde')", // + "SOUNDEX, smythe, SOUNDEX('smythe')", // + "UCASE, AbCdEf, UCASE('AbCdEf')", // + "UNICODE, ä, UNICODE('ä')", // + "UPPER, AbCdEf, UPPER('AbCdEf')", // + "TO_NUMBER, +123, TO_NUMBER('+123')", // + "TO_CHAR, 1999-12-31, TO_CHAR('1999-12-31')" // }) - void testScalarFunctionWithString(final String functionName, final String columnName, final String literalString, - final String expected) { - final Select select = StatementFactory.getInstance().select() // - .function(ExasolScalarFunction.valueOf(functionName), columnName, stringLiteral(literalString)); - assertThat(select, rendersTo(expected)); + void testScalarFunctionWithString(final String functionName, final String literalString, final String expected) { + final ExasolFunction function = ExasolFunction.of(ExasolScalarFunction.valueOf(functionName), + stringLiteral(literalString)); + assertThat(renderFunction(function), equalTo(expected)); } @ParameterizedTest @CsvSource(value = { // - "CONCAT; abc; def; SELECT CONCAT('abc', 'def')", // - "EDIT_DISTANCE; schmitt; Schmidt; SELECT EDIT_DISTANCE('schmitt', 'Schmidt')", // - "INSTR; abcabcabc; cab; SELECT INSTR('abcabcabc', 'cab')", // - "LOCATE; cab; abcabcabc; SELECT LOCATE('cab', 'abcabcabc')", // - "LTRIM; ab cdef; ab; SELECT LTRIM('ab cdef', 'ab')", // - "REGEXP_INSTR; Phone: +497003927877678; \\+?\\d+; SELECT REGEXP_INSTR('Phone: +497003927877678', '\\+?\\d+')", // - "REGEXP_REPLACE; my_mail@yahoo.com; [a-z0-9._%+-]; SELECT REGEXP_REPLACE('my_mail@yahoo.com', '[a-z0-9._%+-]')", // - "REGEXP_SUBSTR; my_mail@yahoo.com; [a-z0-9._%+-]; SELECT REGEXP_SUBSTR('my_mail@yahoo.com', '[a-z0-9._%+-]')", // - "RTRIM; abcdef; afe; SELECT RTRIM('abcdef', 'afe')" // + "CONCAT; abc; def; CONCAT('abc', 'def')", // + "EDIT_DISTANCE; schmitt; Schmidt; EDIT_DISTANCE('schmitt', 'Schmidt')", // + "INSTR; abcabcabc; cab; INSTR('abcabcabc', 'cab')", // + "LOCATE; cab; abcabcabc; LOCATE('cab', 'abcabcabc')", // + "LTRIM; ab cdef; ab; LTRIM('ab cdef', 'ab')", // + "REGEXP_INSTR; Phone: +497003927877678; \\+?\\d+; REGEXP_INSTR('Phone: +497003927877678', '\\+?\\d+')", // + "REGEXP_REPLACE; my_mail@yahoo.com; [a-z0-9._%+-]; REGEXP_REPLACE('my_mail@yahoo.com', '[a-z0-9._%+-]')", // + "REGEXP_SUBSTR; my_mail@yahoo.com; [a-z0-9._%+-]; REGEXP_SUBSTR('my_mail@yahoo.com', '[a-z0-9._%+-]')", // + "RTRIM; abcdef; afe; RTRIM('abcdef', 'afe')", // + "TO_NUMBER; -123.45; 99999.999; TO_NUMBER('-123.45', '99999.999')", // + "TRIM; abcdef; acf; TRIM('abcdef', 'acf')" // }, delimiter = ';') void testScalarFunctionWithTwoStrings(final String functionName, final String first, final String second, final String expected) { - final Select select = StatementFactory.getInstance().select() // - .function(ExasolScalarFunction.valueOf(functionName), stringLiteral(first), stringLiteral(second)); - assertThat(select, rendersTo(expected)); - } - - @Test - void testScalarFunctionInsert() { - final Select select = StatementFactory.getInstance().select() // - .function(ExasolScalarFunction.INSERT, stringLiteral("abc"), integerLiteral(2), integerLiteral(2), - stringLiteral("xxx")) // - .function(ExasolScalarFunction.INSERT, stringLiteral("abcdef"), integerLiteral(3), integerLiteral(2), - stringLiteral("CD")); - assertThat(select, rendersTo("SELECT INSERT('abc', 2, 2, 'xxx'), INSERT('abcdef', 3, 2, 'CD')")); + final ExasolFunction function = ExasolFunction.of(ExasolScalarFunction.valueOf(functionName), + stringLiteral(first), stringLiteral(second)); + assertThat(renderFunction(function), equalTo(expected)); } @ParameterizedTest @CsvSource(value = { // - "LEFT; abcdef; 3; SELECT LEFT('abcdef', 3)", // - "REPEAT; abc; 3; SELECT REPEAT('abc', 3)", // - "RIGHT; abcdef; 3; SELECT RIGHT('abcdef', 3)" // + "LEFT; abcdef; 3; LEFT('abcdef', 3)", // + "REPEAT; abc; 3; REPEAT('abc', 3)", // + "RIGHT; abcdef; 3; RIGHT('abcdef', 3)", // + "ADD_YEARS; 2000-02-29; 1; ADD_YEARS('2000-02-29', 1)" // }, delimiter = ';') void testScalarFunctionStringAndInteger(final String functionName, final String stringLiteral, final int integerLiteral, final String expected) { - final Select select = StatementFactory.getInstance().select() // - .function(ExasolScalarFunction.valueOf(functionName), stringLiteral(stringLiteral), - integerLiteral(integerLiteral)); - assertThat(select, rendersTo(expected)); - } - - @Test - void testScalarFunctionLength() { - final Select select = StatementFactory.getInstance().select() // - .function(ExasolScalarFunction.LENGTH, column("s")); - select.from().table("t"); - assertThat(select, rendersTo("SELECT LENGTH(s) FROM t")); + final ExasolFunction function = ExasolFunction.of(ExasolScalarFunction.valueOf(functionName), + stringLiteral(stringLiteral), integerLiteral(integerLiteral)); + assertThat(renderFunction(function), equalTo(expected)); } @ParameterizedTest @CsvSource(value = { // - "LPAD; abc; 5; X; SELECT LPAD('abc', 5, 'X')", // - "RPAD; abc; 5; X; SELECT RPAD('abc', 5, 'X')" // + "REPLACE; Apple juice is great; Apple; Orange; REPLACE('Apple juice is great', 'Apple', 'Orange')", // + "TRANSLATE; abcd; abc; xy; TRANSLATE('abcd', 'abc', 'xy')" // }, delimiter = ';') - void testScalarFunctionPad(final String functionName, final String stringfirstLiteral, final int integerLiteral, - final String stringSecondLiteral, final String expected) { - final Select select = StatementFactory.getInstance().select() // - .function(ExasolScalarFunction.valueOf(functionName), stringLiteral(stringfirstLiteral), - integerLiteral(integerLiteral), stringLiteral(stringSecondLiteral)); - assertThat(select, rendersTo(expected)); + void testScalarFunctionThreeStrings(final String functionName, final String first, final String second, + final String third, final String expected) { + final ExasolFunction function = ExasolFunction.of(ExasolScalarFunction.valueOf(functionName), + stringLiteral(first), stringLiteral(second), stringLiteral(third)); + assertThat(renderFunction(function), equalTo(expected)); } - @Test - void testScalarFunctionMid() { - final Select select = StatementFactory.getInstance().select() // - .function(ExasolScalarFunction.MID, "MID", stringLiteral("abcdef"), integerLiteral(2), - integerLiteral(3)); - assertThat(select, rendersTo("SELECT MID('abcdef', 2, 3) MID")); + @ParameterizedTest + @CsvSource(value = { // + "MID; abcdef; 2; 3; MID('abcdef', 2, 3)", // + "SUBSTR; abcdef; 2; 3; SUBSTR('abcdef', 2, 3)" // + }, delimiter = ';') + void testScalarFunctionWithStringAndTwoIntegers(final String functionName, final String literalString, + final Integer literalIntegerFirst, final Integer literalIntegerSecond, final String expected) { + final ExasolFunction function = ExasolFunction.of(ExasolScalarFunction.valueOf(functionName), + stringLiteral(literalString), integerLiteral(literalIntegerFirst), + integerLiteral(literalIntegerSecond)); + assertThat(renderFunction(function), equalTo(expected)); } @ParameterizedTest @CsvSource(value = { // - "REPLACE; Apple juice is great; Apple; Orange; SELECT REPLACE('Apple juice is great', 'Apple', 'Orange')", // - "TRANSLATE; abcd; abc; xy; SELECT TRANSLATE('abcd', 'abc', 'xy')" // + "LPAD; abc; 5; X; LPAD('abc', 5, 'X')", // + "RPAD; abc; 5; X; RPAD('abc', 5, 'X')" // }, delimiter = ';') - void testScalarFunctionThreeStrings(final String functionName, final String first, final String second, - final String third, final String expected) { - final Select select = StatementFactory.getInstance().select() // - .function(ExasolScalarFunction.valueOf(functionName), stringLiteral(first), stringLiteral(second), - stringLiteral(third)); - assertThat(select, rendersTo(expected)); + void testScalarFunctionPad(final String functionName, final String stringfirstLiteral, final int integerLiteral, + final String stringSecondLiteral, final String expected) { + final ExasolFunction function = ExasolFunction.of(ExasolScalarFunction.valueOf(functionName), + stringLiteral(stringfirstLiteral), integerLiteral(integerLiteral), stringLiteral(stringSecondLiteral)); + assertThat(renderFunction(function), equalTo(expected)); } @Test - void testScalarFunctionSubstr() { - final Select select = StatementFactory.getInstance().select() // - .function(ExasolScalarFunction.SUBSTR, "S1", stringLiteral("abcdef"), integerLiteral(2), - integerLiteral(3)); - assertThat(select, rendersTo("SELECT SUBSTR('abcdef', 2, 3) S1")); + void testScalarFunctionDegreesWithFunctionArgument() { + final ExasolFunction function = ExasolFunction.of(ExasolScalarFunction.DEGREES, + function(ExasolScalarFunction.PI)); + assertThat(renderFunction(function), equalTo("DEGREES(PI())")); } @Test - void testScalarFunctionDateToChar() { - final Select select = StatementFactory.getInstance().select() // - .function(ExasolScalarFunction.TO_CHAR, "TO_CHAR", stringLiteral("1999-12-31")); - assertThat(select, rendersTo("SELECT TO_CHAR('1999-12-31') TO_CHAR")); + void testScalarFunctionToChar() { + final ExasolFunction function = ExasolFunction.of(ExasolScalarFunction.TO_CHAR, doubleLiteral(12345.67890), + stringLiteral("9999999.999999999")); + assertThat(renderFunction(function), equalTo("TO_CHAR(12345.6789, '9999999.999999999')")); } @Test - void testScalarFunctionTrim() { - final Select select = StatementFactory.getInstance().select() // - .function(ExasolScalarFunction.TRIM, stringLiteral("abcdef"), stringLiteral("acf")); - assertThat(select, rendersTo("SELECT TRIM('abcdef', 'acf')")); + void testScalarFunctionRound() { + final ExasolFunction function = ExasolFunction.of(ExasolScalarFunction.ROUND, doubleLiteral(123.456), + integerLiteral(2)); + assertThat(renderFunction(function), equalTo("ROUND(123.456, 2)")); } @Test - void testScalarFunctionAddYears() { - final Select select = StatementFactory.getInstance().select() // - .function(ExasolScalarFunction.ADD_YEARS, "AY1", stringLiteral("2000-02-29"), integerLiteral(1)) // - .function(ExasolScalarFunction.ADD_YEARS, "AY2", stringLiteral("2005-01-31 12:00:00"), - integerLiteral(-1)); - assertThat(select, - rendersTo("SELECT ADD_YEARS('2000-02-29', 1) AY1, ADD_YEARS('2005-01-31 12:00:00', -1) AY2")); + void testScalarFunctionInsert() { + final ExasolFunction function = ExasolFunction.of(ExasolScalarFunction.INSERT, stringLiteral("abc"), + integerLiteral(2), integerLiteral(2), stringLiteral("xxx")); + assertThat(renderFunction(function), equalTo("INSERT('abc', 2, 2, 'xxx')")); + } + + @Test + void testScalarFunctionLength() { + final ExasolFunction function = ExasolFunction.of(ExasolScalarFunction.LENGTH, column("s")); + assertThat(renderFunction(function), equalTo("LENGTH(s)")); } @Test void testScalarFunctionWithoutBrackets() { - final Select select = StatementFactory.getInstance().select() // - .function(ExasolScalarFunction.SYSDATE); - assertThat(select, rendersTo("SELECT SYSDATE")); + final ExasolFunction function = ExasolFunction.of(ExasolScalarFunction.SYSDATE); + assertThat(renderFunction(function), equalTo("SYSDATE")); } @Test void testScalarFunctionCoalesce() { - final Select select = StatementFactory.getInstance().select() // - .function(ExasolScalarFunction.COALESCE, "COALES", nullLiteral(), stringLiteral("abc"), nullLiteral(), - stringLiteral("xyz")); - assertThat(select, rendersTo("SELECT COALESCE(NULL, 'abc', NULL, 'xyz') COALES")); + final ExasolFunction function = ExasolFunction.of(ExasolScalarFunction.COALESCE, nullLiteral(), + stringLiteral("abc"), nullLiteral(), stringLiteral("xyz")); + assertThat(renderFunction(function), equalTo("COALESCE(NULL, 'abc', NULL, 'xyz')")); } } \ No newline at end of file