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$
}