Unverified 提交 cc90f217 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov 提交者: GitHub

Merge pull request #1481 from sbilinski/sqlserver-compatibility-enchancements

MSSQLServer compatibility enhancements
......@@ -21,6 +21,8 @@ Change Log
<h2>Next Version (unreleased)</h2>
<ul>
<li>Issue #1338: MSSQLServer compatibility enhancements
</li>
<li>Issue #1475: Dropping column used by a view produces misleading error message
</li>
<li>Issue #1473: TestScript needs better detection of sorted result
......
......@@ -1097,6 +1097,8 @@ or the SQL statement <code>SET MODE MSSQLServer</code>.
</li><li>Text can be concatenated using '+'.
</li><li>MONEY data type is treated like NUMERIC(19, 4) data type. SMALLMONEY data type is treated like NUMERIC(10, 4)
data type.
</li><li><code>IDENTITY</code> can be used for automatic id generation on column level.
</li><li>Table hints are discarded. Example: <code>SELECT * FROM table WITH (NOLOCK)</code>.
</li></ul>
<h3>MySQL Compatibility Mode</h3>
......
......@@ -1802,6 +1802,11 @@ public class Parser {
}
}
}
if (database.getMode().discardWithTableHints) {
discardWithTableHints();
}
// inherit alias for CTE as views from table name
if (table.isView() && table.isTableExpression() && alias == null) {
alias = table.getName();
......@@ -1855,6 +1860,30 @@ public class Parser {
return null;
}
private void discardWithTableHints() {
if (readIf(WITH)) {
read(OPEN_PAREN);
do {
discardTableHint();
} while (readIfMore(true));
}
}
private void discardTableHint() {
if (readIf("INDEX")) {
if (readIf(OPEN_PAREN)) {
do {
readExpression();
} while (readIfMore(true));
} else {
read(EQUAL);
readExpression();
}
} else {
readExpression();
}
}
private Prepared parseTruncate() {
read("TABLE");
Table table = readTableOrView();
......@@ -7458,6 +7487,15 @@ public class Parser {
if (readIf("AUTO_INCREMENT")) {
parseAutoIncrement(column);
}
if (database.getMode().useIdentityAsAutoIncrement) {
if (readIf(NOT)) {
read(NULL);
column.setNullable(false);
}
if (readIf("IDENTITY")) {
parseAutoIncrement(column);
}
}
if (affinity) {
CreateIndex idx = createAffinityIndex(schema, tableName, cols);
command.addConstraintCommand(idx);
......
......@@ -187,6 +187,16 @@ public class Mode {
*/
public boolean allowDB2TimestampFormat;
/**
* Discard SQLServer table hints (e.g. "SELECT * FROM table WITH (NOLOCK)")
*/
public boolean discardWithTableHints;
/**
* Use "IDENTITY" as an alias for "auto_increment" (SQLServer style)
*/
public boolean useIdentityAsAutoIncrement;
/**
* Convert (VAR)CHAR to VAR(BINARY) and vice versa with UTF-8 encoding instead of HEX.
*/
......@@ -256,6 +266,8 @@ public class Mode {
mode.allowPlusForStringConcat = true;
mode.swapConvertFunctionParameters = true;
mode.supportPoundSymbolForColumnNames = true;
mode.discardWithTableHints = true;
mode.useIdentityAsAutoIncrement = true;
// MS SQL Server does not support client info properties. See
// https://msdn.microsoft.com/en-Us/library/dd571296%28v=sql.110%29.aspx
mode.supportedClientInfoPropertiesRegEx = null;
......
......@@ -30,6 +30,7 @@ import org.h2.test.db.TestCheckpoint;
import org.h2.test.db.TestCluster;
import org.h2.test.db.TestCompatibility;
import org.h2.test.db.TestCompatibilityOracle;
import org.h2.test.db.TestCompatibilitySQLServer;
import org.h2.test.db.TestCsv;
import org.h2.test.db.TestDateStorage;
import org.h2.test.db.TestDeadlock;
......@@ -745,6 +746,7 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
addTest(new TestCheckpoint());
addTest(new TestCompatibility());
addTest(new TestCompatibilityOracle());
addTest(new TestCompatibilitySQLServer());
addTest(new TestCsv());
addTest(new TestDeadlock());
if (vmlens) {
......
/*
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.test.db;
import org.h2.test.TestBase;
import org.h2.test.TestDb;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
/**
* Test MSSQLServer compatibility mode.
*/
public class TestCompatibilitySQLServer extends TestDb {
/**
* Run just this test.
*
* @param s ignored
*/
public static void main(String... s) throws Exception {
TestBase test = TestBase.createCaller().init();
test.test();
}
@Override
public void test() throws Exception {
deleteDb("sqlserver");
final Connection conn = getConnection("sqlserver;MODE=MSSQLServer");
try {
testDiscardTableHints(conn);
testUseIdentityAsAutoIncrementAlias(conn);
} finally {
conn.close();
deleteDb("sqlserver");
}
}
private void testDiscardTableHints(Connection conn) throws SQLException {
final Statement stat = conn.createStatement();
stat.execute("create table parent(id int primary key, name varchar(255))");
stat.execute("create table child(" +
"id int primary key, " +
"parent_id int, " +
"name varchar(255), " +
"foreign key (parent_id) references public.parent(id))");
stat.execute("select * from parent");
stat.execute("select * from parent with(nolock)");
stat.execute("select * from parent with(nolock, index = id)");
stat.execute("select * from parent with(nolock, index(id, name))");
stat.execute("select * from parent p " +
"join child ch on ch.parent_id = p.id");
stat.execute("select * from parent p with(nolock) " +
"join child ch with(nolock) on ch.parent_id = p.id");
stat.execute("select * from parent p with(nolock) " +
"join child ch with(nolock, index = id) on ch.parent_id = p.id");
stat.execute("select * from parent p with(nolock) " +
"join child ch with(nolock, index(id, name)) on ch.parent_id = p.id");
}
private void testUseIdentityAsAutoIncrementAlias(Connection conn) throws SQLException {
final Statement stat = conn.createStatement();
stat.execute("create table test(id int primary key identity, expected_id int)");
stat.execute("insert into test (expected_id) VALUES (1), (2), (3)");
final ResultSet results = stat.executeQuery("select * from test");
while (results.next()) {
assertEquals(results.getInt("expected_id"), results.getInt("id"));
}
stat.execute("create table test2 (id int primary key not null identity)");
}
}
......@@ -798,3 +798,5 @@ pointzm pointz pointm dimensionality redefine forum measures
mpg casted pzm mls constrained subtypes complains
ranks rno dro rko precede cume reopens preceding unbounded rightly itr lag maximal tiles tile ntile signify
partitioned
discard enhancements nolock
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论