diff --git a/jOOQ/src/main/java/org/jooq/CreateIndexWhereStep.java b/jOOQ/src/main/java/org/jooq/CreateIndexWhereStep.java
index 765d3c8b82..304a5db6e0 100644
--- a/jOOQ/src/main/java/org/jooq/CreateIndexWhereStep.java
+++ b/jOOQ/src/main/java/org/jooq/CreateIndexWhereStep.java
@@ -37,6 +37,7 @@
*/
package org.jooq;
+// ...
// ...
import static org.jooq.SQLDialect.POSTGRES;
import static org.jooq.SQLDialect.SQLITE;
@@ -159,4 +160,11 @@ public interface CreateIndexWhereStep extends CreateIndexFinalStep {
@Support({ POSTGRES, SQLITE })
@PlainSQL
CreateIndexFinalStep where(String sql, QueryPart... parts);
+
+ /**
+ * Add a DB2 style EXCLUDE NULL KEYS clause to create a partial
+ * index.
+ */
+ @Support({ POSTGRES, SQLITE })
+ CreateIndexFinalStep excludeNullKeys();
}
diff --git a/jOOQ/src/main/java/org/jooq/impl/CreateIndexImpl.java b/jOOQ/src/main/java/org/jooq/impl/CreateIndexImpl.java
index 6117d64d43..ad3781b481 100644
--- a/jOOQ/src/main/java/org/jooq/impl/CreateIndexImpl.java
+++ b/jOOQ/src/main/java/org/jooq/impl/CreateIndexImpl.java
@@ -55,11 +55,15 @@ import static org.jooq.SQLDialect.POSTGRES;
// ...
// ...
import static org.jooq.impl.DSL.name;
+import static org.jooq.impl.DSL.row;
import static org.jooq.impl.DSL.table;
import static org.jooq.impl.Keywords.K_CREATE;
+import static org.jooq.impl.Keywords.K_EXCLUDE;
import static org.jooq.impl.Keywords.K_IF_NOT_EXISTS;
import static org.jooq.impl.Keywords.K_INCLUDE;
import static org.jooq.impl.Keywords.K_INDEX;
+import static org.jooq.impl.Keywords.K_KEYS;
+import static org.jooq.impl.Keywords.K_NULL;
import static org.jooq.impl.Keywords.K_ON;
import static org.jooq.impl.Keywords.K_STORING;
import static org.jooq.impl.Keywords.K_UNIQUE;
@@ -69,6 +73,8 @@ import static org.jooq.impl.Tools.EMPTY_NAME;
import static org.jooq.impl.Tools.EMPTY_ORDERFIELD;
import static org.jooq.impl.Tools.EMPTY_SORTFIELD;
import static org.jooq.impl.Tools.EMPTY_STRING;
+import static org.jooq.impl.Tools.field;
+import static org.jooq.impl.Tools.fields;
import java.util.Collection;
import java.util.Set;
@@ -102,19 +108,20 @@ final class CreateIndexImpl extends AbstractRowCountQuery implements
/**
* Generated UID
*/
- private static final long serialVersionUID = 8904572826501186329L;
- private static final Clause[] CLAUSES = { CREATE_INDEX };
- private static final Set NO_SUPPORT_IF_NOT_EXISTS = SQLDialect.supportedBy(DERBY, FIREBIRD);
- private static final Set SUPPORT_UNNAMED_INDEX = SQLDialect.supportedBy(POSTGRES);
- private static final Set SUPPORT_INCLUDE = SQLDialect.supportedBy(POSTGRES);
+ private static final long serialVersionUID = 8904572826501186329L;
+ private static final Clause[] CLAUSES = { CREATE_INDEX };
+ private static final Set NO_SUPPORT_IF_NOT_EXISTS = SQLDialect.supportedBy(DERBY, FIREBIRD);
+ private static final Set SUPPORT_UNNAMED_INDEX = SQLDialect.supportedBy(POSTGRES);
+ private static final Set SUPPORT_INCLUDE = SQLDialect.supportedBy(POSTGRES);
- private final Index index;
- private final boolean unique;
- private final boolean ifNotExists;
- private Table> table;
- private SortField>[] sortFields;
- private Field>[] include;
- private Condition where;
+ private final Index index;
+ private final boolean unique;
+ private final boolean ifNotExists;
+ private Table> table;
+ private SortField>[] sortFields;
+ private Field>[] include;
+ private Condition where;
+ private boolean excludeNullKeys;
CreateIndexImpl(Configuration configuration, Index index, boolean unique, boolean ifNotExists) {
super(configuration);
@@ -238,6 +245,12 @@ final class CreateIndexImpl extends AbstractRowCountQuery implements
return where(DSL.condition(sql, parts));
}
+ @Override
+ public final CreateIndexImpl excludeNullKeys() {
+ excludeNullKeys = true;
+ return this;
+ }
+
// ------------------------------------------------------------------------
// XXX: QueryPart API
// ------------------------------------------------------------------------
@@ -328,13 +341,26 @@ final class CreateIndexImpl extends AbstractRowCountQuery implements
.sql(')');
}
- if (where != null && ctx.configuration().data("org.jooq.ddl.ignore-storage-clauses") == null)
+ Condition c = where;
+
+ if (excludeNullKeys && c == null)
+
+
+
+ c = sortFields.length == 1 ? field(sortFields[0]).isNotNull() : row(fields(sortFields)).isNotNull();
+
+ if (c != null && ctx.configuration().data("org.jooq.ddl.ignore-storage-clauses") == null)
ctx.formatSeparator()
.visit(K_WHERE)
.sql(' ')
.qualify(false)
- .visit(where)
+ .visit(c)
.qualify(true);
+
+
+
+
+
}
private final Name generatedName() {
diff --git a/jOOQ/src/main/java/org/jooq/impl/Keywords.java b/jOOQ/src/main/java/org/jooq/impl/Keywords.java
index 058fa83707..3a52c7e07c 100644
--- a/jOOQ/src/main/java/org/jooq/impl/Keywords.java
+++ b/jOOQ/src/main/java/org/jooq/impl/Keywords.java
@@ -221,6 +221,7 @@ final class Keywords {
static final Keyword K_JSON_OBJECT = keyword("json_object");
static final Keyword K_KEEP = keyword("keep");
static final Keyword K_KEY = keyword("key");
+ static final Keyword K_KEYS = keyword("keys");
static final Keyword K_LAST = keyword("last");
static final Keyword K_LATERAL = keyword("lateral");
static final Keyword K_LEADING = keyword("leading");
diff --git a/jOOQ/src/main/java/org/jooq/impl/Tools.java b/jOOQ/src/main/java/org/jooq/impl/Tools.java
index f4a1deba76..b69dc6e2be 100644
--- a/jOOQ/src/main/java/org/jooq/impl/Tools.java
+++ b/jOOQ/src/main/java/org/jooq/impl/Tools.java
@@ -5166,6 +5166,19 @@ final class Tools {
return DSL.field(DSL.name(name), field.getDataType());
}
+ static final Field field(SortField sortField) {
+ return ((SortFieldImpl) sortField).getField();
+ }
+
+ static final Field>[] fields(SortField>[] sortFields) {
+ Field>[] result = new Field[sortFields.length];
+
+ for (int i = 0; i < result.length; i++)
+ result[i] = field(sortFields[i]);
+
+ return result;
+ }
+
static final Field unalias(Field field) {
Field result = aliased(field);
return result != null ? result : field;