[jOOQ/jOOQ#17686] Add support for PostgreSQL's STRING_TO_ARRAY and ARRAY_TO_STRING functions

This commit is contained in:
Lukas Eder 2024-11-28 13:47:40 +01:00
parent a7c9cee82f
commit 77837a966b
6 changed files with 640 additions and 1 deletions

View File

@ -0,0 +1,207 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Other licenses:
* -----------------------------------------------------------------------------
* Commercial licenses for this work are available. These replace the above
* Apache-2.0 license and offer limited warranties, support, maintenance, and
* commercial database integrations.
*
* For more information, please visit: https://www.jooq.org/legal/licensing
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package org.jooq.impl;
import static org.jooq.impl.DSL.*;
import static org.jooq.impl.Internal.*;
import static org.jooq.impl.Keywords.*;
import static org.jooq.impl.Names.*;
import static org.jooq.impl.SQLDataType.*;
import static org.jooq.impl.Tools.*;
import static org.jooq.impl.Tools.BooleanDataKey.*;
import static org.jooq.impl.Tools.ExtendedDataKey.*;
import static org.jooq.impl.Tools.SimpleDataKey.*;
import static org.jooq.SQLDialect.*;
import org.jooq.*;
import org.jooq.Function1;
import org.jooq.Record;
import org.jooq.conf.ParamType;
import org.jooq.tools.StringUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
/**
* The <code>ARRAY TO STRING</code> statement.
*/
@SuppressWarnings({ "rawtypes", "unchecked", "unused" })
final class ArrayToString<T>
extends
AbstractField<String>
implements
QOM.ArrayToString<T>
{
final Field<? extends Object[]> array;
final Field<String> delimiter;
final Field<String> nullString;
ArrayToString(
Field<? extends Object[]> array,
Field<String> delimiter
) {
super(
N_ARRAY_TO_STRING,
allNotNull(VARCHAR, array, delimiter)
);
this.array = nullSafeNotNull(array, OTHER.array());
this.delimiter = nullSafeNotNull(delimiter, VARCHAR);
this.nullString = null;
}
ArrayToString(
Field<? extends Object[]> array,
Field<String> delimiter,
Field<String> nullString
) {
super(
N_ARRAY_TO_STRING,
allNotNull(VARCHAR, array, delimiter, nullString)
);
this.array = nullSafeNotNull(array, OTHER.array());
this.delimiter = nullSafeNotNull(delimiter, VARCHAR);
this.nullString = nullSafeNotNull(nullString, VARCHAR);
}
// -------------------------------------------------------------------------
// XXX: QueryPart API
// -------------------------------------------------------------------------
@Override
final boolean parenthesised(Context<?> ctx) {
return true;
}
@Override
public final void accept(Context<?> ctx) {
switch (ctx.family()) {
default:
if (nullString != null)
ctx.visit(function(N_ARRAY_TO_STRING, getDataType(), array, delimiter, nullString));
else
ctx.visit(function(N_ARRAY_TO_STRING, getDataType(), array, delimiter));
break;
}
}
// -------------------------------------------------------------------------
// XXX: Query Object Model
// -------------------------------------------------------------------------
@Override
public final Field<? extends Object[]> $arg1() {
return array;
}
@Override
public final Field<String> $arg2() {
return delimiter;
}
@Override
public final Field<String> $arg3() {
return nullString;
}
@Override
public final QOM.ArrayToString<T> $arg1(Field<? extends Object[]> newValue) {
return $constructor().apply(newValue, $arg2(), $arg3());
}
@Override
public final QOM.ArrayToString<T> $arg2(Field<String> newValue) {
return $constructor().apply($arg1(), newValue, $arg3());
}
@Override
public final QOM.ArrayToString<T> $arg3(Field<String> newValue) {
return $constructor().apply($arg1(), $arg2(), newValue);
}
@Override
public final Function3<? super Field<? extends Object[]>, ? super Field<String>, ? super Field<String>, ? extends QOM.ArrayToString<T>> $constructor() {
return (a1, a2, a3) -> new ArrayToString<>(a1, a2, a3);
}
// -------------------------------------------------------------------------
// XXX: The Object API
// -------------------------------------------------------------------------
@Override
public boolean equals(Object that) {
if (that instanceof QOM.ArrayToString<?> o) {
return
StringUtils.equals($array(), o.$array()) &&
StringUtils.equals($delimiter(), o.$delimiter()) &&
StringUtils.equals($nullString(), o.$nullString())
;
}
else
return super.equals(that);
}
}

View File

@ -23250,6 +23250,64 @@ public class DSL {
return new ArrayReplace<>(array, search, replace);
}
/**
* The <code>ARRAY_TO_STRING</code> function.
* <p>
* Join array elements into a string.
*
* @param array The array whose elements are joined
* @param delimiter The delimiter to place between elements
* @param nullString The NULL encoding
*/
@NotNull
@Support({ POSTGRES, YUGABYTEDB })
public static Field<String> arrayToString(Object[] array, @Stringly.Param String delimiter, @Stringly.Param String nullString) {
return new ArrayToString<>(Tools.field(array), Tools.field(delimiter), Tools.field(nullString));
}
/**
* The <code>ARRAY_TO_STRING</code> function.
* <p>
* Join array elements into a string.
*
* @param array The array whose elements are joined
* @param delimiter The delimiter to place between elements
* @param nullString The NULL encoding
*/
@NotNull
@Support({ POSTGRES, YUGABYTEDB })
public static Field<String> arrayToString(Field<? extends Object[]> array, Field<String> delimiter, Field<String> nullString) {
return new ArrayToString<>(array, delimiter, nullString);
}
/**
* The <code>ARRAY_TO_STRING</code> function.
* <p>
* Join array elements into a string.
*
* @param array The array whose elements are joined
* @param delimiter The delimiter to place between elements
*/
@NotNull
@Support({ POSTGRES, YUGABYTEDB })
public static Field<String> arrayToString(Object[] array, @Stringly.Param String delimiter) {
return new ArrayToString<>(Tools.field(array), Tools.field(delimiter));
}
/**
* The <code>ARRAY_TO_STRING</code> function.
* <p>
* Join array elements into a string.
*
* @param array The array whose elements are joined
* @param delimiter The delimiter to place between elements
*/
@NotNull
@Support({ POSTGRES, YUGABYTEDB })
public static Field<String> arrayToString(Field<? extends Object[]> array, Field<String> delimiter) {
return new ArrayToString<>(array, delimiter);
}
/**
* The <code>ARRAY_FILTER</code> function.
* <p>
@ -23530,6 +23588,64 @@ public class DSL {
return new ArrayNoneMatch<>(array, predicate);
}
/**
* The <code>STRING_TO_ARRAY</code> function.
* <p>
* Split a string into array elements.
*
* @param string The string to split
* @param delimiter The delimiter to parse between elements
* @param nullString The NULL encoding
*/
@NotNull
@Support({ POSTGRES, YUGABYTEDB })
public static Field<String[]> stringToArray(@Stringly.Param String string, @Stringly.Param String delimiter, @Stringly.Param String nullString) {
return new StringToArray(Tools.field(string), Tools.field(delimiter), Tools.field(nullString));
}
/**
* The <code>STRING_TO_ARRAY</code> function.
* <p>
* Split a string into array elements.
*
* @param string The string to split
* @param delimiter The delimiter to parse between elements
* @param nullString The NULL encoding
*/
@NotNull
@Support({ POSTGRES, YUGABYTEDB })
public static Field<String[]> stringToArray(Field<String> string, Field<String> delimiter, Field<String> nullString) {
return new StringToArray(string, delimiter, nullString);
}
/**
* The <code>STRING_TO_ARRAY</code> function.
* <p>
* Split a string into array elements.
*
* @param string The string to split
* @param delimiter The delimiter to parse between elements
*/
@NotNull
@Support({ POSTGRES, YUGABYTEDB })
public static Field<String[]> stringToArray(@Stringly.Param String string, @Stringly.Param String delimiter) {
return new StringToArray(Tools.field(string), Tools.field(delimiter));
}
/**
* The <code>STRING_TO_ARRAY</code> function.
* <p>
* Split a string into array elements.
*
* @param string The string to split
* @param delimiter The delimiter to parse between elements
*/
@NotNull
@Support({ POSTGRES, YUGABYTEDB })
public static Field<String[]> stringToArray(Field<String> string, Field<String> delimiter) {
return new StringToArray(string, delimiter);
}
// -------------------------------------------------------------------------
// Utility functions
// -------------------------------------------------------------------------

View File

@ -262,7 +262,6 @@ final class Names {
static final Name N_SEQ8 = systemName("seq8");
static final Name N_SHL = systemName("shl");
static final Name N_SHR = systemName("shr");
static final Name N_SPLIT = systemName("split");
static final Name N_SQL_TSI_DAY = systemName("sql_tsi_day");
static final Name N_SQL_TSI_FRAC_SECOND = systemName("sql_tsi_frac_second");
static final Name N_SQL_TSI_HOUR = systemName("sql_tsi_hour");
@ -355,6 +354,7 @@ final class Names {
static final Name N_ARRAY_PREPEND = systemName("array_prepend");
static final Name N_ARRAY_REMOVE = systemName("array_remove");
static final Name N_ARRAY_REPLACE = systemName("array_replace");
static final Name N_ARRAY_TO_STRING = systemName("array_to_string");
static final Name N_ARRAY_TRANSFORM = systemName("array_transform");
static final Name N_ASC = systemName("asc");
static final Name N_ASCII = systemName("ascii");
@ -593,6 +593,7 @@ final class Names {
static final Name N_SIN = systemName("sin");
static final Name N_SINH = systemName("sinh");
static final Name N_SPACE = systemName("space");
static final Name N_SPLIT = systemName("split");
static final Name N_SPLIT_PART = systemName("split_part");
static final Name N_SQR = systemName("sqr");
static final Name N_SQRT = systemName("sqrt");
@ -600,6 +601,7 @@ final class Names {
static final Name N_STARTS_WITH = systemName("starts_with");
static final Name N_STDDEV_POP = systemName("stddev_pop");
static final Name N_STDDEV_SAMP = systemName("stddev_samp");
static final Name N_STRING_TO_ARRAY = systemName("string_to_array");
static final Name N_STRREVERSE = systemName("strreverse");
static final Name N_STRTOK = systemName("strtok");
static final Name N_STR_SPLIT = systemName("str_split");

View File

@ -9063,6 +9063,8 @@ final class DefaultParseContext extends AbstractScope implements ParseContext {
return parseFunctionArgs2((f1, f2) -> arrayRemove((Field<Void[]>) f1, (Field<Void>) f2));
else if (parseFunctionNameIf("ARRAY_REPLACE"))
return parseFunctionArgs3((f1, f2, f3) -> arrayReplace((Field<Void[]>) f1, (Field<Void>) f2, (Field<Void>) f3));
else if (parseFunctionNameIf("ARRAY_TO_STRING"))
return parseFunctionArgs3(DSL::arrayToString, DSL::arrayToString);
else if ((field = parseFieldArrayConstructIf()) != null)
return field;
else if (parseFunctionNameIf("ADD"))
@ -9618,6 +9620,8 @@ final class DefaultParseContext extends AbstractScope implements ParseContext {
return space((Field) parseFieldParenthesised());
else if (parseFunctionNameIf("SPLIT_PART"))
return parseFunctionArgs3(DSL::splitPart);
else if (parseFunctionNameIf("SPLIT", "STRING_TO_ARRAY"))
return parseFunctionArgs3(DSL::stringToArray, DSL::stringToArray);
else if (parseFunctionNameIf("STR_REPLACE"))
return parseFunctionArgs3(DSL::replace, DSL::replace);
else if (parseFunctionNameIf("STARTS_WITH", "startsWith"))

View File

@ -6727,6 +6727,53 @@ public final class QOM {
@NotNull default ArrayReplace<T> $replace(Field<T> newReplace) { return $arg3(newReplace); }
}
/**
* The <code>ARRAY TO STRING</code> function.
* <p>
* Join array elements into a string.
*/
public /*sealed*/ interface ArrayToString<T>
extends
UOperator3<Field<? extends Object[]>, Field<String>, Field<String>, ArrayToString<T>>,
org.jooq.Field<String>
//permits
// ArrayToString
{
/**
* The array whose elements are joined
*/
@NotNull default Field<? extends Object[]> $array() { return $arg1(); }
/**
* The array whose elements are joined
*/
@CheckReturnValue
@NotNull default ArrayToString<T> $array(Field<? extends Object[]> newArray) { return $arg1(newArray); }
/**
* The delimiter to place between elements
*/
@NotNull default Field<String> $delimiter() { return $arg2(); }
/**
* The delimiter to place between elements
*/
@CheckReturnValue
@NotNull default ArrayToString<T> $delimiter(Field<String> newDelimiter) { return $arg2(newDelimiter); }
/**
* The NULL encoding
*/
@Nullable default Field<String> $nullString() { return $arg3(); }
/**
* The NULL encoding
*/
@CheckReturnValue
@NotNull default ArrayToString<T> $nullString(Field<String> newNullString) { return $arg3(newNullString); }
}
/**
* The <code>ARRAY FILTER</code> function.
* <p>
@ -6907,6 +6954,53 @@ public final class QOM {
@NotNull default ArrayNoneMatch<T> $predicate(Lambda1<Field<T>, Condition> newPredicate) { return $arg2(newPredicate); }
}
/**
* The <code>STRING TO ARRAY</code> function.
* <p>
* Split a string into array elements.
*/
public /*sealed*/ interface StringToArray
extends
UOperator3<Field<String>, Field<String>, Field<String>, StringToArray>,
org.jooq.Field<String[]>
//permits
// StringToArray
{
/**
* The string to split
*/
@NotNull default Field<String> $string() { return $arg1(); }
/**
* The string to split
*/
@CheckReturnValue
@NotNull default StringToArray $string(Field<String> newString) { return $arg1(newString); }
/**
* The delimiter to parse between elements
*/
@NotNull default Field<String> $delimiter() { return $arg2(); }
/**
* The delimiter to parse between elements
*/
@CheckReturnValue
@NotNull default StringToArray $delimiter(Field<String> newDelimiter) { return $arg2(newDelimiter); }
/**
* The NULL encoding
*/
@Nullable default Field<String> $nullString() { return $arg3(); }
/**
* The NULL encoding
*/
@CheckReturnValue
@NotNull default StringToArray $nullString(Field<String> newNullString) { return $arg3(newNullString); }
}
/**
* The <code>NVL</code> function.
* <p>

View File

@ -0,0 +1,216 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Other licenses:
* -----------------------------------------------------------------------------
* Commercial licenses for this work are available. These replace the above
* Apache-2.0 license and offer limited warranties, support, maintenance, and
* commercial database integrations.
*
* For more information, please visit: https://www.jooq.org/legal/licensing
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package org.jooq.impl;
import static org.jooq.impl.DSL.*;
import static org.jooq.impl.Internal.*;
import static org.jooq.impl.Keywords.*;
import static org.jooq.impl.Names.*;
import static org.jooq.impl.SQLDataType.*;
import static org.jooq.impl.Tools.*;
import static org.jooq.impl.Tools.BooleanDataKey.*;
import static org.jooq.impl.Tools.ExtendedDataKey.*;
import static org.jooq.impl.Tools.SimpleDataKey.*;
import static org.jooq.SQLDialect.*;
import org.jooq.*;
import org.jooq.Function1;
import org.jooq.Record;
import org.jooq.conf.ParamType;
import org.jooq.tools.StringUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
/**
* The <code>STRING TO ARRAY</code> statement.
*/
@SuppressWarnings({ "rawtypes", "unchecked", "unused" })
final class StringToArray
extends
AbstractField<String[]>
implements
QOM.StringToArray
{
final Field<String> string;
final Field<String> delimiter;
final Field<String> nullString;
StringToArray(
Field<String> string,
Field<String> delimiter
) {
super(
N_STRING_TO_ARRAY,
allNotNull(VARCHAR.array(), string, delimiter)
);
this.string = nullSafeNotNull(string, VARCHAR);
this.delimiter = nullSafeNotNull(delimiter, VARCHAR);
this.nullString = null;
}
StringToArray(
Field<String> string,
Field<String> delimiter,
Field<String> nullString
) {
super(
N_STRING_TO_ARRAY,
allNotNull(VARCHAR.array(), string, delimiter, nullString)
);
this.string = nullSafeNotNull(string, VARCHAR);
this.delimiter = nullSafeNotNull(delimiter, VARCHAR);
this.nullString = nullSafeNotNull(nullString, VARCHAR);
}
// -------------------------------------------------------------------------
// XXX: QueryPart API
// -------------------------------------------------------------------------
@Override
final boolean parenthesised(Context<?> ctx) {
return true;
}
@Override
public final void accept(Context<?> ctx) {
switch (ctx.family()) {
default:
if (nullString != null)
ctx.visit(function(N_STRING_TO_ARRAY, getDataType(), string, delimiter, nullString));
else
ctx.visit(function(N_STRING_TO_ARRAY, getDataType(), string, delimiter));
break;
}
}
// -------------------------------------------------------------------------
// XXX: Query Object Model
// -------------------------------------------------------------------------
@Override
public final Field<String> $arg1() {
return string;
}
@Override
public final Field<String> $arg2() {
return delimiter;
}
@Override
public final Field<String> $arg3() {
return nullString;
}
@Override
public final QOM.StringToArray $arg1(Field<String> newValue) {
return $constructor().apply(newValue, $arg2(), $arg3());
}
@Override
public final QOM.StringToArray $arg2(Field<String> newValue) {
return $constructor().apply($arg1(), newValue, $arg3());
}
@Override
public final QOM.StringToArray $arg3(Field<String> newValue) {
return $constructor().apply($arg1(), $arg2(), newValue);
}
@Override
public final Function3<? super Field<String>, ? super Field<String>, ? super Field<String>, ? extends QOM.StringToArray> $constructor() {
return (a1, a2, a3) -> new StringToArray(a1, a2, a3);
}
// -------------------------------------------------------------------------
// XXX: The Object API
// -------------------------------------------------------------------------
@Override
public boolean equals(Object that) {
if (that instanceof QOM.StringToArray o) {
return
StringUtils.equals($string(), o.$string()) &&
StringUtils.equals($delimiter(), o.$delimiter()) &&
StringUtils.equals($nullString(), o.$nullString())
;
}
else
return super.equals(that);
}
}