You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by nt...@apache.org on 2021/02/25 12:21:47 UTC
[cayenne] branch master updated (dda8c48 -> 37ee115)
This is an automated email from the ASF dual-hosted git repository.
ntimofeev pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/cayenne.git.
from dda8c48 CAY-2661 release notes
new ed66f0e CAY-2587 SQLServer Limit Offset convertation
new c996804 fixed manual offset for sql server
new ed86e5d the TOP query is used for null db version
new d839fb7 Merge branch 'pr/448' into asf-master
new 37ee115 CAY-2587 SQLServer Limit Offset translation - refactoring and cleanup - release notes
The 5 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
RELEASE-NOTES.txt | 1 +
.../access/sqlbuilder/sqltree/NodeType.java | 3 +-
.../access/sqlbuilder/sqltree/OrderByNode.java | 5 +++
.../java/org/apache/cayenne/dba/AutoAdapter.java | 1 +
.../java/org/apache/cayenne/dba/DbAdapter.java | 1 +
.../dba/sqlserver/SQLServerActionBuilder.java | 52 +++++++++++++++++++---
.../cayenne/dba/sqlserver/SQLServerAdapter.java | 32 +++++++++++--
.../sqlserver/SQLServerSelectAction.java} | 43 ++++++------------
.../cayenne/dba/sqlserver/SQLServerSniffer.java | 1 +
.../dba/sqlserver/SQLServerTreeProcessor.java | 6 +--
.../SQLServerTreeProcessorV12.java} | 29 +++++++++---
.../sqltree/SQLServerLimitOffsetNode.java} | 46 ++++++++-----------
12 files changed, 145 insertions(+), 75 deletions(-)
copy cayenne-server/src/main/java/org/apache/cayenne/{value/Json.java => dba/sqlserver/SQLServerSelectAction.java} (54%)
copy cayenne-server/src/main/java/org/apache/cayenne/dba/{h2/H2SQLTreeProcessor.java => sqlserver/SQLServerTreeProcessorV12.java} (55%)
copy cayenne-server/src/main/java/org/apache/cayenne/{value/GeoJson.java => dba/sqlserver/sqltree/SQLServerLimitOffsetNode.java} (51%)
[cayenne] 01/05: CAY-2587 SQLServer Limit Offset convertation
Posted by nt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
ntimofeev pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cayenne.git
commit ed66f0e4e8aa73c5cd49fd6237452786b85db7e7
Author: andreykravchenko <an...@objectstyle.com>
AuthorDate: Mon Feb 8 15:46:18 2021 +0300
CAY-2587 SQLServer Limit Offset convertation
---
.../java/org/apache/cayenne/dba/AutoAdapter.java | 7 +++++
.../java/org/apache/cayenne/dba/DbAdapter.java | 2 ++
.../java/org/apache/cayenne/dba/JdbcAdapter.java | 10 +++++++
.../cayenne/dba/sqlserver/SQLServerAdapter.java | 4 ++-
.../cayenne/dba/sqlserver/SQLServerSniffer.java | 1 +
.../dba/sqlserver/SQLServerTreeProcessor.java | 28 +++++++++++++++++--
.../sqltree/SQLServerLimitOffsetNode.java | 31 ++++++++++++++++++++++
7 files changed, 80 insertions(+), 3 deletions(-)
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/AutoAdapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/AutoAdapter.java
index 54baa19..3c68a62 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/AutoAdapter.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/AutoAdapter.java
@@ -60,6 +60,8 @@ public class AutoAdapter implements DbAdapter {
*/
volatile DbAdapter adapter;
+ protected Integer version;
+
/**
* Creates an {@link AutoAdapter} based on a delegate adapter obtained via
* "adapterProvider".
@@ -270,4 +272,9 @@ public class AutoAdapter implements DbAdapter {
public List<String> getSystemSchemas() {
return getAdapter().getSystemSchemas();
}
+
+ @Override
+ public Integer getVersion() {
+ return version;
+ }
}
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/DbAdapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/DbAdapter.java
index a043e2f..70f88ae 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/DbAdapter.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/DbAdapter.java
@@ -255,4 +255,6 @@ public interface DbAdapter {
* @return list of system schemas
*/
List<String> getSystemSchemas();
+
+ Integer getVersion();
}
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcAdapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcAdapter.java
index 4a23596..ad0a0ca 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcAdapter.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcAdapter.java
@@ -78,6 +78,8 @@ public class JdbcAdapter implements DbAdapter {
protected ResourceLocator resourceLocator;
protected boolean caseInsensitiveCollations;
+ protected Integer version;
+
/**
* @since 3.1
* @deprecated since 4.0 BatchQueryBuilderfactory is attached to the DataNode.
@@ -653,4 +655,12 @@ public class JdbcAdapter implements DbAdapter {
return this;
}
+ @Override
+ public Integer getVersion() {
+ return version;
+ }
+
+ public void setVersion(Integer version) {
+ this.version = version;
+ }
}
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerAdapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerAdapter.java
index 92fcd46..611260a 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerAdapter.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerAdapter.java
@@ -109,7 +109,9 @@ public class SQLServerAdapter extends SybaseAdapter {
*/
@Override
public SQLTreeProcessor getSqlTreeProcessor() {
- return new SQLServerTreeProcessor();
+ SQLServerTreeProcessor sqlServerTreeProcessor = new SQLServerTreeProcessor();
+ sqlServerTreeProcessor.setVersion(this.getVersion());
+ return sqlServerTreeProcessor;
}
/**
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerSniffer.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerSniffer.java
index 052e8eb..f0c7d6f 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerSniffer.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerSniffer.java
@@ -50,6 +50,7 @@ public class SQLServerSniffer implements DbAdapterDetector {
SQLServerAdapter adapter = objectFactory.newInstance(
SQLServerAdapter.class,
SQLServerAdapter.class.getName());
+ adapter.setVersion(md.getDatabaseMajorVersion());
// detect whether generated keys are supported
boolean generatedKeys = false;
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerTreeProcessor.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerTreeProcessor.java
index e2ecd53..77721a3 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerTreeProcessor.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerTreeProcessor.java
@@ -19,9 +19,9 @@
package org.apache.cayenne.dba.sqlserver;
-import org.apache.cayenne.access.sqlbuilder.sqltree.ColumnNode;
-import org.apache.cayenne.access.sqlbuilder.sqltree.Node;
+import org.apache.cayenne.access.sqlbuilder.sqltree.*;
import org.apache.cayenne.dba.sqlserver.sqltree.SQLServerColumnNode;
+import org.apache.cayenne.dba.sqlserver.sqltree.SQLServerLimitOffsetNode;
import org.apache.cayenne.dba.sybase.SybaseSQLTreeProcessor;
/**
@@ -29,8 +29,32 @@ import org.apache.cayenne.dba.sybase.SybaseSQLTreeProcessor;
*/
public class SQLServerTreeProcessor extends SybaseSQLTreeProcessor {
+ private Integer version;
+
@Override
protected void onColumnNode(Node parent, ColumnNode child, int index) {
replaceChild(parent, index, new SQLServerColumnNode(child));
}
+
+ @Override
+ protected void onLimitOffsetNode(Node parent, LimitOffsetNode child, int index) {
+ if (version >= 12) {
+ for (int i = 0; i < parent.getChildrenCount(); i++) {
+ if (parent.getChild(i) instanceof OrderByNode) {
+ replaceChild(parent, index, new SQLServerLimitOffsetNode(child.getLimit(), child.getOffset()));
+ return;
+ }
+ }
+ }
+
+ super.onLimitOffsetNode(parent, child, index);
+ }
+
+ public Integer getVersion() {
+ return version;
+ }
+
+ public void setVersion(Integer version) {
+ this.version = version;
+ }
}
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/sqltree/SQLServerLimitOffsetNode.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/sqltree/SQLServerLimitOffsetNode.java
new file mode 100644
index 0000000..47cda22
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/sqltree/SQLServerLimitOffsetNode.java
@@ -0,0 +1,31 @@
+package org.apache.cayenne.dba.sqlserver.sqltree;
+
+import org.apache.cayenne.access.sqlbuilder.QuotingAppendable;
+import org.apache.cayenne.access.sqlbuilder.sqltree.LimitOffsetNode;
+import org.apache.cayenne.access.sqlbuilder.sqltree.Node;
+
+/**
+ * @since 4.2
+ */
+public class SQLServerLimitOffsetNode extends LimitOffsetNode {
+
+ public SQLServerLimitOffsetNode(int limit, int offset) {
+ // Per SQLServer documentation: "To retrieve all rows from a certain offset up to the end of the result set,
+ // you can use some large number for the second parameter."
+ super(limit == 0 && offset > 0 ? Integer.MAX_VALUE : limit, offset);
+ }
+
+ @Override
+ public QuotingAppendable append(QuotingAppendable buffer) {
+ if(limit == 0 && offset == 0) {
+ return buffer;
+ }
+ return buffer.append(" OFFSET ").append(offset).append(" ROWS FETCH NEXT ").append(limit).append(" ROWS ONLY ");
+ }
+
+ @Override
+ public Node copy() {
+ return new SQLServerLimitOffsetNode(limit, offset);
+ }
+
+}
[cayenne] 04/05: Merge branch 'pr/448' into asf-master
Posted by nt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
ntimofeev pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cayenne.git
commit d839fb7871aab6ddb3590e5acff39b7d16c75c6b
Merge: dda8c48 ed86e5d
Author: Nikita Timofeev <st...@gmail.com>
AuthorDate: Thu Feb 25 12:12:57 2021 +0300
Merge branch 'pr/448' into asf-master
.../java/org/apache/cayenne/dba/AutoAdapter.java | 1 +
.../java/org/apache/cayenne/dba/DbAdapter.java | 1 +
.../dba/sqlserver/SQLServerActionBuilder.java | 45 ++++++++++++++++--
.../cayenne/dba/sqlserver/SQLServerAdapter.java | 24 +++++++++-
.../dba/sqlserver/SQLServerSelectAction.java | 50 ++++++++++++++++++++
.../cayenne/dba/sqlserver/SQLServerSniffer.java | 1 +
.../dba/sqlserver/SQLServerTreeProcessor.java | 28 +++++++++++-
.../sqltree/SQLServerLimitOffsetNode.java | 53 ++++++++++++++++++++++
8 files changed, 196 insertions(+), 7 deletions(-)
[cayenne] 02/05: fixed manual offset for sql server
Posted by nt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
ntimofeev pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cayenne.git
commit c99680429a68ebd992d99f1f4988fbe739f1e7bf
Author: andreykravchenko <an...@objectstyle.com>
AuthorDate: Wed Feb 10 12:30:33 2021 +0300
fixed manual offset for sql server
---
.../java/org/apache/cayenne/dba/AutoAdapter.java | 6 ---
.../java/org/apache/cayenne/dba/DbAdapter.java | 1 -
.../java/org/apache/cayenne/dba/JdbcAdapter.java | 10 -----
.../dba/sqlserver/SQLServerActionBuilder.java | 28 ++++++++++--
.../cayenne/dba/sqlserver/SQLServerAdapter.java | 18 +++++++-
.../dba/sqlserver/SQLServerSelectAction.java | 50 ++++++++++++++++++++++
.../dba/sqlserver/SQLServerTreeProcessor.java | 4 +-
.../sqltree/SQLServerLimitOffsetNode.java | 30 +++++++++++--
8 files changed, 120 insertions(+), 27 deletions(-)
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/AutoAdapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/AutoAdapter.java
index 3c68a62..87d0972 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/AutoAdapter.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/AutoAdapter.java
@@ -60,8 +60,6 @@ public class AutoAdapter implements DbAdapter {
*/
volatile DbAdapter adapter;
- protected Integer version;
-
/**
* Creates an {@link AutoAdapter} based on a delegate adapter obtained via
* "adapterProvider".
@@ -273,8 +271,4 @@ public class AutoAdapter implements DbAdapter {
return getAdapter().getSystemSchemas();
}
- @Override
- public Integer getVersion() {
- return version;
- }
}
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/DbAdapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/DbAdapter.java
index 70f88ae..54e8580 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/DbAdapter.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/DbAdapter.java
@@ -256,5 +256,4 @@ public interface DbAdapter {
*/
List<String> getSystemSchemas();
- Integer getVersion();
}
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcAdapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcAdapter.java
index ad0a0ca..4a23596 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcAdapter.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcAdapter.java
@@ -78,8 +78,6 @@ public class JdbcAdapter implements DbAdapter {
protected ResourceLocator resourceLocator;
protected boolean caseInsensitiveCollations;
- protected Integer version;
-
/**
* @since 3.1
* @deprecated since 4.0 BatchQueryBuilderfactory is attached to the DataNode.
@@ -655,12 +653,4 @@ public class JdbcAdapter implements DbAdapter {
return this;
}
- @Override
- public Integer getVersion() {
- return version;
- }
-
- public void setVersion(Integer version) {
- this.version = version;
- }
}
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerActionBuilder.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerActionBuilder.java
index 4ebde3f..f19a671 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerActionBuilder.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerActionBuilder.java
@@ -21,9 +21,7 @@ package org.apache.cayenne.dba.sqlserver;
import org.apache.cayenne.access.DataNode;
import org.apache.cayenne.dba.JdbcActionBuilder;
-import org.apache.cayenne.query.BatchQuery;
-import org.apache.cayenne.query.ProcedureQuery;
-import org.apache.cayenne.query.SQLAction;
+import org.apache.cayenne.query.*;
/**
* @since 1.2
@@ -53,4 +51,28 @@ public class SQLServerActionBuilder extends JdbcActionBuilder {
public SQLAction procedureAction(ProcedureQuery query) {
return new SQLServerProcedureAction(query, dataNode);
}
+
+ /**
+ * @since 4.2
+ */
+ @Override
+ public <T> SQLAction objectSelectAction(SelectQuery<T> query) {
+ if (query.getOrderings() == null || query.getOrderings().size() == 0) {
+ return new SQLServerSelectAction(query, dataNode, true);
+ }
+
+ return new SQLServerSelectAction(query, dataNode, false);
+ }
+
+ /**
+ * @since 4.2
+ */
+ @Override
+ public <T> SQLAction objectSelectAction(FluentSelect<T> query) {
+ if (query.getOrderings() == null || query.getOrderings().size() == 0) {
+ return new SQLServerSelectAction(query, dataNode, true);
+ }
+
+ return new SQLServerSelectAction(query, dataNode, false);
+ }
}
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerAdapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerAdapter.java
index 611260a..67871df 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerAdapter.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerAdapter.java
@@ -75,6 +75,15 @@ import org.apache.cayenne.resource.ResourceLocator;
public class SQLServerAdapter extends SybaseAdapter {
/**
+ * Stores the major version of the database.
+ * Database versions 12 and higher support the use of LIMIT,
+ * lower versions use TOP N
+ *
+ * @since 4.2
+ */
+ protected Integer version;
+
+ /**
* @deprecated since 4.2 unused
*/
@Deprecated
@@ -110,7 +119,7 @@ public class SQLServerAdapter extends SybaseAdapter {
@Override
public SQLTreeProcessor getSqlTreeProcessor() {
SQLServerTreeProcessor sqlServerTreeProcessor = new SQLServerTreeProcessor();
- sqlServerTreeProcessor.setVersion(this.getVersion());
+ sqlServerTreeProcessor.setVersion(getVersion());
return sqlServerTreeProcessor;
}
@@ -129,4 +138,11 @@ public class SQLServerAdapter extends SybaseAdapter {
return SYSTEM_SCHEMAS;
}
+ public Integer getVersion() {
+ return version;
+ }
+
+ public void setVersion(Integer version) {
+ this.version = version;
+ }
}
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerSelectAction.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerSelectAction.java
new file mode 100644
index 0000000..7c09eef
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerSelectAction.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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
+ *
+ * https://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 org.apache.cayenne.dba.sqlserver;
+
+import org.apache.cayenne.access.DataNode;
+import org.apache.cayenne.access.jdbc.SelectAction;
+import org.apache.cayenne.query.Select;
+
+/**
+ * @since 4.2
+ */
+public class SQLServerSelectAction extends SelectAction {
+
+ /**
+ * When using TOP N instead of LIMIT. The offset will be manual.
+ *
+ */
+ private Boolean isManualOffset;
+
+ public SQLServerSelectAction(Select<?> query, DataNode dataNode, Boolean isManualOffset) {
+ super(query, dataNode);
+
+ this.isManualOffset = isManualOffset;
+ }
+
+ @Override
+ protected int getInMemoryOffset(int queryOffset) {
+ if (isManualOffset) {
+ return super.getInMemoryOffset(queryOffset);
+ }
+ return 0;
+ }
+}
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerTreeProcessor.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerTreeProcessor.java
index 77721a3..c1c8c98 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerTreeProcessor.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerTreeProcessor.java
@@ -38,10 +38,10 @@ public class SQLServerTreeProcessor extends SybaseSQLTreeProcessor {
@Override
protected void onLimitOffsetNode(Node parent, LimitOffsetNode child, int index) {
- if (version >= 12) {
+ if (version == null || version >= 12) {
for (int i = 0; i < parent.getChildrenCount(); i++) {
if (parent.getChild(i) instanceof OrderByNode) {
- replaceChild(parent, index, new SQLServerLimitOffsetNode(child.getLimit(), child.getOffset()));
+ replaceChild(parent, index, new SQLServerLimitOffsetNode(child.getLimit(), child.getOffset()), false);
return;
}
}
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/sqltree/SQLServerLimitOffsetNode.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/sqltree/SQLServerLimitOffsetNode.java
index 47cda22..1b916aa 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/sqltree/SQLServerLimitOffsetNode.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/sqltree/SQLServerLimitOffsetNode.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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
+ *
+ * https://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 org.apache.cayenne.dba.sqlserver.sqltree;
import org.apache.cayenne.access.sqlbuilder.QuotingAppendable;
@@ -10,17 +29,20 @@ import org.apache.cayenne.access.sqlbuilder.sqltree.Node;
public class SQLServerLimitOffsetNode extends LimitOffsetNode {
public SQLServerLimitOffsetNode(int limit, int offset) {
- // Per SQLServer documentation: "To retrieve all rows from a certain offset up to the end of the result set,
- // you can use some large number for the second parameter."
- super(limit == 0 && offset > 0 ? Integer.MAX_VALUE : limit, offset);
+ super(limit, offset);
}
@Override
public QuotingAppendable append(QuotingAppendable buffer) {
+ // OFFSET X ROWS FETCH NEXT Y ROWS ONLY
if(limit == 0 && offset == 0) {
return buffer;
}
- return buffer.append(" OFFSET ").append(offset).append(" ROWS FETCH NEXT ").append(limit).append(" ROWS ONLY ");
+ buffer.append(" OFFSET ").append(offset).append(" ROWS");
+ if (limit > 0) {
+ return buffer.append(" FETCH NEXT ").append(limit).append(" ROWS ONLY");
+ }
+ return buffer;
}
@Override
[cayenne] 05/05: CAY-2587 SQLServer Limit Offset translation -
refactoring and cleanup - release notes
Posted by nt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
ntimofeev pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cayenne.git
commit 37ee115185a3234c14d7dcf1bc6afc014e7225c1
Author: Nikita Timofeev <st...@gmail.com>
AuthorDate: Thu Feb 25 15:21:36 2021 +0300
CAY-2587 SQLServer Limit Offset translation
- refactoring and cleanup
- release notes
---
RELEASE-NOTES.txt | 1 +
.../access/sqlbuilder/sqltree/NodeType.java | 3 +-
.../access/sqlbuilder/sqltree/OrderByNode.java | 5 +++
.../dba/sqlserver/SQLServerActionBuilder.java | 41 ++++++++++----------
.../cayenne/dba/sqlserver/SQLServerAdapter.java | 26 +++++++------
.../dba/sqlserver/SQLServerSelectAction.java | 15 +++-----
.../dba/sqlserver/SQLServerTreeProcessor.java | 26 +------------
...ocessor.java => SQLServerTreeProcessorV12.java} | 44 ++++++++++------------
8 files changed, 70 insertions(+), 91 deletions(-)
diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt
index 5b821b1..ddd59d4 100644
--- a/RELEASE-NOTES.txt
+++ b/RELEASE-NOTES.txt
@@ -13,6 +13,7 @@ Date:
----------------------------------
Changes/New Features:
+CAY-2587 SQLServer Limit Offset translation
CAY-2677 Custom Class Generation Templates for Embeddables and DataMaps
CAY-2689 ServerRuntime API: missing some variants of the performInTransaction() method
CAY-2692 Add entity lifecycle callbacks via annotated methods
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/NodeType.java b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/NodeType.java
index 575d330..f463c07 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/NodeType.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/NodeType.java
@@ -38,5 +38,6 @@ public enum NodeType {
FROM,
UPDATE_SET,
INSERT_COLUMNS,
- INSERT_VALUES
+ INSERT_VALUES,
+ ORDER_BY
}
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/OrderByNode.java b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/OrderByNode.java
index 7e54ae6..663f66c 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/OrderByNode.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/OrderByNode.java
@@ -40,4 +40,9 @@ public class OrderByNode extends Node {
public Node copy() {
return new OrderByNode();
}
+
+ @Override
+ public NodeType getType() {
+ return NodeType.ORDER_BY;
+ }
}
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerActionBuilder.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerActionBuilder.java
index bd43ee9..bb82143 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerActionBuilder.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerActionBuilder.java
@@ -33,23 +33,32 @@ public class SQLServerActionBuilder extends JdbcActionBuilder {
*
* @since 4.2
*/
- private Integer version;
+ private final Integer version;
/**
+ * @param dataNode current data node
* @since 4.0
*/
public SQLServerActionBuilder(DataNode dataNode) {
+ this(dataNode, null);
+ }
+
+ /**
+ * @param dataNode current data node
+ * @param version database server version
+ * @since 4.2
+ */
+ public SQLServerActionBuilder(DataNode dataNode, Integer version) {
super(dataNode);
+ this.version = version;
}
@Override
public SQLAction batchAction(BatchQuery query) {
// check run strategy...
- // optimistic locking is not supported in batches due to JDBC driver
- // limitations
+ // optimistic locking is not supported in batches due to JDBC driver limitations
boolean useOptimisticLock = query.isUsingOptimisticLocking();
-
boolean runningAsBatch = !useOptimisticLock && dataNode.getAdapter().supportsBatchUpdates();
return new SQLServerBatchAction(query, dataNode, runningAsBatch);
}
@@ -64,12 +73,7 @@ public class SQLServerActionBuilder extends JdbcActionBuilder {
*/
@Override
public <T> SQLAction objectSelectAction(SelectQuery<T> query) {
- if (query.getOrderings() == null || query.getOrderings().size() == 0 ||
- version == null || version < 12) {
- return new SQLServerSelectAction(query, dataNode, true);
- }
-
- return new SQLServerSelectAction(query, dataNode, false);
+ return new SQLServerSelectAction(query, dataNode, needInMemoryOffset(query));
}
/**
@@ -77,19 +81,16 @@ public class SQLServerActionBuilder extends JdbcActionBuilder {
*/
@Override
public <T> SQLAction objectSelectAction(FluentSelect<T> query) {
- if (query.getOrderings() == null || query.getOrderings().size() == 0 ||
- version == null || version < 12) {
- return new SQLServerSelectAction(query, dataNode, true);
- }
-
- return new SQLServerSelectAction(query, dataNode, false);
+ return new SQLServerSelectAction(query, dataNode, needInMemoryOffset(query));
}
- public Integer getVersion() {
- return version;
+ private boolean needInMemoryOffset(SelectQuery<?> query) {
+ return query.getOrderings() == null || query.getOrderings().size() == 0
+ || version == null || version < 12;
}
- public void setVersion(Integer version) {
- this.version = version;
+ private boolean needInMemoryOffset(FluentSelect<?> query) {
+ return query.getOrderings() == null || query.getOrderings().size() == 0
+ || version == null || version < 12;
}
}
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerAdapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerAdapter.java
index 9805e0d..6642e8e 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerAdapter.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerAdapter.java
@@ -76,8 +76,7 @@ public class SQLServerAdapter extends SybaseAdapter {
/**
* Stores the major version of the database.
- * Database versions 12 and higher support the use of LIMIT,
- * lower versions use TOP N
+ * Database versions 12 and higher supports the use of LIMIT,lower versions use TOP N.
*
* @since 4.2
*/
@@ -89,10 +88,12 @@ public class SQLServerAdapter extends SybaseAdapter {
@Deprecated
public static final String TRIM_FUNCTION = "RTRIM";
- private List<String> SYSTEM_SCHEMAS = Arrays.asList("db_accessadmin", "db_backupoperator",
+ private final List<String> SYSTEM_SCHEMAS = Arrays.asList(
+ "db_accessadmin", "db_backupoperator",
"db_datareader", "db_datawriter", "db_ddladmin", "db_denydatareader",
"db_denydatawriter","dbo", "sys", "db_owner", "db_securityadmin", "guest",
- "INFORMATION_SCHEMA");
+ "INFORMATION_SCHEMA"
+ );
public SQLServerAdapter(@Inject RuntimeProperties runtimeProperties,
@Inject(Constants.SERVER_DEFAULT_TYPES_LIST) List<ExtendedType> defaultExtendedTypes,
@@ -106,7 +107,7 @@ public class SQLServerAdapter extends SybaseAdapter {
}
/**
- * Not supported, see: <a href="http://microsoft/mssql-jdbc#245">mssql-jdbc #245</a>
+ * Not supported, see: <a href="https://github.com/microsoft/mssql-jdbc/issues/245">mssql-jdbc #245</a>
*/
@Override
public boolean supportsGeneratedKeysForBatchInserts() {
@@ -118,9 +119,10 @@ public class SQLServerAdapter extends SybaseAdapter {
*/
@Override
public SQLTreeProcessor getSqlTreeProcessor() {
- SQLServerTreeProcessor sqlServerTreeProcessor = new SQLServerTreeProcessor();
- sqlServerTreeProcessor.setVersion(getVersion());
- return sqlServerTreeProcessor;
+ if(getVersion() != null && getVersion() >= 12) {
+ return new SQLServerTreeProcessorV12();
+ }
+ return new SQLServerTreeProcessor();
}
/**
@@ -130,9 +132,7 @@ public class SQLServerAdapter extends SybaseAdapter {
*/
@Override
public SQLAction getAction(Query query, DataNode node) {
- SQLServerActionBuilder sqlServerActionBuilder = new SQLServerActionBuilder(node);
- sqlServerActionBuilder.setVersion(this.version);
- return query.createSQLAction(sqlServerActionBuilder);
+ return query.createSQLAction(new SQLServerActionBuilder(node, getVersion()));
}
@Override
@@ -144,6 +144,10 @@ public class SQLServerAdapter extends SybaseAdapter {
return version;
}
+ /**
+ * @since 4.2
+ * @param version of the server as provided by the JDBC driver
+ */
public void setVersion(Integer version) {
this.version = version;
}
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerSelectAction.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerSelectAction.java
index 7c09eef..5c9d7d2 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerSelectAction.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerSelectAction.java
@@ -29,22 +29,17 @@ import org.apache.cayenne.query.Select;
public class SQLServerSelectAction extends SelectAction {
/**
- * When using TOP N instead of LIMIT. The offset will be manual.
- *
+ * When using TOP N instead of LIMIT the offset will be processed in-memory.
*/
- private Boolean isManualOffset;
+ private final boolean needsInMemoryOffset;
- public SQLServerSelectAction(Select<?> query, DataNode dataNode, Boolean isManualOffset) {
+ public SQLServerSelectAction(Select<?> query, DataNode dataNode, boolean needsInMemoryOffset) {
super(query, dataNode);
-
- this.isManualOffset = isManualOffset;
+ this.needsInMemoryOffset = needsInMemoryOffset;
}
@Override
protected int getInMemoryOffset(int queryOffset) {
- if (isManualOffset) {
- return super.getInMemoryOffset(queryOffset);
- }
- return 0;
+ return needsInMemoryOffset ? super.getInMemoryOffset(queryOffset) : 0;
}
}
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerTreeProcessor.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerTreeProcessor.java
index 347da1f..46be80d 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerTreeProcessor.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerTreeProcessor.java
@@ -21,7 +21,6 @@ package org.apache.cayenne.dba.sqlserver;
import org.apache.cayenne.access.sqlbuilder.sqltree.*;
import org.apache.cayenne.dba.sqlserver.sqltree.SQLServerColumnNode;
-import org.apache.cayenne.dba.sqlserver.sqltree.SQLServerLimitOffsetNode;
import org.apache.cayenne.dba.sybase.SybaseSQLTreeProcessor;
/**
@@ -29,32 +28,9 @@ import org.apache.cayenne.dba.sybase.SybaseSQLTreeProcessor;
*/
public class SQLServerTreeProcessor extends SybaseSQLTreeProcessor {
- private Integer version;
-
@Override
protected void onColumnNode(Node parent, ColumnNode child, int index) {
- replaceChild(parent, index, new SQLServerColumnNode(child));
- }
-
- @Override
- protected void onLimitOffsetNode(Node parent, LimitOffsetNode child, int index) {
- if (version != null && version >= 12) {
- for (int i = 0; i < parent.getChildrenCount(); i++) {
- if (parent.getChild(i) instanceof OrderByNode) {
- replaceChild(parent, index, new SQLServerLimitOffsetNode(child.getLimit(), child.getOffset()), false);
- return;
- }
- }
- }
-
- super.onLimitOffsetNode(parent, child, index);
- }
-
- public Integer getVersion() {
- return version;
+ replaceChild(parent, index, new SQLServerColumnNode(child));
}
- public void setVersion(Integer version) {
- this.version = version;
- }
}
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerTreeProcessor.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerTreeProcessorV12.java
similarity index 57%
copy from cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerTreeProcessor.java
copy to cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerTreeProcessorV12.java
index 347da1f..7a7bb27 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerTreeProcessor.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerTreeProcessorV12.java
@@ -19,42 +19,38 @@
package org.apache.cayenne.dba.sqlserver;
-import org.apache.cayenne.access.sqlbuilder.sqltree.*;
-import org.apache.cayenne.dba.sqlserver.sqltree.SQLServerColumnNode;
+import org.apache.cayenne.access.sqlbuilder.sqltree.LimitOffsetNode;
+import org.apache.cayenne.access.sqlbuilder.sqltree.Node;
+import org.apache.cayenne.access.sqlbuilder.sqltree.NodeType;
import org.apache.cayenne.dba.sqlserver.sqltree.SQLServerLimitOffsetNode;
-import org.apache.cayenne.dba.sybase.SybaseSQLTreeProcessor;
/**
+ * SQL tree processor that supports OFFSET X ROWS FETCH NEXT Y ROWS ONLY clause
+ * for the SQLServer 2012 and later.
+ *
* @since 4.2
*/
-public class SQLServerTreeProcessor extends SybaseSQLTreeProcessor {
-
- private Integer version;
-
- @Override
- protected void onColumnNode(Node parent, ColumnNode child, int index) {
- replaceChild(parent, index, new SQLServerColumnNode(child));
- }
+public class SQLServerTreeProcessorV12 extends SQLServerTreeProcessor {
@Override
protected void onLimitOffsetNode(Node parent, LimitOffsetNode child, int index) {
- if (version != null && version >= 12) {
- for (int i = 0; i < parent.getChildrenCount(); i++) {
- if (parent.getChild(i) instanceof OrderByNode) {
- replaceChild(parent, index, new SQLServerLimitOffsetNode(child.getLimit(), child.getOffset()), false);
- return;
- }
- }
+ if (hasOrderingClause(parent)) {
+ replaceChild(parent, index, new SQLServerLimitOffsetNode(child.getLimit(), child.getOffset()), false);
+ return;
}
-
super.onLimitOffsetNode(parent, child, index);
}
- public Integer getVersion() {
- return version;
+ protected boolean hasOrderingClause(Node parent) {
+ if(parent == null) {
+ return false;
+ }
+ for (int i = 0; i < parent.getChildrenCount(); i++) {
+ if (parent.getChild(i).getType() == NodeType.ORDER_BY) {
+ return true;
+ }
+ }
+ return hasOrderingClause(parent.getParent());
}
- public void setVersion(Integer version) {
- this.version = version;
- }
}
[cayenne] 03/05: the TOP query is used for null db version
Posted by nt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
ntimofeev pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cayenne.git
commit ed86e5d770867bf1c25c6462be1db7cdea510026
Author: andreykravchenko <an...@objectstyle.com>
AuthorDate: Wed Feb 10 17:26:39 2021 +0300
the TOP query is used for null db version
---
.../dba/sqlserver/SQLServerActionBuilder.java | 21 +++++++++++++++++++--
.../cayenne/dba/sqlserver/SQLServerAdapter.java | 6 ++++--
.../dba/sqlserver/SQLServerTreeProcessor.java | 2 +-
3 files changed, 24 insertions(+), 5 deletions(-)
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerActionBuilder.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerActionBuilder.java
index f19a671..bd43ee9 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerActionBuilder.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerActionBuilder.java
@@ -29,6 +29,13 @@ import org.apache.cayenne.query.*;
public class SQLServerActionBuilder extends JdbcActionBuilder {
/**
+ * Stores the major version of the database.
+ *
+ * @since 4.2
+ */
+ private Integer version;
+
+ /**
* @since 4.0
*/
public SQLServerActionBuilder(DataNode dataNode) {
@@ -57,7 +64,8 @@ public class SQLServerActionBuilder extends JdbcActionBuilder {
*/
@Override
public <T> SQLAction objectSelectAction(SelectQuery<T> query) {
- if (query.getOrderings() == null || query.getOrderings().size() == 0) {
+ if (query.getOrderings() == null || query.getOrderings().size() == 0 ||
+ version == null || version < 12) {
return new SQLServerSelectAction(query, dataNode, true);
}
@@ -69,10 +77,19 @@ public class SQLServerActionBuilder extends JdbcActionBuilder {
*/
@Override
public <T> SQLAction objectSelectAction(FluentSelect<T> query) {
- if (query.getOrderings() == null || query.getOrderings().size() == 0) {
+ if (query.getOrderings() == null || query.getOrderings().size() == 0 ||
+ version == null || version < 12) {
return new SQLServerSelectAction(query, dataNode, true);
}
return new SQLServerSelectAction(query, dataNode, false);
}
+
+ public Integer getVersion() {
+ return version;
+ }
+
+ public void setVersion(Integer version) {
+ this.version = version;
+ }
}
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerAdapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerAdapter.java
index 67871df..9805e0d 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerAdapter.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerAdapter.java
@@ -81,7 +81,7 @@ public class SQLServerAdapter extends SybaseAdapter {
*
* @since 4.2
*/
- protected Integer version;
+ private Integer version;
/**
* @deprecated since 4.2 unused
@@ -130,7 +130,9 @@ public class SQLServerAdapter extends SybaseAdapter {
*/
@Override
public SQLAction getAction(Query query, DataNode node) {
- return query.createSQLAction(new SQLServerActionBuilder(node));
+ SQLServerActionBuilder sqlServerActionBuilder = new SQLServerActionBuilder(node);
+ sqlServerActionBuilder.setVersion(this.version);
+ return query.createSQLAction(sqlServerActionBuilder);
}
@Override
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerTreeProcessor.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerTreeProcessor.java
index c1c8c98..347da1f 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerTreeProcessor.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerTreeProcessor.java
@@ -38,7 +38,7 @@ public class SQLServerTreeProcessor extends SybaseSQLTreeProcessor {
@Override
protected void onLimitOffsetNode(Node parent, LimitOffsetNode child, int index) {
- if (version == null || version >= 12) {
+ if (version != null && version >= 12) {
for (int i = 0; i < parent.getChildrenCount(); i++) {
if (parent.getChild(i) instanceof OrderByNode) {
replaceChild(parent, index, new SQLServerLimitOffsetNode(child.getLimit(), child.getOffset()), false);