Skip to content

Conversation

@sjednac
Copy link
Contributor

@sjednac sjednac commented Sep 29, 2018

Provides several enhancements for MSSQLServer compatibility mode, as described in #1338 (discarding "table hints" & treating "identity" as an auto_increment alias).

The code base changed significantly, since my original "hack", therefore the proposed implementation is brand new, although, the original idea didn't change at all.

Add support for `create table test(id int primary key identity)` statements,
which are common in the SQLServer world.
Add a dedicated example for `MSSQLServer` compatibility mode, that
shows all DBMS-specific features in a central, user-friendly place.
}

private void discardWithTableHints() {
if (readIf("WITH")) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use readIf(WITH) instead, WITH is a keyword with own token type.

}
if (database.getMode().useIdentityAsAutoIncrement) {
if (readIf("NOT")) {
read("NULL");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. readIf(NOT), read(NULL)

  2. I guess column.setNullable(false); should be invoked here.

do {
readExpression();
} while (readIf(COMMA));
read(CLOSE_PAREN);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use } while (readIfMore(true));.

} else if (readIf(EQUAL)){
readExpression();
} else {
throw getSyntaxError();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just use

} else {
    read(EQUAL);
    readExpression();
}

private void discardWithTableHints() {
if (readIf("WITH")) {
read(OPEN_PAREN);
if (!readIf(CLOSE_PAREN)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

while (readIfMore(true)) {

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))");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Long line.

assertSupportedSyntax(stat, "select * from parent p join child ch on ch.parent_id = p.id");
assertSupportedSyntax(stat, "select * from parent p with(nolock) join child ch with(nolock) on ch.parent_id = p.id");
assertSupportedSyntax(stat, "select * from parent p with(nolock) join child ch with(nolock, index = id) on ch.parent_id = p.id");
assertSupportedSyntax(stat, "select * from parent p with(nolock) join child ch with(nolock, index(id, name)) on ch.parent_id = p.id");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Long lines.

private void testDiscardTableHints() throws SQLException {
deleteDb("sqlserver");

Connection conn = getConnection("sqlserver;MODE=MSSQLServer");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Connection should be closed somewhere. The same problem in testUseIdentityAsAutoIncrementAlias().

Also it's better to delete database not only before execution of test case, but also after it. Actually you can do it in test() method and use shared connection in both test cases, there is no reason to use a separate connection in them now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI, I actually used TestCompatibilityOracle as a reference point (and still forgot to close the connections) - it deletes the db before each test only. Might be worth checking out.

assertSupportedSyntax(stat, "create table test2 (id int primary key not null identity)");
}

private void assertSupportedSyntax(Statement stat, String sql) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is not needed, just run the SQL directly. If it fails, exception will be visible in log. Your method only hides the stack trace, that's not a good idea.

@@ -0,0 +1,76 @@
package org.h2.test.db;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a copyright header.

Adjust style and remove the `SQLServerSample` as it seems redundant with the
unit test present.
@sjednac
Copy link
Contributor Author

sjednac commented Sep 30, 2018

Thanks for the comments @katzyn! I've applied some changes and replied to some questions above - please take another look.

@katzyn
Copy link
Contributor

katzyn commented Sep 30, 2018

@sjednac
Copy link
Contributor Author

sjednac commented Sep 30, 2018

I've posted a license statement to the mailing list, included a changelog entry, fixed the spellcheck target and extended documentation as described here. Thanks for all the tips @katzyn.

@katzyn katzyn merged commit cc90f21 into h2database:master Sep 30, 2018
@katzyn
Copy link
Contributor

katzyn commented Sep 30, 2018

Thank you for your contribution!

@jrsall92
Copy link

Can we get a release with this fix if there isn't any?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants