You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ak...@apache.org on 2016/08/31 06:33:21 UTC
[31/38] ignite git commit: IGNITE-3742: ODBC: Added support for OUTER
JOIN escape sequence. This closes #1000.
IGNITE-3742: ODBC: Added support for OUTER JOIN escape sequence. This closes #1000.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/3244a5c9
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/3244a5c9
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/3244a5c9
Branch: refs/heads/ignite-3443
Commit: 3244a5c9dabf6d4fcaa32a661cc0adc6f8ea30de
Parents: f9ff97c
Author: Andrey V. Mashenkov <an...@gmail.com>
Authored: Tue Aug 30 11:49:11 2016 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Tue Aug 30 11:49:11 2016 +0300
----------------------------------------------------------------------
.../processors/odbc/escape/OdbcEscapeUtils.java | 32 +++---
.../odbc/OdbcEscapeSequenceSelfTest.java | 109 ++++++++++++++++++-
2 files changed, 122 insertions(+), 19 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/3244a5c9/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/escape/OdbcEscapeUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/escape/OdbcEscapeUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/escape/OdbcEscapeUtils.java
index a4b89c3..27120d4 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/escape/OdbcEscapeUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/escape/OdbcEscapeUtils.java
@@ -105,14 +105,14 @@ public class OdbcEscapeUtils {
if (nested == null)
// Found sequence without nesting, process it.
- parseRes = parseExpression(text, openPos, curPos + 1 - openPos);
+ parseRes = parseEscapeSequence(text, openPos, curPos + 1 - openPos);
else {
// Special case to process nesting.
String res0 = appendNested(text, openPos, curPos + 1, nested);
nested = null;
- parseRes = parseExpression(res0, 0, res0.length());
+ parseRes = parseEscapeSequence(res0, 0, res0.length());
}
if (earlyExit)
@@ -139,14 +139,14 @@ public class OdbcEscapeUtils {
}
/**
- * Parse concrete expression.
+ * Parse escape sequence: {escape_sequence}.
*
* @param text Text.
* @param startPos Start position within text.
* @param len Length.
* @return Result.
*/
- private static String parseExpression(String text, int startPos, int len) {
+ private static String parseEscapeSequence(String text, int startPos, int len) {
assert validSubstring(text, startPos, len);
char firstChar = text.charAt(startPos);
@@ -228,7 +228,7 @@ public class OdbcEscapeUtils {
}
/**
- * Parse standard token.
+ * Parse standard expression: {TOKEN expression}
*
* @param text Text.
* @param startPos Start position.
@@ -245,10 +245,13 @@ public class OdbcEscapeUtils {
switch (token.type()) {
case SCALAR_FUNCTION:
- return parseScalarExpression(text, startPos0, len0);
+ return parseExpression(text, startPos0, len0);
+
+ case GUID: {
+ String res = parseExpression(text, startPos0, len0, token.type(), GUID_PATTERN);
- case GUID:
- return parseExpression(text, startPos0, len0, token.type(), GUID_PATTERN);
+ return "CAST(" + res + " AS UUID)";
+ }
case DATE:
return parseExpression(text, startPos0, len0, token.type(), DATE_PATTERN);
@@ -259,6 +262,9 @@ public class OdbcEscapeUtils {
case TIMESTAMP:
return parseExpression(text, startPos0, len0, token.type(), TIMESTAMP_PATTERN);
+ case OUTER_JOIN:
+ return parseExpression(text, startPos0, len0);
+
default:
throw new IgniteException("Unsupported escape sequence token [text=" +
substring(text, startPos, len) + ", token=" + token.type().body() + ']');
@@ -266,19 +272,19 @@ public class OdbcEscapeUtils {
}
/**
- * Parse scalar function expression.
+ * Parse simple expression.
*
* @param text Text.
* @param startPos Start position.
* @param len Length.
* @return Parsed expression.
*/
- private static String parseScalarExpression(String text, int startPos, int len) {
+ private static String parseExpression(String text, int startPos, int len) {
return substring(text, startPos, len).trim();
}
/**
- * Parse concrete expression.
+ * Parse expression and validate against ODBC specification with regex pattern.
*
* @param text Text.
* @param startPos Start position.
@@ -286,12 +292,12 @@ public class OdbcEscapeUtils {
* @return Parsed expression.
*/
private static String parseExpression(String text, int startPos, int len, OdbcEscapeType type, Pattern pattern) {
- String val = substring(text, startPos, len).trim();
+ String val = parseExpression(text, startPos, len);
if (!pattern.matcher(val).matches())
throw new IgniteException("Invalid " + type + " escape sequence: " + substring(text, startPos, len));
- return "CAST(" + val + " AS UUID)";
+ return val;
}
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/3244a5c9/modules/core/src/test/java/org/apache/ignite/internal/processors/odbc/OdbcEscapeSequenceSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/odbc/OdbcEscapeSequenceSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/odbc/OdbcEscapeSequenceSelfTest.java
index 1aa90fd..4887a67 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/odbc/OdbcEscapeSequenceSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/odbc/OdbcEscapeSequenceSelfTest.java
@@ -167,17 +167,17 @@ public class OdbcEscapeSequenceSelfTest extends GridCommonAbstractTest {
*/
public void testGuidEscapeSequence() {
check(
- "'12345678-9abc-def0-1234-123456789abc'",
+ "CAST('12345678-9abc-def0-1234-123456789abc' AS UUID)",
"{guid '12345678-9abc-def0-1234-123456789abc'}"
);
check(
- "select '12345678-9abc-def0-1234-123456789abc' from SomeTable;",
+ "select CAST('12345678-9abc-def0-1234-123456789abc' AS UUID) from SomeTable;",
"select {guid '12345678-9abc-def0-1234-123456789abc'} from SomeTable;"
);
check(
- "select '12345678-9abc-def0-1234-123456789abc'",
+ "select CAST('12345678-9abc-def0-1234-123456789abc' AS UUID)",
"select {guid '12345678-9abc-def0-1234-123456789abc'}"
);
}
@@ -212,17 +212,17 @@ public class OdbcEscapeSequenceSelfTest extends GridCommonAbstractTest {
*/
public void testGuidEscapeSequenceWithWhitespaces() throws Exception {
check(
- "'12345678-9abc-def0-1234-123456789abc'",
+ "CAST('12345678-9abc-def0-1234-123456789abc' AS UUID)",
"{ guid '12345678-9abc-def0-1234-123456789abc'}"
);
check(
- "'12345678-9abc-def0-1234-123456789abc'",
+ "CAST('12345678-9abc-def0-1234-123456789abc' AS UUID)",
"{ guid '12345678-9abc-def0-1234-123456789abc'}"
);
check(
- "'12345678-9abc-def0-1234-123456789abc'",
+ "CAST('12345678-9abc-def0-1234-123456789abc' AS UUID)",
"{ \n guid\n'12345678-9abc-def0-1234-123456789abc'}"
);
}
@@ -388,6 +388,103 @@ public class OdbcEscapeSequenceSelfTest extends GridCommonAbstractTest {
checkFail("select {}ts '2016-08-26 13:15:08'} from table;");
}
+
+ /**
+ * Test escape sequence series.
+ */
+ public void testOuterJoinFunction() throws Exception {
+ check(
+ "t OUTER JOIN t2 ON t.id=t2.id",
+ "{oj t OUTER JOIN t2 ON t.id=t2.id}"
+ );
+
+ check(
+ "select * from t OUTER JOIN t2 ON t.id=t2.id",
+ "select * from {oj t OUTER JOIN t2 ON t.id=t2.id}"
+ );
+
+ check(
+ "select * from t OUTER JOIN t2 ON t.id=t2.id ORDER BY t2.id",
+ "select * from {oj t OUTER JOIN t2 ON t.id=t2.id} ORDER BY t2.id"
+ );
+ }
+
+ /**
+ * Test simple nested escape sequences. Depth = 2.
+ */
+ public void testNestedOuterJoin() throws Exception {
+ check(
+ "t OUTER JOIN (t2 OUTER JOIN t3 ON t2.id=t3.id) ON t.id=t2.id",
+ "{oj t OUTER JOIN ({oj t2 OUTER JOIN t3 ON t2.id=t3.id}) ON t.id=t2.id}"
+ );
+
+ check(
+ "select * from t OUTER JOIN (t2 OUTER JOIN t3 ON t2.id=t3.id) ON t.id=t2.id",
+ "select * from {oj t OUTER JOIN ({oj t2 OUTER JOIN t3 ON t2.id=t3.id}) ON t.id=t2.id}"
+ );
+
+ check(
+ "select * from t OUTER JOIN (t2 OUTER JOIN t3 ON t2.id=t3.id) ON t.id=t2.id ORDER BY t2.id",
+ "select * from {oj t OUTER JOIN ({oj t2 OUTER JOIN t3 ON t2.id=t3.id}) ON t.id=t2.id} ORDER BY t2.id"
+ );
+ }
+
+ /**
+ * Test nested escape sequences. Depth > 2.
+ */
+ public void testDeepNestedOuterJoin() {
+ check(
+ "t OUTER JOIN (t2 OUTER JOIN (t3 OUTER JOIN t4 ON t3.id=t4.id) ON t2.id=t3.id) ON t.id=t2.id",
+ "{oj t OUTER JOIN ({oj t2 OUTER JOIN ({oj t3 OUTER JOIN t4 ON t3.id=t4.id}) ON t2.id=t3.id}) ON t.id=t2.id}"
+ );
+
+ check(
+ "select * from " +
+ "t OUTER JOIN (t2 OUTER JOIN (t3 OUTER JOIN t4 ON t3.id=t4.id) ON t2.id=t3.id) ON t.id=t2.id",
+ "select * from " +
+ "{oj t OUTER JOIN ({oj t2 OUTER JOIN ({oj t3 OUTER JOIN t4 ON t3.id=t4.id}) ON t2.id=t3.id})" +
+ " ON t.id=t2.id}"
+ );
+
+ check(
+ "select * from t OUTER JOIN (t2 OUTER JOIN (t3 OUTER JOIN t4 ON t3.id=t4.id) " +
+ "ON t2.id=t3.id) ON t.id=t2.id ORDER BY t4.id",
+ "select * from {oj t OUTER JOIN ({oj t2 OUTER JOIN ({oj t3 OUTER JOIN t4 ON t3.id=t4.id}) " +
+ "ON t2.id=t3.id}) ON t.id=t2.id} ORDER BY t4.id"
+ );
+ }
+
+ /**
+ * Test invalid escape sequence.
+ */
+ public void testFailedOnInvalidOuterJoinSequence() {
+ checkFail("{ojt OUTER JOIN t2 ON t.id=t2.id}");
+
+ checkFail("select {oj t OUTER JOIN ({oj t2 OUTER JOIN t3 ON t2.id=t3.id) ON t.id=t2.id} from SomeTable;");
+
+ checkFail("select oj t OUTER JOIN t2 ON t.id=t2.id} from SomeTable;");
+ }
+
+ /**
+ * Test escape sequences with additional whitespace characters
+ */
+ public void testOuterJoinSequenceWithWhitespaces() throws Exception {
+ check(
+ "t OUTER JOIN t2 ON t.id=t2.id",
+ "{ oj t OUTER JOIN t2 ON t.id=t2.id}"
+ );
+
+ check(
+ "t OUTER JOIN t2 ON t.id=t2.id",
+ "{ oj t OUTER JOIN t2 ON t.id=t2.id}"
+ );
+
+ check(
+ "t OUTER JOIN t2 ON t.id=t2.id",
+ " \n { oj\nt OUTER JOIN t2 ON t.id=t2.id}"
+ );
+ }
+
/**
* Check parsing logic.
*