/*
* ModeShape (http://www.modeshape.org)
*
* Licensed 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
*
* http://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.modeshape.sequencer.ddl.dialect.teiid;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsInstanceOf.instanceOf;
import static org.hamcrest.core.IsNull.nullValue;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import static org.hamcrest.CoreMatchers.hasItem;
import static org.hamcrest.CoreMatchers.hasItems;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.modeshape.common.text.ParsingException;
import org.modeshape.jcr.api.JcrConstants;
import org.modeshape.sequencer.ddl.DdlConstants;
import org.modeshape.sequencer.ddl.StandardDdlLexicon;
import org.modeshape.sequencer.ddl.dialect.teiid.TeiidDdlConstants.SchemaElementType;
import org.modeshape.sequencer.ddl.dialect.teiid.TeiidDdlConstants.TeiidDataType;
import org.modeshape.sequencer.ddl.dialect.teiid.TeiidDdlConstants.TeiidNonReservedWord;
import org.modeshape.sequencer.ddl.dialect.teiid.TeiidDdlConstants.TeiidReservedWord;
import org.modeshape.sequencer.ddl.node.AstNode;
/**
* A test class for {@link CreateTableParser}.
*/
public class CreateTableParserTest extends TeiidDdlTest {
private CreateTableParser parser;
private AstNode rootNode;
@Before
public void beforeEach() {
final TeiidDdlParser teiidDdlParser = new TeiidDdlParser();
this.parser = new CreateTableParser(teiidDdlParser);
this.rootNode = teiidDdlParser.nodeFactory().node("ddlRootNode");
}
/**
* See Teiid TestDDLParser#testForeignTable()
*/
@Test
public void shouldParseForeignTable() {
final String content = "CREATE FOREIGN TABLE G1(e1 integer primary key, e2 varchar(10) unique,"
+ "e3 date not null unique, e4 decimal(12,3) options (searchable 'unsearchable'),"
+ "e5 integer auto_increment INDEX OPTIONS (UUID 'uuid', NAMEINSOURCE 'nis', SELECTABLE 'NO'),"
+ "e6 varchar index default 'hello')"
+ "OPTIONS (CARDINALITY 12, UUID 'uuid2', UPDATABLE 'true', FOO 'BAR', ANNOTATION 'Test Table')";
final AstNode tableNode = this.parser.parse(getTokens(content), this.rootNode);
assertThat(tableNode.getName(), is("G1"));
assertMixinType(tableNode, TeiidDdlLexicon.CreateTable.TABLE_STATEMENT);
assertProperty(tableNode, TeiidDdlLexicon.SchemaElement.TYPE, SchemaElementType.FOREIGN.toDdl());
// columns
assertThat(tableNode.getChildren(TeiidDdlLexicon.CreateTable.TABLE_ELEMENT).size(), is(6));
{ // column e1
assertThat(tableNode.childrenWithName("e1").size(), is(1));
final AstNode e1 = tableNode.childrenWithName("e1").get(0);
assertProperty(e1, StandardDdlLexicon.DATATYPE_NAME, TeiidDataType.INTEGER.toDdl());
assertProperty(e1, TeiidDdlLexicon.CreateTable.AUTO_INCREMENT, false);
assertProperty(e1, StandardDdlLexicon.NULLABLE, DdlConstants.NULL);
}
{ // column e2
assertThat(tableNode.childrenWithName("e2").size(), is(1));
final AstNode e2 = tableNode.childrenWithName("e2").get(0);
assertProperty(e2, StandardDdlLexicon.DATATYPE_NAME, TeiidDataType.VARCHAR.toDdl());
assertProperty(e2, StandardDdlLexicon.DATATYPE_LENGTH, 10L);
assertProperty(e2, TeiidDdlLexicon.CreateTable.AUTO_INCREMENT, false);
assertProperty(e2, StandardDdlLexicon.NULLABLE, "NULL");
}
{ // column e3
assertThat(tableNode.childrenWithName("e3").size(), is(1));
final AstNode e3 = tableNode.childrenWithName("e3").get(0);
assertProperty(e3, StandardDdlLexicon.DATATYPE_NAME, TeiidDataType.DATE.toDdl());
assertProperty(e3, TeiidDdlLexicon.CreateTable.AUTO_INCREMENT, false);
assertProperty(e3, StandardDdlLexicon.NULLABLE, "NOT NULL");
}
{ // column e4
assertThat(tableNode.childrenWithName("e4").size(), is(1));
final AstNode e4 = tableNode.childrenWithName("e4").get(0);
assertProperty(e4, StandardDdlLexicon.DATATYPE_NAME, TeiidDataType.DECIMAL.toDdl());
assertProperty(e4, StandardDdlLexicon.DATATYPE_PRECISION, 12);
assertProperty(e4, StandardDdlLexicon.DATATYPE_SCALE, 3);
assertProperty(e4, TeiidDdlLexicon.CreateTable.AUTO_INCREMENT, false);
assertProperty(e4, StandardDdlLexicon.NULLABLE, "NULL");
// options
assertThat(e4.getChildren(StandardDdlLexicon.TYPE_STATEMENT_OPTION).size(), is(1));
assertThat(e4.getChildren(StandardDdlLexicon.TYPE_STATEMENT_OPTION).get(0).getName(), is("searchable"));
assertProperty(e4.getChildren(StandardDdlLexicon.TYPE_STATEMENT_OPTION).get(0),
StandardDdlLexicon.VALUE,
"unsearchable");
}
{ // column e5
assertThat(tableNode.childrenWithName("e5").size(), is(1));
final AstNode e5 = tableNode.childrenWithName("e5").get(0);
assertProperty(e5, StandardDdlLexicon.DATATYPE_NAME, TeiidDataType.INTEGER.toDdl());
assertProperty(e5, TeiidDdlLexicon.CreateTable.AUTO_INCREMENT, true);
assertProperty(e5, StandardDdlLexicon.NULLABLE, "NULL");
// options
assertThat(e5.getChildren(StandardDdlLexicon.TYPE_STATEMENT_OPTION).size(), is(3));
assertThat(e5.childrenWithName("UUID").size(), is(1));
assertProperty(e5.childrenWithName("UUID").get(0), StandardDdlLexicon.VALUE, "uuid");
assertThat(e5.childrenWithName("NAMEINSOURCE").size(), is(1));
assertProperty(e5.childrenWithName("NAMEINSOURCE").get(0), StandardDdlLexicon.VALUE, "nis");
assertThat(e5.childrenWithName("SELECTABLE").size(), is(1));
assertProperty(e5.childrenWithName("SELECTABLE").get(0), StandardDdlLexicon.VALUE, "NO");
}
{ // column e6
assertThat(tableNode.childrenWithName("e6").size(), is(1));
final AstNode e6 = tableNode.childrenWithName("e6").get(0);
assertProperty(e6, StandardDdlLexicon.DATATYPE_NAME, TeiidDataType.VARCHAR.toDdl());
assertProperty(e6, TeiidDdlLexicon.CreateTable.AUTO_INCREMENT, false);
assertProperty(e6, StandardDdlLexicon.NULLABLE, "NULL");
assertProperty(e6, StandardDdlLexicon.DEFAULT_VALUE, "hello");
}
// constraints
assertThat(tableNode.getChildren(TeiidDdlLexicon.Constraint.TABLE_ELEMENT).size(), is(3));
{ // e1 primary key
assertThat(tableNode.childrenWithName(DdlConstants.PRIMARY_KEY).size(), is(1));
final Object temp = tableNode.childrenWithName(DdlConstants.PRIMARY_KEY).get(0).getProperty(TeiidDdlLexicon.Constraint.REFERENCES);
assertThat(temp, is(instanceOf(List.class)));
@SuppressWarnings( "unchecked" )
final List<AstNode> references = (List<AstNode>)temp;
assertThat(references.size(), is(1));
assertThat(references.get(0), is(tableNode.childrenWithName("e1").get(0)));
}
{ // e2, e3 unique constraints
final List<AstNode> uniques = tableNode.childrenWithName(DdlConstants.UNIQUE);
assertThat(uniques.size(), is(2));
final Object temp1 = uniques.get(0).getProperty(TeiidDdlLexicon.Constraint.REFERENCES);
assertThat(temp1, is(instanceOf(List.class)));
@SuppressWarnings( "unchecked" )
final List<AstNode> references1 = (List<AstNode>)temp1;
assertThat(references1.size(), is(1));
final Object temp2 = uniques.get(1).getProperty(TeiidDdlLexicon.Constraint.REFERENCES);
assertThat(temp2, is(instanceOf(List.class)));
@SuppressWarnings( "unchecked" )
final List<AstNode> references2 = (List<AstNode>)temp2;
assertThat(references2.size(), is(1));
if (references1.get(0).equals(tableNode.childrenWithName("e2").get(0))) {
assertThat(references2, hasItem(tableNode.childrenWithName("e3").get(0)));
} else if (references1.get(0).equals(tableNode.childrenWithName("e3").get(0))) {
assertThat(references2, hasItem(tableNode.childrenWithName("e2").get(0)));
} else {
fail("unique constraints for column 'e1' and 'e2' not found");
}
}
assertThat(tableNode.getChildren(TeiidDdlLexicon.Constraint.INDEX_CONSTRAINT).size(), is(2));
// options
assertThat(tableNode.getChildren(StandardDdlLexicon.TYPE_STATEMENT_OPTION).size(), is(5));
assertThat(tableNode.childrenWithName("CARDINALITY").size(), is(1));
assertProperty(tableNode.childrenWithName("CARDINALITY").get(0), StandardDdlLexicon.VALUE, "12");
assertThat(tableNode.childrenWithName("UUID").size(), is(1));
assertProperty(tableNode.childrenWithName("UUID").get(0), StandardDdlLexicon.VALUE, "uuid2");
assertThat(tableNode.childrenWithName("UPDATABLE").size(), is(1));
assertProperty(tableNode.childrenWithName("UPDATABLE").get(0), StandardDdlLexicon.VALUE, "true");
assertThat(tableNode.childrenWithName("FOO").size(), is(1));
assertProperty(tableNode.childrenWithName("FOO").get(0), StandardDdlLexicon.VALUE, "BAR");
assertThat(tableNode.childrenWithName("ANNOTATION").size(), is(1));
assertProperty(tableNode.childrenWithName("ANNOTATION").get(0), StandardDdlLexicon.VALUE, "Test Table");
}
/**
* See Teiid TestDDLParser#testDuplicatePrimarykey()
*/
@Test
public void shouldParseDuplicatePrimaryKey() {
final String content = "CREATE FOREIGN TABLE G1( e1 integer primary key, e2 varchar primary key)";
final AstNode tableNode = this.parser.parse(getTokens(content), this.rootNode);
assertThat(tableNode.getName(), is("G1"));
assertMixinType(tableNode, TeiidDdlLexicon.CreateTable.TABLE_STATEMENT);
assertProperty(tableNode, TeiidDdlLexicon.SchemaElement.TYPE, SchemaElementType.FOREIGN.toDdl());
// columns
assertThat(tableNode.getChildren(TeiidDdlLexicon.Constraint.TABLE_ELEMENT).size(), is(2));
assertThat(tableNode.childrenWithName("e1").size(), is(1));
assertProperty(tableNode.childrenWithName("e1").get(0), StandardDdlLexicon.DATATYPE_NAME, TeiidDataType.INTEGER.toDdl());
assertThat(tableNode.childrenWithName("e2").size(), is(1));
assertProperty(tableNode.childrenWithName("e2").get(0), StandardDdlLexicon.DATATYPE_NAME, TeiidDataType.VARCHAR.toDdl());
// constraints
assertThat(tableNode.getChildren(TeiidDdlLexicon.Constraint.INDEX_CONSTRAINT).size(), is(0));
}
/**
* See Teiid TestDDLParser#testAutoIncrementPrimarykey()
*/
@Test
public void shouldParseAutoIncrementPrimaryKey() {
final String content = "CREATE FOREIGN TABLE G1( e1 integer auto_increment primary key, e2 varchar)";
final AstNode tableNode = this.parser.parse(getTokens(content), this.rootNode);
assertThat(tableNode.getName(), is("G1"));
assertMixinType(tableNode, TeiidDdlLexicon.CreateTable.TABLE_STATEMENT);
assertProperty(tableNode, TeiidDdlLexicon.SchemaElement.TYPE, SchemaElementType.FOREIGN.toDdl());
// columns
assertThat(tableNode.getChildren(TeiidDdlLexicon.CreateTable.TABLE_ELEMENT).size(), is(2));
{ // column e1
assertThat(tableNode.childrenWithName("e1").size(), is(1));
final AstNode e1 = tableNode.childrenWithName("e1").get(0);
assertProperty(e1, StandardDdlLexicon.DATATYPE_NAME, TeiidDataType.INTEGER.toDdl());
assertProperty(e1, TeiidDdlLexicon.CreateTable.AUTO_INCREMENT, true);
assertProperty(e1, StandardDdlLexicon.NULLABLE, DdlConstants.NULL);
}
{ // column e2
assertThat(tableNode.childrenWithName("e2").size(), is(1));
final AstNode e2 = tableNode.childrenWithName("e2").get(0);
assertProperty(e2, StandardDdlLexicon.DATATYPE_NAME, TeiidDataType.VARCHAR.toDdl());
assertProperty(e2, TeiidDdlLexicon.CreateTable.AUTO_INCREMENT, false);
assertProperty(e2, StandardDdlLexicon.NULLABLE, "NULL");
}
// constraints
assertThat(tableNode.getChildren(TeiidDdlLexicon.Constraint.TABLE_ELEMENT).size(), is(1));
assertThat(tableNode.getChildren(TeiidDdlLexicon.Constraint.INDEX_CONSTRAINT).size(), is(0));
}
/**
* See Teiid TestDDLParser#testUDT()
*/
@Test
public void shouldParseUdt() {
final String content = "CREATE FOREIGN TABLE G1( e1 integer, e2 varchar OPTIONS (UDT 'NMTOKENS(12,13,14)'))";
final AstNode tableNode = this.parser.parse(getTokens(content), this.rootNode);
assertThat(tableNode.getName(), is("G1"));
assertMixinType(tableNode, TeiidDdlLexicon.CreateTable.TABLE_STATEMENT);
assertProperty(tableNode, TeiidDdlLexicon.SchemaElement.TYPE, SchemaElementType.FOREIGN.toDdl());
// columns
assertThat(tableNode.getChildren(TeiidDdlLexicon.CreateTable.TABLE_ELEMENT).size(), is(2));
{ // column e1
assertThat(tableNode.childrenWithName("e1").size(), is(1));
final AstNode e1 = tableNode.childrenWithName("e1").get(0);
assertProperty(e1, StandardDdlLexicon.DATATYPE_NAME, TeiidDataType.INTEGER.toDdl());
assertProperty(e1, TeiidDdlLexicon.CreateTable.AUTO_INCREMENT, false);
assertProperty(e1, StandardDdlLexicon.NULLABLE, DdlConstants.NULL);
}
{ // column e2
assertThat(tableNode.childrenWithName("e2").size(), is(1));
final AstNode e2 = tableNode.childrenWithName("e2").get(0);
assertProperty(e2, StandardDdlLexicon.DATATYPE_NAME, TeiidDataType.VARCHAR.toDdl());
assertProperty(e2, TeiidDdlLexicon.CreateTable.AUTO_INCREMENT, false);
assertProperty(e2, StandardDdlLexicon.NULLABLE, "NULL");
}
// constraints
assertThat(tableNode.getChildren(TeiidDdlLexicon.Constraint.TABLE_ELEMENT).size(), is(0));
assertThat(tableNode.getChildren(TeiidDdlLexicon.Constraint.INDEX_CONSTRAINT).size(), is(0));
}
/**
* See Teiid TestDDLParser#testFBI()
*/
@Test
public void shouldParseFunctionIndex() {
final String content = "CREATE FOREIGN TABLE G1(e1 integer, e2 varchar, CONSTRAINT fbi INDEX (UPPER(e2)))";
final AstNode tableNode = this.parser.parse(getTokens(content), this.rootNode);
assertThat(tableNode.getName(), is("G1"));
assertMixinType(tableNode, TeiidDdlLexicon.CreateTable.TABLE_STATEMENT);
assertProperty(tableNode, TeiidDdlLexicon.SchemaElement.TYPE, SchemaElementType.FOREIGN.toString());
// columns
assertThat(tableNode.getChildren(TeiidDdlLexicon.CreateTable.TABLE_ELEMENT).size(), is(2));
{ // column e1
assertThat(tableNode.childrenWithName("e1").size(), is(1));
final AstNode e1 = tableNode.childrenWithName("e1").get(0);
assertProperty(e1, StandardDdlLexicon.DATATYPE_NAME, TeiidDataType.INTEGER.toDdl());
assertProperty(e1, TeiidDdlLexicon.CreateTable.AUTO_INCREMENT, false);
assertProperty(e1, StandardDdlLexicon.NULLABLE, DdlConstants.NULL);
}
{ // column e2
assertThat(tableNode.childrenWithName("e2").size(), is(1));
final AstNode e2 = tableNode.childrenWithName("e2").get(0);
assertProperty(e2, StandardDdlLexicon.DATATYPE_NAME, TeiidDataType.VARCHAR.toDdl());
assertProperty(e2, TeiidDdlLexicon.CreateTable.AUTO_INCREMENT, false);
assertProperty(e2, StandardDdlLexicon.NULLABLE, "NULL");
}
// there are no table element constraints
assertThat(tableNode.getChildren(TeiidDdlLexicon.Constraint.TABLE_ELEMENT).size(), is(0));
{ // index constraint
assertThat(tableNode.getChildren(TeiidDdlLexicon.Constraint.INDEX_CONSTRAINT).size(), is(1));
final AstNode indexNode = tableNode.getChildren(TeiidDdlLexicon.Constraint.INDEX_CONSTRAINT).get(0);
assertThat(indexNode.getName(), is("fbi"));
assertProperty(indexNode, TeiidDdlLexicon.Constraint.EXPRESSION, "UPPER(e2)");
final Object temp = indexNode.getProperty(TeiidDdlLexicon.Constraint.REFERENCES);
assertThat(temp, is(instanceOf(List.class)));
@SuppressWarnings( "unchecked" )
final List<AstNode> references = (List<AstNode>)temp;
assertThat(references.size(), is(1));
assertThat(references.get(0), is(tableNode.childrenWithName("e2").get(0)));
}
}
/**
* See Teiid TestDDLParser#testMultiKeyPK()
*/
@Test
public void shouldParseMultiKeyPrimaryKey() {
final String content = "CREATE FOREIGN TABLE G1( e1 integer, e2 varchar, e3 date, PRIMARY KEY (e1, e2))";
final AstNode tableNode = this.parser.parse(getTokens(content), this.rootNode);
assertThat(tableNode.getName(), is("G1"));
assertMixinType(tableNode, TeiidDdlLexicon.CreateTable.TABLE_STATEMENT);
assertProperty(tableNode, TeiidDdlLexicon.SchemaElement.TYPE, SchemaElementType.FOREIGN.toDdl());
// columns
assertThat(tableNode.getChildren(TeiidDdlLexicon.CreateTable.TABLE_ELEMENT).size(), is(3));
{ // column e1
assertThat(tableNode.childrenWithName("e1").size(), is(1));
final AstNode e1 = tableNode.childrenWithName("e1").get(0);
assertProperty(e1, StandardDdlLexicon.DATATYPE_NAME, TeiidDataType.INTEGER.toDdl());
assertProperty(e1, TeiidDdlLexicon.CreateTable.AUTO_INCREMENT, false);
assertProperty(e1, StandardDdlLexicon.NULLABLE, DdlConstants.NULL);
}
{ // column e2
assertThat(tableNode.childrenWithName("e2").size(), is(1));
final AstNode e2 = tableNode.childrenWithName("e2").get(0);
assertProperty(e2, StandardDdlLexicon.DATATYPE_NAME, TeiidDataType.VARCHAR.toDdl());
assertProperty(e2, TeiidDdlLexicon.CreateTable.AUTO_INCREMENT, false);
assertProperty(e2, StandardDdlLexicon.NULLABLE, "NULL");
}
{ // column e3
assertThat(tableNode.childrenWithName("e3").size(), is(1));
final AstNode e3 = tableNode.childrenWithName("e3").get(0);
assertProperty(e3, StandardDdlLexicon.DATATYPE_NAME, TeiidDataType.DATE.toDdl());
assertProperty(e3, TeiidDdlLexicon.CreateTable.AUTO_INCREMENT, false);
assertProperty(e3, StandardDdlLexicon.NULLABLE, "NULL");
}
// constraints
assertThat(tableNode.getChildren(TeiidDdlLexicon.Constraint.TABLE_ELEMENT).size(), is(1));
assertThat(tableNode.getChildren(TeiidDdlLexicon.Constraint.INDEX_CONSTRAINT).size(), is(0));
}
/**
* See Teiid TestDDLParser#testOptionsKey()
*/
@Test
public void shouldParseOptionsKey() {
final String content = "CREATE FOREIGN TABLE G1( e1 integer, e2 varchar, e3 date, UNIQUE (e1) OPTIONS (CUSTOM_PROP 'VALUE'))";
final AstNode tableNode = this.parser.parse(getTokens(content), this.rootNode);
assertThat(tableNode.getName(), is("G1"));
assertMixinType(tableNode, TeiidDdlLexicon.CreateTable.TABLE_STATEMENT);
assertProperty(tableNode, TeiidDdlLexicon.SchemaElement.TYPE, SchemaElementType.FOREIGN.toDdl());
// columns
assertThat(tableNode.getChildren(TeiidDdlLexicon.CreateTable.TABLE_ELEMENT).size(), is(3));
{ // column e1
assertThat(tableNode.childrenWithName("e1").size(), is(1));
final AstNode e1 = tableNode.childrenWithName("e1").get(0);
assertProperty(e1, StandardDdlLexicon.DATATYPE_NAME, TeiidDataType.INTEGER.toDdl());
assertProperty(e1, TeiidDdlLexicon.CreateTable.AUTO_INCREMENT, false);
assertProperty(e1, StandardDdlLexicon.NULLABLE, DdlConstants.NULL);
}
{ // column e2
assertThat(tableNode.childrenWithName("e2").size(), is(1));
final AstNode e2 = tableNode.childrenWithName("e2").get(0);
assertProperty(e2, StandardDdlLexicon.DATATYPE_NAME, TeiidDataType.VARCHAR.toDdl());
assertProperty(e2, TeiidDdlLexicon.CreateTable.AUTO_INCREMENT, false);
assertProperty(e2, StandardDdlLexicon.NULLABLE, "NULL");
}
{ // column e3
assertThat(tableNode.childrenWithName("e3").size(), is(1));
final AstNode e3 = tableNode.childrenWithName("e3").get(0);
assertProperty(e3, StandardDdlLexicon.DATATYPE_NAME, TeiidDataType.DATE.toDdl());
assertProperty(e3, TeiidDdlLexicon.CreateTable.AUTO_INCREMENT, false);
assertProperty(e3, StandardDdlLexicon.NULLABLE, "NULL");
}
// constraints
assertThat(tableNode.getChildren(TeiidDdlLexicon.Constraint.TABLE_ELEMENT).size(), is(1));
assertThat(tableNode.getChildren(TeiidDdlLexicon.Constraint.INDEX_CONSTRAINT).size(), is(0));
}
/**
* See Teiid TestDDLParser#testConstraints()
*/
@Test
public void shouldParseConstraints() {
final String content = "CREATE FOREIGN TABLE G1( e1 integer, e2 varchar, e3 date, PRIMARY KEY (e1, e2), INDEX(e2, e3), ACCESSPATTERN(e1), UNIQUE(e1), ACCESSPATTERN(e2, e3))";
final AstNode tableNode = this.parser.parse(getTokens(content), this.rootNode);
assertThat(tableNode.getName(), is("G1"));
assertMixinType(tableNode, TeiidDdlLexicon.CreateTable.TABLE_STATEMENT);
assertProperty(tableNode, TeiidDdlLexicon.SchemaElement.TYPE, SchemaElementType.FOREIGN.toDdl());
// columns
assertThat(tableNode.getChildren(TeiidDdlLexicon.CreateTable.TABLE_ELEMENT).size(), is(3));
{ // column e1
assertThat(tableNode.childrenWithName("e1").size(), is(1));
final AstNode e1 = tableNode.childrenWithName("e1").get(0);
assertProperty(e1, StandardDdlLexicon.DATATYPE_NAME, TeiidDataType.INTEGER.toDdl());
assertProperty(e1, TeiidDdlLexicon.CreateTable.AUTO_INCREMENT, false);
assertProperty(e1, StandardDdlLexicon.NULLABLE, DdlConstants.NULL);
}
{ // column e2
assertThat(tableNode.childrenWithName("e2").size(), is(1));
final AstNode e2 = tableNode.childrenWithName("e2").get(0);
assertProperty(e2, StandardDdlLexicon.DATATYPE_NAME, TeiidDataType.VARCHAR.toDdl());
assertProperty(e2, TeiidDdlLexicon.CreateTable.AUTO_INCREMENT, false);
assertProperty(e2, StandardDdlLexicon.NULLABLE, "NULL");
}
{ // column e3
assertThat(tableNode.childrenWithName("e3").size(), is(1));
final AstNode e3 = tableNode.childrenWithName("e3").get(0);
assertProperty(e3, StandardDdlLexicon.DATATYPE_NAME, TeiidDataType.DATE.toDdl());
assertProperty(e3, TeiidDdlLexicon.CreateTable.AUTO_INCREMENT, false);
assertProperty(e3, StandardDdlLexicon.NULLABLE, "NULL");
}
{ // table element constraints (1 primary key, 2 access patterns, 1 unique)
final List<AstNode> tableElementConstraints = tableNode.getChildren(TeiidDdlLexicon.Constraint.TABLE_ELEMENT);
assertThat(tableElementConstraints.size(), is(4));
{ // primary key
final AstNode constraintNode = tableElementConstraints.get(0);
final Object temp = constraintNode.getProperty(TeiidDdlLexicon.Constraint.REFERENCES);
assertThat(temp, is(instanceOf(List.class)));
@SuppressWarnings( "unchecked" )
final List<AstNode> references = (List<AstNode>)temp;
assertThat(references.size(), is(2));
assertThat(references, hasItems(tableNode.childrenWithName("e1").get(0), tableNode.childrenWithName("e2").get(0)));
}
{ // access pattern
final AstNode constraintNode = tableElementConstraints.get(1);
final Object temp = constraintNode.getProperty(TeiidDdlLexicon.Constraint.REFERENCES);
assertThat(temp, is(instanceOf(List.class)));
@SuppressWarnings( "unchecked" )
final List<AstNode> references = (List<AstNode>)temp;
assertThat(references.size(), is(1));
assertThat(references, hasItems(tableNode.childrenWithName("e1").get(0)));
}
{ // unique
final AstNode constraintNode = tableElementConstraints.get(2);
final Object temp = constraintNode.getProperty(TeiidDdlLexicon.Constraint.REFERENCES);
assertThat(temp, is(instanceOf(List.class)));
@SuppressWarnings( "unchecked" )
final List<AstNode> references = (List<AstNode>)temp;
assertThat(references.size(), is(1));
assertThat(references, hasItems(tableNode.childrenWithName("e1").get(0)));
}
{ // access pattern
final AstNode constraintNode = tableElementConstraints.get(3);
final Object temp = constraintNode.getProperty(TeiidDdlLexicon.Constraint.REFERENCES);
assertThat(temp, is(instanceOf(List.class)));
@SuppressWarnings( "unchecked" )
final List<AstNode> references = (List<AstNode>)temp;
assertThat(references.size(), is(2));
assertThat(references, hasItems(tableNode.childrenWithName("e2").get(0), tableNode.childrenWithName("e3").get(0)));
}
}
{ // index constraint
assertThat(tableNode.getChildren(TeiidDdlLexicon.Constraint.INDEX_CONSTRAINT).size(), is(1));
final AstNode indexNode = tableNode.getChildren(TeiidDdlLexicon.Constraint.INDEX_CONSTRAINT).get(0);
assertProperty(indexNode, TeiidDdlLexicon.Constraint.EXPRESSION, "e2, e3");
assertProperty(indexNode, TeiidDdlLexicon.Constraint.TYPE, "INDEX");
final Object temp = indexNode.getProperty(TeiidDdlLexicon.Constraint.REFERENCES);
assertThat(temp, is(instanceOf(List.class)));
@SuppressWarnings( "unchecked" )
final List<AstNode> references = (List<AstNode>)temp;
assertThat(references.size(), is(2));
assertThat(references, hasItems(tableNode.childrenWithName("e2").get(0), tableNode.childrenWithName("e3").get(0)));
}
}
/**
* See Teiid TestDDLParser#testConstraints2()
*/
@Test
public void shouldParseConstraints2() {
final String content = "CREATE FOREIGN TABLE G1( e1 integer, e2 varchar, e3 date, ACCESSPATTERN(e1), UNIQUE(e1), ACCESSPATTERN(e2, e3))";
final AstNode tableNode = this.parser.parse(getTokens(content), this.rootNode);
assertThat(tableNode.getName(), is("G1"));
assertMixinType(tableNode, TeiidDdlLexicon.CreateTable.TABLE_STATEMENT);
assertProperty(tableNode, TeiidDdlLexicon.SchemaElement.TYPE, SchemaElementType.FOREIGN.toDdl());
// columns
assertThat(tableNode.getChildren(TeiidDdlLexicon.CreateTable.TABLE_ELEMENT).size(), is(3));
{ // column e1
assertThat(tableNode.childrenWithName("e1").size(), is(1));
final AstNode e1 = tableNode.childrenWithName("e1").get(0);
assertProperty(e1, StandardDdlLexicon.DATATYPE_NAME, TeiidDataType.INTEGER.toDdl());
assertProperty(e1, TeiidDdlLexicon.CreateTable.AUTO_INCREMENT, false);
assertProperty(e1, StandardDdlLexicon.NULLABLE, DdlConstants.NULL);
}
{ // column e2
assertThat(tableNode.childrenWithName("e2").size(), is(1));
final AstNode e2 = tableNode.childrenWithName("e2").get(0);
assertProperty(e2, StandardDdlLexicon.DATATYPE_NAME, TeiidDataType.VARCHAR.toDdl());
assertProperty(e2, TeiidDdlLexicon.CreateTable.AUTO_INCREMENT, false);
assertProperty(e2, StandardDdlLexicon.NULLABLE, "NULL");
}
{ // column e3
assertThat(tableNode.childrenWithName("e3").size(), is(1));
final AstNode e3 = tableNode.childrenWithName("e3").get(0);
assertProperty(e3, StandardDdlLexicon.DATATYPE_NAME, TeiidDataType.DATE.toDdl());
assertProperty(e3, TeiidDdlLexicon.CreateTable.AUTO_INCREMENT, false);
assertProperty(e3, StandardDdlLexicon.NULLABLE, "NULL");
}
// constraints
assertThat(tableNode.getChildren(TeiidDdlLexicon.Constraint.TABLE_ELEMENT).size(), is(3));
assertThat(tableNode.childrenWithName(CreateTableParser.ACCESS_PATTERN_PREFIX + "1").size(), is(1));
assertThat(tableNode.childrenWithName(CreateTableParser.ACCESS_PATTERN_PREFIX + "2").size(), is(1));
assertThat(tableNode.childrenWithName(CreateTableParser.UNIQUE_CONSTRAINT_PREFIX + "1").size(), is(1));
final Object temp = tableNode.childrenWithName(CreateTableParser.UNIQUE_CONSTRAINT_PREFIX + "1").get(0).getProperty(TeiidDdlLexicon.Constraint.REFERENCES);
assertThat(temp, is(instanceOf(List.class)));
@SuppressWarnings( "unchecked" )
final List<AstNode> references = (List<AstNode>)temp;
assertThat(references.size(), is(1));
assertThat(references.get(0), is(tableNode.childrenWithName("e1").get(0)));
assertThat(tableNode.getChildren(TeiidDdlLexicon.Constraint.INDEX_CONSTRAINT).size(), is(0));
}
/**
* See Teiid TestDDLParser#testWrongPrimarykey()
*/
@Test
public void shouldParseUnresolvedColumnInPrimaryKey() {
final String content = "CREATE FOREIGN TABLE G1( e1 integer, e2 varchar, PRIMARY KEY (missingColumn))";
final AstNode tableNode = this.parser.parse(getTokens(content), this.rootNode);
assertThat(tableNode.getName(), is("G1"));
assertMixinType(tableNode, TeiidDdlLexicon.CreateTable.TABLE_STATEMENT);
assertProperty(tableNode, TeiidDdlLexicon.SchemaElement.TYPE, SchemaElementType.FOREIGN.toDdl());
assertThat(tableNode.childrenWithName(CreateTableParser.PRIMARY_KEY_PREFIX + "1").size(), is(1)); // make sure primary key
// still created
}
@Test
public void shouldParseUnresolvedTableInForeignKey() {
final String content = "CREATE FOREIGN TABLE G1 (e1 integer, e2 varchar, CONSTRAINT fk_1 FOREIGN KEY (e1, e2) REFERENCES missingTable)";
final AstNode tableNode = this.parser.parse(getTokens(content), this.rootNode);
assertThat(tableNode.getName(), is("G1"));
assertMixinType(tableNode, TeiidDdlLexicon.CreateTable.TABLE_STATEMENT);
assertProperty(tableNode, TeiidDdlLexicon.SchemaElement.TYPE, SchemaElementType.FOREIGN.toDdl());
assertThat(tableNode.childrenWithName("fk_1").size(), is(1)); // make sure foreign key still created
}
@Test
public void shouldNotParseUnresolvedColumnReferenceInForeignKey() {
this.parser.parse(getTokens("CREATE FOREIGN TABLE refTable( t1 integer, t2 varchar)"), this.rootNode);
final String content = "CREATE FOREIGN TABLE G1 (e1 integer, e2 varchar, CONSTRAINT fk_1 FOREIGN KEY (e1, e2) REFERENCES refTable (t1, missingColumn))";
final AstNode tableNode = this.parser.parse(getTokens(content), this.rootNode);
assertThat(tableNode.getName(), is("G1"));
assertMixinType(tableNode, TeiidDdlLexicon.CreateTable.TABLE_STATEMENT);
assertProperty(tableNode, TeiidDdlLexicon.SchemaElement.TYPE, SchemaElementType.FOREIGN.toDdl());
assertThat(tableNode.childrenWithName("fk_1").size(), is(1)); // make sure foreign key still created
}
/**
* See Teiid TestDDLParser#testWrongPrimarykey()
*/
@Test
public void shouldParseViewWithoutColumns() {
final String content = "CREATE VIEW V1 AS SELECT * FROM PM1.G1";
final AstNode viewNode = this.parser.parse(getTokens(content), this.rootNode);
assertThat(viewNode.getName(), is("V1"));
assertMixinType(viewNode, TeiidDdlLexicon.CreateTable.VIEW_STATEMENT);
assertProperty(viewNode, TeiidDdlLexicon.SchemaElement.TYPE, SchemaElementType.FOREIGN.toDdl());
assertProperty(viewNode, TeiidDdlLexicon.CreateTable.QUERY_EXPRESSION, "SELECT * FROM PM1.G1");
// columns
assertThat(viewNode.getChildren(TeiidDdlLexicon.CreateTable.TABLE_ELEMENT).size(), is(0));
// constraints
assertThat(viewNode.getChildren(TeiidDdlLexicon.Constraint.TABLE_ELEMENT).size(), is(0));
assertThat(viewNode.getChildren(TeiidDdlLexicon.Constraint.INDEX_CONSTRAINT).size(), is(0));
}
/**
* See Teiid TestDDLParser#testView()
*/
@Test
public void shouldParseView() {
final String content = "CREATE View G1( e1 integer, e2 varchar) OPTIONS (CARDINALITY 12) AS select e1, e2 from foo.bar";
final AstNode viewNode = this.parser.parse(getTokens(content), this.rootNode);
assertThat(viewNode.getName(), is("G1"));
assertMixinType(viewNode, TeiidDdlLexicon.CreateTable.VIEW_STATEMENT);
assertProperty(viewNode, TeiidDdlLexicon.SchemaElement.TYPE, SchemaElementType.FOREIGN.toDdl());
assertProperty(viewNode, TeiidDdlLexicon.CreateTable.QUERY_EXPRESSION, "select e1, e2 from foo.bar");
// columns
final List<AstNode> columns = viewNode.getChildren(TeiidDdlLexicon.CreateTable.TABLE_ELEMENT);
assertThat(columns.size(), is(2));
if ("e1".equals(columns.get(0).getName())) {
assertProperty(columns.get(0), StandardDdlLexicon.DATATYPE_NAME, TeiidDataType.INTEGER.toDdl());
assertThat("e2", is(columns.get(1).getName()));
assertProperty(columns.get(1), StandardDdlLexicon.DATATYPE_NAME, TeiidDataType.VARCHAR.toDdl());
} else if ("e1".equals(columns.get(1).getName())) {
assertProperty(columns.get(1), StandardDdlLexicon.DATATYPE_NAME, TeiidDataType.INTEGER.toDdl());
assertThat("e2", is(columns.get(0).getName()));
assertProperty(columns.get(0), StandardDdlLexicon.DATATYPE_NAME, TeiidDataType.VARCHAR.toDdl());
} else {
fail("column 'e1' not found");
}
// options
assertThat(viewNode.childrenWithName("CARDINALITY").size(), is(1));
assertProperty(viewNode.childrenWithName("CARDINALITY").get(0), StandardDdlLexicon.VALUE, "12");
// constraints
assertThat(viewNode.getChildren(TeiidDdlLexicon.Constraint.TABLE_ELEMENT).size(), is(0));
assertThat(viewNode.getChildren(TeiidDdlLexicon.Constraint.INDEX_CONSTRAINT).size(), is(0));
}
@Test
public void shouldParseCreateForeignTableWithoutBody() {
final String content = "CREATE FOREIGN TABLE FOO";
final AstNode tableNode = this.parser.parse(getTokens(content), this.rootNode);
assertThat(tableNode.getName(), is("FOO"));
assertMixinType(tableNode, TeiidDdlLexicon.CreateTable.TABLE_STATEMENT);
assertProperty(tableNode, TeiidDdlLexicon.SchemaElement.TYPE, SchemaElementType.FOREIGN.toDdl());
// columns
assertThat(tableNode.getChildren(TeiidDdlLexicon.CreateTable.TABLE_ELEMENT).size(), is(0));
// constraints
assertThat(tableNode.getChildren(TeiidDdlLexicon.Constraint.TABLE_ELEMENT).size(), is(0));
assertThat(tableNode.getChildren(TeiidDdlLexicon.Constraint.INDEX_CONSTRAINT).size(), is(0));
}
@Test
public void shouldParseCreateViewWithoutBody() {
final String content = "CREATE VIEW FOO";
final AstNode viewNode = this.parser.parse(getTokens(content), this.rootNode);
assertThat(viewNode.getName(), is("FOO"));
assertMixinType(viewNode, TeiidDdlLexicon.CreateTable.VIEW_STATEMENT);
assertProperty(viewNode, TeiidDdlLexicon.SchemaElement.TYPE, SchemaElementType.FOREIGN.toDdl());
// columns
assertThat(viewNode.getChildren(TeiidDdlLexicon.CreateTable.TABLE_ELEMENT).size(), is(0));
// constraints
assertThat(viewNode.getChildren(TeiidDdlLexicon.Constraint.TABLE_ELEMENT).size(), is(0));
assertThat(viewNode.getChildren(TeiidDdlLexicon.Constraint.INDEX_CONSTRAINT).size(), is(0));
}
@Test
public void shouldParseCreateVirtualViewWithoutBody() {
final String content = "CREATE VIRTUAL VIEW FOO";
final AstNode viewNode = this.parser.parse(getTokens(content), this.rootNode);
assertThat(viewNode.getName(), is("FOO"));
assertMixinType(viewNode, TeiidDdlLexicon.CreateTable.VIEW_STATEMENT);
assertProperty(viewNode, TeiidDdlLexicon.SchemaElement.TYPE, SchemaElementType.VIRTUAL.toDdl());
// columns
assertThat(viewNode.getChildren(TeiidDdlLexicon.CreateTable.TABLE_ELEMENT).size(), is(0));
// constraints
assertThat(viewNode.getChildren(TeiidDdlLexicon.Constraint.TABLE_ELEMENT).size(), is(0));
assertThat(viewNode.getChildren(TeiidDdlLexicon.Constraint.INDEX_CONSTRAINT).size(), is(0));
}
// ********* table element tests ***********
@Test
public void shouldParseTableElement() {
final String content = "symbol string";
final AstNode node = this.parser.parseTableElement(getTokens(content), this.rootNode);
assertMixinType(node, TeiidDdlLexicon.CreateTable.TABLE_ELEMENT);
assertThat(node.getName(), is("symbol"));
assertProperty(node, StandardDdlLexicon.DATATYPE_NAME, TeiidDdlConstants.TeiidDataType.STRING.toDdl());
assertThat(this.rootNode.getChildCount(), is(1));
}
@Test
public void shouldParseTableElementWithDataTypeLength() {
final String content = "company_name varchar(256)";
final AstNode node = this.parser.parseTableElement(getTokens(content), this.rootNode);
assertMixinType(node, TeiidDdlLexicon.CreateTable.TABLE_ELEMENT);
assertThat(node.getName(), is("company_name"));
assertProperty(node, StandardDdlLexicon.DATATYPE_NAME, TeiidDdlConstants.TeiidDataType.VARCHAR.toDdl());
assertProperty(node, StandardDdlLexicon.DATATYPE_LENGTH, 256L);
}
@Test
public void shouldParseTableElementWithNotNull() {
final String content = "ACCOUNT_ID long NOT NULL";
final AstNode node = this.parser.parseTableElement(getTokens(content), this.rootNode);
assertMixinType(node, TeiidDdlLexicon.CreateTable.TABLE_ELEMENT);
assertThat(node.getName(), is("ACCOUNT_ID"));
assertProperty(node, StandardDdlLexicon.DATATYPE_NAME, TeiidDdlConstants.TeiidDataType.LONG.toDdl());
assertProperty(node, StandardDdlLexicon.NULLABLE, "NOT NULL");
}
@Test
public void shouldParseTableElementWithQuotedDefaultValue() {
final String content = "DATEOPENED timestamp DEFAULT 'CURRENT_TIMESTAMP'";
final AstNode node = this.parser.parseTableElement(getTokens(content), this.rootNode);
assertMixinType(node, TeiidDdlLexicon.CreateTable.TABLE_ELEMENT);
assertThat(node.getName(), is("DATEOPENED"));
assertProperty(node, StandardDdlLexicon.DATATYPE_NAME, TeiidDdlConstants.TeiidDataType.TIMESTAMP.toDdl());
assertProperty(node, StandardDdlLexicon.DEFAULT_OPTION, StandardDdlLexicon.DEFAULT_ID_DATETIME);
assertProperty(node, StandardDdlLexicon.DEFAULT_VALUE, "CURRENT_TIMESTAMP");
}
@Test
public void shouldParseTableElementWithOptionsClause() {
final String content = "DATECLOSED timestamp OPTIONS (ANNOTATION 'This is the date closed', NAMEINSOURCE '`DATECLOSED`', NATIVE_TYPE 'TIMESTAMP')";
final AstNode node = this.parser.parseTableElement(getTokens(content), this.rootNode);
assertMixinType(node, TeiidDdlLexicon.CreateTable.TABLE_ELEMENT);
assertThat(node.getName(), is("DATECLOSED"));
assertProperty(node, StandardDdlLexicon.DATATYPE_NAME, TeiidDdlConstants.TeiidDataType.TIMESTAMP.toDdl());
// make sure the is an options clause
final List<AstNode> kids = node.getChildren();
assertThat(kids.size(), is(3));
for (final AstNode kid : kids) {
assertMixinType(kid, StandardDdlLexicon.TYPE_STATEMENT_OPTION);
}
}
@Test
public void shouldParseTableElementWithPrimaryKeyConstraint() {
final String content = "KEY STRING(9) PRIMARY KEY";
final AstNode columnNode = this.parser.parseTableElement(getTokens(content), this.rootNode);
assertMixinType(columnNode, TeiidDdlLexicon.CreateTable.TABLE_ELEMENT);
assertThat(columnNode.getName(), is("KEY"));
assertProperty(columnNode, StandardDdlLexicon.DATATYPE_NAME, TeiidDdlConstants.TeiidDataType.STRING.toDdl());
assertProperty(columnNode, StandardDdlLexicon.DATATYPE_LENGTH, 9L);
// check constraint
final List<AstNode> kids = this.rootNode.getChildren();
assertThat(kids.size(), is(2)); // one for column, one for constraint
final AstNode constraintNode = ((kids.get(0) == columnNode) ? kids.get(1) : kids.get(0));
assertThat(constraintNode.getMixins(), hasItem(TeiidDdlLexicon.Constraint.TABLE_ELEMENT));
assertProperty(constraintNode, TeiidDdlLexicon.Constraint.TYPE, DdlConstants.PRIMARY_KEY);
final Object temp = constraintNode.getProperty(TeiidDdlLexicon.Constraint.REFERENCES);
assertThat(temp, is(instanceOf(List.class)));
@SuppressWarnings( "unchecked" )
final List<AstNode> references = (List<AstNode>)temp;
assertThat(references.size(), is(1));
assertThat(references.get(0), is(columnNode));
}
@Test
public void shouldParseTableElementWithPrimaryUniqueConstraint() {
final String content = "KEY VARCHAR(9) UNIQUE";
final AstNode columnNode = this.parser.parseTableElement(getTokens(content), this.rootNode);
assertMixinType(columnNode, TeiidDdlLexicon.CreateTable.TABLE_ELEMENT);
assertThat(columnNode.getName(), is("KEY"));
assertProperty(columnNode, StandardDdlLexicon.DATATYPE_NAME, TeiidDdlConstants.TeiidDataType.VARCHAR.toDdl());
assertProperty(columnNode, StandardDdlLexicon.DATATYPE_LENGTH, 9L);
// check constraint
final List<AstNode> kids = this.rootNode.getChildren();
assertThat(kids.size(), is(2)); // one for column, one for constraint
final AstNode constraintNode = ((kids.get(0) == columnNode) ? kids.get(1) : kids.get(0));
assertThat(constraintNode.getMixins(), hasItem(TeiidDdlLexicon.Constraint.TABLE_ELEMENT));
assertProperty(constraintNode, TeiidDdlLexicon.Constraint.TYPE, DdlConstants.UNIQUE);
final Object temp = constraintNode.getProperty(TeiidDdlLexicon.Constraint.REFERENCES);
assertThat(temp, is(instanceOf(List.class)));
@SuppressWarnings( "unchecked" )
final List<AstNode> references = (List<AstNode>)temp;
assertThat(references.size(), is(1));
assertThat(references.get(0), is(columnNode));
}
@Test
public void shouldParseTableElementWithIndexConstraint() {
final String content = "KEY STRING(9) INDEX";
final AstNode columnNode = this.parser.parseTableElement(getTokens(content), this.rootNode);
assertMixinType(columnNode, TeiidDdlLexicon.CreateTable.TABLE_ELEMENT);
assertThat(columnNode.getName(), is("KEY"));
assertProperty(columnNode, StandardDdlLexicon.DATATYPE_NAME, TeiidDdlConstants.TeiidDataType.STRING.toDdl());
// check constraint
final List<AstNode> kids = this.rootNode.getChildren();
assertThat(kids.size(), is(2)); // one for column, one for constraint
final AstNode constraintNode = ((kids.get(0) == columnNode) ? kids.get(1) : kids.get(0));
assertThat(constraintNode.getMixins(), hasItem(TeiidDdlLexicon.Constraint.INDEX_CONSTRAINT));
assertProperty(constraintNode, TeiidDdlLexicon.Constraint.TYPE, DdlConstants.INDEX);
assertThat(constraintNode.getProperty(TeiidDdlLexicon.Constraint.EXPRESSION), is(nullValue()));
}
@Test
public void shouldParseTableElementWithAutoIncrementIndexConstraint() {
final String content = "e5 integer auto_increment INDEX";
final AstNode columnNode = this.parser.parseTableElement(getTokens(content), this.rootNode);
assertMixinType(columnNode, TeiidDdlLexicon.CreateTable.TABLE_ELEMENT);
assertThat(columnNode.getName(), is("e5"));
assertProperty(columnNode, StandardDdlLexicon.DATATYPE_NAME, TeiidDdlConstants.TeiidDataType.INTEGER.toDdl());
assertProperty(columnNode, TeiidDdlLexicon.CreateTable.AUTO_INCREMENT, true);
assertProperty(columnNode, StandardDdlLexicon.NULLABLE, DdlConstants.NULL);
// check constraint
final List<AstNode> kids = this.rootNode.getChildren();
assertThat(kids.size(), is(2)); // one for column, one for constraint
final AstNode constraintNode = ((kids.get(0) == columnNode) ? kids.get(1) : kids.get(0));
assertThat(constraintNode.getMixins(), hasItem(TeiidDdlLexicon.Constraint.INDEX_CONSTRAINT));
assertProperty(constraintNode, TeiidDdlLexicon.Constraint.TYPE, DdlConstants.INDEX);
assertThat(constraintNode.getProperty(TeiidDdlLexicon.Constraint.EXPRESSION), is(nullValue()));
}
@Test
public void shouldParseTableElementWithAllClauses() {
final String name = "foo";
final int precision = 9;
final int scale = 3;
final String value = "bar";
final String content = name
+ " bigdecimal("
+ precision
+ ','
+ scale
+ ") NOT NULL auto_increment index DEFAULT '"
+ value
+ "' OPTIONS (CARDINALITY 12, UUID 'uuid2', UPDATABLE 'true', FOO 'BAR', ANNOTATION 'Test Table')";
final AstNode columnNode = this.parser.parseTableElement(getTokens(content), this.rootNode);
assertThat(columnNode.getName(), is(name));
assertProperty(columnNode, StandardDdlLexicon.DATATYPE_NAME, TeiidDdlConstants.TeiidDataType.BIGDECIMAL.toDdl());
assertProperty(columnNode, StandardDdlLexicon.DATATYPE_PRECISION, precision);
assertProperty(columnNode, StandardDdlLexicon.DATATYPE_SCALE, scale);
assertProperty(columnNode, StandardDdlLexicon.DEFAULT_OPTION, StandardDdlLexicon.DEFAULT_ID_LITERAL);
assertProperty(columnNode, StandardDdlLexicon.DEFAULT_VALUE, value);
assertProperty(columnNode, TeiidDdlLexicon.CreateTable.AUTO_INCREMENT, true);
assertProperty(columnNode, StandardDdlLexicon.NULLABLE, "NOT NULL");
// make sure root has 2 children (column, constraint)
final List<AstNode> rootKids = this.rootNode.getChildren();
assertThat(rootKids.size(), is(2));
// check constraint
final AstNode constraintNode = ((rootKids.get(0) == columnNode) ? rootKids.get(1) : rootKids.get(0));
assertThat(constraintNode.getMixins(), hasItem(TeiidDdlLexicon.Constraint.INDEX_CONSTRAINT));
assertProperty(constraintNode, TeiidDdlLexicon.Constraint.TYPE, DdlConstants.INDEX);
assertThat(constraintNode.getProperty(TeiidDdlLexicon.Constraint.EXPRESSION), is(nullValue()));
// make sure there are 5 options clauses on the column
final List<AstNode> kids = columnNode.getChildren();
assertThat(kids.size(), is(5));
for (final AstNode kid : kids) {
assertMixinType(kid, StandardDdlLexicon.TYPE_STATEMENT_OPTION);
}
}
// ********* table body constraint tests ***********
@Test
public void shouldParseNamedIndexConstraint() {
final String content = "CONSTRAINT fbi INDEX (UPPER(e2))";
assertThat(this.parser.parseTableBodyConstraint(getTokens(content), this.rootNode), is(true));
// check constraint
final List<AstNode> kids = this.rootNode.getChildren();
assertThat(kids.size(), is(1));
final AstNode constraintNode = kids.get(0);
assertThat(constraintNode.getMixins(), hasItem(TeiidDdlLexicon.Constraint.INDEX_CONSTRAINT));
assertThat(constraintNode.getName(), is("fbi"));
assertProperty(constraintNode, TeiidDdlLexicon.Constraint.TYPE, DdlConstants.INDEX);
assertProperty(constraintNode, TeiidDdlLexicon.Constraint.EXPRESSION, "UPPER(e2)");
}
@Test
public void shouldParseUnnamedIndexConstraint() {
final String content = " INDEX (UPPER(e2))";
assertThat(this.parser.parseTableBodyConstraint(getTokens(content), this.rootNode), is(true));
// check constraint
final List<AstNode> kids = this.rootNode.getChildren();
assertThat(kids.size(), is(1));
final AstNode constraintNode = kids.get(0);
assertThat(constraintNode.getMixins(), hasItem(TeiidDdlLexicon.Constraint.INDEX_CONSTRAINT));
assertProperty(constraintNode, TeiidDdlLexicon.Constraint.TYPE, DdlConstants.INDEX);
assertThat(constraintNode.getName(), is(CreateTableParser.INDEX_PREFIX + "1"));
assertProperty(constraintNode, TeiidDdlLexicon.Constraint.EXPRESSION, "UPPER(e2)");
}
@Test
public void shouldParseNamedPrimaryKeyConstraint() {
final AstNode col1Node = new AstNode(this.rootNode, "col1");
final AstNode col2Node = new AstNode(this.rootNode, "col2");
final String content = "CONSTRAINT pk_1 PRIMARY KEY (col1, col2)";
assertThat(this.parser.parseTableBodyConstraint(getTokens(content), this.rootNode), is(true));
assertThat(this.rootNode.getChildCount(), is(3)); // 2 columns, 1 constraint
final List<AstNode> kids = this.rootNode.childrenWithName("pk_1");
assertThat(kids.size(), is(1)); // constraint node
final AstNode constraintNode = kids.get(0);
assertThat(constraintNode.getMixins(), hasItem(TeiidDdlLexicon.Constraint.TABLE_ELEMENT));
assertThat(constraintNode.getName(), is("pk_1"));
assertProperty(constraintNode, TeiidDdlLexicon.Constraint.TYPE, DdlConstants.PRIMARY_KEY);
// referenced columns
@SuppressWarnings( "unchecked" )
final List<AstNode> refs = (List<AstNode>)constraintNode.getProperty(TeiidDdlLexicon.Constraint.REFERENCES);
assertThat(refs.size(), is(2));
assertThat(refs, hasItems(col1Node, col2Node));
}
@Test
public void shouldParseUnnamedPrimaryKeyConstraint() {
final AstNode col1Node = new AstNode(this.rootNode, "col1");
final AstNode col2Node = new AstNode(this.rootNode, "col2");
final String content = "PRIMARY KEY (col1, col2)";
assertThat(this.parser.parseTableBodyConstraint(getTokens(content), this.rootNode), is(true));
assertThat(this.rootNode.getChildCount(), is(3)); // 2 columns, 1 constraint
final List<AstNode> kids = this.rootNode.childrenWithName(CreateTableParser.PRIMARY_KEY_PREFIX + "1");
assertThat(kids.size(), is(1)); // constraint node
final AstNode constraintNode = kids.get(0);
assertThat(constraintNode.getMixins(), hasItem(TeiidDdlLexicon.Constraint.TABLE_ELEMENT));
assertProperty(constraintNode, TeiidDdlLexicon.Constraint.TYPE, DdlConstants.PRIMARY_KEY);
// referenced columns
@SuppressWarnings( "unchecked" )
final List<AstNode> refs = (List<AstNode>)constraintNode.getProperty(TeiidDdlLexicon.Constraint.REFERENCES);
assertThat(refs.size(), is(2));
assertThat(refs, hasItems(col1Node, col2Node));
}
@Test
public void shouldParseNamedUniqueConstraint() {
final AstNode col1Node = new AstNode(this.rootNode, "col1");
final String content = "CONSTRAINT uk_1 UNIQUE (col1)";
assertThat(this.parser.parseTableBodyConstraint(getTokens(content), this.rootNode), is(true));
assertThat(this.rootNode.getChildCount(), is(2)); // 1 column, 1 constraint
final List<AstNode> kids = this.rootNode.childrenWithName("uk_1");
assertThat(kids.size(), is(1)); // constraint node
final AstNode constraintNode = kids.get(0);
assertThat(constraintNode.getMixins(), hasItem(TeiidDdlLexicon.Constraint.TABLE_ELEMENT));
assertProperty(constraintNode, TeiidDdlLexicon.Constraint.TYPE, TeiidReservedWord.UNIQUE.toDdl());
// referenced columns
@SuppressWarnings( "unchecked" )
final List<AstNode> refs = (List<AstNode>)constraintNode.getProperty(TeiidDdlLexicon.Constraint.REFERENCES);
assertThat(refs.size(), is(1));
assertThat(refs, hasItem(col1Node));
}
@Test
public void shouldParseUnnamedUniqueConstraint() {
final AstNode col1Node = new AstNode(this.rootNode, "col1");
final String content = "UNIQUE (col1)";
assertThat(this.parser.parseTableBodyConstraint(getTokens(content), this.rootNode), is(true));
assertThat(this.rootNode.getChildCount(), is(2)); // 1 column, 1 constraint
final List<AstNode> kids = this.rootNode.childrenWithName(CreateTableParser.UNIQUE_CONSTRAINT_PREFIX + "1");
assertThat(kids.size(), is(1)); // constraint node
final AstNode constraintNode = kids.get(0);
assertThat(constraintNode.getMixins(), hasItem(TeiidDdlLexicon.Constraint.TABLE_ELEMENT));
assertProperty(constraintNode, TeiidDdlLexicon.Constraint.TYPE, TeiidReservedWord.UNIQUE.toDdl());
// referenced columns
@SuppressWarnings( "unchecked" )
final List<AstNode> refs = (List<AstNode>)constraintNode.getProperty(TeiidDdlLexicon.Constraint.REFERENCES);
assertThat(refs.size(), is(1));
assertThat(refs, hasItem(col1Node));
}
@Test
public void shouldParseNamedAccessPatternConstraint() {
final AstNode col1Node = new AstNode(this.rootNode, "col1");
final AstNode col2Node = new AstNode(this.rootNode, "col2");
final String content = "CONSTRAINT ap_1 ACCESSPATTERN (col1, col2)";
assertThat(this.parser.parseTableBodyConstraint(getTokens(content), this.rootNode), is(true));
assertThat(this.rootNode.getChildCount(), is(3)); // 2 columns, 1 constraint
final List<AstNode> kids = this.rootNode.childrenWithName("ap_1");
assertThat(kids.size(), is(1)); // constraint node
final AstNode constraintNode = kids.get(0);
assertThat(constraintNode.getMixins(), hasItem(TeiidDdlLexicon.Constraint.TABLE_ELEMENT));
assertProperty(constraintNode, TeiidDdlLexicon.Constraint.TYPE, TeiidNonReservedWord.ACCESSPATTERN.toDdl());
// referenced columns
@SuppressWarnings( "unchecked" )
final List<AstNode> refs = (List<AstNode>)constraintNode.getProperty(TeiidDdlLexicon.Constraint.REFERENCES);
assertThat(refs.size(), is(2));
assertThat(refs, hasItems(col1Node, col2Node));
}
@Test
public void shouldParseUnnamedAccessPatternConstraint() {
final AstNode col1Node = new AstNode(this.rootNode, "col1");
final AstNode col2Node = new AstNode(this.rootNode, "col2");
final String content = "ACCESSPATTERN (col1, col2)";
assertThat(this.parser.parseTableBodyConstraint(getTokens(content), this.rootNode), is(true));
assertThat(this.rootNode.getChildCount(), is(3)); // 2 columns, 1 constraint
final List<AstNode> kids = this.rootNode.childrenWithName(CreateTableParser.ACCESS_PATTERN_PREFIX + "1");
assertThat(kids.size(), is(1)); // constraint node
final AstNode constraintNode = kids.get(0);
assertThat(constraintNode.getMixins(), hasItem(TeiidDdlLexicon.Constraint.TABLE_ELEMENT));
assertProperty(constraintNode, TeiidDdlLexicon.Constraint.TYPE, TeiidNonReservedWord.ACCESSPATTERN.toDdl());
// referenced columns
@SuppressWarnings( "unchecked" )
final List<AstNode> refs = (List<AstNode>)constraintNode.getProperty(TeiidDdlLexicon.Constraint.REFERENCES);
assertThat(refs.size(), is(2));
assertThat(refs, hasItems(col1Node, col2Node));
}
@Test
public void shouldParseNamedForeignKeyConstraintWithReferencesRefs() {
final AstNode tableNode = new AstNode(this.rootNode, "tableWithForeignKey");
final String col1 = "col1";
final String col2 = "col2";
final AstNode col1Node = new AstNode(tableNode, col1);
final AstNode col2Node = new AstNode(tableNode, col2);
final String refTable = "refTable";
final AstNode refTableNode = new AstNode(this.rootNode, refTable);
refTableNode.setProperty(JcrConstants.JCR_PRIMARY_TYPE, TeiidDdlLexicon.CreateTable.TABLE_STATEMENT);
final String refCol1 = "refCol1";
final String refCol2 = "refCol2";
final AstNode refCol1Node = new AstNode(refTableNode, refCol1);
final AstNode refCol2Node = new AstNode(refTableNode, refCol2);
final String name = "fk_1";
final String content = "CONSTRAINT " + name + " FOREIGN KEY (" + col1 + ", " + col2 + ") REFERENCES " + refTable + '('
+ refCol1 + ',' + refCol2 + ')';
assertThat(this.parser.parseTableBodyConstraint(getTokens(content), tableNode), is(true));
assertThat(tableNode.getChildCount(), is(3)); // 2 columns, 1 constraint
final List<AstNode> kids = tableNode.childrenWithName(name);
assertThat(kids.size(), is(1)); // constraint node
final AstNode constraintNode = kids.get(0);
assertThat(constraintNode.getMixins(), hasItem(TeiidDdlLexicon.Constraint.FOREIGN_KEY_CONSTRAINT));
assertThat(constraintNode.getName(), is(name));
assertProperty(constraintNode, TeiidDdlLexicon.Constraint.TYPE, DdlConstants.FOREIGN_KEY);
assertProperty(constraintNode, TeiidDdlLexicon.Constraint.TABLE_REFERENCE, refTableNode);
{ // referenced columns
@SuppressWarnings( "unchecked" )
final List<AstNode> refs = (List<AstNode>)constraintNode.getProperty(TeiidDdlLexicon.Constraint.REFERENCES);
assertThat(refs.size(), is(2));
assertThat(refs, hasItems(col1Node, col2Node));
}
{ // references referenced columns
@SuppressWarnings( "unchecked" )
final List<AstNode> refRefs = (List<AstNode>)constraintNode.getProperty(TeiidDdlLexicon.Constraint.TABLE_REFERENCE_REFERENCES);
assertThat(refRefs.size(), is(2));
assertThat(refRefs, hasItems(refCol1Node, refCol2Node));
}
}
@Test
public void shouldParseNamedForeignKeyConstraintNoReferencesRefs() {
final AstNode tableNode = new AstNode(this.rootNode, "tableWithForeignKey");
final String col1 = "col1";
final String col2 = "col2";
final AstNode col1Node = new AstNode(tableNode, col1);
final AstNode col2Node = new AstNode(tableNode, col2);
final String refTable = "refTable";
final AstNode refTableNode = new AstNode(this.rootNode, refTable);
refTableNode.setProperty(JcrConstants.JCR_PRIMARY_TYPE, TeiidDdlLexicon.CreateTable.TABLE_STATEMENT);
final String name = "fk_1";
final String content = "CONSTRAINT " + name + " FOREIGN KEY (" + col1 + ", " + col2 + ") REFERENCES " + refTable;
assertThat(this.parser.parseTableBodyConstraint(getTokens(content), tableNode), is(true));
assertThat(tableNode.getChildCount(), is(3)); // 2 columns, 1 constraint
final List<AstNode> kids = tableNode.childrenWithName(name);
assertThat(kids.size(), is(1)); // constraint node
final AstNode constraintNode = kids.get(0);
assertThat(constraintNode.getMixins(), hasItem(TeiidDdlLexicon.Constraint.FOREIGN_KEY_CONSTRAINT));
assertThat(constraintNode.getName(), is(name));
assertProperty(constraintNode, TeiidDdlLexicon.Constraint.TYPE, DdlConstants.FOREIGN_KEY);
assertProperty(constraintNode, TeiidDdlLexicon.Constraint.TABLE_REFERENCE, refTableNode);
{ // referenced columns
@SuppressWarnings( "unchecked" )
final List<AstNode> refs = (List<AstNode>)constraintNode.getProperty(TeiidDdlLexicon.Constraint.REFERENCES);
assertThat(refs.size(), is(2));
assertThat(refs, hasItems(col1Node, col2Node));
}
{ // references referenced columns
@SuppressWarnings( "unchecked" )
final List<AstNode> refRefs = (List<AstNode>)constraintNode.getProperty(TeiidDdlLexicon.Constraint.TABLE_REFERENCE_REFERENCES);
assertThat(refRefs, is(nullValue()));
}
}
// ********* parse query expression tests ***********
@Test
public void shouldParseQueryExpression() {
final String content = "WITH X (Y, Z) AS (SELECT 1, 2)";
assertThat(this.parser.parseQueryExpression(getTokens(content), this.rootNode), is(true));
assertProperty(this.rootNode, TeiidDdlLexicon.CreateTable.QUERY_EXPRESSION, content);
}
@Test
public void shouldNotParseEmptyQueryExpression() {
assertThat(this.parser.parseQueryExpression(getTokens(""), this.rootNode), is(false));
}
// ********* parse identifier list tests ***********
@Test( expected = ParsingException.class )
public void shouldNotParseEmptyIdentifierList() {
final String content = "()";
this.parser.parseIdentifierList(getTokens(content));
}
@Test
public void shouldParseIdentifierListWithOneElement() {
final String id = "a";
final String content = '(' + id + ')';
final List<String> idList = this.parser.parseIdentifierList(getTokens(content));
assertThat(idList.size(), is(1));
assertThat(idList.get(0), is(id));
}
@Test
public void shouldParseIdentifierListWithMultipleElements() {
final String a = "a";
final String b = "b";
final String c = "c";
final String content = '(' + a + ',' + b + ',' + c + ')';
final List<String> idList = this.parser.parseIdentifierList(getTokens(content));
assertThat(idList.size(), is(3));
assertThat(idList.get(0), is(a));
assertThat(idList.get(1), is(b));
assertThat(idList.get(2), is(c));
}
@Test
public void shouldParseExpressionLists() {
assertThat(CreateTableParser.contains("UPPER(e2)", "e2"), is(true));
assertThat(CreateTableParser.contains("UPPER(e2)", "E2"), is(true));
assertThat(CreateTableParser.contains("UPPER(e1, e2)", "e3"), is(false));
assertThat(CreateTableParser.contains("abc, def", "def"), is(true));
assertThat(CreateTableParser.contains("abc, def", "DEF"), is(true));
}
//
// @Test
// public void shouldTestWhitespace() {
// final String prevValue = "a";
// final int currCol = 3;
// final int prevCol = 5;
// final int currLine = 5;
// final int prevLine = 4;
//
// final Position curr = new Position(currCol-1, currLine, currCol);
// final Position prev = new Position(prevCol-1, prevLine, prevCol);
// assertThat(getParser().getWhitespace(curr, prev, prevValue), is("\n "));
// }
}