Skip to content

Commit

Permalink
JCBC-1171 Allow to add hints for hash and nested loop joins in Query dsl
Browse files Browse the repository at this point in the history
Change-Id: Ib651726f38514adcc2fef150e41265ad81255299
Reviewed-on: http://review.couchbase.org/102501
Reviewed-by: David Nault <david.nault@couchbase.com>
Tested-by: Subhashni Balakrishnan <b.subhashni@gmail.com>
  • Loading branch information
bsubhashni committed Dec 6, 2018
1 parent db9b353 commit 37dbcb9
Show file tree
Hide file tree
Showing 6 changed files with 184 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright (c) 2018 Couchbase, Inc.
*
* 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
*
* http://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.
*/
package com.couchbase.client.java.query.dsl.element;

import com.couchbase.client.core.annotations.InterfaceAudience;
import com.couchbase.client.core.annotations.InterfaceStability;

/**
* Hint to use Nested loop join
*
* @author Subhashni Balakrishnan
*/
@InterfaceStability.Experimental
@InterfaceAudience.Private
public class NestedLoopJoinHintElement implements Element {

@Override
public String export() {
return "USE NL";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package com.couchbase.client.java.query.dsl.path;

import com.couchbase.client.java.query.dsl.element.AsElement;
import com.couchbase.client.java.query.dsl.element.NestedLoopJoinHintElement;

/**
* .
Expand All @@ -29,8 +30,20 @@ public DefaultJoinPath(AbstractPath parent) {
}

@Override
public KeysPath as(String alias) {
public JoinPath as(String alias) {
element(new AsElement(alias));
return new DefaultJoinPath(this);
}

@Override
public KeysPath useHash(HashSide side) {
element(new HashJoinHintElement(side));
return new DefaultKeysPath(this);
}

@Override
public KeysPath useNestedLoop() {
element(new NestedLoopJoinHintElement());
return new DefaultKeysPath(this);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright (c) 2018 Couchbase, Inc.
*
* 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
*
* http://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.
*/

package com.couchbase.client.java.query.dsl.path;

import java.util.Objects;

import com.couchbase.client.core.annotations.InterfaceAudience;
import com.couchbase.client.core.annotations.InterfaceStability;
import com.couchbase.client.java.query.dsl.element.Element;

/**
* Hash Join hint for hash based join
*
* @author Subhashni Balakrishnan
*/
@InterfaceStability.Experimental
@InterfaceAudience.Private
public class HashJoinHintElement implements Element {

private final HashSide side;

public HashJoinHintElement(HashSide side) {
Objects.requireNonNull(side);
this.side = side;
}

@Override
public String export() {
return "USE HASH(" + this.side + ")";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright (c) 2018 Couchbase, Inc.
*
* 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
*
* http://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.
*/

package com.couchbase.client.java.query.dsl.path;

import com.couchbase.client.core.annotations.InterfaceAudience;
import com.couchbase.client.core.annotations.InterfaceStability;

/**
* Hash side for hash based join
*
* @author Subhashni Balakrishnan
*/
@InterfaceStability.Experimental
@InterfaceAudience.Public
public enum HashSide {

/**
* The PROBE side will use that table to find matches and perform the join
* */
PROBE("PROBE"),

/**
* The BUILD side of the join will be used to create an in-memory hash table
* */
BUILD("BUILD");

private final String value;

HashSide(String value) {
this.value = value;
}

@Override
public String toString() {
return this.value;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,15 @@
*/
public interface JoinPath extends KeysPath {

KeysPath as(String alias);
JoinPath as(String alias);

/**
* Use hash join hint (Available in Enterprise Edition only)
*/
KeysPath useHash(HashSide side);

/**
* Use nested loop join
*/
KeysPath useNestedLoop();
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import com.couchbase.client.java.document.json.JsonArray;
import com.couchbase.client.java.query.Statement;
import com.couchbase.client.java.query.dsl.functions.DateFunctions;
import com.couchbase.client.java.query.dsl.path.HashSide;
import org.junit.Ignore;
import org.junit.Test;

Expand Down Expand Up @@ -679,4 +680,33 @@ public void test56() {

assertEquals("SELECT DISTINCT RAW name FROM authors", statement.toString());
}

@Test
public void test57() {
Statement statement = selectDistinctRaw("books.authorName").from("A").as("books").join("A")
.as("authors").useHash(HashSide.PROBE).on(x("books.authorName").eq(x("authors.name")))
.where(x("books.type").eq(s("book")).and(x("authors.type").eq(s("author"))));

assertEquals("SELECT DISTINCT RAW books.authorName FROM A AS books JOIN A AS authors USE HASH(PROBE) ON " +
"books.authorName = authors.name WHERE books.type = \"book\" AND authors.type = \"author\"", statement.toString());
}

@Test
public void test58() {
Statement statement = selectDistinctRaw("books.authorName").from("A").as("books").join("A")
.as("authors").useHash(HashSide.BUILD).on(x("books.authorName").eq(x("authors.name")))
.where(x("books.type").eq(s("book")).and(x("authors.type").eq(s("author"))));

assertEquals("SELECT DISTINCT RAW books.authorName FROM A AS books JOIN A AS authors USE HASH(BUILD) ON " +
"books.authorName = authors.name WHERE books.type = \"book\" AND authors.type = \"author\"", statement.toString());
}

@Test
public void test59() {
Statement statement = selectDistinctRaw("books.authorName").from("A").as("books").join("A")
.as("authors").useNestedLoop().on(x("books.authorName").eq(x("authors.name"))).where(x("books.type").eq(s("book")).and(x("authors.type").eq(s("author"))));

assertEquals("SELECT DISTINCT RAW books.authorName FROM A AS books JOIN A AS authors USE NL ON " +
"books.authorName = authors.name WHERE books.type = \"book\" AND authors.type = \"author\"", statement.toString());
}
}

0 comments on commit 37dbcb9

Please sign in to comment.