teiid SVN: r4370 - in branches/7.7.x/engine/src: test/java/org/teiid/query/processor and 1 other directory.
by teiid-commits@lists.jboss.org
Author: jolee
Date: 2012-08-27 16:43:40 -0400 (Mon, 27 Aug 2012)
New Revision: 4370
Modified:
branches/7.7.x/engine/src/main/java/org/teiid/query/processor/relational/XMLTableNode.java
branches/7.7.x/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java
Log:
TEIID-2112 using the local timezone for saxon calendarvalues
Modified: branches/7.7.x/engine/src/main/java/org/teiid/query/processor/relational/XMLTableNode.java
===================================================================
--- branches/7.7.x/engine/src/main/java/org/teiid/query/processor/relational/XMLTableNode.java 2012-08-27 20:14:33 UTC (rev 4369)
+++ branches/7.7.x/engine/src/main/java/org/teiid/query/processor/relational/XMLTableNode.java 2012-08-27 20:43:40 UTC (rev 4370)
@@ -23,10 +23,14 @@
package org.teiid.query.processor.relational;
import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collection;
import java.util.Collections;
+import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.TimeZone;
import net.sf.saxon.om.Item;
import net.sf.saxon.om.NodeInfo;
@@ -37,6 +41,7 @@
import net.sf.saxon.type.BuiltInAtomicType;
import net.sf.saxon.type.ConversionResult;
import net.sf.saxon.value.AtomicValue;
+import net.sf.saxon.value.CalendarValue;
import net.sf.saxon.value.StringValue;
import net.sf.saxon.value.Value;
@@ -51,6 +56,7 @@
import org.teiid.core.TeiidRuntimeException;
import org.teiid.core.types.DataTypeManager;
import org.teiid.core.types.XMLType;
+import org.teiid.core.util.TimestampWithTimezone;
import org.teiid.query.QueryPlugin;
import org.teiid.query.eval.Evaluator;
import org.teiid.query.function.FunctionDescriptor;
@@ -274,14 +280,14 @@
}
Object value = colItem;
if (value instanceof AtomicValue) {
- value = Value.convertToJava(colItem);
+ value = getValue((AtomicValue)colItem);
} else if (value instanceof Item) {
Item i = (Item)value;
BuiltInAtomicType bat = typeMapping.get(proColumn.getSymbol().getType());
if (bat != null) {
ConversionResult cr = StringValue.convertStringToBuiltInType(i.getStringValueCS(), bat, null);
value = cr.asAtomic();
- value = Value.convertToJava((AtomicValue)value);
+ value = getValue((AtomicValue)value);
if (value instanceof Item) {
value = ((Item)value).getStringValue();
}
@@ -299,6 +305,19 @@
item = null;
return tuple;
}
+
+ private Object getValue(AtomicValue value) throws XPathException {
+ if (value instanceof CalendarValue) {
+ CalendarValue cv = (CalendarValue)value;
+ if (!cv.hasTimezone()) {
+ Calendar cal = cv.getCalendar();
+ Date d = cal.getTime();
+ cal.setTimeZone(getContext().getServerTimeZone());
+ return TimestampWithTimezone.createTimestamp(d, TimeZone.getTimeZone("GMT"), cal);
+ }
+ }
+ return Value.convertToJava(value);
+ }
@Override
public boolean hasFinalBuffer() {
Modified: branches/7.7.x/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java
===================================================================
--- branches/7.7.x/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java 2012-08-27 20:14:33 UTC (rev 4369)
+++ branches/7.7.x/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java 2012-08-27 20:43:40 UTC (rev 4370)
@@ -193,6 +193,16 @@
process(sql, expected);
}
+ @Test public void testXmlTableDateTime() throws Exception {
+ String sql = "select * from xmltable('/a' passing convert('<a dt=\"2011-11-17T07:38:49\" dtz=\"2011-11-17T07:38:49Z\" t=\"13:23:14\" d=\"2010-04-05\" />', xml) columns x timestamp path '@dt', x1 timestamp path '@dtz', y date path '@d', z time path '@t') as x"; //$NON-NLS-1$
+
+ List<?>[] expected = new List<?>[] {
+ Arrays.asList(TimestampUtil.createTimestamp(111, 10, 17, 7, 38, 49, 0), TimestampUtil.createTimestamp(111, 10, 17, 1, 38, 49, 0), TimestampUtil.createDate(110, 3, 5), TimestampUtil.createTime(13, 23, 14))
+ };
+
+ process(sql, expected);
+ }
+
@Test public void testXmlTablePassingSubquery() throws Exception {
String sql = "select * from xmltable('/a/b' passing (SELECT xmlelement(name a, xmlAgg(xmlelement(name b, e1))) from pm1.g1) columns val string path '/.') as x"; //$NON-NLS-1$
12 years, 4 months
teiid SVN: r4369 - in trunk: admin/src/main/java/org/teiid/adminapi/impl and 13 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2012-08-27 16:14:33 -0400 (Mon, 27 Aug 2012)
New Revision: 4369
Added:
trunk/engine/src/test/java/org/teiid/query/processor/TestObjectTable.java
Removed:
trunk/admin/src/main/java/org/teiid/adminapi/impl/PermissionMap.java
Modified:
trunk/admin/src/main/java/org/teiid/adminapi/DataPolicy.java
trunk/admin/src/main/java/org/teiid/adminapi/impl/DataPolicyMetadata.java
trunk/admin/src/main/java/org/teiid/adminapi/impl/VDBMetadataParser.java
trunk/admin/src/test/java/org/teiid/adminapi/impl/TestDataPolicyMetaData.java
trunk/client/src/main/resources/vdb-deployer.xsd
trunk/common-core/src/main/java/org/teiid/core/util/StringUtil.java
trunk/engine/src/main/java/org/teiid/dqp/internal/process/AuthorizationValidationVisitor.java
trunk/engine/src/main/java/org/teiid/dqp/internal/process/DataRolePolicyDecider.java
trunk/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java
trunk/engine/src/main/java/org/teiid/query/processor/relational/ObjectTableNode.java
trunk/engine/src/main/java/org/teiid/query/util/Options.java
trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj
trunk/engine/src/main/resources/org/teiid/query/i18n.properties
trunk/engine/src/test/java/org/teiid/dqp/internal/process/TestAuthorizationValidationVisitor.java
trunk/engine/src/test/java/org/teiid/query/unittest/RealMetadataFactory.java
trunk/test-integration/common/src/test/java/org/teiid/jdbc/TestLocalConnections.java
Log:
TEIID-2141 TEIID-2164 rounding out objecttable with authorization and fixing permissionmap by turning permissions into bit masked values
Modified: trunk/admin/src/main/java/org/teiid/adminapi/DataPolicy.java
===================================================================
--- trunk/admin/src/main/java/org/teiid/adminapi/DataPolicy.java 2012-08-27 17:50:17 UTC (rev 4368)
+++ trunk/admin/src/main/java/org/teiid/adminapi/DataPolicy.java 2012-08-27 20:14:33 UTC (rev 4369)
@@ -37,8 +37,9 @@
STORED_PROCEDURE;
}
- public enum PermissionType {CREATE, READ, UPDATE, DELETE, ALTER, EXECUTE, DROP};
+ public enum PermissionType {CREATE, READ, UPDATE, DELETE, ALTER, EXECUTE, DROP, LANGUAGE};
+
/**
* Get the Name of the Data Policy
* @return
@@ -116,6 +117,13 @@
* Is "EXECUTE" allowed?
* @return
*/
- Boolean getAllowExecute();
+ Boolean getAllowExecute();
+
+ /**
+ * Is "LANGUAGE" allowed?
+ * @return
+ */
+ Boolean getAllowLanguage();
+
}
}
Modified: trunk/admin/src/main/java/org/teiid/adminapi/impl/DataPolicyMetadata.java
===================================================================
--- trunk/admin/src/main/java/org/teiid/adminapi/impl/DataPolicyMetadata.java 2012-08-27 17:50:17 UTC (rev 4368)
+++ trunk/admin/src/main/java/org/teiid/adminapi/impl/DataPolicyMetadata.java 2012-08-27 20:14:33 UTC (rev 4369)
@@ -23,7 +23,9 @@
import java.io.Serializable;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import org.teiid.adminapi.DataPolicy;
@@ -37,7 +39,8 @@
protected boolean anyAuthenticated;
protected Boolean allowCreateTemporaryTables;
- protected PermissionMap permissions = new PermissionMap();
+ protected Map<String, PermissionMetaData> permissions = new HashMap<String, PermissionMetaData>();
+ protected Map<String, PermissionMetaData> languagePermissions = new HashMap<String, PermissionMetaData>(2);
protected List<String> mappedRoleNames = new CopyOnWriteArrayList<String>();
@@ -61,21 +64,36 @@
@Override
public List<DataPermission> getPermissions() {
- return new ArrayList<DataPermission>(this.permissions.values());
+ List<DataPermission> result = new ArrayList<DataPermission>(this.permissions.values());
+ result.addAll(this.languagePermissions.values());
+ return result;
}
public void setPermissions(List<DataPermission> permissions) {
this.permissions.clear();
for (DataPermission permission:permissions) {
- this.permissions.put(permission.getResourceName().toLowerCase(), (PermissionMetaData)permission);
+ addPermission((PermissionMetaData)permission);
}
}
- public void addPermission(PermissionMetaData... permissions) {
- for (PermissionMetaData permission:permissions) {
- this.permissions.put(permission.getResourceName().toLowerCase(), permission);
+ public void addPermission(PermissionMetaData... perms) {
+ for (PermissionMetaData permission:perms) {
+ addPermission(permission);
}
}
+
+ private void addPermission(PermissionMetaData permission) {
+ PermissionMetaData previous = null;
+ if (permission.getAllowLanguage() != null) {
+ previous = this.languagePermissions.put(permission.getResourceName(), permission);
+ } else {
+ previous = permissions.put(permission.getResourceName().toLowerCase(), permission);
+ }
+ if (previous != null) {
+ permission.bits |= previous.bits;
+ permission.bitsSet |= previous.bitsSet;
+ }
+ }
@Override
public List<String> getMappedRoleNames() {
@@ -87,27 +105,25 @@
this.mappedRoleNames.addAll(names);
}
- public void addMappedRoleName(String name) {
- this.mappedRoleNames.add(name);
+ public void addMappedRoleName(String mappedName) {
+ this.mappedRoleNames.add(mappedName);
}
- public void removeMappedRoleName(String name) {
- this.mappedRoleNames.remove(name);
+ public void removeMappedRoleName(String mappedName) {
+ this.mappedRoleNames.remove(mappedName);
}
- public boolean allows(String resourceName, DataPolicy.PermissionType type) {
- resourceName = resourceName.toLowerCase();
- while (resourceName.length() > 0) {
- PermissionMetaData p = this.permissions.get(resourceName);
- if (p != null) {
- Boolean allowed = p.allows(type);
- if (allowed != null) {
- return allowed;
- }
- }
- resourceName = resourceName.substring(0, Math.max(0, resourceName.lastIndexOf('.')));
+ public Boolean allows(String resourceName, DataPolicy.PermissionType type) {
+ PermissionMetaData p = null;
+ if (type == PermissionType.LANGUAGE) {
+ p = this.languagePermissions.get(resourceName);
+ } else {
+ p = this.permissions.get(resourceName);
}
- return false;
+ if (p != null) {
+ return p.allows(type);
+ }
+ return null;
}
public static class PermissionMetaData implements DataPermission, Serializable {
@@ -115,12 +131,8 @@
// XML based fields
private String resourceName;
- protected Boolean allowCreate;
- protected Boolean allowRead;
- protected Boolean allowUpdate;
- protected Boolean allowDelete;
- protected Boolean allowExecute;
- protected Boolean allowAlter;
+ protected byte bits;
+ protected byte bitsSet;
@Override
public String getResourceName() {
@@ -133,38 +145,62 @@
@Override
public Boolean getAllowCreate() {
- return allowCreate;
+ return bitSet(0x01);
}
+ private Boolean bitSet(int bitMask) {
+ if ((bitsSet & bitMask) == bitMask) {
+ if ((bits & bitMask) == bitMask) {
+ return Boolean.TRUE;
+ }
+ return Boolean.FALSE;
+ }
+ return null;
+ }
+
+ private void setBit(int bitMask, Boolean bool) {
+ if (bool == null) {
+ bitsSet &= (~bitMask);
+ bits &= (~bitMask);
+ return;
+ }
+ bitsSet |= bitMask;
+ if (bool) {
+ bits |= bitMask;
+ } else {
+ bits &= (~bitMask);
+ }
+ }
+
public void setAllowCreate(Boolean value) {
- this.allowCreate = value;
+ setBit(0x01, value);
}
@Override
public Boolean getAllowRead() {
- return allowRead;
+ return bitSet(0x02);
}
public void setAllowRead(Boolean value) {
- this.allowRead = value;
+ setBit(0x02, value);
}
@Override
public Boolean getAllowUpdate() {
- return allowUpdate;
+ return bitSet(0x04);
}
public void setAllowUpdate(Boolean value) {
- this.allowUpdate = value;
+ setBit(0x04, value);
}
@Override
public Boolean getAllowDelete() {
- return allowDelete;
+ return bitSet(0x08);
}
public void setAllowDelete(Boolean value) {
- this.allowDelete = value;
+ setBit(0x08, value);
}
public String getType() {
@@ -187,6 +223,9 @@
if (Boolean.TRUE.equals(getAllowAlter())) {
sb.append("A");//$NON-NLS-1$
}
+ if (Boolean.TRUE.equals(getAllowLanguage())) {
+ sb.append("L");//$NON-NLS-1$
+ }
return sb.toString();
}
@@ -206,27 +245,38 @@
return getAllowUpdate();
case DELETE:
return getAllowDelete();
- }
+ case LANGUAGE:
+ return getAllowLanguage();
+ }
throw new AssertionError();
}
@Override
public Boolean getAllowAlter() {
- return allowAlter;
+ return bitSet(0x10);
}
@Override
public Boolean getAllowExecute() {
- return allowExecute;
+ return bitSet(0x20);
}
public void setAllowAlter(Boolean allowAlter) {
- this.allowAlter = allowAlter;
+ setBit(0x10, allowAlter);
}
public void setAllowExecute(Boolean allowExecute) {
- this.allowExecute = allowExecute;
+ setBit(0x20, allowExecute);
}
+
+ @Override
+ public Boolean getAllowLanguage() {
+ return bitSet(0x40);
+ }
+
+ public void setAllowLanguage(Boolean value) {
+ setBit(0x40, value);
+ }
public String toString() {
StringBuilder sb = new StringBuilder();
Deleted: trunk/admin/src/main/java/org/teiid/adminapi/impl/PermissionMap.java
===================================================================
--- trunk/admin/src/main/java/org/teiid/adminapi/impl/PermissionMap.java 2012-08-27 17:50:17 UTC (rev 4368)
+++ trunk/admin/src/main/java/org/teiid/adminapi/impl/PermissionMap.java 2012-08-27 20:14:33 UTC (rev 4369)
@@ -1,53 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright (C) 2008 Red Hat, Inc.
- * Licensed to Red Hat, Inc. under one or more contributor
- * license agreements. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * 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.
- */
-package org.teiid.adminapi.impl;
-
-import java.util.LinkedHashMap;
-
-import org.teiid.adminapi.impl.DataPolicyMetadata.PermissionMetaData;
-
-public class PermissionMap extends LinkedHashMap<String, PermissionMetaData> {
-
- private static final long serialVersionUID = -1170556665834875267L;
-
- @Override
- public PermissionMetaData put(String key, PermissionMetaData element) {
- PermissionMetaData previous = get(element.getResourceName().toLowerCase());
- if (previous != null) {
- if (element.allowCreate != null) {
- previous.setAllowCreate(element.allowCreate);
- }
- if (element.allowRead != null) {
- previous.setAllowRead(element.allowRead);
- }
- if (element.allowUpdate != null) {
- previous.setAllowUpdate(element.allowUpdate);
- }
- if (element.allowDelete != null) {
- previous.setAllowDelete(element.allowDelete);
- }
- return previous;
- }
- return super.put(element.getResourceName().toLowerCase(), element);
- }
-}
Modified: trunk/admin/src/main/java/org/teiid/adminapi/impl/VDBMetadataParser.java
===================================================================
--- trunk/admin/src/main/java/org/teiid/adminapi/impl/VDBMetadataParser.java 2012-08-27 17:50:17 UTC (rev 4368)
+++ trunk/admin/src/main/java/org/teiid/adminapi/impl/VDBMetadataParser.java 2012-08-27 20:14:33 UTC (rev 4369)
@@ -214,6 +214,9 @@
case ALLOW_CREATE:
permission.setAllowCreate(Boolean.parseBoolean(reader.getElementText()));
break;
+ case ALLOW_LANGUAGE:
+ permission.setAllowLanguage(Boolean.parseBoolean(reader.getElementText()));
+ break;
case ALLOW_DELETE:
permission.setAllowDelete(Boolean.parseBoolean(reader.getElementText()));
break;
@@ -235,7 +238,7 @@
Element.ALLOW_DELETE.getLocalName(),
Element.ALLOW_EXECUTE.getLocalName(),
Element.ALLOW_READ.getLocalName(),
- Element.ALLOW_UPADTE), reader.getLocation());
+ Element.ALLOW_UPADTE, Element.ALLOW_LANGUAGE), reader.getLocation());
}
}
}
@@ -375,6 +378,7 @@
ALLOW_DELETE("allow-delete"),
ALLOW_EXECUTE("allow-execute"),
ALLOW_ALTER("allow-alter"),
+ ALLOW_LANGUAGE("allow-language"),
MAPPED_ROLE_NAME("mapped-role-name"),
ENTRY("entry"),
METADATA("metadata");
@@ -497,6 +501,9 @@
if (permission.getAllowAlter() != null) {
writeElement(writer, Element.ALLOW_ALTER, permission.getAllowAlter().toString());
}
+ if (permission.getAllowLanguage() != null) {
+ writeElement(writer, Element.ALLOW_LANGUAGE, permission.getAllowCreate().toString());
+ }
writer.writeEndElement();
}
Modified: trunk/admin/src/test/java/org/teiid/adminapi/impl/TestDataPolicyMetaData.java
===================================================================
--- trunk/admin/src/test/java/org/teiid/adminapi/impl/TestDataPolicyMetaData.java 2012-08-27 17:50:17 UTC (rev 4368)
+++ trunk/admin/src/test/java/org/teiid/adminapi/impl/TestDataPolicyMetaData.java 2012-08-27 20:14:33 UTC (rev 4369)
@@ -21,12 +21,13 @@
*/
package org.teiid.adminapi.impl;
+import static org.junit.Assert.*;
+
import java.util.Arrays;
import org.junit.Test;
import org.teiid.adminapi.DataPolicy.PermissionType;
import org.teiid.adminapi.impl.DataPolicyMetadata.PermissionMetaData;
-import static junit.framework.Assert.*;
public class TestDataPolicyMetaData {
@@ -60,24 +61,22 @@
policy.addPermission(perm1, perm2, perm3, perm4, perm5);
+ assertTrue(policy.allows("catalog.schema.Table1".toLowerCase(), PermissionType.READ)); //$NON-NLS-1$
+ assertNull(policy.allows("catalog.schema.Table1".toLowerCase(), PermissionType.CREATE)); //$NON-NLS-1$
- assertTrue(policy.allows("catalog.schema.Table1", PermissionType.READ)); //$NON-NLS-1$
- assertFalse(policy.allows("catalog.schema.Table1", PermissionType.CREATE)); //$NON-NLS-1$
+ assertNull(policy.allows("catalog.schema", PermissionType.READ)); //$NON-NLS-1$
- assertFalse(policy.allows("catalog.schema", PermissionType.READ)); //$NON-NLS-1$
+ assertNull(policy.allows("catalog.schema.Table2.column".toLowerCase(), PermissionType.READ)); //$NON-NLS-1$
+ assertFalse(policy.allows("catalog.schema.Table2".toLowerCase(), PermissionType.READ)); //$NON-NLS-1$
- assertFalse(policy.allows("catalog.schema.Table2.column", PermissionType.READ)); //$NON-NLS-1$
- assertFalse(policy.allows("catalog.schema.Table2", PermissionType.READ)); //$NON-NLS-1$
+ assertNull(policy.allows("catalog.schema.Table3.column".toLowerCase(), PermissionType.READ)); //$NON-NLS-1$
+ assertTrue(policy.allows("catalog.schema.Table3".toLowerCase(), PermissionType.READ)); //$NON-NLS-1$
- assertTrue(policy.allows("catalog.schema.Table3.column", PermissionType.READ)); //$NON-NLS-1$
- assertTrue(policy.allows("catalog.schema.Table3", PermissionType.READ)); //$NON-NLS-1$
+ assertTrue(policy.allows("catalog.schema.Table4".toLowerCase(), PermissionType.READ)); //$NON-NLS-1$
+ assertNull(policy.allows("catalog.schema.Table4".toLowerCase(), PermissionType.DELETE)); //$NON-NLS-1$
- assertTrue(policy.allows("catalog.schema.Table4.column", PermissionType.READ)); //$NON-NLS-1$
- assertTrue(policy.allows("catalog.schema.Table4", PermissionType.READ)); //$NON-NLS-1$
- assertFalse(policy.allows("catalog.schema.Table4", PermissionType.DELETE)); //$NON-NLS-1$
-
- assertTrue(policy.allows("catalog.schema.Table5.column1", PermissionType.READ)); //$NON-NLS-1$
- assertFalse(policy.allows("catalog.schema.Table5.column2", PermissionType.READ)); //$NON-NLS-1$
- assertFalse(policy.allows("catalog.schema.Table5", PermissionType.READ)); //$NON-NLS-1$
+ assertTrue(policy.allows("catalog.schema.Table5.column1".toLowerCase(), PermissionType.READ)); //$NON-NLS-1$
+ assertNull(policy.allows("catalog.schema.Table5.column2".toLowerCase(), PermissionType.READ)); //$NON-NLS-1$
+ assertNull(policy.allows("catalog.schema.Table5".toLowerCase(), PermissionType.READ)); //$NON-NLS-1$
}
}
Modified: trunk/client/src/main/resources/vdb-deployer.xsd
===================================================================
--- trunk/client/src/main/resources/vdb-deployer.xsd 2012-08-27 17:50:17 UTC (rev 4368)
+++ trunk/client/src/main/resources/vdb-deployer.xsd 2012-08-27 20:14:33 UTC (rev 4369)
@@ -118,12 +118,17 @@
<xs:complexType>
<xs:sequence>
<xs:element name="resource-name" type="xs:string"/>
- <xs:element name="allow-create" type="xs:boolean" minOccurs="0"/>
- <xs:element name="allow-read" type="xs:boolean" minOccurs="0"/>
- <xs:element name="allow-update" type="xs:boolean" minOccurs="0"/>
- <xs:element name="allow-delete" type="xs:boolean" minOccurs="0"/>
- <xs:element name="allow-execute" type="xs:boolean" minOccurs="0"/>
- <xs:element name="allow-alter" type="xs:boolean" minOccurs="0"/>
+ <xs:choice>
+ <xs:sequence>
+ <xs:element name="allow-create" type="xs:boolean" minOccurs="0"/>
+ <xs:element name="allow-read" type="xs:boolean" minOccurs="0"/>
+ <xs:element name="allow-update" type="xs:boolean" minOccurs="0"/>
+ <xs:element name="allow-delete" type="xs:boolean" minOccurs="0"/>
+ <xs:element name="allow-execute" type="xs:boolean" minOccurs="0"/>
+ <xs:element name="allow-alter" type="xs:boolean" minOccurs="0"/>
+ </xs:sequence>
+ <xs:element name="allow-language" type="xs:boolean" minOccurs="0"/>
+ </xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
Modified: trunk/common-core/src/main/java/org/teiid/core/util/StringUtil.java
===================================================================
--- trunk/common-core/src/main/java/org/teiid/core/util/StringUtil.java 2012-08-27 17:50:17 UTC (rev 4368)
+++ trunk/common-core/src/main/java/org/teiid/core/util/StringUtil.java 2012-08-27 20:14:33 UTC (rev 4369)
@@ -20,14 +20,7 @@
import java.lang.reflect.Array;
import java.net.MalformedURLException;
import java.net.URL;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.StringTokenizer;
+import java.util.*;
import java.util.regex.Pattern;
import org.teiid.core.CorePlugin;
@@ -974,6 +967,9 @@
else if (type.isAssignableFrom(List.class)) {
return (T)new ArrayList<String>(Arrays.asList(value.split(","))); //$NON-NLS-1$
}
+ else if (type.isAssignableFrom(Set.class)) {
+ return (T)new HashSet<String>(Arrays.asList(value.split(","))); //$NON-NLS-1$
+ }
else if (type.isArray()) {
String[] values = value.split(","); //$NON-NLS-1$
Object array = Array.newInstance(type.getComponentType(), values.length);
Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/process/AuthorizationValidationVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/process/AuthorizationValidationVisitor.java 2012-08-27 17:50:17 UTC (rev 4368)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/AuthorizationValidationVisitor.java 2012-08-27 20:14:33 UTC (rev 4369)
@@ -84,6 +84,17 @@
public void visit(AlterView obj) {
validateEntitlements(Arrays.asList(obj.getTarget()), DataPolicy.PermissionType.ALTER, Context.ALTER);
}
+
+ @Override
+ public void visit(ObjectTable objectTable) {
+ String language = ObjectTable.DEFAULT_LANGUAGE;
+ if (objectTable.getScriptingLanguage() != null) {
+ language = objectTable.getScriptingLanguage();
+ }
+ Map<String, LanguageObject> map = new HashMap<String, LanguageObject>();
+ map.put(language, objectTable);
+ validateEntitlements(PermissionType.LANGUAGE, Context.QUERY, map);
+ }
private void validateTemp(DataPolicy.PermissionType action, GroupSymbol symbol, Context context) {
String resource = symbol.getNonCorrelationName();
Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/process/DataRolePolicyDecider.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/process/DataRolePolicyDecider.java 2012-08-27 17:50:17 UTC (rev 4368)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/DataRolePolicyDecider.java 2012-08-27 20:14:33 UTC (rev 4369)
@@ -22,9 +22,10 @@
package org.teiid.dqp.internal.process;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
-import java.util.LinkedHashSet;
+import java.util.List;
import java.util.Set;
import org.teiid.CommandContext;
@@ -45,22 +46,33 @@
if (action == PermissionType.EXECUTE && context == Context.FUNCTION && allowFunctionCallsByDefault) {
return Collections.emptySet();
}
- LinkedHashSet<String> results = new LinkedHashSet<String>(resources);
- for(DataPolicy p:commandContext.getAllowedDataPolicies().values()) {
- DataPolicyMetadata policy = (DataPolicyMetadata)p;
-
- if (results.isEmpty()) {
- break;
+ List<DataPolicy> policies = new ArrayList<DataPolicy>(commandContext.getAllowedDataPolicies().values());
+ int policyCount = policies.size();
+ outer:for (Iterator<String> iter = resources.iterator(); iter.hasNext();) {
+ String resource = iter.next();
+ if (action != PermissionType.LANGUAGE) {
+ resource = resource.toLowerCase();
}
-
- Iterator<String> i = results.iterator();
- while (i.hasNext()) {
- if (policy.allows(i.next(), action)) {
- i.remove();
+ while (resource.length() > 0) {
+ boolean isFalse = false;
+ for (int j = 0; j < policyCount; j++) {
+ DataPolicyMetadata policy = (DataPolicyMetadata)policies.get(j);
+ Boolean allows = policy.allows(resource, action);
+ if (allows != null) {
+ if (allows) {
+ iter.remove();
+ continue outer;
+ }
+ isFalse = true;
+ }
}
+ if (isFalse || action == PermissionType.LANGUAGE) {
+ break; //don't check less specific permissions
+ }
+ resource = resource.substring(0, Math.max(0, resource.lastIndexOf('.')));
}
}
- return results;
+ return resources;
}
@Override
Modified: trunk/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java 2012-08-27 17:50:17 UTC (rev 4368)
+++ trunk/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java 2012-08-27 20:14:33 UTC (rev 4369)
@@ -28,6 +28,7 @@
import java.io.Serializable;
import java.util.*;
+import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import javax.script.ScriptEngineManager;
@@ -75,6 +76,8 @@
*/
public class TransformationMetadata extends BasicQueryMetadata implements Serializable {
+ public static final String ALLOWED_LANGUAGES = "allowed-languages"; //$NON-NLS-1$
+
private static final class LiveQueryNode extends QueryNode {
Procedure p;
private LiveQueryNode(Procedure p) {
@@ -158,7 +161,9 @@
private FunctionLibrary functionLibrary;
private VDBMetaData vdbMetaData;
private ScriptEngineManager scriptEngineManager;
+ private Map<String, ScriptEngineFactory> scriptEngineFactories = Collections.synchronizedMap(new HashMap<String, ScriptEngineFactory>());
private Set<String> importedModels;
+ private Set<String> allowedLanguages;
/*
* TODO: move caching to jboss cache structure
@@ -177,6 +182,10 @@
if (this.vdbMetaData !=null) {
this.scriptEngineManager = vdbMetadata.getAttachment(ScriptEngineManager.class);
this.importedModels = this.vdbMetaData.getImportedModels();
+ this.allowedLanguages = StringUtil.valueOf(vdbMetadata.getPropertyValue(ALLOWED_LANGUAGES), Set.class);
+ if (this.allowedLanguages == null) {
+ this.allowedLanguages = Collections.emptySet();
+ }
} else {
this.importedModels = Collections.emptySet();
}
@@ -1096,6 +1105,7 @@
tm.procedureCache = this.procedureCache;
tm.scriptEngineManager = this.scriptEngineManager;
tm.importedModels = this.importedModels;
+ tm.allowedLanguages = this.allowedLanguages;
return tm;
}
@@ -1112,18 +1122,34 @@
if (language == null) {
language = ObjectTable.DEFAULT_LANGUAGE;
}
- /*
- * because of state caching in the engine, we'll return a new instance for each
- * usage. we can pool if needed and add a returnEngine method
- */
- ScriptEngine engine = this.scriptEngineManager.getEngineByName(language);
+ ScriptEngine engine = null;
+ if (allowedLanguages == null || allowedLanguages.contains(language)) {
+ /*
+ * because of state caching in the engine, we'll return a new instance for each
+ * usage. we can pool if needed and add a returnEngine method
+ */
+ ScriptEngineFactory sef = this.scriptEngineFactories.get(language);
+ if (sef != null) {
+ try {
+ engine = sef.getScriptEngine();
+ engine.setBindings(scriptEngineManager.getBindings(), ScriptContext.ENGINE_SCOPE);
+ } catch (Exception e) {
+ //just swallow the exception to mimic the jsr behavior
+ }
+ }
+ engine = this.scriptEngineManager.getEngineByName(language);
+ }
if (engine == null) {
Set<String> names = new LinkedHashSet<String>();
for (ScriptEngineFactory factory : this.scriptEngineManager.getEngineFactories()) {
names.addAll(factory.getNames());
}
+ if (allowedLanguages != null) {
+ names.retainAll(allowedLanguages);
+ }
throw new TeiidProcessingException(QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31109, language, names));
}
+ this.scriptEngineFactories.put(language, engine.getFactory());
return engine;
}
Modified: trunk/engine/src/main/java/org/teiid/query/processor/relational/ObjectTableNode.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/relational/ObjectTableNode.java 2012-08-27 17:50:17 UTC (rev 4368)
+++ trunk/engine/src/main/java/org/teiid/query/processor/relational/ObjectTableNode.java 2012-08-27 20:14:33 UTC (rev 4369)
@@ -51,7 +51,7 @@
*/
public class ObjectTableNode extends SubqueryAwareRelationalNode {
- private static final String TEIID_ROW_COUNT = "teiid_rowcount"; //$NON-NLS-1$
+ private static final String TEIID_ROWN_NUMBER = "teiid_row_number"; //$NON-NLS-1$
private static final String TEIID_ROW = "teiid_row"; //$NON-NLS-1$
private static final String TEIID_CONTEXT = "teiid_context"; //$NON-NLS-1$
@@ -168,7 +168,7 @@
TeiidComponentException, TeiidProcessingException {
List<Object> tuple = new ArrayList<Object>(projectedColumns.size());
this.scriptContext.setAttribute(TEIID_ROW, this.item, ScriptContext.ENGINE_SCOPE);
- this.scriptContext.setAttribute(TEIID_ROW_COUNT, this.rowCount, ScriptContext.ENGINE_SCOPE);
+ this.scriptContext.setAttribute(TEIID_ROWN_NUMBER, this.rowCount, ScriptContext.ENGINE_SCOPE);
for (ObjectColumn proColumn : projectedColumns) {
Object value = evalScript(proColumn.getCompiledScript(), proColumn.getPath());
if (value == null) {
Modified: trunk/engine/src/main/java/org/teiid/query/util/Options.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/util/Options.java 2012-08-27 17:50:17 UTC (rev 4368)
+++ trunk/engine/src/main/java/org/teiid/query/util/Options.java 2012-08-27 20:14:33 UTC (rev 4369)
@@ -23,6 +23,7 @@
package org.teiid.query.util;
import java.util.Properties;
+import java.util.Set;
/**
* A holder for options
@@ -30,8 +31,10 @@
public class Options {
public static final String UNNEST_DEFAULT = "org.teiid.subqueryUnnestDefault"; //$NON-NLS-1$
+ public static final String LANGUAGES_DEFAULT = "org.teiid.languagesWithoutDataRoles"; //$NON-NLS-1$
private Properties properties;
+ private Set<String> languages;
private boolean subqueryUnnestDefault;
public Properties getProperties() {
@@ -42,6 +45,14 @@
this.properties = properties;
}
+ public void setLanguages(Set<String> languages) {
+ this.languages = languages;
+ }
+
+ public Set<String> getLanguages() {
+ return languages;
+ }
+
public boolean isSubqueryUnnestDefault() {
return subqueryUnnestDefault;
}
Modified: trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj
===================================================================
--- trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj 2012-08-27 17:50:17 UTC (rev 4368)
+++ trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj 2012-08-27 20:14:33 UTC (rev 4369)
@@ -2636,7 +2636,7 @@
/*
name=object table column
description=object table column.
-example={code:sql}y integer 'teiid_rowcount'{code}
+example={code:sql}y integer 'teiid_row_number'{code}
*/
ObjectTable.ObjectColumn objectColumn(ParseInfo info):
{
Modified: trunk/engine/src/main/resources/org/teiid/query/i18n.properties
===================================================================
--- trunk/engine/src/main/resources/org/teiid/query/i18n.properties 2012-08-27 17:50:17 UTC (rev 4368)
+++ trunk/engine/src/main/resources/org/teiid/query/i18n.properties 2012-08-27 20:14:33 UTC (rev 4369)
@@ -1024,8 +1024,8 @@
TEIID31105=Returing warning to client: {0}
TEIID31106=Duplicate parameter {1} defined on {0}
TEIID31107=Procedure {0} can only have 1 RESULT/return value
-TEIID31109=Invalid language {0}. Supported language names are {1}.
-TEIID31109=Invalid script {0}. Scrpting engine reported: {1}.
+TEIID31109=Invalid language {0}. Supported and allowed language names are {1}.
+TEIID31110=Invalid script {0}. Scrpting engine reported: {1}.
SQLParser.proc_type_conflict=Result type {1} conflicts with return type {2} for procedure {0}
SQLParser.param_out=Procedure {0} RESULT param {1} must be of type OUT.
Modified: trunk/engine/src/test/java/org/teiid/dqp/internal/process/TestAuthorizationValidationVisitor.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/dqp/internal/process/TestAuthorizationValidationVisitor.java 2012-08-27 17:50:17 UTC (rev 4368)
+++ trunk/engine/src/test/java/org/teiid/dqp/internal/process/TestAuthorizationValidationVisitor.java 2012-08-27 20:14:33 UTC (rev 4369)
@@ -30,6 +30,7 @@
import java.util.Set;
import org.junit.Before;
+import org.junit.BeforeClass;
import org.junit.Test;
import org.teiid.adminapi.DataPolicy;
import org.teiid.adminapi.DataPolicy.PermissionType;
@@ -57,14 +58,21 @@
public static final String CONN_ID = "connID"; //$NON-NLS-1$
private CommandContext context;
+ private static DataPolicyMetadata exampleAuthSvc1;
+ private static DataPolicyMetadata exampleAuthSvc2;
@Before public void setup() {
context = new CommandContext();
context.setSession(new SessionMetadata());
context.setDQPWorkContext(new DQPWorkContext());
}
+
+ @BeforeClass static public void oneTimeSetup() {
+ exampleAuthSvc1 = exampleAuthSvc1();
+ exampleAuthSvc2 = exampleAuthSvc2();
+ }
- PermissionMetaData addResource(PermissionType type, boolean flag, String resource) {
+ static PermissionMetaData addResource(PermissionType type, boolean flag, String resource) {
PermissionMetaData p = new PermissionMetaData();
p.setResourceName(resource);
switch(type) {
@@ -86,14 +94,16 @@
case EXECUTE:
p.setAllowExecute(flag);
break;
+ case LANGUAGE:
+ p.setAllowLanguage(flag);
}
return p;
}
- PermissionMetaData addResource(PermissionType type, String resource) {
+ static PermissionMetaData addResource(PermissionType type, String resource) {
return addResource(type, true, resource);
}
- private DataPolicyMetadata exampleAuthSvc1() {
+ private static DataPolicyMetadata exampleAuthSvc1() {
DataPolicyMetadata svc = new DataPolicyMetadata();
svc.setName("test"); //$NON-NLS-1$
@@ -143,7 +153,7 @@
}
//allow by default
- private DataPolicyMetadata exampleAuthSvc2() {
+ private static DataPolicyMetadata exampleAuthSvc2() {
DataPolicyMetadata svc = new DataPolicyMetadata();
svc.setName("test"); //$NON-NLS-1$
@@ -208,137 +218,144 @@
}
@Test public void testProcRelational() throws Exception {
- helpTest("select * from sp1", RealMetadataFactory.example1Cached(), new String[] {}, RealMetadataFactory.example1VDB(), exampleAuthSvc1()); //$NON-NLS-1$
- helpTest("select * from pm1.sp1", RealMetadataFactory.example1Cached(), new String[] {}, RealMetadataFactory.example1VDB(), exampleAuthSvc1()); //$NON-NLS-1$
- helpTest("select * from sp1", RealMetadataFactory.example1Cached(), new String[] {"sp1"}, RealMetadataFactory.example1VDB(), exampleAuthSvc2()); //$NON-NLS-1$
+ helpTest("select * from sp1", RealMetadataFactory.example1Cached(), new String[] {}, RealMetadataFactory.example1VDB(), exampleAuthSvc1); //$NON-NLS-1$
+ helpTest("select * from pm1.sp1", RealMetadataFactory.example1Cached(), new String[] {}, RealMetadataFactory.example1VDB(), exampleAuthSvc1); //$NON-NLS-1$
+ helpTest("select * from sp1", RealMetadataFactory.example1Cached(), new String[] {"sp1"}, RealMetadataFactory.example1VDB(), exampleAuthSvc2); //$NON-NLS-1$
}
@Test public void testTemp() throws Exception {
//allowed by default
- helpTest("create local temporary table x (y string)", RealMetadataFactory.example1Cached(), new String[] {}, RealMetadataFactory.example1VDB(), exampleAuthSvc1()); //$NON-NLS-1$
+ helpTest("create local temporary table x (y string)", RealMetadataFactory.example1Cached(), new String[] {}, RealMetadataFactory.example1VDB(), exampleAuthSvc1); //$NON-NLS-1$
//explicitly denied
- helpTest("create local temporary table x (y string)", RealMetadataFactory.example1Cached(), new String[] {"x"}, RealMetadataFactory.example1VDB(), exampleAuthSvc2()); //$NON-NLS-1$
+ helpTest("create local temporary table x (y string)", RealMetadataFactory.example1Cached(), new String[] {"x"}, RealMetadataFactory.example1VDB(), exampleAuthSvc2); //$NON-NLS-1$
}
@Test public void testFunction() throws Exception {
QueryMetadataInterface metadata = RealMetadataFactory.example1Cached();
- helpTest("SELECT e1 FROM pm1.g1 where xyz() > 0", metadata, new String[] {}, RealMetadataFactory.example1VDB(), exampleAuthSvc1()); //$NON-NLS-1$
- helpTest("SELECT e1, curdate() FROM pm1.g2 where xyz() > 0", metadata, new String[] {"xyz()"}, RealMetadataFactory.example1VDB(), exampleAuthSvc2()); //$NON-NLS-1$
+ helpTest("SELECT e1 FROM pm1.g1 where xyz() > 0", metadata, new String[] {}, RealMetadataFactory.example1VDB(), exampleAuthSvc1); //$NON-NLS-1$
+ helpTest("SELECT e1, curdate() FROM pm1.g2 where xyz() > 0", metadata, new String[] {"xyz()"}, RealMetadataFactory.example1VDB(), exampleAuthSvc2); //$NON-NLS-1$
}
@Test public void testEverythingAccessible() throws Exception {
- helpTest("SELECT e1 FROM pm1.g1", RealMetadataFactory.example1Cached(), new String[] {}, RealMetadataFactory.example1VDB(), exampleAuthSvc1()); //$NON-NLS-1$
+ helpTest("SELECT e1 FROM pm1.g1", RealMetadataFactory.example1Cached(), new String[] {}, RealMetadataFactory.example1VDB(), exampleAuthSvc1); //$NON-NLS-1$
}
@Test public void testEverythingAccessible1() throws Exception {
- helpTest("SELECT e1 FROM (select e1 from pm1.g1) x", RealMetadataFactory.example1Cached(), new String[] {}, RealMetadataFactory.example1VDB(), exampleAuthSvc1()); //$NON-NLS-1$
+ helpTest("SELECT e1 FROM (select e1 from pm1.g1) x", RealMetadataFactory.example1Cached(), new String[] {}, RealMetadataFactory.example1VDB(), exampleAuthSvc1); //$NON-NLS-1$
}
@Test public void testEverythingAccessible2() throws Exception {
- helpTest("SELECT lookup('pm1.g1', 'e1', 'e1', '1'), e1 FROM (select e1 from pm1.g1) x", RealMetadataFactory.example1Cached(), new String[] {}, RealMetadataFactory.example1VDB(), exampleAuthSvc1()); //$NON-NLS-1$
+ helpTest("SELECT lookup('pm1.g1', 'e1', 'e1', '1'), e1 FROM (select e1 from pm1.g1) x", RealMetadataFactory.example1Cached(), new String[] {}, RealMetadataFactory.example1VDB(), exampleAuthSvc1); //$NON-NLS-1$
}
@Test public void testInaccesibleElement() throws Exception {
- helpTest("SELECT e2 FROM pm1.g1", RealMetadataFactory.example1Cached(), new String[] {"pm1.g1.e2"}, RealMetadataFactory.example1VDB(), exampleAuthSvc1()); //$NON-NLS-1$ //$NON-NLS-2$
+ helpTest("SELECT e2 FROM pm1.g1", RealMetadataFactory.example1Cached(), new String[] {"pm1.g1.e2"}, RealMetadataFactory.example1VDB(), exampleAuthSvc1); //$NON-NLS-1$ //$NON-NLS-2$
}
@Test public void testInaccesibleElement2() throws Exception {
- helpTest("SELECT lookup('pm1.g1', 'e1', 'e2', '1')", RealMetadataFactory.example1Cached(), new String[] {"pm1.g1.e2"}, RealMetadataFactory.example1VDB(), exampleAuthSvc1()); //$NON-NLS-1$ //$NON-NLS-2$
+ helpTest("SELECT lookup('pm1.g1', 'e1', 'e2', '1')", RealMetadataFactory.example1Cached(), new String[] {"pm1.g1.e2"}, RealMetadataFactory.example1VDB(), exampleAuthSvc1); //$NON-NLS-1$ //$NON-NLS-2$
}
@Test public void testInaccesibleGroup() throws Exception {
- helpTest("SELECT e1 FROM pm1.g2", RealMetadataFactory.example1Cached(), new String[] {"pm1.g2", "pm1.g2.e1"}, RealMetadataFactory.example1VDB(), exampleAuthSvc1()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ helpTest("SELECT e1 FROM pm1.g2", RealMetadataFactory.example1Cached(), new String[] {"pm1.g2", "pm1.g2.e1"}, RealMetadataFactory.example1VDB(), exampleAuthSvc1); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
@Test public void testInsert() throws Exception {
- helpTest("INSERT INTO pm1.g1 (e1, e2, e3, e4) VALUES ('x', 5, {b'true'}, 1.0)", RealMetadataFactory.example1Cached(), new String[] {}, RealMetadataFactory.example1VDB(), exampleAuthSvc1()); //$NON-NLS-1$
+ helpTest("INSERT INTO pm1.g1 (e1, e2, e3, e4) VALUES ('x', 5, {b'true'}, 1.0)", RealMetadataFactory.example1Cached(), new String[] {}, RealMetadataFactory.example1VDB(), exampleAuthSvc1); //$NON-NLS-1$
}
@Test public void testInsertInaccessible() throws Exception {
- helpTest("INSERT INTO pm1.g2 (e1, e2, e3, e4) VALUES ('x', 5, {b'true'}, 1.0)", RealMetadataFactory.example1Cached(), new String[] {"pm1.g2.e1"}, RealMetadataFactory.example1VDB(), exampleAuthSvc1()); //$NON-NLS-1$ //$NON-NLS-2$
+ helpTest("INSERT INTO pm1.g2 (e1, e2, e3, e4) VALUES ('x', 5, {b'true'}, 1.0)", RealMetadataFactory.example1Cached(), new String[] {"pm1.g2.e1"}, RealMetadataFactory.example1VDB(), exampleAuthSvc1); //$NON-NLS-1$ //$NON-NLS-2$
}
@Test public void testUpdate() throws Exception {
- helpTest("UPDATE pm1.g1 SET e2 = 5", RealMetadataFactory.example1Cached(), new String[] {}, RealMetadataFactory.example1VDB(), exampleAuthSvc1()); //$NON-NLS-1$
+ helpTest("UPDATE pm1.g1 SET e2 = 5", RealMetadataFactory.example1Cached(), new String[] {}, RealMetadataFactory.example1VDB(), exampleAuthSvc1); //$NON-NLS-1$
}
@Test public void testUpdateCriteriaInaccessibleForRead() throws Exception {
- helpTest("UPDATE pm1.g2 SET e2 = 5 WHERE e1 = 'x'", RealMetadataFactory.example1Cached(), new String[] {"pm1.g2.e1"}, RealMetadataFactory.example1VDB(), exampleAuthSvc1()); //$NON-NLS-1$ //$NON-NLS-2$
+ helpTest("UPDATE pm1.g2 SET e2 = 5 WHERE e1 = 'x'", RealMetadataFactory.example1Cached(), new String[] {"pm1.g2.e1"}, RealMetadataFactory.example1VDB(), exampleAuthSvc1); //$NON-NLS-1$ //$NON-NLS-2$
}
@Test public void testUpdateCriteriaInaccessibleForRead1() throws Exception {
- helpTest("UPDATE pm1.g2 SET e2 = cast(e1 as integer)", RealMetadataFactory.example1Cached(), new String[] {"pm1.g2.e1"}, RealMetadataFactory.example1VDB(), exampleAuthSvc1()); //$NON-NLS-1$ //$NON-NLS-2$
+ helpTest("UPDATE pm1.g2 SET e2 = cast(e1 as integer)", RealMetadataFactory.example1Cached(), new String[] {"pm1.g2.e1"}, RealMetadataFactory.example1VDB(), exampleAuthSvc1); //$NON-NLS-1$ //$NON-NLS-2$
}
@Test public void testUpdateElementInaccessibleForUpdate() throws Exception {
- helpTest("UPDATE pm1.g1 SET e1 = 5 WHERE e1 = 'x'", RealMetadataFactory.example1Cached(), new String[] {"pm1.g1.e1"}, RealMetadataFactory.example1VDB(), exampleAuthSvc1()); //$NON-NLS-1$ //$NON-NLS-2$
+ helpTest("UPDATE pm1.g1 SET e1 = 5 WHERE e1 = 'x'", RealMetadataFactory.example1Cached(), new String[] {"pm1.g1.e1"}, RealMetadataFactory.example1VDB(), exampleAuthSvc1); //$NON-NLS-1$ //$NON-NLS-2$
}
@Test public void testDelete() throws Exception {
- helpTest("DELETE FROM pm1.g1", RealMetadataFactory.example1Cached(), new String[] {}, RealMetadataFactory.example1VDB(), exampleAuthSvc1()); //$NON-NLS-1$
+ helpTest("DELETE FROM pm1.g1", RealMetadataFactory.example1Cached(), new String[] {}, RealMetadataFactory.example1VDB(), exampleAuthSvc1); //$NON-NLS-1$
}
@Test public void testDeleteCriteriaInaccesibleForRead() throws Exception {
- helpTest("DELETE FROM pm1.g2 WHERE e1 = 'x'", RealMetadataFactory.example1Cached(), new String[] {"pm1.g2.e1"}, RealMetadataFactory.example1VDB(), exampleAuthSvc1()); //$NON-NLS-1$ //$NON-NLS-2$
+ helpTest("DELETE FROM pm1.g2 WHERE e1 = 'x'", RealMetadataFactory.example1Cached(), new String[] {"pm1.g2.e1"}, RealMetadataFactory.example1VDB(), exampleAuthSvc1); //$NON-NLS-1$ //$NON-NLS-2$
}
@Test public void testDeleteInaccesibleGroup() throws Exception {
- helpTest("DELETE FROM pm1.g3", RealMetadataFactory.example1Cached(), new String[] {"pm1.g3"}, RealMetadataFactory.example1VDB(), exampleAuthSvc1()); //$NON-NLS-1$ //$NON-NLS-2$
+ helpTest("DELETE FROM pm1.g3", RealMetadataFactory.example1Cached(), new String[] {"pm1.g3"}, RealMetadataFactory.example1VDB(), exampleAuthSvc1); //$NON-NLS-1$ //$NON-NLS-2$
}
@Test public void testProc() throws Exception {
- helpTest("EXEC pm1.sq1()", RealMetadataFactory.example1Cached(), new String[] {}, RealMetadataFactory.example1VDB(), exampleAuthSvc1()); //$NON-NLS-1$
+ helpTest("EXEC pm1.sq1()", RealMetadataFactory.example1Cached(), new String[] {}, RealMetadataFactory.example1VDB(), exampleAuthSvc1); //$NON-NLS-1$
}
@Test public void testProcInaccesible() throws Exception {
- helpTest("EXEC pm1.sq2('xyz')", RealMetadataFactory.example1Cached(), new String[] {"pm1.sq2"}, RealMetadataFactory.example1VDB(), exampleAuthSvc1()); //$NON-NLS-1$ //$NON-NLS-2$
+ helpTest("EXEC pm1.sq2('xyz')", RealMetadataFactory.example1Cached(), new String[] {"pm1.sq2"}, RealMetadataFactory.example1VDB(), exampleAuthSvc1); //$NON-NLS-1$ //$NON-NLS-2$
}
@Test public void testSelectIntoEverythingAccessible() throws Exception {
- helpTest("SELECT e1, e2, e3, e4 INTO pm1.g2 FROM pm2.g1", RealMetadataFactory.example1Cached(), new String[] {}, RealMetadataFactory.example1VDB(), exampleAuthSvc2()); //$NON-NLS-1$
+ helpTest("SELECT e1, e2, e3, e4 INTO pm1.g2 FROM pm2.g1", RealMetadataFactory.example1Cached(), new String[] {}, RealMetadataFactory.example1VDB(), exampleAuthSvc2); //$NON-NLS-1$
}
@Test public void testSelectIntoTarget_e1_NotAccessible() throws Exception {
- helpTest("SELECT e1, e2, e3, e4 INTO pm2.g2 FROM pm2.g1", RealMetadataFactory.example1Cached(), new String[] {"pm2.g2", "pm2.g2.e2","pm2.g2.e4","pm2.g2.e3"}, RealMetadataFactory.example1VDB(), exampleAuthSvc2()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ helpTest("SELECT e1, e2, e3, e4 INTO pm2.g2 FROM pm2.g1", RealMetadataFactory.example1Cached(), new String[] {"pm2.g2", "pm2.g2.e2","pm2.g2.e4","pm2.g2.e3"}, RealMetadataFactory.example1VDB(), exampleAuthSvc2); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
}
@Test public void testSelectIntoTarget_e1e2_NotAccessible() throws Exception {
- helpTest("SELECT e1, e2, e3, e4 INTO pm3.g2 FROM pm2.g1", RealMetadataFactory.example1Cached(), new String[] {"pm3.g2", "pm3.g2.e4", "pm3.g2.e3"}, RealMetadataFactory.example1VDB(),exampleAuthSvc2()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ helpTest("SELECT e1, e2, e3, e4 INTO pm3.g2 FROM pm2.g1", RealMetadataFactory.example1Cached(), new String[] {"pm3.g2", "pm3.g2.e4", "pm3.g2.e3"}, RealMetadataFactory.example1VDB(),exampleAuthSvc2); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
@Test public void testTempTableSelectInto() throws Exception {
- helpTest("SELECT e1 INTO #temp FROM pm1.g1", RealMetadataFactory.example1Cached(), new String[] {}, RealMetadataFactory.example1VDB(), exampleAuthSvc1()); //$NON-NLS-1$
- helpTest("SELECT e1 INTO #temp FROM pm1.g1", RealMetadataFactory.example1Cached(), new String[] {"#temp"}, RealMetadataFactory.example1VDB(), exampleAuthSvc2()); //$NON-NLS-1$
- helpTest("SELECT e1 INTO #temp FROM pm1.g1", RealMetadataFactory.example1Cached(), new String[] {}, RealMetadataFactory.example1VDB(), exampleAuthSvc2(), exampleAuthSvc1()); //$NON-NLS-1$
+ helpTest("SELECT e1 INTO #temp FROM pm1.g1", RealMetadataFactory.example1Cached(), new String[] {}, RealMetadataFactory.example1VDB(), exampleAuthSvc1); //$NON-NLS-1$
+ helpTest("SELECT e1 INTO #temp FROM pm1.g1", RealMetadataFactory.example1Cached(), new String[] {"#temp"}, RealMetadataFactory.example1VDB(), exampleAuthSvc2); //$NON-NLS-1$
+ helpTest("SELECT e1 INTO #temp FROM pm1.g1", RealMetadataFactory.example1Cached(), new String[] {}, RealMetadataFactory.example1VDB(), exampleAuthSvc2, exampleAuthSvc1); //$NON-NLS-1$
}
@Test public void testCommonTable() throws Exception {
- helpTest("WITH X AS (SELECT e1 from pm1.g2) SELECT e1 from x", RealMetadataFactory.example1Cached(), new String[] {}, RealMetadataFactory.example1VDB(), exampleAuthSvc2()); //$NON-NLS-1$
+ helpTest("WITH X AS (SELECT e1 from pm1.g2) SELECT e1 from x", RealMetadataFactory.example1Cached(), new String[] {}, RealMetadataFactory.example1VDB(), exampleAuthSvc2); //$NON-NLS-1$
}
@Test public void testTempTableSelectInto1() throws Exception {
- helpTest("SELECT e1, e2 INTO #temp FROM pm1.g1", RealMetadataFactory.example1Cached(), new String[] {"pm1.g1.e2"}, RealMetadataFactory.example1VDB(), exampleAuthSvc1()); //$NON-NLS-1$ //$NON-NLS-2$
+ helpTest("SELECT e1, e2 INTO #temp FROM pm1.g1", RealMetadataFactory.example1Cached(), new String[] {"pm1.g1.e2"}, RealMetadataFactory.example1VDB(), exampleAuthSvc1); //$NON-NLS-1$ //$NON-NLS-2$
}
@Test public void testTempTableInsert() throws Exception {
- helpTest("insert into #temp (e1, e2, e3, e4) values ('1', '2', '3', '4')", RealMetadataFactory.example1Cached(), new String[] {}, RealMetadataFactory.example1VDB(), exampleAuthSvc1()); //$NON-NLS-1$
- helpTest("insert into #temp (e1, e2, e3, e4) values ('1', '2', '3', '4')", RealMetadataFactory.example1Cached(), new String[] {"#temp"}, RealMetadataFactory.example1VDB(), exampleAuthSvc2()); //$NON-NLS-1$
+ helpTest("insert into #temp (e1, e2, e3, e4) values ('1', '2', '3', '4')", RealMetadataFactory.example1Cached(), new String[] {}, RealMetadataFactory.example1VDB(), exampleAuthSvc1); //$NON-NLS-1$
+ helpTest("insert into #temp (e1, e2, e3, e4) values ('1', '2', '3', '4')", RealMetadataFactory.example1Cached(), new String[] {"#temp"}, RealMetadataFactory.example1VDB(), exampleAuthSvc2); //$NON-NLS-1$
}
@Test public void testXMLAccessible() throws Exception {
- helpTest("select * from xmltest.doc1", RealMetadataFactory.example1Cached(), new String[] {}, RealMetadataFactory.example1VDB(), exampleAuthSvc2()); //$NON-NLS-1$ //$NON-NLS-2$
+ helpTest("select * from xmltest.doc1", RealMetadataFactory.example1Cached(), new String[] {}, RealMetadataFactory.example1VDB(), exampleAuthSvc2); //$NON-NLS-1$ //$NON-NLS-2$
}
@Test public void testXMLInAccessible() throws Exception {
- helpTest("select * from xmltest.doc1", RealMetadataFactory.example1Cached(), new String[] {"xmltest.doc1"}, RealMetadataFactory.example1VDB(), exampleAuthSvc1()); //$NON-NLS-1$ //$NON-NLS-2$
+ helpTest("select * from xmltest.doc1", RealMetadataFactory.example1Cached(), new String[] {"xmltest.doc1"}, RealMetadataFactory.example1VDB(), exampleAuthSvc1); //$NON-NLS-1$ //$NON-NLS-2$
}
@Test public void testAlter() throws Exception {
- helpTest("alter view SmallA_2589 as select * from bqt1.smalla", RealMetadataFactory.exampleBQTCached(), new String[] {"SmallA_2589"}, RealMetadataFactory.exampleBQTVDB(), exampleAuthSvc1()); //$NON-NLS-1$ //$NON-NLS-2$
+ helpTest("alter view SmallA_2589 as select * from bqt1.smalla", RealMetadataFactory.exampleBQTCached(), new String[] {"SmallA_2589"}, RealMetadataFactory.exampleBQTVDB(), exampleAuthSvc1); //$NON-NLS-1$ //$NON-NLS-2$
helpTest("alter view SmallA_2589 as select * from bqt1.smalla", RealMetadataFactory.exampleBQTCached(), new String[] {}, RealMetadataFactory.exampleBQTVDB(), examplePolicyBQT()); //$NON-NLS-1$ //$NON-NLS-2$
- helpTest("alter trigger on SmallA_2589 INSTEAD OF UPDATE enabled", RealMetadataFactory.exampleBQTCached(), new String[] {"SmallA_2589"}, RealMetadataFactory.exampleBQTVDB(), exampleAuthSvc1()); //$NON-NLS-1$ //$NON-NLS-2$
+ helpTest("alter trigger on SmallA_2589 INSTEAD OF UPDATE enabled", RealMetadataFactory.exampleBQTCached(), new String[] {"SmallA_2589"}, RealMetadataFactory.exampleBQTVDB(), exampleAuthSvc1); //$NON-NLS-1$ //$NON-NLS-2$
helpTest("alter trigger on SmallA_2589 INSTEAD OF UPDATE enabled", RealMetadataFactory.exampleBQTCached(), new String[] {}, RealMetadataFactory.exampleBQTVDB(), examplePolicyBQT()); //$NON-NLS-1$ //$NON-NLS-2$
}
+ @Test public void testObjectTable() throws Exception {
+ helpTest("select * from objecttable(language 'javascript' 'teiid_context' columns x string 'teiid_row.userName') as x", RealMetadataFactory.exampleBQTCached(), new String[] {"OBJECTTABLE(LANGUAGE 'javascript' 'teiid_context' COLUMNS x string 'teiid_row.userName') AS x"}, RealMetadataFactory.exampleBQTVDB(), exampleAuthSvc1); //$NON-NLS-1$ //$NON-NLS-2$
+ DataPolicyMetadata policy = exampleAuthSvc1();
+ policy.addPermission(addResource(PermissionType.LANGUAGE, "javascript"));
+ helpTest("select * from objecttable(language 'javascript' 'teiid_context' columns x string 'teiid_row.userName') as x", RealMetadataFactory.exampleBQTCached(), new String[] {}, RealMetadataFactory.exampleBQTVDB(), policy); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
}
Added: trunk/engine/src/test/java/org/teiid/query/processor/TestObjectTable.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/TestObjectTable.java (rev 0)
+++ trunk/engine/src/test/java/org/teiid/query/processor/TestObjectTable.java 2012-08-27 20:14:33 UTC (rev 4369)
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ */
+
+package org.teiid.query.processor;
+
+import static org.teiid.query.processor.TestProcessor.*;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Properties;
+
+import org.junit.Test;
+import org.teiid.query.metadata.TransformationMetadata;
+import org.teiid.query.sql.lang.ObjectTable;
+import org.teiid.query.unittest.RealMetadataFactory;
+
+@SuppressWarnings({"nls", "unchecked"})
+public class TestObjectTable {
+
+ @Test public void testIterator() throws Exception {
+ String sql = "select x.* from bqt1.smalla, objecttable('ov' passing objectvalue as ov COLUMNS x string 'teiid_row', y integer 'teiid_row_number') x"; //$NON-NLS-1$
+
+ List<?>[] expected = new List[] {
+ Arrays.asList("hello", 1),
+ Arrays.asList("world", 2),
+ Arrays.asList("x", 1),
+ Arrays.asList("y", 2),
+ };
+
+ process(sql, expected);
+ }
+
+ @Test public void testProjection() throws Exception {
+ String sql = "select y, z from bqt1.smalla, objecttable('ov' passing objectvalue as ov COLUMNS x string 'teiid_row', y integer 'teiid_row_number', z integer 'teiid_row.length') x order by x.x desc limit 1"; //$NON-NLS-1$
+
+ List<?>[] expected = new List[] {
+ Arrays.asList(2, 1),
+ };
+
+ process(sql, expected);
+ }
+
+ @Test public void testContext() throws Exception {
+ String sql = "select * from objecttable('teiid_context' COLUMNS y string 'teiid_row.userName') as X"; //$NON-NLS-1$
+
+ List<?>[] expected = new List[] {
+ Arrays.asList("user"),
+ };
+
+ process(sql, expected);
+ }
+
+ public static void process(String sql, List[] expectedResults) throws Exception {
+ HardcodedDataManager dataManager = new HardcodedDataManager();
+ dataManager.addData("SELECT BQT1.SmallA.ObjectValue FROM BQT1.SmallA", new List[] {Collections.singletonList(Arrays.asList("hello", "world")), Collections.singletonList(Arrays.asList("x", null, "y")), Collections.singletonList(null)} );
+ Properties p = new Properties();
+ p.put(TransformationMetadata.ALLOWED_LANGUAGES, ObjectTable.DEFAULT_LANGUAGE);
+ TransformationMetadata metadata = RealMetadataFactory.createTransformationMetadata(RealMetadataFactory.exampleBQTCached().getMetadataStore(), "bqt", p);
+ ProcessorPlan plan = helpGetPlan(helpParse(sql), metadata);
+ helpProcess(plan, createCommandContext(), dataManager, expectedResults);
+ }
+
+}
Property changes on: trunk/engine/src/test/java/org/teiid/query/processor/TestObjectTable.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: trunk/engine/src/test/java/org/teiid/query/unittest/RealMetadataFactory.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/unittest/RealMetadataFactory.java 2012-08-27 17:50:17 UTC (rev 4368)
+++ trunk/engine/src/test/java/org/teiid/query/unittest/RealMetadataFactory.java 2012-08-27 20:14:33 UTC (rev 4369)
@@ -30,6 +30,7 @@
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
+import java.util.Properties;
import org.teiid.adminapi.Model;
import org.teiid.adminapi.impl.ModelMetaData;
@@ -322,10 +323,17 @@
}
public static TransformationMetadata createTransformationMetadata(MetadataStore metadataStore, String vdbName, FunctionTree... functionModels) {
+ return createTransformationMetadata(metadataStore, vdbName, null, functionModels);
+ }
+
+ public static TransformationMetadata createTransformationMetadata(MetadataStore metadataStore, String vdbName, Properties vdbProperties, FunctionTree... functionModels) {
CompositeMetadataStore store = new CompositeMetadataStore(metadataStore);
VDBMetaData vdbMetaData = new VDBMetaData();
vdbMetaData.setName(vdbName); //$NON-NLS-1$
vdbMetaData.setVersion(1);
+ if (vdbProperties != null) {
+ vdbMetaData.setProperties(vdbProperties);
+ }
List<FunctionTree> udfs = new ArrayList<FunctionTree>();
udfs.addAll(Arrays.asList(functionModels));
for (Schema schema : metadataStore.getSchemas().values()) {
Modified: trunk/test-integration/common/src/test/java/org/teiid/jdbc/TestLocalConnections.java
===================================================================
--- trunk/test-integration/common/src/test/java/org/teiid/jdbc/TestLocalConnections.java 2012-08-27 17:50:17 UTC (rev 4368)
+++ trunk/test-integration/common/src/test/java/org/teiid/jdbc/TestLocalConnections.java 2012-08-27 20:14:33 UTC (rev 4369)
@@ -225,7 +225,11 @@
}
@Test public void testUseInDifferentThreads() throws Throwable {
- assertTrue(server.getDqp().getRequests().isEmpty());
+ for (int i = 0; !server.getDqp().getRequests().isEmpty() && i < 40; i++) {
+ //the previous test may not have cleaned up
+ Thread.sleep(50);
+ }
+ int count = server.getDqp().getRequests().size();
Connection c = server.createConnection("jdbc:teiid:PartsSupplier");
final Statement s = c.createStatement();
@@ -252,11 +256,11 @@
if (handler.t != null) {
throw handler.t;
}
- for (int i = 0; !server.getDqp().getRequests().isEmpty() && i < 40; i++) {
+ for (int i = 0; server.getDqp().getRequests().size() != count && i < 40; i++) {
//the concurrent modification may not be seen initially
Thread.sleep(50);
}
- assertTrue(server.getDqp().getRequests().isEmpty());
+ assertEquals(count, server.getDqp().getRequests().size());
}
@Test public void testWait() throws Throwable {
12 years, 4 months
teiid SVN: r4368 - trunk/jboss-integration/src/main/java/org/teiid/jboss/rest.
by teiid-commits@lists.jboss.org
Author: rareddy
Date: 2012-08-27 13:50:17 -0400 (Mon, 27 Aug 2012)
New Revision: 4368
Modified:
trunk/jboss-integration/src/main/java/org/teiid/jboss/rest/RestASMBasedWebArchiveBuilder.java
Log:
TEIID-2158: fixing method signature
Modified: trunk/jboss-integration/src/main/java/org/teiid/jboss/rest/RestASMBasedWebArchiveBuilder.java
===================================================================
--- trunk/jboss-integration/src/main/java/org/teiid/jboss/rest/RestASMBasedWebArchiveBuilder.java 2012-08-26 19:02:32 UTC (rev 4367)
+++ trunk/jboss-integration/src/main/java/org/teiid/jboss/rest/RestASMBasedWebArchiveBuilder.java 2012-08-27 17:50:17 UTC (rev 4368)
@@ -262,6 +262,9 @@
}
}
}
+
+// buildQueryProcedure(vdbName, vdbVersion, "xml", cw);
+// buildQueryProcedure(vdbName, vdbVersion, "json", cw);
cw.visitEnd();
@@ -323,7 +326,7 @@
}
paramSignature.append(")");
- mv = cw.visitMethod(ACC_PUBLIC, procedure.getName()+contentType, paramSignature+"Ljava/io/InputStream;", null, new String[] { "javax/ws/rs/WebApplicationException" });
+ mv = cw.visitMethod(ACC_PUBLIC, procedure.getName()+contentType.replace('/', '_'), paramSignature+"Ljava/io/InputStream;", null, new String[] { "javax/ws/rs/WebApplicationException" });
{
av0 = mv.visitAnnotation("Ljavax/ws/rs/Produces;", true);
{
@@ -400,7 +403,7 @@
mv.visitVarInsn(ALOAD, paramsSize+1);
mv.visitLdcInsn(charSet==null?"":charSet);
- mv.visitMethodInsn(INVOKEVIRTUAL, "org/teiid/jboss/rest/"+modelName, "execute", "(Ljava/lang/String;Ljava/util/LinkedHashMap;Ljava/lang/String;)Ljava/io/InputStream;");
+ mv.visitMethodInsn(INVOKEVIRTUAL, "org/teiid/jboss/rest/"+modelName, "execute", "(Ljava/lang/String;ILjava/lang/String;Ljava/util/LinkedHashMap;Ljava/lang/String;)Ljava/io/InputStream;");
mv.visitLabel(l1);
mv.visitInsn(ARETURN);
mv.visitLabel(l2);
@@ -416,4 +419,60 @@
mv.visitEnd();
}
}
+
+ private void buildQueryProcedure(String vdbName, int vdbVersion, String context, ClassWriter cw) {
+ MethodVisitor mv;
+ {
+ AnnotationVisitor av0;
+ mv = cw.visitMethod(ACC_PUBLIC, "sqlQuery"+context, "(Ljava/lang/String;)Ljava/io/InputStream;", null, null);
+ {
+ av0 = mv.visitAnnotation("Ljavax/ws/rs/Produces;", true);
+ {
+ AnnotationVisitor av1 = av0.visitArray("value");
+ av1.visit(null, "application/"+context);
+ av1.visitEnd();
+ }
+ av0.visitEnd();
+ }
+ {
+ av0 = mv.visitAnnotation("Ljavax/ws/rs/POST;", true);
+ av0.visitEnd();
+ }
+ {
+ av0 = mv.visitAnnotation("Ljavax/ws/rs/Path;", true);
+ av0.visit("value", "/query");
+ av0.visitEnd();
+ }
+ {
+ av0 = mv.visitParameterAnnotation(0, "Ljavax/ws/rs/FormParam;", true);
+ av0.visit("value", "sql");
+ av0.visitEnd();
+ }
+ mv.visitCode();
+ Label l0 = new Label();
+ Label l1 = new Label();
+ Label l2 = new Label();
+ mv.visitTryCatchBlock(l0, l1, l2, "java/sql/SQLException");
+ mv.visitLabel(l0);
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitLdcInsn(vdbName);
+ mv.visitIntInsn(BIPUSH, vdbVersion);
+ mv.visitVarInsn(ALOAD, 1);
+ mv.visitInsn(context.equals("xml")?ICONST_0:ICONST_1);
+ mv.visitMethodInsn(INVOKEVIRTUAL, "org/teiid/jboss/rest/View", "executeQuery", "(Ljava/lang/String;ILjava/lang/String;Z)Ljava/io/InputStream;");
+ mv.visitLabel(l1);
+ mv.visitInsn(ARETURN);
+ mv.visitLabel(l2);
+ mv.visitFrame(F_SAME1, 0, null, 1, new Object[] {"java/sql/SQLException"});
+ mv.visitVarInsn(ASTORE, 2);
+ mv.visitTypeInsn(NEW, "javax/ws/rs/WebApplicationException");
+ mv.visitInsn(DUP);
+ mv.visitVarInsn(ALOAD, 2);
+ mv.visitFieldInsn(GETSTATIC, "javax/ws/rs/core/Response$Status", "INTERNAL_SERVER_ERROR", "Ljavax/ws/rs/core/Response$Status;");
+ mv.visitMethodInsn(INVOKESPECIAL, "javax/ws/rs/WebApplicationException", "<init>", "(Ljava/lang/Throwable;Ljavax/ws/rs/core/Response$Status;)V");
+ mv.visitInsn(ATHROW);
+ mv.visitMaxs(5, 3);
+ mv.visitEnd();
+ }
+ }
}
12 years, 4 months
teiid SVN: r4367 - trunk/jboss-integration/src/main/java/org/teiid/jboss/rest.
by teiid-commits@lists.jboss.org
Author: rareddy
Date: 2012-08-26 15:02:32 -0400 (Sun, 26 Aug 2012)
New Revision: 4367
Modified:
trunk/jboss-integration/src/main/java/org/teiid/jboss/rest/RestASMBasedWebArchiveBuilder.java
trunk/jboss-integration/src/main/java/org/teiid/jboss/rest/TeiidRSProvider.java
Log:
TEIID-2158: removing the getConnection method and fixing the unit test
Modified: trunk/jboss-integration/src/main/java/org/teiid/jboss/rest/RestASMBasedWebArchiveBuilder.java
===================================================================
--- trunk/jboss-integration/src/main/java/org/teiid/jboss/rest/RestASMBasedWebArchiveBuilder.java 2012-08-25 20:38:37 UTC (rev 4366)
+++ trunk/jboss-integration/src/main/java/org/teiid/jboss/rest/RestASMBasedWebArchiveBuilder.java 2012-08-26 19:02:32 UTC (rev 4367)
@@ -257,28 +257,12 @@
else if (contentType.equals("plain")) {
contentType = "text/plain";
}
- buildRestService(modelName, procedure, method, uri, cw, contentType, charSet);
+ buildRestService(vdbName, vdbVersion, modelName, procedure, method, uri, cw, contentType, charSet);
hasValidProcedures = true;
}
}
}
- // getConnection method
- {
- mv = cw.visitMethod(ACC_PROTECTED, "getConnection", "()Ljava/sql/Connection;", null, new String[] { "java/sql/SQLException" });
- mv.visitCode();
- mv.visitTypeInsn(NEW, "org/teiid/jdbc/TeiidDriver");
- mv.visitInsn(DUP);
- mv.visitMethodInsn(INVOKESPECIAL, "org/teiid/jdbc/TeiidDriver", "<init>", "()V");
- mv.visitVarInsn(ASTORE, 1);
- mv.visitVarInsn(ALOAD, 1);
- mv.visitLdcInsn("jdbc:teiid:"+vdbName+"."+vdbVersion);
- mv.visitInsn(ACONST_NULL);
- mv.visitMethodInsn(INVOKEVIRTUAL, "org/teiid/jdbc/TeiidDriver", "connect", "(Ljava/lang/String;Ljava/util/Properties;)Lorg/teiid/jdbc/ConnectionImpl;");
- mv.visitInsn(ARETURN);
- mv.visitMaxs(3, 2);
- mv.visitEnd();
- }
cw.visitEnd();
if (!hasValidProcedures) {
@@ -314,7 +298,7 @@
return contentType;
}
- private void buildRestService(String modelName, Procedure procedure,
+ private void buildRestService(String vdbName, int vdbVersion, String modelName, Procedure procedure,
String method, String uri, ClassWriter cw, String contentType,
String charSet) {
@@ -407,11 +391,16 @@
sb.append("?");
}
sb.append(") }");
+
+ mv.visitLdcInsn(vdbName);
+ mv.visitIntInsn(BIPUSH, vdbVersion);
+
mv.visitLdcInsn(sb.toString());
mv.visitVarInsn(ALOAD, paramsSize+1);
- mv.visitLdcInsn(charSet);
- mv.visitMethodInsn(INVOKEVIRTUAL, "org/teiid/jboss/rest/"+modelName, "execute", "(Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;)Ljava/io/InputStream;");
+ mv.visitLdcInsn(charSet==null?"":charSet);
+
+ mv.visitMethodInsn(INVOKEVIRTUAL, "org/teiid/jboss/rest/"+modelName, "execute", "(Ljava/lang/String;Ljava/util/LinkedHashMap;Ljava/lang/String;)Ljava/io/InputStream;");
mv.visitLabel(l1);
mv.visitInsn(ARETURN);
mv.visitLabel(l2);
@@ -423,7 +412,7 @@
mv.visitFieldInsn(GETSTATIC, "javax/ws/rs/core/Response$Status", "INTERNAL_SERVER_ERROR", "Ljavax/ws/rs/core/Response$Status;");
mv.visitMethodInsn(INVOKESPECIAL, "javax/ws/rs/WebApplicationException", "<init>", "(Ljava/lang/Throwable;Ljavax/ws/rs/core/Response$Status;)V");
mv.visitInsn(ATHROW);
- mv.visitMaxs(4, paramsSize+2);
+ mv.visitMaxs(6, paramsSize+2);
mv.visitEnd();
}
}
Modified: trunk/jboss-integration/src/main/java/org/teiid/jboss/rest/TeiidRSProvider.java
===================================================================
--- trunk/jboss-integration/src/main/java/org/teiid/jboss/rest/TeiidRSProvider.java 2012-08-25 20:38:37 UTC (rev 4366)
+++ trunk/jboss-integration/src/main/java/org/teiid/jboss/rest/TeiidRSProvider.java 2012-08-26 19:02:32 UTC (rev 4367)
@@ -38,14 +38,22 @@
import org.teiid.core.types.XMLType;
import org.teiid.core.util.ReaderInputStream;
import org.teiid.jboss.IntegrationPlugin;
+import org.teiid.jdbc.TeiidDriver;
import org.teiid.query.function.source.XMLSystemFunctions;
import org.teiid.query.sql.symbol.XMLSerialize;
public abstract class TeiidRSProvider {
- public InputStream execute(String procedureSignature, LinkedHashMap<String, String> parameters, String charSet) throws SQLException {
+ public InputStream execute(String vdbName, int version, String procedureSignature,
+ LinkedHashMap<String, String> parameters, String charSet) throws SQLException {
Object result = null;
- Connection conn = getConnection();
+
+ //the generated code sends a empty string rather than null.
+ if (charSet != null && charSet.trim().isEmpty()) {
+ charSet = null;
+ }
+
+ Connection conn = getConnection(vdbName, version);
boolean usingReturn = procedureSignature.startsWith("{ ?"); //$NON-NLS-1$
try {
//TODO: an alternative strategy would be to set the parameters based upon name
@@ -111,7 +119,10 @@
}
}
}
-
- protected abstract Connection getConnection() throws SQLException;
-
+
+ private Connection getConnection(String vdbName, int version) throws SQLException {
+ TeiidDriver driver = new TeiidDriver();
+ return driver.connect("jdbc:teiid:"+vdbName+"."+version, null);
+ }
+
}
12 years, 4 months
teiid SVN: r4366 - trunk/jboss-integration/src/main/java/org/teiid/jboss/rest.
by teiid-commits@lists.jboss.org
Author: rareddy
Date: 2012-08-25 16:38:37 -0400 (Sat, 25 Aug 2012)
New Revision: 4366
Modified:
trunk/jboss-integration/src/main/java/org/teiid/jboss/rest/RestASMBasedWebArchiveBuilder.java
trunk/jboss-integration/src/main/java/org/teiid/jboss/rest/TeiidRSProvider.java
Log:
TEIID-2158: changing to prepare call, and handling the result as return parameter. Patch by SteveH.
Modified: trunk/jboss-integration/src/main/java/org/teiid/jboss/rest/RestASMBasedWebArchiveBuilder.java
===================================================================
--- trunk/jboss-integration/src/main/java/org/teiid/jboss/rest/RestASMBasedWebArchiveBuilder.java 2012-08-24 21:00:59 UTC (rev 4365)
+++ trunk/jboss-integration/src/main/java/org/teiid/jboss/rest/RestASMBasedWebArchiveBuilder.java 2012-08-25 20:38:37 UTC (rev 4366)
@@ -32,6 +32,7 @@
import java.io.Reader;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.List;
import java.util.Properties;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
@@ -56,6 +57,7 @@
import org.teiid.metadata.Procedure;
import org.teiid.metadata.ProcedureParameter;
import org.teiid.metadata.Schema;
+import org.teiid.metadata.ProcedureParameter.Type;
import org.teiid.query.metadata.TransformationMetadata;
@@ -115,7 +117,7 @@
}
private static ArrayList<String> getPathParameters(String uri ) {
- ArrayList pathParams = new ArrayList();
+ ArrayList<String> pathParams = new ArrayList<String>();
String param;
if (uri.contains("{")) {
while (uri.indexOf("}") > -1) {
@@ -255,7 +257,7 @@
else if (contentType.equals("plain")) {
contentType = "text/plain";
}
- buildRestService(modelName, procedure, method, uri, cw, contentType, charSet==null?"US-ASCII":charSet);
+ buildRestService(modelName, procedure, method, uri, cw, contentType, charSet);
hasValidProcedures = true;
}
}
@@ -316,7 +318,16 @@
String method, String uri, ClassWriter cw, String contentType,
String charSet) {
- int paramsSize = procedure.getParameters().size();
+ List<ProcedureParameter> params = new ArrayList<ProcedureParameter>(procedure.getParameters().size());
+ boolean usingReturn = false;
+ for (ProcedureParameter p : procedure.getParameters()) {
+ if (p.getType() == Type.In || p.getType() == Type.InOut) {
+ params.add(p);
+ } else if (p.getType() == Type.ReturnValue && procedure.getResultSet() == null) {
+ usingReturn = true;
+ }
+ }
+ int paramsSize = params.size();
MethodVisitor mv;
AnnotationVisitor av0;
@@ -355,7 +366,7 @@
for (int i = 0; i < paramsSize; i++)
{
av0 = mv.visitParameterAnnotation(i, "Ljavax/ws/rs/PathParam;", true);
- av0.visit("value", procedure.getParameters().get(i).getName());
+ av0.visit("value", params.get(i).getName());
av0.visitEnd();
}
@@ -372,7 +383,7 @@
mv.visitVarInsn(ASTORE, paramsSize+1);
for (int i = 0; i < paramsSize; i++) {
mv.visitVarInsn(ALOAD, paramsSize+1);
- mv.visitLdcInsn(procedure.getParameters().get(i).getName());
+ mv.visitLdcInsn(params.get(i).getName());
mv.visitVarInsn(ALOAD, i+1);
mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
mv.visitInsn(POP);
@@ -382,11 +393,20 @@
// send parametr type information the procedure name
StringBuilder sb = new StringBuilder();
- sb.append(procedure.getFullName()).append("(");
- for (ProcedureParameter pp:procedure.getParameters()) {
- sb.append(pp.getRuntimeType()).append(",");
+ sb.append("{ ");
+ if (usingReturn) {
+ sb.append("? = ");
}
- sb.append(")");
+ sb.append("CALL ");
+ procedure.getSQLString(sb);
+ sb.append("(");
+ for (int i = 0; i < paramsSize; i++) {
+ if (i > 0) {
+ sb.append(", ");
+ }
+ sb.append("?");
+ }
+ sb.append(") }");
mv.visitLdcInsn(sb.toString());
mv.visitVarInsn(ALOAD, paramsSize+1);
Modified: trunk/jboss-integration/src/main/java/org/teiid/jboss/rest/TeiidRSProvider.java
===================================================================
--- trunk/jboss-integration/src/main/java/org/teiid/jboss/rest/TeiidRSProvider.java 2012-08-24 21:00:59 UTC (rev 4365)
+++ trunk/jboss-integration/src/main/java/org/teiid/jboss/rest/TeiidRSProvider.java 2012-08-25 20:38:37 UTC (rev 4366)
@@ -25,47 +25,38 @@
import java.io.InputStream;
import java.nio.charset.Charset;
import java.sql.Blob;
+import java.sql.CallableStatement;
import java.sql.Clob;
import java.sql.Connection;
-import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLXML;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.StringTokenizer;
+import java.util.LinkedHashMap;
-import org.teiid.core.types.DataTypeManager;
-import org.teiid.core.types.Transform;
+import org.teiid.core.types.BlobType;
import org.teiid.core.types.TransformationException;
+import org.teiid.core.types.XMLType;
import org.teiid.core.util.ReaderInputStream;
import org.teiid.jboss.IntegrationPlugin;
+import org.teiid.query.function.source.XMLSystemFunctions;
+import org.teiid.query.sql.symbol.XMLSerialize;
public abstract class TeiidRSProvider {
- public InputStream execute(String procedureSignature, Map<String, String> parameters, String charSet) throws SQLException {
+ public InputStream execute(String procedureSignature, LinkedHashMap<String, String> parameters, String charSet) throws SQLException {
Object result = null;
Connection conn = getConnection();
+ boolean usingReturn = procedureSignature.startsWith("{ ?"); //$NON-NLS-1$
try {
- List<String> paramTypes = getPathTypes(procedureSignature);
- final String executeStatement = "call " + procedureSignature.substring(0, procedureSignature.indexOf('(')) + (parameters.isEmpty() ? "()" : createParmString(parameters.size())) + ";"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-
- PreparedStatement statement = conn.prepareStatement(executeStatement);
+ //TODO: an alternative strategy would be to set the parameters based upon name
+ // which would also allow for less parameters to be passed than the procedure requires
+ // however an enhancement would be needed to support named parameters with callable syntax
+ // alternatively if the end parameters are defaultable, then they can be omitted.
+ CallableStatement statement = conn.prepareCall(procedureSignature);
if (!parameters.isEmpty()) {
- int i = 1;
- for (Object value : parameters.values()) {
- try {
- Transform t = DataTypeManager.getTransform(DataTypeManager.DefaultDataTypes.STRING, paramTypes.get(i-1));
- if (t != null) {
- statement.setObject(i++, t.transform(value));
- }
- else {
- statement.setString(i++, (String)value);
- }
- } catch (TransformationException e) {
- throw new SQLException(e);
- }
+ int i = usingReturn?2:1;
+ for (String value : parameters.values()) {
+ statement.setString(i++, value);
}
}
@@ -79,22 +70,38 @@
}
rs.close();
}
- else {
+ else if (!usingReturn){
throw new SQLException(IntegrationPlugin.Util.gs(IntegrationPlugin.Event.TEIID50092));
+ } else {
+ result = statement.getObject(1);
}
-
statement.close();
+ if (result == null) {
+ return null; //or should this be an empty result?
+ }
if (result instanceof SQLXML) {
+ if (charSet != null) {
+ XMLSerialize serialize = new XMLSerialize();
+ serialize.setTypeString("blob"); //$NON-NLS-1$
+ serialize.setDeclaration(true);
+ serialize.setEncoding(charSet);
+ serialize.setDocument(true);
+ try {
+ return ((BlobType)XMLSystemFunctions.serialize(serialize, (XMLType)result)).getBinaryStream();
+ } catch (TransformationException e) {
+ throw new SQLException(e);
+ }
+ }
return ((SQLXML)result).getBinaryStream();
}
else if (result instanceof Blob) {
return ((Blob)result).getBinaryStream();
}
else if (result instanceof Clob) {
- return new ReaderInputStream(((Clob)result).getCharacterStream(), Charset.forName(charSet));
+ return new ReaderInputStream(((Clob)result).getCharacterStream(), charSet==null?Charset.defaultCharset():Charset.forName(charSet));
}
- return new ByteArrayInputStream(result.toString().getBytes());
+ return new ByteArrayInputStream(result.toString().getBytes(charSet==null?Charset.defaultCharset():Charset.forName(charSet)));
} finally {
if (conn != null) {
try {
@@ -105,28 +112,6 @@
}
}
- protected String createParmString(int paramCount ) {
- StringBuilder sb = new StringBuilder();
- sb.append("(?"); //$NON-NLS-1$
- for (int i = 1; i < paramCount; i++) {
- sb.append(","); //$NON-NLS-1$
- sb.append("?"); //$NON-NLS-1$
- }
- sb.append(")"); //$NON-NLS-1$
- return sb.toString();
- }
-
- private ArrayList<String> getPathTypes(String pathStr ) {
- ArrayList pathParams = new ArrayList();
-
- String parms = pathStr.substring(pathStr.indexOf('(')+1, pathStr.indexOf(')'));
- StringTokenizer st = new StringTokenizer(parms, ","); //$NON-NLS-1$
- while (st.hasMoreTokens()) {
- pathParams.add(st.nextToken());
- }
- return pathParams;
- }
-
protected abstract Connection getConnection() throws SQLException;
}
12 years, 4 months
teiid SVN: r4365 - trunk/build/kits/jboss-as7/docs/teiid.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2012-08-24 17:00:59 -0400 (Fri, 24 Aug 2012)
New Revision: 4365
Modified:
trunk/build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html
Log:
TEIID-2163 adding a release notE
Modified: trunk/build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html
===================================================================
--- trunk/build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html 2012-08-24 19:54:48 UTC (rev 4364)
+++ trunk/build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html 2012-08-24 21:00:59 UTC (rev 4365)
@@ -30,6 +30,7 @@
<li>TEIID-2148 <b>Streaming Improvements</b> - the ws translator invoke/invokeHttp procedures now accept a "stream"" parameter to indicate that the result should be streamed directly without an intermediate copy being created.
Also intermediate document/blob copies are made concurrently with reading to reduce latency.
<li>TEIID-2158 <b>Rest Services</b> - when required extension metadata defined on the virtual procedure, a REST based service on that procedure is automatically generated and deployed upon VDB deployment.
+ <li>TEIID-2163 <b>Binary XMLSERIALIZE</b> - XMLSERIALIZE now supports blob/varbinary and the encoding/version and XMLDECLARATION options.
</ul>
<h2><a name="Compatibility">Compatibility Issues</a></h2>
12 years, 4 months
teiid SVN: r4364 - in trunk: api/src/main/java/org/teiid/metadata and 16 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2012-08-24 15:54:48 -0400 (Fri, 24 Aug 2012)
New Revision: 4364
Added:
trunk/api/src/main/java/org/teiid/util/XMLReader.java
trunk/api/src/test/java/org/teiid/util/TestXMLReader.java
Modified:
trunk/api/src/main/java/org/teiid/language/SQLConstants.java
trunk/api/src/main/java/org/teiid/metadata/AbstractMetadataRecord.java
trunk/api/src/main/java/org/teiid/util/StAXSQLXML.java
trunk/api/src/main/java/org/teiid/util/XMLInputStream.java
trunk/api/src/test/java/org/teiid/util/TestXMLInputStream.java
trunk/common-core/src/main/java/org/teiid/core/types/InputStreamFactory.java
trunk/common-core/src/main/java/org/teiid/core/types/XMLType.java
trunk/common-core/src/test/java/org/teiid/core/types/basic/TestStringToXmlTransform.java
trunk/engine/src/main/java/org/teiid/query/eval/Evaluator.java
trunk/engine/src/main/java/org/teiid/query/function/source/XMLSystemFunctions.java
trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
trunk/engine/src/main/java/org/teiid/query/sql/symbol/XMLSerialize.java
trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java
trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java
trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj
trunk/engine/src/main/resources/org/teiid/query/i18n.properties
trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java
trunk/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java
trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java
trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java
Log:
TEIID-2163 adding support for binary xmlserialize
Modified: trunk/api/src/main/java/org/teiid/language/SQLConstants.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/SQLConstants.java 2012-08-23 18:14:04 UTC (rev 4363)
+++ trunk/api/src/main/java/org/teiid/language/SQLConstants.java 2012-08-24 19:54:48 UTC (rev 4364)
@@ -120,6 +120,10 @@
public static final String TRIM = "TRIM"; //$NON-NLS-1$
public static final String RESULT = "RESULT"; //$NON-NLS-1$
public static final Object OBJECTTABLE = "OBJECTTABLE"; //$NON-NLS-1$
+ public static final Object VERSION = "VERSION"; //$NON-NLS-1$
+ public static final Object INCLUDING = "INCLUDING"; //$NON-NLS-1$
+ public static final Object EXCLUDING = "EXCLUDING"; //$NON-NLS-1$
+ public static final Object XMLDECLARATION = "XMLDECLARATION"; //$NON-NLS-1$
}
public interface Reserved {
Modified: trunk/api/src/main/java/org/teiid/metadata/AbstractMetadataRecord.java
===================================================================
--- trunk/api/src/main/java/org/teiid/metadata/AbstractMetadataRecord.java 2012-08-23 18:14:04 UTC (rev 4363)
+++ trunk/api/src/main/java/org/teiid/metadata/AbstractMetadataRecord.java 2012-08-24 19:54:48 UTC (rev 4364)
@@ -32,6 +32,7 @@
import org.teiid.core.types.DataTypeManager;
import org.teiid.core.util.EquivalenceUtil;
+import org.teiid.core.util.StringUtil;
/**
@@ -94,7 +95,26 @@
}
return name;
}
+
+ public void getSQLString(StringBuilder sb) {
+ AbstractMetadataRecord parent = getParent();
+ if (parent != null) {
+ parent.getSQLString(sb);
+ sb.append(NAME_DELIM_CHAR);
+ }
+ sb.append('"').append(StringUtil.replace(name, "\"", "\"\"")).append('"'); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ /**
+ * Get the full name as a SQL safe string
+ * @return
+ */
+ public String getSQLString() {
+ StringBuilder sb = new StringBuilder();
+ getSQLString(sb);
+ return sb.toString();
+ }
+
public AbstractMetadataRecord getParent() {
return null;
}
Modified: trunk/api/src/main/java/org/teiid/util/StAXSQLXML.java
===================================================================
--- trunk/api/src/main/java/org/teiid/util/StAXSQLXML.java 2012-08-23 18:14:04 UTC (rev 4363)
+++ trunk/api/src/main/java/org/teiid/util/StAXSQLXML.java 2012-08-24 19:54:48 UTC (rev 4364)
@@ -24,7 +24,9 @@
import java.io.IOException;
import java.io.InputStream;
+import java.io.Reader;
import java.io.StringWriter;
+import java.nio.charset.Charset;
import java.sql.SQLException;
import javax.xml.stream.FactoryConfigurationError;
@@ -36,27 +38,52 @@
import org.teiid.core.types.SQLXMLImpl;
import org.teiid.core.types.StandardXMLTranslator;
+import org.teiid.core.types.Streamable;
/**
* NOTE that this representation of XML does become unreadable after a read operation.
*/
public class StAXSQLXML extends SQLXMLImpl {
- private StAXSource source;
-
- public StAXSQLXML(StAXSource source) {
- this.source = source;
+
+ public interface StAXSourceProvider {
+ StAXSource getStaxSource() throws SQLException;
}
-
- @SuppressWarnings("unchecked")
- public <T extends Source> T getSource(Class<T> sourceClass) throws SQLException {
- if (sourceClass == null || sourceClass == StAXSource.class) {
+
+ private static final class SingleUseStAXSourceProvider implements
+ StAXSourceProvider {
+ private StAXSource source;
+
+ public SingleUseStAXSourceProvider(StAXSource source) {
+ this.source = source;
+ }
+
+ @Override
+ public StAXSource getStaxSource() throws SQLException {
if (source == null) {
throw new SQLException("Already Freed"); //$NON-NLS-1$
}
StAXSource result = source;
source = null;
- return (T) result;
+ return result;
}
+ }
+
+ private StAXSourceProvider sourceProvider;
+
+ public StAXSQLXML(StAXSource source) {
+ this(new SingleUseStAXSourceProvider(source), Streamable.CHARSET);
+ }
+
+ public StAXSQLXML(StAXSourceProvider provider, Charset charSet) {
+ this.sourceProvider = provider;
+ this.setCharset(charSet);
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T extends Source> T getSource(Class<T> sourceClass) throws SQLException {
+ if (sourceClass == null || sourceClass == StAXSource.class) {
+ return (T) sourceProvider.getStaxSource();
+ }
return super.getSource(sourceClass);
}
@@ -76,7 +103,7 @@
@Override
public InputStream getBinaryStream() throws SQLException {
try {
- return new XMLInputStream(getSource(StAXSource.class), XMLOutputFactory.newFactory());
+ return new XMLInputStream(getSource(StAXSource.class), XMLOutputFactory.newFactory(), getCharset().name());
} catch (XMLStreamException e) {
throw new SQLException(e);
} catch (FactoryConfigurationError e) {
@@ -84,4 +111,15 @@
}
}
+ @Override
+ public Reader getCharacterStream() throws SQLException {
+ try {
+ return new XMLReader(getSource(StAXSource.class), XMLOutputFactory.newFactory());
+ } catch (XMLStreamException e) {
+ throw new SQLException(e);
+ } catch (FactoryConfigurationError e) {
+ throw new SQLException(e);
+ }
+ }
+
}
\ No newline at end of file
Modified: trunk/api/src/main/java/org/teiid/util/XMLInputStream.java
===================================================================
--- trunk/api/src/main/java/org/teiid/util/XMLInputStream.java 2012-08-23 18:14:04 UTC (rev 4363)
+++ trunk/api/src/main/java/org/teiid/util/XMLInputStream.java 2012-08-24 19:54:48 UTC (rev 4364)
@@ -32,22 +32,36 @@
import javax.xml.stream.events.XMLEvent;
import javax.xml.transform.stax.StAXSource;
+import org.teiid.core.types.Streamable;
import org.teiid.core.types.XMLType;
import org.teiid.core.util.AccessibleByteArrayOutputStream;
+/**
+ * Provides an {@link InputStream} adapter for StAX
+ */
public class XMLInputStream extends InputStream {
private static final int BUFFER_SIZE = 1<<13;
private int pos = 0;
private AccessibleByteArrayOutputStream baos = new AccessibleByteArrayOutputStream(BUFFER_SIZE);
private XMLEventReader reader;
private XMLEventWriter writer;
+
+ /**
+ * Return a UTF-8 {@link InputStream} of the XML
+ * @param source
+ * @param outFactory
+ * @throws XMLStreamException
+ */
+ public XMLInputStream(StAXSource source, XMLOutputFactory outFactory) throws XMLStreamException {
+ this(source, outFactory, Streamable.ENCODING);
+ }
- public XMLInputStream(StAXSource source, XMLOutputFactory outFactory) throws XMLStreamException {
+ public XMLInputStream(StAXSource source, XMLOutputFactory outFactory, String encoding) throws XMLStreamException {
reader = source.getXMLEventReader();
if (reader == null) {
this.reader = XMLType.getXmlInputFactory().createXMLEventReader(source.getXMLStreamReader());
}
- this.writer = outFactory.createXMLEventWriter(baos);
+ this.writer = outFactory.createXMLEventWriter(baos, encoding);
}
@Override
@@ -68,7 +82,7 @@
throw new IOException(e);
}
}
- return baos.getBuffer()[pos++];
+ return 0xff & baos.getBuffer()[pos++];
}
@Override
Added: trunk/api/src/main/java/org/teiid/util/XMLReader.java
===================================================================
--- trunk/api/src/main/java/org/teiid/util/XMLReader.java (rev 0)
+++ trunk/api/src/main/java/org/teiid/util/XMLReader.java 2012-08-24 19:54:48 UTC (rev 4364)
@@ -0,0 +1,126 @@
+/*
+ * 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.
+ */
+
+package org.teiid.util;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLEventWriter;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.XMLEvent;
+import javax.xml.transform.stax.StAXSource;
+
+import org.teiid.core.types.XMLType;
+
+/**
+ * Provides a {@link Reader} adapter for StAX
+ */
+public class XMLReader extends Reader {
+ private static final int BUFFER_SIZE = 1<<13;
+ private int pos = 0;
+ private StringBuilder builder = new StringBuilder(BUFFER_SIZE);
+ private XMLEventReader reader;
+ private XMLEventWriter writer;
+
+ public XMLReader(StAXSource source, XMLOutputFactory outFactory) throws XMLStreamException {
+ reader = source.getXMLEventReader();
+ if (reader == null) {
+ this.reader = XMLType.getXmlInputFactory().createXMLEventReader(source.getXMLStreamReader());
+ }
+ this.writer = outFactory.createXMLEventWriter(new Writer() {
+
+ @Override
+ public void write(char[] cbuf, int off, int len) throws IOException {
+ builder.append(cbuf, off, len);
+ }
+
+ @Override
+ public void flush() throws IOException {
+
+ }
+
+ @Override
+ public void write(String str, int off, int len) throws IOException {
+ builder.append(str, off, len);
+ }
+
+ @Override
+ public void close() throws IOException {
+
+ }
+ });
+ }
+
+ @Override
+ public int read() throws IOException {
+ while (pos >= builder.length()) {
+ if (!reader.hasNext()) {
+ return -1;
+ }
+ if (builder.length() > BUFFER_SIZE) {
+ builder.setLength(0);
+ pos = 0;
+ }
+ try {
+ XMLEvent event = reader.nextEvent();
+ writer.add(event);
+ writer.flush();
+ } catch (XMLStreamException e) {
+ throw new IOException(e);
+ }
+ }
+ return builder.charAt(pos++);
+ }
+
+
+ @Override
+ public void close() throws IOException {
+ try {
+ reader.close();
+ } catch (XMLStreamException e) {
+ throw new IOException(e);
+ }
+ }
+
+ @Override
+ public int read(char[] cbuf, int off, int len) throws IOException {
+ int i = 0;
+ int c = 0;
+ for (i = 0; i < len; i++) {
+ c = read();
+ if (c == -1) {
+ if (i == 0) {
+ return -1;
+ }
+ break;
+ }
+ cbuf[i+off] = (char)c;
+ }
+ return i;
+ }
+
+
+}
\ No newline at end of file
Property changes on: trunk/api/src/main/java/org/teiid/util/XMLReader.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: trunk/api/src/test/java/org/teiid/util/TestXMLInputStream.java
===================================================================
--- trunk/api/src/test/java/org/teiid/util/TestXMLInputStream.java 2012-08-23 18:14:04 UTC (rev 4363)
+++ trunk/api/src/test/java/org/teiid/util/TestXMLInputStream.java 2012-08-24 19:54:48 UTC (rev 4364)
@@ -51,5 +51,21 @@
byte[] bytes = ObjectConverterUtil.convertToByteArray(is);
assertEquals(xml, new String(bytes, "UTF-8"));
}
+
+ @Test public void testUTF16Streaming() throws Exception {
+ StringBuilder xmlBuilder = new StringBuilder();
+ xmlBuilder.append("<?xml version=\"1.0\"?><root>");
+ for (int i = 0; i < 1000; i++) {
+ xmlBuilder.append("<a></a>");
+ xmlBuilder.append("<b></b>");
+ }
+ xmlBuilder.append("</root>");
+ String xml = xmlBuilder.toString();
+
+ StAXSource source = new StAXSource(XMLType.getXmlInputFactory().createXMLEventReader(new StringReader(xml)));
+ XMLInputStream is = new XMLInputStream(source, XMLOutputFactory.newFactory(), "UTF-16");
+ byte[] bytes = ObjectConverterUtil.convertToByteArray(is);
+ assertEquals(xml, new String(bytes, "UTF-16"));
+ }
}
Added: trunk/api/src/test/java/org/teiid/util/TestXMLReader.java
===================================================================
--- trunk/api/src/test/java/org/teiid/util/TestXMLReader.java (rev 0)
+++ trunk/api/src/test/java/org/teiid/util/TestXMLReader.java 2012-08-24 19:54:48 UTC (rev 4364)
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+package org.teiid.util;
+
+import static org.junit.Assert.*;
+
+import java.io.StringReader;
+
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.transform.stax.StAXSource;
+
+import org.junit.Test;
+import org.teiid.core.types.XMLType;
+import org.teiid.core.util.ObjectConverterUtil;
+
+@SuppressWarnings("nls")
+public class TestXMLReader {
+
+ @Test public void testStreaming() throws Exception {
+ StringBuilder xmlBuilder = new StringBuilder();
+ xmlBuilder.append("<?xml version=\"1.0\"?><root>");
+ for (int i = 0; i < 1000; i++) {
+ xmlBuilder.append("<a></a>");
+ xmlBuilder.append("<b></b>");
+ }
+ xmlBuilder.append("</root>");
+ String xml = xmlBuilder.toString();
+
+ StAXSource source = new StAXSource(XMLType.getXmlInputFactory().createXMLEventReader(new StringReader(xml)));
+ XMLReader is = new XMLReader(source, XMLOutputFactory.newFactory());
+ String str = ObjectConverterUtil.convertToString(is);
+ assertEquals(xml, str);
+ }
+
+}
Property changes on: trunk/api/src/test/java/org/teiid/util/TestXMLReader.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: trunk/common-core/src/main/java/org/teiid/core/types/InputStreamFactory.java
===================================================================
--- trunk/common-core/src/main/java/org/teiid/core/types/InputStreamFactory.java 2012-08-23 18:14:04 UTC (rev 4363)
+++ trunk/common-core/src/main/java/org/teiid/core/types/InputStreamFactory.java 2012-08-24 19:54:48 UTC (rev 4364)
@@ -262,7 +262,7 @@
public static class SQLXMLInputStreamFactory extends InputStreamFactory implements DataSource {
- private SQLXML sqlxml;
+ protected SQLXML sqlxml;
public SQLXMLInputStreamFactory(SQLXML sqlxml) {
this.sqlxml = sqlxml;
Modified: trunk/common-core/src/main/java/org/teiid/core/types/XMLType.java
===================================================================
--- trunk/common-core/src/main/java/org/teiid/core/types/XMLType.java 2012-08-23 18:14:04 UTC (rev 4363)
+++ trunk/common-core/src/main/java/org/teiid/core/types/XMLType.java 2012-08-24 19:54:48 UTC (rev 4364)
@@ -136,6 +136,9 @@
}
public String getEncoding() {
+ if (encoding == null) {
+ this.encoding = getEncoding(this);
+ }
return encoding;
}
@@ -211,7 +214,7 @@
if (xml instanceof SQLXMLImpl) {
Charset cs = ((SQLXMLImpl)xml).getCharset();
if (cs != null) {
- return cs.displayName();
+ return cs.name();
}
}
return getEncoding(xml.getBinaryStream());
Modified: trunk/common-core/src/test/java/org/teiid/core/types/basic/TestStringToXmlTransform.java
===================================================================
--- trunk/common-core/src/test/java/org/teiid/core/types/basic/TestStringToXmlTransform.java 2012-08-23 18:14:04 UTC (rev 4363)
+++ trunk/common-core/src/test/java/org/teiid/core/types/basic/TestStringToXmlTransform.java 2012-08-24 19:54:48 UTC (rev 4364)
@@ -28,7 +28,7 @@
import org.junit.Test;
import org.teiid.core.types.TransformationException;
-import org.teiid.core.types.basic.StringToSQLXMLTransform;
+import org.teiid.core.types.XMLType;
@SuppressWarnings("nls")
@@ -45,6 +45,19 @@
SQLXML xmlValue = (SQLXML)transform.transformDirect(xml);
assertEquals(xml.replaceAll("[\r]", ""), xmlValue.getString().replaceAll("[\r]", ""));
}
+
+ @Test public void testGoodElement() throws Exception {
+ String xml = "<customer>\n" + //$NON-NLS-1$
+ "<name>ABC</name>" + //$NON-NLS-1$
+ "<age>32</age>" + //$NON-NLS-1$
+ "</customer>"; //$NON-NLS-1$
+
+ StringToSQLXMLTransform transform = new StringToSQLXMLTransform();
+
+ XMLType xmlValue = (XMLType)transform.transformDirect(xml);
+ assertEquals(xml.replaceAll("[\r]", ""), xmlValue.getString().replaceAll("[\r]", ""));
+ assertEquals(XMLType.Type.ELEMENT, xmlValue.getType());
+ }
@Test(expected=TransformationException.class) public void testBadXML() throws Exception {
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><customer>\n" + //$NON-NLS-1$
Modified: trunk/engine/src/main/java/org/teiid/query/eval/Evaluator.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/eval/Evaluator.java 2012-08-23 18:14:04 UTC (rev 4363)
+++ trunk/engine/src/main/java/org/teiid/query/eval/Evaluator.java 2012-08-24 19:54:48 UTC (rev 4364)
@@ -54,7 +54,15 @@
import org.teiid.core.TeiidComponentException;
import org.teiid.core.TeiidProcessingException;
import org.teiid.core.TeiidRuntimeException;
-import org.teiid.core.types.*;
+import org.teiid.core.types.BaseLob;
+import org.teiid.core.types.BlobType;
+import org.teiid.core.types.ClobType;
+import org.teiid.core.types.InputStreamFactory;
+import org.teiid.core.types.SQLXMLImpl;
+import org.teiid.core.types.Sequencable;
+import org.teiid.core.types.Streamable;
+import org.teiid.core.types.TransformationException;
+import org.teiid.core.types.XMLType;
import org.teiid.core.types.XMLType.Type;
import org.teiid.core.types.basic.StringToSQLXMLTransform;
import org.teiid.core.util.EquivalenceUtil;
@@ -694,8 +702,20 @@
return xml;
}
- //TODO: determine when wrapping is not needed
public static InputStreamFactory getInputStreamFactory(Streamable<?> s) {
+ if (s.getReference() instanceof Streamable<?>) {
+ return getInputStreamFactory((Streamable<?>) s.getReference());
+ }
+ if (s.getReference() instanceof BaseLob) {
+ BaseLob bl = (BaseLob) s.getReference();
+ try {
+ InputStreamFactory isf = bl.getStreamFactory();
+ if (isf != null) {
+ return isf;
+ }
+ } catch (SQLException e) {
+ }
+ }
if (s instanceof ClobType) {
return new InputStreamFactory.ClobInputStreamFactory((Clob)s.getReference());
} else if (s instanceof BlobType){
@@ -796,14 +816,14 @@
}
try {
if (xs.isDocument() == null || !xs.isDocument()) {
- return serialize(xs, value);
+ return XMLSystemFunctions.serialize(xs, value);
}
if (value.getType() == Type.UNKNOWN) {
Type type = StringToSQLXMLTransform.isXml(value.getCharacterStream());
value.setType(type);
}
if (value.getType() == Type.DOCUMENT || value.getType() == Type.ELEMENT) {
- return serialize(xs, value);
+ return XMLSystemFunctions.serialize(xs, value);
}
} catch (SQLException e) {
throw new FunctionExecutionException(QueryPlugin.Event.TEIID30334, e);
@@ -813,14 +833,6 @@
throw new FunctionExecutionException(QueryPlugin.Event.TEIID30336, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30336));
}
- private Object serialize(XMLSerialize xs, XMLType value) throws TransformationException {
- if (xs.getType() == DataTypeManager.DefaultDataClasses.STRING) {
- return DataTypeManager.transformValue(value, xs.getType());
- }
- InputStreamFactory isf = getInputStreamFactory(value);
- return new ClobType(new ClobImpl(isf, -1));
- }
-
private Object evaluateTextLine(List<?> tuple, TextLine function) throws ExpressionEvaluationException, BlockedException, TeiidComponentException, FunctionExecutionException {
List<DerivedColumn> args = function.getExpressions();
Evaluator.NameValuePair<Object>[] nameValuePairs = getNameValuePairs(tuple, args, true);
Modified: trunk/engine/src/main/java/org/teiid/query/function/source/XMLSystemFunctions.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/source/XMLSystemFunctions.java 2012-08-23 18:14:04 UTC (rev 4363)
+++ trunk/engine/src/main/java/org/teiid/query/function/source/XMLSystemFunctions.java 2012-08-24 19:54:48 UTC (rev 4364)
@@ -42,6 +42,7 @@
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
+import java.util.NoSuchElementException;
import javax.xml.XMLConstants;
import javax.xml.namespace.QName;
@@ -55,6 +56,7 @@
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.XMLEvent;
+import javax.xml.stream.util.EventReaderDelegate;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
@@ -82,23 +84,22 @@
import org.teiid.common.buffer.BufferManager;
import org.teiid.common.buffer.FileStore;
import org.teiid.common.buffer.FileStoreInputStreamFactory;
+import org.teiid.core.CorePlugin;
import org.teiid.core.TeiidComponentException;
import org.teiid.core.TeiidProcessingException;
import org.teiid.core.TeiidRuntimeException;
-import org.teiid.core.types.ClobImpl;
-import org.teiid.core.types.ClobType;
-import org.teiid.core.types.SQLXMLImpl;
-import org.teiid.core.types.StandardXMLTranslator;
-import org.teiid.core.types.Streamable;
-import org.teiid.core.types.XMLTranslator;
-import org.teiid.core.types.XMLType;
+import org.teiid.core.types.*;
import org.teiid.core.types.XMLType.Type;
+import org.teiid.core.util.ObjectConverterUtil;
+import org.teiid.core.util.ReaderInputStream;
import org.teiid.query.QueryPlugin;
import org.teiid.query.eval.Evaluator;
import org.teiid.query.function.CharsetUtils;
+import org.teiid.query.sql.symbol.XMLSerialize;
import org.teiid.query.util.CommandContext;
import org.teiid.translator.WSConnection.Util;
import org.teiid.util.StAXSQLXML;
+import org.teiid.util.StAXSQLXML.StAXSourceProvider;
/**
@@ -141,6 +142,63 @@
}
};
+ private static final EventFilter declarationOmittingFilter = new EventFilter() {
+ @Override
+ public boolean accept(XMLEvent event) {
+ return !event.isStartDocument() && !event.isEndDocument();
+ }
+ };
+
+ private static final class DeclarationStaxSourceProvider implements
+ StAXSourceProvider {
+ private final XMLEvent start;
+ private XMLType value;
+
+ private DeclarationStaxSourceProvider(XMLEvent start, XMLType value) {
+ this.start = start;
+ this.value = value;
+ }
+
+ @Override
+ public StAXSource getStaxSource() throws SQLException {
+ StAXSource source = value.getSource(StAXSource.class);
+ try {
+ XMLEventReader reader = getXMLEventReader(source);
+ reader = new EventReaderDelegate(reader) {
+ @Override
+ public XMLEvent nextEvent() throws XMLStreamException {
+ return replaceStart(super.nextEvent());
+ }
+
+ @Override
+ public XMLEvent peek() throws XMLStreamException {
+ return replaceStart(super.peek());
+ }
+
+ private XMLEvent replaceStart(XMLEvent event) {
+ if (event != null && event.getEventType() == XMLEvent.START_DOCUMENT) {
+ return start;
+ }
+ return event;
+ }
+
+ @Override
+ public Object next() {
+ try {
+ return nextEvent();
+ } catch (XMLStreamException e) {
+ throw new NoSuchElementException();
+ }
+ }
+ };
+ return new StAXSource(reader);
+ } catch (XMLStreamException e) {
+ throw new SQLException(e);
+ }
+ }
+
+ }
+
private static final class JsonToXmlContentHandler implements
ContentHandler, XMLEventReader {
private Reader reader;
@@ -352,6 +410,15 @@
}
static XMLOutputFactory xmlOutputFactory = newXmlOutputFactory();
+ private static XMLEventReader getXMLEventReader(StAXSource source) throws XMLStreamException {
+ XMLEventReader reader = source.getXMLEventReader();
+ if (reader == null) {
+ XMLInputFactory inputFactory = XMLType.getXmlInputFactory();
+ reader = inputFactory.createXMLEventReader(source.getXMLStreamReader());
+ }
+ return reader;
+ }
+
public static XMLOutputFactory getOutputFactory() throws FactoryConfigurationError {
if (XMLType.isThreadSafeXmlFactories()) {
return xmlOutputFactory;
@@ -630,13 +697,12 @@
try {
if (object instanceof XMLType) {
XMLType xml = (XMLType)object;
- r = xml.getCharacterStream();
Type type = xml.getType();
- convertReader(writer, eventWriter, r, type);
+ convertReader(writer, eventWriter, null, type, xml);
} else if (object instanceof Clob) {
Clob clob = (Clob)object;
r = clob.getCharacterStream();
- convertReader(writer, eventWriter, r, Type.TEXT);
+ convertReader(writer, eventWriter, r, Type.TEXT, null);
} else {
String val = convertToAtomicValue(object).getStringValue();
eventWriter.add(eventFactory.createCharacters(val));
@@ -652,8 +718,8 @@
}
private static void convertReader(Writer writer,
- XMLEventWriter eventWriter, Reader r, Type type)
- throws XMLStreamException, IOException, FactoryConfigurationError {
+ XMLEventWriter eventWriter, Reader r, Type type, XMLType xml)
+ throws XMLStreamException, IOException, FactoryConfigurationError, SQLException {
switch(type) {
case CONTENT:
case ELEMENT:
@@ -662,6 +728,9 @@
eventWriter.flush();
char[] buf = new char[1 << 13];
int read = -1;
+ if (r == null) {
+ r = xml.getCharacterStream();
+ }
while ((read = r.read(buf)) != -1) {
writer.write(buf, 0, read);
}
@@ -669,20 +738,27 @@
}
case UNKNOWN: //assume a document
case DOCUMENT: //filter the doc declaration
+ XMLEventReader eventReader = null;
XMLInputFactory inputFactory = XMLType.getXmlInputFactory();
- if (!(r instanceof BufferedReader)) {
- r = new BufferedReader(r);
+ if (r != null) {
+ if (!(r instanceof BufferedReader)) {
+ r = new BufferedReader(r);
+ }
+ eventReader = inputFactory.createXMLEventReader(r);
+ } else {
+ StAXSource staxSource = xml.getSource(StAXSource.class);
+ eventReader = staxSource.getXMLEventReader();
+ if (eventReader == null) {
+ eventReader = inputFactory.createXMLEventReader(staxSource.getXMLStreamReader());
+ }
}
- XMLEventReader eventReader = inputFactory.createXMLEventReader(r);
- eventReader = inputFactory.createFilteredReader(eventReader, new EventFilter() {
- @Override
- public boolean accept(XMLEvent event) {
- return !event.isStartDocument() && !event.isEndDocument();
- }
- });
+ eventReader = inputFactory.createFilteredReader(eventReader, declarationOmittingFilter);
eventWriter.add(eventReader);
break;
case TEXT:
+ if (r == null) {
+ r = xml.getCharacterStream();
+ }
XMLEventFactory eventFactory = threadLocalEventtFactory.get();
char[] buf = new char[1 << 13];
int read = -1;
@@ -919,5 +995,89 @@
}
}
}
+
+ public static Object serialize(XMLSerialize xs, XMLType value) throws TransformationException {
+ Type type = value.getType();
+ final Charset encoding;
+ if (xs.getEncoding() != null) {
+ encoding = Charset.forName(xs.getEncoding());
+ } else {
+ encoding = UTF_8;
+ }
+ if (Boolean.TRUE.equals(xs.getDeclaration())) {
+ //need to replace existing/default declaration
+ if (type == Type.ELEMENT || type == Type.DOCUMENT) {
+ XMLEventFactory xmlEventFactory = threadLocalEventtFactory.get();
+ xmlEventFactory.setLocation(dummyLocation);
+ XMLEvent start = null;
+ if (xs.getVersion() != null) {
+ start = xmlEventFactory.createStartDocument(encoding.name(), xs.getVersion());
+ } else if (xs.getEncoding() != null) {
+ start = xmlEventFactory.createStartDocument(encoding.name());
+ } else {
+ start = xmlEventFactory.createStartDocument();
+ }
+ StAXSourceProvider sourceProvider = new DeclarationStaxSourceProvider(start, value);
+ value = new XMLType(new StAXSQLXML(sourceProvider, encoding));
+ value.setType(type);
+ }
+ //else just ignore, since the result is likely invalid
+ } else if (type == Type.DOCUMENT && Boolean.FALSE.equals(xs.getDeclaration())){
+ final XMLType v = value;
+ StAXSourceProvider sourceProvider = new StAXSourceProvider() {
+ @Override
+ public StAXSource getStaxSource() throws SQLException {
+ try {
+ XMLEventReader eventReader = getXMLEventReader(v.getSource(StAXSource.class));
+ eventReader = XMLType.getXmlInputFactory().createFilteredReader(eventReader, declarationOmittingFilter);
+ return new StAXSource(eventReader);
+ } catch (XMLStreamException e) {
+ throw new SQLException(e);
+ }
+ }
+ };
+ value = new XMLType(new StAXSQLXML(sourceProvider, encoding));
+ value.setType(Type.DOCUMENT);
+ }
+ if (xs.getType() == DataTypeManager.DefaultDataClasses.STRING) {
+ return DataTypeManager.transformValue(value, xs.getType());
+ }
+ if (xs.getType() == DataTypeManager.DefaultDataClasses.CLOB) {
+ InputStreamFactory isf = Evaluator.getInputStreamFactory(value);
+ return new ClobType(new ClobImpl(isf, -1));
+ }
+ if (xs.getType() == DataTypeManager.DefaultDataClasses.VARBINARY) {
+ try {
+ InputStream is = null;
+ if (!Charset.forName(value.getEncoding()).equals(encoding)) {
+ is = new ReaderInputStream(value.getCharacterStream(), encoding);
+ } else {
+ is = value.getBinaryStream();
+ }
+ byte[] bytes = ObjectConverterUtil.convertToByteArray(is, DataTypeManager.MAX_LOB_MEMORY_BYTES);
+ return new BinaryType(bytes);
+ } catch (SQLException e) {
+ throw new TransformationException(CorePlugin.Event.TEIID10080, e, CorePlugin.Util.gs(CorePlugin.Event.TEIID10080, "XML", "VARBINARY")); //$NON-NLS-1$ //$NON-NLS-2$
+ } catch (IOException e) {
+ throw new TransformationException(CorePlugin.Event.TEIID10080, e, CorePlugin.Util.gs(CorePlugin.Event.TEIID10080, "XML", "VARBINARY")); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+ InputStreamFactory isf = null;
+ if (!Charset.forName(value.getEncoding()).equals(encoding)) {
+ //create a wrapper for the input stream
+ isf = new InputStreamFactory.SQLXMLInputStreamFactory(value) {
+ public InputStream getInputStream() throws IOException {
+ try {
+ return new ReaderInputStream(sqlxml.getCharacterStream(), encoding);
+ } catch (SQLException e) {
+ throw new IOException(e);
+ }
+ }
+ };
+ } else {
+ isf = Evaluator.getInputStreamFactory(value);
+ }
+ return new BlobType(new BlobImpl(isf));
+ }
}
Modified: trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java 2012-08-23 18:14:04 UTC (rev 4363)
+++ trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java 2012-08-24 19:54:48 UTC (rev 4364)
@@ -24,6 +24,7 @@
import java.math.BigDecimal;
import java.math.BigInteger;
+import java.nio.charset.Charset;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
@@ -1949,6 +1950,22 @@
expression = rewriteExpressionDirect(((ExpressionSymbol)expression).getExpression());
} else if (expression instanceof Criteria) {
expression = rewriteCriteria((Criteria)expression);
+ } else if (expression instanceof XMLSerialize) {
+ rewriteExpressions(expression);
+ XMLSerialize serialize = (XMLSerialize)expression;
+ if (isNull(serialize.getExpression())) {
+ return new Constant(null, serialize.getType());
+ }
+ if (serialize.getDeclaration() == null && serialize.isDocument()) {
+ if ((serialize.getVersion() != null && !serialize.getVersion().equals("1.0"))) { //$NON-NLS-1$
+ serialize.setDeclaration(true);
+ } else if (serialize.getEncoding() != null) {
+ Charset encoding = Charset.forName(serialize.getEncoding());
+ if (!encoding.equals(Charset.forName("UTF-8")) && !encoding.equals(Charset.forName("UTF-16"))) { //$NON-NLS-1$ //$NON-NLS-2$
+ serialize.setDeclaration(true);
+ }
+ }
+ }
} else {
rewriteExpressions(expression);
}
Modified: trunk/engine/src/main/java/org/teiid/query/sql/symbol/XMLSerialize.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/symbol/XMLSerialize.java 2012-08-23 18:14:04 UTC (rev 4363)
+++ trunk/engine/src/main/java/org/teiid/query/sql/symbol/XMLSerialize.java 2012-08-24 19:54:48 UTC (rev 4364)
@@ -23,6 +23,8 @@
package org.teiid.query.sql.symbol;
import org.teiid.core.types.DataTypeManager;
+import org.teiid.core.util.EquivalenceUtil;
+import org.teiid.core.util.HashCodeUtil;
import org.teiid.query.sql.LanguageVisitor;
import org.teiid.query.sql.visitor.SQLStringVisitor;
@@ -31,9 +33,12 @@
private static final long serialVersionUID = -6574662238317329252L;
private Boolean document;
+ private Boolean declaration;
private Expression expression;
private String typeString;
private Class<?> type;
+ private String version;
+ private String encoding;
@Override
public Class<?> getType() {
@@ -47,6 +52,30 @@
return type;
}
+ public String getEncoding() {
+ return encoding;
+ }
+
+ public void setEncoding(String encoding) {
+ this.encoding = encoding;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ public Boolean getDeclaration() {
+ return declaration;
+ }
+
+ public void setDeclaration(Boolean declaration) {
+ this.declaration = declaration;
+ }
+
public Expression getExpression() {
return expression;
}
@@ -83,12 +112,15 @@
clone.expression = (Expression)this.expression.clone();
clone.typeString = this.typeString;
clone.type = this.type;
+ clone.declaration = this.declaration;
+ clone.version = this.version;
+ clone.encoding = this.encoding;
return clone;
}
@Override
public int hashCode() {
- return expression.hashCode();
+ return HashCodeUtil.hashCode(expression.hashCode(), getType());
}
public boolean equals(Object obj) {
@@ -99,9 +131,12 @@
return false;
}
XMLSerialize other = (XMLSerialize)obj;
- return document == other.document
+ return EquivalenceUtil.areEqual(this.document, other.document)
&& this.expression.equals(other.expression)
- && this.getType() == other.getType();
+ && this.getType() == other.getType()
+ && EquivalenceUtil.areEqual(this.declaration, other.declaration)
+ && EquivalenceUtil.areEqual(this.version, other.version)
+ && EquivalenceUtil.areEqual(this.encoding, other.encoding);
}
@Override
Modified: trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java 2012-08-23 18:14:04 UTC (rev 4363)
+++ trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java 2012-08-24 19:54:48 UTC (rev 4364)
@@ -1922,6 +1922,28 @@
append(SPACE);
append(obj.getTypeString());
}
+ if (obj.getEncoding() != null) {
+ append(SPACE);
+ append(NonReserved.ENCODING);
+ append(SPACE);
+ append(escapeSinglePart(obj.getEncoding()));
+ }
+ if (obj.getVersion() != null) {
+ append(SPACE);
+ append(NonReserved.VERSION);
+ append(SPACE);
+ append(new Constant(obj.getVersion()));
+ }
+ if (obj.getDeclaration() != null) {
+ append(SPACE);
+ if (obj.getDeclaration()) {
+ append(NonReserved.INCLUDING);
+ } else {
+ append(NonReserved.EXCLUDING);
+ }
+ append(SPACE);
+ append(NonReserved.XMLDECLARATION);
+ }
append(Tokens.RPAREN);
}
Modified: trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java 2012-08-23 18:14:04 UTC (rev 4363)
+++ trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java 2012-08-24 19:54:48 UTC (rev 4364)
@@ -248,6 +248,20 @@
handleValidationError(QueryPlugin.Util.getString("ERR.015.012.0011"),obj); //$NON-NLS-1$
}
}
+
+ @Override
+ public void visit(XMLSerialize obj) {
+ if (obj.getEncoding() != null ) {
+ try {
+ Charset.forName(obj.getEncoding());
+ } catch (IllegalArgumentException e) {
+ handleValidationError(QueryPlugin.Util.getString("ValidationVisitor.invalid_encoding", obj.getEncoding()), obj); //$NON-NLS-1$
+ }
+ if ((obj.getType() != DataTypeManager.DefaultDataClasses.BLOB && obj.getType() != DataTypeManager.DefaultDataClasses.VARBINARY)) {
+ handleValidationError(QueryPlugin.Util.getString("ValidationVisitor.encoding_for_binary"), obj); //$NON-NLS-1$
+ }
+ }
+ }
public void visit(DependentSetCriteria obj) {
this.validateRowLimitFunctionNotInInvalidCriteria(obj);
Modified: trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj
===================================================================
--- trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj 2012-08-23 18:14:04 UTC (rev 4363)
+++ trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj 2012-08-24 19:54:48 UTC (rev 4364)
@@ -450,6 +450,10 @@
| <HEADER: "header">
| <NULLS: "nulls">
| <OBJECTTABLE: "objecttable">
+| <VERSION: "version">
+| <INCLUDING: "including">
+| <EXCLUDING: "excluding">
+| <XMLDECLARATION: "xmldeclaration">
}
/*
@@ -552,7 +556,12 @@
{
}
{
- (<INSTEAD>|<VIEW>|<ENABLED>|<DISABLED>|<KEY>|<SERIAL>|<TEXTAGG>|<COUNT>|<ROW_NUMBER>|<RANK>|<DENSE_RANK>|<SUM>|<AVG>|<MIN>|<MAX>|<EVERY>|<STDDEV_POP>|<STDDEV_SAMP>|<VAR_SAMP>|<VAR_POP>|<DOCUMENT>|<CONTENT>|<TRIM>|<EMPTY>|<ORDINALITY>|<PATH>|<FIRST>|<LAST>|<NEXT>|<SUBSTRING>|<EXTRACT>|<TO_CHARS>|<TO_BYTES>|<TIMESTAMPADD>|<TIMESTAMPDIFF>|<QUERYSTRING>|<NAMESPACE>|<RESULT>|<INDEX>|<ACCESSPATTERN>|<AUTO_INCREMENT>|<WELLFORMED>|<SQL_TSI_FRAC_SECOND>|<SQL_TSI_SECOND>|<SQL_TSI_MINUTE>|<SQL_TSI_HOUR>|<SQL_TSI_DAY>|<SQL_TSI_WEEK>|<SQL_TSI_MONTH>|<SQL_TSI_QUARTER>|<SQL_TSI_YEAR>|<TEXTTABLE>|<ARRAYTABLE>|<SELECTOR>|<SKIP_KEYWORD>|<WIDTH>|<PASSING>|<NAME>|<ENCODING>|<COLUMNS>|<DELIMITER>|<QUOTE>|<HEADER>|<NULLS>|<OBJECTTABLE>)
+ (<INSTEAD>|<VIEW>|<ENABLED>|<DISABLED>|<KEY>|<SERIAL>|<TEXTAGG>|<COUNT>|<ROW_NUMBER>|<RANK>|<DENSE_RANK>|<SUM>|<AVG>|<MIN>|<MAX>|<EVERY>|<STDDEV_POP>
+ |<STDDEV_SAMP>|<VAR_SAMP>|<VAR_POP>|<DOCUMENT>|<CONTENT>|<TRIM>|<EMPTY>|<ORDINALITY>|<PATH>|<FIRST>|<LAST>|<NEXT>|<SUBSTRING>|<EXTRACT>|<TO_CHARS>
+ |<TO_BYTES>|<TIMESTAMPADD>|<TIMESTAMPDIFF>|<QUERYSTRING>|<NAMESPACE>|<RESULT>|<INDEX>|<ACCESSPATTERN>|<AUTO_INCREMENT>|<WELLFORMED>|<SQL_TSI_FRAC_SECOND>
+ |<SQL_TSI_SECOND>|<SQL_TSI_MINUTE>|<SQL_TSI_HOUR>|<SQL_TSI_DAY>|<SQL_TSI_WEEK>|<SQL_TSI_MONTH>|<SQL_TSI_QUARTER>|<SQL_TSI_YEAR>|<TEXTTABLE>|<ARRAYTABLE>
+ |<SELECTOR>|<SKIP_KEYWORD>|<WIDTH>|<PASSING>|<NAME>|<ENCODING>|<COLUMNS>|<DELIMITER>|<QUOTE>|<HEADER>|<NULLS>|<OBJECTTABLE>
+ |<VERSION>|<INCLUDING>|<EXCLUDING>|<XMLDECLARATION>)
{
return getToken(0);
}
@@ -2326,17 +2335,26 @@
Expression expr = null;
Boolean doc = null;
Token t = null;
+ String enc = null;
+ Boolean declr = null;
+ String ver = null;
}
{
<XMLSERIALIZE> <LPAREN>
[LOOKAHEAD(1) (<DOCUMENT> {doc = true;}| <CONTENT> {doc = false;})]
expr = expression(info)
[
- <AS> (t = <STRING> | t = <VARCHAR> | t = <CLOB>)
+ <AS> (<STRING> | <VARCHAR> | <CLOB> | <VARBINARY> | <BLOB>) { t = getToken(0);}
]
+ [ <ENCODING> enc = id() ]
+ [ <VERSION> ver = stringVal() ]
+ [ ( <INCLUDING> {declr = true;}| <EXCLUDING> {declr = false;}) <XMLDECLARATION> ]
<RPAREN>
{
XMLSerialize result = new XMLSerialize();
+ result.setEncoding(enc);
+ result.setVersion(ver);
+ result.setDeclaration(declr);
result.setExpression(expr);
if (doc != null) {
result.setDocument(doc);
Modified: trunk/engine/src/main/resources/org/teiid/query/i18n.properties
===================================================================
--- trunk/engine/src/main/resources/org/teiid/query/i18n.properties 2012-08-23 18:14:04 UTC (rev 4363)
+++ trunk/engine/src/main/resources/org/teiid/query/i18n.properties 2012-08-24 19:54:48 UTC (rev 4364)
@@ -185,6 +185,7 @@
ValidationVisitor.no_loop = CONTINUE/BREAK can only be used in a LOOP/WHILE statement.
ValidationVisitor.invalid_label = CONTINUE/BREAK labels can only target LOOP/WHILE statements. {0} targets a block.
ValidationVisitor.unknown_block_label = No label found in containing scope with name {0}.
+ValidationVisitor.encoding_for_binary=The XMLSERIALIZE ENCODING option is only for binary serialization types.
ERR.015.012.0029 = INSERT, UPDATE, and DELETE not allowed on XML documents
ERR.015.012.0030 = Commands used in stored procedure language not allowed on XML documents
TEIID30130=Queries against XML documents can not have a GROUP By clause
Modified: trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java 2012-08-23 18:14:04 UTC (rev 4363)
+++ trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java 2012-08-24 19:54:48 UTC (rev 4364)
@@ -5073,6 +5073,18 @@
assertEquals("SELECT * FROM OBJECTTABLE(LANGUAGE 'foo' 'x' COLUMNS y date 'row.date' DEFAULT {d'2000-01-01'}) AS x", actualCommand.toString());
}
+ @Test public void testObjectTable1() throws Exception {
+ Query query = new Query();
+ query.setSelect(new Select(Arrays.asList(new MultipleElementSymbol())));
+ ObjectTable objectTable = new ObjectTable();
+ objectTable.setRowScript("y");
+ objectTable.setPassing(Arrays.asList(new DerivedColumn("y", new ElementSymbol("e1"))));
+ objectTable.setColumns(Arrays.asList(new ObjectTable.ObjectColumn("z", "time", "now()", null)));
+ objectTable.setName("x");
+ query.setFrom(new From(Arrays.asList(objectTable)));
+ helpTest("select * from objecttable('y' passing e1 as y columns z time 'now()') as x", "SELECT * FROM OBJECTTABLE('y' PASSING e1 AS y COLUMNS z time 'now()') AS x", query);
+ }
+
@Test public void testXmlSerialize() throws Exception {
XMLSerialize f = new XMLSerialize();
f.setDocument(true);
@@ -5104,6 +5116,16 @@
helpTestExpression("xmlserialize(x as CLOB)", "XMLSERIALIZE(x AS CLOB)", f);
}
+ @Test public void testXmlSerialize2() throws Exception {
+ XMLSerialize f = new XMLSerialize();
+ f.setExpression(new ElementSymbol("x"));
+ f.setTypeString("BLOB");
+ f.setDeclaration(Boolean.TRUE);
+ f.setVersion("1.0");
+ f.setEncoding("UTF-8");
+ helpTestExpression("xmlserialize(x as BLOB encoding \"UTF-8\" version '1.0' INCLUDING xmldeclaration)", "XMLSERIALIZE(x AS BLOB ENCODING \"UTF-8\" VERSION '1.0' INCLUDING XMLDECLARATION)", f);
+ }
+
@Test public void testExpressionCriteria() throws Exception {
SearchedCaseExpression sce = new SearchedCaseExpression(Arrays.asList(new ExpressionCriteria(new ElementSymbol("x"))), Arrays.asList(new ElementSymbol("y")));
helpTestExpression("case when x then y end", "CASE WHEN x THEN y END", sce);
Modified: trunk/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java 2012-08-23 18:14:04 UTC (rev 4363)
+++ trunk/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java 2012-08-24 19:54:48 UTC (rev 4364)
@@ -187,6 +187,69 @@
process(sql, expected);
}
+ @Test public void testXmlSerialize1() throws Exception {
+ String sql = "SELECT xmlserialize(document xmlelement(parent) as string including xmldeclaration)"; //$NON-NLS-1$
+
+ List<?>[] expected = new List<?>[] {
+ Arrays.asList("<?xml version=\"1.0\" encoding=\"UTF-8\"?><parent></parent>"),
+ };
+
+ process(sql, expected);
+ }
+
+ @Test public void testXmlSerialize2() throws Exception {
+ String sql = "SELECT xmlserialize(document xmlelement(parent) as string version '1.2' including xmldeclaration)"; //$NON-NLS-1$
+
+ List<?>[] expected = new List<?>[] {
+ Arrays.asList("<?xml version=\"1.2\" encoding=\"UTF-8\"?><parent></parent>"),
+ };
+
+ process(sql, expected);
+ }
+
+ @Test public void testXmlSerializeBinary() throws Exception {
+ String sql = "SELECT xmlserialize(document xmlelement(parent) as varbinary version '1.2' including xmldeclaration)"; //$NON-NLS-1$
+
+ List<?>[] expected = new List<?>[] {
+ Arrays.asList(new BinaryType("<?xml version=\"1.2\" encoding=\"UTF-8\"?><parent></parent>".getBytes(Charset.forName("UTF-8")))),
+ };
+
+ process(sql, expected);
+ }
+
+ @Test public void testXmlSerializeBinary1() throws Exception {
+ String sql = "SELECT xmlserialize(document xmlelement(parent) as varbinary encoding \"UTF-16\" version '1.2' including xmldeclaration)"; //$NON-NLS-1$
+
+ List<?>[] expected = new List<?>[] {
+ Arrays.asList(new BinaryType("<?xml version=\"1.2\" encoding=\"UTF-16\"?><parent></parent>".getBytes(Charset.forName("UTF-16")))),
+ };
+
+ process(sql, expected);
+ }
+
+ @Test public void testXmlSerializeBinary2() throws Exception {
+ String sql = "SELECT cast(xmlserialize(document xmlelement(other) as blob encoding \"UTF-16\" version '1.2' including xmldeclaration) as varbinary)"; //$NON-NLS-1$
+
+ List<?>[] expected = new List<?>[] {
+ Arrays.asList(new BinaryType("<?xml version=\"1.2\" encoding=\"UTF-16\"?><other></other>".getBytes(Charset.forName("UTF-16")))),
+ };
+
+ process(sql, expected);
+ }
+
+ /**
+ * if not specifically excluding, then leave the declaration intact (pre-8.2 behavior)
+ */
+ @Test public void testXmlSerialize3() throws Exception {
+ String sql = "SELECT xmlserialize(document xmlparse(document '<?xml version=\"1.1\" encoding=\"UTF-8\"?><a></a>') as string)"; //$NON-NLS-1$
+
+ List<?>[] expected = new List<?>[] {
+ Arrays.asList("<?xml version=\"1.1\" encoding=\"UTF-8\"?><a></a>"),
+ };
+
+ process(sql, expected);
+ }
+
@Test public void testXmlTable() throws Exception {
String sql = "select * from xmltable('/a/b' passing convert('<a><b>first</b><b x=\"attr\">second</b></a>', xml) columns x string path '@x', val string path '/.') as x"; //$NON-NLS-1$
Modified: trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java 2012-08-23 18:14:04 UTC (rev 4363)
+++ trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java 2012-08-24 19:54:48 UTC (rev 4364)
@@ -1636,5 +1636,9 @@
@Test public void testRewriteTrim1() throws Exception {
helpTestRewriteExpression("trim(leading from pm1.g1.e1)", "ltrim(pm1.g1.e1)", RealMetadataFactory.example1Cached());
}
+
+ @Test public void testRewriteXmlSerialize1() throws Exception {
+ helpTestRewriteExpression("xmlserialize(DOCUMENT cast (pm1.g1.e1 as xml) as clob version '2.0')", "XMLSERIALIZE(DOCUMENT convert(pm1.g1.e1, xml) AS clob VERSION '2.0' INCLUDING XMLDECLARATION)", RealMetadataFactory.example1Cached());
+ }
}
Modified: trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java 2012-08-23 18:14:04 UTC (rev 4363)
+++ trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java 2012-08-24 19:54:48 UTC (rev 4364)
@@ -595,6 +595,19 @@
helpRunValidator(command, new String[] {}, metadata);
}
+
+ @Test public void testXMLSerializeEncoding() {
+ helpValidate("SELECT xmlserialize(? AS CLOB ENCODING \"UTF-8\")", new String[] {"XMLSERIALIZE(? AS CLOB ENCODING \"UTF-8\")"}, RealMetadataFactory.example1Cached()); //$NON-NLS-1$
+ }
+
+ @Test public void testXMLSerializeEncoding1() {
+ helpValidate("SELECT xmlserialize(? AS BLOB ENCODING \"UTF-8\" INCLUDING XMLDECLARATION)", new String[] {}, RealMetadataFactory.example1Cached()); //$NON-NLS-1$
+ }
+
+ @Test public void testXMLSerializeEncoding2() {
+ helpValidate("SELECT xmlserialize(? AS BLOB ENCODING \"UTF-75\" INCLUDING XMLDECLARATION)", new String[] {"XMLSERIALIZE(? AS BLOB ENCODING \"UTF-75\" INCLUDING XMLDECLARATION)"}, RealMetadataFactory.example1Cached()); //$NON-NLS-1$
+ }
+
@Test public void testXMLQuery1() {
helpValidate("SELECT * FROM vm1.doc1", new String[] {}, exampleMetadata()); //$NON-NLS-1$
}
12 years, 4 months
teiid SVN: r4363 - in branches/7.4.x: engine/src/main/java/org/teiid/query/processor/relational and 1 other directories.
by teiid-commits@lists.jboss.org
Author: jolee
Date: 2012-08-23 14:14:04 -0400 (Thu, 23 Aug 2012)
New Revision: 4363
Modified:
branches/7.4.x/common-core/src/test/java/org/teiid/core/util/TestTimestampWithTimezone.java
branches/7.4.x/engine/src/main/java/org/teiid/query/processor/relational/XMLTableNode.java
branches/7.4.x/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java
Log:
TEIID-2112 (reprise): consistent handling of local timezone on xsd:date, xsd:datetime, and xsd:time values that have no timezone specified.
Modified: branches/7.4.x/common-core/src/test/java/org/teiid/core/util/TestTimestampWithTimezone.java
===================================================================
--- branches/7.4.x/common-core/src/test/java/org/teiid/core/util/TestTimestampWithTimezone.java 2012-08-23 17:56:45 UTC (rev 4362)
+++ branches/7.4.x/common-core/src/test/java/org/teiid/core/util/TestTimestampWithTimezone.java 2012-08-23 18:14:04 UTC (rev 4363)
@@ -22,6 +22,8 @@
package org.teiid.core.util;
+import static org.junit.Assert.*;
+
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
@@ -29,28 +31,20 @@
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
+import java.util.GregorianCalendar;
import java.util.TimeZone;
-import org.teiid.core.util.TimestampWithTimezone;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
-import junit.framework.TestCase;
+public class TestTimestampWithTimezone {
-public class TestTimestampWithTimezone extends TestCase {
-
- /**
- * Constructor for TestTimestampWithTimezone.
- *
- * @param name
- */
- public TestTimestampWithTimezone(String name) {
- super(name);
- }
-
- public void setUp() {
+ @Before public void setUp() {
TimestampWithTimezone.resetCalendar(TimeZone.getTimeZone("America/Chicago")); //$NON-NLS-1$
}
- public void tearDown() {
+ @After public void tearDown() {
TimestampWithTimezone.resetCalendar(null);
}
@@ -117,7 +111,7 @@
return ts;
}
- public void testDST() {
+ @Test public void testDST() {
helpTestSame("2005-10-30 02:39:10", 1, "America/Chicago", //$NON-NLS-1$ //$NON-NLS-2$
"GMT-05:00"); //$NON-NLS-1$
@@ -137,32 +131,32 @@
}
- public void testTimezone() {
+ @Test public void testTimezone() {
helpTestSame("2004-06-29 15:39:10", 1, "GMT-06:00", //$NON-NLS-1$ //$NON-NLS-2$
"GMT-05:00"); //$NON-NLS-1$
}
- public void testTimezone2() {
+ @Test public void testTimezone2() {
helpTestSame("2004-06-29 15:39:10", 1, "GMT-08:00", //$NON-NLS-1$ //$NON-NLS-2$
"GMT-06:00"); //$NON-NLS-1$
}
- public void testTimezone3() {
+ @Test public void testTimezone3() {
helpTestSame("2004-08-31 18:25:54", 1, "Europe/London", //$NON-NLS-1$ //$NON-NLS-2$
"GMT"); //$NON-NLS-1$
}
- public void testTimezoneOverMidnight() {
+ @Test public void testTimezoneOverMidnight() {
helpTestSame("2004-06-30 23:39:10", 1, "America/Los_Angeles", //$NON-NLS-1$ //$NON-NLS-2$
"America/Chicago"); //$NON-NLS-1$
}
- public void testCase2852() {
+ @Test public void testCase2852() {
helpTestSame("2005-05-17 22:35:33", 508659, "GMT", //$NON-NLS-1$ //$NON-NLS-2$
"America/New_York"); //$NON-NLS-1$
}
- public void testCreateDate() {
+ @Test public void testCreateDate() {
Timestamp t = Timestamp.valueOf("2004-06-30 23:39:10.1201"); //$NON-NLS-1$
Date date = TimestampWithTimezone.createDate(t);
@@ -179,7 +173,7 @@
assertEquals(cal.get(Calendar.DATE), 30);
}
- public void testCreateTime() {
+ @Test public void testCreateTime() {
Timestamp t = Timestamp.valueOf("2004-06-30 23:39:10.1201"); //$NON-NLS-1$
Time date = TimestampWithTimezone.createTime(t);
@@ -199,14 +193,14 @@
/**
* Even though the id of the timezones are different, this should not change the result
*/
- public void testDateToDateConversion() {
+ @Test public void testDateToDateConversion() {
Date t = Date.valueOf("2004-06-30"); //$NON-NLS-1$
Date converted = TimestampWithTimezone.createDate(t, TimeZone.getTimeZone("America/Chicago"), Calendar.getInstance(TimeZone.getTimeZone("US/Central"))); //$NON-NLS-1$ //$NON-NLS-2$
assertEquals(t.getTime(), converted.getTime());
}
- public void testDateToDateConversion1() {
+ @Test public void testDateToDateConversion1() {
Date t = Date.valueOf("2004-06-30"); //$NON-NLS-1$
Date converted = TimestampWithTimezone.createDate(t, TimeZone.getTimeZone("America/Chicago"), Calendar.getInstance(TimeZone.getTimeZone("GMT"))); //$NON-NLS-1$ //$NON-NLS-2$
Modified: branches/7.4.x/engine/src/main/java/org/teiid/query/processor/relational/XMLTableNode.java
===================================================================
--- branches/7.4.x/engine/src/main/java/org/teiid/query/processor/relational/XMLTableNode.java 2012-08-23 17:56:45 UTC (rev 4362)
+++ branches/7.4.x/engine/src/main/java/org/teiid/query/processor/relational/XMLTableNode.java 2012-08-23 18:14:04 UTC (rev 4363)
@@ -22,15 +22,14 @@
package org.teiid.query.processor.relational;
+import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
-import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.TimeZone;
import net.sf.saxon.om.Item;
import net.sf.saxon.om.NodeInfo;
@@ -56,7 +55,6 @@
import org.teiid.core.TeiidRuntimeException;
import org.teiid.core.types.DataTypeManager;
import org.teiid.core.types.XMLType;
-import org.teiid.core.util.TimestampWithTimezone;
import org.teiid.query.QueryPlugin;
import org.teiid.query.function.FunctionDescriptor;
import org.teiid.query.sql.lang.XMLTable;
@@ -258,10 +256,11 @@
if (value instanceof CalendarValue) {
CalendarValue cv = (CalendarValue)value;
if (!cv.hasTimezone()) {
+ int tzMin = getContext().getServerTimeZone().getRawOffset()/60000;
+ cv.setTimezoneInMinutes(tzMin);
Calendar cal = cv.getCalendar();
- Date d = cal.getTime();
- cal.setTimeZone(getContext().getServerTimeZone());
- return TimestampWithTimezone.createTimestamp(d, TimeZone.getTimeZone("GMT"), cal);
+
+ return new Timestamp(cal.getTime().getTime());
}
}
return Value.convertToJava(value);
Modified: branches/7.4.x/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java
===================================================================
--- branches/7.4.x/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java 2012-08-23 17:56:45 UTC (rev 4362)
+++ branches/7.4.x/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java 2012-08-23 18:14:04 UTC (rev 4363)
@@ -194,10 +194,10 @@
}
@Test public void testXmlTableDateTime() throws Exception {
- String sql = "select * from xmltable('/a' passing convert('<a dt=\"2011-11-17T07:38:49\" dtz=\"2011-11-17T07:38:49Z\" t=\"13:23:14\" d=\"2010-04-05\" />', xml) columns x timestamp path '@dt', x1 timestamp path '@dtz', y date path '@d', z time path '@t') as x"; //$NON-NLS-1$
+ String sql = "select * from xmltable('/a' passing convert('<a dt=\"0001-11-17T07:38:49\" dtz=\"2011-11-17T07:38:49Z\" t=\"13:23:14\" d=\"2010-04-05\" />', xml) columns x timestamp path '@dt', x1 timestamp path '@dtz', y date path '@d', z time path '@t') as x"; //$NON-NLS-1$
List<?>[] expected = new List<?>[] {
- Arrays.asList(TimestampUtil.createTimestamp(111, 10, 17, 7, 38, 49, 0), TimestampUtil.createTimestamp(111, 10, 17, 1, 38, 49, 0), TimestampUtil.createDate(110, 3, 5), TimestampUtil.createTime(13, 23, 14))
+ Arrays.asList(TimestampUtil.createTimestamp(-1899, 10, 19, 7, 38, 49, 0), TimestampUtil.createTimestamp(111, 10, 17, 1, 38, 49, 0), TimestampUtil.createDate(110, 3, 5), TimestampUtil.createTime(13, 23, 14))
};
process(sql, expected);
12 years, 4 months
teiid SVN: r4362 - in trunk: engine/src/main/java/org/teiid/query/processor/relational and 1 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2012-08-23 13:56:45 -0400 (Thu, 23 Aug 2012)
New Revision: 4362
Modified:
trunk/common-core/src/test/java/org/teiid/core/util/TestTimestampWithTimezone.java
trunk/engine/src/main/java/org/teiid/query/processor/relational/XMLTableNode.java
trunk/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java
Log:
TEIID-2112 addressing pre-gregorian cutoff values
Modified: trunk/common-core/src/test/java/org/teiid/core/util/TestTimestampWithTimezone.java
===================================================================
--- trunk/common-core/src/test/java/org/teiid/core/util/TestTimestampWithTimezone.java 2012-08-23 16:43:06 UTC (rev 4361)
+++ trunk/common-core/src/test/java/org/teiid/core/util/TestTimestampWithTimezone.java 2012-08-23 17:56:45 UTC (rev 4362)
@@ -22,6 +22,8 @@
package org.teiid.core.util;
+import static org.junit.Assert.*;
+
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
@@ -29,28 +31,20 @@
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
+import java.util.GregorianCalendar;
import java.util.TimeZone;
-import org.teiid.core.util.TimestampWithTimezone;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
-import junit.framework.TestCase;
+public class TestTimestampWithTimezone {
-public class TestTimestampWithTimezone extends TestCase {
-
- /**
- * Constructor for TestTimestampWithTimezone.
- *
- * @param name
- */
- public TestTimestampWithTimezone(String name) {
- super(name);
- }
-
- public void setUp() {
+ @Before public void setUp() {
TimestampWithTimezone.resetCalendar(TimeZone.getTimeZone("America/Chicago")); //$NON-NLS-1$
}
- public void tearDown() {
+ @After public void tearDown() {
TimestampWithTimezone.resetCalendar(null);
}
@@ -117,7 +111,7 @@
return ts;
}
- public void testDST() {
+ @Test public void testDST() {
helpTestSame("2005-10-30 02:39:10", 1, "America/Chicago", //$NON-NLS-1$ //$NON-NLS-2$
"GMT-05:00"); //$NON-NLS-1$
@@ -137,32 +131,32 @@
}
- public void testTimezone() {
+ @Test public void testTimezone() {
helpTestSame("2004-06-29 15:39:10", 1, "GMT-06:00", //$NON-NLS-1$ //$NON-NLS-2$
"GMT-05:00"); //$NON-NLS-1$
}
- public void testTimezone2() {
+ @Test public void testTimezone2() {
helpTestSame("2004-06-29 15:39:10", 1, "GMT-08:00", //$NON-NLS-1$ //$NON-NLS-2$
"GMT-06:00"); //$NON-NLS-1$
}
- public void testTimezone3() {
+ @Test public void testTimezone3() {
helpTestSame("2004-08-31 18:25:54", 1, "Europe/London", //$NON-NLS-1$ //$NON-NLS-2$
"GMT"); //$NON-NLS-1$
}
- public void testTimezoneOverMidnight() {
+ @Test public void testTimezoneOverMidnight() {
helpTestSame("2004-06-30 23:39:10", 1, "America/Los_Angeles", //$NON-NLS-1$ //$NON-NLS-2$
"America/Chicago"); //$NON-NLS-1$
}
- public void testCase2852() {
+ @Test public void testCase2852() {
helpTestSame("2005-05-17 22:35:33", 508659, "GMT", //$NON-NLS-1$ //$NON-NLS-2$
"America/New_York"); //$NON-NLS-1$
}
- public void testCreateDate() {
+ @Test public void testCreateDate() {
Timestamp t = Timestamp.valueOf("2004-06-30 23:39:10.1201"); //$NON-NLS-1$
Date date = TimestampWithTimezone.createDate(t);
@@ -179,7 +173,7 @@
assertEquals(cal.get(Calendar.DATE), 30);
}
- public void testCreateTime() {
+ @Test public void testCreateTime() {
Timestamp t = Timestamp.valueOf("2004-06-30 23:39:10.1201"); //$NON-NLS-1$
Time date = TimestampWithTimezone.createTime(t);
@@ -199,14 +193,14 @@
/**
* Even though the id of the timezones are different, this should not change the result
*/
- public void testDateToDateConversion() {
+ @Test public void testDateToDateConversion() {
Date t = Date.valueOf("2004-06-30"); //$NON-NLS-1$
Date converted = TimestampWithTimezone.createDate(t, TimeZone.getTimeZone("America/Chicago"), Calendar.getInstance(TimeZone.getTimeZone("US/Central"))); //$NON-NLS-1$ //$NON-NLS-2$
assertEquals(t.getTime(), converted.getTime());
}
- public void testDateToDateConversion1() {
+ @Test public void testDateToDateConversion1() {
Date t = Date.valueOf("2004-06-30"); //$NON-NLS-1$
Date converted = TimestampWithTimezone.createDate(t, TimeZone.getTimeZone("America/Chicago"), Calendar.getInstance(TimeZone.getTimeZone("GMT"))); //$NON-NLS-1$ //$NON-NLS-2$
Modified: trunk/engine/src/main/java/org/teiid/query/processor/relational/XMLTableNode.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/relational/XMLTableNode.java 2012-08-23 16:43:06 UTC (rev 4361)
+++ trunk/engine/src/main/java/org/teiid/query/processor/relational/XMLTableNode.java 2012-08-23 17:56:45 UTC (rev 4362)
@@ -22,15 +22,14 @@
package org.teiid.query.processor.relational;
+import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
-import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.TimeZone;
import net.sf.saxon.om.Item;
import net.sf.saxon.om.NodeInfo;
@@ -56,7 +55,6 @@
import org.teiid.core.TeiidRuntimeException;
import org.teiid.core.types.DataTypeManager;
import org.teiid.core.types.XMLType;
-import org.teiid.core.util.TimestampWithTimezone;
import org.teiid.query.QueryPlugin;
import org.teiid.query.eval.Evaluator;
import org.teiid.query.function.FunctionDescriptor;
@@ -318,10 +316,10 @@
if (value instanceof CalendarValue) {
CalendarValue cv = (CalendarValue)value;
if (!cv.hasTimezone()) {
+ int tzMin = getContext().getServerTimeZone().getRawOffset()/60000;
+ cv.setTimezoneInMinutes(tzMin);
Calendar cal = cv.getCalendar();
- Date d = cal.getTime();
- cal.setTimeZone(getContext().getServerTimeZone());
- return TimestampWithTimezone.createTimestamp(d, TimeZone.getTimeZone("GMT"), cal); //$NON-NLS-1$
+ return new Timestamp(cal.getTime().getTime());
}
}
return Value.convertToJava(value);
Modified: trunk/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java 2012-08-23 16:43:06 UTC (rev 4361)
+++ trunk/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java 2012-08-23 17:56:45 UTC (rev 4362)
@@ -216,10 +216,10 @@
}
@Test public void testXmlTableDateTime() throws Exception {
- String sql = "select * from xmltable('/a' passing convert('<a dt=\"2011-11-17T07:38:49\" dtz=\"2011-11-17T07:38:49Z\" t=\"13:23:14\" d=\"2010-04-05\" />', xml) columns x timestamp path '@dt', x1 timestamp path '@dtz', y date path '@d', z time path '@t') as x"; //$NON-NLS-1$
+ String sql = "select * from xmltable('/a' passing convert('<a dt=\"0001-11-17T07:38:49\" dtz=\"2011-11-17T07:38:49Z\" t=\"13:23:14\" d=\"2010-04-05\" />', xml) columns x timestamp path '@dt', x1 timestamp path '@dtz', y date path '@d', z time path '@t') as x"; //$NON-NLS-1$
List<?>[] expected = new List<?>[] {
- Arrays.asList(TimestampUtil.createTimestamp(111, 10, 17, 7, 38, 49, 0), TimestampUtil.createTimestamp(111, 10, 17, 1, 38, 49, 0), TimestampUtil.createDate(110, 3, 5), TimestampUtil.createTime(13, 23, 14))
+ Arrays.asList(TimestampUtil.createTimestamp(-1899, 10, 19, 7, 38, 49, 0), TimestampUtil.createTimestamp(111, 10, 17, 1, 38, 49, 0), TimestampUtil.createDate(110, 3, 5), TimestampUtil.createTime(13, 23, 14))
};
process(sql, expected);
12 years, 4 months
teiid SVN: r4361 - in trunk: connectors/translator-olap/src/main/java/org/teiid/translator/olap and 21 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2012-08-23 12:43:06 -0400 (Thu, 23 Aug 2012)
New Revision: 4361
Added:
trunk/engine/src/main/java/org/teiid/query/processor/relational/ObjectTableNode.java
trunk/engine/src/main/java/org/teiid/query/sql/lang/ObjectTable.java
Modified:
trunk/api/src/main/java/org/teiid/language/SQLConstants.java
trunk/connectors/translator-olap/src/main/java/org/teiid/translator/olap/OlapQueryExecution.java
trunk/engine/src/main/java/org/teiid/dqp/internal/process/multisource/MultiSourceMetadataWrapper.java
trunk/engine/src/main/java/org/teiid/query/QueryPlugin.java
trunk/engine/src/main/java/org/teiid/query/eval/Evaluator.java
trunk/engine/src/main/java/org/teiid/query/metadata/BasicQueryMetadata.java
trunk/engine/src/main/java/org/teiid/query/metadata/BasicQueryMetadataWrapper.java
trunk/engine/src/main/java/org/teiid/query/metadata/MetadataValidator.java
trunk/engine/src/main/java/org/teiid/query/metadata/QueryMetadataInterface.java
trunk/engine/src/main/java/org/teiid/query/metadata/TempMetadataAdapter.java
trunk/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/PlanToProcessConverter.java
trunk/engine/src/main/java/org/teiid/query/processor/relational/RelationalPlan.java
trunk/engine/src/main/java/org/teiid/query/processor/relational/XMLTableNode.java
trunk/engine/src/main/java/org/teiid/query/resolver/command/SimpleQueryResolver.java
trunk/engine/src/main/java/org/teiid/query/resolver/util/ResolverUtil.java
trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
trunk/engine/src/main/java/org/teiid/query/sql/LanguageVisitor.java
trunk/engine/src/main/java/org/teiid/query/sql/lang/XMLTable.java
trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrPostOrderNavigator.java
trunk/engine/src/main/java/org/teiid/query/sql/visitor/ExpressionMappingVisitor.java
trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java
trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java
trunk/engine/src/main/java/org/teiid/query/xquery/saxon/XQueryEvaluator.java
trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj
trunk/engine/src/main/resources/org/teiid/query/i18n.properties
trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java
trunk/engine/src/test/java/org/teiid/query/resolver/TestResolver.java
trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java
trunk/jboss-integration/src/main/java/org/teiid/jboss/VDBDeployer.java
Log:
TEIID-2141 adding initial support for an object table and a few minor fixes
Modified: trunk/api/src/main/java/org/teiid/language/SQLConstants.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/SQLConstants.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/api/src/main/java/org/teiid/language/SQLConstants.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -119,6 +119,7 @@
public static final String TRIM = "TRIM"; //$NON-NLS-1$
public static final String RESULT = "RESULT"; //$NON-NLS-1$
+ public static final Object OBJECTTABLE = "OBJECTTABLE"; //$NON-NLS-1$
}
public interface Reserved {
Modified: trunk/connectors/translator-olap/src/main/java/org/teiid/translator/olap/OlapQueryExecution.java
===================================================================
--- trunk/connectors/translator-olap/src/main/java/org/teiid/translator/olap/OlapQueryExecution.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/connectors/translator-olap/src/main/java/org/teiid/translator/olap/OlapQueryExecution.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -127,7 +127,7 @@
Cell cell = cellSet.getCell(colPos, rowPosition);
result[i++] = cell.getValue();
}
- ArrayList<Object[]> results = new ArrayList<Object[]>();
+ ArrayList<Object[]> results = new ArrayList<Object[]>(1);
results.add(result);
return results;
}
Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/process/multisource/MultiSourceMetadataWrapper.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/process/multisource/MultiSourceMetadataWrapper.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/multisource/MultiSourceMetadataWrapper.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -373,7 +373,7 @@
}
@Override
- public QueryMetadataInterface getDesignTimeMetadata() {
+ protected QueryMetadataInterface createDesignTimeMetadata() {
return new MultiSourceMetadataWrapper(actualMetadata.getDesignTimeMetadata(), multiSourceModels);
}
Modified: trunk/engine/src/main/java/org/teiid/query/QueryPlugin.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/QueryPlugin.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/query/QueryPlugin.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -526,5 +526,7 @@
TEIID31106, //duplicate param name
TEIID31107, //too many result params
TEIID31108, //datasource not available
+ TEIID31109, //invalid scripting language
+ TEIID31110, //invalid script
}
}
Modified: trunk/engine/src/main/java/org/teiid/query/eval/Evaluator.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/eval/Evaluator.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/query/eval/Evaluator.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -879,7 +879,7 @@
* Evaluate the parameters and return the context item if it exists
*/
public Object evaluateParameters(List<DerivedColumn> cols, List<?> tuple,
- HashMap<String, Object> parameters)
+ Map<String, Object> parameters)
throws ExpressionEvaluationException, BlockedException,
TeiidComponentException {
Object contextItem = null;
Modified: trunk/engine/src/main/java/org/teiid/query/metadata/BasicQueryMetadata.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/metadata/BasicQueryMetadata.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/query/metadata/BasicQueryMetadata.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -28,8 +28,11 @@
import java.util.Properties;
import java.util.Set;
+import javax.script.ScriptEngine;
+
import org.teiid.api.exception.query.QueryMetadataException;
import org.teiid.core.TeiidComponentException;
+import org.teiid.core.TeiidProcessingException;
import org.teiid.query.function.FunctionLibrary;
import org.teiid.query.mapping.relational.QueryNode;
import org.teiid.query.mapping.xml.MappingNode;
@@ -519,5 +522,10 @@
public Set<String> getImportedModels() {
return Collections.emptySet();
}
-
+
+ @Override
+ public ScriptEngine getScriptEngine(String langauge) throws TeiidProcessingException {
+ return null;
+ }
+
}
Modified: trunk/engine/src/main/java/org/teiid/query/metadata/BasicQueryMetadataWrapper.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/metadata/BasicQueryMetadataWrapper.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/query/metadata/BasicQueryMetadataWrapper.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -27,8 +27,11 @@
import java.util.Properties;
import java.util.Set;
+import javax.script.ScriptEngine;
+
import org.teiid.api.exception.query.QueryMetadataException;
import org.teiid.core.TeiidComponentException;
+import org.teiid.core.TeiidProcessingException;
import org.teiid.query.function.FunctionLibrary;
import org.teiid.query.mapping.relational.QueryNode;
import org.teiid.query.mapping.xml.MappingNode;
@@ -37,6 +40,8 @@
public class BasicQueryMetadataWrapper implements QueryMetadataInterface {
protected QueryMetadataInterface actualMetadata;
+ protected QueryMetadataInterface designTimeMetadata;
+ protected boolean designTime;
public BasicQueryMetadataWrapper(QueryMetadataInterface actualMetadata) {
this.actualMetadata = actualMetadata;
@@ -355,6 +360,19 @@
@Override
public QueryMetadataInterface getDesignTimeMetadata() {
+ if (designTime) {
+ return this;
+ }
+ if (designTimeMetadata == null) {
+ designTimeMetadata = createDesignTimeMetadata();
+ if (designTimeMetadata instanceof BasicQueryMetadataWrapper) {
+ ((BasicQueryMetadataWrapper)designTimeMetadata).designTime = true;
+ }
+ }
+ return designTimeMetadata;
+ }
+
+ protected QueryMetadataInterface createDesignTimeMetadata() {
return actualMetadata.getDesignTimeMetadata();
}
@@ -378,5 +396,10 @@
public Set<String> getImportedModels() {
return actualMetadata.getImportedModels();
}
-
+
+ @Override
+ public ScriptEngine getScriptEngine(String langauge) throws TeiidProcessingException {
+ return actualMetadata.getScriptEngine(langauge);
+ }
+
}
Modified: trunk/engine/src/main/java/org/teiid/query/metadata/MetadataValidator.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/metadata/MetadataValidator.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/query/metadata/MetadataValidator.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -147,6 +147,8 @@
static class ResolveQueryPlans implements MetadataRule {
@Override
public void execute(VDBMetaData vdb, MetadataStore store, ValidatorReport report, MetadataValidator metadataValidator) {
+ QueryMetadataInterface metadata = vdb.getAttachment(QueryMetadataInterface.class);
+ metadata = new TempMetadataAdapter(metadata, new TempMetadataStore());
for (Schema schema:store.getSchemaList()) {
ModelMetaData model = vdb.getModel(schema.getName());
@@ -163,7 +165,7 @@
metadataValidator.log(report, model, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31079, t.getName(), model.getName()));
}
else {
- metadataValidator.validate(vdb, model, t, report);
+ metadataValidator.validate(vdb, model, t, report, metadata);
}
}
}
@@ -174,7 +176,7 @@
metadataValidator.log(report, model, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31081, p.getName(), model.getName()));
}
else {
- metadataValidator.validate(vdb, model, p, report);
+ metadataValidator.validate(vdb, model, p, report, metadata);
}
}
}
@@ -198,9 +200,7 @@
LogManager.log(messageLevel, LogConstants.CTX_QUERY_RESOLVER, msg);
}
- private void validate(VDBMetaData vdb, ModelMetaData model, AbstractMetadataRecord record, ValidatorReport report) {
- QueryMetadataInterface metadata = vdb.getAttachment(QueryMetadataInterface.class);
- metadata = new TempMetadataAdapter(metadata, new TempMetadataStore()); //TODO: optimize this
+ private void validate(VDBMetaData vdb, ModelMetaData model, AbstractMetadataRecord record, ValidatorReport report, QueryMetadataInterface metadata) {
ValidatorReport resolverReport = null;
try {
if (record instanceof Procedure) {
Modified: trunk/engine/src/main/java/org/teiid/query/metadata/QueryMetadataInterface.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/metadata/QueryMetadataInterface.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/query/metadata/QueryMetadataInterface.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -27,8 +27,11 @@
import java.util.Properties;
import java.util.Set;
+import javax.script.ScriptEngine;
+
import org.teiid.api.exception.query.QueryMetadataException;
import org.teiid.core.TeiidComponentException;
+import org.teiid.core.TeiidProcessingException;
import org.teiid.query.function.FunctionLibrary;
import org.teiid.query.mapping.relational.QueryNode;
import org.teiid.query.mapping.xml.MappingNode;
@@ -623,6 +626,14 @@
FunctionLibrary getFunctionLibrary();
+ /**
+ *
+ * @param langauge null is treated as the default of 'javascript'
+ * @return the ScriptEngine or null if the ScriptEngine is not available
+ * @throws TeiidProcessingException if the ScriptEngine is required
+ */
+ ScriptEngine getScriptEngine(String langauge) throws TeiidProcessingException;
+
Object getPrimaryKey(Object metadataID);
boolean isMultiSource(Object modelId) throws QueryMetadataException, TeiidComponentException;
Modified: trunk/engine/src/main/java/org/teiid/query/metadata/TempMetadataAdapter.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/metadata/TempMetadataAdapter.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/query/metadata/TempMetadataAdapter.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -95,9 +95,14 @@
if (isSession()) {
return this.actualMetadata.getDesignTimeMetadata();
}
- return new TempMetadataAdapter(this.actualMetadata.getDesignTimeMetadata(), tempStore, materializationTables, queryNodes);
+ return super.getDesignTimeMetadata();
}
+ @Override
+ protected QueryMetadataInterface createDesignTimeMetadata() {
+ return new TempMetadataAdapter(this.actualMetadata.getDesignTimeMetadata(), tempStore, materializationTables, queryNodes);
+ }
+
public TempMetadataStore getMetadataStore() {
return this.tempStore;
}
Modified: trunk/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -26,20 +26,17 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
+import java.util.*;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineFactory;
+import javax.script.ScriptEngineManager;
+
import org.jboss.vfs.VirtualFile;
import org.teiid.adminapi.impl.VDBMetaData;
import org.teiid.api.exception.query.QueryMetadataException;
import org.teiid.core.TeiidComponentException;
+import org.teiid.core.TeiidProcessingException;
import org.teiid.core.types.BlobImpl;
import org.teiid.core.types.ClobImpl;
import org.teiid.core.types.DataTypeManager;
@@ -68,6 +65,7 @@
import org.teiid.query.mapping.xml.MappingDocument;
import org.teiid.query.mapping.xml.MappingLoader;
import org.teiid.query.mapping.xml.MappingNode;
+import org.teiid.query.sql.lang.ObjectTable;
import org.teiid.query.sql.lang.SPParameter;
@@ -159,6 +157,8 @@
private Map<String, Resource> vdbEntries;
private FunctionLibrary functionLibrary;
private VDBMetaData vdbMetaData;
+ private ScriptEngineManager scriptEngineManager;
+ private Set<String> importedModels;
/*
* TODO: move caching to jboss cache structure
@@ -174,6 +174,12 @@
public TransformationMetadata(VDBMetaData vdbMetadata, final CompositeMetadataStore store, Map<String, Resource> vdbEntries, FunctionTree systemFunctions, Collection<FunctionTree> functionTrees) {
ArgCheck.isNotNull(store);
this.vdbMetaData = vdbMetadata;
+ if (this.vdbMetaData !=null) {
+ this.scriptEngineManager = vdbMetadata.getAttachment(ScriptEngineManager.class);
+ this.importedModels = this.vdbMetaData.getImportedModels();
+ } else {
+ this.importedModels = Collections.emptySet();
+ }
this.store = store;
if (vdbEntries == null) {
this.vdbEntries = Collections.emptyMap();
@@ -188,7 +194,6 @@
}
private TransformationMetadata(final CompositeMetadataStore store, FunctionLibrary functionLibrary) {
- ArgCheck.isNotNull(store);
this.store = store;
this.vdbEntries = Collections.emptyMap();
this.functionLibrary = functionLibrary;
@@ -1089,14 +1094,37 @@
tm.metadataCache = this.metadataCache;
tm.partialNameToFullNameCache = this.partialNameToFullNameCache;
tm.procedureCache = this.procedureCache;
+ tm.scriptEngineManager = this.scriptEngineManager;
+ tm.importedModels = this.importedModels;
return tm;
}
@Override
public Set<String> getImportedModels() {
- if (this.vdbMetaData == null) {
- return Collections.emptySet();
+ return this.importedModels;
+ }
+
+ @Override
+ public ScriptEngine getScriptEngine(String language) throws TeiidProcessingException {
+ if (this.scriptEngineManager == null) {
+ this.scriptEngineManager = new ScriptEngineManager();
}
- return this.vdbMetaData.getImportedModels();
+ if (language == null) {
+ language = ObjectTable.DEFAULT_LANGUAGE;
+ }
+ /*
+ * because of state caching in the engine, we'll return a new instance for each
+ * usage. we can pool if needed and add a returnEngine method
+ */
+ ScriptEngine engine = this.scriptEngineManager.getEngineByName(language);
+ if (engine == null) {
+ Set<String> names = new LinkedHashSet<String>();
+ for (ScriptEngineFactory factory : this.scriptEngineManager.getEngineFactories()) {
+ names.addAll(factory.getNames());
+ }
+ throw new TeiidProcessingException(QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31109, language, names));
+ }
+ return engine;
}
+
}
\ No newline at end of file
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/PlanToProcessConverter.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/PlanToProcessConverter.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/PlanToProcessConverter.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -60,6 +60,7 @@
import org.teiid.query.processor.relational.SortUtility.Mode;
import org.teiid.query.resolver.util.ResolverUtil;
import org.teiid.query.sql.lang.*;
+import org.teiid.query.sql.lang.ObjectTable.ObjectColumn;
import org.teiid.query.sql.lang.SetQuery.Operation;
import org.teiid.query.sql.lang.XMLTable.XMLColumn;
import org.teiid.query.sql.symbol.ElementSymbol;
@@ -421,7 +422,7 @@
//we handle the projection filtering once here rather than repeating the
//path analysis on a per plan basis
updateGroupName(node, xt);
- Map elementMap = RelationalNode.createLookupMap(xt.getProjectedSymbols());
+ Map<Expression, Integer> elementMap = RelationalNode.createLookupMap(xt.getProjectedSymbols());
List cols = (List) node.getProperty(NodeConstants.Info.OUTPUT_COLS);
int[] projectionIndexes = RelationalNode.getProjectionIndexes(elementMap, cols);
ArrayList<XMLColumn> filteredColumns = new ArrayList<XMLColumn>(projectionIndexes.length);
@@ -434,6 +435,24 @@
processNode = xtn;
break;
}
+ if (source instanceof ObjectTable) {
+ ObjectTable ot = (ObjectTable)source;
+ ObjectTableNode otn = new ObjectTableNode(getID());
+ //we handle the projection filtering once here rather than repeating the
+ //path analysis on a per plan basis
+ updateGroupName(node, ot);
+ Map<Expression, Integer> elementMap = RelationalNode.createLookupMap(ot.getProjectedSymbols());
+ List<Expression> cols = (List<Expression>) node.getProperty(NodeConstants.Info.OUTPUT_COLS);
+ int[] projectionIndexes = RelationalNode.getProjectionIndexes(elementMap, cols);
+ ArrayList<ObjectColumn> filteredColumns = new ArrayList<ObjectColumn>(projectionIndexes.length);
+ for (int col : projectionIndexes) {
+ filteredColumns.add(ot.getColumns().get(col));
+ }
+ otn.setProjectedColumns(filteredColumns);
+ otn.setTable(ot);
+ processNode = otn;
+ break;
+ }
if (source instanceof TextTable) {
TextTableNode ttn = new TextTableNode(getID());
TextTable tt = (TextTable)source;
Added: trunk/engine/src/main/java/org/teiid/query/processor/relational/ObjectTableNode.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/relational/ObjectTableNode.java (rev 0)
+++ trunk/engine/src/main/java/org/teiid/query/processor/relational/ObjectTableNode.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -0,0 +1,194 @@
+/*
+ * 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.
+ */
+
+package org.teiid.query.processor.relational;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.script.CompiledScript;
+import javax.script.ScriptContext;
+import javax.script.ScriptException;
+import javax.script.SimpleScriptContext;
+
+import org.teiid.api.exception.query.ExpressionEvaluationException;
+import org.teiid.common.buffer.BlockedException;
+import org.teiid.common.buffer.TupleBatch;
+import org.teiid.core.TeiidComponentException;
+import org.teiid.core.TeiidProcessingException;
+import org.teiid.query.QueryPlugin;
+import org.teiid.query.eval.Evaluator;
+import org.teiid.query.function.FunctionDescriptor;
+import org.teiid.query.sql.LanguageObject;
+import org.teiid.query.sql.lang.ObjectTable;
+import org.teiid.query.sql.lang.ObjectTable.ObjectColumn;
+
+/**
+ * Handles object table processing.
+ */
+public class ObjectTableNode extends SubqueryAwareRelationalNode {
+
+ private static final String TEIID_ROW_COUNT = "teiid_rowcount"; //$NON-NLS-1$
+ private static final String TEIID_ROW = "teiid_row"; //$NON-NLS-1$
+ private static final String TEIID_CONTEXT = "teiid_context"; //$NON-NLS-1$
+
+ private ObjectTable table;
+ private List<ObjectColumn> projectedColumns;
+
+ //processing state
+ private int rowCount = 0;
+ private Object item;
+ private Iterator<?> result;
+ private SimpleScriptContext scriptContext;
+
+ public ObjectTableNode(int nodeID) {
+ super(nodeID);
+ }
+
+ @Override
+ public void open() throws TeiidComponentException, TeiidProcessingException {
+ super.open();
+ if (table.getScriptEngine() == null) {
+ table.setScriptEngine(getContext().getMetadata().getScriptEngine(table.getScriptingLanguage()));
+ }
+ scriptContext = new SimpleScriptContext();
+ this.scriptContext.setAttribute(TEIID_CONTEXT, this.getContext(), ScriptContext.ENGINE_SCOPE);
+ }
+
+ @Override
+ public synchronized void closeDirect() {
+ super.closeDirect();
+ reset();
+ }
+
+ @Override
+ public void reset() {
+ super.reset();
+ item = null;
+ result = null;
+ rowCount = 0;
+ this.scriptContext = null;
+ }
+
+ public void setTable(ObjectTable table) {
+ this.table = table;
+ }
+
+ public void setProjectedColumns(List<ObjectColumn> projectedColumns) {
+ this.projectedColumns = projectedColumns;
+ }
+
+ @Override
+ public ObjectTableNode clone() {
+ ObjectTableNode clone = new ObjectTableNode(getID());
+ this.copyTo(clone);
+ clone.setTable(table);
+ clone.setProjectedColumns(projectedColumns);
+ return clone;
+ }
+
+ @Override
+ protected synchronized TupleBatch nextBatchDirect() throws BlockedException,
+ TeiidComponentException, TeiidProcessingException {
+
+ evaluate();
+
+ while (!isBatchFull() && result.hasNext()) {
+ if (item == null) {
+ item = result.next();
+ if (item == null) {
+ continue;
+ }
+ rowCount++;
+ }
+ addBatchRow(processRow());
+ }
+ if (!result.hasNext()) {
+ terminateBatches();
+ }
+ return pullBatch();
+ }
+
+ private void evaluate() throws TeiidComponentException,
+ ExpressionEvaluationException, BlockedException,
+ TeiidProcessingException {
+ if (result != null) {
+ return;
+ }
+ setReferenceValues(this.table);
+ Evaluator eval = getEvaluator(Collections.emptyMap());
+ Object context = eval.evaluateParameters(this.table.getPassing(), null, scriptContext.getBindings(ScriptContext.ENGINE_SCOPE));
+ assert context == null;
+
+ Object value = evalScript(this.table.getCompiledScript(), this.table.getRowScript());
+ if (value instanceof Iterable<?>) {
+ result = ((Iterable<?>)value).iterator();
+ } else if (value instanceof Iterator<?>) {
+ result = (Iterator<?>)value;
+ } else {
+ result = Arrays.asList(value).iterator();
+ }
+ }
+
+ private Object evalScript(CompiledScript compiledScript, String script) throws TeiidProcessingException {
+ try {
+ if (compiledScript != null) {
+ return compiledScript.eval(this.scriptContext);
+ }
+ return this.table.getScriptEngine().eval(script, this.scriptContext);
+ } catch (ScriptException e) {
+ throw new TeiidProcessingException(QueryPlugin.Event.TEIID31110, e, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31110, script, e.getMessage()));
+ }
+ }
+
+ private List<?> processRow() throws ExpressionEvaluationException,
+ TeiidComponentException, TeiidProcessingException {
+ List<Object> tuple = new ArrayList<Object>(projectedColumns.size());
+ this.scriptContext.setAttribute(TEIID_ROW, this.item, ScriptContext.ENGINE_SCOPE);
+ this.scriptContext.setAttribute(TEIID_ROW_COUNT, this.rowCount, ScriptContext.ENGINE_SCOPE);
+ for (ObjectColumn proColumn : projectedColumns) {
+ Object value = evalScript(proColumn.getCompiledScript(), proColumn.getPath());
+ if (value == null) {
+ if (proColumn.getDefaultExpression() != null) {
+ tuple.add(getEvaluator(Collections.emptyMap()).evaluate(proColumn.getDefaultExpression(), null));
+ } else {
+ tuple.add(null);
+ }
+ continue;
+ }
+ value = FunctionDescriptor.importValue(value, proColumn.getSymbol().getType());
+ tuple.add(value);
+ }
+ item = null;
+ return tuple;
+ }
+
+ @Override
+ protected Collection<? extends LanguageObject> getObjects() {
+ return this.table.getPassing();
+ }
+
+}
\ No newline at end of file
Property changes on: trunk/engine/src/main/java/org/teiid/query/processor/relational/ObjectTableNode.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: trunk/engine/src/main/java/org/teiid/query/processor/relational/RelationalPlan.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/relational/RelationalPlan.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/query/processor/relational/RelationalPlan.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -125,6 +125,7 @@
return this.outputCols;
}
+ @Override
public void open()
throws TeiidComponentException, TeiidProcessingException {
if (with != null) {
Modified: trunk/engine/src/main/java/org/teiid/query/processor/relational/XMLTableNode.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/relational/XMLTableNode.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/query/processor/relational/XMLTableNode.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -321,7 +321,7 @@
Calendar cal = cv.getCalendar();
Date d = cal.getTime();
cal.setTimeZone(getContext().getServerTimeZone());
- return TimestampWithTimezone.createTimestamp(d, TimeZone.getTimeZone("GMT"), cal);
+ return TimestampWithTimezone.createTimestamp(d, TimeZone.getTimeZone("GMT"), cal); //$NON-NLS-1$
}
}
return Value.convertToJava(value);
Modified: trunk/engine/src/main/java/org/teiid/query/resolver/command/SimpleQueryResolver.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/resolver/command/SimpleQueryResolver.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/query/resolver/command/SimpleQueryResolver.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -328,6 +328,26 @@
}
}
+ @Override
+ public void visit(ObjectTable obj) {
+ LinkedHashSet<GroupSymbol> saved = preTableFunctionReference(obj);
+ visitNodes(obj.getPassing());
+ postTableFunctionReference(obj, saved);
+ try {
+ ResolverUtil.setDesiredType(obj.getPassing(), obj, DataTypeManager.DefaultDataClasses.OBJECT);
+ for (ObjectTable.ObjectColumn column : obj.getColumns()) {
+ if (column.getDefaultExpression() == null) {
+ continue;
+ }
+ visitNode(column.getDefaultExpression());
+ Expression ex = ResolverUtil.convertExpression(column.getDefaultExpression(), DataTypeManager.getDataTypeName(column.getSymbol().getType()), metadata);
+ column.setDefaultExpression(ex);
+ }
+ } catch (TeiidException e) {
+ throw new TeiidRuntimeException(e);
+ }
+ }
+
/**
* @param tfr
*/
Modified: trunk/engine/src/main/java/org/teiid/query/resolver/util/ResolverUtil.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/resolver/util/ResolverUtil.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/query/resolver/util/ResolverUtil.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -252,13 +252,14 @@
return conversion;
}
+
+ public static void setDesiredType(List<DerivedColumn> passing, LanguageObject obj) throws QueryResolverException {
+ setDesiredType(passing, obj, DataTypeManager.DefaultDataClasses.XML);
+ }
- public static void setDesiredType(List<DerivedColumn> passing, LanguageObject obj) throws QueryResolverException {
+ public static void setDesiredType(List<DerivedColumn> passing, LanguageObject obj, Class<?> type) throws QueryResolverException {
for (DerivedColumn dc : passing) {
- if (dc.getAlias() == null) {
- ResolverUtil.setDesiredType(dc.getExpression(), DataTypeManager.DefaultDataClasses.XML, obj);
- break;
- }
+ ResolverUtil.setDesiredType(dc.getExpression(), type, obj);
}
}
Modified: trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -703,9 +703,9 @@
TextTable tt = (TextTable)clause;
tt.setFile(rewriteExpressionDirect(tt.getFile()));
} else if (clause instanceof XMLTable) {
- XMLTable xt = (XMLTable)clause;
- xt.rewriteDefaultColumn();
rewriteExpressions(clause);
+ } else if (clause instanceof ObjectTable) {
+ rewriteExpressions(clause);
} else if (clause instanceof ArrayTable) {
ArrayTable at = (ArrayTable)clause;
at.setArrayValue(rewriteExpressionDirect(at.getArrayValue()));
Modified: trunk/engine/src/main/java/org/teiid/query/sql/LanguageVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/LanguageVisitor.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/query/sql/LanguageVisitor.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -144,4 +144,5 @@
public void visit(WindowSpecification windowSpecification) {}
public void visit(Array array) {}
+ public void visit(ObjectTable objectTable) {}
}
Added: trunk/engine/src/main/java/org/teiid/query/sql/lang/ObjectTable.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/lang/ObjectTable.java (rev 0)
+++ trunk/engine/src/main/java/org/teiid/query/sql/lang/ObjectTable.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -0,0 +1,197 @@
+/*
+ * 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.
+ */
+
+package org.teiid.query.sql.lang;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.script.CompiledScript;
+import javax.script.ScriptEngine;
+
+import org.teiid.core.util.EquivalenceUtil;
+import org.teiid.query.sql.LanguageVisitor;
+import org.teiid.query.sql.symbol.DerivedColumn;
+import org.teiid.query.sql.symbol.Expression;
+
+public class ObjectTable extends TableFunctionReference {
+
+ public static final String DEFAULT_LANGUAGE = "javascript"; //$NON-NLS-1$
+
+ public static class ObjectColumn extends ProjectedColumn {
+ private String path;
+ private Expression defaultExpression;
+ private CompiledScript compiledScript;
+
+ public ObjectColumn(String name, String type, String path, Expression defaultExpression) {
+ super(name, type);
+ this.path = path;
+ this.defaultExpression = defaultExpression;
+ }
+
+ protected ObjectColumn() {
+
+ }
+
+ public Expression getDefaultExpression() {
+ return defaultExpression;
+ }
+
+ public void setDefaultExpression(Expression defaultExpression) {
+ this.defaultExpression = defaultExpression;
+ }
+
+ public String getPath() {
+ return path;
+ }
+
+ public void setPath(String path) {
+ this.path = path;
+ }
+
+ public CompiledScript getCompiledScript() {
+ return compiledScript;
+ }
+
+ public void setCompiledScript(CompiledScript compiledScript) {
+ this.compiledScript = compiledScript;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!super.equals(obj) || !(obj instanceof ObjectColumn)) {
+ return false;
+ }
+ ObjectColumn other = (ObjectColumn)obj;
+ return EquivalenceUtil.areEqual(this.path, other.path)
+ && EquivalenceUtil.areEqual(this.defaultExpression, other.defaultExpression);
+ }
+
+ @Override
+ public ObjectColumn clone() {
+ ObjectColumn clone = new ObjectColumn();
+ super.copyTo(clone);
+ clone.path = this.path;
+ if (this.defaultExpression != null) {
+ clone.defaultExpression = (Expression)this.defaultExpression.clone();
+ }
+ clone.compiledScript = this.compiledScript;
+ return clone;
+ }
+ }
+
+ private List<ObjectColumn> columns = new ArrayList<ObjectColumn>();
+ private String rowScript;
+ private List<DerivedColumn> passing = new ArrayList<DerivedColumn>();
+ private String scriptingLanguage;
+
+ private CompiledScript compiledScript;
+ private ScriptEngine scriptEngine;
+
+ public CompiledScript getCompiledScript() {
+ return compiledScript;
+ }
+
+ public void setCompiledScript(CompiledScript compiledScript) {
+ this.compiledScript = compiledScript;
+ }
+
+ public String getScriptingLanguage() {
+ return scriptingLanguage;
+ }
+
+ public void setScriptingLanguage(String scriptingLanguage) {
+ this.scriptingLanguage = scriptingLanguage;
+ }
+
+ public List<DerivedColumn> getPassing() {
+ return passing;
+ }
+
+ public void setPassing(List<DerivedColumn> passing) {
+ this.passing = passing;
+ }
+
+ public String getRowScript() {
+ return rowScript;
+ }
+
+ public void setRowScript(String query) {
+ this.rowScript = query;
+ }
+
+ public List<ObjectColumn> getColumns() {
+ return columns;
+ }
+
+ public void setColumns(List<ObjectColumn> columns) {
+ this.columns = columns;
+ }
+
+ @Override
+ public void acceptVisitor(LanguageVisitor visitor) {
+ visitor.visit(this);
+ }
+
+ @Override
+ protected ObjectTable cloneDirect() {
+ ObjectTable clone = new ObjectTable();
+ this.copy(clone);
+ for (ObjectColumn column : columns) {
+ clone.getColumns().add(column.clone());
+ }
+ if (this.passing != null) {
+ for (DerivedColumn col : this.passing) {
+ clone.passing.add(col.clone());
+ }
+ }
+ clone.rowScript = this.rowScript;
+ clone.compiledScript = this.compiledScript;
+ return clone;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!super.equals(obj) || !(obj instanceof ObjectTable)) {
+ return false;
+ }
+ ObjectTable other = (ObjectTable)obj;
+ return this.columns.equals(other.columns)
+ && this.rowScript.equals(other.rowScript)
+ && this.passing.equals(other.passing);
+ }
+
+ public ScriptEngine getScriptEngine() {
+ return scriptEngine;
+ }
+
+ public void setScriptEngine(ScriptEngine scriptEngine) {
+ this.scriptEngine = scriptEngine;
+ }
+
+}
Property changes on: trunk/engine/src/main/java/org/teiid/query/sql/lang/ObjectTable.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: trunk/engine/src/main/java/org/teiid/query/sql/lang/XMLTable.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/lang/XMLTable.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/query/sql/lang/XMLTable.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -1,7 +1,6 @@
package org.teiid.query.sql.lang;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
import net.sf.saxon.sxpath.XPathExpression;
@@ -11,7 +10,6 @@
import org.teiid.core.util.EquivalenceUtil;
import org.teiid.query.sql.LanguageVisitor;
import org.teiid.query.sql.symbol.DerivedColumn;
-import org.teiid.query.sql.symbol.ElementSymbol;
import org.teiid.query.sql.symbol.Expression;
import org.teiid.query.sql.symbol.XMLNamespaces;
import org.teiid.query.xquery.saxon.SaxonXQueryExpression;
@@ -104,7 +102,7 @@
private XMLNamespaces namespaces;
private String xquery;
private List<DerivedColumn> passing = new ArrayList<DerivedColumn>();
- private XMLColumn defaultColumn;
+ private boolean usingDefaultColumn;
private SaxonXQueryExpression xqueryExpression;
@@ -113,11 +111,7 @@
}
public void compileXqueryExpression() throws TeiidProcessingException {
- List<XMLColumn> cols = this.columns;
- if (cols.isEmpty()) {
- cols = Arrays.asList(defaultColumn);
- }
- this.xqueryExpression = new SaxonXQueryExpression(xquery, namespaces, passing, cols);
+ this.xqueryExpression = new SaxonXQueryExpression(xquery, namespaces, passing, this.columns);
}
public SaxonXQueryExpression getXQueryExpression() {
@@ -141,9 +135,17 @@
}
public void setColumns(List<XMLColumn> columns) {
+ if (columns.isEmpty()) {
+ usingDefaultColumn = true;
+ columns.add(new XMLColumn("OBJECT_VALUE", DataTypeManager.DefaultDataTypes.XML, ".", null)); //$NON-NLS-1$ //$NON-NLS-2$
+ }
this.columns = columns;
}
+ public boolean isUsingDefaultColumn() {
+ return usingDefaultColumn;
+ }
+
public XMLNamespaces getNamespaces() {
return namespaces;
}
@@ -152,17 +154,6 @@
this.namespaces = namespaces;
}
- @Override
- public List<ElementSymbol> getProjectedSymbols() {
- if (!columns.isEmpty()) {
- return super.getProjectedSymbols();
- }
- if (defaultColumn == null) {
- defaultColumn = new XMLColumn("OBJECT_VALUE", DataTypeManager.DefaultDataTypes.XML, ".", null); //$NON-NLS-1$ //$NON-NLS-2$
- }
- return Arrays.asList(defaultColumn.getSymbol());
- }
-
@Override
public void acceptVisitor(LanguageVisitor visitor) {
visitor.visit(this);
@@ -175,9 +166,6 @@
for (XMLColumn column : columns) {
clone.getColumns().add(column.clone());
}
- if (defaultColumn != null) {
- clone.defaultColumn = this.defaultColumn;
- }
if (this.namespaces != null) {
clone.namespaces = this.namespaces.clone();
}
@@ -190,6 +178,7 @@
if (this.xqueryExpression != null) {
clone.xqueryExpression = this.xqueryExpression.clone();
}
+ clone.usingDefaultColumn = usingDefaultColumn;
return clone;
}
@@ -208,11 +197,4 @@
&& this.passing.equals(other.passing);
}
- public void rewriteDefaultColumn() {
- if (this.columns.isEmpty() && defaultColumn != null) {
- this.columns.add(defaultColumn);
- defaultColumn = null;
- }
- }
-
}
Modified: trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrPostOrderNavigator.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrPostOrderNavigator.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrPostOrderNavigator.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -503,6 +503,17 @@
}
@Override
+ public void visit(ObjectTable obj) {
+ preVisitVisitor(obj);
+ visitNodes(obj.getPassing());
+ for (ObjectTable.ObjectColumn column : obj.getColumns()) {
+ visitNode(column.getDefaultExpression());
+ }
+ visitNode(obj.getGroupSymbol());
+ postVisitVisitor(obj);
+ }
+
+ @Override
public void visit(XMLQuery obj) {
preVisitVisitor(obj);
visitNode(obj.getNamespaces());
Modified: trunk/engine/src/main/java/org/teiid/query/sql/visitor/ExpressionMappingVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/visitor/ExpressionMappingVisitor.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/query/sql/visitor/ExpressionMappingVisitor.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -34,6 +34,7 @@
import org.teiid.query.sql.LanguageObject;
import org.teiid.query.sql.LanguageVisitor;
import org.teiid.query.sql.lang.*;
+import org.teiid.query.sql.lang.ObjectTable.ObjectColumn;
import org.teiid.query.sql.lang.XMLTable.XMLColumn;
import org.teiid.query.sql.navigator.PreOrPostOrderNavigator;
import org.teiid.query.sql.navigator.PreOrderNavigator;
@@ -111,6 +112,16 @@
}
@Override
+ public void visit(ObjectTable obj) {
+ for (ObjectColumn col : obj.getColumns()) {
+ Expression exp = col.getDefaultExpression();
+ if (exp != null) {
+ col.setDefaultExpression(replaceExpression(exp));
+ }
+ }
+ }
+
+ @Override
public void visit(XMLSerialize obj) {
obj.setExpression(replaceExpression(obj.getExpression()));
}
Modified: trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -41,6 +41,7 @@
import org.teiid.query.sql.LanguageVisitor;
import org.teiid.query.sql.lang.*;
import org.teiid.query.sql.lang.ExistsCriteria.SubqueryHint;
+import org.teiid.query.sql.lang.ObjectTable.ObjectColumn;
import org.teiid.query.sql.lang.TableFunctionReference.ProjectedColumn;
import org.teiid.query.sql.lang.TextTable.TextColumn;
import org.teiid.query.sql.lang.XMLTable.XMLColumn;
@@ -1778,7 +1779,7 @@
append(SPACE);
registerNodes(obj.getPassing(), 0);
}
- if (!obj.getColumns().isEmpty()) {
+ if (!obj.getColumns().isEmpty() && !obj.isUsingDefaultColumn()) {
append(SPACE);
append(NonReserved.COLUMNS);
for (Iterator<XMLColumn> cols = obj.getColumns().iterator(); cols.hasNext();) {
@@ -1818,6 +1819,50 @@
}
@Override
+ public void visit( ObjectTable obj ) {
+ addHintComment(obj);
+ append("OBJECTTABLE("); //$NON-NLS-1$
+ if (obj.getScriptingLanguage() != null) {
+ append(LANGUAGE);
+ append(SPACE);
+ visitNode(new Constant(obj.getScriptingLanguage()));
+ append(SPACE);
+ }
+ visitNode(new Constant(obj.getRowScript()));
+ if (!obj.getPassing().isEmpty()) {
+ append(SPACE);
+ append(NonReserved.PASSING);
+ append(SPACE);
+ registerNodes(obj.getPassing(), 0);
+ }
+ append(SPACE);
+ append(NonReserved.COLUMNS);
+ for (Iterator<ObjectColumn> cols = obj.getColumns().iterator(); cols.hasNext();) {
+ ObjectColumn col = cols.next();
+ append(SPACE);
+ outputDisplayName(col.getName());
+ append(SPACE);
+ append(col.getType());
+ append(SPACE);
+ visitNode(new Constant(col.getPath()));
+ if (col.getDefaultExpression() != null) {
+ append(SPACE);
+ append(DEFAULT);
+ append(SPACE);
+ visitNode(col.getDefaultExpression());
+ }
+ if (cols.hasNext()) {
+ append(","); //$NON-NLS-1$
+ }
+ }
+ append(")");//$NON-NLS-1$
+ append(SPACE);
+ append(AS);
+ append(SPACE);
+ outputDisplayName(obj.getName());
+ }
+
+ @Override
public void visit( XMLQuery obj ) {
append("XMLQUERY("); //$NON-NLS-1$
if (obj.getNamespaces() != null) {
Modified: trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -31,7 +31,12 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
+import java.util.TreeSet;
+import javax.script.Compilable;
+import javax.script.ScriptEngine;
+import javax.script.ScriptException;
+
import net.sf.saxon.om.Name11Checker;
import net.sf.saxon.om.QNameException;
import net.sf.saxon.trans.XPathException;
@@ -44,6 +49,7 @@
import org.teiid.core.TeiidProcessingException;
import org.teiid.core.types.DataTypeManager;
import org.teiid.core.util.EquivalenceUtil;
+import org.teiid.language.SQLConstants;
import org.teiid.metadata.AggregateAttributes;
import org.teiid.query.QueryPlugin;
import org.teiid.query.eval.Evaluator;
@@ -57,6 +63,7 @@
import org.teiid.query.resolver.util.ResolverUtil;
import org.teiid.query.sql.LanguageObject;
import org.teiid.query.sql.lang.*;
+import org.teiid.query.sql.lang.ObjectTable.ObjectColumn;
import org.teiid.query.sql.lang.SetQuery.Operation;
import org.teiid.query.sql.lang.XMLTable.XMLColumn;
import org.teiid.query.sql.navigator.PreOrPostOrderNavigator;
@@ -1191,6 +1198,45 @@
}
@Override
+ public void visit(ObjectTable obj) {
+ List<DerivedColumn> passing = obj.getPassing();
+ TreeSet<String> names = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
+ for (DerivedColumn dc : passing) {
+ if (dc.getAlias() == null) {
+ handleValidationError(QueryPlugin.Util.getString("ValidationVisitor.context_item_not_allowed"), obj); //$NON-NLS-1$
+ } else if (!names.add(dc.getAlias())) {
+ handleValidationError(QueryPlugin.Util.getString("ValidationVisitor.duplicate_passing", dc.getAlias()), obj); //$NON-NLS-1$
+ }
+ }
+ Compilable scriptCompiler = null;
+ try {
+ ScriptEngine engine = this.getMetadata().getScriptEngine(obj.getScriptingLanguage());
+ obj.setScriptEngine(engine);
+ if (engine instanceof Compilable) {
+ scriptCompiler = (Compilable)engine;
+ engine.put(ScriptEngine.FILENAME, SQLConstants.NonReserved.OBJECTTABLE);
+ obj.setCompiledScript(scriptCompiler.compile(obj.getRowScript()));
+ }
+ } catch (TeiidProcessingException e) {
+ handleValidationError(e.getMessage(), obj);
+ } catch (ScriptException e) {
+ handleValidationError(QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31110, obj.getRowScript(), e.getMessage()), obj); //$NON-NLS
+ }
+ for (ObjectColumn xc : obj.getColumns()) {
+ if (scriptCompiler != null) {
+ try {
+ xc.setCompiledScript(scriptCompiler.compile(xc.getPath()));
+ } catch (ScriptException e) {
+ handleValidationError(QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31110, xc.getPath(), e.getMessage()), obj); //$NON-NLS
+ }
+ }
+ if (xc.getDefaultExpression() != null && !EvaluatableVisitor.isFullyEvaluatable(xc.getDefaultExpression(), false)) {
+ handleValidationError(QueryPlugin.Util.getString("ValidationVisitor.invalid_default", xc.getDefaultExpression()), obj); //$NON-NLS-1$
+ }
+ }
+ }
+
+ @Override
public void visit(XMLQuery obj) {
validatePassing(obj, obj.getXQueryExpression(), obj.getPassing());
}
@@ -1198,7 +1244,7 @@
private void validatePassing(LanguageObject obj, SaxonXQueryExpression xqe, List<DerivedColumn> passing) {
boolean context = false;
boolean hadError = false;
- HashSet<String> names = new HashSet<String>();
+ TreeSet<String> names = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
for (DerivedColumn dc : passing) {
if (dc.getAlias() == null) {
Class<?> type = dc.getExpression().getType();
@@ -1212,7 +1258,7 @@
context = true;
} else {
validateXMLContentTypes(dc.getExpression(), obj);
- if (!names.add(dc.getAlias().toUpperCase())) {
+ if (!names.add(dc.getAlias())) {
handleValidationError(QueryPlugin.Util.getString("ValidationVisitor.duplicate_passing", dc.getAlias()), obj); //$NON-NLS-1$
}
}
Modified: trunk/engine/src/main/java/org/teiid/query/xquery/saxon/XQueryEvaluator.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/xquery/saxon/XQueryEvaluator.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/query/xquery/saxon/XQueryEvaluator.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -41,6 +41,7 @@
import net.sf.saxon.om.NodeInfo;
import net.sf.saxon.query.DynamicQueryContext;
import net.sf.saxon.trans.XPathException;
+import net.sf.saxon.value.HexBinaryValue;
import nu.xom.Builder;
import nu.xom.DocType;
import nu.xom.Element;
@@ -53,6 +54,7 @@
import org.teiid.core.TeiidComponentException;
import org.teiid.core.TeiidProcessingException;
import org.teiid.core.TeiidRuntimeException;
+import org.teiid.core.types.BinaryType;
import org.teiid.logging.LogConstants;
import org.teiid.logging.LogManager;
import org.teiid.logging.MessageLevel;
@@ -90,6 +92,8 @@
value = wrapStax((Source)value, xquery.getConfig());
} else if (value instanceof java.util.Date) {
value = XMLSystemFunctions.convertToAtomicValue(value);
+ } else if (value instanceof BinaryType) {
+ value = new HexBinaryValue(((BinaryType)value).getBytesDirect());
}
dynamicContext.setParameter(entry.getKey(), value);
}
Modified: trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj
===================================================================
--- trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj 2012-08-23 16:43:06 UTC (rev 4361)
@@ -449,6 +449,7 @@
| <QUOTE: "quote">
| <HEADER: "header">
| <NULLS: "nulls">
+| <OBJECTTABLE: "objecttable">
}
/*
@@ -551,7 +552,7 @@
{
}
{
- (<INSTEAD>|<VIEW>|<ENABLED>|<DISABLED>|<KEY>|<SERIAL>|<TEXTAGG>|<COUNT>|<ROW_NUMBER>|<RANK>|<DENSE_RANK>|<SUM>|<AVG>|<MIN>|<MAX>|<EVERY>|<STDDEV_POP>|<STDDEV_SAMP>|<VAR_SAMP>|<VAR_POP>|<DOCUMENT>|<CONTENT>|<TRIM>|<EMPTY>|<ORDINALITY>|<PATH>|<FIRST>|<LAST>|<NEXT>|<SUBSTRING>|<EXTRACT>|<TO_CHARS>|<TO_BYTES>|<TIMESTAMPADD>|<TIMESTAMPDIFF>|<QUERYSTRING>|<NAMESPACE>|<RESULT>|<INDEX>|<ACCESSPATTERN>|<AUTO_INCREMENT>|<WELLFORMED>|<SQL_TSI_FRAC_SECOND>|<SQL_TSI_SECOND>|<SQL_TSI_MINUTE>|<SQL_TSI_HOUR>|<SQL_TSI_DAY>|<SQL_TSI_WEEK>|<SQL_TSI_MONTH>|<SQL_TSI_QUARTER>|<SQL_TSI_YEAR>|<TEXTTABLE>|<ARRAYTABLE>|<SELECTOR>|<SKIP_KEYWORD>|<WIDTH>|<PASSING>|<NAME>|<ENCODING>|<COLUMNS>|<DELIMITER>|<QUOTE>|<HEADER>|<NULLS>)
+ (<INSTEAD>|<VIEW>|<ENABLED>|<DISABLED>|<KEY>|<SERIAL>|<TEXTAGG>|<COUNT>|<ROW_NUMBER>|<RANK>|<DENSE_RANK>|<SUM>|<AVG>|<MIN>|<MAX>|<EVERY>|<STDDEV_POP>|<STDDEV_SAMP>|<VAR_SAMP>|<VAR_POP>|<DOCUMENT>|<CONTENT>|<TRIM>|<EMPTY>|<ORDINALITY>|<PATH>|<FIRST>|<LAST>|<NEXT>|<SUBSTRING>|<EXTRACT>|<TO_CHARS>|<TO_BYTES>|<TIMESTAMPADD>|<TIMESTAMPDIFF>|<QUERYSTRING>|<NAMESPACE>|<RESULT>|<INDEX>|<ACCESSPATTERN>|<AUTO_INCREMENT>|<WELLFORMED>|<SQL_TSI_FRAC_SECOND>|<SQL_TSI_SECOND>|<SQL_TSI_MINUTE>|<SQL_TSI_HOUR>|<SQL_TSI_DAY>|<SQL_TSI_WEEK>|<SQL_TSI_MONTH>|<SQL_TSI_QUARTER>|<SQL_TSI_YEAR>|<TEXTTABLE>|<ARRAYTABLE>|<SELECTOR>|<SKIP_KEYWORD>|<WIDTH>|<PASSING>|<NAME>|<ENCODING>|<COLUMNS>|<DELIMITER>|<QUOTE>|<HEADER>|<NULLS>|<OBJECTTABLE>)
{
return getToken(0);
}
@@ -2294,6 +2295,8 @@
|
clause = xmlTable(info)
|
+ LOOKAHEAD(2) clause = objectTable(info)
+ |
clause = unaryFromClause(info)
|
LOOKAHEAD(subqueryFromClause(info)) clause = subqueryFromClause(info)
@@ -2555,6 +2558,89 @@
}
/*
+name=object table
+description=Returns table results by processing a script.
+example={code:sql}OBJECTTABLE('z' PASSING val AS z COLUMNS col OBJECT 'teiid_row') AS X{code}
+*/
+ObjectTable objectTable(ParseInfo info) :
+{
+ String rowScript = null;
+ String lang = null;
+ DerivedColumn passing = null;
+ ArrayList<DerivedColumn> passingValues = new ArrayList<DerivedColumn>();
+ ObjectTable.ObjectColumn column = null;
+ ArrayList<ObjectTable.ObjectColumn> columns = new ArrayList<ObjectTable.ObjectColumn>();
+ String aliasID = null;
+}
+{
+ <OBJECTTABLE> <LPAREN>
+ [<LANGUAGE> lang = stringVal()]
+ rowScript = stringVal()
+ [
+ <PASSING>
+ passing = derivedColumn(info)
+ {
+ passingValues.add(passing);
+ passing.setPropagateName(false);
+ }
+ (<COMMA>
+ passing = derivedColumn(info)
+ {
+ passingValues.add(passing);
+ passing.setPropagateName(false);
+ }
+ )*
+ ]
+ <COLUMNS>
+ column = objectColumn(info)
+ {
+ columns.add(column);
+ }
+ (<COMMA>
+ column = objectColumn(info)
+ {
+ columns.add(column);
+ }
+ )*
+ <RPAREN>
+ [<AS>] aliasID=id()
+ {
+ ObjectTable result = new ObjectTable();
+ result.setScriptingLanguage(lang);
+ result.setRowScript(rowScript);
+ result.setPassing(passingValues);
+ result.setColumns(columns);
+ result.setName(validateAlias(aliasID));
+ return result;
+ }
+}
+
+/*
+name=object table column
+description=object table column.
+example={code:sql}y integer 'teiid_rowcount'{code}
+*/
+ObjectTable.ObjectColumn objectColumn(ParseInfo info):
+{
+ String name = null;
+ ParsedDataType datatype = null;
+ String path = null;
+ Expression defaultExpr = null;
+}
+{
+ name = id()
+ datatype = parseDataType()
+ path = stringVal()
+ [
+ <DEFAULT_KEYWORD> defaultExpr = expression(info)
+ ]
+ {
+ return new ObjectTable.ObjectColumn(name, datatype.type, path, defaultExpr);
+ }
+}
+
+
+/*
name=xml table
description=Returns table results by processing an XQuery.
example={code:sql}XMLTABLE('/a/b' PASSING doc COLUMNS col XML PATH '.') AS X{code}
Modified: trunk/engine/src/main/resources/org/teiid/query/i18n.properties
===================================================================
--- trunk/engine/src/main/resources/org/teiid/query/i18n.properties 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/resources/org/teiid/query/i18n.properties 2012-08-23 16:43:06 UTC (rev 4361)
@@ -719,9 +719,10 @@
ValidationVisitor.xml_invalid_qname=The qname "{0}" is invalid.
ValidationVisitor.context_item_type=XMLTABLE or XMLQUERY PASSING context item must be an XML value.
ValidationVisitor.passing_requires_name=XMLTABLE or XMLQUERY PASSING clause can only contain at most 1 unnamed item.
-ValidationVisitor.duplicate_passing=XMLTABLE or XMLQUERY PASSING clause duplicate item name "{0}".
+ValidationVisitor.duplicate_passing=XMLTABLE, XMLQUERY, or OBJECTTABLE PASSING clause duplicate item name "{0}".
+ValidationVisitor.ValidationVisitor.context_item_not_allowed=OBJECTTABLE does not support passing unnamed items.
ValidationVisitor.one_ordinal=Only one FOR ORDINALITY column is allowed for an XMLTABLE.
-ValidationVisitor.invalid_default=XMLTABLE DEFAULT expression is invalid: "{0}"
+ValidationVisitor.invalid_default=XMLTABLE or OBJECTTABLE DEFAULT expression is invalid: "{0}"
ValidationVisitor.context_required=The XQuery requires a context item, but none exists in the PASSING clause.
ValidationVisitor.xmlparse_type=XMLPARSE expects a STRING, CLOB, or BLOB value.
ValidationVisitor.invalid_encoding=Encoding {0} is not valid.
@@ -1022,6 +1023,8 @@
TEIID31105=Returing warning to client: {0}
TEIID31106=Duplicate parameter {1} defined on {0}
TEIID31107=Procedure {0} can only have 1 RESULT/return value
+TEIID31109=Invalid language {0}. Supported language names are {1}.
+TEIID31109=Invalid script {0}. Scrpting engine reported: {1}.
SQLParser.proc_type_conflict=Result type {1} conflicts with return type {2} for procedure {0}
SQLParser.param_out=Procedure {0} RESULT param {1} must be of type OUT.
Modified: trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -5068,6 +5068,11 @@
helpTest(sql, "SELECT * FROM XMLTABLE(XMLNAMESPACES(NO DEFAULT), '/' COLUMNS x FOR ORDINALITY, y date DEFAULT {d'2000-01-01'} PATH '@date') AS x", query);
}
+ @Test public void testObjectTable() throws Exception {
+ Query actualCommand = (Query)QueryParser.getQueryParser().parseCommand("SELECT * from objecttable(LANGUAGE 'foo' 'x' columns y date 'row.date' default {d'2000-01-01'}) as x", new ParseInfo());
+ assertEquals("SELECT * FROM OBJECTTABLE(LANGUAGE 'foo' 'x' COLUMNS y date 'row.date' DEFAULT {d'2000-01-01'}) AS x", actualCommand.toString());
+ }
+
@Test public void testXmlSerialize() throws Exception {
XMLSerialize f = new XMLSerialize();
f.setDocument(true);
Modified: trunk/engine/src/test/java/org/teiid/query/resolver/TestResolver.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/resolver/TestResolver.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/test/java/org/teiid/query/resolver/TestResolver.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -169,27 +169,11 @@
CheckSymbolsAreResolvedVisitor vis = new CheckSymbolsAreResolvedVisitor();
DeepPreOrderNavigator.doVisit(command, vis);
- Collection unresolvedSymbols = vis.getUnresolvedSymbols();
+ Collection<LanguageObject> unresolvedSymbols = vis.getUnresolvedSymbols();
assertTrue("Found unresolved symbols: " + unresolvedSymbols, unresolvedSymbols.isEmpty()); //$NON-NLS-1$
return command;
}
- /**
- * Expect a QueryResolverException (not any other kind of Throwable)
- */
- private void helpResolveFails(Command command) {
- // resolve
- QueryResolverException exception = null;
- try {
- QueryResolver.resolveCommand(command, metadata);
- } catch(QueryResolverException e) {
- exception = e;
- } catch(TeiidException e) {
- fail("Exception during resolution (" + e.getClass().getName() + "): " + e.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
- }
- assertNotNull("Expected a QueryResolverException but got none.", exception); //$NON-NLS-1$
- }
-
private Criteria helpResolveCriteria(String sql) {
Criteria criteria = null;
@@ -211,7 +195,7 @@
CheckSymbolsAreResolvedVisitor vis = new CheckSymbolsAreResolvedVisitor();
DeepPreOrderNavigator.doVisit(criteria, vis);
- Collection unresolvedSymbols = vis.getUnresolvedSymbols();
+ Collection<LanguageObject> unresolvedSymbols = vis.getUnresolvedSymbols();
assertTrue("Found unresolved symbols: " + unresolvedSymbols, unresolvedSymbols.isEmpty()); //$NON-NLS-1$
return criteria;
}
@@ -229,7 +213,7 @@
CheckSymbolsAreResolvedVisitor vis = new CheckSymbolsAreResolvedVisitor();
DeepPreOrderNavigator.doVisit(command, vis);
- Collection unresolvedSymbols = vis.getUnresolvedSymbols();
+ Collection<LanguageObject> unresolvedSymbols = vis.getUnresolvedSymbols();
assertTrue("Found unresolved symbols: " + unresolvedSymbols, unresolvedSymbols.isEmpty()); //$NON-NLS-1$
return command;
}
@@ -331,27 +315,22 @@
StoredProcedure proc = (StoredProcedure)helpResolve(sql);
- List params = proc.getParameters();
+ List<SPParameter> params = proc.getParameters();
- // Remove all but IN and IN/OUT params
- Iterator paramIter = params.iterator();
- while (paramIter.hasNext()) {
- final SPParameter param = (SPParameter)paramIter.next();
- if (param.getParameterType() != ParameterInfo.IN && param.getParameterType() != ParameterInfo.INOUT) {
- paramIter.remove();
- }
- }
-
// Check remaining params against expected expressions
- assertEquals(expectedParameterExpressions.length, params.size());
- for (int i=0; i<expectedParameterExpressions.length; i++) {
- SPParameter param = (SPParameter)params.get(i);
+ int i = 0;
+ for (SPParameter param : params) {
+ if (param.getParameterType() != SPParameter.IN && param.getParameterType() != SPParameter.INOUT) {
+ continue;
+ }
if (expectedParameterExpressions[i] == null) {
assertNull(param.getExpression());
} else {
assertEquals(expectedParameterExpressions[i], param.getExpression());
}
+ i++;
}
+ assertEquals(expectedParameterExpressions.length, i);
return proc;
}
@@ -932,13 +911,13 @@
Query resolvedQuery = (Query) helpResolve("select * from (EXEC pm1.sq2('abc')) as x"); //$NON-NLS-1$
helpCheckFrom(resolvedQuery, new String[] { "x" }); //$NON-NLS-1$
- List elements = (List) ElementCollectorVisitor.getElements(resolvedQuery.getSelect(), false);
+ List<ElementSymbol> elements = (List<ElementSymbol>) ElementCollectorVisitor.getElements(resolvedQuery.getSelect(), false);
- ElementSymbol elem1 = (ElementSymbol)elements.get(0);
+ ElementSymbol elem1 = elements.get(0);
assertEquals("Did not get expected element", "x.e1", elem1.getName() ); //$NON-NLS-1$ //$NON-NLS-2$
assertEquals("Did not get expected type", DataTypeManager.DefaultDataClasses.STRING, elem1.getType()); //$NON-NLS-1$
- ElementSymbol elem2 = (ElementSymbol)elements.get(1);
+ ElementSymbol elem2 = elements.get(1);
assertEquals("Did not get expected element", "x.e2", elem2.getName() ); //$NON-NLS-1$ //$NON-NLS-2$
assertEquals("Did not get expected type", DataTypeManager.DefaultDataClasses.INTEGER, elem2.getType()); //$NON-NLS-1$
}
@@ -2355,7 +2334,7 @@
String update1 = "update pm1.g1 set e1 =1"; //$NON-NLS-1$
String update2 = "update pm2.g1 set e1 =1"; //$NON-NLS-1$
- List commands = new ArrayList();
+ List<Command> commands = new ArrayList<Command>();
commands.add(QueryParser.getQueryParser().parseCommand(update1));
commands.add(QueryParser.getQueryParser().parseCommand(update2));
BatchedUpdateCommand command = new BatchedUpdateCommand(commands);
@@ -2438,11 +2417,11 @@
StoredProcedure proc = (StoredProcedure)helpResolve(query);
- List projected = proc.getProjectedSymbols();
+ List<Expression> projected = proc.getProjectedSymbols();
assertEquals(2, projected.size());
- for (Iterator i = projected.iterator(); i.hasNext();) {
+ for (Iterator<Expression> i = projected.iterator(); i.hasNext();) {
ElementSymbol symbol = (ElementSymbol)i.next();
assertNotNull(symbol.getGroupSymbol());
}
@@ -2923,6 +2902,10 @@
helpResolve("select * from xmltable('/a' passing ?) as x");
}
+ @Test public void testObjectTableWithParam() {
+ helpResolve("select * from objecttable('x + 1' passing ? as x columns obj OBJECT '') as y");
+ }
+
@Test public void testXmlQueryWithParam() {
Query q = (Query)helpResolve("select xmlquery('/a' passing ?)");
XMLQuery ex = (XMLQuery) SymbolMap.getExpression(q.getSelect().getSymbols().get(0));
Modified: trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -1576,6 +1576,22 @@
@Test public void testXMLTableContextRequired() {
helpValidate("select * from xmltable('/a/b' passing convert('<a/>', xml) as a columns x for ordinality, c integer path '.') as x", new String[] {"XMLTABLE('/a/b' PASSING convert('<a/>', xml) AS a COLUMNS x FOR ORDINALITY, c integer PATH '.') AS x"}, RealMetadataFactory.example1Cached());
}
+
+ @Test public void testObjectTablePassing() {
+ helpValidate("select * from objecttable('x' passing 'a' columns c integer 'row') as x", new String[] {"OBJECTTABLE('x' PASSING 'a' COLUMNS c integer 'row') AS x"}, RealMetadataFactory.example1Cached());
+ }
+
+ @Test public void testObjectTablePassingSameName() {
+ helpValidate("select * from objecttable('x' passing 'a' AS X, 'b' AS x columns c integer 'row') as x", new String[] {"OBJECTTABLE('x' PASSING 'a' AS X, 'b' AS x COLUMNS c integer 'row') AS x"}, RealMetadataFactory.example1Cached());
+ }
+
+ @Test public void testObjectTableLanguage() {
+ helpValidate("select * from objecttable(language 'foo!' 'x' columns c integer 'row') as x", new String[] {"OBJECTTABLE(LANGUAGE 'foo!' 'x' COLUMNS c integer 'row') AS x"}, RealMetadataFactory.example1Cached());
+ }
+
+ @Test public void testObjectTableScript() {
+ helpValidate("select * from objecttable('this is not valid' columns c integer 'row') as x", new String[] {"OBJECTTABLE('this is not valid' COLUMNS c integer 'row') AS x"}, RealMetadataFactory.example1Cached());
+ }
@Test public void testXMLQueryPassingContextType() {
helpValidate("select xmlquery('/' passing 2)", new String[] {"XMLQUERY('/' PASSING 2)"}, RealMetadataFactory.example1Cached());
Modified: trunk/jboss-integration/src/main/java/org/teiid/jboss/VDBDeployer.java
===================================================================
--- trunk/jboss-integration/src/main/java/org/teiid/jboss/VDBDeployer.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/jboss-integration/src/main/java/org/teiid/jboss/VDBDeployer.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -29,6 +29,8 @@
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
+import javax.script.ScriptEngineManager;
+
import org.jboss.as.controller.ModelController;
import org.jboss.as.naming.deployment.ContextNames;
import org.jboss.as.server.Services;
@@ -38,7 +40,16 @@
import org.jboss.as.server.deployment.DeploymentUnitProcessingException;
import org.jboss.as.server.deployment.DeploymentUnitProcessor;
import org.jboss.modules.Module;
-import org.jboss.msc.service.*;
+import org.jboss.modules.ModuleClassLoader;
+import org.jboss.msc.service.AbstractServiceListener;
+import org.jboss.msc.service.Service;
+import org.jboss.msc.service.ServiceBuilder;
+import org.jboss.msc.service.ServiceController;
+import org.jboss.msc.service.ServiceName;
+import org.jboss.msc.service.ServiceTarget;
+import org.jboss.msc.service.StartContext;
+import org.jboss.msc.service.StartException;
+import org.jboss.msc.service.StopContext;
import org.jboss.msc.service.ServiceBuilder.DependencyType;
import org.jboss.msc.service.ServiceController.Mode;
import org.jboss.msc.service.ServiceController.State;
@@ -121,7 +132,9 @@
}
// add VDB module's classloader as an attachment
- deployment.addAttchment(ClassLoader.class, deploymentUnit.getAttachment(Attachments.MODULE).getClassLoader());
+ ModuleClassLoader classLoader = deploymentUnit.getAttachment(Attachments.MODULE).getClassLoader();
+ deployment.addAttchment(ClassLoader.class, classLoader);
+ deployment.addAttchment(ScriptEngineManager.class, new ScriptEngineManager(classLoader));
// check if this is a VDB with index files, if there are then build the TransformationMetadata
UDFMetaData udf = deploymentUnit.removeAttachment(TeiidAttachments.UDF_METADATA);
12 years, 4 months