Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolve some MySQL compatibility issues #1944

Merged
merged 3 commits into from
May 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions h2/src/docsrc/html/changelog.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ <h1>Change Log</h1>

<h2>Next Version (unreleased)</h2>
<ul>
<li>Issue #1942: MySQL Mode: convertInsertNullToZero should be turned off by default?
</li>
<li>Issue #1940: MySQL Mode: Modify column from NOT NULL to NULL syntax
</li>
<li>PR #1941: Extract OFFSET / FETCH handling from Select and SelectUnion to Query
</li>
<li>Issue #1938: Regression with CREATE OR REPLACE VIEW. Causes "Duplicate column name" exception.
</li>
<li>PR #1937: Get rid of FunctionCursorResultSet
Expand Down
6 changes: 1 addition & 5 deletions h2/src/docsrc/html/features.html
Original file line number Diff line number Diff line change
Expand Up @@ -903,11 +903,7 @@ <h3>MySQL Compatibility Mode</h3>
When case-insensitive identifiers are needed append <code>;CASE_INSENSITIVE_IDENTIFIERS=TRUE</code> to URL.
Do not change value of DATABASE_TO_LOWER after creation of database.
</p>
<ul><li>When inserting data, if a column is defined to be <code>NOT NULL</code>
and <code>NULL</code> is inserted,
then a 0 (or empty string, or the current timestamp for timestamp columns) value is used.
Usually, this operation is not allowed and an exception is thrown.
</li><li>Creating indexes in the <code>CREATE TABLE</code> statement is allowed using
<ul><li>Creating indexes in the <code>CREATE TABLE</code> statement is allowed using
<code>INDEX(..)</code> or <code>KEY(..)</code>.
Example: <code>create table test(id int primary key, name varchar(255), key idx_name(name));</code>
</li><li>When converting a floating point number to an integer, the fractional
Expand Down
9 changes: 5 additions & 4 deletions h2/src/main/org/h2/command/Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -7593,7 +7593,8 @@ private Prepared parseAlterTable() {
}
break;
case NO_NULL_CONSTRAINT_FOUND:
command = parseAlterTableAlterColumnType(schema, tableName, columnName, ifTableExists);
command = parseAlterTableAlterColumnType(schema, tableName, columnName, ifTableExists,
database.getMode().getEnum() != ModeEnum.MySQL);
break;
default:
throw DbException.get(ErrorCode.UNKNOWN_MODE_1,
Expand Down Expand Up @@ -7704,7 +7705,7 @@ private Prepared parseAlterTable() {
command.setSelectivity(readExpression());
return command;
} else {
return parseAlterTableAlterColumnType(schema, tableName, columnName, ifTableExists);
return parseAlterTableAlterColumnType(schema, tableName, columnName, ifTableExists, true);
}
} else if (database.getMode().getEnum() == ModeEnum.MySQL && readIf("AUTO_INCREMENT")) {
readIf(EQUAL);
Expand Down Expand Up @@ -7758,10 +7759,10 @@ private Prepared commandIfTableExists(Schema schema, String tableName,
}

private AlterTableAlterColumn parseAlterTableAlterColumnType(Schema schema,
String tableName, String columnName, boolean ifTableExists) {
String tableName, String columnName, boolean ifTableExists, boolean preserveNotNull) {
Column oldColumn = columnIfTableExists(schema, tableName, columnName, ifTableExists);
Column newColumn = parseColumnForTable(columnName,
oldColumn == null ? true : oldColumn.isNullable(), true);
!preserveNotNull || oldColumn == null || oldColumn.isNullable(), true);
if (readIf(CHECK)) {
Expression expr = readExpression();
newColumn.addCheckConstraint(session, expr);
Expand Down
9 changes: 0 additions & 9 deletions h2/src/main/org/h2/engine/Mode.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,6 @@ public enum UniqueIndexNullsHandling {
*/
public boolean aliasColumnName;

/**
* When inserting data, if a column is defined to be NOT NULL and NULL is
* inserted, then a 0 (or empty string, or the current timestamp for
* timestamp columns) value is used. Usually, this operation is not allowed
* and an exception is thrown.
*/
public boolean convertInsertNullToZero;

/**
* When converting the scale of decimal data, the number is only converted
* if the new scale is smaller than the current scale. Usually, the scale is
Expand Down Expand Up @@ -299,7 +291,6 @@ public enum UniqueIndexNullsHandling {
add(mode);

mode = new Mode(ModeEnum.MySQL);
mode.convertInsertNullToZero = true;
mode.indexDefinitionInCreateTable = true;
mode.lowerCaseIdentifiers = true;
// Next one is for MariaDB
Expand Down
23 changes: 1 addition & 22 deletions h2/src/main/org/h2/table/Column.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,8 @@
import org.h2.value.DataType;
import org.h2.value.TypeInfo;
import org.h2.value.Value;
import org.h2.value.ValueInt;
import org.h2.value.ValueLong;
import org.h2.value.ValueNull;
import org.h2.value.ValueString;
import org.h2.value.ValueTime;
import org.h2.value.ValueUuid;

/**
Expand Down Expand Up @@ -398,25 +395,7 @@ public Value validateConvertUpdateSequence(Session session, Value value) {
}
}
if (value == ValueNull.INSTANCE && !nullable) {
if (mode.convertInsertNullToZero) {
int t = type.getValueType();
DataType dt = DataType.getDataType(t);
if (dt.decimal) {
value = ValueInt.get(0).convertTo(t);
} else if (dt.type == Value.TIMESTAMP) {
value = session.getCurrentCommandStart().convertTo(Value.TIMESTAMP);
} else if (dt.type == Value.TIMESTAMP_TZ) {
value = session.getCurrentCommandStart();
} else if (dt.type == Value.TIME) {
value = ValueTime.fromNanos(0);
} else if (dt.type == Value.DATE) {
value = session.getCurrentCommandStart().convertTo(Value.DATE);
} else {
value = ValueString.get("").convertTo(t);
}
} else {
throw DbException.get(ErrorCode.NULL_NOT_ALLOWED, name);
}
throw DbException.get(ErrorCode.NULL_NOT_ALLOWED, name);
}
}
if (checkConstraint != null) {
Expand Down
47 changes: 47 additions & 0 deletions h2/src/test/org/h2/test/scripts/ddl/alterTableAlterColumn.sql
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,50 @@ SET MODE Regular;

DROP TABLE TEST;
> ok

-- Compatibility syntax

CREATE MEMORY TABLE TEST(V INT NOT NULL);
> ok

ALTER TABLE TEST MODIFY COLUMN V BIGINT;
> ok

SCRIPT NODATA NOPASSWORDS NOSETTINGS TABLE TEST;
> SCRIPT
> -----------------------------------------------------------
> -- 0 +/- SELECT COUNT(*) FROM PUBLIC.TEST;
> CREATE MEMORY TABLE "PUBLIC"."TEST"( "V" BIGINT NOT NULL );
> CREATE USER IF NOT EXISTS "SA" PASSWORD '' ADMIN;
> rows: 3

SET MODE MySQL;
> ok

ALTER TABLE TEST MODIFY COLUMN V INT;
> ok

SCRIPT NODATA NOPASSWORDS NOSETTINGS TABLE TEST;
> SCRIPT
> -------------------------------------------------
> -- 0 +/- SELECT COUNT(*) FROM PUBLIC.TEST;
> CREATE MEMORY TABLE "PUBLIC"."TEST"( "V" INT );
> CREATE USER IF NOT EXISTS "SA" PASSWORD '' ADMIN;
> rows: 3

ALTER TABLE TEST MODIFY COLUMN V BIGINT NOT NULL;
> ok

SCRIPT NODATA NOPASSWORDS NOSETTINGS TABLE TEST;
> SCRIPT
> -----------------------------------------------------------
> -- 0 +/- SELECT COUNT(*) FROM PUBLIC.TEST;
> CREATE MEMORY TABLE "PUBLIC"."TEST"( "V" BIGINT NOT NULL );
> CREATE USER IF NOT EXISTS "SA" PASSWORD '' ADMIN;
> rows: 3

SET MODE Regular;
> ok

DROP TABLE TEST;
> ok