Skip to content

Commit

Permalink
Further work on oracle and mssql support
Browse files Browse the repository at this point in the history
  • Loading branch information
beikov committed Nov 28, 2016
1 parent 8d7a2ad commit 90d5a47
Show file tree
Hide file tree
Showing 23 changed files with 305 additions and 147 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Expand Up @@ -9,8 +9,10 @@ Not yet released
### New features

* Spring integration for Entity Views
* Spring Data integration for Entity Views
* Showcase for CDI and Spring usage
* Allow to reuse keyset page in more situations
* Oracle and SQL Server support

### Bug fixes

Expand All @@ -22,7 +24,7 @@ Not yet released

### Backwards-incompatible changes

None
* DbmsDialect has been extended. If you have a custom implementation you have to adapt

## 1.2.0-Alpha1

Expand Down
3 changes: 3 additions & 0 deletions build-local.sh
Expand Up @@ -32,6 +32,9 @@ if [ "$DBMS" == "" ]; then
elif [ "$input" == "oracle" ]; then
DBMS=$input
PROPERTIES="-Djdbc.url=jdbc:oracle:thin:@$DB_HOST:1521/xe -Djdbc.user=$ORACLE_USER -Djdbc.password=$ORACLE_PASSWORD"
elif [ "$input" == "mssql" ]; then
DBMS=$input
PROPERTIES="-Djdbc.url=jdbc:sqlserver://$DB_HOST:1433"
else
DBMS=$input
fi
Expand Down
Expand Up @@ -58,6 +58,13 @@ public interface DbmsDialect {
*/
public boolean supportsNonRecursiveWithClause();

/**
* Returns true if the dbms supports the with clause head for aliasing, false otherwise.
*
* @return Whether the with clause head is supported by the dbms
*/
public boolean supportsWithClauseHead();

/**
* Returns the SQL representation for the normal or recursive with clause.
*
Expand Down
Expand Up @@ -1358,27 +1358,47 @@ protected List<CTENode> getCteNodes(Query baseQuery, boolean isSubquery) {
}

String cteName = cteInfo.cteType.getName();
sb.setLength(0);
sb.append(cteName);
sb.append('(');

final List<String> attributes = cteInfo.attributes;
boolean first = true;
for (int i = 0; i < attributes.size(); i++) {
String[] columns = cbf.getExtendedQuerySupport().getColumnNames(em, cteInfo.cteType, attributes.get(i));
for (String column : columns) {
if (first) {
first = false;
} else {
sb.append(", ");
String head;
String[] aliases;

if (dbmsDialect.supportsWithClauseHead()) {
sb.setLength(0);
sb.append(cteName);
sb.append('(');

boolean first = true;
for (int i = 0; i < attributes.size(); i++) {
String[] columns = cbf.getExtendedQuerySupport().getColumnNames(em, cteInfo.cteType, attributes.get(i));
for (String column : columns) {
if (first) {
first = false;
} else {
sb.append(", ");
}

sb.append(column);
}
}

sb.append(column);
sb.append(')');
head = sb.toString();
aliases = null;
} else {
sb.setLength(0);
sb.append(cteName);
List<String> list = new ArrayList<>(attributes.size());

for (int i = 0; i < attributes.size(); i++) {
String[] columns = cbf.getExtendedQuerySupport().getColumnNames(em, cteInfo.cteType, attributes.get(i));
for (String column : columns) {
list.add(column);
}
}
}

sb.append(')');
String head = sb.toString();
head = sb.toString();
aliases = list.toArray(new String[list.size()]);
}

String nonRecursiveWithClauseSuffix = null;
if (!cteInfo.recursive && !dbmsDialect.supportsNonRecursiveWithClause()) {
Expand All @@ -1401,6 +1421,7 @@ protected List<CTENode> getCteNodes(Query baseQuery, boolean isSubquery) {
cteInfo.name,
cteInfo.cteType.getName(),
head,
aliases,
cteInfo.unionAll,
nonRecursiveQuerySpecification,
recursiveQuerySpecification,
Expand Down
Expand Up @@ -220,25 +220,26 @@ protected boolean isCompatibilityVectorMYS() {
}

@Override
protected void appendSetOperands(StringBuilder sqlSb, SetOperationType setType, String operator, boolean isSubquery, List<String> operands, boolean hasOuterClause) {
protected String[] appendSetOperands(StringBuilder sqlSb, SetOperationType setType, String operator, boolean isSubquery, List<String> operands, boolean hasOuterClause) {
if (!hasOuterClause) {
super.appendSetOperands(sqlSb, setType, operator, isSubquery, operands, hasOuterClause);
return super.appendSetOperands(sqlSb, setType, operator, isSubquery, operands, hasOuterClause);
} else {
sqlSb.append("select * from (");
super.appendSetOperands(sqlSb, setType, operator, isSubquery, operands, hasOuterClause);
String[] aliases = super.appendSetOperands(sqlSb, setType, operator, isSubquery, operands, hasOuterClause);
sqlSb.append(')');
return aliases;
}
}

@Override
protected void appendOrderByElement(StringBuilder sqlSb, OrderByElement element) {
protected void appendOrderByElement(StringBuilder sqlSb, OrderByElement element, String[] aliases) {
if ((element.isNullsFirst() && !element.isAscending()) || (!element.isNullsFirst() && element.isAscending())) {
// The following are ok according to DB2 docs
// ASC + NULLS LAST
// DESC + NULLS FIRST
super.appendOrderByElement(sqlSb, element);
super.appendOrderByElement(sqlSb, element, aliases);
} else {
appendEmulatedOrderByElementWithNulls(sqlSb, element);
appendEmulatedOrderByElementWithNulls(sqlSb, element, aliases);
}
}

Expand Down
Expand Up @@ -92,6 +92,11 @@ public boolean supportsNonRecursiveWithClause() {
return true;
}

@Override
public boolean supportsWithClauseHead() {
return supportsWithClause();
}

@Override
public boolean supportsJoinsInRecursiveCte() {
return true;
Expand Down Expand Up @@ -123,7 +128,7 @@ public Map<String, String> appendExtendedSql(StringBuilder sqlSb, DbmsStatementT
if (limit != null) {
appendLimit(sqlSb, isSubquery, limit, offset);
}
if (isSubquery && !supportsReturningColumns() && returningColumns != null) {
if (isSubquery && !supportsModificationQueryInWithClause() && returningColumns != null) {
throw new IllegalArgumentException("Returning columns in a subquery is not possible for this dbms!");
}

Expand All @@ -146,8 +151,8 @@ public void appendSet(StringBuilder sqlSb, SetOperationType setType, boolean isS
boolean hasOrderBy = orderByElements.size() > 0;
boolean hasOuterClause = hasLimit || hasOrderBy;

appendSetOperands(sqlSb, setType, operator, isSubquery, operands, hasOuterClause);
appendOrderBy(sqlSb, orderByElements);
String[] aliases = appendSetOperands(sqlSb, setType, operator, isSubquery, operands, hasOuterClause);
appendOrderBy(sqlSb, orderByElements, aliases);

if (limit != null) {
appendLimit(sqlSb, isSubquery, limit, offset);
Expand All @@ -168,17 +173,30 @@ protected String getWindowFunctionDummyOrderBy() {
return null;
}

protected void appendSetOperands(StringBuilder sqlSb, SetOperationType setType, String operator, boolean isSubquery, List<String> operands, boolean hasOuterClause) {
protected boolean needsAliasInSetOrderby() {
return false;
}

protected String[] appendSetOperands(StringBuilder sqlSb, SetOperationType setType, String operator, boolean isSubquery, List<String> operands, boolean hasOuterClause) {
boolean first = true;
final boolean emulate = setType == SetOperationType.EXCEPT_ALL && !supportsExcept(true) || setType == SetOperationType.INTERSECT_ALL && !supportsIntersect(true);
final String select = "select ";
final String windowFunctionDummyOrderBy = getWindowFunctionDummyOrderBy();
String[] aliases = null;

if (needsAliasInSetOrderby()) {
int selectIndex = SqlUtils.indexOfSelect(operands.get(0));
aliases = SqlUtils.getSelectItemAliases(operands.get(0), selectIndex);
}

for (String operand : operands) {
if (first) {
first = false;
if (emulate) {
int selectIndex = SqlUtils.indexOfSelect(operand);
String[] aliases = SqlUtils.getSelectItemAliases(operand, selectIndex);
if (aliases == null) {
int selectIndex = SqlUtils.indexOfSelect(operand);
aliases = SqlUtils.getSelectItemAliases(operand, selectIndex);
}

sqlSb.append(select);
for (int i = 0; i < aliases.length; i++) {
Expand Down Expand Up @@ -223,9 +241,11 @@ protected void appendSetOperands(StringBuilder sqlSb, SetOperationType setType,
if (emulate) {
sqlSb.append(')');
}

return aliases;
}

protected void appendOrderBy(StringBuilder sqlSb, List<? extends OrderByElement> orderByElements) {
protected void appendOrderBy(StringBuilder sqlSb, List<? extends OrderByElement> orderByElements, String[] aliases) {
if (orderByElements.isEmpty()) {
return;
}
Expand All @@ -239,12 +259,16 @@ protected void appendOrderBy(StringBuilder sqlSb, List<? extends OrderByElement>
sqlSb.append(',');
}

appendOrderByElement(sqlSb, element);
appendOrderByElement(sqlSb, element, aliases);
}
}

protected void appendOrderByElement(StringBuilder sqlSb, OrderByElement element) {
sqlSb.append(element.getPosition());
protected void appendOrderByElement(StringBuilder sqlSb, OrderByElement element, String[] aliases) {
if (aliases != null) {
sqlSb.append(aliases[element.getPosition() - 1]);
} else {
sqlSb.append(element.getPosition());
}

if (element.isAscending()) {
sqlSb.append(" asc");
Expand All @@ -258,9 +282,13 @@ protected void appendOrderByElement(StringBuilder sqlSb, OrderByElement element)
}
}

protected void appendEmulatedOrderByElementWithNulls(StringBuilder sqlSb, OrderByElement element) {
protected void appendEmulatedOrderByElementWithNulls(StringBuilder sqlSb, OrderByElement element, String[] aliases) {
sqlSb.append("case when ");
sqlSb.append(element.getPosition());
if (aliases != null) {
sqlSb.append(aliases[element.getPosition() - 1]);
} else {
sqlSb.append(element.getPosition());
}
sqlSb.append(" is null then ");
sqlSb.append(element.isNullsFirst() ? 0 : 1);
sqlSb.append(" else ");
Expand Down
Expand Up @@ -72,13 +72,14 @@ public Map<String, String> appendExtendedSql(StringBuilder sqlSb, DbmsStatementT
}

@Override
protected void appendSetOperands(StringBuilder sqlSb, SetOperationType setType, String operator, boolean isSubquery, List<String> operands, boolean hasOuterClause) {
protected String[] appendSetOperands(StringBuilder sqlSb, SetOperationType setType, String operator, boolean isSubquery, List<String> operands, boolean hasOuterClause) {
if (!hasOuterClause) {
super.appendSetOperands(sqlSb, setType, operator, isSubquery, operands, hasOuterClause);
return super.appendSetOperands(sqlSb, setType, operator, isSubquery, operands, hasOuterClause);
} else {
sqlSb.append("select * from (");
super.appendSetOperands(sqlSb, setType, operator, isSubquery, operands, hasOuterClause);
String[] aliases = super.appendSetOperands(sqlSb, setType, operator, isSubquery, operands, hasOuterClause);
sqlSb.append(')');
return aliases;
}
}

Expand Down

0 comments on commit 90d5a47

Please sign in to comment.