package org.teiid.query.parser;
/*
* JBoss, Home of Professional Open Source.
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership. Some portions may be licensed
* to Red Hat, Inc. under one or more contributor license agreements.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*/
import static org.junit.Assert.*;
import java.io.StringReader;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.junit.Ignore;
import org.junit.Test;
import org.teiid.adminapi.impl.ModelMetaData;
import org.teiid.adminapi.impl.VDBMetaData;
import org.teiid.metadata.BaseColumn.NullType;
import org.teiid.metadata.*;
import org.teiid.metadata.Column.SearchType;
import org.teiid.metadata.Grant.Permission;
import org.teiid.metadata.Grant.Permission.Privilege;
import org.teiid.metadata.Table.TriggerEvent;
import org.teiid.query.function.SystemFunctionManager;
import org.teiid.query.metadata.CompositeMetadataStore;
import org.teiid.query.metadata.DatabaseStore;
import org.teiid.query.metadata.DatabaseStore.Mode;
import org.teiid.query.metadata.DatabaseUtil;
import org.teiid.query.metadata.MetadataValidator;
import org.teiid.query.metadata.SystemMetadata;
import org.teiid.query.metadata.TransformationMetadata;
import org.teiid.query.validator.ValidatorReport;
//import static org.junit.Assert.*;
@SuppressWarnings("nls")
public class TestDDLParser {
@Test
public void testForeignTable() throws Exception {
String ddl = "CREATE FOREIGN TABLE G1(\n" +
"e1 integer primary key,\n" +
"e2 varchar(10) unique,\n" +
"e3 date not null unique,\n" +
"e4 decimal(12,3) default 12.2 options (searchable 'unsearchable'),\n" +
"e5 integer auto_increment INDEX OPTIONS (UUID 'uuid', NAMEINSOURCE 'nis', SELECTABLE 'NO'),\n" +
"e6 varchar index default 'hello')\n" +
"OPTIONS (CARDINALITY 12, UUID 'uuid2', UPDATABLE 'true', FOO 'BAR', ANNOTATION 'Test Table')";
Schema s = helpParse(ddl, "model").getSchema();
Map<String, Table> tableMap = s.getTables();
assertTrue("Table not found", tableMap.containsKey("G1"));
Table table = tableMap.get("G1");
assertTrue(table.isPhysical());
assertFalse(table.isVirtual());
assertFalse(table.isSystem());
assertFalse(table.isMaterialized());
assertFalse(table.isDeletePlanEnabled());
assertEquals("uuid2", table.getUUID());
assertEquals(12, table.getCardinality());
assertTrue(table.supportsUpdate());
assertEquals("BAR", table.getProperties().get("FOO"));
assertEquals("Test Table", table.getAnnotation());
assertEquals(6, table.getColumns().size());
List<Column> columns = table.getColumns();
Column e1 = columns.get(0);
Column e2 = columns.get(1);
Column e3 = columns.get(2);
Column e4 = columns.get(3);
Column e5 = columns.get(4);
Column e6 = columns.get(5);
assertEquals("e1", e1.getName());
assertEquals("integer", e1.getDatatype().getName());
assertEquals("primary key not same", e1, table.getPrimaryKey().getColumns().get(0));
assertEquals("e2", e2.getName());
assertEquals("string", e2.getDatatype().getName());
assertEquals("unique", e2, table.getUniqueKeys().get(0).getColumns().get(0));
assertEquals(NullType.Nullable, e2.getNullType());
assertEquals(10, e2.getLength());
assertEquals(0, e2.getPrecision());
assertEquals("e3", e3.getName());
assertEquals("date", e3.getDatatype().getName());
assertEquals("unique", e3, table.getUniqueKeys().get(1).getColumns().get(0));
assertEquals(NullType.No_Nulls, e3.getNullType());
assertEquals("e4", e4.getName());
assertEquals("bigdecimal", e4.getDatatype().getName());
assertEquals(false, e4.isAutoIncremented());
assertEquals(12, e4.getPrecision());
assertEquals(3, e4.getScale());
assertEquals(SearchType.Unsearchable, e4.getSearchType());
assertEquals("12.2", e4.getDefaultValue());
assertEquals("e5", e5.getName());
assertEquals("integer", e5.getDatatype().getName());
assertEquals(true, e5.isAutoIncremented());
assertEquals("uuid", e5.getUUID());
assertEquals("nis", e5.getNameInSource());
assertEquals(false, e5.isSelectable());
assertEquals("index", e5, table.getIndexes().get(0).getColumns().get(0));
assertEquals("e6", e6.getName());
assertEquals("string", e6.getDatatype().getName());
assertEquals("index", e6, table.getIndexes().get(1).getColumns().get(0));
assertEquals("hello", e6.getDefaultValue());
}
@Test(expected=MetadataException.class)
public void testZeroPrecision() throws Exception {
String ddl = "CREATE FOREIGN TABLE G1(e4 decimal(0))";
helpParse(ddl, "model").getSchema();
}
@Test
public void testDefaultPrecision() throws Exception {
String ddl = "CREATE FOREIGN TABLE G1(e4 decimal)";
Schema s = helpParse(ddl, "model").getSchema();
Map<String, Table> tableMap = s.getTables();
assertTrue("Table not found", tableMap.containsKey("G1"));
Table table = tableMap.get("G1");
Column e4 = table.getColumns().get(0);
assertEquals("e4", e4.getName());
assertEquals("bigdecimal", e4.getDatatype().getName());
assertEquals(false, e4.isAutoIncremented());
assertEquals(Short.MAX_VALUE, e4.getPrecision());
assertEquals(Short.MAX_VALUE/2, e4.getScale());
assertEquals(SearchType.Searchable, e4.getSearchType());
}
@Test(expected=MetadataException.class)
public void testDuplicatePrimarykey() throws Exception {
QueryParser parser = new QueryParser();
String ddl = "CREATE FOREIGN TABLE G1( e1 integer primary key, e2 varchar primary key)";
MetadataStore mds = new MetadataStore();
MetadataFactory mf = new MetadataFactory("x", 1, "model", getDataTypes(), new Properties(), null);
parser.parseDDL(mf, ddl);
mf.mergeInto(mds);
}
@Test public void testAutoIncrementPrimarykey() throws Exception {
QueryParser parser = new QueryParser();
String ddl = "CREATE FOREIGN TABLE G1( e1 integer auto_increment primary key, e2 varchar)";
MetadataStore mds = new MetadataStore();
MetadataFactory mf = new MetadataFactory("x", 1, "model", getDataTypes(), new Properties(), null);
parser.parseDDL(mf, ddl);
mf.mergeInto(mds);
}
@Test
public void testUDT() throws Exception {
String ddl = "CREATE FOREIGN TABLE G1( e1 integer, e2 varchar OPTIONS (UDT 'NMTOKENS(12,13,11)'))";
Schema s = helpParse(ddl, "model").getSchema();
Map<String, Table> tableMap = s.getTables();
assertTrue("Table not found", tableMap.containsKey("G1"));
Table table = tableMap.get("G1");
assertEquals("NMTOKENS", table.getColumns().get(1).getDatatype().getName());
assertEquals(12, table.getColumns().get(1).getLength());
assertEquals(13, table.getColumns().get(1).getPrecision());
assertEquals(11, table.getColumns().get(1).getScale());
}
@Test public void testFBI() throws Exception {
String ddl = "CREATE FOREIGN TABLE G1(e1 integer, e2 varchar, CONSTRAINT fbi INDEX (UPPER(e2)))";
Schema s = helpParse(ddl, "model").getSchema();
Map<String, Table> tableMap = s.getTables();
Table table = tableMap.get("G1");
assertEquals(1, table.getFunctionBasedIndexes().size());
}
@Test
public void testMultiKeyPK() throws Exception {
String ddl = "CREATE FOREIGN TABLE G1( e1 integer, e2 varchar, e3 date, PRIMARY KEY (e1, e2))";
Schema s = helpParse(ddl, "model").getSchema();
Map<String, Table> tableMap = s.getTables();
assertTrue("Table not found", tableMap.containsKey("G1"));
Table table = tableMap.get("G1");
assertEquals(table.getColumns().subList(0, 2), table.getPrimaryKey().getColumns());
}
@Test
public void testOptionsKey() throws Exception {
String ddl = "CREATE FOREIGN TABLE G1( e1 integer, e2 varchar, e3 date, UNIQUE (e1) OPTIONS (CUSTOM_PROP 'VALUE'))";
Schema s = helpParse(ddl, "model").getSchema();
Map<String, Table> tableMap = s.getTables();
assertTrue("Table not found", tableMap.containsKey("G1"));
Table table = tableMap.get("G1");
KeyRecord record = table.getAllKeys().iterator().next();
assertEquals("VALUE", record.getProperty("CUSTOM_PROP", false));
}
@Test
public void testConstraints() throws Exception {
String ddl = "CREATE FOREIGN TABLE G1( e1 integer, e2 varchar, e3 date, " +
" PRIMARY KEY (e1, e2), INDEX(e2, e3), ACCESSPATTERN(e1), UNIQUE(e1)," +
" ACCESSPATTERN(e2, e3))";
Schema s = helpParse(ddl, "model").getSchema();
Map<String, Table> tableMap = s.getTables();
assertTrue("Table not found", tableMap.containsKey("G1"));
Table table = tableMap.get("G1");
assertEquals(table.getColumns().subList(0, 2), table.getPrimaryKey().getColumns());
assertEquals(table.getColumns().subList(1, 3), table.getIndexes().get(0).getColumns());
assertEquals(table.getColumns().subList(0, 1), table.getUniqueKeys().get(0).getColumns());
assertEquals(2, table.getAccessPatterns().size());
assertEquals(table.getColumns().subList(0, 1), table.getAccessPatterns().get(0).getColumns());
assertEquals(table.getColumns().subList(1, 3), table.getAccessPatterns().get(1).getColumns());
}
@Test
public void testConstraints2() throws Exception {
String ddl = "CREATE FOREIGN TABLE G1( e1 integer, e2 varchar, e3 date, " +
"ACCESSPATTERN(e1), UNIQUE(e1), ACCESSPATTERN(e2, e3))";
Schema s = helpParse(ddl, "model").getSchema();
Map<String, Table> tableMap = s.getTables();
assertTrue("Table not found", tableMap.containsKey("G1"));
Table table = tableMap.get("G1");
assertEquals(table.getColumns().subList(0, 1), table.getUniqueKeys().get(0).getColumns());
assertEquals(2, table.getAccessPatterns().size());
assertEquals(table.getColumns().subList(0, 1), table.getAccessPatterns().get(0).getColumns());
assertEquals(table.getColumns().subList(1, 3), table.getAccessPatterns().get(1).getColumns());
}
@Test(expected=MetadataException.class)
public void testWrongPrimarykey() throws Exception {
QueryParser parser = new QueryParser();
String ddl = "CREATE FOREIGN TABLE G1( e1 integer, e2 varchar, PRIMARY KEY (e3))";
MetadataStore mds = new MetadataStore();
MetadataFactory mf = new MetadataFactory("x", 1, "model", getDataTypes(), new Properties(), null);
parser.parseDDL(mf, ddl);
mf.mergeInto(mds);
}
@Test
public void testFK() throws Exception {
String ddl = "CREATE FOREIGN TABLE G1(g1e1 integer, g1e2 varchar, PRIMARY KEY(g1e1, g1e2));\n" +
"CREATE FOREIGN TABLE G2( g2e1 integer, g2e2 varchar, " +
"FOREIGN KEY (g2e1, g2e2) REFERENCES G1 (g1e1, g1e2) options (\"teiid_rel:allow-join\" true))";
Schema s = helpParse(ddl, "model").getSchema();
Map<String, Table> tableMap = s.getTables();
assertEquals(2, tableMap.size());
assertTrue("Table not found", tableMap.containsKey("G1"));
assertTrue("Table not found", tableMap.containsKey("G2"));
Table table = tableMap.get("G2");
ForeignKey fk = table.getForeignKeys().get(0);
assertEquals(Boolean.TRUE.toString(), fk.getProperty(ForeignKey.ALLOW_JOIN, false));
assertEquals(fk.getColumns(), table.getColumns());
assertEquals("G1", fk.getReferenceTableName());
}
@Test
public void testOptionalFK() throws Exception {
String ddl = "CREATE FOREIGN TABLE G1(g1e1 integer, g1e2 varchar, PRIMARY KEY(g1e1, g1e2));\n" +
"CREATE FOREIGN TABLE G2( g2e1 integer, g2e2 varchar, PRIMARY KEY(g2e1, g2e2)," +
"FOREIGN KEY (g2e1, g2e2) REFERENCES G1)";
MetadataFactory s = helpParse(ddl, "model");
Map<String, Table> tableMap = s.getSchema().getTables();
assertEquals(2, tableMap.size());
assertTrue("Table not found", tableMap.containsKey("G1"));
assertTrue("Table not found", tableMap.containsKey("G2"));
Table table = tableMap.get("G2");
ForeignKey fk = table.getForeignKeys().get(0);
assertEquals(fk.getColumns(), table.getColumns());
assertEquals("G1", fk.getReferenceTableName());
VDBMetaData vdb = new VDBMetaData();
vdb.setName("myVDB"); //$NON-NLS-1$
ModelMetaData modelOne = new ModelMetaData();
modelOne.setName("model"); //$NON-NLS-1$
vdb.addModel(modelOne);
ValidatorReport report = new MetadataValidator().validate(vdb, s.asMetadataStore());
assertFalse(report.hasItems());
assertEquals(fk.getPrimaryKey().getColumns(), tableMap.get("G1").getColumns());
}
@Test
public void testOptionalFKFail() throws Exception {
String ddl = "CREATE FOREIGN TABLE G1(g1e1 integer, g1e2 varchar);\n" +
"CREATE FOREIGN TABLE G2( g2e1 integer, g2e2 varchar, PRIMARY KEY(g2e1, g2e2)," +
"FOREIGN KEY (g2e1, g2e2) REFERENCES G1)";
MetadataFactory s = helpParse(ddl, "model");
Map<String, Table> tableMap = s.getSchema().getTables();
assertEquals(2, tableMap.size());
assertTrue("Table not found", tableMap.containsKey("G1"));
assertTrue("Table not found", tableMap.containsKey("G2"));
Table table = tableMap.get("G2");
ForeignKey fk = table.getForeignKeys().get(0);
assertEquals(fk.getColumns(), table.getColumns());
assertEquals("G1", fk.getReferenceTableName());
VDBMetaData vdb = new VDBMetaData();
vdb.setName("myVDB"); //$NON-NLS-1$
ModelMetaData modelOne = new ModelMetaData();
modelOne.setName("model"); //$NON-NLS-1$
vdb.addModel(modelOne);
ValidatorReport report = new MetadataValidator().validate(vdb, s.asMetadataStore());
assertTrue(report.hasItems());
}
@Test
public void testFKAccrossSchemas() throws Exception {
String ddl = "CREATE FOREIGN TABLE G1(g1e1 integer, g1e2 varchar, PRIMARY KEY(g1e1, g1e2));\n";
String ddl2 = "CREATE FOREIGN TABLE G2( g2e1 integer, g2e2 varchar, PRIMARY KEY(g2e1, g2e2)," +
"FOREIGN KEY (g2e1, g2e2) REFERENCES model.G1)";
MetadataFactory f1 = helpParse(ddl, "model");
MetadataFactory f2 = helpParse(ddl2, "model2");
VDBMetaData vdb = new VDBMetaData();
vdb.setName("myVDB"); //$NON-NLS-1$
ModelMetaData modelOne = new ModelMetaData();
modelOne.setName("model"); //$NON-NLS-1$
vdb.addModel(modelOne);
ModelMetaData modelTwo = new ModelMetaData();
modelTwo.setName("model2"); //$NON-NLS-1$
vdb.addModel(modelTwo);
MetadataStore s = f1.asMetadataStore();
f2.mergeInto(s);
ValidatorReport report = new MetadataValidator().validate(vdb, s);
assertFalse(report.hasItems());
Table table = s.getSchema("model2").getTable("G2");
ForeignKey fk = table.getForeignKeys().get(0);
assertEquals(fk.getColumns(), table.getColumns());
assertEquals("G1", fk.getReferenceTableName());
assertEquals(fk.getPrimaryKey().getColumns(), s.getSchema("model").getTable("G1").getColumns());
}
@Test(expected=MetadataException.class)
public void testTableWithPlan() throws Exception {
QueryParser parser = new QueryParser();
String ddl = "CREATE foreign table G1 as select 1";
MetadataStore mds = new MetadataStore();
MetadataFactory mf = new MetadataFactory("x", 1, "model", getDataTypes(), new Properties(), null);
parser.parseDDL(mf,ddl);
mf.mergeInto(mds);
}
@Test
public void testViewWithoutColumns() throws Exception {
QueryParser parser = new QueryParser();
MetadataStore mds = new MetadataStore();
MetadataFactory mf = new MetadataFactory("x", 1, "VM1", getDataTypes(), new Properties(), null);
parser.parseDDL(mf,"CREATE VIEW V1 AS SELECT * FROM PM1.G1");
mf.mergeInto(mds);
}
@Test
public void testMultipleCommands() throws Exception {
String ddl = "CREATE VIEW V1 AS SELECT * FROM PM1.G1; " +
"CREATE PROCEDURE FOO(P1 integer) RETURNS (e1 integer, e2 varchar) AS SELECT * FROM PM1.G1;";
Schema s = helpParse(ddl, "model").getSchema();
Map<String, Table> tableMap = s.getTables();
Table table = tableMap.get("V1");
assertNotNull(table);
assertEquals("SELECT * FROM PM1.G1", table.getSelectTransformation());
Map<String, Procedure> procedureMap = s.getProcedures();
Procedure p = procedureMap.get("FOO");
assertNotNull(p);
assertEquals("SELECT * FROM PM1.G1;", p.getQueryPlan());
}
@Test
public void testMultipleCommands2() throws Exception {
String ddl = " CREATE VIRTUAL PROCEDURE getTweets(query varchar) RETURNS (created_on varchar(25), from_user varchar(25), to_user varchar(25), \n" +
" profile_image_url varchar(25), source varchar(25), text varchar(140)) AS \n" +
" select tweet.* from \n" +
" (call twitter.invokeHTTP(action => 'GET', endpoint =>querystring('',query as \"q\"))) w, \n" +
" XMLTABLE('results' passing JSONTOXML('myxml', w.result) columns \n" +
" created_on string PATH 'created_at', \n" +
" from_user string PATH 'from_user',\n" +
" to_user string PATH 'to_user', \n" +
" profile_image_url string PATH 'profile_image_url', \n" +
" source string PATH 'source', \n" +
" text string PATH 'text') tweet;" +
" CREATE VIEW Tweet AS select * FROM twitterview.getTweets;";
Schema s = helpParse(ddl, "model").getSchema();
Map<String, Table> tableMap = s.getTables();
Table table = tableMap.get("Tweet");
assertNotNull(table);
Map<String, Procedure> procedureMap = s.getProcedures();
Procedure p = procedureMap.get("getTweets");
assertNotNull(p);
}
@Test
public void testView() throws Exception {
String ddl = "CREATE View G1( e1 integer, e2 varchar) OPTIONS (CARDINALITY 12) AS select e1, e2 from foo.bar";
Schema s = helpParse(ddl, "model").getSchema();
Map<String, Table> tableMap = s.getTables();
Table table = tableMap.get("G1");
assertEquals("SELECT e1, e2 FROM foo.bar", table.getSelectTransformation());
assertEquals(12, table.getCardinality());
}
@Test
public void testPushdownFunctionNoArgs() throws Exception {
String ddl = "CREATE FOREIGN FUNCTION SourceFunc() RETURNS integer OPTIONS (UUID 'hello world')";
Schema s = helpParse(ddl, "model").getSchema();
FunctionMethod fm = s.getFunction("hello world");
assertNotNull(fm);
assertEquals("integer", fm.getOutputParameter().getType());
assertEquals(FunctionMethod.PushDown.MUST_PUSHDOWN, fm.getPushdown());
}
@Test(expected=org.teiid.metadata.ParseException.class)
public void testDuplicateFunctions() throws Exception {
String ddl = "CREATE FUNCTION SourceFunc() RETURNS integer; CREATE FUNCTION SourceFunc() RETURNS string";
helpParse(ddl, "model");
}
@Test(expected=org.teiid.metadata.ParseException.class)
public void testDuplicateFunctions1() throws Exception {
String ddl = "CREATE FUNCTION SourceFunc() RETURNS string OPTIONS (UUID 'a'); CREATE FUNCTION SourceFunc1() RETURNS string OPTIONS (UUID 'a')";
helpParse(ddl, "model");
}
@Test()
public void testDuplicateFunctions2() throws Exception {
String ddl = "CREATE FUNCTION SourceFunc() RETURNS string; CREATE FUNCTION SourceFunc(param string) RETURNS string";
helpParse(ddl, "model");
}
@Test
public void testUDF() throws Exception {
String ddl = "CREATE VIRTUAL FUNCTION SourceFunc(flag boolean, msg varchar) RETURNS varchar " +
"OPTIONS(CATEGORY 'misc', DETERMINISM 'DETERMINISTIC', " +
"\"NULL-ON-NULL\" 'true', JAVA_CLASS 'foo', JAVA_METHOD 'bar', RANDOM 'any', UUID 'x')";
Schema s = helpParse(ddl, "model").getSchema();
FunctionMethod fm = s.getFunction("x");
assertNotNull(fm);
assertEquals("string", fm.getOutputParameter().getType());
assertEquals(FunctionMethod.PushDown.CAN_PUSHDOWN, fm.getPushdown());
assertEquals(2, fm.getInputParameterCount());
assertEquals("flag", fm.getInputParameters().get(0).getName());
assertEquals("boolean", fm.getInputParameters().get(0).getType());
assertEquals("msg", fm.getInputParameters().get(1).getName());
assertEquals("string", fm.getInputParameters().get(1).getType());
assertFalse( fm.getInputParameters().get(1).isVarArg());
assertEquals(FunctionMethod.Determinism.DETERMINISTIC, fm.getDeterminism());
assertEquals("misc", fm.getCategory());
assertEquals(true, fm.isNullOnNull());
assertEquals("foo", fm.getInvocationClass());
assertEquals("bar", fm.getInvocationMethod());
assertEquals("any", fm.getProperties().get("RANDOM"));
}
@Test
public void testUDAggregate() throws Exception {
String ddl = "CREATE VIRTUAL FUNCTION SourceFunc(flag boolean, msg varchar) RETURNS varchar " +
"OPTIONS(CATEGORY 'misc', AGGREGATE 'true', \"allows-distinct\" 'true', UUID 'y')";
Schema s = helpParse(ddl, "model").getSchema();
FunctionMethod fm = s.getFunction("y");
assertNotNull(fm);
assertEquals("string", fm.getOutputParameter().getType());
assertEquals(FunctionMethod.PushDown.CAN_PUSHDOWN, fm.getPushdown());
assertEquals(2, fm.getInputParameterCount());
assertEquals("flag", fm.getInputParameters().get(0).getName());
assertEquals("boolean", fm.getInputParameters().get(0).getType());
assertEquals("msg", fm.getInputParameters().get(1).getName());
assertEquals("string", fm.getInputParameters().get(1).getType());
assertFalse( fm.getInputParameters().get(1).isVarArg());
assertNotNull(fm.getAggregateAttributes());
assertTrue(fm.getAggregateAttributes().allowsDistinct());
assertEquals(FunctionMethod.Determinism.DETERMINISTIC, fm.getDeterminism());
assertEquals("misc", fm.getCategory());
assertFalse(fm.isNullOnNull());
}
@Test
public void testVarArgs() throws Exception {
String ddl = "CREATE FUNCTION SourceFunc(flag boolean) RETURNS varchar options (varargs 'true', UUID 'z')";
Schema s = helpParse(ddl, "model").getSchema();
FunctionMethod fm = s.getFunction("z");
assertTrue( fm.getInputParameters().get(0).isVarArg());
}
@Test public void testMixedCaseTypes() throws Exception {
String ddl = "CREATE FUNCTION SourceFunc(flag Boolean) RETURNS varchaR options (UUID 'z')";
Schema s = helpParse(ddl, "model").getSchema();
FunctionMethod fm = s.getFunction("z");
assertEquals("boolean", fm.getInputParameters().get(0).getType());
}
@Test(expected=MetadataException.class) public void testInvalidFunctionBody() throws Exception {
String ddl = "CREATE FOREIGN FUNCTION SourceFunc(flag boolean) RETURNS varchar AS SELECT 'a';";
Schema s = helpParse(ddl, "model").getSchema();
FunctionMethod fm = s.getFunction("z");
assertTrue( fm.getInputParameters().get(0).isVarArg());
}
@Test(expected=MetadataException.class) public void testInvalidProcedureBody() throws Exception {
String ddl = "CREATE FOREIGN PROCEDURE SourceFunc(flag boolean) RETURNS varchar AS SELECT 'a';";
Schema s = helpParse(ddl, "model").getSchema();
FunctionMethod fm = s.getFunction("z");
assertTrue( fm.getInputParameters().get(0).isVarArg());
}
@Test
public void testVirtualProcedure() throws Exception {
String ddl = "CREATE VIRTUAL PROCEDURE myProc(OUT p1 boolean, p2 varchar, INOUT p3 decimal) " +
"RETURNS (r1 varchar, r2 decimal) " +
"OPTIONS(RANDOM 'any', UUID 'uuid', NAMEINSOURCE 'nis', ANNOTATION 'desc', UPDATECOUNT '2') " +
"AS /*+ cache */ BEGIN select * from foo; END";
Schema s = helpParse(ddl, "model").getSchema();
Procedure proc = s.getProcedure("myProc");
assertNotNull(proc);
assertTrue(proc.isVirtual());
assertFalse(proc.isFunction());
assertEquals(3, proc.getParameters().size());
assertEquals("p1", proc.getParameters().get(0).getName());
assertEquals("boolean", proc.getParameters().get(0).getDatatype().getName());
assertEquals(ProcedureParameter.Type.Out, proc.getParameters().get(0).getType());
assertEquals("p2", proc.getParameters().get(1).getName());
assertEquals("string", proc.getParameters().get(1).getDatatype().getName());
assertEquals(ProcedureParameter.Type.In, proc.getParameters().get(1).getType());
assertEquals("p3", proc.getParameters().get(2).getName());
assertEquals("bigdecimal", proc.getParameters().get(2).getDatatype().getName());
assertEquals(ProcedureParameter.Type.InOut, proc.getParameters().get(2).getType());
ColumnSet<Procedure> ret = proc.getResultSet();
assertNotNull(ret);
assertEquals(2, ret.getColumns().size());
assertEquals("r1", ret.getColumns().get(0).getName());
assertEquals("string", ret.getColumns().get(0).getDatatype().getName());
assertEquals("r2", ret.getColumns().get(1).getName());
assertEquals("bigdecimal", ret.getColumns().get(1).getDatatype().getName());
assertEquals("uuid", proc.getUUID());
assertEquals("nis", proc.getNameInSource());
assertEquals("desc", proc.getAnnotation());
assertEquals(2, proc.getUpdateCount());
assertEquals("any", proc.getProperties().get("RANDOM"));
assertEquals("/*+ cache */ BEGIN\nSELECT * FROM foo;\nEND", proc.getQueryPlan());
}
@Test
public void testInsteadOfTrigger() throws Exception {
String ddl = "CREATE VIEW G1( e1 integer, e2 varchar) AS select * from foo;" +
"CREATE TRIGGER ON G1 INSTEAD OF INSERT AS " +
"FOR EACH ROW \n" +
"BEGIN ATOMIC \n" +
"insert into g1 (e1, e2) values (1, 'trig');\n" +
"END;" +
"CREATE View G2( e1 integer, e2 varchar) AS select * from foo;";
Schema s = helpParse(ddl, "model").getSchema();
Map<String, Table> tableMap = s.getTables();
assertTrue("Table not found", tableMap.containsKey("G1"));
assertTrue("Table not found", tableMap.containsKey("G2"));
assertEquals("FOR EACH ROW\nBEGIN ATOMIC\nINSERT INTO g1 (e1, e2) VALUES (1, 'trig');\nEND", s.getTable("G1").getInsertPlan());
}
@Test
public void testInsteadOfTriggerIsDistinct() throws Exception {
String ddl = "CREATE VIEW G1( e1 integer, e2 varchar) AS select * from foo;" +
"CREATE TRIGGER ON G1 INSTEAD OF UPDATE AS " +
"FOR EACH ROW \n" +
"BEGIN ATOMIC \n" +
"if (\"new\" is not distinct from \"old\") raise sqlexception 'error';\n" +
"END;";
Schema s = helpParse(ddl, "model").getSchema();
assertEquals("FOR EACH ROW\nBEGIN ATOMIC\nIF(\"new\" IS NOT DISTINCT FROM \"old\")\nBEGIN\nRAISE SQLEXCEPTION 'error';\nEND\nEND", s.getTable("G1").getUpdatePlan());
}
@Test(expected=MetadataException.class)
public void testInsteadOfTriggerNoView() throws Exception {
String ddl = "CREATE TRIGGER ON G1 INSTEAD OF INSERT AS " +
"FOR EACH ROW \n" +
"BEGIN ATOMIC \n" +
"insert into g1 (e1, e2) values (1, 'trig');\n" +
"END;" +
"CREATE View G2( e1 integer, e2 varchar) AS select * from foo;";
helpParse(ddl, "model");
}
@Test
public void testSourceProcedure() throws Exception {
String ddl = "CREATE FOREIGN PROCEDURE myProc(OUT p1 boolean, p2 varchar, INOUT p3 decimal) " +
"RETURNS (r1 varchar, r2 decimal)" +
"OPTIONS(RANDOM 'any', UUID 'uuid', NAMEINSOURCE 'nis', ANNOTATION 'desc', UPDATECOUNT '2');";
Schema s = helpParse(ddl, "model").getSchema();
Procedure proc = s.getProcedure("myProc");
assertNotNull(proc);
assertFalse(proc.isVirtual());
assertFalse(proc.isFunction());
assertEquals(3, proc.getParameters().size());
assertEquals("p1", proc.getParameters().get(0).getName());
assertEquals("boolean", proc.getParameters().get(0).getDatatype().getName());
assertEquals(ProcedureParameter.Type.Out, proc.getParameters().get(0).getType());
assertEquals("p2", proc.getParameters().get(1).getName());
assertEquals("string", proc.getParameters().get(1).getDatatype().getName());
assertEquals(ProcedureParameter.Type.In, proc.getParameters().get(1).getType());
assertEquals("p3", proc.getParameters().get(2).getName());
assertEquals("bigdecimal", proc.getParameters().get(2).getDatatype().getName());
assertEquals(ProcedureParameter.Type.InOut, proc.getParameters().get(2).getType());
ColumnSet<Procedure> ret = proc.getResultSet();
assertNotNull(ret);
assertEquals(2, ret.getColumns().size());
assertEquals("r1", ret.getColumns().get(0).getName());
assertEquals("string", ret.getColumns().get(0).getDatatype().getName());
assertEquals("r2", ret.getColumns().get(1).getName());
assertEquals("bigdecimal", ret.getColumns().get(1).getDatatype().getName());
assertEquals("uuid", proc.getUUID());
assertEquals("nis", proc.getNameInSource());
assertEquals("desc", proc.getAnnotation());
assertEquals(2, proc.getUpdateCount());
assertEquals("any", proc.getProperties().get("RANDOM"));
}
@Test
public void testNamespace() throws Exception {
QueryParser parser = new QueryParser();
String ddl = "set namespace 'http://teiid.org' AS teiid";
MetadataStore mds = new MetadataStore();
MetadataFactory mf = new MetadataFactory("x", 1, "model", getDataTypes(), new Properties(), null);
parser.parseDDL(mf, ddl);
mf.mergeInto(mds);
assertTrue(mf.getNamespaces().keySet().contains("teiid"));
assertEquals("http://teiid.org", mf.getNamespaces().get("teiid"));
}
@Test
public void testReservedNamespace1() throws Exception {
QueryParser parser = new QueryParser();
String ddl = "set namespace 'http://www.teiid.org/translator/salesforce/2012' AS teiid_sf";
MetadataStore mds = new MetadataStore();
MetadataFactory mf = new MetadataFactory("x", 1, "model", getDataTypes(), new Properties(), null);
parser.parseDDL(mf, ddl);
mf.mergeInto(mds);
assertTrue(mf.getNamespaces().keySet().contains("teiid_sf"));
assertEquals("http://www.teiid.org/translator/salesforce/2012", mf.getNamespaces().get("teiid_sf"));
}
@Test(expected=MetadataException.class)
public void testReservedNamespaceURIWrong() throws Exception {
QueryParser parser = new QueryParser();
String ddl = "set namespace 'http://www.teiid.org/translator/salesforce/2013' AS teiid_sf";
MetadataStore mds = new MetadataStore();
MetadataFactory mf = new MetadataFactory("x", 1, "model", getDataTypes(), new Properties(), null);
parser.parseDDL(mf, ddl);
mf.mergeInto(mds);
assertTrue(mf.getNamespaces().keySet().contains("teiid_sf"));
assertEquals("http://www.teiid.org/translator/salesforce/2012", mf.getNamespaces().get("teiid_sf"));
}
@Test(expected=MetadataException.class)
public void testReservedNamespacePrefixMismatch() throws Exception {
QueryParser parser = new QueryParser();
String ddl = "set namespace 'http://www.teiid.org/translator/salesforce/2012' AS teiid_foo";
MetadataStore mds = new MetadataStore();
MetadataFactory mf = new MetadataFactory("x", 1, "model", getDataTypes(), new Properties(), null);
parser.parseDDL(mf, ddl);
mf.mergeInto(mds);
assertTrue(mf.getNamespaces().keySet().contains("teiid_foo"));
assertEquals("http://www.teiid.org/translator/salesforce/2012", mf.getNamespaces().get("teiid_foo"));
}
@Test
public void testReservedURIDifferentNS() throws Exception {
QueryParser parser = new QueryParser();
String ddl = "set namespace 'http://www.teiid.org/translator/salesforce/2012' AS ns";
MetadataStore mds = new MetadataStore();
MetadataFactory mf = new MetadataFactory("x", 1, "model", getDataTypes(), new Properties(), null);
parser.parseDDL(mf, ddl);
mf.mergeInto(mds);
assertTrue(mf.getNamespaces().keySet().contains("ns"));
assertEquals("http://www.teiid.org/translator/salesforce/2012", mf.getNamespaces().get("ns"));
}
public static MetadataFactory helpParse(String ddl, String model) {
MetadataFactory mf = new MetadataFactory("x", 1, model, getDataTypes(), new Properties(), null);
QueryParser.getQueryParser().parseDDL(mf, ddl);
return mf;
}
public static Database helpParse(String ddl) {
return helpParse(ddl, Mode.ANY);
}
public static Database helpParse(String ddl, DatabaseStore.Mode mode) {
final Map<String, Datatype> dataTypes = getDataTypes();
DatabaseStore store = new DatabaseStore() {
@Override
public Map<String, Datatype> getRuntimeTypes() {
return dataTypes;
}
@Override
public SystemFunctionManager getSystemFunctionManager() {
return new SystemFunctionManager();
}
@Override
protected TransformationMetadata getTransformationMetadata() {
Database database = getCurrentDatabase();
CompositeMetadataStore store = new CompositeMetadataStore(database.getMetadataStore());
//grants are already stored on the VDBMetaData
store.getGrants().clear();
return new TransformationMetadata(DatabaseUtil.convert(database), store, null,
getSystemFunctionManager().getSystemFunctions(), null);
}
};
store.startEditing(true);
store.setMode(mode);
QueryParser.getQueryParser().parseDDL(store, new StringReader(ddl));
store.stopEditing();
if (store.getDatabases().isEmpty()) {
return null;
}
return store.getDatabases().get(0);
}
public static Map<String, Datatype> getDataTypes() {
return SystemMetadata.getInstance().getRuntimeTypeMap();
}
@Test public void testKeyResolve() {
MetadataFactory mf = new MetadataFactory("x", 1, "foo", getDataTypes(), new Properties(), null);
mf.addNamespace("x", "http://x");
assertEquals("{http://x}z", MetadataFactory.resolvePropertyKey(mf, "x:z"));
assertEquals("y:z", MetadataFactory.resolvePropertyKey(mf, "y:z"));
}
@Test public void testCreateError() {
try {
helpParse("CREATE foreign FUNCTION convert(msg integer, type varchar) RETURNS varchar", "x");
fail();
} catch (org.teiid.metadata.ParseException e) {
assertEquals("TEIID30386 org.teiid.api.exception.query.QueryParserException: TEIID31100 Parsing error: Encountered \"CREATE foreign FUNCTION [*]convert[*](msg\" at line 1, column 25.\nWas expecting: id", e.getMessage());
}
}
@Test
public void testAlterTableAddOptions() throws Exception {
String ddl = "CREATE FOREIGN TABLE G1( e1 integer, e2 varchar, e3 date);" +
"ALTER FOREIGN TABLE G1 OPTIONS(ADD CARDINALITY 12);" +
"ALTER FOREIGN TABLE G1 OPTIONS(ADD FOO 'BAR');";
Schema s = helpParse(ddl, "model").getSchema();
Map<String, Table> tableMap = s.getTables();
assertTrue("Table not found", tableMap.containsKey("G1"));
Table table = tableMap.get("G1");
assertEquals(12, table.getCardinality());
assertEquals("BAR", table.getProperty("FOO", false));
}
@Test
public void testAlterTableModifyOptions() throws Exception {
String ddl = "CREATE FOREIGN TABLE G1( e1 integer, e2 varchar, e3 date) OPTIONS(CARDINALITY 12, FOO 'BAR');" +
"ALTER FOREIGN TABLE G1 OPTIONS(SET CARDINALITY 24);" +
"ALTER FOREIGN TABLE G1 OPTIONS(SET FOO 'BARBAR');";
Schema s = helpParse(ddl, "model").getSchema();
Map<String, Table> tableMap = s.getTables();
assertTrue("Table not found", tableMap.containsKey("G1"));
Table table = tableMap.get("G1");
assertEquals(24, table.getCardinality());
assertEquals("BARBAR", table.getProperty("FOO", false));
}
@Test
public void testAlterTableDropOptions() throws Exception {
String ddl = "CREATE FOREIGN TABLE G1( e1 integer, e2 varchar, e3 date) OPTIONS(CARDINALITY 12, FOO 'BAR');" +
"ALTER FOREIGN TABLE G1 OPTIONS(DROP CARDINALITY);" +
"ALTER FOREIGN TABLE G1 OPTIONS(DROP FOO);";
Schema s = helpParse(ddl, "model").getSchema();
Map<String, Table> tableMap = s.getTables();
assertTrue("Table not found", tableMap.containsKey("G1"));
Table table = tableMap.get("G1");
assertEquals(-1, table.getCardinality());
assertNull(table.getProperty("FOO", false));
}
@Test
public void testAlterTableAlterColumnType() throws Exception {
String ddl = "CREATE FOREIGN TABLE G1( e1 integer, e2 varchar, e3 date);" +
"ALTER FOREIGN TABLE G1 ALTER COLUMN e1 TYPE varchar(12);" +
"ALTER FOREIGN TABLE G1 ALTER COLUMN e2 TYPE serial;" +
"ALTER FOREIGN TABLE G1 ALTER COLUMN e3 TYPE integer not null auto_increment;";
Schema s = helpParse(ddl, "model").getSchema();
Map<String, Table> tableMap = s.getTables();
assertTrue("Table not found", tableMap.containsKey("G1"));
Table table = tableMap.get("G1");
Column e1 = table.getColumnByName("e1");
assertNotNull(e1);
assertEquals("string", e1.getRuntimeType());
assertEquals(NullType.Nullable, e1.getNullType());
Column e2 = table.getColumnByName("e2");
assertNotNull(e2);
assertEquals("integer", e2.getRuntimeType());
assertTrue(e2.isAutoIncremented());
assertEquals(NullType.No_Nulls, e2.getNullType());
Column e3 = table.getColumnByName("e3");
assertNotNull(e3);
assertEquals("integer", e3.getRuntimeType());
assertTrue(e3.isAutoIncremented());
assertEquals(NullType.No_Nulls, e3.getNullType());
}
@Test
public void testAlterTableRenameColumn() throws Exception {
String ddl = "CREATE FOREIGN TABLE G1( e1 integer, e2 varchar, e3 date);" +
"ALTER FOREIGN TABLE G1 RENAME COLUMN e3 TO e3renamed;";
Schema s = helpParse(ddl, "model").getSchema();
Map<String, Table> tableMap = s.getTables();
assertTrue("Table not found", tableMap.containsKey("G1"));
Table table = tableMap.get("G1");
Column e3 = table.getColumnByName("e3renamed");
assertNotNull(e3);
assertEquals("date", e3.getRuntimeType());
}
@Test
public void testAlterTableAddColumnOptions() throws Exception {
String ddl = "CREATE FOREIGN TABLE G1( e1 integer, e2 varchar, e3 date);" +
"ALTER FOREIGN TABLE G1 OPTIONS(ADD CARDINALITY 12);" +
"ALTER FOREIGN TABLE G1 ALTER COLUMN e1 OPTIONS(ADD NULL_VALUE_COUNT 12);" +
"ALTER FOREIGN TABLE G1 ALTER COLUMN e1 OPTIONS(ADD FOO 'BAR');";
Schema s = helpParse(ddl, "model").getSchema();
Map<String, Table> tableMap = s.getTables();
assertTrue("Table not found", tableMap.containsKey("G1"));
Table table = tableMap.get("G1");
assertEquals(12, table.getCardinality());
Column c = table.getColumnByName("e1");
assertNotNull(c);
assertEquals("BAR", c.getProperty("FOO", false));
assertEquals(12, c.getNullValues());
}
@Test
public void testAlterTableRemoveColumnOptions() throws Exception {
String ddl = "CREATE FOREIGN TABLE G1( e1 integer OPTIONS (NULL_VALUE_COUNT 12, FOO 'BAR'), e2 varchar, e3 date);" +
"ALTER FOREIGN TABLE G1 ALTER COLUMN e1 OPTIONS(DROP NULL_VALUE_COUNT);" +
"ALTER FOREIGN TABLE G1 ALTER COLUMN e1 OPTIONS(DROP FOO);" +
"ALTER FOREIGN TABLE G1 ALTER COLUMN e1 OPTIONS( ADD x 'y');" ;
Schema s = helpParse(ddl, "model").getSchema();
Map<String, Table> tableMap = s.getTables();
assertTrue("Table not found", tableMap.containsKey("G1"));
Table table = tableMap.get("G1");
Column c = table.getColumnByName("e1");
assertNotNull(c);
assertNull(c.getProperty("FOO", false));
assertEquals(-1, c.getNullValues());
assertEquals("y", c.getProperty("x", false));
}
@Test
public void testAlterProcedureOptions() throws Exception {
String ddl = "CREATE FOREIGN PROCEDURE myProc(OUT p1 boolean, p2 varchar, INOUT p3 decimal) " +
"RETURNS (r1 varchar, r2 decimal)" +
"OPTIONS(RANDOM 'any', UUID 'uuid', NAMEINSOURCE 'nis', ANNOTATION 'desc', UPDATECOUNT '2');" +
"ALTER FOREIGN PROCEDURE myProc OPTIONS(SET NAMEINSOURCE 'x');" +
"ALTER FOREIGN PROCEDURE myProc ALTER PARAMETER p2 OPTIONS (ADD x 'y');" +
"ALTER FOREIGN PROCEDURE myProc OPTIONS(DROP UPDATECOUNT);";
Schema s = helpParse(ddl, "model").getSchema();
Procedure proc = s.getProcedure("myProc");
assertNotNull(proc);
assertEquals("x", proc.getNameInSource());
assertEquals("p2", proc.getParameters().get(1).getName());
assertEquals("y", proc.getParameters().get(1).getProperty("x", false));
assertEquals(1, proc.getUpdateCount());
}
@Test
public void testAlterProcedureColumnType() throws Exception {
String ddl = "CREATE FOREIGN PROCEDURE myProc(OUT p1 boolean, p2 varchar, INOUT p3 decimal) " +
"RETURNS (r1 varchar, r2 decimal)" +
"OPTIONS(RANDOM 'any', UUID 'uuid', NAMEINSOURCE 'nis', ANNOTATION 'desc', UPDATECOUNT '2');" +
"ALTER FOREIGN PROCEDURE myProc ALTER PARAMETER p2 TYPE integer;";
Schema s = helpParse(ddl, "model").getSchema();
Procedure proc = s.getProcedure("myProc");
assertNotNull(proc);
assertEquals("p2", proc.getParameters().get(1).getName());
assertEquals("integer", proc.getParameters().get(1).getRuntimeType());
}
@Test
public void testAlterProcedureColumnRename() throws Exception {
String ddl = "CREATE FOREIGN PROCEDURE myProc(OUT p1 boolean, p2 varchar, INOUT p3 decimal) " +
"RETURNS (r1 varchar, r2 decimal)" +
"OPTIONS(RANDOM 'any', UUID 'uuid', NAMEINSOURCE 'nis', ANNOTATION 'desc', UPDATECOUNT '2');" +
"ALTER FOREIGN PROCEDURE myProc RENAME PARAMETER p2 TO p2renamed;";
Schema s = helpParse(ddl, "model").getSchema();
Procedure proc = s.getProcedure("myProc");
assertNotNull(proc);
assertEquals("p2renamed", proc.getParameters().get(1).getName());
}
@Test
public void testTypeLength() throws Exception {
String ddl = "CREATE FOREIGN PROCEDURE myProc(OUT p1 boolean, p2 varchar, INOUT p3 decimal) " +
"RETURNS (r1 varchar(10), r2 decimal(11,2), r3 object(1), r4 clob(10000))" +
"OPTIONS(RANDOM 'any', UUID 'uuid', NAMEINSOURCE 'nis', ANNOTATION 'desc', UPDATECOUNT '2');";
Schema s = helpParse(ddl, "model").getSchema();
Procedure proc = s.getProcedure("myProc");
assertNotNull(proc);
List<Column> cols = proc.getResultSet().getColumns();
assertEquals(10, cols.get(0).getLength());
assertEquals(11, cols.get(1).getPrecision());
assertEquals(1, cols.get(2).getLength());
assertEquals(10000, cols.get(3).getLength());
}
@Test
public void testGlobalTemp() throws Exception {
String ddl = "CREATE GLOBAL TEMPORARY TABLE T (col string);";
Schema s = helpParse(ddl, "model").getSchema();
Table t = s.getTable("T");
assertEquals(1, t.getColumns().size());
}
@Test public void testArrayType() throws Exception {
String ddl = "CREATE VIEW V (col string[]) as select ('a','b');";
Schema s = helpParse(ddl, "model").getSchema();
Table t = s.getTable("V");
assertEquals(1, t.getColumns().size());
assertEquals("string[]", t.getColumns().get(0).getRuntimeType());
assertEquals(String[].class, t.getColumns().get(0).getJavaType());
}
@Test(expected=MetadataException.class) public void testAfterTriggerNameRequired() throws Exception {
String ddl = "CREATE FOREIGN TABLE T ( e1 integer, e2 varchar);" +
"CREATE TRIGGER ON T AFTER UPDATE AS " +
"FOR EACH ROW \n" +
"BEGIN ATOMIC \n" +
"if (\"new\" is not distinct from \"old\") raise sqlexception 'error';\n" +
"END;";
helpParse(ddl, "model").getSchema();
}
@Test public void testAfterTrigger() throws Exception {
String ddl = "CREATE FOREIGN TABLE T ( e1 integer, e2 varchar);" +
"CREATE TRIGGER tr ON T AFTER UPDATE AS " +
"FOR EACH ROW \n" +
"BEGIN ATOMIC \n" +
"if (\"new\" is not distinct from \"old\") raise sqlexception 'error';\n" +
"END;";
Schema s = helpParse(ddl, "model").getSchema();
Table t = s.getTable("T");
assertEquals(1, t.getTriggers().size());
Trigger tr = t.getTriggers().values().iterator().next();
assertEquals("tr", tr.getName());
assertEquals(TriggerEvent.UPDATE, tr.getEvent());
assertNotNull(tr.getPlan());
}
@Test
public void testCreateDatabase() throws Exception {
String ddl = "CREATE DATABASE FOO VERSION '2' OPTIONS (k1 'v1', k2 'v2')";
Database db = helpParse(ddl);
assertEquals("FOO", db.getName());
assertEquals("2", db.getVersion());
assertEquals("v1", db.getProperty("k1", false));
assertEquals("v2", db.getProperty("k2", false));
}
@Test
public void testAlterDatabase() throws Exception {
String ddl = "CREATE DATABASE FOO VERSION '2' OPTIONS (k1 'v1', k2 'v2');"
+ "USE DATABASE FOO version '2';"
+ "ALTER DATABASE FOO OPTIONS (ADD k3 'v3', SET k1 'v4', DROP k2);";
Database db = helpParse(ddl);
assertEquals("FOO", db.getName());
assertEquals("2", db.getVersion());
assertEquals("v4", db.getProperty("k1", false));
assertNull(db.getProperty("k2", false));
assertEquals("v3", db.getProperty("k3", false));
}
@Test
public void testAlterServer() throws Exception {
String ddl = "CREATE DATABASE FOO VERSION '2';"
+ "USE DATABASE FOO version '2';"
+ "CREATE FOREIGN DATA WRAPPER orcl;"
+ "CREATE SERVER x TYPE 'oracle' VERSION '2.0' FOREIGN DATA WRAPPER orcl OPTIONS (k1 'v1');"
+ "ALTER SERVER x OPTIONS(SET k1 'v2')";
Database db = helpParse(ddl);
assertEquals("FOO", db.getName());
assertEquals("2", db.getVersion());
Server s = db.getServer("x");
assertNotNull(s);
assertEquals("v2", s.getProperty("k1", false));
}
@Test
public void testCreateServerNoType() throws Exception {
String ddl = "CREATE DATABASE FOO VERSION '2';"
+ "USE DATABASE FOO version '2';"
+ "CREATE FOREIGN DATA WRAPPER orcl;"
+ "CREATE SERVER x FOREIGN DATA WRAPPER orcl;";
Database db = helpParse(ddl);
assertEquals("FOO", db.getName());
assertEquals("2", db.getVersion());
Server s = db.getServer("x");
assertNotNull(s);
assertTrue(s.isVirtual());
}
@Test
public void testCreateDatabaseNoVersion() throws Exception {
String ddl = "CREATE DATABASE FOO OPTIONS (k1 'v1', k2 'v2')";
Database db = helpParse(ddl);
assertEquals("FOO", db.getName());
assertEquals("1", db.getVersion());
assertEquals("v1", db.getProperty("k1", false));
assertEquals("v2", db.getProperty("k2", false));
}
@Ignore
public void testCreateDropDatabase() throws Exception {
String ddl = "CREATE DATABASE FOO;"
+ "DROP DATABASE FOO;";
Database db = helpParse(ddl);
assertNull(db);
}
@Test
public void testCreateSchema() throws Exception {
String ddl = "CREATE DATABASE FOO;"
+ "USE DATABASE FOO ;"
+ "CREATE FOREIGN DATA WRAPPER orcl;"
+ "CREATE SERVER x TYPE 'oracle' VERSION '2.0' FOREIGN DATA WRAPPER orcl OPTIONS (k1 'v1');"
+ "CREATE SCHEMA S1 SERVER x OPTIONS (x 'y');";
Database db = helpParse(ddl);
// schema test
Schema schema = db.getSchema("S1");
assertNotNull(schema);
assertEquals("y", schema.getProperty("x", false));
//server test
assertNotNull(db.getServer("x"));
assertNotNull(schema.getServer("x"));
assertEquals("v1", db.getServer("x").getProperty("k1", false));
// data wrapper test
assertNotNull(db.getDataWrapper("orcl"));
assertEquals("orcl", db.getServer("x").getDataWrapper());
}
@Test
public void testRole() throws Exception {
String ddl = "CREATE DATABASE FOO;"
+ "USE DATABASE FOO ;"
+ "CREATE ROLE superuser WITH JAAS ROLE x,y;";
Database db = helpParse(ddl);
Role role = db.getRole("superuser");
assertNotNull(role);
assertEquals("[x, y]", role.getJassRoles().toString());
}
@Test
public void testRoleAnyAuth() throws Exception {
String ddl = "CREATE DATABASE FOO;"
+ "USE DATABASE FOO ;"
+ "CREATE ROLE superuser WITH JAAS ROLE x,y WITH ANY AUTHENTICATED;";
Database db = helpParse(ddl);
Role role = db.getRole("superuser");
assertNotNull(role);
assertEquals("[x, y]", role.getJassRoles().toString());
assertTrue(role.isAnyAuthenticated());
}
@Test
public void testDropRole() throws Exception {
String ddl = "CREATE DATABASE FOO;"
+ "USE DATABASE FOO ;"
+ "CREATE ROLE superuser WITH JAAS ROLE x,y WITH ANY AUTHENTICATED;"
+ "DROP ROLE superuser";
Database db = helpParse(ddl);
Role role = db.getRole("superuser");
assertNull(role);
}
@Test
public void testGrant() throws Exception {
String ddl = "CREATE DATABASE FOO;"
+ "USE DATABASE FOO ;"
+ "CREATE FOREIGN DATA WRAPPER postgresql;"
+ "CREATE SERVER pgsql TYPE 'custom' FOREIGN DATA WRAPPER postgresql OPTIONS (\"jndi-name\" 'jndiname');"
+ "CREATE SCHEMA test SERVER pgsql;"
+ "SET SCHEMA test;"
+ "CREATE FOREIGN TABLE G1( e1 integer, e2 varchar, e3 date);"
+ "CREATE ROLE superuser WITH JAAS ROLE x,y WITH ANY AUTHENTICATED;"
+ "GRANT SELECT,INSERT,DELETE ON TABLE test.G1 TO superuser;"
+ "GRANT UPDATE ON TABLE test.G1 TO superuser;";
Database db = helpParse(ddl);
Role role = db.getRole("superuser");
assertNotNull(role);
Collection<Grant> grants = db.getGrants();
assertEquals(1, grants.size());
Grant g = grants.iterator().next();
assertEquals(1, g.getPermissions().size());
Permission p = g.getPermissions().iterator().next();
assertTrue(p.hasPrivilege(Privilege.SELECT));
assertTrue(p.hasPrivilege(Privilege.INSERT));
assertTrue(p.hasPrivilege(Privilege.DELETE));
assertTrue(p.hasPrivilege(Privilege.UPDATE));
assertNull(p.hasPrivilege(Privilege.DROP));
}
@Test
public void testGrantAll() throws Exception {
String ddl = "CREATE DATABASE FOO;"
+ "USE DATABASE FOO ;"
+ "CREATE FOREIGN DATA WRAPPER postgresql;"
+ "CREATE SERVER pgsql TYPE 'custom' FOREIGN DATA WRAPPER postgresql OPTIONS (\"jndi-name\" 'jndiname');"
+ "CREATE SCHEMA test SERVER pgsql;"
+ "SET SCHEMA test;"
+ "CREATE FOREIGN TABLE G1( e1 integer, e2 varchar, e3 date);"
+ "CREATE ROLE superuser WITH JAAS ROLE x,y WITH ANY AUTHENTICATED;"
+ "GRANT ALL PRIVILEGES TO superuser;";
Database db = helpParse(ddl);
Role role = db.getRole("superuser");
assertNotNull(role);
Collection<Grant> grants = db.getGrants();
assertEquals(1, grants.size());
Grant g = grants.iterator().next();
assertEquals(1, g.getPermissions().size());
Permission p = g.getPermissions().iterator().next();
assertTrue(p.hasPrivilege(Privilege.ALL_PRIVILEGES));
}
@Test
public void testGrantWithCondition() throws Exception {
String ddl = "CREATE DATABASE FOO;"
+ "USE DATABASE FOO ;"
+ "CREATE FOREIGN DATA WRAPPER postgresql;"
+ "CREATE SERVER pgsql TYPE 'custom' FOREIGN DATA WRAPPER postgresql OPTIONS (\"jndi-name\" 'jndiname');"
+ "CREATE SCHEMA test SERVER pgsql;"
+ "SET SCHEMA test;"
+ "CREATE FOREIGN TABLE G1( e1 integer, e2 varchar, e3 date);"
+ "CREATE ROLE superuser WITH JAAS ROLE x,y WITH ANY AUTHENTICATED;"
+ "GRANT SELECT ON TABLE test.G1 CONDITION CONSTRAINT 'foo=bar' TO superuser;";
Database db = helpParse(ddl);
Role role = db.getRole("superuser");
assertNotNull(role);
Collection<Grant> grants = db.getGrants();
assertEquals(1, grants.size());
Grant g = grants.iterator().next();
assertEquals(1, g.getPermissions().size());
Permission p = g.getPermissions().iterator().next();
assertTrue(p.hasPrivilege(Privilege.SELECT));
assertEquals("foo=bar", p.getCondition());
assertTrue(p.isConditionAConstraint());
}
@Test
public void testRevokeGrant() throws Exception {
String ddl = "CREATE DATABASE FOO;"
+ "USE DATABASE FOO ;"
+ "CREATE FOREIGN DATA WRAPPER postgresql;"
+ "CREATE SERVER pgsql TYPE 'custom' FOREIGN DATA WRAPPER postgresql OPTIONS (\"jndi-name\" 'jndiname');"
+ "CREATE SCHEMA test SERVER pgsql;"
+ "SET SCHEMA test;"
+ "CREATE FOREIGN TABLE G1( e1 integer, e2 varchar, e3 date);"
+ "CREATE ROLE superuser WITH JAAS ROLE x,y WITH ANY AUTHENTICATED;"
+ "GRANT SELECT,INSERT,DELETE ON TABLE test.G1 TO superuser;"
+ "GRANT UPDATE ON TABLE test.G1 TO superuser;"
+ "REVOKE SELECT ON TABLE test.G1 FROM superuser;";
Database db = helpParse(ddl);
Role role = db.getRole("superuser");
assertNotNull(role);
Collection<Grant> grants = db.getGrants();
assertEquals(1, grants.size());
Grant g = grants.iterator().next();
assertEquals(1, g.getPermissions().size());
Permission p = g.getPermissions().iterator().next();
assertNull(p.hasPrivilege(Privilege.SELECT));
assertTrue(p.hasPrivilege(Privilege.INSERT));
assertTrue(p.hasPrivilege(Privilege.DELETE));
assertTrue(p.hasPrivilege(Privilege.UPDATE));
assertNull(p.hasPrivilege(Privilege.DROP));
}
@Test
public void testRevokeAll() throws Exception {
String ddl = "CREATE DATABASE FOO;"
+ "USE DATABASE FOO ;"
+ "CREATE FOREIGN DATA WRAPPER postgresql;"
+ "CREATE SERVER pgsql TYPE 'custom' FOREIGN DATA WRAPPER postgresql OPTIONS (\"jndi-name\" 'jndiname');"
+ "CREATE SCHEMA test SERVER pgsql;"
+ "SET SCHEMA test;"
+ "CREATE FOREIGN TABLE G1( e1 integer, e2 varchar, e3 date);"
+ "CREATE ROLE superuser WITH JAAS ROLE x,y WITH ANY AUTHENTICATED;"
+ "GRANT SELECT,INSERT,DELETE ON TABLE G1 TO superuser;"
+ "GRANT UPDATE ON TABLE test.G1 TO superuser;"
+ "REVOKE ALL PRIVILEGES FROM superuser;";
Database db = helpParse(ddl);
Role role = db.getRole("superuser");
assertNotNull(role);
Collection<Grant> grants = db.getGrants();
//revoke all privileges will only have an already granted all privileges
assertEquals(1, grants.size());
}
@Test
public void testPhysicalTable() throws Exception {
String ddl = "CREATE DATABASE FOO;"
+ "USE DATABASE FOO ;"
+ "CREATE FOREIGN DATA WRAPPER postgresql;"
+ "CREATE SERVER pgsql TYPE 'custom' FOREIGN DATA WRAPPER postgresql OPTIONS (\"jndi-name\" 'jndiname');"
+ "CREATE SCHEMA test SERVER pgsql;"
+ "SET SCHEMA test;"
+ "CREATE FOREIGN TABLE G1( e1 integer, e2 varchar, e3 date);";
Database db = helpParse(ddl);
Schema s = db.getSchema("test");
Table t = s.getTable("G1");
assertNotNull(t);
assertTrue(t.getColumns().size() == 3);
assertNotNull(t.getColumnByName("e1"));
assertNotNull(t.getColumnByName("e2"));
assertNotNull(t.getColumnByName("e3"));
}
@Test
public void testAlterView() throws Exception {
String ddl = "CREATE DATABASE FOO;"
+ "USE DATABASE FOO ;"
+ "CREATE VIRTUAL SCHEMA test;"
+ "SET SCHEMA test;"
+ "CREATE VIRTUAL VIEW G1( e1 integer, e2 varchar, e3 date) AS SELECT 1, '2', curdate();"
+ "ALTER VIEW G1 AS /*+ foo */ SELECT 1, 'foo', curdate()";
Database db = helpParse(ddl);
Schema s = db.getSchema("test");
Table t = s.getTable("G1");
assertEquals("SELECT 1, 'foo', curdate()", t.getSelectTransformation());
}
@Test
public void testPhysicalTableAlterAddColumn() throws Exception {
String ddl = "CREATE DATABASE FOO;"
+ "USE DATABASE FOO ;"
+ "CREATE FOREIGN DATA WRAPPER postgresql;"
+ "CREATE SERVER pgsql TYPE 'custom' FOREIGN DATA WRAPPER postgresql OPTIONS (\"jndi-name\" 'jndiname');"
+ "CREATE SCHEMA test SERVER pgsql;"
+ "SET SCHEMA test;"
+ "CREATE FOREIGN TABLE G1( e1 integer, e2 varchar, e3 date);"
+ "ALTER TABLE G1 ADD COLUMN e4 integer PRIMARY KEY OPTIONS(x 10)";
Database db = helpParse(ddl);
Schema s = db.getSchema("test");
Table t = s.getTable("G1");
assertNotNull(t);
assertTrue(t.getColumns().size() == 4);
assertNotNull(t.getColumnByName("e1"));
assertNotNull(t.getColumnByName("e2"));
assertNotNull(t.getColumnByName("e3"));
assertNotNull(t.getColumnByName("e4"));
Column c = t.getColumnByName("e4");
assertEquals("integer", c.getRuntimeType());
assertNotNull(t.getPrimaryKey().getColumnByName("e4"));
assertEquals("10", c.getProperty("x", false));
}
@Test
public void testPhysicalTableAlterDropColumn() throws Exception {
String ddl = "CREATE DATABASE FOO;"
+ "USE DATABASE FOO ;"
+ "CREATE FOREIGN DATA WRAPPER postgresql;"
+ "CREATE SERVER pgsql TYPE 'custom' FOREIGN DATA WRAPPER postgresql OPTIONS (\"jndi-name\" 'jndiname');"
+ "CREATE SCHEMA test SERVER pgsql;"
+ "SET SCHEMA test;"
+ "CREATE FOREIGN TABLE G1( e1 integer, e2 varchar, e3 date);"
+ "ALTER TABLE G1 DROP COLUMN e1";
Database db = helpParse(ddl);
Schema s = db.getSchema("test");
Table t = s.getTable("G1");
assertNotNull(t);
assertTrue(t.getColumns().size() == 2);
assertNull(t.getColumnByName("e1"));
assertNotNull(t.getColumnByName("e2"));
assertNotNull(t.getColumnByName("e3"));
}
@Test
public void testDropPhysicalTable() throws Exception {
String ddl = "CREATE DATABASE FOO;"
+ "USE DATABASE FOO ;"
+ "CREATE FOREIGN DATA WRAPPER postgresql;"
+ "CREATE SERVER pgsql TYPE 'custom' FOREIGN DATA WRAPPER postgresql OPTIONS (\"jndi-name\" 'jndiname');"
+ "CREATE SCHEMA test SERVER pgsql;"
+ "SET SCHEMA test;"
+ "CREATE FOREIGN TABLE G1( e1 integer, e2 varchar, e3 date);"
+ "DROP FOREIGN TABLE G1";
Database db = helpParse(ddl);
Schema s = db.getSchema("test");
Table t = s.getTable("G1");
assertNull(t);
}
@Test
public void testAlterViewAddColumn2() throws Exception {
String ddl = "CREATE DATABASE FOO;"
+ "USE DATABASE FOO ;"
+ "CREATE VIRTUAL SCHEMA test;"
+ "SET SCHEMA test;"
+ "CREATE VIRTUAL VIEW G1 AS SELECT 1 as e1, '2' as e2, curdate() as e3;"
+ "ALTER VIEW G1 AS SELECT 1 as e1, '2' as e2, curdate() as e3, 'foo' as e4;";
Database db = helpParse(ddl);
Schema s = db.getSchema("test");
Table t = s.getTable("G1");
assertEquals("SELECT 1 AS e1, '2' AS e2, curdate() AS e3, 'foo' AS e4", t.getSelectTransformation());
}
@Test
public void testDropView() throws Exception {
String ddl = "CREATE DATABASE FOO;"
+ "USE DATABASE FOO ;"
+ "CREATE VIRTUAL SCHEMA test;"
+ "SET SCHEMA test;"
+ "CREATE VIRTUAL VIEW G1 AS SELECT 1 as e1, '2' as e2, curdate() as e3;"
+ "DROP VIEW G1";
Database db = helpParse(ddl);
Schema s = db.getSchema("test");
Table t = s.getTable("G1");
assertNull(t);
}
@Test
public void testFunction() throws Exception {
String ddl = "CREATE DATABASE FOO;"
+ "USE DATABASE FOO ;"
+ "CREATE FOREIGN DATA WRAPPER postgresql;"
+ "CREATE SERVER pgsql TYPE 'custom' FOREIGN DATA WRAPPER postgresql OPTIONS (\"jndi-name\" 'jndiname');"
+ "CREATE SCHEMA test SERVER pgsql;"
+ "SET SCHEMA test;"
+ "CREATE FOREIGN FUNCTION SourceFunc(flag Boolean) RETURNS varchar";
FunctionMethod method = null;
Database db = helpParse(ddl);
Schema s = db.getSchema("test");
for (FunctionMethod fm : s.getFunctions().values()) {
if (fm.getName().equalsIgnoreCase("SourceFunc")) {
method = fm;
break;
}
}
assertNotNull(method);
assertEquals("boolean", method.getInputParameters().get(0).getType());
}
@Test
public void testDropFunction() throws Exception {
String ddl = "CREATE DATABASE FOO;"
+ "USE DATABASE FOO ;"
+ "CREATE FOREIGN DATA WRAPPER postgresql;"
+ "CREATE SERVER pgsql TYPE 'custom' FOREIGN DATA WRAPPER postgresql OPTIONS (\"jndi-name\" 'jndiname');"
+ "CREATE SCHEMA test SERVER pgsql;"
+ "SET SCHEMA test;"
+ "CREATE FUNCTION SourceFunc(flag Boolean) RETURNS varchaR options (UUID 'z');"
+ "DROP FUNCTION SourceFunc;";
FunctionMethod method = null;
Database db = helpParse(ddl);
Schema s = db.getSchema("test");
for (FunctionMethod fm : s.getFunctions().values()) {
if (fm.getName().equalsIgnoreCase("SourceFunc")) {
method = fm;
break;
}
}
assertNull(method);
}
@Test
public void testDropSchema() throws Exception {
String ddl = "CREATE DATABASE FOO;"
+ "USE DATABASE FOO ;"
+ "CREATE VIRTUAL SCHEMA test;"
+ "SET SCHEMA test;"
+ "CREATE VIRTUAL VIEW G1 AS SELECT 1 as e1, '2' as e2, curdate() as e3;"
+ "DROP VIRTUAL SCHEMA test";
Database db = helpParse(ddl);
Schema s = db.getSchema("test");
assertNull(s);
}
@Test(expected=MetadataException.class)
public void testDropDataWrapper() throws Exception {
String ddl = "CREATE DATABASE FOO VERSION '2';"
+ "CREATE FOREIGN DATA WRAPPER orcl;"
+ "CREATE SERVER x TYPE 'oracle' VERSION '2.0' FOREIGN DATA WRAPPER orcl OPTIONS (k1 'v1');"
+ "DROP FOREIGN DATA WRAPPER orcl;";
Database db = helpParse(ddl);
assertNull(db.getDataWrapper("orcl"));
}
@Test
public void testDropDataWrappers() throws Exception {
String ddl = "CREATE DATABASE FOO VERSION '2';"
+ "USE DATABASE FOO version '2';"
+ "CREATE FOREIGN DATA WRAPPER orcl;"
+ "CREATE SERVER x TYPE 'oracle' VERSION '2.0' FOREIGN DATA WRAPPER orcl OPTIONS (k1 'v1');"
+ "DROP SERVER x;"
+ "DROP FOREIGN DATA WRAPPER orcl;";
Database db = helpParse(ddl);
assertNull(db.getDataWrapper("orcl"));
}
@Test
public void testCreateProcedure() throws Exception {
String ddl = "CREATE DATABASE FOO;"
+ "USE DATABASE FOO;"
+ "CREATE FOREIGN DATA WRAPPER postgresql;"
+ "CREATE SERVER pgsql TYPE 'custom' FOREIGN DATA WRAPPER postgresql OPTIONS (\"jndi-name\" 'jndiname');"
+ "CREATE SCHEMA test SERVER pgsql;"
+ "SET SCHEMA test;"
+ "CREATE FOREIGN PROCEDURE procG1(P1 integer) RETURNS (e1 integer, e2 varchar)";
Database db = helpParse(ddl);
Schema s = db.getSchema("test");
Procedure p = s.getProcedure("procG1");
assertNotNull(p);
assertEquals(1, p.getParameters().size());
assertNotNull(p.getParameterByName("P1"));
assertEquals(2, p.getResultSet().getColumns().size());
assertEquals("e1", p.getResultSet().getColumns().get(0).getName());
}
@Test
public void testDropProcedure() throws Exception {
String ddl = "CREATE DATABASE FOO;"
+ "USE DATABASE FOO ;"
+ "CREATE FOREIGN DATA WRAPPER postgresql;"
+ "CREATE SERVER pgsql TYPE 'custom' FOREIGN DATA WRAPPER postgresql OPTIONS (\"jndi-name\" 'jndiname');"
+ "CREATE SCHEMA test SERVER pgsql;"
+ "SET SCHEMA test;"
+ "CREATE FOREIGN PROCEDURE procG1(P1 integer) RETURNS (e1 integer, e2 varchar);"
+ "DROP FOREIGN PROCEDURE procG1";
Database db = helpParse(ddl);
Schema s = db.getSchema("test");
Procedure p = s.getProcedure("procG1");
assertNull(p);
}
@Test(expected=MetadataException.class)
public void testCreateDomainAlreadyExists() throws Exception {
String ddl = "CREATE DATABASE FOO VERSION '2.0.0'; USE DATABASE FOO VERSION '2.0.0';"
+ "CREATE DOMAIN \"INTEGER\" AS string(4000)";
helpParse(ddl);
}
@Test
public void testCreateDomain() throws Exception {
String ddl = "CREATE DATABASE FOO VERSION '2.0.0'; USE DATABASE FOO VERSION '2.0.0';"
+ "CREATE DOMAIN nnint AS integer not null;";
Database db = helpParse(ddl);
assertEquals(NullType.No_Nulls, db.getMetadataStore().getDatatypes().get("NNINT").getNullType());
}
@Test
public void testCreateDomainUsedInSchema() throws Exception {
String ddl = "CREATE DATABASE FOO VERSION '2.0.0'; USE DATABASE FOO VERSION '2.0.0';"
+ "CREATE DOMAIN my_string AS string(1000) not null;"
+ "CREATE SCHEMA S1; SET SCHEMA S1;"
+ "CREATE VIEW X (y my_string) as select 'a';";
Database db = helpParse(ddl);
assertEquals(1000, db.getMetadataStore().getDatatypes().get("my_string").getLength());
}
@Test(expected=MetadataException.class) public void testDDLNotAllowed() throws Exception {
String ddl = "CREATE DATABASE FOO;";
helpParse(ddl, "model");
}
@Test(expected=MetadataException.class)
public void testDDLOutOfSequence() throws Exception {
String ddl = "CREATE DATABASE FOO VERSION '2.0.0'; USE DATABASE FOO VERSION '2.0.0';"
+ "CREATE SCHEMA S1; SET SCHEMA S1;"
+ "CREATE VIEW X (y string) as select 'a';"
+ "CREATE SCHEMA S2;";
helpParse(ddl, Mode.DATABASE_STRUCTURE);
}
}