[#894] Move functions from Field<?> to new org.jooq.impl.SQL and make them static - moved string functions

This commit is contained in:
Lukas Eder 2011-11-05 18:04:32 +00:00
parent 98fcc1a1bb
commit 081d0e71a1
16 changed files with 709 additions and 606 deletions

View File

@ -2149,7 +2149,7 @@ public class DefaultGenerator implements Generator {
version = properties.getProperty("version");
}
catch (Exception e) {
version = "unknown";
version = "2.0.0";
}
}

View File

@ -35,6 +35,7 @@
*/
package org.jooq.util.ingres;
import static org.jooq.impl.Factory.trim;
import static org.jooq.util.ingres.ingres.tables.IiconstraintIndexes.IICONSTRAINT_INDEXES;
import static org.jooq.util.ingres.ingres.tables.Iiconstraints.IICONSTRAINTS;
import static org.jooq.util.ingres.ingres.tables.IiindexColumns.IIINDEX_COLUMNS;
@ -85,9 +86,9 @@ public class IngresDatabase extends AbstractDatabase {
@Override
protected void loadPrimaryKeys(DefaultRelations relations) throws SQLException {
for (Record record : fetchKeys("P")) {
String key = record.getValue(Iiconstraints.CONSTRAINT_NAME.trim());
String tableName = record.getValue(Iiconstraints.TABLE_NAME.trim());
String columnName = record.getValue(IiindexColumns.COLUMN_NAME.trim());
String key = record.getValue(trim(Iiconstraints.CONSTRAINT_NAME));
String tableName = record.getValue(trim(Iiconstraints.TABLE_NAME));
String columnName = record.getValue(trim(IiindexColumns.COLUMN_NAME));
TableDefinition table = getTable(tableName);
if (table != null) {
@ -99,9 +100,9 @@ public class IngresDatabase extends AbstractDatabase {
@Override
protected void loadUniqueKeys(DefaultRelations relations) throws SQLException {
for (Record record : fetchKeys("U")) {
String key = record.getValue(Iiconstraints.CONSTRAINT_NAME.trim());
String tableName = record.getValue(Iiconstraints.TABLE_NAME.trim());
String columnName = record.getValue(IiindexColumns.COLUMN_NAME.trim());
String key = record.getValue(trim(Iiconstraints.CONSTRAINT_NAME));
String tableName = record.getValue(trim(Iiconstraints.TABLE_NAME));
String columnName = record.getValue(trim(IiindexColumns.COLUMN_NAME));
TableDefinition table = getTable(tableName);
if (table != null) {
@ -112,9 +113,9 @@ public class IngresDatabase extends AbstractDatabase {
private List<Record> fetchKeys(String constraintType) {
return create().select(
Iiconstraints.TABLE_NAME.trim(),
Iiconstraints.CONSTRAINT_NAME.trim(),
IiindexColumns.COLUMN_NAME.trim())
trim(Iiconstraints.TABLE_NAME),
trim(Iiconstraints.CONSTRAINT_NAME),
trim(IiindexColumns.COLUMN_NAME))
.from(IICONSTRAINTS)
.join(IICONSTRAINT_INDEXES)
.on(Iiconstraints.CONSTRAINT_NAME.equal(IiconstraintIndexes.CONSTRAINT_NAME))
@ -138,10 +139,10 @@ public class IngresDatabase extends AbstractDatabase {
protected void loadForeignKeys(DefaultRelations relations) throws SQLException {
Result<Record> result = create()
.select(
IirefConstraints.REF_CONSTRAINT_NAME.trim(),
IirefConstraints.UNIQUE_CONSTRAINT_NAME.trim(),
IirefConstraints.REF_TABLE_NAME.trim(),
IiindexColumns.COLUMN_NAME.trim())
trim(IirefConstraints.REF_CONSTRAINT_NAME),
trim(IirefConstraints.UNIQUE_CONSTRAINT_NAME),
trim(IirefConstraints.REF_TABLE_NAME),
trim(IiindexColumns.COLUMN_NAME))
.from(IICONSTRAINTS)
.join(IIREF_CONSTRAINTS)
.on(Iiconstraints.CONSTRAINT_NAME.equal(IirefConstraints.REF_CONSTRAINT_NAME))
@ -164,10 +165,10 @@ public class IngresDatabase extends AbstractDatabase {
.fetch();
for (Record record : result) {
String foreignKey = record.getValue(IirefConstraints.REF_CONSTRAINT_NAME.trim());
String foreignKeyTable = record.getValue(IirefConstraints.REF_TABLE_NAME.trim());
String foreignKeyColumn = record.getValue(IiindexColumns.COLUMN_NAME.trim());
String uniqueKey = record.getValue(IirefConstraints.UNIQUE_CONSTRAINT_NAME.trim());
String foreignKey = record.getValue(trim(IirefConstraints.REF_CONSTRAINT_NAME));
String foreignKeyTable = record.getValue(trim(IirefConstraints.REF_TABLE_NAME));
String foreignKeyColumn = record.getValue(trim(IiindexColumns.COLUMN_NAME));
String uniqueKey = record.getValue(trim(IirefConstraints.UNIQUE_CONSTRAINT_NAME));
TableDefinition referencingTable = getTable(foreignKeyTable);
@ -183,18 +184,18 @@ public class IngresDatabase extends AbstractDatabase {
List<SequenceDefinition> result = new ArrayList<SequenceDefinition>();
for (Record record : create().select(
Iisequences.SEQ_NAME.trim(),
Iisequences.DATA_TYPE.trim())
trim(Iisequences.SEQ_NAME),
trim(Iisequences.DATA_TYPE))
.from(IISEQUENCES)
.where(Iisequences.SEQ_OWNER.equal(getSchemaName()))
.orderBy(Iisequences.SEQ_NAME)
.fetch()) {
DataTypeDefinition type = new DefaultDataTypeDefinition(this,
record.getValue(Iisequences.DATA_TYPE.trim()), 0, 0);
record.getValue(trim(Iisequences.DATA_TYPE)), 0, 0);
result.add(new DefaultSequenceDefinition(
getSchema(), record.getValue(Iisequences.SEQ_NAME.trim()), type));
getSchema(), record.getValue(trim(Iisequences.SEQ_NAME)), type));
}
return result;
@ -204,13 +205,13 @@ public class IngresDatabase extends AbstractDatabase {
protected List<TableDefinition> getTables0() throws SQLException {
List<TableDefinition> result = new ArrayList<TableDefinition>();
for (Record record : create().select(Iitables.TABLE_NAME.trim())
for (Record record : create().select(trim(Iitables.TABLE_NAME))
.from(IITABLES)
.where(Iitables.TABLE_OWNER.equal(getSchemaName()))
.orderBy(Iitables.TABLE_NAME.trim())
.orderBy(trim(Iitables.TABLE_NAME))
.fetch()) {
result.add(new IngresTableDefinition(this, record.getValue(Iitables.TABLE_NAME.trim())));
result.add(new IngresTableDefinition(this, record.getValue(trim(Iitables.TABLE_NAME))));
}
return result;

View File

@ -35,6 +35,7 @@
*/
package org.jooq.util.ingres;
import static org.jooq.impl.Factory.trim;
import static org.jooq.util.ingres.ingres.tables.Iicolumns.IICOLUMNS;
import java.sql.SQLException;
@ -65,19 +66,19 @@ public class IngresTableDefinition extends AbstractTableDefinition {
for (Record record : create().select(
Iicolumns.COLUMN_SEQUENCE,
Iicolumns.COLUMN_NAME.trim(),
Iicolumns.COLUMN_DATATYPE.trim(),
trim(Iicolumns.COLUMN_NAME),
trim(Iicolumns.COLUMN_DATATYPE),
Iicolumns.COLUMN_LENGTH,
Iicolumns.COLUMN_SCALE,
Iicolumns.COLUMN_ALWAYS_IDENT,
Iicolumns.COLUMN_BYDEFAULT_IDENT)
.from(IICOLUMNS)
.where(Iicolumns.TABLE_OWNER.equal(getSchemaName()))
.and(Iicolumns.TABLE_NAME.trim().equal(getName()))
.and(trim(Iicolumns.TABLE_NAME).equal(getName()))
.orderBy(Iicolumns.COLUMN_SEQUENCE)
.fetch()) {
String typeName = record.getValue(Iicolumns.COLUMN_DATATYPE.trim());
String typeName = record.getValue(trim(Iicolumns.COLUMN_DATATYPE));
// [#664] INTEGER types come with a COLUMN_LENGTH in bytes
// This is important to distinguish BIGINT, INT, SMALLINT, TINYINT
@ -114,7 +115,7 @@ public class IngresTableDefinition extends AbstractTableDefinition {
ColumnDefinition column = new DefaultColumnDefinition(
getDatabase().getTable(getName()),
record.getValue(Iicolumns.COLUMN_NAME.trim()),
record.getValue(trim(Iicolumns.COLUMN_NAME)),
record.getValue(Iicolumns.COLUMN_SEQUENCE),
type,
record.getValueAsBoolean(Iicolumns.COLUMN_ALWAYS_IDENT, false) ||

View File

@ -39,6 +39,7 @@ package org.jooq.util.postgres;
import static org.jooq.impl.Factory.count;
import static org.jooq.impl.Factory.decode;
import static org.jooq.impl.Factory.exists;
import static org.jooq.impl.Factory.upper;
import static org.jooq.impl.Factory.val;
import static org.jooq.util.postgres.information_schema.tables.Attributes.ATTRIBUTES;
import static org.jooq.util.postgres.information_schema.tables.KeyColumnUsage.KEY_COLUMN_USAGE;
@ -284,7 +285,7 @@ public class PostgresDatabase extends AbstractDatabase {
.from(PARAMETERS)
.where(Parameters.SPECIFIC_SCHEMA.equal(r1.getField(Routines.SPECIFIC_SCHEMA)))
.and(Parameters.SPECIFIC_NAME.equal(r1.getField(Routines.SPECIFIC_NAME)))
.and(Parameters.PARAMETER_MODE.upper().notEqual("IN"))), val("void"))
.and(upper(Parameters.PARAMETER_MODE).notEqual("IN"))), val("void"))
.otherwise(r1.getField(Routines.DATA_TYPE)).as("data_type"),
r1.getField(Routines.NUMERIC_PRECISION),
r1.getField(Routines.NUMERIC_SCALE),

View File

@ -30,6 +30,8 @@
*/
package org.jooq.util.sybase;
import static org.jooq.impl.Factory.concat;
import static org.jooq.impl.Factory.val;
import static org.jooq.util.sybase.sys.tables.Sysfkey.SYSFKEY;
import static org.jooq.util.sybase.sys.tables.Sysidx.SYSIDX;
import static org.jooq.util.sybase.sys.tables.Sysidxcol.SYSIDXCOL;
@ -81,7 +83,7 @@ public class SybaseDatabase extends AbstractDatabase {
@Override
protected void loadPrimaryKeys(DefaultRelations relations) throws SQLException {
for (Record record : create().select(
Systable.TABLE_NAME.concat("_").concat(Sysidx.INDEX_NAME).as("indexName"),
concat(Systable.TABLE_NAME, val("_"), Sysidx.INDEX_NAME).as("indexName"),
Systable.TABLE_NAME,
Systabcol.COLUMN_NAME)
.from(SYSIDX)
@ -112,7 +114,7 @@ public class SybaseDatabase extends AbstractDatabase {
@Override
protected void loadUniqueKeys(DefaultRelations r) throws SQLException {
for (Record record : create().select(
Systable.TABLE_NAME.concat("_").concat(Sysidx.INDEX_NAME).as("indexName"),
concat(Systable.TABLE_NAME, val("_"), Sysidx.INDEX_NAME).as("indexName"),
Systable.TABLE_NAME,
Systabcol.COLUMN_NAME)
.from(SYSIDX)
@ -149,16 +151,16 @@ public class SybaseDatabase extends AbstractDatabase {
Table<SystableRecord> ukTable = SYSTABLE.as("ukTable");
for (Record record : create().select(
fkTable.getField(Systable.TABLE_NAME)
.concat("_")
.concat(fkIndex.getField(Sysidx.INDEX_NAME))
.as("fkIndexName"),
concat(
fkTable.getField(Systable.TABLE_NAME),
val("_"),
fkIndex.getField(Sysidx.INDEX_NAME)).as("fkIndexName"),
fkTable.getField(Systable.TABLE_NAME),
Systabcol.COLUMN_NAME,
ukTable.getField(Systable.TABLE_NAME)
.concat("_")
.concat(ukIndex.getField(Sysidx.INDEX_NAME))
.as("ukIndexName"))
concat(
ukTable.getField(Systable.TABLE_NAME),
val("_"),
ukIndex.getField(Sysidx.INDEX_NAME)).as("ukIndexName"))
.from(SYSFKEY)
.join(fkIndex)
.on(Sysfkey.FOREIGN_INDEX_ID.equal(fkIndex.getField(Sysidx.INDEX_ID)))

View File

@ -49,13 +49,17 @@ import static org.jooq.SQLDialect.SQLSERVER;
import static org.jooq.SQLDialect.SYBASE;
import static org.jooq.impl.Factory.abs;
import static org.jooq.impl.Factory.acos;
import static org.jooq.impl.Factory.ascii;
import static org.jooq.impl.Factory.asin;
import static org.jooq.impl.Factory.atan;
import static org.jooq.impl.Factory.atan2;
import static org.jooq.impl.Factory.avg;
import static org.jooq.impl.Factory.bitLength;
import static org.jooq.impl.Factory.cast;
import static org.jooq.impl.Factory.castNull;
import static org.jooq.impl.Factory.ceil;
import static org.jooq.impl.Factory.charLength;
import static org.jooq.impl.Factory.concat;
import static org.jooq.impl.Factory.cos;
import static org.jooq.impl.Factory.cosh;
import static org.jooq.impl.Factory.cot;
@ -83,34 +87,44 @@ import static org.jooq.impl.Factory.groupingId;
import static org.jooq.impl.Factory.groupingSets;
import static org.jooq.impl.Factory.lag;
import static org.jooq.impl.Factory.lead;
import static org.jooq.impl.Factory.length;
import static org.jooq.impl.Factory.ln;
import static org.jooq.impl.Factory.log;
import static org.jooq.impl.Factory.lower;
import static org.jooq.impl.Factory.lpad;
import static org.jooq.impl.Factory.max;
import static org.jooq.impl.Factory.median;
import static org.jooq.impl.Factory.min;
import static org.jooq.impl.Factory.nullif;
import static org.jooq.impl.Factory.nvl;
import static org.jooq.impl.Factory.nvl2;
import static org.jooq.impl.Factory.octetLength;
import static org.jooq.impl.Factory.one;
import static org.jooq.impl.Factory.percentRank;
import static org.jooq.impl.Factory.pi;
import static org.jooq.impl.Factory.position;
import static org.jooq.impl.Factory.power;
import static org.jooq.impl.Factory.rad;
import static org.jooq.impl.Factory.rand;
import static org.jooq.impl.Factory.rank;
import static org.jooq.impl.Factory.repeat;
import static org.jooq.impl.Factory.replace;
import static org.jooq.impl.Factory.rollup;
import static org.jooq.impl.Factory.round;
import static org.jooq.impl.Factory.rowNumber;
import static org.jooq.impl.Factory.rpad;
import static org.jooq.impl.Factory.sign;
import static org.jooq.impl.Factory.sin;
import static org.jooq.impl.Factory.sinh;
import static org.jooq.impl.Factory.sqrt;
import static org.jooq.impl.Factory.stddevPop;
import static org.jooq.impl.Factory.stddevSamp;
import static org.jooq.impl.Factory.substring;
import static org.jooq.impl.Factory.sum;
import static org.jooq.impl.Factory.table;
import static org.jooq.impl.Factory.tan;
import static org.jooq.impl.Factory.tanh;
import static org.jooq.impl.Factory.trim;
import static org.jooq.impl.Factory.trueCondition;
import static org.jooq.impl.Factory.two;
import static org.jooq.impl.Factory.val;
@ -863,7 +877,7 @@ public abstract class jOOQAbstractTest<
return;
}
Field<?> user = currentUser().lower().trim();
Field<?> user = trim(lower(currentUser()));
Record record = create().select(user).fetchOne();
assertTrue(Arrays.asList("test", "db2admin", "sa", "root@localhost", "postgres", "dbo", "dba")
@ -4586,7 +4600,7 @@ public abstract class jOOQAbstractTest<
q2.addFrom(a);
q2.addJoin(b, b_authorID.equal(a_authorID));
q2.addConditions(b_title.notEqual("1984"));
q2.addOrderBy(b_title.lower());
q2.addOrderBy(lower(b_title));
int rows1 = q1.execute();
int rows2 = q2.execute();
@ -4852,8 +4866,8 @@ public abstract class jOOQAbstractTest<
create().select(val(2)),
create().select(val(3).add(4)),
create().select(val(3).add(4)),
create().select(val(" test ").trim()),
create().select(val(" test ").trim()))
create().select(trim(" test ")),
create().select(trim(" test ")))
.fetch();
assertEquals(1, result.size());
@ -4863,7 +4877,7 @@ public abstract class jOOQAbstractTest<
assertEquals(Integer.valueOf(2), result.getValue(0, 3));
assertEquals(Integer.valueOf(7), result.getValue(0, val(3).add(4)));
assertEquals(Integer.valueOf(7), result.getValue(0, 5));
assertEquals("test", result.getValue(0, val(" test ").trim()));
assertEquals("test", result.getValue(0, trim(" test ")));
assertEquals("test", result.getValue(0, 7));
result =
@ -4874,8 +4888,8 @@ public abstract class jOOQAbstractTest<
create().select(val(2)).asField(),
create().select(val(3).add(4)).asField(),
create().select(val(3).add(4)).asField(),
create().select(val(" test ").trim()).asField(),
create().select(val(" test ").trim()).asField())
create().select(trim(" test ")).asField(),
create().select(trim(" test ")).asField())
.fetch();
assertEquals(1, result.size());
@ -5458,26 +5472,19 @@ public abstract class jOOQAbstractTest<
public void testFunctionsOnStrings() throws Exception {
// Trimming
assertEquals("abc", create().select(val("abc").trim()).fetchOne(0));
assertEquals("abc", create().select(val("abc ").trim()).fetchOne(0));
assertEquals("abc", create().select(val(" abc").trim()).fetchOne(0));
assertEquals("abc", create().select(val(" abc ").trim()).fetchOne(0));
assertEquals("abc", create().select(trim("abc")).fetchOne(0));
assertEquals("abc", create().select(trim("abc ")).fetchOne(0));
assertEquals("abc", create().select(trim(" abc")).fetchOne(0));
assertEquals("abc", create().select(trim(" abc ")).fetchOne(0));
// String concatenation
assertEquals("abc", create().select(val("a").concat("b", "c")).fetchOne(0));
assertEquals("abc", create().select(concat("a", "b", "c")).fetchOne(0));
assertEquals("George Orwell", create()
.select(TAuthor_FIRST_NAME().concat(" ").concat(TAuthor_LAST_NAME()))
.select(concat(TAuthor_FIRST_NAME(), val(" "), TAuthor_LAST_NAME()))
.from(TAuthor())
.where(TAuthor_FIRST_NAME().equal("George")).fetchOne(0));
// Derby cannot easily cast numbers to strings...
if (getDialect() != SQLDialect.DERBY) {
assertEquals("1ab45", create().select(val(1).concat("ab", "45")).fetchOne(0));
assertEquals("1ab45", create().select(val(1).concat(val("ab"), val(45))).fetchOne(0));
}
else {
log.info("SKIPPING", "Concatenation with numbers");
}
assertEquals("1ab45", create().select(concat(val(1), val("ab"), val(45))).fetchOne(0));
// Standard String functions
SelectQuery q = create().selectQuery();
@ -5492,9 +5499,9 @@ public abstract class jOOQAbstractTest<
// These two tests will validate #154
default: {
Field<String> x = constant.replace("b", "x");
Field<String> y = constant.replace("b", "y");
Field<String> z = constant.replace("b");
Field<String> x = replace(constant, "b", "x");
Field<String> y = replace(constant, "b", "y");
Field<String> z = replace(constant, "b");
Record record = create().select(x, y, z).fetchOne();
assertEquals("axc", record.getValue(x));
@ -5503,10 +5510,10 @@ public abstract class jOOQAbstractTest<
}
}
Field<Integer> length = constant.length();
Field<Integer> charLength = constant.charLength();
Field<Integer> bitLength = constant.bitLength();
Field<Integer> octetLength = constant.octetLength();
Field<Integer> length = length(constant);
Field<Integer> charLength = charLength(constant);
Field<Integer> bitLength = bitLength(constant);
Field<Integer> octetLength = octetLength(constant);
q.addSelect(length, charLength, bitLength, octetLength);
q.execute();
@ -5537,10 +5544,10 @@ public abstract class jOOQAbstractTest<
default: {
Record result = create().select(
val("aa").rpad(4),
val("aa").rpad(4, '-'),
val("aa").lpad(4),
val("aa").lpad(4, '-')).fetchOne();
rpad(val("aa"), 4),
rpad(val("aa"), 4, "-"),
lpad(val("aa"), 4),
lpad(val("aa"), 4, "-")).fetchOne();
assertEquals("aa ", result.getValue(0));
assertEquals("aa--", result.getValue(1));
@ -5553,10 +5560,10 @@ public abstract class jOOQAbstractTest<
// SUBSTRING
Record result = create().select(
val("abcde").substring(1),
val("abcde").substring(1, 2),
val("abcde").substring(3),
val("abcde").substring(3, 2)).fetchOne();
substring(val("abcde"), 1),
substring(val("abcde"), 1, 2),
substring(val("abcde"), 3),
substring(val("abcde"), 3, 2)).fetchOne();
assertEquals("abcde", result.getValue(0));
assertEquals("ab", result.getValue(1));
@ -5565,14 +5572,14 @@ public abstract class jOOQAbstractTest<
result =
create().select(
TAuthor_FIRST_NAME().substring(2),
TAuthor_FIRST_NAME().substring(2, 2))
substring(TAuthor_FIRST_NAME(), 2),
substring(TAuthor_FIRST_NAME(), 2, 2))
.from(TAuthor())
.where(TAuthor_ID().equal(1))
.fetchOne();
assertEquals("eorge", result.getValue(TAuthor_FIRST_NAME().substring(2)));
assertEquals("eo", result.getValue(TAuthor_FIRST_NAME().substring(2, 2)));
assertEquals("eorge", result.getValue(substring(TAuthor_FIRST_NAME(), 2)));
assertEquals("eo", result.getValue(substring(TAuthor_FIRST_NAME(), 2, 2)));
// REPEAT
switch (getDialect()) {
@ -5583,9 +5590,9 @@ public abstract class jOOQAbstractTest<
default: {
result = create().select(
val("a").repeat(1),
val("ab").repeat(2),
val("abc").repeat(3)).fetchOne();
repeat("a", 1),
repeat("ab", 2),
repeat("abc", 3)).fetchOne();
assertEquals("a", result.getValue(0));
assertEquals("abab", result.getValue(1));
assertEquals("abcabcabc", result.getValue(2));
@ -5604,10 +5611,10 @@ public abstract class jOOQAbstractTest<
default:
record =
create().select(
val("A").ascii(),
val("a").ascii(),
val("-").ascii(),
val(" ").ascii()).fetchOne();
ascii("A"),
ascii("a"),
ascii("-"),
ascii(" ")).fetchOne();
assertEquals((int) 'A', (int) record.getValueAsInteger(0));
assertEquals((int) 'a', (int) record.getValueAsInteger(1));
assertEquals((int) '-', (int) record.getValueAsInteger(2));
@ -5628,7 +5635,7 @@ public abstract class jOOQAbstractTest<
SelectQuery q = create().selectQuery();
q.addFrom(VLibrary());
Field<Integer> position = VLibrary_AUTHOR().position("o").as("p");
Field<Integer> position = position(VLibrary_AUTHOR(), "o").as("p");
q.addSelect(VLibrary_AUTHOR());
q.addSelect(position);
@ -7785,7 +7792,7 @@ public abstract class jOOQAbstractTest<
assertEquals(create().select(TBook_ID(), TBook_TITLE()).from(TBook()).fetchAny(),
create().select(TBook_ID(), TBook_TITLE()).from(TBook()).fetchAny());
assertEquals(create().select(TBook_ID(), TBook_TITLE()).from(TBook()).fetchAny(),
create().select(TBook_ID(), TBook_TITLE().trim()).from(TBook()).fetchAny());
create().select(TBook_ID(), trim(TBook_TITLE())).from(TBook()).fetchAny());
assertFalse(create().select(TBook_ID(), TBook_TITLE()).from(TBook()).fetchAny().equals(
create().select(TBook_TITLE(), TBook_ID()).from(TBook()).fetchAny()));
@ -7802,7 +7809,7 @@ public abstract class jOOQAbstractTest<
assertEquals(create().select(TBook_ID(), TBook_TITLE()).from(TBook()).fetch(),
create().select(TBook_ID(), TBook_TITLE()).from(TBook()).fetch());
assertEquals(create().select(TBook_ID(), TBook_TITLE()).from(TBook()).fetch(),
create().select(TBook_ID(), TBook_TITLE().trim()).from(TBook()).fetch());
create().select(TBook_ID(), trim(TBook_TITLE())).from(TBook()).fetch());
assertFalse(create().selectFrom(TBook()).orderBy(TBook_ID().asc()).fetch().equals(
create().selectFrom(TBook()).orderBy(TBook_ID().desc()).fetch()));

View File

@ -38,6 +38,7 @@ package org.jooq.test;
import static junit.framework.Assert.assertEquals;
import static org.jooq.impl.Factory.one;
import static org.jooq.impl.Factory.substring;
import static org.jooq.test.oracle.generatedclasses.tables.VAuthor.V_AUTHOR;
import static org.jooq.test.oracle.generatedclasses.tables.VBook.V_BOOK;
import static org.jooq.util.oracle.OracleFactory.connectByIsCycle;
@ -661,7 +662,7 @@ public class jOOQOracleTest extends jOOQAbstractTest<
OracleFactory ora = new OracleFactory(create().getConnection(), create().getSchemaMapping());
List<?> paths =
ora.select(sysConnectByPath(TDirectory_NAME(), "/").substring(2))
ora.select(substring(sysConnectByPath(TDirectory_NAME(), "/"), 2))
.from(TDirectory())
.connectBy(prior(TDirectory_ID()).equal(TDirectory_PARENT_ID()))
.startWith(TDirectory_PARENT_ID().isNull())

View File

@ -561,321 +561,6 @@ public interface Field<T> extends NamedTypeProviderQueryPart<T>, AliasProvider<F
*/
Field<T> shr(Field<? extends Number> value);
// ------------------------------------------------------------------------
// String functions created from this field
// ------------------------------------------------------------------------
/**
* Get the upper(field) function
* <p>
* This renders the upper function in all dialects:
* <code><pre>upper([this])</pre></code>
*/
Field<String> upper();
/**
* Get the lower(field) function
* <p>
* This renders the lower function in all dialects:
* <code><pre>lower([this])</pre></code>
*/
Field<String> lower();
/**
* Get the trim(field) function
* <p>
* This renders the trim function where available:
* <code><pre>trim([this])</pre></code> ... or simulates it elsewhere using
* rtrim and ltrim: <code><pre>ltrim(rtrim([this]))</pre></code>
*/
Field<String> trim();
/**
* Get the rtrim(field) function
* <p>
* This renders the rtrim function in all dialects:
* <code><pre>rtrim([this])</pre></code>
*/
Field<String> rtrim();
/**
* Get the ltrim(field) function
* <p>
* This renders the ltrim function in all dialects:
* <code><pre>ltrim([this])</pre></code>
*/
Field<String> ltrim();
/**
* Get the rpad(field, length) function
* <p>
* This renders the rpad function where available:
* <code><pre>rpad([this], [length])</pre></code> ... or simulates it
* elsewhere using concat, repeat, and length, which may be simulated as
* well, depending on the RDBMS:
* <code><pre>concat([this], repeat(' ', [length] - length([this])))</pre></code>
*/
Field<String> rpad(Field<? extends Number> length);
/**
* Get the rpad(field, length) function
* <p>
* This renders the rpad function where available:
* <code><pre>rpad([this], [length])</pre></code> ... or simulates it
* elsewhere using concat, repeat, and length, which may be simulated as
* well, depending on the RDBMS:
* <code><pre>concat([this], repeat(' ', [length] - length([this])))</pre></code>
*/
Field<String> rpad(int length);
/**
* Get the rpad(field, length, character) function
* <p>
* This renders the rpad function where available:
* <code><pre>rpad([this], [length])</pre></code> ... or simulates it
* elsewhere using concat, repeat, and length, which may be simulated as
* well, depending on the RDBMS:
* <code><pre>concat([this], repeat([character], [length] - length([this])))</pre></code>
*/
Field<String> rpad(Field<? extends Number> length, Field<String> character);
/**
* Get the rpad(field, length, character) function
* <p>
* This renders the rpad function where available:
* <code><pre>rpad([this], [length])</pre></code> ... or simulates it
* elsewhere using concat, repeat, and length, which may be simulated as
* well, depending on the RDBMS:
* <code><pre>concat([this], repeat([character], [length] - length([this])))</pre></code>
*/
Field<String> rpad(int length, char character);
/**
* Get the lpad(field, length) function
* <p>
* This renders the lpad function where available:
* <code><pre>lpad([this], [length])</pre></code> ... or simulates it
* elsewhere using concat, repeat, and length, which may be simulated as
* well, depending on the RDBMS:
* <code><pre>concat(repeat(' ', [length] - length([this])), [this])</pre></code>
*/
Field<String> lpad(Field<? extends Number> length);
/**
* Get the lpad(field, length) function
* <p>
* This renders the lpad function where available:
* <code><pre>lpad([this], [length])</pre></code> ... or simulates it
* elsewhere using concat, repeat, and length, which may be simulated as
* well, depending on the RDBMS:
* <code><pre>concat(repeat(' ', [length] - length([this])), [this])</pre></code>
*/
Field<String> lpad(int length);
/**
* Get the lpad(field, length, character) function
* <p>
* This renders the lpad function where available:
* <code><pre>lpad([this], [length])</pre></code> ... or simulates it
* elsewhere using concat, repeat, and length, which may be simulated as
* well, depending on the RDBMS:
* <code><pre>concat(repeat([character], [length] - length([this])), [this])</pre></code>
*/
Field<String> lpad(Field<? extends Number> length, Field<String> character);
/**
* Get the lpad(field, length, character) function
* <p>
* This renders the lpad function where available:
* <code><pre>lpad([this], [length])</pre></code> ... or simulates it
* elsewhere using concat, repeat, and length, which may be simulated as
* well, depending on the RDBMS:
* <code><pre>concat(repeat([character], [length] - length([this])), [this])</pre></code>
*/
Field<String> lpad(int length, char character);
/**
* Get the repeat(count) function
* <p>
* This renders the repeat or replicate function where available:
* <code><pre>repeat([this], [count]) or
* replicate([this], [count])</pre></code> ... or simulates it elsewhere
* using rpad and length, which may be simulated as well, depending on the
* RDBMS:
* <code><pre>rpad([this], length([this]) * [count], [this])</pre></code>
*/
Field<String> repeat(Number count);
/**
* Get the repeat(field, count) function
* <p>
* This renders the repeat or replicate function where available:
* <code><pre>repeat([this], [count]) or
* replicate([this], [count])</pre></code> ... or simulates it elsewhere
* using rpad and length, which may be simulated as well, depending on the
* RDBMS:
* <code><pre>rpad([this], length([this]) * [count], [this])</pre></code>
*/
Field<String> repeat(Field<? extends Number> count);
/**
* Get the replace(in, search) function
* <p>
* This renders the replace or str_replace function where available:
* <code><pre>replace([this], [search]) or
* str_replace([this], [search])</pre></code> ... or simulates it elsewhere
* using the three-argument replace function:
* <code><pre>replace([this], [search], '')</pre></code>
*/
Field<String> replace(Field<String> search);
/**
* Get the replace(in, search) function
* <p>
* This renders the replace or str_replace function where available:
* <code><pre>replace([this], [search]) or
* str_replace([this], [search])</pre></code> ... or simulates it elsewhere
* using the three-argument replace function:
* <code><pre>replace([this], [search], '')</pre></code>
*/
Field<String> replace(String search);
/**
* Get the replace(in, search, replace) function
* <p>
* This renders the replace or str_replace function:
* <code><pre>replace([this], [search]) or
* str_replace([this], [search])</pre></code>
*/
Field<String> replace(Field<String> search, Field<String> replace);
/**
* Get the replace(in, search, replace) function
* <p>
* This renders the replace or str_replace function:
* <code><pre>replace([this], [search]) or
* str_replace([this], [search])</pre></code>
*/
Field<String> replace(String search, String replace);
/**
* Get the position(in, search) function
* <p>
* This renders the position or any equivalent function:
* <code><pre>position([search] in [this]) or
* locate([this], [search]) or
* locate([search], [this]) or
* instr([this], [search]) or
* charindex([search], [this])</pre></code>
*/
Field<Integer> position(String search);
/**
* Get the position(in, search) function
* <p>
* This renders the position or any equivalent function:
* <code><pre>position([search] in [this]) or
* locate([this], [search]) or
* locate([search], [this]) or
* instr([this], [search]) or
* charindex([search], [this])</pre></code>
*/
Field<Integer> position(Field<String> search);
/**
* Get the ascii(field) function
* <p>
* This renders the replace or str_replace function:
* <code><pre>ascii([this])</pre></code>
*/
Field<Integer> ascii();
/**
* Get the concat(field[, field, ...]) function
* <p>
* This creates <code>this || fields[0] || fields[1] || ...</code> as an
* expression, or <code>concat(this, fields[0], fields[1], ...)</code>,
* depending on the dialect.
* <p>
* If any of the given fields is not a {@link String} field, they are cast
* to <code>Field&lt;String&gt;</code> first using {@link #cast(Class)}
*/
Field<String> concat(Field<?>... fields);
/**
* Get the concat(value[, value, ...]) function
* <p>
* This creates <code>this || fields[0] || fields[1] || ...</code> as an
* expression, or <code>concat(this, fields[0], fields[1], ...)</code>,
* depending on the dialect.
*/
Field<String> concat(String... values);
/**
* Get the substring(field, startingPosition) function
* <p>
* This renders the substr or substring function:
* <code><pre>substr([this], [startingPosition]) or
* substring([this], [startingPosition])</pre></code>
*/
Field<String> substring(int startingPosition);
/**
* Get the substring(field, startingPosition) function
* <p>
* This renders the substr or substring function:
* <code><pre>substr([this], [startingPosition]) or
* substring([this], [startingPosition])</pre></code>
*/
Field<String> substring(Field<? extends Number> startingPosition);
/**
* Get the substring(field, startingPosition, length) function
* <p>
* This renders the substr or substring function:
* <code><pre>substr([this], [startingPosition], [length]) or
* substring([this], [startingPosition], [length])</pre></code>
*/
Field<String> substring(int startingPosition, int length);
/**
* Get the substring(field, startingPosition, length) function
* <p>
* This renders the substr or substring function:
* <code><pre>substr([this], [startingPosition], [length]) or
* substring([this], [startingPosition], [length])</pre></code>
*/
Field<String> substring(Field<? extends Number> startingPosition, Field<? extends Number> length);
/**
* Get the length of a <code>VARCHAR</code> type. This is a synonym for
* {@link #charLength()}
*
* @see #charLength()
*/
Field<Integer> length();
/**
* Get the char_length(field) function
* <p>
* This translates into any dialect
*/
Field<Integer> charLength();
/**
* Get the bit_length(field) function
* <p>
* This translates into any dialect
*/
Field<Integer> bitLength();
/**
* Get the octet_length(field) function
* <p>
* This translates into any dialect
*/
Field<Integer> octetLength();
/**
* Get the extract(field, datePart) function
* <p>

View File

@ -67,7 +67,6 @@ import org.jooq.RenderContext;
import org.jooq.Select;
import org.jooq.SortField;
import org.jooq.SortOrder;
import org.jooq.exception.SQLDialectNotSupportedException;
abstract class AbstractField<T> extends AbstractNamedTypeProviderQueryPart<T> implements Field<T> {
@ -406,170 +405,6 @@ abstract class AbstractField<T> extends AbstractNamedTypeProviderQueryPart<T> im
// Other functions created from this field
// ------------------------------------------------------------------------
@Override
public final Field<String> upper() {
return function("upper", SQLDataType.VARCHAR, this);
}
@Override
public final Field<String> lower() {
return function("lower", SQLDataType.VARCHAR, this);
}
@Override
public final Field<String> trim() {
return new Trim(this);
}
@Override
public final Field<String> rtrim() {
return function("rtrim", SQLDataType.VARCHAR, this);
}
@Override
public final Field<String> ltrim() {
return function("ltrim", SQLDataType.VARCHAR, this);
}
@Override
public final Field<String> rpad(Field<? extends Number> length) {
return new Rpad(this, nullSafe(length), null);
}
@Override
public final Field<String> rpad(int length) {
return rpad(val(length));
}
@Override
public final Field<String> rpad(Field<? extends Number> length, Field<String> c) {
return new Rpad(this, nullSafe(length), nullSafe(c));
}
@Override
public final Field<String> rpad(int length, char c) {
return rpad(val(length), val("" + c));
}
@Override
public final Field<String> lpad(Field<? extends Number> length) {
return new Lpad(this, nullSafe(length), null);
}
@Override
public final Field<String> lpad(int length) {
return lpad(val(length));
}
@Override
public final Field<String> lpad(Field<? extends Number> length, Field<String> c) {
return new Lpad(this, nullSafe(length), nullSafe(c));
}
@Override
public final Field<String> lpad(int length, char c) {
return lpad(val(length), val("" + c));
}
@Override
public final Field<String> repeat(Number count) {
return repeat(val(count));
}
@Override
public final Field<String> repeat(Field<? extends Number> count) {
return new Repeat(this, nullSafe(count));
}
@Override
public final Field<String> replace(Field<String> search) {
return new Replace(this, nullSafe(search));
}
@Override
public final Field<String> replace(String search) {
return replace(val(search));
}
@Override
public final Field<String> replace(Field<String> search, Field<String> replace) {
return new Replace(this, nullSafe(search), nullSafe(replace));
}
@Override
public final Field<String> replace(String search, String replace) {
return replace(val(search), val(replace));
}
@Override
public final Field<Integer> position(String search) throws SQLDialectNotSupportedException {
return position(val(search));
}
@Override
public final Field<Integer> position(Field<String> search) throws SQLDialectNotSupportedException {
return new Position(nullSafe(search), this);
}
@Override
public final Field<Integer> ascii() {
return new Ascii(this);
}
/**
* This default implementation is known to be overridden by
* {@link Expression} to generate neater expressions
*/
@Override
public final Field<String> concat(Field<?>... fields) {
return new Concat(nullSafe(combine(this, fields)));
}
@Override
public final Field<String> concat(String... values) {
return concat(vals((Object[]) values).toArray(new Field[0]));
}
@Override
public final Field<String> substring(int startingPosition) {
return substring(val(startingPosition));
}
@Override
public final Field<String> substring(int startingPosition, int length) {
return substring(val(startingPosition), val(length));
}
@Override
public final Field<String> substring(Field<? extends Number> startingPosition) {
return new Substring(this, nullSafe(startingPosition));
}
@Override
public final Field<String> substring(Field<? extends Number> startingPosition, Field<? extends Number> length) {
return new Substring(this, nullSafe(startingPosition), nullSafe(length));
}
@Override
public final Field<Integer> length() {
return charLength();
}
@Override
public final Field<Integer> charLength() {
return new Function<Integer>(Term.CHAR_LENGTH, SQLDataType.INTEGER, this);
}
@Override
public final Field<Integer> bitLength() {
return new Function<Integer>(Term.BIT_LENGTH, SQLDataType.INTEGER, this);
}
@Override
public final Field<Integer> octetLength() {
return new Function<Integer>(Term.OCTET_LENGTH, SQLDataType.INTEGER, this);
}
@Override
public final Field<Integer> extract(DatePart datePart) {
return new Extract(this, datePart);

View File

@ -37,6 +37,7 @@ package org.jooq.impl;
import static java.util.Arrays.asList;
import static org.jooq.impl.Factory.literal;
import static org.jooq.impl.Factory.lower;
import static org.jooq.impl.SQLDataType.BOOLEAN;
import static org.jooq.impl.SQLDataType.DOUBLE;
import static org.jooq.impl.SQLDataType.FLOAT;
@ -152,8 +153,8 @@ class Cast<T> extends AbstractField<T> {
// [#859] '0', 'f', 'false' => false, null => null, all else is true
return Factory.decode().when(s.equal(literal("'0'")), literal(false))
.when(s.lower().equal(literal("'false'")), literal(false))
.when(s.lower().equal(literal("'f'")), literal(false))
.when(lower(s).equal(literal("'false'")), literal(false))
.when(lower(s).equal(literal("'f'")), literal(false))
.when(s.isNull(), literal((Boolean) null))
.otherwise(literal(true));
}

View File

@ -1438,6 +1438,524 @@ public class Factory implements FactoryOperations {
return function("nullif", nullSafeDataType(value), nullSafe(value), nullSafe(other));
}
// -------------------------------------------------------------------------
// String function factory
// -------------------------------------------------------------------------
/**
* Get the upper(field) function
* <p>
* This renders the upper function in all dialects:
* <code><pre>upper([this])</pre></code>
*/
public static Field<String> upper(String value) {
return upper(val(value));
}
/**
* Get the upper(field) function
* <p>
* This renders the upper function in all dialects:
* <code><pre>upper([this])</pre></code>
*/
public static Field<String> upper(Field<String> field) {
return function("upper", SQLDataType.VARCHAR, nullSafe(field));
}
/**
* Get the lower(field) function
* <p>
* This renders the lower function in all dialects:
* <code><pre>lower([this])</pre></code>
*/
public static Field<String> lower(String value) {
return lower(val(value));
}
/**
* Get the lower(field) function
* <p>
* This renders the lower function in all dialects:
* <code><pre>lower([this])</pre></code>
*/
public static Field<String> lower(Field<String> value) {
return function("lower", SQLDataType.VARCHAR, nullSafe(value));
}
/**
* Get the trim(field) function
* <p>
* This renders the trim function where available:
* <code><pre>trim([this])</pre></code> ... or simulates it elsewhere using
* rtrim and ltrim: <code><pre>ltrim(rtrim([this]))</pre></code>
*/
public static Field<String> trim(String value) {
return trim(val(value));
}
/**
* Get the trim(field) function
* <p>
* This renders the trim function where available:
* <code><pre>trim([this])</pre></code> ... or simulates it elsewhere using
* rtrim and ltrim: <code><pre>ltrim(rtrim([this]))</pre></code>
*/
public static Field<String> trim(Field<String> field) {
return new Trim(nullSafe(field));
}
/**
* Get the rtrim(field) function
* <p>
* This renders the rtrim function in all dialects:
* <code><pre>rtrim([this])</pre></code>
*/
public static Field<String> rtrim(String value) {
return rtrim(val(value));
}
/**
* Get the rtrim(field) function
* <p>
* This renders the rtrim function in all dialects:
* <code><pre>rtrim([this])</pre></code>
*/
public static Field<String> rtrim(Field<String> field) {
return function("rtrim", SQLDataType.VARCHAR, nullSafe(field));
}
/**
* Get the ltrim(field) function
* <p>
* This renders the ltrim function in all dialects:
* <code><pre>ltrim([this])</pre></code>
*/
public static Field<String> ltrim(String value) {
return ltrim(val(value));
}
/**
* Get the ltrim(field) function
* <p>
* This renders the ltrim function in all dialects:
* <code><pre>ltrim([this])</pre></code>
*/
public static Field<String> ltrim(Field<String> value) {
return function("ltrim", SQLDataType.VARCHAR, nullSafe(value));
}
/**
* Get the rpad(field, length) function
* <p>
* This renders the rpad function where available:
* <code><pre>rpad([this], [length])</pre></code> ... or simulates it
* elsewhere using concat, repeat, and length, which may be simulated as
* well, depending on the RDBMS:
* <code><pre>concat([this], repeat(' ', [length] - length([this])))</pre></code>
*/
public static Field<String> rpad(Field<String> field, int length) {
return rpad(nullSafe(field), val(length));
}
/**
* Get the rpad(field, length) function
* <p>
* This renders the rpad function where available:
* <code><pre>rpad([this], [length])</pre></code> ... or simulates it
* elsewhere using concat, repeat, and length, which may be simulated as
* well, depending on the RDBMS:
* <code><pre>concat([this], repeat(' ', [length] - length([this])))</pre></code>
*/
public static Field<String> rpad(Field<String> field, Field<? extends Number> length) {
return new Rpad(nullSafe(field), nullSafe(length));
}
/**
* Get the rpad(field, length, character) function
* <p>
* This renders the rpad function where available:
* <code><pre>rpad([this], [length])</pre></code> ... or simulates it
* elsewhere using concat, repeat, and length, which may be simulated as
* well, depending on the RDBMS:
* <code><pre>concat([this], repeat([character], [length] - length([this])))</pre></code>
*/
public static Field<String> rpad(Field<String> field, int length, String character) {
return rpad(nullSafe(field), val(length), val(character));
}
/**
* Get the rpad(field, length, character) function
* <p>
* This renders the rpad function where available:
* <code><pre>rpad([this], [length])</pre></code> ... or simulates it
* elsewhere using concat, repeat, and length, which may be simulated as
* well, depending on the RDBMS:
* <code><pre>concat([this], repeat([character], [length] - length([this])))</pre></code>
*/
public static Field<String> rpad(Field<String> field, Field<? extends Number> length, Field<String> character) {
return new Rpad(nullSafe(field), nullSafe(length), nullSafe(character));
}
/**
* Get the lpad(field, length) function
* <p>
* This renders the lpad function where available:
* <code><pre>lpad([this], [length])</pre></code> ... or simulates it
* elsewhere using concat, repeat, and length, which may be simulated as
* well, depending on the RDBMS:
* <code><pre>concat(repeat(' ', [length] - length([this])), [this])</pre></code>
*/
public static Field<String> lpad(Field<String> field, int length) {
return lpad(nullSafe(field), val(length));
}
/**
* Get the lpad(field, length) function
* <p>
* This renders the lpad function where available:
* <code><pre>lpad([this], [length])</pre></code> ... or simulates it
* elsewhere using concat, repeat, and length, which may be simulated as
* well, depending on the RDBMS:
* <code><pre>concat(repeat(' ', [length] - length([this])), [this])</pre></code>
*/
public static Field<String> lpad(Field<String> field, Field<? extends Number> length) {
return new Lpad(nullSafe(field), nullSafe(length));
}
/**
* Get the lpad(field, length, character) function
* <p>
* This renders the lpad function where available:
* <code><pre>lpad([this], [length])</pre></code> ... or simulates it
* elsewhere using concat, repeat, and length, which may be simulated as
* well, depending on the RDBMS:
* <code><pre>concat(repeat([character], [length] - length([this])), [this])</pre></code>
*/
public static Field<String> lpad(Field<String> field, int length, String character) {
return lpad(nullSafe(field), val(length), val(character));
}
/**
* Get the lpad(field, length, character) function
* <p>
* This renders the lpad function where available:
* <code><pre>lpad([this], [length])</pre></code> ... or simulates it
* elsewhere using concat, repeat, and length, which may be simulated as
* well, depending on the RDBMS:
* <code><pre>concat(repeat([character], [length] - length([this])), [this])</pre></code>
*/
public static Field<String> lpad(Field<String> field, Field<? extends Number> length, Field<String> character) {
return new Lpad(nullSafe(field), nullSafe(length), nullSafe(character));
}
/**
* Get the repeat(count) function
* <p>
* This renders the repeat or replicate function where available:
* <code><pre>repeat([this], [count]) or
* replicate([this], [count])</pre></code> ... or simulates it elsewhere
* using rpad and length, which may be simulated as well, depending on the
* RDBMS:
* <code><pre>rpad([this], length([this]) * [count], [this])</pre></code>
*/
public static Field<String> repeat(String field, int count) {
return repeat(val(field), val(count));
}
/**
* Get the repeat(count) function
* <p>
* This renders the repeat or replicate function where available:
* <code><pre>repeat([this], [count]) or
* replicate([this], [count])</pre></code> ... or simulates it elsewhere
* using rpad and length, which may be simulated as well, depending on the
* RDBMS:
* <code><pre>rpad([this], length([this]) * [count], [this])</pre></code>
*/
public static Field<String> repeat(String field, Field<? extends Number> count) {
return repeat(val(field), nullSafe(count));
}
/**
* Get the repeat(count) function
* <p>
* This renders the repeat or replicate function where available:
* <code><pre>repeat([this], [count]) or
* replicate([this], [count])</pre></code> ... or simulates it elsewhere
* using rpad and length, which may be simulated as well, depending on the
* RDBMS:
* <code><pre>rpad([this], length([this]) * [count], [this])</pre></code>
*/
public static Field<String> repeat(Field<String> field, int count) {
return repeat(nullSafe(field), val(count));
}
/**
* Get the repeat(field, count) function
* <p>
* This renders the repeat or replicate function where available:
* <code><pre>repeat([this], [count]) or
* replicate([this], [count])</pre></code> ... or simulates it elsewhere
* using rpad and length, which may be simulated as well, depending on the
* RDBMS:
* <code><pre>rpad([this], length([this]) * [count], [this])</pre></code>
*/
public static Field<String> repeat(Field<String> field, Field<? extends Number> count) {
return new Repeat(nullSafe(field), nullSafe(count));
}
/**
* Get the replace(in, search) function
* <p>
* This renders the replace or str_replace function where available:
* <code><pre>replace([this], [search]) or
* str_replace([this], [search])</pre></code> ... or simulates it elsewhere
* using the three-argument replace function:
* <code><pre>replace([this], [search], '')</pre></code>
*/
public static Field<String> replace(Field<String> field, String search) {
return replace(nullSafe(field), val(search));
}
/**
* Get the replace(in, search) function
* <p>
* This renders the replace or str_replace function where available:
* <code><pre>replace([this], [search]) or
* str_replace([this], [search])</pre></code> ... or simulates it elsewhere
* using the three-argument replace function:
* <code><pre>replace([this], [search], '')</pre></code>
*/
public static Field<String> replace(Field<String> field, Field<String> search) {
return new Replace(nullSafe(field), nullSafe(search));
}
/**
* Get the replace(in, search, replace) function
* <p>
* This renders the replace or str_replace function:
* <code><pre>replace([this], [search]) or
* str_replace([this], [search])</pre></code>
*/
public static Field<String> replace(Field<String> field, String search, String replace) {
return replace(nullSafe(field), val(search), val(replace));
}
/**
* Get the replace(in, search, replace) function
* <p>
* This renders the replace or str_replace function:
* <code><pre>replace([this], [search]) or
* str_replace([this], [search])</pre></code>
*/
public static Field<String> replace(Field<String> field, Field<String> search, Field<String> replace) {
return new Replace(nullSafe(field), nullSafe(search), nullSafe(replace));
}
/**
* Get the position(in, search) function
*
* @see #position(Field, Field)
*/
public static Field<Integer> position(String in, String search) {
return position(val(in), val(search));
}
/**
* Get the position(in, search) function
*
* @see #position(Field, Field)
*/
public static Field<Integer> position(String in, Field<String> search) {
return position(val(in), nullSafe(search));
}
/**
* Get the position(in, search) function
*
* @see #position(Field, Field)
*/
public static Field<Integer> position(Field<String> in, String search) {
return position(nullSafe(in), val(search));
}
/**
* Get the position(in, search) function
* <p>
* This renders the position or any equivalent function:
* <code><pre>position([search] in [in]) or
* locate([in], [search]) or
* locate([search], [in]) or
* instr([in], [search]) or
* charindex([search], [in])</pre></code>
*/
public static Field<Integer> position(Field<String> in, Field<String> search) {
return new Position(nullSafe(search), nullSafe(in));
}
/**
* Get the ascii(field) function
* <p>
* This renders the replace or str_replace function:
* <code><pre>ascii([this])</pre></code>
*/
public static Field<Integer> ascii(String field) {
return ascii(val(field));
}
/**
* Get the ascii(field) function
* <p>
* This renders the replace or str_replace function:
* <code><pre>ascii([this])</pre></code>
*/
public static Field<Integer> ascii(Field<String> field) {
return new Ascii(nullSafe(field));
}
/**
* Get the concat(value[, value, ...]) function
* <p>
* This creates <code>this || fields[0] || fields[1] || ...</code> as an
* expression, or <code>concat(this, fields[0], fields[1], ...)</code>,
* depending on the dialect.
*/
public static Field<String> concat(String... values) {
return concat(vals((Object[]) values).toArray(new Field[0]));
}
/**
* Get the concat(field[, field, ...]) function
* <p>
* This creates <code>this || fields[0] || fields[1] || ...</code> as an
* expression, or <code>concat(this, fields[0], fields[1], ...)</code>,
* depending on the dialect.
* <p>
* If any of the given fields is not a {@link String} field, they are cast
* to <code>Field&lt;String&gt;</code> first using {@link #cast(Class)}
*/
public static Field<String> concat(Field<?>... fields) {
return new Concat(nullSafe(fields));
}
/**
* Get the substring(field, startingPosition) function
* <p>
* This renders the substr or substring function:
* <code><pre>substr([this], [startingPosition]) or
* substring([this], [startingPosition])</pre></code>
*/
public static Field<String> substring(Field<String> field, int startingPosition) {
return substring(nullSafe(field), val(startingPosition));
}
/**
* Get the substring(field, startingPosition) function
* <p>
* This renders the substr or substring function:
* <code><pre>substr([this], [startingPosition]) or
* substring([this], [startingPosition])</pre></code>
*/
public static Field<String> substring(Field<String> field, Field<? extends Number> startingPosition) {
return new Substring(nullSafe(field), nullSafe(startingPosition));
}
/**
* Get the substring(field, startingPosition, length) function
* <p>
* This renders the substr or substring function:
* <code><pre>substr([this], [startingPosition], [length]) or
* substring([this], [startingPosition], [length])</pre></code>
*/
public static Field<String> substring(Field<String> field, int startingPosition, int length) {
return substring(nullSafe(field), val(startingPosition), val(length));
}
/**
* Get the substring(field, startingPosition, length) function
* <p>
* This renders the substr or substring function:
* <code><pre>substr([this], [startingPosition], [length]) or
* substring([this], [startingPosition], [length])</pre></code>
*/
public static Field<String> substring(Field<String> field, Field<? extends Number> startingPosition, Field<? extends Number> length) {
return new Substring(nullSafe(field), nullSafe(startingPosition), nullSafe(length));
}
/**
* Get the length of a <code>VARCHAR</code> type. This is a synonym for
* {@link #charLength()}
*
* @see #charLength()
*/
public static Field<Integer> length(String value) {
return length(val(value));
}
/**
* Get the length of a <code>VARCHAR</code> type. This is a synonym for
* {@link #charLength()}
*
* @see #charLength()
*/
public static Field<Integer> length(Field<String> field) {
return charLength(field);
}
/**
* Get the char_length(field) function
* <p>
* This translates into any dialect
*/
public static Field<Integer> charLength(String value) {
return charLength(val(value));
}
/**
* Get the char_length(field) function
* <p>
* This translates into any dialect
*/
public static Field<Integer> charLength(Field<String> field) {
return new Function<Integer>(Term.CHAR_LENGTH, SQLDataType.INTEGER, nullSafe(field));
}
/**
* Get the bit_length(field) function
* <p>
* This translates into any dialect
*/
public static Field<Integer> bitLength(String value) {
return bitLength(val(value));
}
/**
* Get the bit_length(field) function
* <p>
* This translates into any dialect
*/
public static Field<Integer> bitLength(Field<String> field) {
return new Function<Integer>(Term.BIT_LENGTH, SQLDataType.INTEGER, nullSafe(field));
}
/**
* Get the octet_length(field) function
* <p>
* This translates into any dialect
*/
public static Field<Integer> octetLength(String value) {
return octetLength(val(value));
}
/**
* Get the octet_length(field) function
* <p>
* This translates into any dialect
*/
public static Field<Integer> octetLength(Field<String> field) {
return new Function<Integer>(Term.OCTET_LENGTH, SQLDataType.INTEGER, nullSafe(field));
}
// ------------------------------------------------------------------------
// Construction of special grouping functions
// ------------------------------------------------------------------------

View File

@ -35,7 +35,10 @@
*/
package org.jooq.impl;
import static org.jooq.impl.Factory.concat;
import static org.jooq.impl.Factory.function;
import static org.jooq.impl.Factory.length;
import static org.jooq.impl.Factory.repeat;
import static org.jooq.impl.Factory.val;
import org.jooq.Configuration;
@ -52,11 +55,15 @@ class Lpad extends AbstractFunction<String> {
*/
private static final long serialVersionUID = -7273879239726265322L;
private final Field<?> field;
private final Field<String> field;
private final Field<? extends Number> length;
private final Field<String> character;
Lpad(Field<?> field, Field<? extends Number> length, Field<String> character) {
Lpad(Field<String> field, Field<? extends Number> length) {
this(field, length, null);
}
Lpad(Field<String> field, Field<? extends Number> length, Field<String> character) {
super("lpad", SQLDataType.VARCHAR, field, length, character);
this.field = field;
@ -71,10 +78,10 @@ class Lpad extends AbstractFunction<String> {
case SQLSERVER:
case SYBASE: {
if (character == null) {
return val(" ").repeat(length.sub(field.length())).concat(field);
return concat(repeat(" ", length.sub(length(field))), field);
}
else {
return character.repeat(length.sub(field.length())).concat(field);
return concat(repeat(character, length.sub(length(field))), field);
}
}

View File

@ -36,6 +36,8 @@
package org.jooq.impl;
import static org.jooq.impl.Factory.function;
import static org.jooq.impl.Factory.length;
import static org.jooq.impl.Factory.rpad;
import org.jooq.Configuration;
import org.jooq.Field;
@ -50,23 +52,22 @@ class Repeat extends AbstractFunction<String> {
*/
private static final long serialVersionUID = -7273879239726265322L;
private final Field<?> string;
private final Field<String> string;
private final Field<? extends Number> count;
Repeat(Field<?> string, Field<? extends Number> count) {
Repeat(Field<String> string, Field<? extends Number> count) {
super("rpad", SQLDataType.VARCHAR, string, count);
this.string = string;
this.count = count;
}
@SuppressWarnings("unchecked")
@Override
final Field<String> getFunction0(Configuration configuration) {
switch (configuration.getDialect()) {
case INGRES:
case ORACLE:
return string.rpad(string.length().mul(count), (Field<String>) string);
return rpad(string, length(string).mul(count), string);
case ASE:
case SQLSERVER:

View File

@ -35,7 +35,10 @@
*/
package org.jooq.impl;
import static org.jooq.impl.Factory.concat;
import static org.jooq.impl.Factory.function;
import static org.jooq.impl.Factory.length;
import static org.jooq.impl.Factory.repeat;
import static org.jooq.impl.Factory.val;
import org.jooq.Configuration;
@ -52,11 +55,15 @@ class Rpad extends AbstractFunction<String> {
*/
private static final long serialVersionUID = -7273879239726265322L;
private final Field<?> field;
private final Field<String> field;
private final Field<? extends Number> length;
private final Field<String> character;
Rpad(Field<?> field, Field<? extends Number> length, Field<String> character) {
Rpad(Field<String> field, Field<? extends Number> length) {
this(field, length, null);
}
Rpad(Field<String> field, Field<? extends Number> length, Field<String> character) {
super("rpad", SQLDataType.VARCHAR, field, length, character);
this.field = field;
@ -71,10 +78,10 @@ class Rpad extends AbstractFunction<String> {
case SQLSERVER:
case SYBASE: {
if (character == null) {
return field.concat(val(" ").repeat(length.sub(field.length())));
return concat(field, repeat(" ", length.sub(length(field))));
}
else {
return field.concat(character.repeat(length.sub(field.length())));
return concat(field, repeat(character, length.sub(length(field))));
}
}

View File

@ -36,6 +36,8 @@
package org.jooq.impl;
import static org.jooq.impl.Factory.function;
import static org.jooq.impl.Factory.ltrim;
import static org.jooq.impl.Factory.rtrim;
import org.jooq.Configuration;
import org.jooq.Field;
@ -48,11 +50,11 @@ class Trim extends AbstractFunction<String> {
/**
* Generated UID
*/
private static final long serialVersionUID = -7273879239726265322L;
private static final long serialVersionUID = -7273879239726265322L;
private final Field<?> argument;
private final Field<String> argument;
Trim(Field<?> argument) {
Trim(Field<String> argument) {
super("trim", SQLDataType.VARCHAR, argument);
this.argument = argument;
@ -64,7 +66,7 @@ class Trim extends AbstractFunction<String> {
case ASE:
case INGRES:
case SQLSERVER:
return argument.rtrim().ltrim();
return ltrim(rtrim(argument));
default:
return function("trim", SQLDataType.VARCHAR, argument);

View File

@ -48,6 +48,7 @@ import static org.jooq.impl.Factory.falseCondition;
import static org.jooq.impl.Factory.field;
import static org.jooq.impl.Factory.max;
import static org.jooq.impl.Factory.min;
import static org.jooq.impl.Factory.replace;
import static org.jooq.impl.Factory.round;
import static org.jooq.impl.Factory.sum;
import static org.jooq.impl.Factory.trueCondition;
@ -213,9 +214,6 @@ public class jOOQTest {
assertEquals(
FIELD_ID1.coalesce((Integer) null),
FIELD_ID1.coalesce((Field<Integer>) null));
assertEquals(
FIELD_ID1.concat((String) null),
FIELD_ID1.concat((Field<String>) null));
assertEquals(
FIELD_ID1.decode((Integer) null, null),
FIELD_ID1.decode((Field<Integer>) null, null));
@ -258,18 +256,6 @@ public class jOOQTest {
assertEquals(
FIELD_ID1.notIn((Integer) null),
FIELD_ID1.notIn((Field<Integer>) null));
assertEquals(
FIELD_ID1.position((String) null),
FIELD_ID1.position((Field<String>) null));
assertEquals(
FIELD_ID1.repeat((Integer) null),
FIELD_ID1.repeat((Field<Integer>) null));
assertEquals(
FIELD_ID1.replace((String) null),
FIELD_ID1.replace((Field<String>) null));
assertEquals(
FIELD_ID1.replace((String) null, null),
FIELD_ID1.replace((Field<String>) null, null));
assertEquals(
FIELD_ID1.shl((Integer) null),
FIELD_ID1.shl((Field<Integer>) null));
@ -303,9 +289,18 @@ public class jOOQTest {
assertEquals(
Factory.atan2((Integer) null, (Integer) null),
Factory.atan2((Integer) null, (Field<Integer>) null));
assertEquals(
Factory.bitLength((String) null),
Factory.bitLength((Field<String>) null));
assertEquals(
Factory.ceil((Integer) null),
Factory.ceil((Field<Integer>) null));
assertEquals(
Factory.charLength((String) null),
Factory.charLength((Field<String>) null));
assertEquals(
Factory.concat((String) null, (String) null),
Factory.concat((Field<String>) null, (Field<String>) null));
assertEquals(
Factory.cos((Integer) null),
Factory.cos((Field<Integer>) null));
@ -336,12 +331,21 @@ public class jOOQTest {
assertEquals(
Factory.lead((Field<Integer>) null, 1, (Integer) null),
Factory.lead((Field<Integer>) null, 1, (Field<Integer>) null));
assertEquals(
Factory.length((String) null),
Factory.length((Field<String>) null));
assertEquals(
Factory.ln((Integer) null),
Factory.ln((Field<Integer>) null));
assertEquals(
Factory.log((Integer) null, 2),
Factory.log((Field<Integer>) null, 2));
assertEquals(
Factory.lower((String) null),
Factory.lower((Field<String>) null));
assertEquals(
Factory.ltrim((String) null),
Factory.ltrim((Field<String>) null));
assertEquals(
Factory.nullif((Integer) null, (Integer) null),
Factory.nullif((Field<Integer>) null, (Integer) null));
@ -369,6 +373,18 @@ public class jOOQTest {
assertEquals(
Factory.nvl2((Field<Integer>) null, (Integer) null, (Integer) null),
Factory.nvl2((Field<Integer>) null, (Field<Integer>) null, (Field<Integer>) null));
assertEquals(
Factory.octetLength((String) null),
Factory.octetLength((Field<String>) null));
assertEquals(
Factory.position((String) null, (String) null),
Factory.position((String) null, (Field<String>) null));
assertEquals(
Factory.position((String) null, (String) null),
Factory.position((Field<String>) null, (String) null));
assertEquals(
Factory.position((String) null, (String) null),
Factory.position((Field<String>) null, (Field<String>) null));
assertEquals(
Factory.power((Integer) null, (Integer) null),
Factory.power((Field<Integer>) null, (Field<Integer>) null));
@ -381,12 +397,24 @@ public class jOOQTest {
assertEquals(
Factory.rad((Integer) null),
Factory.rad((Field<Integer>) null));
assertEquals(
Factory.repeat((String) null, (Field<Integer>) null),
Factory.repeat((Field<String>) null, (Field<Integer>) null));
assertEquals(
Factory.replace((Field<String>) null, (String) null),
Factory.replace((Field<String>) null, (Field<String>) null));
assertEquals(
Factory.replace((Field<String>) null, (String) null, (String) null),
Factory.replace((Field<String>) null, (Field<String>) null, (Field<String>) null));
assertEquals(
Factory.round((Integer) null),
Factory.round((Field<Integer>) null));
assertEquals(
Factory.round((Integer) null, 1),
Factory.round((Field<Integer>) null, 1));
assertEquals(
Factory.rtrim((String) null),
Factory.rtrim((Field<String>) null));
assertEquals(
Factory.sign((Integer) null),
Factory.sign((Field<Integer>) null));
@ -405,6 +433,12 @@ public class jOOQTest {
assertEquals(
Factory.tanh((Integer) null),
Factory.tanh((Field<Integer>) null));
assertEquals(
Factory.trim((String) null),
Factory.trim((Field<String>) null));
assertEquals(
Factory.upper((String) null),
Factory.upper((Field<String>) null));
}
@Test
@ -968,7 +1002,7 @@ public class jOOQTest {
@Test
public final void testFunctions() {
Field<String> f = FIELD_NAME1.replace("a", "b");
Field<String> f = replace(FIELD_NAME1, "a", "b");
assertEquals("replace(\"TABLE1\".\"NAME1\", 'a', 'b')", r_refI().render(f));
assertEquals("replace(\"TABLE1\".\"NAME1\", ?, ?)", r_ref().render(f));
}