Skip to content

Commit

Permalink
TEIID-5112 adding parsing restrictions for length
Browse files Browse the repository at this point in the history
  • Loading branch information
shawkins committed Oct 22, 2017
1 parent 45068e2 commit eee3d81
Show file tree
Hide file tree
Showing 13 changed files with 57 additions and 38 deletions.
Expand Up @@ -1001,15 +1001,22 @@ public static Class<?> getArrayType(Class<?> classType) {
return Array.newInstance(classType, 0).getClass();
}

private static final HashSet<String> LENGTH_DATATYPES = new HashSet<String>(
Arrays.asList(
DataTypeManager.DefaultDataTypes.CHAR,
DataTypeManager.DefaultDataTypes.CLOB,
DataTypeManager.DefaultDataTypes.BLOB,
DataTypeManager.DefaultDataTypes.OBJECT,
DataTypeManager.DefaultDataTypes.XML,
DataTypeManager.DefaultDataTypes.STRING,
DataTypeManager.DefaultDataTypes.VARBINARY,
DataTypeManager.DefaultDataTypes.BIG_INTEGER));

/**
* Return true if the type may be defined with a length
*/
public static boolean hasLength(Class<?> classType) {
return (DataTypeManager.isLOB(classType)
|| classType == DefaultDataClasses.OBJECT
|| classType == DefaultDataClasses.STRING
|| classType == DefaultDataClasses.VARBINARY
|| classType == DefaultDataClasses.CHAR);
public static boolean hasLength(String typeName) {
return LENGTH_DATATYPES.contains(typeName);
}

}
Expand Up @@ -17,6 +17,8 @@
*/
package org.teiid.translator.infinispan.hotrod;

import static org.junit.Assert.*;

import java.io.FileReader;
import java.util.Properties;

Expand All @@ -29,7 +31,6 @@
import org.teiid.metadata.MetadataFactory;
import org.teiid.query.metadata.SystemMetadata;
import org.teiid.query.parser.QueryParser;
import static org.junit.Assert.*;

public class TestSchemaToProtobufProcessor {

Expand Down Expand Up @@ -170,7 +171,7 @@ public void testSimpleNoMetadataConversion() throws Exception {
" optional int32 e5 = 5;\n" +
" /* @Teiid(type=byte) */\n" +
" optional int32 e6 = 6;\n" +
" /* @Teiid(type=char, length=2) */\n" +
" /* @Teiid(type=char, length=1) */\n" +
" optional string e7 = 7;\n" +
" optional int64 e8 = 8;\n" +
" /* @Teiid(type=bigdecimal) */\n" +
Expand Down
Expand Up @@ -22,7 +22,7 @@ CREATE FOREIGN TABLE G4 (
e4 float,
e5 short,
e6 byte,
e7 char(2),
e7 char(1),
e8 long,
e9 bigdecimal,
e10 biginteger,
Expand Down
Expand Up @@ -52,16 +52,6 @@ public class DDLStringVisitor {
private static final String TAB = "\t"; //$NON-NLS-1$
private static final String NEWLINE = "\n";//$NON-NLS-1$
public static final String GENERATED = "TEIID_GENERATED"; //$NON-NLS-1$
private static final HashSet<String> LENGTH_DATATYPES = new HashSet<String>(
Arrays.asList(
DataTypeManager.DefaultDataTypes.CHAR,
DataTypeManager.DefaultDataTypes.CLOB,
DataTypeManager.DefaultDataTypes.BLOB,
DataTypeManager.DefaultDataTypes.OBJECT,
DataTypeManager.DefaultDataTypes.XML,
DataTypeManager.DefaultDataTypes.STRING,
DataTypeManager.DefaultDataTypes.VARBINARY,
DataTypeManager.DefaultDataTypes.BIG_INTEGER));

private static final HashSet<String> PRECISION_DATATYPES = new HashSet<String>(
Arrays.asList(DataTypeManager.DefaultDataTypes.BIG_DECIMAL));
Expand Down Expand Up @@ -253,7 +243,7 @@ private void visit(Datatype dt) {
String runtimeTypeName = dt.getBasetypeName();
append(runtimeTypeName);
Datatype base = SystemMetadata.getInstance().getRuntimeTypeMap().get(runtimeTypeName);
if (LENGTH_DATATYPES.contains(runtimeTypeName)) {
if (DataTypeManager.hasLength(runtimeTypeName)) {
if (dt.getLength() != base.getLength()) {
append(LPAREN).append(dt.getLength()).append(RPAREN);
}
Expand Down Expand Up @@ -698,7 +688,7 @@ private void appendColumn(BaseColumn column, boolean includeName, boolean includ
append(datatype.getName());
} else {
append(runtimeTypeName);
if (LENGTH_DATATYPES.contains(runtimeTypeName)) {
if (DataTypeManager.hasLength(runtimeTypeName)) {
if (column.getLength() != 0 && (datatype == null || column.getLength() != datatype.getLength())) {
append(LPAREN).append(column.getLength()).append(RPAREN);
}
Expand Down
8 changes: 8 additions & 0 deletions engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj
Expand Up @@ -4804,6 +4804,14 @@ ParsedDataType parseDataTypePrimary() :
return new ParsedDataType(typeName, length, scale, precision);
}
else if (length != null){
if (!precision) {
if (length == 0) {
throw new ParseException(QueryPlugin.Util.getString("SQLParser.zero_length", typeName)); //$NON-NLS-1$
}
if (length != 1 && typeName.equalsIgnoreCase("CHAR")) {
throw new ParseException(QueryPlugin.Util.getString("SQLParser.char_length")); //$NON-NLS-1$
}
}
return new ParsedDataType(typeName, length, precision);
}
return new ParsedDataType(typeName);
Expand Down
2 changes: 2 additions & 0 deletions engine/src/main/resources/org/teiid/query/i18n.properties
Expand Up @@ -225,6 +225,8 @@ SQLParser.Aggregate_only_top_level=Aggregate functions are only allowed HAVING/S
SQLParser.window_only_top_level=Window functions are not allowed in the HAVING clause: {0}
SQLParser.Unknown_agg_func=Unknown aggregate function: {0}
SQLParser.Invalid_func=Invalid function name: [{0}]
SQLParser.zero_length={0} type length may not be 0.
SQLParser.char_length=Char type length must be 1.
SQLParser.Integer_parse=Unable to parse integer literal: {0}
SQLParser.Float_parse=Unable to parse floating point literal: {0}
SQLParser.decimal_parse=Unable to parse decimal literal: {0}
Expand Down
8 changes: 8 additions & 0 deletions engine/src/test/java/org/teiid/query/parser/TestParser.java
Expand Up @@ -5294,5 +5294,13 @@ private void helpTestCompoundNonJoinCriteria(String sqlPred, PredicateCriteria p
query.setSelect(new Select(Arrays.asList(as)));
helpTest(sql, "SELECT y AS \"_name\"", query); //$NON-NLS-1$
}

@Test public void testCharLength() {
helpException("select cast('abc' as char(2))");
}

@Test public void testVarcharLength() {
helpException("select cast('abc' as varchar(0))");
}

}
Expand Up @@ -34,8 +34,8 @@
import org.teiid.core.TeiidComponentException;
import org.teiid.core.types.DataTypeManager;
import org.teiid.dqp.internal.process.DQPWorkContext;
import org.teiid.metadata.BaseColumn.NullType;
import org.teiid.metadata.*;
import org.teiid.metadata.BaseColumn.NullType;
import org.teiid.metadata.Column.SearchType;
import org.teiid.metadata.ProcedureParameter.Type;
import org.teiid.metadata.Table.TriggerEvent;
Expand Down Expand Up @@ -1705,7 +1705,9 @@ public static Column createElement(String name, ColumnSet<?> group, String type)
column.setPosition(group.getColumns().size()); //1 based indexing
column.setUpdatable(true);
column.setDatatype(SystemMetadata.getInstance().getRuntimeTypeMap().get(type), true, 0);
column.setLength(100);
if (DataTypeManager.hasLength(type) && !type.equalsIgnoreCase(DataTypeManager.DefaultDataTypes.CHAR)) {
column.setLength(100);
}
column.setNameInSource(name);
return column;
}
Expand Down
Expand Up @@ -250,9 +250,9 @@ private void setDataType(BaseColumn baseColumn) {
}
baseColumn.setDatatype(dataType, false, arrayDimensions);
if (baseColumn.getLength() == 0) {
Class<?> baseType = DataTypeManager.getDataTypeClass(type);
if (DataTypeManager.hasLength(baseType)) {
//designer sends a default length of 0 as a default, but the engine does not expect that generally
if (DataTypeManager.hasLength(type)) {
Class<?> baseType = DataTypeManager.getDataTypeClass(type);
//designer sends a default length of 0 as a default, but the engine does not expect that generally
Integer length = JDBCSQLTypeInfo.getMaxDisplaySize(baseType);
if (length != null) {
baseColumn.setLength(length);
Expand Down
8 changes: 4 additions & 4 deletions runtime/src/test/resources/portfolio-converted-vdb.ddl
Expand Up @@ -47,7 +47,7 @@ SET SCHEMA Accounts;

CREATE FOREIGN TABLE CUSTOMER
(
SSN char(10),
SSN varchar(10),
FIRSTNAME varchar(64),
LASTNAME varchar(64),
ST_ADDRESS varchar(256),
Expand All @@ -61,9 +61,9 @@ SET SCHEMA Accounts;
CREATE FOREIGN TABLE ACCOUNT
(
ACCOUNT_ID integer,
SSN char(10),
STATUS char(10),
"TYPE" char(10),
SSN varchar(10),
STATUS varchar(10),
"TYPE" char(1),
DATEOPENED timestamp,
DATECLOSED timestamp,
CONSTRAINT ACCOUNT_PK PRIMARY KEY(ACCOUNT_ID)
Expand Down
8 changes: 4 additions & 4 deletions runtime/src/test/resources/portfolio-vdb.ddl
Expand Up @@ -47,7 +47,7 @@ SET SCHEMA Accounts;

CREATE FOREIGN TABLE CUSTOMER
(
SSN char(10),
SSN varchar(10),
FIRSTNAME varchar(64),
LASTNAME varchar(64),
ST_ADDRESS varchar(256),
Expand All @@ -61,9 +61,9 @@ SET SCHEMA Accounts;
CREATE FOREIGN TABLE ACCOUNT
(
ACCOUNT_ID integer,
SSN char(10),
STATUS char(10),
"TYPE" char(10),
SSN varchar(10),
STATUS varchar(10),
"TYPE" char(1),
DATEOPENED timestamp,
DATECLOSED timestamp,
CONSTRAINT ACCOUNT_PK PRIMARY KEY(ACCOUNT_ID)
Expand Down
8 changes: 4 additions & 4 deletions runtime/src/test/resources/portfolio-vdb.xml
Expand Up @@ -15,7 +15,7 @@
<metadata type="DDL"><![CDATA[
CREATE FOREIGN TABLE CUSTOMER
(
SSN char(10),
SSN varchar(10),
FIRSTNAME varchar(64),
LASTNAME varchar(64),
ST_ADDRESS varchar(256),
Expand All @@ -29,9 +29,9 @@
CREATE FOREIGN TABLE ACCOUNT
(
ACCOUNT_ID integer,
SSN char(10),
STATUS char(10),
"TYPE" char(10),
SSN varchar(10),
STATUS varchar(10),
"TYPE" char(1),
DATEOPENED timestamp,
DATECLOSED timestamp,
CONSTRAINT ACCOUNT_PK PRIMARY KEY(ACCOUNT_ID)
Expand Down
Expand Up @@ -52,6 +52,7 @@ <h4>from 9.3</h4>
<li><a href="https://issues.jboss.org/browse/TEIID-5026">TEIID-5026</a> The FROM_UNIXTIME function now returns a string rather than a timestamp value and no longer is rewritten to the timestampadd function. The functionality now matches that of HIVE/IMPALA. See also the to_millis and from_millis functions.</li>
<li><a href="https://issues.jboss.org/browse/TEIID-5012">TEIID-5012</a> A Description column was added to SYS.VirtualDatabases. </li>
<li><a href="https://issues.jboss.org/browse/TEIID-4943">TEIID-4943</a> Copy criteria created from a join will typically only be pushed when the join is not pushed.</li>
<li><a href="https://issues.jboss.org/browse/TEIID-5112">TEIID-5112</a> Type length specified in DDL or SQL must be greater than 0. Char type length must only be 1.</li>
</ul>

<h4>from 9.2</h4>
Expand Down

0 comments on commit eee3d81

Please sign in to comment.